@runfusion/fusion 0.17.2 → 0.18.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.
- package/dist/bin.js +1004 -633
- package/dist/client/assets/ChatView-BomXmqar.js +1 -0
- package/dist/client/assets/{DevServerView-GFFVXHVP.js → DevServerView-yFvF4xL4.js} +1 -1
- package/dist/client/assets/DirectoryPicker-BDNodhtF.js +1 -0
- package/dist/client/assets/DocumentsView-CAWtDEaL.js +1 -0
- package/dist/client/assets/{InsightsView-Bxu0TJkt.js → InsightsView-CDkiJeW1.js} +2 -2
- package/dist/client/assets/MemoryView-ZRQ9EL9H.js +2 -0
- package/dist/client/assets/NodesView-DosrOyeH.js +14 -0
- package/dist/client/assets/NodesView-sJgPLTzz.css +1 -0
- package/dist/client/assets/{PiExtensionsManager-4e3MlD62.js → PiExtensionsManager-CzZ1LEpz.js} +3 -3
- package/dist/client/assets/PluginManager-Dp3vPsMO.js +1 -0
- package/dist/client/assets/ResearchView-PvNkdaQE.js +1 -0
- package/dist/client/assets/{RoadmapsView-jHTOK0RQ.js → RoadmapsView-BUW-HJz5.js} +2 -2
- package/dist/client/assets/SettingsModal-BNSrO1M9.css +1 -0
- package/dist/client/assets/{SettingsModal-4Z8ZJMzD.js → SettingsModal-ByVl_fUi.js} +1 -1
- package/dist/client/assets/SettingsModal-oOnIed5O.css +1 -0
- package/dist/client/assets/SettingsModal-uzo470XS.js +31 -0
- package/dist/client/assets/SetupWizardModal-DH1hpyiP.js +1 -0
- package/dist/client/assets/SkillsView-B-RqQSFE.js +1 -0
- package/dist/client/assets/index-CtiRbTNv.js +1229 -0
- package/dist/client/assets/index-Dy-xC2C2.css +1 -0
- package/dist/client/assets/{users-D3u6f2Rz.js → users-WyHhw14V.js} +2 -2
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/index.ts +12 -7
- package/dist/droid-cli/package.json +4 -1
- package/dist/droid-cli/src/__tests__/provider.test.ts +42 -6
- package/dist/extension.js +488 -43
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/package.json +2 -1
- package/skill/fusion/SKILL.md +2 -2
- package/skill/fusion/references/best-practices.md +33 -0
- package/skill/fusion/references/extension-tools.md +47 -2
- package/skill/fusion/references/fusion-capabilities.md +7 -2
- package/dist/client/assets/AgentDetailView-17J-F0Rl.js +0 -18
- package/dist/client/assets/AgentDetailView-yu8Xltqk.css +0 -1
- package/dist/client/assets/AgentsView-Bs03ptrd.css +0 -1
- package/dist/client/assets/AgentsView-sbBkb7Wd.js +0 -517
- package/dist/client/assets/ChatView-BR5cvK_B.js +0 -1
- package/dist/client/assets/DirectoryPicker-WPDSBdT6.js +0 -1
- package/dist/client/assets/DocumentsView-BHpDsIIt.js +0 -1
- package/dist/client/assets/MemoryView-CmnzZorw.js +0 -2
- package/dist/client/assets/NodesView-CO9_4hCr.js +0 -14
- package/dist/client/assets/NodesView-DuAXX_0j.css +0 -1
- package/dist/client/assets/PluginManager-DGN2rvOY.js +0 -1
- package/dist/client/assets/ResearchView-Dsa6Gykl.js +0 -1
- package/dist/client/assets/SettingsModal-D0kuJpBA.js +0 -31
- package/dist/client/assets/SettingsModal-D_AFkDJa.css +0 -1
- package/dist/client/assets/SettingsModal-Dq4a5KSX.css +0 -1
- package/dist/client/assets/SetupWizardModal-Bhumd4Rf.js +0 -1
- package/dist/client/assets/SkillsView-MHweJTz4.js +0 -1
- package/dist/client/assets/folder-open-BNQW9dE9.js +0 -6
- package/dist/client/assets/index-DEVBHvyW.css +0 -1
- package/dist/client/assets/index-k_85J1DS.js +0 -682
- package/dist/client/assets/star-7L86NZrT.js +0 -6
- package/dist/client/assets/upload-DsAS6tno.js +0 -6
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as s,j as t}from"./vendor-react-K0fH_qHe.js";import{i as et,aT as Ht,y as Bt,aU as Gt,D as Vt,aV as Kt,aW as qt,aX as Xt,aY as Yt,aZ as Jt,a_ as Qt,s as Zt,a$ as es,w as ts,b0 as ss,u as ns,b1 as as,ae as pt,af as xt,S as is,_ as ot,O as Qe,ar as rs,a0 as ls,B as We,ab as vt,ac as wt,b2 as os,b3 as cs,b4 as ds,aK as us,b5 as hs,b6 as ms,b7 as ct,b8 as fs,h as gs,j as dt,l as ps}from"./index-k_85J1DS.js";import"./vendor-xterm-DzcZoU0P.js";const Ze="kb-chat-active-session";function xs(a){const i=typeof a=="string"?a.trim():"",r=i.indexOf("/");return!i||r<=0||r>=i.length-1?{}:{modelProvider:i.slice(0,r),modelId:i.slice(r+1)}}function vs(a){const i=a?.toolCalls;if(!Array.isArray(i))return;const r=i.map(c=>{if(!c||typeof c!="object")return null;const l=c,w=typeof l.toolName=="string"?l.toolName:"";if(!w)return null;const N=l.args;return{toolName:w,...N&&typeof N=="object"?{args:N}:{},isError:!!l.isError,result:l.result,status:"completed"}}).filter(c=>c!==null);return r.length>0?r:void 0}function ws(a){const i=a?.fallback;if(!i||typeof i!="object")return;const r=i,c=typeof r.primaryModel=="string"?r.primaryModel:"",l=typeof r.fallbackModel=="string"?r.fallbackModel:"",w=r.triggerPoint;if(!(!c||!l||w!=="session-creation"&&w!=="prompt-time"))return{primaryModel:c,fallbackModel:l,triggerPoint:w}}function ut(a){return{id:a.id,sessionId:a.sessionId,role:a.role,content:a.content,thinkingOutput:a.thinkingOutput,toolCalls:vs(a.metadata),fallbackInfo:ws(a.metadata),attachments:a.attachments,createdAt:a.createdAt}}function bs(a,i){const[r,c]=s.useState([]),[l,w]=s.useState(null),[N,$]=s.useState(!0),[L,b]=s.useState([]),[G,k]=s.useState(!1),[F,y]=s.useState(!1),[z,u]=s.useState(""),[C,S]=s.useState(""),[I,D]=s.useState([]),[O,Q]=s.useState(""),[U,W]=s.useState(""),[X,m]=s.useState(!0),[j,ce]=s.useState(new Map),p=s.useRef(null),se=s.useRef(!1),Y=s.useRef(""),J=s.useRef(null),Ce=s.useRef(r),Z=s.useRef(l),Me=s.useRef(F);Ce.current=r,Z.current=l,Me.current=F,s.useEffect(()=>{Y.current=O},[O]);const pe=s.useRef(new Set),de=s.useRef(0),$e=s.useRef(a);$e.current!==a&&($e.current=a,de.current++),s.useEffect(()=>{const h=de.current;et(void 0,a).then(x=>{if(de.current!==h)return;const f=new Map;for(const R of x)f.set(R.id,R);ce(f)}).catch(()=>{})},[a]);const ue=s.useCallback(async()=>{$(!0);try{const x=[...(await Ht(a)).sessions].sort((f,R)=>new Date(R.updatedAt).getTime()-new Date(f.updatedAt).getTime());c(x)}catch{}finally{$(!1)}},[a]);s.useEffect(()=>{ue()},[ue]);const re=s.useRef(()=>{});s.useEffect(()=>{if(N)return;const h=Bt(Ze,a);h&&r.find(f=>f.id===h)&&re.current(h)},[N,r,a]);const ee=s.useCallback(async(h,x)=>{k(!0);try{const f=await Gt(h,{limit:50,...x},a),R=f.messages.map(ut);x?.offset&&x.offset>0?b(_=>[...R,..._]):b(R),m(f.messages.length>=50)}catch{}finally{k(!1)}},[a]),he=s.useCallback(()=>{J.current?.(),J.current=null,Y.current="",Q(""),u(""),S(""),D([]),y(!1)},[]),le=s.useCallback((h,x)=>{p.current&&(p.current.close(),p.current=null);const f=x??r.find(R=>R.id===h);w(f||null),he(),m(!0),h?ee(h):b([]),f?.isGenerating&&(y(!0),u("")),h?Vt(Ze,h,a):Kt(Ze,a)},[r,ee,a,he]);re.current=le;const be=s.useCallback(async h=>{const x=await qt(h,a);p.current&&(p.current.close(),p.current=null);const f={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 c(R=>R.some(_=>_.id===f.id)?R:[f,...R]),he(),le(f.id,f),b([]),f},[a,he,le]),xe=s.useCallback(async h=>{await Xt(h,{status:"archived"},a),c(x=>x.filter(f=>f.id!==h)),l?.id===h&&(w(null),b([]))},[l,a]),Se=s.useCallback(async h=>{l?.id===h&&p.current&&(p.current.close(),p.current=null),await Yt(h,a),c(x=>x.filter(f=>f.id!==h)),l?.id===h&&(w(null),b([]))},[l,a]),me=s.useCallback(async()=>{!l||!X||await ee(l.id,{offset:L.length})},[l,X,ee,L.length]),ne=s.useCallback(()=>{l&&(se.current=!0,J.current?.(),J.current=null,p.current?.close(),p.current=null,Jt(l.id,a).catch(()=>{}),y(!1),u(""),S(""),D([]))},[l,a]),fe=s.useCallback(()=>{Y.current="",Q("")},[]),ve=s.useCallback((h,x)=>{if(!l)return;if(F){Y.current=h,Q(h);return}se.current=!1,p.current&&(p.current.close(),p.current=null);const f=`temp-${Date.now()}`,R={id:f,sessionId:l.id,role:"user",content:h,createdAt:new Date().toISOString()};b(g=>[...g,R]),u(""),S(""),D([]),y(!0);let _="",oe="",K=[],ge,q=null,P=null;const E=()=>{q=null,u(_)},d=()=>{P=null,S(oe)},M=()=>{q!==null&&(cancelAnimationFrame(q),q=null),P!==null&&(cancelAnimationFrame(P),P=null)};J.current=M;const ae={onThinking:g=>{oe+=g,P===null&&(P=requestAnimationFrame(d))},onText:g=>{_+=g,q===null&&(q=requestAnimationFrame(E))},onToolStart:g=>{K=[...K,{toolName:g.toolName,args:g.args,isError:!1,status:"running"}],D(K)},onToolEnd:g=>{const T=[...K];for(let v=T.length-1;v>=0;v--){const V=T[v];if(V?.toolName===g.toolName&&V.status==="running"){T[v]={...V,status:"completed",isError:g.isError,result:g.result},K=T,D(T);return}}K=[...T,{toolName:g.toolName,isError:g.isError,result:g.result,status:"completed"}],D(K)},onFallback:g=>{ge=g;const T=xs(g.fallbackModel);c(v=>v.map(V=>V.id===l.id?{...V,...T}:V)),w(v=>v&&v.id===l.id?{...v,...T}:v),i?.(`Primary model unavailable. Switched to fallback ${g.fallbackModel}.`,"warning")},onDone:g=>{M();const T={id:g.messageId||`msg-${Date.now()}`,sessionId:l.id,role:"assistant",content:_,thinkingOutput:oe,toolCalls:K.length>0?K:void 0,fallbackInfo:ge,createdAt:new Date().toISOString()};pe.current.add(T.id),b(V=>[...V,T]),u(""),S(""),D([]),y(!1),p.current=null,setTimeout(()=>{pe.current.delete(T.id)},1e3),ue();const v=Y.current.trim();v&&(Y.current="",Q(""),ve(v))},onError:g=>{if(M(),b(T=>T.filter(v=>v.id!==f)),u(""),S(""),D([]),y(!1),p.current=null,console.error("[useChat] Stream error:",g),i?.(typeof g=="string"&&g.trim()?g:"Failed to get response","error"),!se.current){const T=Y.current.trim();T&&(Y.current="",Q(""),ve(T))}}};p.current=Qt(l.id,h,ae,x,a)},[l,F,a,ue,i]),ke=U?r.filter(h=>h.title?.toLowerCase().includes(U.toLowerCase())||h.agentId.toLowerCase().includes(U.toLowerCase())):r;return s.useEffect(()=>{const h=de.current,x=a?`?projectId=${encodeURIComponent(a)}`:"",f=()=>de.current!==h,R=P=>{if(f())return;const E=JSON.parse(P.data);c(d=>d.some(M=>M.id===E.id)?d:[E,...d])},_=P=>{if(f())return;const E=JSON.parse(P.data);c(d=>[...d.map(ae=>ae.id===E.id?E:ae)]),Z.current?.id===E.id&&w(E)},oe=P=>{if(f())return;const{id:E}=JSON.parse(P.data);c(d=>d.filter(M=>M.id!==E)),Z.current?.id===E&&(w(null),b([]))},K=P=>{if(f())return;const E=JSON.parse(P.data),d=ut(E);if(!pe.current.has(d.id)){if(Z.current?.id===d.sessionId&&Me.current&&!p.current&&d.role==="assistant"){b(M=>M.some(ae=>ae.id===d.id)?M:[...M,d]),u(""),S(""),D([]),y(!1);return}Z.current?.id===d.sessionId&&!Me.current&&b(M=>M.some(ae=>ae.id===d.id)?M:[...M,d])}},ge=P=>{if(f())return;const{id:E}=JSON.parse(P.data);b(d=>d.filter(M=>M.id!==E))};return Zt(`/api/events${x}`,{events:{"chat:session:created":R,"chat:session:updated":_,"chat:session:deleted":oe,"chat:message:added":K,"chat:message:deleted":ge}})},[a]),s.useEffect(()=>()=>{p.current&&(p.current.close(),p.current=null)},[]),{sessions:r,activeSession:l,sessionsLoading:N,messages:L,messagesLoading:G,isStreaming:F,streamingText:z,streamingThinking:C,streamingToolCalls:I,pendingMessage:O,selectSession:le,createSession:be,archiveSession:xe,deleteSession:Se,sendMessage:ve,stopStreaming:ne,clearPendingMessage:fe,loadMoreMessages:me,hasMoreMessages:X,searchQuery:U,setSearchQuery:W,filteredSessions:ke,refreshSessions:ue,agentsMap:j}}function bt(a){const i=new Date(a),c=new Date().getTime()-i.getTime(),l=Math.floor(c/1e3),w=Math.floor(l/60),N=Math.floor(w/60),$=Math.floor(N/24);return l<60?"just now":w<60?`${w}m ago`:N<24?`${N}h ago`:$<7?`${$}d ago`:i.toLocaleDateString()}function ht(a,i){if(!a||!i)return null;const r=i.toLowerCase();if(r.includes("claude")){let l=i.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 l=l.replace(/\s+/g," "),l.length>30?l.slice(0,30)+"…":l}if(r.includes("gpt")||r.includes("openai")){const l=i.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 l.length>30?l.slice(0,30)+"…":l}if(r.includes("gemini")){const l=i.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 l.length>30?l.slice(0,30)+"…":l}const c=i.replace(/-/g," ").replace(/^\w/,l=>l.toUpperCase()).replace(/\s+/g," ").trim();return c.length>30?c.slice(0,30)+"…":c}function Oe(a,i){return a.length<=i?a:`${a.slice(0,i)}…`}function Ss(a){if(!a)return null;const i=Object.entries(a);return i.length===0?null:i.map(([r,c])=>{const l=typeof c=="string"?c:(()=>{try{return JSON.stringify(c)}catch{return String(c)}})();return`${r}=${Oe(l,50)}`}).join(", ")}function ks(a){if(a===void 0)return null;if(typeof a=="string")return Oe(a,200);try{return Oe(JSON.stringify(a),200)}catch{return Oe(String(a),200)}}function St(a){if(!a||a.length===0)return null;const i=(k,F)=>{const y=k.status==="running",z=k.status==="completed"&&k.isError,u=Ss(k.args),C=ks(k.result),S=y?u:C?`result: ${C}`:u?`args: ${u}`:null,I=y?"running":z?"error":"completed";return t.jsxs("details",{className:`chat-tool-call${y?" chat-tool-call--running":""}${z?" chat-tool-call--error":""}`,open:y,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",children:k.toolName}),S&&t.jsx("span",{className:"chat-tool-call-preview",title:S,children:S}),t.jsx("span",{className:"chat-tool-call-status-text",children:I})]}),t.jsxs("div",{className:"chat-tool-call-content",children:[u&&t.jsxs("div",{className:"chat-tool-call-row",children:[t.jsx("span",{className:"chat-tool-call-label",children:"args"}),t.jsx("span",{className:"chat-tool-call-value",children:u})]}),C&&t.jsxs("div",{className:`chat-tool-call-row${z?" chat-tool-call-row--error":""}`,children:[t.jsx("span",{className:"chat-tool-call-label",children:"result"}),t.jsx("span",{className:"chat-tool-call-value",children:C})]})]})]},`${k.toolName}-${F}`)},r="chat-tool-calls";if(a.length===1)return t.jsxs("div",{className:r,"data-testid":"chat-tool-calls",children:[t.jsxs("div",{className:"chat-tool-calls-header",children:[t.jsx(ct,{size:12,"aria-hidden":"true"}),t.jsx("span",{children:"Tool calls"})]}),i(a[0],0)]});const c=a.filter(k=>k.status==="running").length,l=a.filter(k=>k.status==="completed"&&k.isError).length,w=c>0,N=Array.from(new Set(a.map(k=>k.toolName))),$=N.slice(0,5),L=Math.max(0,N.length-$.length),b=L>0?`${$.join(", ")}, +${L} more`:$.join(", "),G=w?`(${c} running)`:l>0?`(${l} ${l===1?"error":"errors"})`:null;return t.jsx("div",{className:r,"data-testid":"chat-tool-calls",children:t.jsxs("details",{className:"chat-tool-calls-group","data-testid":"chat-tool-calls-group",open:w,children:[t.jsxs("summary",{className:"chat-tool-calls-group-summary",children:[t.jsx(ct,{size:12,"aria-hidden":"true"}),t.jsxs("span",{children:[a.length," tool calls"]}),t.jsx("span",{className:"chat-tool-calls-names",title:b,children:b}),G&&t.jsx("span",{className:"chat-tool-calls-group-status",children:G})]}),a.map((k,F)=>i(k,F))]})})}const kt={pre:({children:a,...i})=>t.jsx("pre",{...i,className:"chat-markdown-pre",children:a}),table:({children:a,...i})=>t.jsx("table",{...i,className:"chat-markdown-table",children:a})},Ue="__fn_agent__",ys=280,Le=180,ze=500,mt="fusion:chat-sidebar-width",Ns=["image/png","image/jpeg","image/gif","image/webp","text/plain","application/json","text/yaml","text/markdown","text/csv","application/xml","text/x-log"];function ft(a){const i=/(^|[\s])\/([^\s]*)$/.exec(a);if(!i)return null;const r=i[1]??"",c=i[2]??"",l=i.index+r.length;return{filter:c,start:l,end:a.length}}function js(a,i){const r=a.slice(0,i),c=/(^|[\s\n])@([\w-]*)$/.exec(r);if(!c)return null;const l=c[2]??"",w=r.length-l.length-1;return{filter:l,start:w,end:i}}function Cs({projectId:a,onClose:i,onCreate:r}){const[c,l]=s.useState("agent"),[w,N]=s.useState([]),[$,L]=s.useState(!0),[b,G]=s.useState(""),[k,F]=s.useState([]),[y,z]=s.useState(!0),[u,C]=s.useState(""),[S,I]=s.useState([]),[D,O]=s.useState([]);s.useEffect(()=>{let m=!1;return L(!0),et(void 0,a).then(j=>{m||N(j)}).catch(()=>{m||N([])}).finally(()=>{m||L(!1)}),()=>{m=!0}},[a]),s.useEffect(()=>{z(!0),gs().then(m=>{F(m.models),I(m.favoriteProviders),O(m.favoriteModels)}).catch(()=>{F([]),I([]),O([])}).finally(()=>{z(!1)})},[]);const Q=s.useCallback(async m=>{const j=S,p=j.includes(m)?j.filter(se=>se!==m):[m,...j];I(p);try{await dt({favoriteProviders:p,favoriteModels:D})}catch{I(j)}},[S,D]),U=s.useCallback(async m=>{const j=D,p=j.includes(m)?j.filter(se=>se!==m):[m,...j];O(p);try{await dt({favoriteProviders:S,favoriteModels:p})}catch{O(j)}},[D,S]),W=m=>{if(m.preventDefault(),c==="agent"){if(!b)return;r({agentId:b});return}if(!u)return;const j=u.indexOf("/");if(j<=0)return;const ce=u.slice(0,j),p=u.slice(j+1);r({agentId:Ue,modelProvider:ce,modelId:p})},X=c==="agent"?!b:!u;return t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:i,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:"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${c==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{l("agent"),C("")},children:"Agent"}),t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${c==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{l("model"),G("")},children:"Model"})]}),t.jsxs("form",{onSubmit:W,children:[c==="agent"&&t.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",$?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):w.length===0?t.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):t.jsx("div",{className:"chat-new-dialog-agent-list",children:w.map(m=>t.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${b===m.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>G(m.id),"data-testid":`agent-option-${m.id}`,children:[t.jsx(We,{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))})]}),c==="model"&&t.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:y?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading models..."}):t.jsx(ps,{models:k,value:u,onChange:C,label:"Model",placeholder:"Select a model",favoriteProviders:S,onToggleFavorite:Q,favoriteModels:D,onToggleModelFavorite:U})}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{type:"button",className:"btn btn-sm",onClick:i,children:"Cancel"}),t.jsx("button",{type:"submit",className:"btn btn-sm btn-primary",disabled:X,children:"Create"})]})]})]})})}const gt=s.memo(function({message:i,forcePlain:r,agentName:c,showAssistantModelTag:l,activeModelTag:w,activeSessionId:N,mentionAgentsByName:$,onToggleRender:L}){const b=i.role==="assistant",G=s.useMemo(()=>{if(b)return null;const y=i.content,z=/@([\w-]+)/g,u=[];let C=0,S=z.exec(y);for(;S;){const[I,D=""]=S,O=S.index;O>C&&u.push(y.slice(C,O));const Q=D.replace(/_/g," ").toLowerCase(),U=$.get(Q);U?u.push(t.jsxs("span",{className:"chat-mention-chip",children:["@",U.name.replace(/\s+/g,"_")]},`${U.id}-${O}`)):u.push(I),C=O+I.length,S=z.exec(y)}return C<y.length&&u.push(y.slice(C)),u.length===0?y:u},[b,i.content,$]),k=s.useMemo(()=>{const y=i.attachments;if(!y||y.length===0||!N)return null;const z=`/api/chat/sessions/${encodeURIComponent(N)}/attachments/`;return t.jsx("div",{className:"chat-message-attachments",children:y.map(u=>{const C=u.mimeType.startsWith("image/"),S=u.id||u.filename,I=`${z}${encodeURIComponent(u.filename)}`;return C?t.jsx("a",{className:"chat-message-attachment-link","data-testid":"chat-message-attachment",href:I,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{className:"chat-message-attachment",src:I,alt:u.originalName})},S):t.jsxs("a",{className:"chat-message-attachment-file","data-testid":"chat-message-attachment",href:I,target:"_blank",rel:"noopener noreferrer",children:[t.jsx(ms,{size:14}),t.jsx("span",{children:u.originalName})]},S)})})},[i.attachments,N]),F=s.useMemo(()=>b?r?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:i.content}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(pt,{remarkPlugins:[xt],components:kt,children:i.content})}):null,[b,r,i.content]);return t.jsxs("div",{className:`chat-message chat-message--${i.role}`,"data-testid":`chat-message-${i.id}`,children:[b&&t.jsxs("div",{className:"chat-message-avatar",children:[t.jsx(We,{size:14}),t.jsx("span",{children:c}),l&&w&&t.jsx("span",{className:"chat-model-tag",children:w}),t.jsx("button",{type:"button",className:`chat-message-render-toggle${r?" chat-message-render-toggle--plain":""}`,"data-testid":"chat-message-render-toggle","aria-label":r?"Show rendered markdown":"Show plain text",onClick:()=>L(i.id),children:r?t.jsx(vt,{size:14}):t.jsx(wt,{size:14})})]}),b?F:t.jsx("div",{className:"chat-message-content",children:G}),St(i.toolCalls),i.thinkingOutput&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:i.thinkingOutput})]}),k,t.jsx("div",{className:"chat-message-time",children:bt(i.createdAt)})]})});function Rs({projectId:a,addToast:i}){const{activeSession:r,sessionsLoading:c,messages:l,messagesLoading:w,isStreaming:N,streamingText:$,streamingThinking:L,streamingToolCalls:b,selectSession:G,createSession:k,archiveSession:F,deleteSession:y,sendMessage:z,stopStreaming:u,pendingMessage:C,clearPendingMessage:S,searchQuery:I,setSearchQuery:D,filteredSessions:O}=bs(a,i),[Q,U]=s.useState(!1),[W,X]=s.useState(""),[m,j]=s.useState(null),[ce,p]=s.useState(null),[se,Y]=s.useState(!0),[J,Ce]=s.useState(ys),[Z,Me]=s.useState(new Map),[pe,de]=s.useState([]),[$e,ue]=s.useState(!0),[re,ee]=s.useState(!1),[he,le]=s.useState(""),[be,xe]=s.useState(0),[Se,me]=s.useState(""),[ne,fe]=s.useState(!1),[ve,ke]=s.useState(0),[h,x]=s.useState(-1),[f,R]=s.useState(()=>new Set),[_,oe]=s.useState([]),[K,ge]=s.useState(!1),[,q]=s.useState(!1),[P,E]=s.useState({top:0,left:0}),d=es({projectId:a}),M=s.useCallback(e=>{if(!e||!d.mentionActive)return;const n=e.getBoundingClientRect();E({top:n.top-260,left:n.left+8})},[d.mentionActive]),ae=s.useRef(null),g=s.useRef(null),T=s.useRef(null),v=s.useRef(null),V=s.useRef(!1),Pe=s.useRef(!1),tt=s.useRef(null),st=s.useRef([]),Te=s.useRef(0),H=ts()==="mobile";s.useEffect(()=>{try{const e=localStorage.getItem(mt);if(!e)return;const n=Number.parseInt(e,10);if(Number.isNaN(n))return;const o=Math.max(Le,Math.min(ze,n));Ce(o)}catch{}},[]);const{keyboardOverlap:He,viewportHeight:nt,viewportOffsetTop:yt,keyboardOpen:at}=ss({enabled:H&&!!r}),Nt=at?{"--keyboard-overlap":`${He}px`,"--vv-offset-top":`${yt}px`,...nt!==null?{"--vv-height":`${nt}px`}:{}}:{},te=s.useMemo(()=>{const e=he.trim().toLowerCase();return(e?pe.filter(o=>o.name.toLowerCase().includes(e)):pe).slice(0,10)},[pe,he]),ye=s.useMemo(()=>Array.from(Z.values()),[Z]),we=s.useMemo(()=>{const e=Se.trim().toLowerCase();return e?ye.filter(n=>n.name.toLowerCase().includes(e)):ye},[ye,Se]),it=s.useMemo(()=>{const e=new Map;for(const n of ye)e.set(n.name.toLowerCase(),n);return e},[ye]);s.useEffect(()=>{xe(0)},[te]),s.useEffect(()=>{ke(0)},[Se,ne]),s.useEffect(()=>()=>{g.current!==null&&window.clearTimeout(g.current)},[]),s.useEffect(()=>{const e=T.current;e&&(e.scrollTop=e.scrollHeight)},[l,$,L,N]),s.useEffect(()=>{if(He<=0)return;const e=T.current;e&&(e.scrollTop=e.scrollHeight)},[He]),ns(H&&at),s.useEffect(()=>{const e=()=>j(null);if(m)return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[m]),s.useEffect(()=>{let e=!1;const n=a;return et(void 0,a).then(o=>{if(e||n!==a)return;const A=new Map;for(const B of o)A.set(B.id,B);Me(A)}).catch(()=>{}),()=>{e=!0}},[a]),s.useEffect(()=>{let e=!1;return ue(!0),as(a).then(n=>{e||de(n)}).catch(()=>{e||de([])}).finally(()=>{e||ue(!1)}),()=>{e=!0}},[a]),s.useEffect(()=>{st.current=_},[_]),s.useEffect(()=>()=>{for(const e of st.current)e.previewUrl&&URL.revokeObjectURL(e.previewUrl)},[]);const Ee=s.useCallback(e=>{if(!e||e.length===0)return;const n=[];for(const o of Array.from(e)){if(!Ns.includes(o.type))continue;const A=o.type.startsWith("image/");n.push({file:o,previewUrl:A?URL.createObjectURL(o):""})}n.length>0&&oe(o=>[...o,...n])},[]),jt=s.useCallback(e=>{oe(n=>{const o=n[e];return o?.previewUrl&&URL.revokeObjectURL(o.previewUrl),n.filter((A,B)=>B!==e)})},[]),Ct=s.useCallback(e=>{const n=e.clipboardData?.files;if(!n||n.length===0)return;const o=Array.from(n).filter(A=>A.type.startsWith("image/"));o.length!==0&&Ee(o)},[Ee]),Mt=s.useCallback(async e=>{try{await k(e),U(!1),H&&Y(!1)}catch{i("Failed to create chat session","error")}},[k,i,H]),Be=s.useCallback(()=>{X(""),ee(!1),le(""),fe(!1),me(""),x(-1),oe(e=>{for(const n of e)n.previewUrl&&URL.revokeObjectURL(n.previewUrl);return[]})},[]),Ae=s.useCallback(()=>{const e=W.trim(),n=_.map(o=>o.file);if(!(!e&&n.length===0||!r)){if(e==="/clear"){Be(),u(),S(),k({agentId:r.agentId,modelProvider:r.modelProvider??void 0,modelId:r.modelId??void 0}).catch(()=>{i("Failed to clear conversation","error")});return}Be(),z(e,n)}},[W,_,r,Be,u,S,k,i,z]),Fe=s.useCallback(()=>{if(typeof window>"u"||window.innerWidth>768)return;const e=v.current;if(!e||e.disabled)return;const n=window.scrollX,o=window.scrollY;e.focus({preventScroll:!0}),window.requestAnimationFrame(()=>{(window.scrollX!==n||window.scrollY!==o)&&window.scrollTo(n,o)})},[]),rt=s.useCallback(()=>{typeof window>"u"||window.innerWidth>768||(V.current=!0)},[]),Ge=s.useCallback(e=>{X(n=>{const o=ft(n);if(!o)return n;const A=`/skill:${e.name} `,B=n.slice(0,o.start)+A+n.slice(o.end);return window.requestAnimationFrame(()=>{v.current&&(v.current.style.height="auto",v.current.style.height=`${Math.min(v.current.scrollHeight,120)}px`,v.current.focus())}),B}),ee(!1),le(""),xe(0)},[]),Ve=s.useCallback(e=>{const n=v.current;if(!n||h<0)return;const o=n.selectionStart??Te.current,A=n.selectionEnd??o,B=Math.max(o,A),Re=Math.min(h,B),Ne=`${`@${e.name.replace(/\s+/g,"_")}`} `,Je=W.slice(0,Re)+Ne+W.slice(B),je=Re+Ne.length;X(Je),fe(!1),me(""),ke(0),x(-1),window.requestAnimationFrame(()=>{v.current&&(v.current.style.height="auto",v.current.style.height=`${Math.min(v.current.scrollHeight,120)}px`,v.current.focus(),v.current.setSelectionRange(je,je))})},[h,W]),Tt=s.useCallback(e=>{if(Te.current=e.currentTarget.selectionStart??Te.current,d.mentionActive&&d.files.length>0){if(d.handleKeyDown(e,W),e.key==="Enter"||e.key==="Tab"){const n=d.files[d.selectedIndex];if(n){const o=d.selectFile(n,W);X(o),d.dismissMention(),q(!1)}}return}if(ne&&e.key==="ArrowDown"){e.preventDefault(),we.length>0&&ke(n=>(n+1)%we.length);return}if(ne&&e.key==="ArrowUp"){e.preventDefault(),we.length>0&&ke(n=>n===0?we.length-1:n-1);return}if(ne&&e.key==="Enter"){e.preventDefault();const n=we[ve]??we[0];n&&Ve(n);return}if(ne&&e.key==="Escape"){e.preventDefault(),fe(!1),me(""),x(-1);return}if(re&&e.key==="ArrowDown"){e.preventDefault(),te.length>0&&xe(n=>(n+1)%te.length);return}if(re&&e.key==="ArrowUp"){e.preventDefault(),te.length>0&&xe(n=>n===0?te.length-1:n-1);return}if(re&&(e.key==="Enter"||e.key==="Tab")&&te.length>0){e.preventDefault();const n=te[be]??te[0];n&&Ge(n);return}if(re&&e.key==="Escape"){e.preventDefault(),ee(!1);return}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),Ae())},[ne,we,ve,Ve,re,te,be,Ge,Ae,d,W]),Ie=s.useCallback((e,n)=>{const o=js(e,n);if(o){fe(!0),me(o.filter),x(o.start);return}fe(!1),me(""),x(-1)},[]),At=s.useCallback(e=>{const n=e.target,o=n.value,A=n.selectionStart??o.length;Te.current=A,X(o);const B=ft(o);B?(ee(!0),le(B.filter)):(ee(!1),le("")),Ie(o,A),d.detectMention(o,A),q(d.mentionActive),d.mentionActive&&M(n),n.style.height="auto",n.style.height=`${Math.min(n.scrollHeight,120)}px`},[Ie]),Ke=s.useCallback(e=>{const n=e.currentTarget,o=n.selectionStart??n.value.length;Te.current=o,Ie(n.value,o),d.detectMention(n.value,o),q(d.mentionActive),d.mentionActive&&M(n)},[Ie,d,M]),Dt=s.useCallback(e=>{e.key!=="Escape"&&Ke(e)},[Ke]),Rt=s.useCallback(()=>{if(V.current){window.requestAnimationFrame(()=>{Fe()});return}g.current!==null&&window.clearTimeout(g.current),g.current=window.setTimeout(()=>{ee(!1),fe(!1),me(""),x(-1),q(!1),d.dismissMention(),g.current=null},120)},[d,Fe]),$t=s.useCallback(()=>{g.current!==null&&(window.clearTimeout(g.current),g.current=null)},[]),Pt=s.useCallback(async e=>{j(null);try{await F(e),i("Conversation archived","success")}catch{i("Failed to archive conversation","error")}},[F,i]),Et=s.useCallback(async e=>{p(null),j(null);try{await y(e),i("Conversation deleted","success")}catch{i("Failed to delete conversation","error")}},[y,i]),De=s.useCallback(e=>{try{localStorage.setItem(mt,String(e))}catch{}},[]),Ft=s.useCallback(e=>{if(H)return;e.preventDefault(),e.stopPropagation();const n=e.currentTarget;typeof n.setPointerCapture=="function"&&n.setPointerCapture(e.pointerId);const o=e.clientX,A=J;let B=A;document.body.style.userSelect="none";const Re=Ne=>{const Je=Ne.clientX-o,je=Math.max(Le,Math.min(ze,A+Je));B=je,Ce(je),De(je)},Ye=Ne=>{typeof n.releasePointerCapture=="function"&&n.releasePointerCapture(Ne.pointerId),document.body.style.userSelect="",document.removeEventListener("pointermove",Re),document.removeEventListener("pointerup",Ye),De(B)};document.addEventListener("pointermove",Re),document.addEventListener("pointerup",Ye)},[H,De,J]),It=s.useCallback(e=>{if(H||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;e.preventDefault();const n=e.shiftKey?50:10,o=e.key==="ArrowLeft"?-n:n,A=Math.max(Le,Math.min(ze,J+o));Ce(A),De(A)},[H,De,J]),_t=s.useCallback(e=>{G(e),H&&Y(!1)},[G,H]),Lt=s.useCallback(()=>{G(""),Y(!0)},[G]),zt=()=>t.jsxs("div",{className:"chat-empty-state",children:[t.jsx(fs,{size:48,strokeWidth:1.5}),t.jsx("h2",{children:"Start a new conversation"}),t.jsxs("button",{className:"btn btn-primary",onClick:()=>U(!0),children:[t.jsx(Qe,{size:16}),"New Chat"]})]}),ie=ht(r?.modelProvider,r?.modelId),lt=r?.agentId===Ue?ie??"Fusion":r?.title||Z.get(r?.agentId??"")?.name||r?.agentId||"Chat",Ot=!!(ie&&ie!==lt),_e=Z.get(r?.agentId??"")?.name||(r?.agentId===Ue?ie??"Fusion":r?.agentId?.slice(0,30)??"Fusion"),qe=!!(ie&&ie!==_e),Ut=C.length>50?`${C.slice(0,50)}…`:C,Xe=s.useCallback(e=>{R(n=>{const o=new Set(n);return o.has(e)?o.delete(e):o.add(e),o})},[]),Wt=s.useCallback((e,n=!1)=>n?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(pt,{remarkPlugins:[xt],components:kt,children:e})}),[]);return t.jsxs("div",{className:"chat-view",children:[t.jsxs("div",{className:`chat-sidebar${se?"":" chat-sidebar--hidden"}`,style:H?void 0:{width:`${J}px`},children:[t.jsx("div",{className:"chat-sidebar-search",children:t.jsxs("div",{className:"chat-sidebar-search-wrapper",children:[t.jsx(is,{size:14,className:"chat-sidebar-search-icon"}),t.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:I,onChange:e=>D(e.target.value),"data-testid":"chat-search-input"})]})}),t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:c?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"Loading..."}):O.length===0?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"No conversations yet"}):O.map(e=>t.jsxs("div",{className:`chat-session-item${r?.id===e.id?" chat-session-item--active":""}`,onClick:()=>_t(e.id),onContextMenu:n=>{n.preventDefault(),j({sessionId:e.id,x:n.clientX,y:n.clientY})},"data-testid":`chat-session-${e.id}`,children:[t.jsx("button",{className:"chat-session-delete-btn",onClick:n=>{n.stopPropagation(),p(e.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:t.jsx(ot,{size:14})}),t.jsx("div",{className:"chat-session-title",children:e.title||"Untitled"}),t.jsx("div",{className:"chat-session-preview",children:e.lastMessagePreview||"No messages"}),t.jsxs("div",{className:"chat-session-meta",children:[t.jsx("span",{children:Z.get(e.agentId)?.name||(e.agentId===Ue?ht(e.modelProvider,e.modelId)??"Fusion":e.agentId.slice(0,30))}),t.jsx("span",{children:e.updatedAt?bt(e.updatedAt):""})]})]},e.id))}),t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>U(!0),"data-testid":"chat-new-btn",children:[t.jsx(Qe,{size:14}),"New Chat"]})})]}),!H&&se&&t.jsx("div",{className:"chat-sidebar-resize-handle",role:"separator","aria-orientation":"vertical","aria-valuemin":Le,"aria-valuemax":ze,"aria-valuenow":J,"aria-label":"Resize chat sidebar",tabIndex:0,onPointerDown:Ft,onKeyDown:It}),m&&t.jsxs("div",{className:"chat-session-context-menu",style:{top:m.y,left:m.x},onClick:e=>e.stopPropagation(),children:[t.jsxs("button",{onClick:()=>Pt(m.sessionId),"data-testid":"chat-context-archive",children:[t.jsx(rs,{size:14}),"Archive"]}),t.jsxs("button",{onClick:()=>{j(null),p(m.sessionId)},"data-testid":"chat-context-delete",children:[t.jsx(ot,{size:14}),"Delete"]})]}),ce&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>p(null),children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:e=>e.stopPropagation(),children:[t.jsx("h3",{children:"Delete Conversation?"}),t.jsx("p",{className:"chat-view-delete-dialog-copy",children:"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:()=>p(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void Et(ce),children:"Delete"})]})]})}),t.jsxs("div",{className:"chat-thread",style:Nt,children:[(r||!H)&&t.jsxs("div",{className:"chat-thread-header",children:[H&&r&&t.jsx("button",{className:"btn-icon",onClick:Lt,"data-testid":"chat-back-btn",children:t.jsx(ls,{size:16})}),t.jsx(We,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:lt}),Ot&&t.jsx("span",{className:"chat-model-tag",children:ie}),!H&&t.jsxs("button",{className:"btn btn-sm btn-primary chat-thread-header-new-chat",onClick:()=>U(!0),"data-testid":"chat-thread-new-chat-btn",children:[t.jsx(Qe,{size:14}),"New Chat"]})]}),t.jsxs("div",{className:"chat-messages",ref:T,children:[N?t.jsxs(t.Fragment,{children:[l.map(e=>t.jsx(gt,{message:e,forcePlain:f.has(e.id),agentName:_e,showAssistantModelTag:qe,activeModelTag:ie,activeSessionId:r?.id??null,mentionAgentsByName:it,onToggleRender:Xe},e.id)),t.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[t.jsxs("div",{className:"chat-message-avatar",children:[t.jsx(We,{size:14}),t.jsx("span",{children:_e}),qe&&t.jsx("span",{className:"chat-model-tag",children:ie}),t.jsx("button",{type:"button",className:`chat-message-render-toggle${f.has("__streaming__")?" chat-message-render-toggle--plain":""}`,"data-testid":"chat-message-render-toggle","aria-label":f.has("__streaming__")?"Show rendered markdown":"Show plain text",onClick:()=>Xe("__streaming__"),children:f.has("__streaming__")?t.jsx(vt,{size:14}):t.jsx(wt,{size:14})})]}),$?Wt($,f.has("__streaming__")):t.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:L?"Thinking…":"Connecting…"}),St(b),L&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:L})]}),t.jsxs("div",{className:"chat-typing-indicator",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]})]})]}):w?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):l.length===0&&!r?zt():l.length===0&&r?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):t.jsx(t.Fragment,{children:l.map(e=>t.jsx(gt,{message:e,forcePlain:f.has(e.id),agentName:_e,showAssistantModelTag:qe,activeModelTag:ie,activeSessionId:r?.id??null,mentionAgentsByName:it,onToggleRender:Xe},e.id))}),t.jsx("div",{ref:ae})]}),r&&t.jsxs("div",{className:"chat-input-area",children:[t.jsx("input",{ref:tt,type:"file",accept:"image/*,.txt,.json,.yaml,.yml,.log,.csv,.xml,.md",multiple:!0,style:{display:"none"},onChange:e=>{Ee(e.target.files),e.target.value=""}}),re&&t.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:$e?t.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):te.length===0?t.jsx("div",{className:"chat-skill-menu-empty",children:he?"No skills found":"No skills available"}):te.map((e,n)=>t.jsxs("button",{type:"button",role:"option","aria-selected":n===be,className:`chat-skill-menu-item${n===be?" chat-skill-menu-item--highlighted":""}`,onMouseDown:o=>o.preventDefault(),onMouseEnter:()=>xe(n),onClick:()=>Ge(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))}),_.length>0&&t.jsx("div",{className:"chat-attachment-previews","data-testid":"chat-attachment-previews",children:_.map((e,n)=>t.jsxs("div",{className:"chat-attachment-preview","data-testid":`chat-attachment-preview-${n}`,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:()=>jt(n),"data-testid":`chat-attachment-remove-${n}`,"aria-label":`Remove ${e.file.name}`,children:"×"})]},e.previewUrl||`${e.file.name}-${n}`))}),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":"Attach files",onClick:()=>tt.current?.click(),children:t.jsx(os,{size:16})}),t.jsxs("div",{className:`chat-input-wrapper${K?" chat-input-wrapper--dragover":""}`,onDragOver:e=>{e.preventDefault(),ge(!0)},onDragLeave:()=>ge(!1),onDrop:e=>{e.preventDefault(),ge(!1),Ee(e.dataTransfer.files)},children:[t.jsx("textarea",{ref:v,className:"chat-input-textarea",placeholder:"Type a message...",value:W,onChange:At,onKeyDown:Tt,onKeyUp:Dt,onClick:Ke,onBlur:Rt,onFocus:$t,onPaste:Ct,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(cs,{agents:ye,filter:Se,highlightedIndex:ve,visible:ne,onSelect:Ve,position:"below"}),t.jsx(ds,{visible:d.mentionActive&&!ne,position:P,files:d.files,selectedIndex:d.selectedIndex,onSelect:e=>{const n=d.selectFile(e,W);X(n),d.dismissMention(),q(!1),v.current?.focus()},loading:d.loading}),C&&t.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[t.jsx("span",{children:`Queued: ${Ut}`}),t.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:S,children:"×"})]})]}),N?t.jsx("button",{className:"chat-input-stop",onClick:u,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:t.jsx(us,{size:14})}):t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{typeof window>"u"||window.innerWidth>768||(e.preventDefault(),e.pointerType&&e.pointerType!=="mouse"&&(Pe.current=!0,rt(),Fe(),Ae(),window.setTimeout(()=>{V.current=!1},1500)))},onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||(e.preventDefault(),Pe.current=!0,rt(),Fe(),Ae(),window.setTimeout(()=>{V.current=!1},1500))},onMouseDown:e=>{typeof window>"u"||window.innerWidth>768||e.preventDefault()},onClick:()=>{if(Pe.current){Pe.current=!1;return}Ae()},disabled:!W.trim()&&_.length===0,"data-testid":"chat-send-btn",children:t.jsx(hs,{size:16})})]})]})]}),Q&&t.jsx(Cs,{projectId:a,onClose:()=>U(!1),onCreate:Mt})]})}export{Rs as ChatView};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as i,j as r}from"./vendor-react-K0fH_qHe.js";import{dX as f,dY as g,cX as b,b as y,ag as P,ab as H,ac as C,L as O,an as v}from"./index-k_85J1DS.js";import{F as z}from"./folder-open-BNQW9dE9.js";function D({value:o,onChange:d,placeholder:m,onInputKeyDown:x,nodeId:l,localNodeId:h}){const[e,n]=i.useState({isOpen:!1,loading:!1,error:null,currentPath:"",parentPath:null,entries:[],showHidden:!1}),a=i.useCallback(async(s,c=!1)=>{n(t=>({...t,loading:!0,error:null}));try{const t=await f(s,c,l,h);n(u=>({...u,loading:!1,currentPath:t.currentPath,parentPath:t.parentPath,entries:t.entries}))}catch(t){n(u=>({...u,loading:!1,error:t instanceof Error?t.message:"Failed to browse directory"}))}},[l,h]),j=i.useCallback(()=>{n(s=>s.isOpen?{...s,isOpen:!1}:{...s,isOpen:!0})},[]);i.useEffect(()=>{e.isOpen&&!e.loading&&e.entries.length===0&&!e.error&&a(o||void 0,e.showHidden)},[e.isOpen,e.loading,e.entries.length,e.error,o,e.showHidden,a,l,h]);const p=i.useCallback(s=>{a(s,e.showHidden)},[a,e.showHidden]),k=i.useCallback(()=>{d(e.currentPath),n(s=>({...s,isOpen:!1}))},[e.currentPath,d]),w=i.useCallback(()=>{n(s=>{const c=!s.showHidden;return{...s,showHidden:c}})},[]);i.useEffect(()=>{e.isOpen&&e.currentPath&&a(e.currentPath,e.showHidden)},[e.showHidden]);const N=e.currentPath?g(e.currentPath):[];return r.jsxs("div",{className:"directory-picker",children:[r.jsxs("div",{className:"directory-picker-input-row",children:[r.jsx("input",{type:"text",className:"input directory-picker-input",value:o,onChange:s=>d(s.target.value),onKeyDown:x,placeholder:m||"/path/to/your/project"}),r.jsxs("button",{type:"button",className:"btn btn-secondary btn-sm directory-picker-browse-btn",onClick:j,"aria-label":e.isOpen?"Close directory browser":"Browse directories",children:[e.isOpen?r.jsx(z,{size:16}):r.jsx(b,{size:16}),r.jsx("span",{children:"Browse"})]})]}),e.isOpen&&r.jsxs("div",{className:"directory-picker-browser",role:"tree","aria-label":"Directory browser",children:[r.jsx("div",{className:"directory-picker-breadcrumbs",children:N.map((s,c)=>r.jsxs("span",{className:"directory-picker-breadcrumb-item",children:[c>0&&r.jsx(y,{size:12,className:"directory-picker-breadcrumb-sep"}),r.jsx("button",{type:"button",className:"directory-picker-breadcrumb",onClick:()=>p(s.path),title:s.path,children:s.label})]},s.path))}),r.jsxs("div",{className:"directory-picker-toolbar",children:[e.parentPath&&r.jsxs("button",{type:"button",className:"btn btn-sm btn-secondary directory-picker-up-btn",onClick:()=>p(e.parentPath),"aria-label":"Go to parent directory",title:"Parent directory",children:[r.jsx(P,{size:14}),r.jsx("span",{children:"Up"})]}),r.jsxs("button",{type:"button",className:"btn btn-sm btn-secondary directory-picker-hidden-toggle",onClick:w,"aria-label":e.showHidden?"Hide hidden directories":"Show hidden directories",title:e.showHidden?"Hide hidden":"Show hidden",children:[e.showHidden?r.jsx(H,{size:14}):r.jsx(C,{size:14}),r.jsx("span",{children:e.showHidden?"Hide hidden":"Show hidden"})]})]}),e.loading?r.jsxs("div",{className:"directory-picker-loading",children:[r.jsx(O,{size:20,className:"animate-spin"}),r.jsx("span",{children:"Loading…"})]}):e.error?r.jsxs("div",{className:"directory-picker-error",children:[r.jsx(v,{size:16}),r.jsx("span",{children:e.error})]}):r.jsx("div",{className:"directory-picker-entries",children:e.entries.length===0?r.jsx("div",{className:"directory-picker-empty",children:"No subdirectories"}):e.entries.map(s=>r.jsxs("button",{type:"button",className:"directory-picker-entry",onClick:()=>p(s.path),role:"treeitem",title:s.path,children:[r.jsx(b,{size:16,className:"directory-picker-entry-icon"}),r.jsx("span",{className:"directory-picker-entry-name",children:s.name}),s.hasChildren&&r.jsx(y,{size:14,className:"directory-picker-entry-arrow"})]},s.path))}),r.jsxs("div",{className:"directory-picker-actions",children:[r.jsx("span",{className:"directory-picker-selected-path",title:e.currentPath,children:e.currentPath}),r.jsx("button",{type:"button",className:"btn btn-primary directory-picker-select-btn",onClick:k,children:"Select"})]})]})]})}export{D};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{a8 as oe,a9 as K,f as le,aa as ie,F as z,ab as de,ac as ue,S as me,X as he,R as pe,ad as fe,ae as W,af as V,a as X,b as je,ag as xe}from"./index-k_85J1DS.js";import"./vendor-xterm-DzcZoU0P.js";function we(n){const{projectId:c,searchQuery:u,includeProjectFiles:a=!0}=n??{},[x,l]=s.useState([]),[h,i]=s.useState([]),[o,p]=s.useState(!0),[k,b]=s.useState(null),f=s.useRef(null),g=s.useRef(!1),m=s.useRef(null),j=s.useCallback(async()=>{f.current&&f.current.abort();const C=new AbortController;f.current=C;const E=!g.current;E&&p(!0),b(null);const L=oe(u?{q:u}:void 0,c),y=a?K(c):Promise.resolve({files:[]}),[v,F]=await Promise.allSettled([L,y]);if(C.signal.aborted)return;let R=null;if(v.status==="fulfilled"?(l(v.value),g.current=!0):R=v.reason instanceof Error?v.reason.message:String(v.reason),F.status==="fulfilled"){const M=F.value.files,P=u?.trim().toLowerCase(),T=P?M.filter(N=>N.name.toLowerCase().includes(P)||N.path.toLowerCase().includes(P)):M;i(T)}b(R),E&&p(!1)},[a,c,u]);return s.useEffect(()=>(m.current&&clearTimeout(m.current),m.current=setTimeout(()=>{j()},300),()=>{m.current&&clearTimeout(m.current)}),[j]),s.useEffect(()=>(j(),()=>{f.current&&f.current.abort()}),[]),{documents:x,projectFiles:h,loading:o,error:k,refresh:j}}function ke(n,c){const[u,a]=s.useState([]),[x,l]=s.useState(!0),[h,i]=s.useState(null),o=s.useRef(null),p=s.useRef(!1),k=c?.showHidden??!1,b=s.useCallback(async f=>{o.current&&o.current.abort();const g=new AbortController;o.current=g;const m=!p.current;m&&l(!0),i(null);try{const j=await K(n,{showHidden:f?.showHidden??k});if(g.signal.aborted)return;a(j.files),p.current=!0}catch(j){if(g.signal.aborted)return;i(j instanceof Error?j.message:String(j))}finally{!g.signal.aborted&&m&&l(!1)}},[n,k]);return s.useEffect(()=>(p.current=!1,b({showHidden:k}),()=>{o.current&&o.current.abort()}),[b,k]),{files:u,loading:x,error:h,refresh:b}}const be=768;function _(n){return n?new Date(n).toLocaleString():""}function ge(n){return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(n>=10*1024?0:1)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}function ve(n,c=200){return n.length<=c?n:`${n.substring(0,c)}…`}function Ne({document:n,renderMarkdown:c,onToggleMarkdown:u}){const[a,x]=s.useState(!1),l=ve(n.content),h=n.content.length>200;return e.jsxs("div",{className:"document-card",children:[e.jsxs("div",{className:"document-card-header",children:[e.jsxs("div",{className:"document-card-key",children:[e.jsx(z,{size:14}),e.jsx("span",{className:"document-card-key-text",children:n.key}),e.jsxs("span",{className:"document-card-revision-badge",children:["v",n.revision]})]}),e.jsx("div",{className:"document-card-actions",children:e.jsx("button",{className:"btn btn-sm document-card-expand-btn",onClick:()=>x(i=>!i),title:a?"Collapse":"Expand","aria-label":a?"Collapse content":"Expand content",children:a?e.jsx(xe,{size:14}):e.jsx(X,{size:14})})})]}),e.jsxs("div",{className:"document-card-meta",children:[e.jsx("span",{className:"document-card-author",children:n.author}),e.jsx("span",{className:"document-card-separator",children:"·"}),e.jsx("span",{className:"document-card-date",children:_(n.updatedAt)})]}),e.jsxs("div",{className:`document-card-content${a?" document-card-content--expanded":""}`,children:[a?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"document-card-content-header",children:e.jsx("button",{className:"btn btn-sm document-mode-toggle",onClick:u,"aria-label":c?"Switch to plain text":"Switch to markdown","aria-pressed":c,title:c?"Switch to plain text":"Switch to markdown",children:c?"Markdown":"Plain"})}),c?e.jsx("div",{className:"document-card-content-markdown",children:e.jsx("div",{className:"markdown-body",children:e.jsx(W,{remarkPlugins:[V],children:n.content})})}):e.jsx("pre",{className:"document-card-content-text",children:n.content})]}):e.jsx("p",{className:"document-card-preview",children:l}),h&&!a&&e.jsx("p",{className:"document-card-preview-truncated",children:"…"})]})]})}function Se({taskId:n,taskTitle:c,documents:u,onOpenTask:a,renderMarkdownStates:x,onToggleMarkdown:l}){const[h,i]=s.useState(!1);return e.jsxs("div",{className:"documents-group",children:[e.jsxs("div",{className:"documents-group-header",children:[e.jsxs("button",{className:"documents-group-toggle-btn",onClick:()=>i(o=>!o),"aria-expanded":h,"aria-label":`${h?"Collapse":"Expand"} documents for task ${n}`,children:[e.jsx("span",{className:"documents-group-toggle","aria-hidden":"true",children:h?e.jsx(X,{size:16}):e.jsx(je,{size:16})}),e.jsx("span",{className:"documents-group-task-id",children:n}),e.jsx("span",{className:"documents-group-task-title",children:c||"Untitled"})]}),e.jsxs("span",{className:"documents-group-count",children:[u.length," doc",u.length!==1?"s":""]}),e.jsx("button",{className:"documents-group-task-link",onClick:()=>a(n),"aria-label":`Open task ${n}: ${c||"Untitled"}`,children:"Open task"})]}),h&&e.jsx("div",{className:"documents-group-content",children:u.map(o=>e.jsx(Ne,{document:o,renderMarkdown:x.get(o.id)??!1,onToggleMarkdown:()=>l(o.id)},o.id))})]})}function ye({projectId:n,addToast:c,onOpenDetail:u}){const[a,x]=s.useState("project"),[l,h]=s.useState(""),[i,o]=s.useState(null),[p,k]=s.useState(!1),[b,f]=s.useState(null),[g,m]=s.useState(!1),[j,C]=s.useState(null),[E,L]=s.useState(!1),y=s.useRef(0),v=s.useRef(!1),[F,R]=s.useState(!1),[M,P]=s.useState(new Map),T=a==="tasks"?l.trim():"",{documents:N,loading:D,error:J,refresh:B}=we({projectId:n,searchQuery:T||void 0,includeProjectFiles:!1}),{files:S,loading:$,error:Y,refresh:O}=ke(n,{showHidden:p});s.useEffect(()=>{const t=()=>{L(window.innerWidth<=be)};return t(),window.addEventListener("resize",t),()=>{window.removeEventListener("resize",t)}},[]),s.useEffect(()=>{v.current=!1,x("project"),o(null),k(!1),f(null),C(null),m(!1),R(!1),P(new Map)},[n]),s.useEffect(()=>{v.current||D||$||(S.length>0?x("project"):N.length>0&&x("tasks"),v.current=!0)},[N.length,D,S.length,$]);const H=s.useMemo(()=>{const t=new Map;for(const r of N){const d=t.get(r.taskId)||[];t.set(r.taskId,[...d,r])}return Array.from(t.entries()).map(([r,d])=>{const w=[...d].sort((re,ce)=>ce.updatedAt.localeCompare(re.updatedAt));return{taskId:r,taskTitle:w[0]?.taskTitle,documents:w,latestUpdated:w[0]?.updatedAt??""}}).sort((r,d)=>d.latestUpdated.localeCompare(r.latestUpdated))},[N]),A=s.useMemo(()=>{const t=l.trim().toLowerCase();return t?S.filter(r=>{const d=r.path.toLowerCase(),w=r.name.toLowerCase();return d.includes(t)||w.includes(t)}):S},[S,l]);s.useEffect(()=>{if(!i)return;S.some(r=>r.path===i.path)||(o(null),f(null),C(null),m(!1))},[S,i]);const Z=s.useCallback(t=>{h(t.target.value)},[]),I=s.useCallback(()=>{h("")},[]),Q=s.useCallback(t=>{x(t)},[]),ee=s.useCallback(async t=>{try{const r=await le(t,n);u(r)}catch{c(`Failed to open task ${t}`,"error")}},[n,u,c]),se=s.useCallback(async t=>{o(t),m(!0),C(null),f(null);const r=y.current+1;y.current=r;try{const d=await ie("project",t.path,n);if(y.current!==r)return;f(d.content)}catch(d){if(y.current!==r)return;const w=d instanceof Error?d.message:`Failed to open ${t.path}`;C(w),c(w,"error")}finally{y.current===r&&m(!1)}},[n,c]),te=s.useCallback(()=>{o(null),f(null),C(null),m(!1)},[]),ne=s.useCallback(t=>{P(r=>{const d=new Map(r),w=d.get(t)??!1;return d.set(t,!w),d})},[]),U=a==="project"?Y:J,ae=s.useCallback(async()=>{if(a==="project"){await O();return}await B()},[a,O,B]),q=a==="project"?A.length:N.length,G=a==="project"?"Search project markdown files…":"Search task documents…";return e.jsxs("div",{className:"documents-view",children:[e.jsxs("div",{className:"documents-view-header",children:[e.jsxs("div",{className:"documents-view-title-row",children:[e.jsxs("h2",{className:"documents-view-title",children:[e.jsx(z,{size:20}),"Documents"]}),e.jsxs("span",{className:"documents-view-count",children:[q," result",q!==1?"s":""]})]}),e.jsxs("div",{className:"documents-controls-row",children:[e.jsxs("div",{className:"documents-tab-bar",role:"tablist","aria-label":"Documents sections",children:[e.jsxs("button",{className:`btn documents-tab${a==="project"?" active":""}`,role:"tab","aria-selected":a==="project","aria-label":"Show project markdown files",onClick:()=>Q("project"),children:["Project Files",e.jsx("span",{className:"documents-tab-count",children:S.length})]}),e.jsxs("button",{className:`btn documents-tab${a==="tasks"?" active":""}`,role:"tab","aria-selected":a==="tasks","aria-label":"Show task documents",onClick:()=>Q("tasks"),children:["Task Documents",e.jsx("span",{className:"documents-tab-count",children:H.length})]})]}),a==="project"&&e.jsxs("button",{className:"btn btn-sm documents-hidden-toggle",onClick:()=>k(t=>!t),"aria-pressed":p,"aria-label":p?"Hide hidden project files":"Show hidden project files",title:p?"Hide hidden files":"Show hidden files",children:[p?e.jsx(de,{size:14}):e.jsx(ue,{size:14}),p?"Hide Hidden":"Show Hidden"]}),e.jsxs("div",{className:"documents-search",children:[e.jsx(me,{size:16,className:"documents-search-icon"}),e.jsx("input",{type:"text",className:"documents-search-input",placeholder:G,value:l,onChange:Z,"aria-label":G}),l&&e.jsx("button",{className:"documents-search-clear",onClick:I,"aria-label":"Clear search",children:e.jsx(he,{size:16})})]})]})]}),e.jsx("div",{className:"documents-view-content",children:U?e.jsxs("div",{className:"documents-view-error",children:[e.jsxs("p",{children:["Failed to load ",a==="project"?"project files":"task documents",": ",U]}),e.jsxs("button",{className:"btn btn-primary",onClick:()=>void ae(),"aria-label":"Retry loading documents",children:[e.jsx(pe,{size:16}),"Retry"]})]}):a==="project"?$&&S.length===0?e.jsx("div",{className:"documents-view-loading",children:e.jsx("p",{children:"Loading project markdown files…"})}):A.length===0?e.jsx("div",{className:"documents-view-empty",children:l.trim()?e.jsxs("p",{children:['No project markdown files match "',l.trim(),'".']}):e.jsxs(e.Fragment,{children:[e.jsx(z,{size:48,className:"documents-view-empty-icon"}),e.jsx("p",{children:"No Markdown files found in this project."})]})}):e.jsxs("div",{className:`documents-project-layout${E?" documents-project-layout--mobile":""}`,children:[(!E||!i)&&e.jsx("aside",{className:"documents-view-sidebar","aria-label":"Project markdown files",children:e.jsx("ul",{className:"markdown-file-list",children:A.map(t=>{const r=i?.path===t.path;return e.jsx("li",{className:"markdown-file-list-item",children:e.jsxs("button",{className:`markdown-file-item${r?" markdown-file-item--selected":""}`,onClick:()=>void se(t),"aria-label":`Open ${t.path}`,"aria-current":r?"true":void 0,children:[e.jsx("span",{className:"markdown-file-item-name",children:t.name}),e.jsx("span",{className:"markdown-file-item-path",children:t.path}),e.jsxs("span",{className:"markdown-file-item-meta",children:[ge(t.size)," · ",_(t.mtime)]})]})},t.path)})})}),(!E||i)&&e.jsxs("section",{className:"documents-view-main","aria-label":"Project file content preview",children:[E&&i&&e.jsxs("button",{className:"btn btn-sm documents-mobile-back",onClick:te,"aria-label":"Back to project files list",children:[e.jsx(fe,{size:14}),"Back to files"]}),i?e.jsxs("div",{className:"documents-content-viewer",children:[e.jsxs("div",{className:"documents-content-header",children:[e.jsx("p",{className:"documents-file-path-header",children:i.path}),e.jsx("button",{className:"btn btn-sm document-mode-toggle",onClick:()=>R(t=>!t),"aria-label":F?"Switch to plain text":"Switch to markdown","aria-pressed":F,title:F?"Switch to plain text":"Switch to markdown",children:F?"Markdown":"Plain"})]}),g?e.jsx("p",{className:"documents-content-state",children:"Loading file content…"}):j?e.jsx("p",{className:"documents-content-state documents-content-state--error",children:j}):F?e.jsx("div",{className:"documents-content-markdown",children:e.jsx("div",{className:"markdown-body",children:e.jsx(W,{remarkPlugins:[V],children:b??""})})}):e.jsx("pre",{className:"document-card-content-text documents-content-viewer-text",children:b??""})]}):e.jsx("div",{className:"documents-view-empty",children:e.jsx("p",{children:"Select a Markdown file to view its content."})})]})]}):D&&N.length===0?e.jsx("div",{className:"documents-view-loading",children:e.jsx("p",{children:"Loading task documents…"})}):H.length===0?e.jsx("div",{className:"documents-view-empty",children:l.trim()?e.jsxs("p",{children:['No task documents match "',l.trim(),'".']}):e.jsxs(e.Fragment,{children:[e.jsx(z,{size:48,className:"documents-view-empty-icon"}),e.jsx("p",{children:"No task documents yet."}),e.jsx("p",{className:"documents-view-empty-hint",children:"Documents are created in task detail tabs."})]})}):e.jsx("div",{className:"documents-task-list-wrap",children:e.jsx("div",{className:"documents-view-list",children:H.map(({taskId:t,taskTitle:r,documents:d})=>e.jsx(Se,{taskId:t,taskTitle:r,documents:d,onOpenTask:ee,renderMarkdownStates:M,onToggleMarkdown:ne},t))})})})]})}export{ye as DocumentsView};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{u as Le}from"./SettingsModal-4Z8ZJMzD.js";import{bw as Ee,bx as ke,by as Ie,H as Re,bz as qe,bA as _e,bB as Pe,bC as Me,bD as we,bE as We,bF as Oe,bG as Te,bH as Ae,bI as $e,E as He,bJ as Ue,L as w,bK as Fe}from"./index-k_85J1DS.js";import"./vendor-xterm-DzcZoU0P.js";const O=".fusion/memory/MEMORY.md",Qe=5e4,Ye="0 3 * * *",Be="0 4 * * *";function he(i){return{memoryEnabled:i.memoryEnabled!==!1,memoryAutoSummarizeEnabled:i.memoryAutoSummarizeEnabled??!1,memoryAutoSummarizeThresholdChars:i.memoryAutoSummarizeThresholdChars??Qe,memoryAutoSummarizeSchedule:i.memoryAutoSummarizeSchedule??Ye,memoryDreamsEnabled:i.memoryDreamsEnabled??!1,memoryDreamsSchedule:i.memoryDreamsSchedule??Be}}function De(i,t){return i.some(m=>m.path===t)?t:i.find(m=>m.path===O)?.path??i[0]?.path??O}function Ge(i={}){const{projectId:t}=i,[m,u]=a.useState(""),[C,A]=a.useState(!0),[E,k]=a.useState(!1),[b,x]=a.useState(!1),[r,p]=a.useState(null),[T,J]=a.useState(!0),[X,L]=a.useState(!1),[S,P]=a.useState(()=>he({})),[F,ee]=a.useState(!0),[ue,$]=a.useState(!1),[o,v]=a.useState([]),[se,I]=a.useState(!0),[c,M]=a.useState(O),[W,y]=a.useState(""),[d,te]=a.useState(!1),[H,f]=a.useState(!1),[ae,U]=a.useState(!1),[ne,Q]=a.useState(!1),[Y,re]=a.useState(!1),[D,z]=a.useState(null),[ye,R]=a.useState(!0),[ge,B]=a.useState(!1),[ie,G]=a.useState(!1),[le,V]=a.useState(null),{status:me,loading:K,refresh:j}=Le({projectId:t}),be=a.useCallback(n=>{y(n),f(!0)},[]),N=a.useCallback(async n=>{te(!0);try{const{content:l}=await Ee(n,t);M(n),y(l),f(!1)}finally{te(!1)}},[t]),q=a.useCallback(async()=>{I(!0);try{const{files:n}=await ke(t);if(v(n),n.length===0){M(O),y(""),f(!1);return}const l=De(n,c);l!==c&&await N(l)}finally{I(!1)}},[t,c,N]);a.useEffect(()=>{let n=!1;async function l(){try{const s=await $e(t);n||(u(s.content),A(!1))}catch{n||(u(""),A(!1))}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){try{const s=await we(t);n||(p(s.content),L(s.exists),J(!1))}catch{n||(p(null),L(!1),J(!1))}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){ee(!0);try{const s=await He(t);n||P(he(s))}catch{n||P(he({}))}finally{n||ee(!1)}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){I(!0);try{const{files:s}=await ke(t);if(n)return;if(v(s),s.length===0){M(O),y(""),f(!1);return}const h=De(s,c),{content:g}=await Ee(h,t);if(n)return;M(h),y(g),f(!1)}catch{n||(v([]),M(O),y(""),f(!1))}finally{n||I(!1)}}return l(),()=>{n=!0}},[t,c]),a.useEffect(()=>{let n=!1;async function l(){try{const s=await Me(t);n||(z(s),R(!1))}catch{n||(z(null),R(!1))}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){try{const s=await Ue(t);n||V(s)}catch{n||V(null)}}return l(),()=>{n=!0}},[t]);const ce=a.useCallback(n=>{u(n),k(!0)},[]),oe=a.useCallback(async()=>{if(E){x(!0);try{await Ie(m,t),k(!1)}finally{x(!1)}}},[m,E,t]),xe=a.useCallback(async n=>{$(!0);try{const l=await Re(n,t);P(he(l))}finally{$(!1)}},[t]),pe=a.useCallback(async n=>{await N(n)},[N]),fe=a.useCallback(async()=>{if(H){U(!0);try{await qe(c,W,t),f(!1),await q()}finally{U(!1)}}},[W,H,c,t,q]),je=a.useCallback(async()=>{G(!0);try{const n=await _e(t);return await j(),n}finally{G(!1)}},[t,j]),Se=a.useCallback(async n=>Pe(n,t),[t]),Z=a.useCallback(async()=>{try{const n=await Me(t);z(n)}catch{z(null)}},[t]),_=a.useCallback(async()=>{try{const n=await we(t);p(n.content),L(n.exists)}catch{p(null),L(!1)}},[t]),de=a.useCallback(async n=>{await We(n,t),await _()},[t,_]),ve=a.useCallback(async()=>{Q(!0);try{const n=await Oe(t);return await Promise.all([_(),Z()]),{success:n.success,summary:n.summary}}finally{Q(!1)}},[t,_,Z]),Ne=a.useCallback(async()=>{re(!0);try{return await Te(t)}finally{re(!1)}},[t]),Ce=a.useCallback(async n=>{B(!0);try{const l=n?await Ae(n,t):await Ae(t);if(n){const s=l.path??n;M(s),y(l.content),f(!1),await q();return}u(l.content),k(!0)}finally{B(!1)}},[t,q]);return{workingMemory:m,workingMemoryLoading:C,workingMemoryDirty:E,setWorkingMemory:ce,saveWorkingMemory:oe,savingWorkingMemory:b,insightsContent:r,insightsLoading:T,insightsExists:X,refreshInsights:_,saveInsights:de,memorySettings:S,settingsLoading:F,savingMemorySettings:ue,saveMemorySettings:xe,memoryFiles:o,memoryFilesLoading:se,selectedFilePath:c,selectedFileContent:W,selectedFileLoading:d,selectedFileDirty:H,setSelectedFileContent:be,selectFile:pe,saveSelectedFile:fe,savingSelectedFile:ae,reloadMemoryFiles:q,backendStatus:me,backendLoading:K,extractInsights:ve,extracting:ne,triggerDreamNow:Ne,dreamRunning:Y,auditReport:D,auditLoading:ye,refreshAudit:Z,compactMemory:Ce,compacting:ge,installQmdAction:je,installingQmd:ie,testRetrieval:Se,stats:le}}const Ve={Patterns:"pattern",Principles:"principle",Conventions:"convention",Pitfalls:"pitfall",Context:"context"},Ke={"long-term":"Long-term",daily:"Daily",dreams:"Dreams"},Ze={"long-term":"Curated durable decisions, conventions, constraints, and pitfalls promoted from dreams.",daily:"Raw daily observations, open loops, and running context for dream processing.",dreams:"Synthesized patterns and open loops promoted from daily memory."},Je=72;function Xe(i,t){if(i.length<=t)return i;const m=Math.max(1,t-1),u=Math.ceil(m/2),C=Math.floor(m/2);return`${i.slice(0,u)}…${i.slice(i.length-C)}`}function es(i){const t=`${i.label} — ${i.path}`;return Xe(t,Je)}function ss(i){if(!i)return[];const t=[],m=i.split(/(?=^## )/m);for(const u of m){const C=u.trim();if(!C)continue;const A=C.match(/^##\s+(.+?)(\n|$)/);if(A){const E=A[1].trim(),k=Ve[E]??E.toLowerCase(),b=C.slice(A[0].length).trim(),x=b.split(`
|
|
2
|
-
`).map(r=>r.replace(/^-\s+/,"").trim()).filter(r=>r.length>0&&(r.startsWith("- ")||r.startsWith("* ")));(x.length>0||b.length>0)&&t.push({name:E,key:k,items:x.length>0?x:b.length>0?[b]:[],expanded:!0})}}return t}function ts(i){if(!i)return null;const t=i.match(/##\s+Last\s+Updated:\s*(\d{4}-\d{2}-\d{2})/i);return t?t[1]:null}function as(i){return i.reduce((t,m)=>t+m.items.length,0)}function ns(i){switch(i){case"file":return"File (.fusion/memory/)";case"readonly":return"Read-Only";case"qmd":return"QMD (Quantized Memory Distillation)";default:return i}}function rs(i){switch(i){case"healthy":return"Healthy";case"warning":return"Warning";case"issues":return"Issues Found"}}function os({projectId:i,addToast:t}){const[m,u]=a.useState("working"),[C,A]=a.useState(new Set),[E,k]=a.useState(!1),[b,x]=a.useState(null),[r,p]=a.useState({memoryEnabled:!0,memoryAutoSummarizeEnabled:!1,memoryAutoSummarizeThresholdChars:5e4,memoryAutoSummarizeSchedule:"0 3 * * *",memoryDreamsEnabled:!1,memoryDreamsSchedule:"0 4 * * *"}),[T,J]=a.useState(""),[X,L]=a.useState(!1),[S,P]=a.useState(null),{insightsContent:F,insightsLoading:ee,insightsExists:ue,saveInsights:$,memorySettings:o,settingsLoading:v,saveMemorySettings:se,savingMemorySettings:I,backendStatus:c,backendLoading:M,extractInsights:W,extracting:y,auditReport:d,auditLoading:te,refreshAudit:H,compactMemory:f,compacting:ae,installQmdAction:U,installingQmd:ne,testRetrieval:Q,memoryFiles:Y,memoryFilesLoading:re,selectedFilePath:D,selectedFileContent:z,selectedFileLoading:ye,selectedFileDirty:R,setSelectedFileContent:ge,selectFile:B,saveSelectedFile:ie,savingSelectedFile:G,reloadMemoryFiles:le,triggerDreamNow:V,dreamRunning:me}=Ge({projectId:i});a.useEffect(()=>{p(o)},[o]);const K=a.useMemo(()=>r.memoryEnabled!==o.memoryEnabled||r.memoryAutoSummarizeEnabled!==o.memoryAutoSummarizeEnabled||r.memoryAutoSummarizeThresholdChars!==o.memoryAutoSummarizeThresholdChars||r.memoryAutoSummarizeSchedule!==o.memoryAutoSummarizeSchedule||r.memoryDreamsEnabled!==o.memoryDreamsEnabled||r.memoryDreamsSchedule!==o.memoryDreamsSchedule,[r,o]),j=a.useMemo(()=>Y.find(s=>s.path===D),[Y,D]),be=j?Ze[j.layer]:"Edits the selected memory file.",N=a.useMemo(()=>ss(F),[F]),q=a.useMemo(()=>as(N),[N]),ce=a.useMemo(()=>ts(F),[F]),oe=a.useCallback(s=>{A(h=>{const g=new Set(h);return g.has(s)?g.delete(s):g.add(s),g})},[]),xe=a.useCallback(async s=>{try{await B(s)}catch{t("Failed to load memory file","error")}},[B,t]),pe=a.useCallback(async()=>{try{await ie(),t("Memory saved","success")}catch{t("Failed to save memory","error")}},[ie,t]),fe=a.useCallback(async()=>{if(!K)return;const s={};r.memoryEnabled!==o.memoryEnabled&&(s.memoryEnabled=r.memoryEnabled),r.memoryAutoSummarizeEnabled!==o.memoryAutoSummarizeEnabled&&(s.memoryAutoSummarizeEnabled=r.memoryAutoSummarizeEnabled),r.memoryAutoSummarizeThresholdChars!==o.memoryAutoSummarizeThresholdChars&&(s.memoryAutoSummarizeThresholdChars=r.memoryAutoSummarizeThresholdChars),r.memoryAutoSummarizeSchedule!==o.memoryAutoSummarizeSchedule&&(s.memoryAutoSummarizeSchedule=r.memoryAutoSummarizeSchedule),r.memoryDreamsEnabled!==o.memoryDreamsEnabled&&(s.memoryDreamsEnabled=r.memoryDreamsEnabled),r.memoryDreamsSchedule!==o.memoryDreamsSchedule&&(s.memoryDreamsSchedule=r.memoryDreamsSchedule);try{await se(s),t("Memory settings saved","success")}catch{t("Failed to save memory settings","error")}},[K,r,o,se,t]),je=a.useCallback(async()=>{try{const s=await U();t(s.qmdAvailable?"qmd installed successfully":"qmd install finished, but qmd is still unavailable",s.qmdAvailable?"success":"info")}catch{t("Failed to install qmd","error")}},[U,t]),Se=a.useCallback(async()=>{L(!0),P(null);try{const s=await Q(T);P(s),t(s.qmdAvailable?"Memory retrieval test complete":"qmd is not installed; local fallback was used",s.qmdAvailable?"success":"info")}catch{t("Failed to test memory retrieval","error")}finally{L(!1)}},[T,Q,t]),Z=a.useCallback(async()=>{try{await V(),t("Dream processing completed","success"),await le()}catch(s){t(s instanceof Error?s.message:"Failed to run dream processing","error")}},[V,le,t]),_=a.useCallback(async()=>{try{await f(D),t("Memory file compacted","success")}catch{t("Failed to compact memory","error")}},[f,D,t]),de=a.useCallback(async()=>{try{const s=await W();t(s.summary,"success")}catch(s){t(s instanceof Error?s.message:"Failed to extract insights","error")}},[W,t]),ve=a.useCallback(async()=>{if(b!==null)try{await $(b),k(!1),x(null),t("Insights saved","success")}catch{t("Failed to save insights","error")}},[b,$,t]),Ne=a.useCallback(()=>{x(F??""),k(!0)},[F]),Ce=a.useCallback(()=>{k(!1),x(null)},[]),n=!M&&c!==null,l=c?.capabilities?.writable??!1;return e.jsxs("div",{className:"memory-view",children:[e.jsx("div",{className:"memory-view-header",children:e.jsxs("div",{children:[e.jsx("h2",{children:"Memory"}),e.jsx("p",{className:"memory-view-description",children:"Working memory, long-term insights, and engine status"})]})}),e.jsxs("div",{className:"memory-view-tabs",role:"tablist",children:[e.jsx("button",{type:"button",role:"tab","aria-selected":m==="working",className:`memory-view-tab${m==="working"?" memory-view-tab--active":""}`,onClick:()=>u("working"),"data-testid":"memory-tab-working",children:"Working Memory"}),e.jsx("button",{type:"button",role:"tab","aria-selected":m==="insights",className:`memory-view-tab${m==="insights"?" memory-view-tab--active":""}`,onClick:()=>u("insights"),"data-testid":"memory-tab-insights",children:"Insights"}),e.jsx("button",{type:"button",role:"tab","aria-selected":m==="engines",className:`memory-view-tab${m==="engines"?" memory-view-tab--active":""}`,onClick:()=>u("engines"),"data-testid":"memory-tab-engines",children:"Engines"})]}),e.jsxs("div",{className:"memory-view-content",children:[m==="working"&&e.jsxs("div",{className:"memory-working-tab",children:[n&&!l&&e.jsx("div",{className:"memory-readonly-banner",children:"This memory backend is read-only. Changes cannot be saved."}),re||ye?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading memory file…"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-editor-section",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryViewFilePath",children:"Memory File"}),e.jsx("select",{id:"memoryViewFilePath",className:"select",value:D,onChange:s=>{xe(s.target.value)},disabled:R,children:Y.map(s=>e.jsx("option",{value:s.path,title:`${s.label} — ${s.path}`,children:es(s)},s.path))}),e.jsx("small",{children:R?"Save or discard the current edits before switching files.":"Choose any project memory file to view or edit."})]}),j&&e.jsxs("div",{className:"memory-file-summary",children:[e.jsx("span",{children:Ke[j.layer]}),e.jsx("strong",{children:j.path}),e.jsxs("small",{children:[j.size.toLocaleString()," bytes · updated ",new Date(j.updatedAt).toLocaleString()]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:j?.label||"Memory Editor"}),e.jsx("small",{children:be}),e.jsx("div",{className:"memory-editor-container",children:e.jsx(Fe,{content:z,onChange:ge,readOnly:!l,filePath:D})})]})]}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsxs("span",{className:"memory-char-count",children:[z.length," characters"]}),e.jsx("div",{className:"memory-flex-spacer"}),l&&z.length>0&&e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:_,disabled:ae||R,children:ae?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Compacting…"]}):"Compact Selected File"}),R&&l&&e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:pe,disabled:G,children:G?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Saving…"]}):"Save"})]}),e.jsxs("div",{className:"memory-config-section",children:[e.jsxs("div",{className:"memory-settings-group",children:[e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryDreamsEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryDreamsEnabled",type:"checkbox",checked:r.memoryDreamsEnabled,onChange:s=>{p(h=>({...h,memoryDreamsEnabled:s.target.checked}))},disabled:!r.memoryEnabled||v}),"Process dreams from daily memory"]}),e.jsx("small",{children:"Turns daily notes into DREAMS.md and promotes reusable lessons into MEMORY.md."})]}),r.memoryEnabled&&r.memoryDreamsEnabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryDreamsSchedule",children:"Dream Schedule"}),e.jsx("input",{id:"memoryDreamsSchedule",type:"text",className:"input",value:r.memoryDreamsSchedule,onChange:s=>{p(h=>({...h,memoryDreamsSchedule:s.target.value}))},placeholder:"0 4 * * *",disabled:v}),e.jsx("small",{children:"Cron expression for dream processing."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:Z,disabled:me||!r.memoryDreamsEnabled,children:me?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Dreaming…"]}):"Dream Now"}),e.jsx("small",{children:"Manually trigger dream processing now."})]})]})]}),e.jsxs("div",{className:"memory-settings-group",children:[e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryAutoSummarizeEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryAutoSummarizeEnabled",type:"checkbox",checked:r.memoryAutoSummarizeEnabled,onChange:s=>{p(h=>({...h,memoryAutoSummarizeEnabled:s.target.checked}))},disabled:!r.memoryEnabled||v}),"Auto-Summarize Memory"]}),e.jsx("small",{children:"Automatically compact memory when it exceeds the threshold on a schedule"})]}),r.memoryEnabled&&r.memoryAutoSummarizeEnabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeThresholdChars",children:"Compaction Threshold (chars)"}),e.jsx("input",{id:"memoryAutoSummarizeThresholdChars",type:"number",className:"input",value:r.memoryAutoSummarizeThresholdChars,onChange:s=>{p(h=>({...h,memoryAutoSummarizeThresholdChars:parseInt(s.target.value,10)||5e4}))},min:1e3,disabled:v}),e.jsx("small",{children:"Memory will be compacted when it exceeds this character count"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeSchedule",children:"Schedule (cron)"}),e.jsx("input",{id:"memoryAutoSummarizeSchedule",type:"text",className:"input",value:r.memoryAutoSummarizeSchedule,onChange:s=>{p(h=>({...h,memoryAutoSummarizeSchedule:s.target.value}))},placeholder:"0 3 * * *",disabled:v}),e.jsx("small",{children:"Cron expression for auto-summarize schedule (default: daily at 3 AM)"})]})]})]}),!r.memoryEnabled&&e.jsx("div",{className:"settings-empty-state memory-status-message",children:"Memory is currently disabled. Enable memory tools in Settings to edit these automations."}),K&&e.jsx("div",{className:"memory-action-bar",children:e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:fe,disabled:I||v,children:I?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Saving…"]}):"Save Settings"})})]})]})]}),m==="insights"&&e.jsx("div",{className:"memory-insights-tab",children:ee?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading insights…"})]}):E?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"memory-editor-container",children:e.jsx(Fe,{content:b??"",onChange:x,readOnly:!1,filePath:".fusion/memory/INSIGHTS.md"})}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Ce,children:"Cancel"}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:ve,children:"Save Insights"})]})]}):!ue||N.length===0?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx("p",{children:"No insights extracted yet."}),e.jsx("p",{children:'Insights are automatically extracted from working memory. Click "Extract Now" to trigger extraction manually.'}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm memory-empty-extract-button",onClick:de,disabled:y,children:y?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Extracting…"]}):"Extract Now"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-stats-row",children:[e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value",children:q}),e.jsx("div",{className:"memory-stat-label",children:"Total Insights"})]}),e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value",children:N.length}),e.jsx("div",{className:"memory-stat-label",children:"Categories"})]}),ce&&e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value memory-stat-value--updated",children:ce}),e.jsx("div",{className:"memory-stat-label",children:"Last Updated"})]})]}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:de,disabled:y,children:y?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Extracting…"]}):"Extract Now"}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Ne,children:"Edit Raw"})]}),e.jsx("div",{className:"memory-categories-list",children:N.map(s=>{const h=!C.has(s.key);return e.jsxs("div",{className:"memory-category-section",children:[e.jsxs("div",{className:"memory-category-header",onClick:()=>oe(s.key),role:"button",tabIndex:0,onKeyDown:g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),oe(s.key))},children:[e.jsx("h4",{children:s.name}),e.jsx("span",{className:"memory-category-count",children:s.items.length})]}),h&&e.jsx("div",{className:"memory-category-items",children:s.items.map((g,ze)=>e.jsx("div",{className:"memory-insight-item",children:g.replace(/^-\s+/,"").replace(/^\*\s+/,"")},ze))})]},s.key)})})]})}),m==="engines"&&e.jsx("div",{className:"memory-engines-tab",children:M||te?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading engine status…"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-engine-card memory-qmd-card",children:[e.jsx("h3",{children:"QMD Integration"}),c?.qmdAvailable===!0?e.jsxs("div",{className:"memory-engine-status",children:[e.jsx("span",{className:"memory-health-badge memory-health-badge--healthy",children:"Installed"}),e.jsx("span",{className:"memory-char-count",children:"qmd is available on PATH."})]}):c?.qmdAvailable===!1?e.jsxs("div",{className:"settings-empty-state memory-status-message",children:[e.jsxs("span",{children:["qmd is not installed. Search will use local files. Install indexed retrieval: ",e.jsx("code",{children:c.qmdInstallCommand||"bun install -g @tobilu/qmd"})]}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:je,disabled:ne,children:ne?"Installing…":"Install qmd"})]}):e.jsxs("div",{className:"memory-engine-status",children:[e.jsx("span",{className:"memory-health-badge",children:"Checking"}),e.jsx("span",{className:"memory-char-count",children:"Checking qmd availability…"})]}),e.jsxs("div",{className:"memory-capability-row",children:[c?.capabilities?.readable&&e.jsx("span",{className:"memory-capability-badge",children:"Readable"}),c?.capabilities?.writable&&e.jsx("span",{className:"memory-capability-badge",children:"Writable"}),c?.capabilities?.supportsAtomicWrite&&e.jsx("span",{className:"memory-capability-badge",children:"Atomic Writes"}),c?.capabilities?.persistent&&e.jsx("span",{className:"memory-capability-badge",children:"Persistent"})]})]}),e.jsxs("div",{className:"memory-engine-card memory-retrieval-card",children:[e.jsx("h3",{children:"Test Memory Search"}),e.jsxs("div",{className:"memory-retrieval-input-row",children:[e.jsx("input",{type:"text",className:"input",value:T,onChange:s=>J(s.target.value),placeholder:"Search memory with qmd"}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Se,disabled:X,children:X?"Testing…":"Test Retrieval"})]}),e.jsx("small",{className:"settings-muted",children:"Runs the same qmd-backed memory_search path agents use."}),S&&e.jsxs("div",{className:"memory-test-result",children:[e.jsxs("strong",{children:[S.results.length," result",S.results.length===1?"":"s"," ",'for "',S.query,'"']}),e.jsxs("small",{children:["qmd ",S.qmdAvailable?"available":"missing"," · ",S.usedFallback?"local fallback used":"qmd path used"]}),S.results.length>0?e.jsx("ul",{children:S.results.map((s,h)=>e.jsxs("li",{children:[e.jsxs("span",{children:[s.path,":",s.lineStart]}),e.jsx("p",{children:s.snippet})]},`${s.path}-${s.lineStart}-${h}`))}):e.jsx("small",{children:"No matching memory found."})]})]}),e.jsxs("div",{className:"memory-engine-card",children:[e.jsx("h3",{children:"Current Backend"}),e.jsx("div",{className:"memory-engine-status",children:e.jsx("span",{className:"memory-emphasis-text",children:ns(c?.currentBackend??"unknown")})}),e.jsxs("div",{className:"memory-capability-row",children:[c?.capabilities?.readable&&e.jsx("span",{className:"memory-capability-badge",children:"Readable"}),c?.capabilities?.writable&&e.jsx("span",{className:"memory-capability-badge",children:"Writable"}),c?.capabilities?.supportsAtomicWrite&&e.jsx("span",{className:"memory-capability-badge",children:"Atomic Writes"}),c?.capabilities?.persistent&&e.jsx("span",{className:"memory-capability-badge",children:"Persistent"})]})]}),d&&e.jsxs("div",{className:"memory-engine-card",children:[e.jsxs("div",{className:"memory-health-header",children:[e.jsx("h3",{children:"Health Status"}),e.jsx("span",{className:`memory-health-badge memory-health-badge--${d.health}`,children:rs(d.health)})]}),e.jsxs("div",{className:"memory-health-grid",children:[e.jsxs("div",{children:[e.jsx("div",{className:"memory-health-label",children:"Working Memory"}),e.jsxs("div",{className:"memory-emphasis-text",children:[d.workingMemory.size," chars"]}),e.jsxs("div",{className:"memory-health-detail",children:[d.workingMemory.sectionCount," sections"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"memory-health-label",children:"Insights Memory"}),e.jsxs("div",{className:"memory-emphasis-text",children:[d.insightsMemory.size," chars"]}),e.jsxs("div",{className:"memory-health-detail",children:[d.insightsMemory.insightCount," insights"]})]})]}),e.jsxs("div",{className:"memory-health-section",children:[e.jsx("div",{className:"memory-health-label",children:"Last Extraction"}),e.jsx("div",{className:"memory-emphasis-text",children:d.extraction.success?e.jsx("span",{className:"memory-status-text memory-status-text--success",children:"Success"}):e.jsx("span",{className:"memory-status-text memory-status-text--error",children:"Failed"})}),e.jsx("div",{className:"memory-health-detail",children:d.extraction.summary||`${d.extraction.insightCount} insights extracted`})]}),e.jsxs("div",{className:"memory-health-section",children:[e.jsx("div",{className:"memory-health-label",children:"Pruning"}),e.jsx("div",{className:"memory-emphasis-text",children:d.pruning.applied?e.jsx("span",{className:"memory-status-text memory-status-text--warning",children:"Applied"}):e.jsx("span",{className:"memory-status-text memory-status-text--muted",children:"Not needed"})}),d.pruning.applied&&e.jsx("div",{className:"memory-health-detail",children:d.pruning.reason})]})]}),d&&d.checks.length>0&&e.jsxs("div",{className:"memory-engine-card",children:[e.jsx("h3",{children:"Audit Checks"}),e.jsx("div",{children:d.checks.map(s=>e.jsxs("div",{className:"memory-audit-check",children:[e.jsx("span",{className:s.passed?"memory-audit-check-passed":"memory-audit-check-failed",children:s.passed?"✓":"✗"}),e.jsxs("div",{className:"memory-audit-check-content",children:[e.jsx("div",{className:"memory-emphasis-text",children:s.name}),e.jsx("div",{className:"memory-health-detail",children:s.details})]})]},s.id))})]}),e.jsx("div",{className:"memory-action-bar",children:e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:()=>H(),children:"Run Audit"})}),e.jsxs("div",{className:"memory-settings-note",children:[e.jsx("span",{children:"Note: Change backend type in"}),e.jsx("button",{type:"button",className:"memory-settings-note-button",onClick:()=>{t("Open Settings → Memory to change backend type","info")},children:"Settings → Memory"})]})]})})]})]})}export{os as MemoryView};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{c as pe,aD as we,aE as Pe,aF as Me,aG as Ee,aH as ye,aI as be,A as je,aJ as Re,W as Ae,aK as De,aL as Le,_ as ie,u as $e,R as de,a as Ne,O as ee,aM as _e,aN as Ke,aO as ze,X as ue,aP as xe,aQ as Ie,aR as Fe,aS as Oe,G as Ve}from"./index-k_85J1DS.js";import{U as ve}from"./upload-DsAS6tno.js";import"./vendor-xterm-DzcZoU0P.js";/**
|
|
2
|
-
* @license lucide-react v1.7.0 - ISC
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the ISC license.
|
|
5
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const Ue=[["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"}]],Be=pe("wifi-off",Ue);/**
|
|
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 He=[["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"}]],Te=pe("wifi",He);function re(t){const{lastSyncAt:l,remoteReachable:a,diff:i}=t,u=i.global.length+i.project.length;return l===null?{syncState:"never-synced",lastSyncAt:l,diffCount:0}:a?u>0?{syncState:"diff",lastSyncAt:l,diffCount:u}:{syncState:"synced",lastSyncAt:l,diffCount:0}:{syncState:"error",lastSyncAt:l,diffCount:u}}function ke(t){if(t===null)return"Never synced";const l=new Date(t);if(Number.isNaN(l.getTime()))return"Never synced";const i=Date.now()-l.getTime(),u=Math.floor(i/1e3),h=Math.floor(u/60),o=Math.floor(h/60),f=Math.floor(o/24);return h<1?"Synced just now":h<60?`Synced ${h}m ago`:o<24?`Synced ${o}h ago`:`Synced ${f}d ago`}function qe(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 Je=3e4;function Xe(){const[t,l]=s.useState({}),[a,i]=s.useState(!1),[u,h]=s.useState({}),[o,f]=s.useState(null),c=s.useRef(new Set),y=s.useRef(!1),p=s.useRef(null),N=s.useRef(null),C=s.useCallback(async(m,r)=>{try{const b=await we(m);l(z=>({...z,[m]:b})),f(null)}catch(b){console.error(`Failed to fetch sync status for node ${m}:`,b),f(b instanceof Error?b.message:"Failed to fetch sync status")}},[]),v=s.useCallback(async()=>{const m=Array.from(c.current);if(m.length===0)return;p.current&&p.current.abort(),p.current=new AbortController;const r=!y.current;r&&i(!0),f(null);try{const b=await Promise.allSettled(m.map(F=>C(F,r)));y.current=!0,b.filter(F=>F.status==="rejected").length>0&&f("Some sync status requests failed")}catch(b){if(b instanceof Error&&b.name==="AbortError")return;f(b instanceof Error?b.message:"Failed to fetch sync status"),y.current=!0}finally{i(!1)}},[C]),P=s.useCallback(()=>{N.current&&clearInterval(N.current),N.current=setInterval(()=>{v()},Je)},[v]),j=s.useCallback(()=>{N.current&&(clearInterval(N.current),N.current=null)},[]);s.useEffect(()=>(v(),P(),()=>{j(),p.current&&p.current.abort()}),[v,P,j]);const n=s.useCallback(m=>{c.current.has(m)||(c.current.add(m),C(m,!y.current))},[C]),x=s.useCallback(m=>{c.current.delete(m),l(r=>{const b={...r};return delete b[m],b}),c.current.size===0&&j()},[j]),g=s.useCallback(async m=>{h(r=>({...r,[m]:!0})),f(null);try{const r=await Pe(m);return C(m,!1),!r.success&&r.error&&f(r.error),r}catch(r){const b=r instanceof Error?r.message:"Push settings failed";throw f(b),r}finally{h(r=>{const b={...r};return delete b[m],b})}},[C]),M=s.useCallback(async m=>{h(r=>({...r,[m]:!0})),f(null);try{const r=await Me(m);return C(m,!1),!r.success&&r.error&&f(r.error),r}catch(r){const b=r instanceof Error?r.message:"Pull settings failed";throw f(b),r}finally{h(r=>{const b={...r};return delete b[m],b})}},[C]),R=s.useCallback(async m=>{h(r=>({...r,[m]:!0})),f(null);try{return await Ee(m)}catch(r){const b=r instanceof Error?r.message:"Auth sync failed";throw f(b),r}finally{h(r=>{const b={...r};return delete b[m],b})}},[]),E=s.useCallback(m=>t[m]?.authMatch,[t]),D=s.useCallback(m=>t[m]?.authDiff,[t]);return{syncStatusMap:t,loading:a,actionLoading:u,error:o,refresh:v,trackNode:n,untrackNode:x,pushSettings:g,pullSettings:M,syncAuth:R,getAuthSyncState:E,getAuthProviders:D}}function Ge(t,l){return l.type==="remote"?t.nodeId===l.id:t.nodeId===l.id||t.nodeId===void 0||t.nodeId===null}function Ce(t,l){return t.filter(a=>Ge(a,l))}function me(t,l){return Ce(t,l).length}const We={online:{label:"Online",color:"var(--color-success)",className:"node-card__status--online"},offline:{label:"Offline",color:"var(--color-error)",className:"node-card__status--offline"},connecting:{label:"Connecting",color:"var(--color-warning)",className:"node-card__status--connecting"},error:{label:"Error",color:"var(--color-error)",className:"node-card__status--error"}},Ye={match:"var(--color-success)",differs:"var(--color-warning)","not-synced":"var(--text-muted)"};function Qe(t,l){if(t==="match")return"Auth credentials match";if(t==="not-synced")return"Auth not synced";if(l&&Object.keys(l).length>0){const a=Object.entries(l).filter(([,i])=>i==="differs").map(([i])=>i);if(a.length>0)return`Auth credentials differ: ${a.join(", ")}`}return"Auth credentials differ"}function Ze(t,l=42){return t.length<=l?t:`${t.slice(0,l-3)}...`}function es(t,l){const a=t.node,i=l.node;if(a.id!==i.id||a.name!==i.name||a.type!==i.type||a.url!==i.url||a.status!==i.status||a.maxConcurrent!==i.maxConcurrent||a.updatedAt!==i.updatedAt||t.isLoading!==l.isLoading)return!1;const u=t.syncStatus,h=l.syncStatus;if(!(!u&&!h)){if(!u||!h)return!1;if(u.syncState!==h.syncState||u.lastSyncAt!==h.lastSyncAt||u.diffCount!==h.diffCount)return!1}if(t.authSyncState!==l.authSyncState)return!1;const o=t.authSyncProviders,f=l.authSyncProviders;if(o!==f){if(!o||!f)return!1;{const p=Object.keys(o),N=Object.keys(f);if(p.length!==N.length||p.some(C=>o[C]!==f[C]))return!1}}const c=me(t.projects,a),y=me(l.projects,i);return c===y}function ss({node:t,projects:l,onHealthCheck:a,onEdit:i,onRemove:u,isLoading:h=!1,syncStatus:o,authSyncState:f,authSyncProviders:c}){const[y,p]=s.useState(!1),N=We[t.status],C=s.useMemo(()=>me(l,t),[l,t]),v=s.useCallback(()=>{i(t)},[i,t]),P=s.useCallback(g=>{g.stopPropagation(),a(t.id)},[a,t.id]),j=s.useCallback(g=>{g.stopPropagation(),i(t)},[i,t]),n=s.useCallback(g=>{if(g.stopPropagation(),!y){p(!0);return}u(t.id),p(!1)},[y,u,t.id]),x=s.useCallback(g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),i(t))},[i,t]);return e.jsxs("article",{className:`node-card ${h?"node-card--loading":""}`,"data-node-id":t.id,role:"button",tabIndex:0,onClick:v,onKeyDown:x,children:[e.jsx("header",{className:"node-card__header",children:e.jsxs("div",{className:"node-card__title-wrap",children:[e.jsx("div",{className:"node-card__icon",children:e.jsx(ye,{size:18})}),e.jsxs("div",{children:[e.jsx("h3",{className:"node-card__name",title:t.name,children:t.name}),e.jsxs("div",{className:"node-card__meta-row",children:[e.jsx("span",{className:"node-card__type-badge",children:t.type==="local"?"Local":"Remote"}),e.jsxs("span",{className:`node-card__status ${N.className}`,style:{color:N.color},"data-status":t.status,children:[e.jsx("span",{className:"node-card__status-indicator",style:{backgroundColor:N.color},"aria-hidden":!0}),N.label]}),t.type==="remote"&&f&&e.jsx("span",{className:`node-card__auth-indicator node-card__auth-indicator--${f}`,title:Qe(f,c),"aria-label":`Auth sync: ${f==="match"?"credentials match":f==="differs"?"credentials differ":"not synced"}`,style:{color:Ye[f]},children:e.jsx(be,{size:14})})]})]})]})}),e.jsxs("div",{className:"node-card__body",children:[t.type==="remote"&&t.url&&e.jsx("div",{className:"node-card__url",title:t.url,children:Ze(t.url)}),e.jsxs("div",{className:"node-card__metrics",children:[e.jsxs("div",{className:"node-card__metric",children:[e.jsx("span",{className:"node-card__metric-label",children:"Projects"}),e.jsx("span",{className:"node-card__metric-value",children:C})]}),e.jsxs("div",{className:"node-card__metric",children:[e.jsx("span",{className:"node-card__metric-label",children:"Concurrency"}),e.jsx("span",{className:"node-card__metric-value",children:t.maxConcurrent})]})]}),t.type==="remote"&&o&&e.jsxs("div",{className:"node-card__sync","data-sync-state":o.syncState,"data-testid":"node-card-sync",children:[e.jsx("span",{className:"node-card__sync-dot",style:{backgroundColor:qe(o.syncState)},"aria-hidden":!0}),e.jsx("span",{className:"node-card__sync-time",children:ke(o.lastSyncAt)})]})]}),e.jsxs("footer",{className:"node-card__actions",children:[e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:P,disabled:h,"aria-label":"Run node health check",title:"Health Check",children:[e.jsx(je,{size:14}),e.jsx("span",{children:"Health"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:j,disabled:h,"aria-label":"Edit node",title:"Edit",children:[e.jsx(Re,{size:14}),e.jsx("span",{children:"Edit"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:j,disabled:h,"aria-label":"Start node container",title:"Start Container",children:[e.jsx(Ae,{size:14}),e.jsx("span",{children:"Start"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:j,disabled:h,"aria-label":"Stop node container",title:"Stop Container",children:[e.jsx(De,{size:14}),e.jsx("span",{children:"Stop"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:j,disabled:h,"aria-label":"Restart node container",title:"Restart Container",children:[e.jsx(Le,{size:14}),e.jsx("span",{children:"Restart"})]}),e.jsxs("button",{className:`btn btn-sm node-card__action node-card__action--remove ${y?"btn-danger is-armed":""}`,type:"button",onClick:n,disabled:h,"aria-label":y?"Confirm remove node":"Remove node",title:y?"Confirm remove":"Remove",children:[e.jsx(ie,{size:14}),e.jsx("span",{children:y?"Confirm":"Remove"})]})]})]})}const ts=s.memo(ss,es),W={online:"var(--success, var(--color-success))",offline:"var(--text-dim)",connecting:"var(--triage)",error:"var(--color-error)"},G=28,ge=12,as=300,ns=120;function ls({nodes:t,className:l}){const a=s.useMemo(()=>t.find(c=>c.type==="local")??t[0],[t]),i=s.useMemo(()=>t.filter(c=>c.type==="remote"),[t]),u=s.useMemo(()=>{const c=as,y=Math.max(0,i.length-4)*20;return c+y},[i.length]),h=u/2,o=u/2,f=s.useMemo(()=>{if(i.length===0)return[];const c=Math.min(ns,u/2-G-10),y=2*Math.PI/i.length,p=-Math.PI/2;return i.map((N,C)=>{const v=p+C*y;return{node:N,x:h+c*Math.cos(v),y:o+c*Math.sin(v)}})},[i,u,h,o]);return t.length===0?e.jsx("div",{className:`mesh-topology mesh-topology--empty ${l??""}`,children:e.jsx("div",{className:"mesh-topology__empty-state",children:e.jsx("p",{children:"No nodes to display"})})}):e.jsxs("div",{className:`mesh-topology ${l??""}`,children:[e.jsxs("svg",{className:"mesh-topology__svg",viewBox:`0 0 ${u} ${u}`,preserveAspectRatio:"xMidYMid meet","aria-label":"Node mesh topology visualization",children:[f.map(c=>e.jsx("line",{className:"mesh-topology__link",x1:h,y1:o,x2:c.x,y2:c.y},`link-${c.node.id}`)),a&&e.jsxs("g",{className:"mesh-topology__node",transform:`translate(${h}, ${o})`,children:[e.jsx("circle",{className:"mesh-topology__node-circle",r:G,fill:W[a.status],"aria-label":`${a.name} (${a.status})`}),e.jsx("text",{className:"mesh-topology__node-label",y:G+ge,textAnchor:"middle",children:a.name.length>12?`${a.name.slice(0,10)}…`:a.name}),e.jsxs("g",{className:"mesh-topology__node-type",transform:`translate(0 ${-G-10})`,children:[e.jsx("circle",{className:"mesh-topology__node-type-badge",r:"8"}),e.jsx("text",{className:"mesh-topology__node-type-text",textAnchor:"middle",dominantBaseline:"middle",children:a.type==="local"?"L":"R"})]})]}),f.map(c=>e.jsxs("g",{className:"mesh-topology__node",transform:`translate(${c.x}, ${c.y})`,children:[e.jsx("circle",{className:"mesh-topology__node-circle",r:G,fill:W[c.node.status],"aria-label":`${c.node.name} (${c.node.status})`}),e.jsx("text",{className:"mesh-topology__node-label",y:G+ge,textAnchor:"middle",children:c.node.name.length>12?`${c.node.name.slice(0,10)}…`:c.node.name}),e.jsxs("g",{className:"mesh-topology__node-type",transform:`translate(0 ${-G-10})`,children:[e.jsx("circle",{className:"mesh-topology__node-type-badge",r:"8"}),e.jsx("text",{className:"mesh-topology__node-type-text",textAnchor:"middle",dominantBaseline:"middle",children:c.node.type==="local"?"L":"R"})]})]},c.node.id))]}),e.jsxs("div",{className:"mesh-topology__legend",children:[e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:W.online}}),e.jsx("span",{children:"Online"})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:W.offline}}),e.jsx("span",{children:"Offline"})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:W.connecting}}),e.jsx("span",{children:"Connecting"})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:W.error}}),e.jsx("span",{children:"Error"})]})]}),e.jsx("p",{className:"mesh-topology__notice",children:"Peer-to-peer discovery data unavailable."})]})}const rs=s.memo(ls),he=1,fe=10;function os(t){const l={};return t.name.trim()||(l.name="Name is required"),t.type==="remote"&&!t.url?.trim()&&(l.url="URL is required for remote nodes"),(!Number.isFinite(t.maxConcurrent)||t.maxConcurrent<he||t.maxConcurrent>fe)&&(l.maxConcurrent=`Concurrency must be between ${he} and ${fe}`),l}function cs({isOpen:t,onClose:l,onSubmit:a,addToast:i}){$e(t);const[u,h]=s.useState(""),[o,f]=s.useState("local"),[c,y]=s.useState(""),[p,N]=s.useState(""),[C,v]=s.useState(2),[P,j]=s.useState("auto-generate"),[n,x]=s.useState({}),[g,M]=s.useState(!1),R=s.useCallback(()=>{h(""),f("local"),y(""),N(""),v(2),j("auto-generate"),x({}),M(!1)},[]),E=s.useCallback(()=>{g||(R(),l())},[g,l,R]);s.useEffect(()=>{if(!t){R();return}const r=b=>{b.key==="Escape"&&(b.preventDefault(),E())};return document.addEventListener("keydown",r),()=>{document.removeEventListener("keydown",r)}},[E,t,R]);const D=s.useMemo(()=>({name:u.trim(),type:o,url:o==="remote"&&c.trim()||void 0,apiKey:o==="remote"&&P==="provide"&&p||void 0,maxConcurrent:C,apiKeyMode:P}),[p,P,C,u,o,c]),m=s.useCallback(async()=>{if(g)return;const r=os(D);if(x(r),!(Object.keys(r).length>0)){M(!0);try{await a(D),i(`Node "${D.name}" registered`,"success"),E()}catch(b){const z=b instanceof Error?b.message:"Failed to register node";i(z,"error")}finally{M(!1)}}},[i,E,D,g,a]);return t?e.jsx("div",{className:"modal-overlay open",onClick:E,children:e.jsxs("div",{className:"modal modal-md add-node-modal",onClick:r=>r.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":"Add Node",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Add Node"}),e.jsx("button",{className:"modal-close",onClick:E,disabled:g,"aria-label":"Close add node modal",children:"×"})]}),e.jsxs("div",{className:"modal-body add-node-modal__body",children:[e.jsx("p",{className:"add-node-modal__description",children:"Register an existing Fusion node by providing its connection details and concurrency settings."}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Name"}),e.jsx("input",{className:"input",type:"text",value:u,onChange:r=>h(r.target.value),placeholder:"Build Machine",disabled:g,"aria-invalid":!!n.name,autoFocus:!0}),n.name&&e.jsx("span",{className:"form-error add-node-modal__error",children:n.name})]}),e.jsxs("div",{className:"add-node-modal__type-toggle",children:[e.jsx("button",{type:"button",className:`add-node-modal__type-btn ${o==="local"?"active":""}`,"data-type":"local",onClick:()=>f("local"),disabled:g,"aria-pressed":o==="local",children:"Local"}),e.jsx("button",{type:"button",className:`add-node-modal__type-btn ${o==="remote"?"active":""}`,"data-type":"remote",onClick:()=>f("remote"),disabled:g,"aria-pressed":o==="remote",children:"Remote"})]}),o==="remote"&&e.jsxs("div",{className:"add-node-modal__remote-fields","data-testid":"remote-fields-container","data-visible":!0,children:[e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Reachable URL / Hostname"}),e.jsx("input",{className:"input",type:"text",value:c,onChange:r=>y(r.target.value),placeholder:"https://node.example.com",disabled:g,"aria-invalid":!!n.url}),n.url&&e.jsx("span",{className:"form-error add-node-modal__error",children:n.url})]}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"API Key Mode"}),e.jsxs("select",{className:"select",value:P,onChange:r=>j(r.target.value),disabled:g,children:[e.jsx("option",{value:"auto-generate",children:"Auto-generate"}),e.jsx("option",{value:"provide",children:"Provide key manually"})]})]}),P==="provide"&&e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"API Key"}),e.jsx("input",{className:"input",type:"password",value:p,onChange:r=>N(r.target.value),placeholder:"Enter node API key",disabled:g})]})]}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Max Concurrent"}),e.jsx("input",{className:"input",type:"number",min:he,max:fe,value:C,onChange:r=>v(Number(r.target.value)),disabled:g,"aria-invalid":!!n.maxConcurrent}),e.jsx("span",{className:"add-node-modal__hint",children:"Max simultaneous task agents (1–10)"}),n.maxConcurrent&&e.jsx("span",{className:"form-error add-node-modal__error",children:n.maxConcurrent})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:E,disabled:g,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary btn-sm","data-testid":"add-node-submit",onClick:m,disabled:g,children:g?"Adding...":"Add Node"})]})]})}):null}function is(){const[t,l]=s.useState([]),[a,i]=s.useState(!1),[u,h]=s.useState(null),[o,f]=s.useState(!1),[c,y]=s.useState(null),[p,N]=s.useState(!1),C=s.useCallback(async()=>{i(!0),h(null);try{const j=await fetch("/api/docker/contexts");if(!j.ok)throw new Error(`Failed to load Docker contexts (${j.status})`);const n=await j.json();return l(n),n}catch(j){const n=j instanceof Error?j.message:String(j);throw h(n),j}finally{i(!1)}},[]),v=s.useCallback(async j=>{f(!0);try{const n=await fetch("/api/docker/test-connection",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hostConfig:j})});if(!n.ok)throw new Error(`Failed to test Docker connection (${n.status})`);const x=await n.json();return y(x),x}finally{f(!1)}},[]),P=s.useCallback(async()=>{N(!0);try{const j=await fetch("/api/docker/local-available");if(!j.ok)throw new Error(`Failed to check local Docker availability (${j.status})`);return await j.json()}finally{N(!1)}},[]);return{contexts:t,isLoadingContexts:a,contextsError:u,loadContexts:C,isTestingConnection:o,lastTestResult:c,testConnection:v,isCheckingLocal:p,checkLocalDocker:P}}function ds({value:t,onChange:l}){const[a,i]=s.useState(!!(t?.tlsCaPath||t?.tlsCertPath||t?.tlsKeyPath||t?.tlsVerify));s.useEffect(()=>{a||l({tlsVerify:void 0,tlsCaPath:void 0,tlsCertPath:void 0,tlsKeyPath:void 0})},[a,l]);const u=s.useMemo(()=>({tlsVerify:t?.tlsVerify??!0,tlsCaPath:t?.tlsCaPath??"",tlsCertPath:t?.tlsCertPath??"",tlsKeyPath:t?.tlsKeyPath??""}),[t]);return e.jsxs("div",{className:"docker-tls-config",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:a,onChange:h=>i(h.target.checked)}),"Use TLS"]}),a&&e.jsxs("div",{className:"docker-tls-config__fields",children:[e.jsxs("div",{className:"docker-tls-config__field",children:[e.jsx("label",{htmlFor:"docker-tls-ca-path",children:"CA Certificate Path"}),e.jsx("input",{id:"docker-tls-ca-path",className:"input",value:u.tlsCaPath,onChange:h=>l({...u,tlsCaPath:h.target.value}),placeholder:"/etc/docker/ca.pem"})]}),e.jsxs("div",{className:"docker-tls-config__field",children:[e.jsx("label",{htmlFor:"docker-tls-cert-path",children:"Client Certificate Path"}),e.jsx("input",{id:"docker-tls-cert-path",className:"input",value:u.tlsCertPath,onChange:h=>l({...u,tlsCertPath:h.target.value}),placeholder:"/etc/docker/cert.pem"})]}),e.jsxs("div",{className:"docker-tls-config__field",children:[e.jsx("label",{htmlFor:"docker-tls-key-path",children:"Client Key Path"}),e.jsx("input",{id:"docker-tls-key-path",className:"input",value:u.tlsKeyPath,onChange:h=>l({...u,tlsKeyPath:h.target.value}),placeholder:"/etc/docker/key.pem"})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:u.tlsVerify,onChange:h=>l({...u,tlsVerify:h.target.checked})}),"Verify TLS Certificate"]})]})]})}function us({value:t,onChange:l,onError:a}){const i=t?.context?"context":t?.host?"host":"local",[u,h]=s.useState(i),[o,f]=s.useState(t?.context??""),[c,y]=s.useState(t?.host??""),[p,N]=s.useState(null),{contexts:C,isLoadingContexts:v,contextsError:P,loadContexts:j,testConnection:n,isTestingConnection:x,lastTestResult:g,checkLocalDocker:M,isCheckingLocal:R}=is(),E=s.useMemo(()=>({tlsVerify:t?.tlsVerify,tlsCaPath:t?.tlsCaPath,tlsCertPath:t?.tlsCertPath,tlsKeyPath:t?.tlsKeyPath}),[t]);s.useEffect(()=>{if(u==="local"){l({});return}if(u==="context"){j().catch(m=>a?.(m instanceof Error?m.message:String(m))),l(o?{context:o}:{});return}l({host:c,...E})},[u]);const D=s.useCallback(m=>{u==="host"&&l({host:c,...m})},[c,u,l]);return e.jsxs("div",{className:"docker-target-selector",children:[e.jsxs("div",{className:"docker-target-selector__modes",role:"group","aria-label":"Docker target mode",children:[e.jsx("button",{type:"button",className:`btn btn-sm ${u==="local"?"docker-target-selector__mode-active":""}`,onClick:()=>{h("local"),M().then(m=>N(m.available?`Docker is available${m.version?` (${m.version})`:""}`:`Docker not found${m.error?`: ${m.error}`:""}`)).catch(m=>{const r=m instanceof Error?m.message:String(m);N(`Docker not found: ${r}`),a?.(r)})},children:"Local Docker"}),e.jsx("button",{type:"button",className:`btn btn-sm ${u==="context"?"docker-target-selector__mode-active":""}`,onClick:()=>h("context"),children:"Docker Context"}),e.jsx("button",{type:"button",className:`btn btn-sm ${u==="host"?"docker-target-selector__mode-active":""}`,onClick:()=>h("host"),children:"Remote Host"})]}),u==="local"&&p&&e.jsx("div",{className:"docker-target-selector__status",children:p}),u==="context"&&e.jsxs("div",{className:"docker-target-selector__panel",children:[e.jsxs("div",{className:"docker-target-selector__context-row",children:[e.jsxs("select",{className:"select",value:o,onChange:m=>{const r=m.target.value;f(r),l(r?{context:r}:{})},children:[e.jsx("option",{value:"",children:"Select context"}),C.map(m=>e.jsxs("option",{value:m.name,children:[m.name,m.isCurrentContext?" (current)":"",m.dockerHost?` — ${m.dockerHost}`:""]},m.name))]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon",onClick:()=>void j(),disabled:v,"aria-label":"Refresh contexts",children:e.jsx(de,{size:14})})]}),P&&e.jsx("div",{className:"docker-target-selector__error",children:P})]}),u==="host"&&e.jsxs("div",{className:"docker-target-selector__panel",children:[e.jsxs("div",{className:"docker-target-selector__field",children:[e.jsx("label",{htmlFor:"docker-target-selector-host",children:"Docker Host"}),e.jsx("input",{id:"docker-target-selector-host",className:"input",placeholder:"tcp://host:2376",value:c,onChange:m=>{const r=m.target.value;y(r),l({host:r,...E})}})]}),e.jsx(ds,{value:E,onChange:D})]}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>void n(u==="local"?void 0:u==="context"?{context:o}:{host:c,...E}),disabled:x||R,children:x?"Testing...":"Test Connection"}),g&&e.jsx("div",{className:g.success?"docker-target-selector__success":"docker-target-selector__error",children:g.success?`Connected${g.dockerVersion?` (Docker ${g.dockerVersion})`:""}`:g.error??"Connection failed"})]})}const oe="http://localhost:4040";function ms({isOpen:t,onClose:l,onSubmit:a,addToast:i}){const[u,h]=s.useState(""),[o,f]=s.useState({}),[c,y]=s.useState(oe),[p,N]=s.useState("auto"),[C,v]=s.useState(""),[P,j]=s.useState(!1),[n,x]=s.useState(!1),[g,M]=s.useState(!0),[R,E]=s.useState(4096),[D,m]=s.useState(2),[r,b]=s.useState(!1),[z,F]=s.useState("runfusion/fusion"),[H,q]=s.useState("latest"),[O,V]=s.useState([]),[T,k]=s.useState([]),[S,K]=s.useState({}),[w,J]=s.useState(!1),L=s.useCallback(()=>{h(""),f({}),y(oe),N("auto"),v(""),j(!1),x(!1),M(!0),E(4096),m(2),b(!1),F("runfusion/fusion"),q("latest"),V([]),k([]),K({}),J(!1)},[]),U=s.useCallback(()=>{w||(L(),l())},[l,L,w]);s.useEffect(()=>{if(!t){L();return}const d=A=>{A.key==="Escape"&&(A.preventDefault(),U())};return document.addEventListener("keydown",d),()=>document.removeEventListener("keydown",d)},[U,t,L]);const X=s.useMemo(()=>({nodeId:null,name:u.trim(),imageName:z.trim()||"runfusion/fusion",imageTag:H.trim()||"latest",hostConfig:{context:o.context?.trim()||void 0,host:o.host?.trim()||void 0,tlsVerify:o.tlsVerify,tlsCaPath:o.tlsCaPath?.trim()||void 0,tlsCertPath:o.tlsCertPath?.trim()||void 0,tlsKeyPath:o.tlsKeyPath?.trim()||void 0},envVars:Object.fromEntries(O.map(d=>[d.key.trim(),d.value]).filter(([d])=>!!d)),volumeMounts:T.map(d=>({hostPath:d.hostPath.trim(),containerPath:d.containerPath.trim(),mode:d.mode})).filter(d=>d.hostPath&&d.containerPath),resourceSizing:{memoryMB:R,cpus:D},extraClis:[P?"claude-cli":null,n?"droid-cli":null].filter(Boolean),persistentStorage:g,reachableUrl:c.trim()||null,apiKey:p==="manual"&&C.trim()||null}),[C,p,D,o,O,z,H,P,n,R,T,u,g,c]),te=s.useCallback(()=>{V(d=>[...d,{key:"",value:""}])},[]),se=s.useCallback((d,A)=>{V($=>$.map((B,Z)=>Z===d?A:B))},[]),Y=s.useCallback(d=>{V(A=>A.filter(($,B)=>B!==d))},[]),ae=s.useCallback(()=>{k(d=>[...d,{hostPath:"",containerPath:"",mode:"rw"}])},[]),Q=s.useCallback((d,A)=>{k($=>$.map((B,Z)=>Z===d?A:B))},[]),ne=s.useCallback(d=>{k(A=>A.filter(($,B)=>B!==d))},[]),le=s.useCallback(async()=>{if(w)return;const d={};if((!X.name||X.name.length>64)&&(d.name="Name is required and must be 64 characters or fewer"),X.reachableUrl||(d.reachableUrl="URL is required"),R<512&&(d.memoryMB="Memory must be at least 512 MB"),D<.5&&(d.cpus="CPUs must be at least 0.5"),K(d),!(Object.keys(d).length>0)){J(!0);try{await a(X),U()}catch{}finally{J(!1)}}},[U,D,X,R,a,w]);return t?e.jsx("div",{className:"modal-overlay open",onClick:U,children:e.jsxs("div",{className:"modal docker-onboarding",role:"dialog","aria-modal":"true","aria-label":"Docker node onboarding",onClick:d=>d.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Provision Docker Node"}),e.jsx("button",{className:"modal-close",onClick:U,disabled:w,"aria-label":"Close onboarding modal",children:"×"})]}),e.jsxs("div",{className:"modal-body docker-onboarding__body",children:[e.jsxs("section",{className:"docker-onboarding__section",children:[e.jsx("h4",{className:"docker-onboarding__section-title",children:"Required Settings"}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Node Name"}),e.jsx("input",{className:"input",value:u,onChange:d=>h(d.target.value),disabled:w,placeholder:"my-docker-node",autoFocus:!0})]}),S.name&&e.jsx("div",{className:"form-error",children:S.name}),e.jsx(us,{value:o,onChange:f}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Reachable URL"}),e.jsx("input",{className:"input",value:c,onChange:d=>y(d.target.value),disabled:w,placeholder:oe})]}),S.reachableUrl&&e.jsx("div",{className:"form-error",children:S.reachableUrl}),e.jsxs("div",{className:"docker-onboarding__radio-group",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"radio",checked:p==="auto",onChange:()=>N("auto"),disabled:w}),"Auto-generate"]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"radio",checked:p==="manual",onChange:()=>N("manual"),disabled:w}),"Provide manually"]})]}),p==="manual"&&e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"API Key"}),e.jsx("input",{className:"input",type:"password",value:C,onChange:d=>v(d.target.value),disabled:w,placeholder:"Enter API key"})]}),e.jsxs("div",{className:"docker-onboarding__checkbox-group",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:P,onChange:d=>j(d.target.checked),disabled:w}),"Claude CLI"]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:n,onChange:d=>x(d.target.checked),disabled:w}),"Droid CLI"]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:g,onChange:d=>M(d.target.checked),disabled:w}),"Keep data across container recreations"]})]}),e.jsxs("div",{className:"docker-onboarding__inline-fields",children:[e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Memory (MB)"}),e.jsx("input",{className:"input",type:"number",min:512,value:R,onChange:d=>E(Number(d.target.value)),disabled:w})]}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"CPUs"}),e.jsx("input",{className:"input",type:"number",min:.5,step:.5,value:D,onChange:d=>m(Number(d.target.value)),disabled:w})]})]}),S.memoryMB&&e.jsx("div",{className:"form-error",children:S.memoryMB}),S.cpus&&e.jsx("div",{className:"form-error",children:S.cpus})]}),e.jsxs("section",{className:"docker-onboarding__section",children:[e.jsxs("button",{type:"button",className:`docker-onboarding__advanced-toggle ${r?"is-expanded":""}`,onClick:()=>b(d=>!d),disabled:w,children:[e.jsx("span",{children:"Advanced"}),e.jsx(Ne,{})]}),e.jsx("div",{className:`docker-onboarding__advanced-content ${r?"is-expanded":""}`,children:e.jsxs("div",{children:[e.jsxs("div",{className:"docker-onboarding__inline-fields",children:[e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Image"}),e.jsx("input",{className:"input",value:z,onChange:d=>F(d.target.value),disabled:w,placeholder:"runfusion/fusion"})]}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Tag"}),e.jsx("input",{className:"input",value:H,onChange:d=>q(d.target.value),disabled:w,placeholder:"latest"})]})]}),e.jsxs("div",{className:"docker-onboarding__kv-list",children:[e.jsx("h5",{children:"Environment Variables"}),O.map((d,A)=>e.jsxs("div",{className:"docker-onboarding__kv-row docker-onboarding__kv-row--env",children:[e.jsx("input",{className:"input",placeholder:"KEY",value:d.key,disabled:w,onChange:$=>se(A,{key:$.target.value,value:d.value})}),e.jsx("input",{className:"input",placeholder:"Value",value:d.value,disabled:w,onChange:$=>se(A,{key:d.key,value:$.target.value})}),e.jsx("button",{type:"button",className:"btn btn-icon","aria-label":"Remove environment variable",onClick:()=>Y(A),disabled:w,children:e.jsx(ie,{size:14})})]},`env-${A}`)),e.jsxs("button",{type:"button",className:"btn btn-sm docker-onboarding__kv-add",onClick:te,disabled:w,children:[e.jsx(ee,{size:14}),"Add variable"]})]}),e.jsxs("div",{className:"docker-onboarding__kv-list",children:[e.jsx("h5",{children:"Volume Mounts"}),T.map((d,A)=>e.jsxs("div",{className:"docker-onboarding__kv-row docker-onboarding__kv-row--mount",children:[e.jsx("input",{className:"input",placeholder:"Host path",value:d.hostPath,disabled:w,onChange:$=>Q(A,{hostPath:$.target.value,containerPath:d.containerPath,mode:d.mode})}),e.jsx("input",{className:"input",placeholder:"Container path",value:d.containerPath,disabled:w,onChange:$=>Q(A,{hostPath:d.hostPath,containerPath:$.target.value,mode:d.mode})}),e.jsxs("select",{className:"select",value:d.mode,disabled:w,onChange:$=>Q(A,{hostPath:d.hostPath,containerPath:d.containerPath,mode:$.target.value==="ro"?"ro":"rw"}),children:[e.jsx("option",{value:"rw",children:"rw"}),e.jsx("option",{value:"ro",children:"ro"})]}),e.jsx("button",{type:"button",className:"btn btn-icon","aria-label":"Remove volume mount",onClick:()=>ne(A),disabled:w,children:e.jsx(ie,{size:14})})]},`mount-${A}`)),e.jsxs("button",{type:"button",className:"btn btn-sm docker-onboarding__kv-add",onClick:ae,disabled:w,children:[e.jsx(ee,{size:14}),"Add mount"]})]})]})})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn",onClick:U,disabled:w,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void le(),disabled:w,children:w?"Creating...":"Create Docker Node"})]})]})}):null}function hs({nodeId:t,entries:l,loading:a=!1,singleNode:i=!1}){const[u,h]=s.useState(!1),[o,f]=s.useState("all"),[c,y]=s.useState("all"),p=s.useCallback(()=>{h(n=>!n)},[]),N=s.useMemo(()=>{const n=new Set;for(const x of l)n.add(x.nodeName);return Array.from(n).sort()},[l]),C=s.useMemo(()=>{let n=[...l];return o!=="all"&&(n=n.filter(x=>x.direction===o)),!i&&c!=="all"&&(n=n.filter(x=>x.nodeName===c)),n.sort((x,g)=>{const M=new Date(x.timestamp).getTime();return new Date(g.timestamp).getTime()-M}),n},[l,o,c,i]),v=s.useCallback(n=>new Date(n).toLocaleString(),[]),P=s.useCallback(n=>{switch(n){case"success":return"settings-sync-log__badge--success";case"conflict":return"settings-sync-log__badge--conflict";case"error":return"settings-sync-log__badge--error";default:return""}},[]),j=s.useCallback(n=>{switch(n){case"success":return"Success";case"conflict":return"Conflict";case"error":return"Error";default:return n}},[]);return e.jsxs("div",{className:"settings-sync-log",children:[e.jsxs("button",{className:"settings-sync-log__header",type:"button",onClick:p,"aria-expanded":u,"data-testid":"settings-sync-log-header",children:[e.jsx(Ne,{size:16,className:`settings-sync-log__chevron ${u?"settings-sync-log__chevron--expanded":""}`}),e.jsxs("span",{children:[l.length," ",l.length===1?"entry":"entries"]})]}),u&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"settings-sync-log__filters",children:[e.jsxs("label",{children:["Direction:",e.jsxs("select",{value:o,onChange:n=>f(n.target.value),children:[e.jsx("option",{value:"all",children:"All"}),e.jsx("option",{value:"push",children:"Push"}),e.jsx("option",{value:"pull",children:"Pull"})]})]}),!i&&e.jsxs("label",{children:["Node:",e.jsxs("select",{value:c,onChange:n=>y(n.target.value),children:[e.jsx("option",{value:"all",children:"All Nodes"}),N.map(n=>e.jsx("option",{value:n,children:n},n))]})]})]}),a&&l.length===0?e.jsx("div",{className:"settings-sync-log__empty",children:"Loading..."}):C.length===0?e.jsx("div",{className:"settings-sync-log__empty",children:"No sync history available"}):e.jsx("div",{className:"settings-sync-log__list",children:C.map(n=>e.jsxs("div",{className:"settings-sync-log__entry",children:[e.jsx("span",{className:"settings-sync-log__entry-timestamp",children:v(n.timestamp)}),e.jsx("span",{className:"settings-sync-log__entry-direction",children:n.direction==="push"?e.jsx(ve,{size:14,"data-testid":"upload-icon"}):e.jsx(_e,{size:14,"data-testid":"download-icon"})}),e.jsx("span",{className:`settings-sync-log__entry-result ${P(n.result)}`,children:j(n.result)}),!i&&e.jsx("span",{className:"settings-sync-log__entry-node",children:n.nodeName}),n.details&&e.jsx("span",{className:"settings-sync-log__entry-details",title:n.details,children:n.details})]},n.id))})]})]})}function fs(t,l){const a=typeof t=="string"?t:JSON.stringify(t,null,2),i=typeof l=="string"?l:JSON.stringify(l,null,2);if(a===i)return a;const u=a.split(`
|
|
12
|
-
`),h=i.split(`
|
|
13
|
-
`),o=[],f=Math.max(u.length,h.length);for(let c=0;c<f;c++){const y=u[c],p=h[c];y!==void 0&&y!==p&&o.push(`- ${y}`),p!==void 0&&p!==y&&o.push(`+ ${p}`),y!==void 0&&y===p&&o.push(` ${y}`)}return o.join(`
|
|
14
|
-
`)}function xs({isOpen:t,onClose:l,onResolve:a,conflicts:i,localNodeName:u,remoteNodeName:h,addToast:o}){const[f,c]=s.useState({}),[y,p]=s.useState(!1);s.useEffect(()=>{const n={};for(const x of i)f[x.key]||(n[x.key]={resolution:"local"});Object.keys(n).length>0&&c(x=>({...x,...n}))},[i,f]),s.useEffect(()=>{if(!t)return;const n=x=>{x.key==="Escape"&&(x.preventDefault(),l())};return document.addEventListener("keydown",n),()=>document.removeEventListener("keydown",n)},[t,l]);const N=s.useCallback((n,x)=>{c(g=>{const M=g[n]??{};return x==="manual"?{...g,[n]:{resolution:"manual",manualValue:M.manualValue??JSON.stringify(i.find(R=>R.key===n)?.localValue??null,null,2)}}:{...g,[n]:{resolution:x}}})},[i]),C=s.useCallback((n,x)=>{c(g=>({...g,[n]:{...g[n],resolution:"manual",manualValue:x}}))},[]),v=s.useCallback(n=>{const x={};for(const g of i)x[g.key]={resolution:n};c(x)},[i]),P=s.useCallback(async()=>{p(!0);try{const n=i.map(x=>{const g=f[x.key]??{resolution:"local"};let M;switch(g.resolution){case"remote":M=x.remoteValue;break;case"manual":try{M=JSON.parse(g.manualValue??"null")}catch{M=g.manualValue??null}break;case"local":default:M=x.localValue;break}return{key:x.key,value:M}});await a(n),o("Settings conflicts resolved successfully","success"),l()}catch(n){const x=n instanceof Error?n.message:"Failed to resolve conflicts";o(x,"error")}finally{p(!1)}},[o,i,l,a,f]),j=s.useMemo(()=>{const n={};for(const x of i)n[x.key]=fs(x.localValue,x.remoteValue);return n},[i]);return!t||i.length===0?null:e.jsx("div",{className:"modal-overlay open",onClick:l,children:e.jsxs("div",{className:"modal modal-lg settings-sync-conflict-modal",onClick:n=>n.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":"Resolve Settings Conflicts",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Resolve Settings Conflicts"}),e.jsx("button",{className:"modal-close",onClick:l,"aria-label":"Close conflict modal",children:"×"})]}),e.jsxs("div",{className:"modal-body",children:[e.jsx("div",{className:"settings-sync-conflict-modal__conflict-list",children:i.map(n=>{const x=f[n.key]??{resolution:"local"},g=j[n.key];return e.jsxs("div",{className:"settings-sync-conflict-modal__conflict-item",children:[e.jsx("div",{className:"settings-sync-conflict-modal__key",children:n.key}),e.jsxs("div",{className:"settings-sync-conflict-modal__diff-panel",children:[e.jsxs("div",{className:"settings-sync-conflict-modal__diff-side",children:[e.jsx("div",{className:"settings-sync-conflict-modal__diff-label",children:u}),e.jsx("div",{className:"settings-sync-conflict-modal__diff-content",children:e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap"},children:g})})]}),e.jsxs("div",{className:"settings-sync-conflict-modal__diff-side",children:[e.jsx("div",{className:"settings-sync-conflict-modal__diff-label",children:h}),e.jsx("div",{className:"settings-sync-conflict-modal__diff-content",children:e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap"},children:g})})]})]}),e.jsxs("div",{className:"settings-sync-conflict-modal__resolution",children:[e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${n.key}`,checked:x.resolution==="local",onChange:()=>N(n.key,"local")}),"Keep Local"]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${n.key}`,checked:x.resolution==="remote",onChange:()=>N(n.key,"remote")}),"Keep Remote"]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${n.key}`,checked:x.resolution==="manual",onChange:()=>N(n.key,"manual")}),"Merge Manually"]})]}),x.resolution==="manual"&&e.jsx("textarea",{className:"settings-sync-conflict-modal__manual-input",value:x.manualValue??"",onChange:M=>C(n.key,M.target.value),placeholder:"Enter JSON value..."})]},n.key)})}),e.jsxs("div",{className:"settings-sync-conflict-modal__bulk-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>v("local"),type:"button",children:"Resolve All: Keep Local"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>v("remote"),type:"button",children:"Resolve All: Keep Remote"})]})]}),e.jsxs("div",{className:"modal-actions settings-sync-conflict-modal__footer",children:[e.jsx("button",{className:"btn btn-sm",onClick:l,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:P,disabled:y,children:y?"Resolving...":"Confirm"})]})]})})}function ce(t){if(!t)return"—";const l=new Date(t);return Number.isNaN(l.getTime())?"—":l.toLocaleString()}function gs(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 ps({isOpen:t,onClose:l,node:a,projects:i,onUpdate:u,onHealthCheck:h,addToast:o,syncStatus:f,onPushSettings:c,onPullSettings:y,onSyncAuth:p,syncHistory:N=[],onResolveConflicts:C}){const v=s.useRef(!0),[P,j]=s.useState(!1),[n,x]=s.useState(""),[g,M]=s.useState(""),[R,E]=s.useState(""),[D,m]=s.useState(2),[r,b]=s.useState(!1),[z,F]=s.useState(!1),[H,q]=s.useState(!1),[O,V]=s.useState(!1),[T,k]=s.useState(null),[S,K]=s.useState(!1),[w]=s.useState([]),[J,L]=s.useState("running"),[U,X]=s.useState("FUSION_LOG_LEVEL=info"),[te,se]=s.useState("/srv/fusion:/data:rw");s.useEffect(()=>(v.current=!0,()=>{v.current=!1}),[]),s.useEffect(()=>{if(!a||!t){j(!1);return}x(a.name),M(a.url??""),E(a.apiKey??""),m(a.maxConcurrent),j(!1)},[t,a]),s.useEffect(()=>{if(!t)return;const _=I=>{I.key==="Escape"&&(I.preventDefault(),l())};return document.addEventListener("keydown",_),()=>document.removeEventListener("keydown",_)},[t,l]);const Y=s.useMemo(()=>a?Ce(i,a):[],[a,i]),ae=s.useMemo(()=>a?.capabilities?.includes("docker-managed")??!1,[a]),Q=s.useCallback(async()=>{if(a)try{if(await h(a.id),!v.current)return;o(`Health check completed for ${a.name}`,"success")}catch(_){if(!v.current)return;const I=_ instanceof Error?_.message:"Health check failed";o(I,"error")}},[o,a,h]),ne=s.useCallback(async()=>{if(!(!a||!c)){k(null),F(!0);try{if(await c(a.id),!v.current)return;o("Settings pushed successfully","success")}catch(_){if(!v.current)return;const I=_ instanceof Error?_.message:"Push settings failed";k(I),o(I,"error")}finally{v.current&&F(!1)}}},[o,a,c]),le=s.useCallback(async()=>{if(!(!a||!y)){k(null),q(!0);try{if(await y(a.id),!v.current)return;o("Settings pulled successfully","success")}catch(_){if(!v.current)return;const I=_ instanceof Error?_.message:"Pull settings failed";k(I),o(I,"error")}finally{v.current&&q(!1)}}},[o,a,y]),d=s.useCallback(async()=>{if(!(!a||!p)){k(null),V(!0);try{if(await p(a.id),!v.current)return;o("Auth credentials synced successfully","success")}catch(_){if(!v.current)return;const I=_ instanceof Error?_.message:"Auth sync failed";k(I),o(I,"error")}finally{v.current&&V(!1)}}},[o,a,p]),A=s.useCallback(()=>{k(null)},[]),$=s.useCallback(_=>{_==="start"&&L("running"),_==="stop"&&L("stopped"),_==="restart"&&L("running"),_==="recreate"&&L("recreating"),_==="upgrade"&&L("recreating"),o(`Docker action queued: ${_}`,"success")},[o]),B=s.useCallback(async()=>{if(!a||r)return;const _=n.trim();if(!_){o("Name is required","error");return}if(a.type==="remote"&&!g.trim()){o("URL is required for remote nodes","error");return}if(!Number.isFinite(D)||D<1){o("Concurrency must be at least 1","error");return}b(!0);try{await u(a.id,{name:_,url:a.type==="remote"&&g.trim()||void 0,apiKey:a.type==="remote"&&R||void 0,maxConcurrent:D}),o(`Updated ${_}`,"success"),j(!1)}catch(I){const Se=I instanceof Error?I.message:"Failed to update node";o(Se,"error")}finally{b(!1)}},[o,R,r,D,n,a,u,g]),Z=s.useCallback(()=>{a&&(x(a.name),M(a.url??""),E(a.apiKey??""),m(a.maxConcurrent),j(!1))},[a]);return!t||!a?null:e.jsxs("div",{className:"modal-overlay open",onClick:l,children:[e.jsxs("div",{className:"modal modal-lg node-detail-modal",onClick:_=>_.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":`Node details for ${a.name}`,children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Node Details"}),e.jsx("button",{className:"modal-close",onClick:l,"aria-label":"Close node detail modal",children:"×"})]}),e.jsxs("div",{className:"modal-body node-detail-modal__body",children:[e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsxs("div",{className:"node-detail-modal__section-header",children:[e.jsx("h4",{children:"Overview"}),!P&&e.jsxs("button",{className:"btn btn-sm",onClick:()=>j(!0),children:[e.jsx(Ke,{size:14}),"Edit"]})]}),e.jsxs("div",{className:"node-detail-modal__grid",children:[e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Name"}),P?e.jsx("input",{className:"input",value:n,onChange:_=>x(_.target.value),disabled:r}):e.jsx("strong",{children:a.name})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Type"}),e.jsx("strong",{children:a.type==="local"?"Local":"Remote"})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Status"}),e.jsx("strong",{children:a.status})]}),e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Max Concurrent"}),P?e.jsx("input",{className:"input",type:"number",min:1,max:10,value:D,onChange:_=>m(Number(_.target.value)),disabled:r}):e.jsx("strong",{children:a.maxConcurrent})]}),a.type==="remote"&&e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"node-detail-modal__field node-detail-modal__field--full",children:[e.jsx("span",{children:"URL"}),P?e.jsx("input",{className:"input",value:g,onChange:_=>M(_.target.value),disabled:r}):e.jsx("strong",{children:a.url??"—"})]}),e.jsxs("label",{className:"node-detail-modal__field node-detail-modal__field--full",children:[e.jsx("span",{children:"API Key"}),P?e.jsx("input",{className:"input",type:"password",value:R,onChange:_=>E(_.target.value),placeholder:"Leave blank to keep unchanged",disabled:r}):e.jsx("strong",{children:a.apiKey?"••••••••":"Not configured"})]})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Created"}),e.jsx("strong",{children:ce(a.createdAt)})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Updated"}),e.jsx("strong",{children:ce(a.updatedAt)})]})]}),P&&e.jsxs("div",{className:"node-detail-modal__edit-actions",children:[e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:B,disabled:r,children:[e.jsx(ze,{size:14}),r?"Saving...":"Save"]}),e.jsxs("button",{className:"btn btn-sm",onClick:Z,disabled:r,children:[e.jsx(ue,{size:14}),"Cancel"]})]})]}),e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsxs("h4",{children:[a.type==="local"?"Projects":"Assigned Projects"," (",Y.length,")"]}),Y.length===0?e.jsx("p",{className:"node-detail-modal__empty",children:a.type==="local"?"No projects are running on this node.":"No projects are assigned to this node."}):e.jsx("ul",{className:"node-detail-modal__project-list",children:Y.map(_=>e.jsxs("li",{className:"node-detail-modal__project-item",children:[e.jsx("span",{children:_.name}),e.jsx("code",{children:_.id})]},_.id))})]}),e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Health"}),e.jsxs("div",{className:"node-detail-modal__health-row",children:[e.jsxs("span",{children:["Status: ",e.jsx("strong",{children:a.status})]}),e.jsxs("span",{children:["Last check: ",e.jsx("strong",{children:ce(a.updatedAt)})]})]})]}),ae&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Docker Management"}),e.jsxs("div",{className:"node-detail-modal__health-row",children:[e.jsxs("span",{children:["Container: ",e.jsx("strong",{children:J})]}),e.jsxs("span",{children:["Image: ",e.jsx("strong",{children:"runfusion/fusion:latest"})]})]}),e.jsxs("div",{className:"node-detail-modal__sync-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>$("start"),children:"Start"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>$("stop"),children:"Stop"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>$("restart"),children:"Restart"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>$("recreate"),children:"Recreate"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>$("upgrade"),children:"Upgrade Image"})]}),e.jsxs("div",{className:"node-detail-modal__docker-grid",children:[e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Environment Variables"}),e.jsx("textarea",{className:"input node-detail-modal__textarea",value:U,onChange:_=>X(_.target.value)})]}),e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Volume Mounts"}),e.jsx("textarea",{className:"input node-detail-modal__textarea",value:te,onChange:_=>se(_.target.value)})]})]}),e.jsxs("div",{className:"node-detail-modal__sync-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>o("Container logs opened","success"),children:"View Logs"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>o("Config changes saved","success"),children:"Save Config"}),e.jsx("button",{className:"btn btn-danger btn-sm",onClick:()=>o("Delete flow opened (retain/remove volumes)","warning"),children:"Delete Node…"})]})]}),a.type==="remote"&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Settings Sync"}),f&&e.jsxs("div",{className:"node-detail-modal__sync-status",children:[e.jsx("span",{className:`node-detail-modal__sync-dot ${gs(f.syncState)}`,"aria-hidden":!0}),e.jsxs("span",{children:["Last sync:"," ",e.jsx("strong",{children:f.lastSyncAt?ke(f.lastSyncAt):"Never synced"})]}),f.diffCount>0&&e.jsxs("span",{className:"node-detail-modal__sync-diff",children:["Differences: ",e.jsx("strong",{children:f.diffCount})]})]}),e.jsxs("div",{className:"node-detail-modal__sync-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:ne,disabled:z||!c,children:[e.jsx(ve,{size:14}),z?"Pushing...":"Push Settings"]}),e.jsxs("button",{className:"btn btn-sm",onClick:le,disabled:H||!y,children:[e.jsx(_e,{size:14}),H?"Pulling...":"Pull Settings"]}),e.jsxs("button",{className:"btn btn-sm",onClick:d,disabled:O||!p,children:[e.jsx(be,{size:14}),O?"Syncing...":"Sync Auth"]})]}),T&&e.jsxs("div",{className:"node-detail-modal__sync-error",children:[e.jsx("span",{children:T}),e.jsx("button",{className:"node-detail-modal__sync-error-dismiss",onClick:A,"aria-label":"Dismiss error",children:e.jsx(ue,{size:14})})]})]}),a.type==="remote"&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Sync History"}),e.jsx(hs,{nodeId:a.id,entries:N,singleNode:!0})]})]}),e.jsxs("div",{className:"modal-actions node-detail-modal__actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:Q,children:[e.jsx(je,{size:14}),"Health Check"]}),e.jsx("button",{className:"btn btn-sm",onClick:l,children:"Close"})]})]}),a.type==="remote"&&e.jsx(xs,{isOpen:S,onClose:()=>K(!1),onResolve:C??(async()=>{}),conflicts:w,localNodeName:"Local",remoteNodeName:a.name,addToast:o})]})}function ys(){const[t,l]=s.useState([]),[a,i]=s.useState(!0),[u,h]=s.useState(null),o=s.useCallback(async()=>{try{h(null);const c=await xe();l(c)}catch(c){h(c instanceof Error?c.message:"Failed to fetch managed Docker nodes")}},[]);s.useEffect(()=>{let c=!1;async function y(){i(!0);try{const p=await xe();c||(l(p),h(null))}catch(p){c||h(p instanceof Error?p.message:"Failed to fetch managed Docker nodes")}finally{c||i(!1)}}return y(),()=>{c=!0}},[]);const f=s.useCallback(async c=>{const y=await Ie(c);return l(p=>[...p,y]),y},[]);return{dockerNodes:t,loading:a,error:u,refresh:o,create:f}}function vs({addToast:t,onClose:l}){const{nodes:a,loading:i,error:u,refresh:h,register:o,update:f,unregister:c,healthCheck:y}=Fe(),{projects:p}=Oe(),{syncStatusMap:N,pushSettings:C,pullSettings:v,syncAuth:P,trackNode:j,getAuthSyncState:n,getAuthProviders:x}=Xe(),{dockerNodes:g,create:M}=ys(),[R,E]=s.useState(!1),[D,m]=s.useState(!1),[r,b]=s.useState(null);s.useEffect(()=>{const k=a.filter(S=>S.type==="remote");for(const S of k)j(S.id)},[a,j]),s.useEffect(()=>{if(!r)return;const k=a.find(S=>S.id===r.id)??null;b(k)},[a,r]);const z=s.useMemo(()=>{const k=a.length,S=a.filter(L=>L.status==="online").length,K=a.filter(L=>L.status==="offline"||L.status==="error").length,w=a.filter(L=>L.type==="remote").length,J=a.filter(L=>L.type==="remote"&&N[L.id]&&re(N[L.id]).syncState==="synced").length;return{total:k,online:S,offline:K,remote:w,synced:J}},[a,N]),F=s.useCallback(async k=>{await o(k)},[o]),H=s.useCallback(async k=>{try{await M(k),t(`Docker node "${k.name}" created`,"success"),m(!1)}catch(S){const K=S instanceof Error?S.message:"Failed to create Docker node";throw t(K,"error"),S}},[t,M]),q=s.useCallback(async()=>{try{await h()}catch{t("Failed to refresh nodes","error")}},[t,h]),O=s.useCallback(async k=>{try{await y(k),t("Node health check complete","success")}catch(S){const K=S instanceof Error?S.message:"Health check failed";t(K,"error")}},[t,y]),V=s.useCallback(async k=>{try{await c(k),t("Node removed","success"),r?.id===k&&b(null)}catch(S){const K=S instanceof Error?S.message:"Failed to remove node";t(K,"error")}},[t,r?.id,c]),T=s.useCallback(async(k,S)=>{await f(k,S)},[f]);return e.jsxs("div",{className:"nodes-view","data-testid":"nodes-view",children:[e.jsxs("div",{className:"nodes-view-header",children:[e.jsxs("div",{className:"nodes-view-title",children:[e.jsxs("h2",{children:[e.jsx(ye,{size:20}),"Nodes"]}),e.jsxs("span",{className:"nodes-view-count",children:[a.length," registered"]})]}),e.jsxs("div",{className:"nodes-view-actions",children:[e.jsx("button",{className:"btn-icon nodes-view-close",onClick:l,"aria-label":"Close nodes view",children:e.jsx(ue,{size:16})}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>void q(),disabled:i,children:[e.jsx(de,{size:14,className:i?"spin":""}),"Refresh"]}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>E(!0),children:[e.jsx(ee,{size:14}),"Add Node"]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>m(!0),children:[e.jsx(ee,{size:14}),"Provision Docker Node"]})]})]}),e.jsxs("div",{className:"nodes-view-stats",children:[e.jsxs("div",{className:"nodes-view-stat","data-testid":"nodes-stat-total",children:[e.jsx("span",{children:"Total"}),e.jsx("strong",{children:z.total})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--online","data-testid":"nodes-stat-online",children:[e.jsxs("span",{children:[e.jsx(Te,{size:14})," Online"]}),e.jsx("strong",{children:z.online})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--offline","data-testid":"nodes-stat-offline",children:[e.jsxs("span",{children:[e.jsx(Be,{size:14})," Offline"]}),e.jsx("strong",{children:z.offline})]}),e.jsxs("div",{className:"nodes-view-stat","data-testid":"nodes-stat-remote",children:[e.jsxs("span",{children:[e.jsx(Ve,{size:14})," Remote"]}),e.jsx("strong",{children:z.remote})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--synced","data-testid":"nodes-stat-synced",children:[e.jsxs("span",{children:[e.jsx(de,{size:14})," Synced"]}),e.jsx("strong",{children:z.synced})]})]}),u&&e.jsx("div",{className:"nodes-view-error",children:u}),e.jsxs("section",{className:"nodes-view-topology","aria-label":"Docker Nodes Summary",children:[e.jsx("h3",{className:"nodes-view-section-title",children:"Docker Nodes"}),e.jsxs("div",{className:"nodes-view-stat",children:[e.jsx("span",{children:"Managed Docker Nodes"}),e.jsx("strong",{children:g.length}),e.jsx("button",{className:"btn btn-sm",onClick:()=>m(!0),children:"Provision"})]})]}),!i&&a.length>0&&e.jsxs("section",{className:"nodes-view-topology","aria-label":"Mesh Topology",children:[e.jsx("h3",{className:"nodes-view-section-title",children:"Mesh Topology"}),e.jsx(rs,{nodes:a})]}),i?e.jsx("div",{className:"nodes-view-grid",children:Array.from({length:4}).map((k,S)=>e.jsx("div",{className:"node-card node-card--loading","aria-hidden":!0},S))}):a.length===0?e.jsxs("div",{className:"nodes-view-empty",children:[e.jsx("p",{children:"No nodes are registered yet."}),e.jsxs("button",{className:"btn btn-primary",onClick:()=>E(!0),children:[e.jsx(ee,{size:14}),"Add First Node"]})]}):e.jsx("div",{className:"nodes-view-grid",children:a.map(k=>{const S=k.type==="remote"&&N[k.id]?re(N[k.id]):void 0;return e.jsx(ts,{node:k,projects:p,onHealthCheck:K=>{O(K)},onEdit:K=>b(K),onRemove:K=>{V(K)},isLoading:i,syncStatus:S,authSyncState:k.type==="remote"?n(k.id):void 0,authSyncProviders:k.type==="remote"?x(k.id):void 0},k.id)})}),e.jsx(cs,{isOpen:R,onClose:()=>E(!1),onSubmit:F,addToast:t}),e.jsx(ms,{isOpen:D,onClose:()=>m(!1),onSubmit:H,addToast:t}),e.jsx(ps,{isOpen:r!==null,onClose:()=>b(null),node:r,projects:p,onUpdate:T,onHealthCheck:O,addToast:t,syncStatus:r?.type==="remote"&&r&&N[r.id]?re(N[r.id]):void 0,onPushSettings:C,onPullSettings:v,onSyncAuth:P})]})}export{vs as NodesView};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.nodes-management-overlay{display:flex;flex-direction:column;gap:var(--space-md);height:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}.nodes-management-overlay__header{display:flex;justify-content:flex-end}.nodes-view{display:flex;flex-direction:column;gap:var(--space-md);padding:var(--space-sm) var(--space-md) var(--space-xl)}.nodes-view-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--space-sm)}.nodes-view-title{display:flex;align-items:center;gap:var(--space-sm)}.nodes-view-title h2{margin:0;display:flex;align-items:center;gap:var(--space-sm)}.nodes-view-count{color:var(--text-muted);font-size:calc(var(--space-md) + var(--space-xs) / 4)}.nodes-view-actions{display:flex;gap:var(--space-sm)}.nodes-view-close{margin-left:auto}.nodes-view-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(calc(var(--space-xl) * 5.833),1fr));gap:var(--space-sm)}.nodes-view-stat{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:var(--space-sm) var(--space-md);display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm)}.nodes-view-stat span{display:inline-flex;align-items:center;gap:var(--space-sm);color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs))}.nodes-view-stat strong{font-size:calc(var(--space-lg) + var(--space-xs) / 2)}.nodes-view-stat--online strong{color:var(--color-success)}.nodes-view-stat--offline strong{color:var(--color-error)}.nodes-view-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(calc(var(--space-lg) * 20),1fr));gap:var(--space-md)}.nodes-view-empty{padding:var(--space-xl);border:1px dashed var(--border);border-radius:var(--radius);text-align:center;color:var(--text-muted);display:flex;flex-direction:column;align-items:center;gap:var(--space-md)}.nodes-view-error{color:var(--color-error);font-size:calc(var(--space-md) + var(--space-xs) / 4)}.node-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-md);cursor:pointer;transition:border-color var(--transition-fast),transform var(--transition-fast)}.node-card:hover{border-color:var(--accent);transform:translateY(calc(var(--space-xs) * -.25))}.node-card:focus-visible{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring-strong)}.node-card--loading{min-height:calc(var(--space-xl) * 9.167);opacity:.55;pointer-events:none}.node-card__header{display:flex;align-items:center;justify-content:space-between}.node-card__title-wrap{display:flex;align-items:center;gap:var(--space-sm)}.node-card__icon{width:calc(var(--space-lg) * 2.125);height:calc(var(--space-lg) * 2.125);border-radius:var(--radius-sm);display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent)}.node-card__name{margin:0;font-size:calc(var(--space-md) + var(--space-xs));line-height:1.25}.node-card__meta-row{margin-top:var(--space-xs);display:flex;align-items:center;gap:var(--space-xs)}.node-card__type-badge{border:1px solid var(--border);border-radius:var(--radius-pill);padding:var(--space-xs) var(--space-sm);font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted)}.node-card__status{display:inline-flex;align-items:center;gap:var(--space-xs);font-size:calc(var(--space-sm) + var(--space-xs) * .75);font-weight:600}.node-card__status-indicator{width:var(--space-sm);height:var(--space-sm);border-radius:50%}.node-card__status--online .node-card__status-indicator{background:var(--color-success)}.node-card__status--offline .node-card__status-indicator,.node-card__status--error .node-card__status-indicator{background:var(--color-error)}.node-card__status--connecting .node-card__status-indicator{background:var(--color-warning)}.node-card__auth-indicator{display:inline-flex;align-items:center;margin-left:var(--space-xs);vertical-align:middle}.node-card__url{font-family:var(--font-mono);font-size:calc(var(--space-sm) + var(--space-xs));color:var(--text-muted);word-break:break-all}.node-card__metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.node-card__metric{display:flex;flex-direction:column;gap:var(--space-xs)}.node-card__metric-label{color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs) * .75);text-transform:uppercase;letter-spacing:.03em}.node-card__metric-value{font-size:calc(var(--space-md) + var(--space-xs));font-weight:600}.node-card__sync{display:flex;align-items:center;gap:var(--space-xs);margin-top:var(--space-sm);font-size:calc(var(--space-sm) + var(--space-xs));color:var(--text-muted)}.node-card__sync-dot{width:var(--space-sm);height:var(--space-sm);border-radius:50%;flex-shrink:0}.node-card__sync-time{color:var(--text-muted)}.nodes-view-stat--synced strong{color:var(--color-success)}.node-card__actions{display:flex;gap:var(--space-xs);flex-wrap:wrap}.node-card__action{display:inline-flex;align-items:center;gap:var(--space-xs)}.node-card__action--remove{margin-left:auto}.node-card__action--remove:not(.btn-danger){color:var(--color-error);border-color:color-mix(in srgb,var(--color-error) 45%,var(--border))}.node-card__action--remove.is-armed{background:color-mix(in srgb,var(--color-error) 14%,transparent)}.mesh-topology{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-md);min-height:calc(var(--space-2xl) * 6.25);padding:var(--space-md);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md)}.mesh-topology__svg{width:100%;max-width:calc(var(--space-2xl) * 12.5);height:auto;aspect-ratio:1}.mesh-topology__node{transition:filter var(--transition-fast)}.mesh-topology__node:hover{filter:brightness(1.1)}.mesh-topology__node-circle{stroke:var(--border);stroke-width:calc(var(--space-xs) / 2);transition:fill var(--transition-fast)}.mesh-topology__node-label{font-size:calc(var(--space-sm) + var(--space-xs) * .75);fill:var(--text);font-weight:500}.mesh-topology__node-type-badge{fill:color-mix(in srgb,var(--surface) 75%,var(--bg));stroke:var(--border);stroke-width:calc(var(--space-xs) / 4)}.mesh-topology__node-type-text{font-size:calc(var(--space-sm) + var(--space-xs) / 2);font-weight:700;fill:var(--text-muted);text-transform:uppercase;letter-spacing:.03em}.mesh-topology__link{stroke:var(--border);stroke-width:calc((var(--space-xs) * 3) / 8);stroke-dasharray:var(--space-xs),var(--space-xs);opacity:.6}.mesh-topology__legend{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--space-md);font-size:calc(var(--space-sm) + var(--space-xs));color:var(--text-muted)}.mesh-topology__legend-item{display:flex;align-items:center;gap:var(--space-sm)}.mesh-topology__notice{margin:var(--space-md) 0 0;text-align:center;color:var(--text-dim);font-size:calc(var(--space-sm) + var(--space-xs))}.mesh-topology__legend-dot{width:calc(var(--space-sm) + var(--space-xs) / 2);height:calc(var(--space-sm) + var(--space-xs) / 2);border-radius:50%;border:1px solid var(--border)}.mesh-topology--empty{justify-content:center}.mesh-topology__empty-state{text-align:center;color:var(--text-muted);font-size:calc(var(--space-md) + var(--space-xs) / 2)}.connect-node-modal{width:min(calc(var(--space-lg) * 30),calc(100vw - (var(--space-lg) * 2)))}.connect-node-form{display:flex;flex-direction:column;gap:var(--space-md)}.connect-node-form .form-group{padding:0;margin-top:0}.connect-node-form .form-group:last-of-type{margin-bottom:0}.connect-node-field{display:flex;flex-direction:column;gap:var(--space-xs)}.connect-node-field__input{width:100%}.connect-node-field__input[aria-invalid=true]{border-color:var(--color-error);background:color-mix(in srgb,var(--color-error) 5%,var(--surface))}.connect-node-field__input[aria-invalid=true]:focus-visible{border-color:var(--color-error);box-shadow:var(--glow-danger)}.connect-node-url-preview{display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) var(--space-md);background:color-mix(in srgb,var(--surface) 50%,var(--bg));border-radius:var(--radius-sm);border-left:var(--space-xs) solid var(--accent);font-size:calc(var(--space-sm) + var(--space-xs))}.connect-node-url-preview-label{color:var(--text-muted)}.connect-node-url-preview code{font-family:var(--font-mono);color:var(--text);font-size:calc(var(--space-sm) + var(--space-xs))}.connect-node-actions{display:flex;justify-content:flex-end;gap:var(--space-sm);padding:var(--modal-padding);border-top:1px solid var(--border)}.nodes-view-topology{margin-bottom:var(--space-md)}.nodes-view-section-title{font-size:calc(var(--space-md) + var(--space-xs) * .5);font-weight:600;color:var(--text);margin:0 0 var(--space-sm)}.nodes-view .node-status-indicator{display:inline-flex;align-items:center;gap:var(--space-xs);font-size:calc(var(--space-sm) + var(--space-xs) * .625)}.nodes-view .node-status-indicator__label,.nodes-view .node-status-indicator--local{color:var(--text-muted)}.nodes-view .node-status-indicator--remote{color:var(--text)}.nodes-view .node-status-indicator__dot{width:var(--space-sm);height:var(--space-sm);border-radius:50%;position:relative;display:inline-block}.nodes-view .node-status-indicator__dot--online{background:var(--color-success);box-shadow:var(--glow-success)}.nodes-view .node-status-indicator__dot--offline,.nodes-view .node-status-indicator__dot--error{background:var(--color-error)}.nodes-view .node-status-indicator__dot--connecting{background:var(--color-warning);animation:pulse-warning 1.5s ease-in-out infinite}.nodes-view .node-status-indicator__spinner{position:absolute;inset:0;border:calc(var(--space-xs) / 2) solid transparent;border-top-color:currentColor;border-radius:50%;animation:spin 1s linear infinite}.nodes-view .node-status-indicator__name{font-weight:500}.nodes-view .node-status-indicator__details{font-size:calc(var(--space-sm) + var(--space-xs));color:var(--text-muted)}@keyframes pulse-warning{0%,to{opacity:1;box-shadow:var(--glow-warning)}50%{opacity:.6;box-shadow:var(--glow-warning)}}@media(max-width:768px){.nodes-view{padding-inline:var(--space-sm)}.nodes-view-grid,.node-card__metrics{grid-template-columns:1fr}.connect-node-modal{width:calc(100vw - (var(--space-md) * 2))}.connect-node-field__input{min-height:calc(var(--space-2xl) + var(--space-md))}.nodes-view-header{padding:var(--space-sm) var(--space-md);flex-wrap:wrap;gap:var(--space-sm)}.nodes-view-title h2{font-size:calc(var(--space-md) + var(--space-xs))}.nodes-view-title h2 svg{flex-shrink:0}.nodes-view-count{font-size:calc(var(--space-sm) + var(--space-xs))}.nodes-view-actions{flex-wrap:wrap;gap:var(--space-sm);width:100%;justify-content:flex-end}.nodes-view-close{min-height:calc(var(--space-xl) + var(--space-md));min-width:calc(var(--space-xl) + var(--space-md))}.nodes-view-actions .btn{min-height:calc(var(--space-xl) + var(--space-md))}.nodes-view-stats{grid-template-columns:repeat(2,1fr);gap:var(--space-sm)}.nodes-view-stat{padding:var(--space-xs) var(--space-sm)}.nodes-view-stat span{font-size:calc(var(--space-sm) + var(--space-xs) * .75)}.nodes-view-stat strong{font-size:calc(var(--space-md) + var(--space-xs) / 2)}.nodes-view-empty{padding:var(--space-xl) var(--space-md);text-align:center}.nodes-view-error{padding:var(--space-md);margin:var(--space-md) 0}.nodes-view-topology{padding:var(--space-sm) 0}.nodes-view-section-title{font-size:calc(var(--space-md) + var(--space-xs) / 4)}}.add-node-modal{width:min(calc(var(--space-lg) * 32.5),calc(100vw - (var(--space-lg) * 2)))}.add-node-modal__body{display:flex;flex-direction:column;gap:var(--space-md)}.add-node-modal__row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.add-node-modal__fieldset{border:1px solid var(--border);border-radius:var(--radius-sm);padding:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-sm)}.add-node-modal__fieldset legend{color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs) * .625);padding:0 var(--space-xs)}.add-node-modal__storage-toggle{border:1px solid var(--border);border-radius:var(--radius-sm);padding:var(--space-sm)}.add-node-modal__advanced-btn{align-self:flex-start}.add-node-modal__advanced{border:1px dashed var(--border);border-radius:var(--radius-sm);padding:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-sm)}.add-node-modal__textarea{min-height:calc(var(--space-2xl) * 2.25);resize:vertical;font-family:var(--font-mono)}.add-node-modal__description{font-size:calc(var(--space-sm) + var(--space-xs) * .625);color:var(--text-muted);margin-bottom:var(--space-sm);padding:0}.add-node-modal__field{display:flex;flex-direction:column;gap:var(--space-xs)}.add-node-modal__field>span{font-size:calc(var(--space-sm) + var(--space-xs) * .625);font-weight:600;color:var(--text-muted)}.add-node-modal__field .input{width:100%;padding:var(--space-sm) var(--space-md);font-size:calc(var(--space-md) + var(--space-xs) * .5)}.add-node-modal__field .input:focus-visible{border-color:var(--accent);box-shadow:var(--focus-ring-strong)}.add-node-modal__field .input[aria-invalid=true]{border-color:var(--color-error);background:color-mix(in srgb,var(--color-error) 5%,var(--surface))}.add-node-modal__field .input[aria-invalid=true]:focus{box-shadow:var(--glow-danger)}.add-node-modal__hint{font-size:calc(var(--space-sm) + var(--space-xs) * .375);color:var(--text-dim);margin-top:calc(var(--space-xs) / 2)}.add-node-modal__error{margin-top:calc(var(--space-xs) / 2)}.add-node-modal__type-toggle{display:flex;gap:0;border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden;background:var(--surface)}.add-node-modal__type-btn{flex:1;padding:calc(var(--space-sm) + var(--space-xs) / 2) var(--space-lg);border:none;background:transparent;color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs) * .625);font-weight:500;cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast)}.add-node-modal__type-btn:hover:not(:disabled){background:color-mix(in srgb,var(--bg) 50%,var(--surface))}.add-node-modal__type-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);z-index:1}.add-node-modal__type-btn.active{background:var(--accent);color:var(--bg)}.add-node-modal__type-btn:disabled{opacity:.6;cursor:not-allowed}.add-node-modal__remote-fields{display:grid;gap:var(--space-sm)}@media(max-width:768px){.add-node-modal{width:calc(100vw - (var(--space-md) * 2))}.add-node-modal__type-toggle{width:100%}.add-node-modal__type-btn{flex:1;padding:var(--space-md) var(--space-lg)}.add-node-modal__field input{min-height:calc(var(--space-2xl) + var(--space-md));font-size:calc(var(--space-md) + var(--space-xs) * .5)}.add-node-modal__row{grid-template-columns:1fr}}.docker-tls-config{display:flex;flex-direction:column;gap:var(--space-md)}.docker-tls-config__fields{display:grid;gap:var(--space-md)}.docker-tls-config__field{display:flex;flex-direction:column;gap:var(--space-xs)}.docker-tls-config__field label{color:var(--text-muted)}@media(max-width:768px){.docker-tls-config .input{min-height:calc(var(--mobile-nav-height) - var(--space-sm))}}.docker-target-selector{display:flex;flex-direction:column;gap:var(--space-md)}.docker-target-selector__modes{display:flex;gap:var(--space-sm);flex-wrap:wrap}.docker-target-selector__mode-active{border-color:var(--todo);box-shadow:var(--focus-ring-strong)}.docker-target-selector__panel{display:grid;gap:var(--space-md)}.docker-target-selector__field{display:flex;flex-direction:column;gap:var(--space-xs)}.docker-target-selector__field label{color:var(--text-muted)}.docker-target-selector__context-row{display:grid;gap:var(--space-sm);grid-template-columns:minmax(0,1fr) auto;align-items:center}.docker-target-selector__status{color:var(--text-muted)}.docker-target-selector__success{color:var(--color-success)}.docker-target-selector__error{color:var(--color-error)}@media(max-width:768px){.docker-target-selector__modes .btn{min-height:calc(var(--mobile-nav-height) - var(--space-sm))}}.docker-onboarding{width:min(calc(var(--space-2xl) * 22.5),calc(100vw - (var(--space-lg) * 2)))}.docker-onboarding__body{display:flex;flex-direction:column;gap:var(--space-md)}.docker-onboarding__section{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-sm)}.docker-onboarding__section-title{margin:0;display:flex;align-items:center;gap:var(--space-sm);font-size:calc(var(--space-md) + var(--space-xs) / 2)}.docker-onboarding__field{display:flex;flex-direction:column;gap:var(--space-xs)}.docker-onboarding__inline-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.docker-onboarding__radio-group{display:flex;align-items:center;gap:var(--space-md);flex-wrap:wrap}.docker-onboarding__type-toggle{display:flex;border:1px solid var(--border);border-radius:var(--radius-sm);overflow:hidden}.docker-onboarding__type-btn{flex:1;border:none;background:var(--surface);color:var(--text);padding:var(--space-sm) var(--space-md);cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast)}.docker-onboarding__type-btn+.docker-onboarding__type-btn{border-left:1px solid var(--border)}.docker-onboarding__type-btn.is-active{background:var(--todo);color:var(--bg)}.docker-onboarding__type-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);position:relative;z-index:1}.docker-onboarding__checkbox-group{display:flex;flex-direction:column;gap:var(--space-xs)}.docker-onboarding__kv-list{display:flex;flex-direction:column;gap:var(--space-sm)}.docker-onboarding__kv-list h5{margin:0;font-size:calc(var(--space-sm) + var(--space-xs))}.docker-onboarding__kv-row{display:grid;gap:var(--space-sm);align-items:center}.docker-onboarding__kv-row--env{grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto}.docker-onboarding__kv-row--mount{grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto auto}.docker-onboarding__kv-add{align-self:flex-start}.docker-onboarding__advanced-toggle{border:none;background:none;color:var(--text);padding:var(--space-xs);margin:calc(var(--space-xs) * -1);border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:space-between;width:100%;cursor:pointer;font-size:calc(var(--space-md) + var(--space-xs) / 2);font-weight:600}.docker-onboarding__advanced-toggle:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.docker-onboarding__advanced-toggle svg{transition:transform var(--transition-fast)}.docker-onboarding__advanced-toggle.is-expanded svg{transform:rotate(180deg)}.docker-onboarding__advanced-content{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--transition-fast)}.docker-onboarding__advanced-content>div{overflow:hidden;display:flex;flex-direction:column;gap:var(--space-sm)}.docker-onboarding__advanced-content.is-expanded{grid-template-rows:1fr}.docker-onboarding__tls-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.docker-onboarding__tls-fields .docker-onboarding__field:first-child{grid-column:1 / -1}@media(max-width:768px){.docker-onboarding{width:calc(100vw - (var(--space-md) * 2))}.docker-onboarding__inline-fields,.docker-onboarding__tls-fields,.docker-onboarding__kv-row{grid-template-columns:1fr}.docker-onboarding .input,.docker-onboarding .select,.docker-onboarding .btn{min-height:calc(var(--space-2xl) + var(--space-md))}.docker-onboarding__advanced-content{transition:none}}.settings-sync-log{display:flex;flex-direction:column;gap:var(--space-sm)}.settings-sync-log__header{display:flex;align-items:center;gap:var(--space-xs);cursor:pointer;padding:var(--space-xs) 0;border-radius:var(--radius-sm);border:none;background:transparent;color:var(--text);font:inherit;text-align:left;transition:background-color var(--transition-fast)}.settings-sync-log__header:hover{background:var(--surface-hover)}.settings-sync-log__header:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);background:var(--surface-hover)}.settings-sync-log__chevron{transform:rotate(0);transition:transform var(--transition-fast)}.settings-sync-log__chevron--expanded{transform:rotate(180deg)}.settings-sync-log__filters{display:flex;gap:var(--space-sm);align-items:center;flex-wrap:wrap}.settings-sync-log__filters label{display:flex;align-items:center;gap:var(--space-xs);font-size:12px;color:var(--text-muted)}.settings-sync-log__filters select{font-size:12px;padding:4px 8px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text)}.settings-sync-log__filters select:focus{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring)}.settings-sync-log__list{display:flex;flex-direction:column}.settings-sync-log__entry{display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-xs) 0;border-bottom:1px solid var(--border)}.settings-sync-log__entry:last-child{border-bottom:none}.settings-sync-log__entry-timestamp{font-size:12px;color:var(--text-muted);min-width:140px}.settings-sync-log__entry-direction{display:flex;align-items:center;color:var(--text-muted)}.settings-sync-log__entry-result{display:inline-flex;padding:2px 8px;border-radius:999px;font-size:11px;font-weight:500}.settings-sync-log__badge--success{background:color-mix(in srgb,var(--color-success, #2da44e) 14%,transparent);color:var(--color-success, #2da44e)}.settings-sync-log__badge--conflict{background:color-mix(in srgb,#d29922 14%,transparent);color:#d29922}.settings-sync-log__badge--error{background:color-mix(in srgb,var(--color-error, #cf222e) 14%,transparent);color:var(--color-error, #cf222e)}.settings-sync-log__entry-node{font-weight:500;font-size:12px}.settings-sync-log__entry-details{font-size:12px;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.settings-sync-log__empty{text-align:center;color:var(--text-muted);padding:var(--space-md);font-size:13px}.node-badge{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:color-mix(in srgb,var(--accent) 14%,transparent);border:1px solid color-mix(in srgb,var(--accent) 36%,transparent);color:var(--text-muted);font-size:11px;width:fit-content;margin-top:4px}@media(max-width:768px){.settings-sync-conflict-modal__diff-panel{grid-template-columns:1fr}}.settings-sync-conflict-modal{max-width:860px;width:min(860px,calc(100vw - 32px))}.settings-sync-conflict-modal__conflict-list{display:flex;flex-direction:column;gap:var(--space-md);max-height:min(50vh,400px);overflow-y:auto}.settings-sync-conflict-modal__conflict-item{border:1px solid var(--border);border-radius:var(--radius);padding:var(--space-md)}.settings-sync-conflict-modal__key{font-weight:600;font-family:monospace;margin-bottom:var(--space-sm)}.settings-sync-conflict-modal__diff-panel{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-sm);margin-bottom:var(--space-sm)}.settings-sync-conflict-modal__diff-side{border:1px solid var(--border);border-radius:var(--radius-sm);overflow:hidden}.settings-sync-conflict-modal__diff-label{font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted);padding:4px 8px;border-bottom:1px solid var(--border);background:var(--surface)}.settings-sync-conflict-modal__diff-content{padding:var(--space-xs) var(--space-sm);white-space:pre;font-family:monospace;font-size:12px;line-height:1.5;overflow-x:auto}.settings-sync-conflict-modal__resolution{display:flex;gap:var(--space-md);align-items:center}.settings-sync-conflict-modal__resolution label{display:flex;align-items:center;gap:var(--space-xs);cursor:pointer}.settings-sync-conflict-modal__resolution input[type=radio]{cursor:pointer}.settings-sync-conflict-modal__manual-input{width:100%;font-family:monospace;font-size:12px;min-height:80px;margin-top:var(--space-xs);padding:var(--space-sm);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);resize:vertical}.settings-sync-conflict-modal__manual-input:focus{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring)}.settings-sync-conflict-modal__bulk-actions{display:flex;gap:var(--space-xs);padding-top:var(--space-sm);border-top:1px solid var(--border)}.settings-sync-conflict-modal__footer{display:flex;justify-content:flex-end;gap:var(--space-xs)}.node-detail-modal{max-width:calc(var(--space-lg) * 53.75);width:min(calc(var(--space-lg) * 53.75),calc(100vw - (var(--space-lg) * 2)))}.node-detail-modal__body{display:flex;flex-direction:column;gap:var(--space-md);max-height:min(72vh,calc(var(--space-lg) * 42.5));overflow-y:auto}.node-detail-modal__section{border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-md)}.node-detail-modal__section h4{margin:0 0 var(--space-sm) 0}.node-detail-modal__section-header{display:flex;justify-content:space-between;align-items:center;gap:var(--space-sm);margin-bottom:var(--space-sm)}.node-detail-modal__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.node-detail-modal__field{display:flex;flex-direction:column;gap:var(--space-xs)}.node-detail-modal__field--full{grid-column:span 2}.node-detail-modal__field span{color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs))}.node-detail-modal__edit-actions{margin-top:var(--space-sm);display:flex;gap:var(--space-xs)}.node-detail-modal__project-list{margin:0;padding-left:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-sm)}.node-detail-modal__project-item{display:flex;justify-content:space-between;align-items:center;gap:var(--space-sm)}.node-detail-modal__project-item code{color:var(--text-muted)}.node-detail-modal__empty{margin:0;color:var(--text-muted)}.node-detail-modal__health-row{display:flex;flex-wrap:wrap;gap:var(--space-md)}.node-detail-modal__actions{justify-content:space-between}.node-detail-modal__docker-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm);margin-top:var(--space-sm)}.node-detail-modal__textarea{min-height:calc(var(--space-2xl) * 2.25);resize:vertical;font-family:var(--font-mono)}.node-detail-modal__sync-status{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-sm);margin-bottom:var(--space-sm)}.node-detail-modal__sync-dot{width:calc(var(--space-sm) + var(--space-xs) / 2);height:calc(var(--space-sm) + var(--space-xs) / 2);border-radius:50%;flex-shrink:0}.node-detail-modal__sync-dot--synced{background:var(--color-success)}.node-detail-modal__sync-dot--diff,.node-detail-modal__sync-dot--pending{background:var(--color-warning)}.node-detail-modal__sync-dot--error{background:var(--color-error)}.node-detail-modal__sync-dot--never{background:var(--text-muted)}.node-detail-modal__sync-diff{color:var(--color-warning);font-size:calc(var(--space-sm) + var(--space-xs))}.node-detail-modal__sync-actions{display:flex;flex-wrap:wrap;gap:var(--space-sm);margin-top:var(--space-sm)}.node-detail-modal__sync-error{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm);margin-top:var(--space-sm);padding:var(--space-sm);background:color-mix(in srgb,var(--color-error) 10%,transparent);border:1px solid color-mix(in srgb,var(--color-error) 30%,transparent);border-radius:var(--radius-sm);color:var(--color-error);font-size:calc(var(--space-sm) + var(--space-xs))}.node-detail-modal__sync-error-dismiss{background:transparent;border:none;color:var(--color-error);cursor:pointer;padding:calc(var(--space-xs) / 2);display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm)}.node-detail-modal__sync-error-dismiss:hover{background:color-mix(in srgb,var(--color-error) 20%,transparent)}.node-detail-modal__sync-error-dismiss:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);background:color-mix(in srgb,var(--color-error) 20%,transparent)}@media(max-width:768px){.node-detail-modal__grid,.node-detail-modal__docker-grid{grid-template-columns:1fr}.node-detail-modal__field--full{grid-column:span 1}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as o,j as s}from"./vendor-react-K0fH_qHe.js";import{z as T,dP as ee,s as se,X as O,aq as ne,O as A,dQ as _,_ as M,R as te,dR as ie,aJ as ae,cc as le,dS as re,dT as ce,dU as de,dV as ue,dW as V,c9 as oe}from"./index-k_85J1DS.js";import{D as me}from"./DirectoryPicker-WPDSBdT6.js";import"./vendor-xterm-DzcZoU0P.js";import"./folder-open-BNQW9dE9.js";const ge=[{id:"fusion-plugin-agent-browser-runtime",name:"Agent Browser Runtime",path:"./plugins/fusion-plugin-agent-browser-runtime",experimental:!0},{id:"fusion-plugin-hermes-runtime",name:"Hermes Runtime",path:"./plugins/fusion-plugin-hermes-runtime",experimental:!0},{id:"fusion-plugin-paperclip-runtime",name:"Paperclip Runtime",path:"./plugins/fusion-plugin-paperclip-runtime"},{id:"fusion-plugin-openclaw-runtime",name:"OpenClaw Runtime",path:"./plugins/fusion-plugin-openclaw-runtime",experimental:!0}],N={started:"var(--color-success)",loaded:"var(--color-warning)",error:"var(--color-error)",stopped:"var(--color-muted)",installed:"var(--color-info)"};function fe({addToast:l,projectId:c}){const[x,b]=o.useState([]),[S,w]=o.useState(!0),[H,f]=o.useState(!1),[j,v]=o.useState(""),[C,P]=o.useState(!1),[h,R]=o.useState(null),[i,y]=o.useState(null),[a,p]=o.useState({}),[J,$]=o.useState(!1),[I,E]=o.useState(null),{confirm:G}=T(),m=o.useCallback(async()=>{try{w(!0);const e=await ee(c);b(e)}catch(e){l(`Failed to load plugins: ${e instanceof Error?e.message:String(e)}`,"error")}finally{w(!1)}},[c,l]);o.useEffect(()=>{m()},[m]);const K=o.useRef([]);K.current=x,o.useEffect(()=>{const e=c?`?projectId=${encodeURIComponent(c)}`:"",n=d=>{try{const t=JSON.parse(d.data);if(c&&t.projectId&&t.projectId!==c)return;switch(t.transition){case"installing":case"enabled":case"disabled":case"settings-updated":b(u=>{const g=u.findIndex(r=>r.id===t.pluginId);if(g>=0){const r=[...u];return r[g]={...r[g],enabled:t.enabled,state:t.state,settings:t.settings,error:t.error},r}else return m(),u});break;case"uninstalled":b(u=>u.filter(g=>g.id!==t.pluginId));break;case"error":b(u=>{const g=u.findIndex(r=>r.id===t.pluginId);if(g>=0){const r=[...u];return r[g]={...r[g],state:t.state,error:t.error},r}return u});break}}catch{}};return se(`/api/events${e}`,{events:{"plugin:lifecycle":n},onReconnect:()=>{m()}})},[c,m]);const z=async()=>{if(!j.trim()){l("Please enter a plugin path","error");return}try{P(!0),await V({path:j},c),l("Plugin installed successfully","success"),f(!1),v(""),await m()}catch(e){l(`Failed to install plugin: ${e instanceof Error?e.message:String(e)}`,"error")}finally{P(!1)}},Q=async e=>{try{E(e.id),await V({path:e.path},c),l(`${e.name} installed successfully`,"success"),await m()}catch(n){l(`Failed to install ${e.name}: ${n instanceof Error?n.message:String(n)}`,"error")}finally{E(null)}},B=async e=>{try{await de(e.id,c),l(`${e.name} enabled`,"success"),await m()}catch(n){l(`Failed to enable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},F=async e=>{try{await ce(e.id,c),l(`${e.name} disabled`,"success"),await m()}catch(n){l(`Failed to disable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},U=async e=>{try{R(e.id),await re(e.id,c),l(`${e.name} reloaded`,"success"),await m()}catch(n){l(`Failed to reload plugin: ${n instanceof Error?n.message:String(n)}`,"error")}finally{R(null)}},L=async e=>{if(await G({title:"Uninstall Plugin",message:`Are you sure you want to uninstall "${e.name}"?`,danger:!0}))try{await ue(e.id,c),l(`${e.name} uninstalled`,"success"),await m(),y(null)}catch(d){l(`Failed to uninstall plugin: ${d instanceof Error?d.message:String(d)}`,"error")}},q=async e=>{y(e);try{$(!0);const n=await oe(e.id,c);p(n)}catch{p({})}finally{$(!1)}},W=async()=>{if(i)try{await le(i.id,a,c),l("Settings saved","success")}catch(e){l(`Failed to save settings: ${e instanceof Error?e.message:String(e)}`,"error")}};if(i)return s.jsxs("div",{className:"plugin-manager-detail","data-testid":"plugin-manager-detail",children:[s.jsxs("div",{className:"plugin-manager-detail-header",children:[s.jsx("button",{className:"btn-icon",onClick:()=>y(null),"aria-label":"Back to plugin list",children:s.jsx(O,{size:16})}),s.jsxs("div",{className:"plugin-detail-title",children:[s.jsx("h4",{className:"plugin-detail-name",children:i.name}),s.jsx("span",{className:"plugin-state-badge",style:{color:N[i.state]||N.installed},children:i.state})]})]}),s.jsxs("div",{className:"plugin-detail-content",children:[s.jsxs("div",{className:"plugin-detail-card",children:[i.description&&s.jsx("p",{className:"plugin-description",children:i.description}),i.author&&s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Author:"}),i.author]}),i.homepage&&s.jsxs("p",{className:"plugin-detail-meta-row plugin-homepage",children:[s.jsx("span",{className:"text-muted",children:"Homepage:"}),s.jsxs("a",{href:i.homepage,target:"_blank",rel:"noopener noreferrer",children:[i.homepage,s.jsx(ne,{size:12})]})]}),s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Version:"}),i.version]})]}),s.jsxs("div",{className:"plugin-detail-card",children:[s.jsx("h5",{className:"plugin-detail-section-heading",children:"Settings"}),J?s.jsx("p",{className:"text-muted",children:"Loading..."}):i.settingsSchema&&Object.keys(i.settingsSchema).length>0?s.jsxs("div",{className:"plugin-settings-form",children:[Object.entries(i.settingsSchema).map(([e,n])=>{const d=`setting-${e}-help`;return s.jsxs("div",{className:"form-group",children:[s.jsxs("label",{htmlFor:`setting-${e}`,children:[n.label||e,n.required&&" *"]}),n.type==="string"&&!n.multiline&&s.jsx("input",{className:"input",type:"text",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="string"&&n.multiline&&s.jsx("textarea",{className:"input",id:`setting-${e}`,rows:4,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="password"&&s.jsx("input",{className:"input",type:"password",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="number"&&s.jsx("input",{className:"input",type:"number",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:Number(t.target.value)}),"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="boolean"&&s.jsxs("label",{className:"checkbox-label",children:[s.jsx("input",{type:"checkbox",checked:a[e]??!1,onChange:t=>p({...a,[e]:t.target.checked})}),n.description]}),n.type==="enum"&&s.jsxs("select",{className:"select",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),"aria-describedby":n.description&&!n.required?d:void 0,children:[s.jsx("option",{value:"",children:"Select..."}),n.enumValues?.map(t=>s.jsx("option",{value:t,children:t},t))]}),n.type==="array"&&s.jsxs("div",{className:"plugin-settings-array",children:[a[e]?.map((t,u)=>s.jsxs("div",{className:"plugin-settings-array-item",children:[s.jsx("input",{className:"input",type:n.itemType==="number"?"number":"text",value:t??"",onChange:g=>{const r=g.target.value,k=[...a[e]||[]];k[u]=n.itemType==="number"?Number(r):r,p({...a,[e]:k})}}),s.jsx("button",{className:"btn-icon",onClick:()=>{const r=[...a[e]||[]];r.splice(u,1),p({...a,[e]:r})},"aria-label":"Remove item",children:s.jsx(O,{size:14})})]},u)),s.jsxs("button",{className:"btn btn-secondary",onClick:()=>{const t=a[e]||[],u=n.itemType==="number"?0:"";p({...a,[e]:[...t,u]})},children:[s.jsx(A,{size:14})," Add Item"]})]}),n.description&&!n.required&&!n.multiline&&s.jsx("span",{id:d,className:"form-help",children:n.description})]},e)}),s.jsx("button",{className:"btn btn-primary",onClick:W,children:"Save Settings"})]}):s.jsx("p",{className:"text-muted",children:"No configurable settings."})]}),s.jsxs("div",{className:"plugin-detail-actions",children:[i.state==="started"&&s.jsxs("button",{className:"btn btn-secondary",onClick:()=>U(i),disabled:h===i.id,children:[s.jsx(_,{size:14,className:h===i.id?"spin":""}),h===i.id?"Reloading...":"Reload"]}),i.enabled?s.jsx("button",{className:"btn btn-secondary",onClick:()=>F(i),children:"Disable"}):s.jsx("button",{className:"btn btn-primary",onClick:()=>B(i),children:"Enable"}),s.jsxs("button",{className:"btn btn-danger",onClick:()=>L(i),children:[s.jsx(M,{size:14})," Uninstall"]})]})]})]});const X=new Set(x.map(e=>e.id)),Y=new Map(x.map(e=>[e.id,e])),D=x,Z=()=>s.jsxs("section",{className:"plugin-bundled-runtime-section","aria-label":"Bundled Runtime Plugins",children:[s.jsxs("div",{className:"plugin-bundled-runtime-header",children:[s.jsx("h4",{className:"plugin-bundled-runtime-heading",children:"Bundled Runtime Plugins"}),s.jsx("p",{className:"plugin-bundled-runtime-description",children:"Install Fusion's bundled runtimes directly from this screen."})]}),s.jsx("div",{className:"plugin-bundled-runtime-list","aria-label":"Bundled runtime plugin recommendations",children:ge.map(e=>{const n=X.has(e.id);return s.jsxs("div",{className:"plugin-bundled-runtime-item",children:[s.jsxs("div",{className:"plugin-bundled-runtime-meta",children:[s.jsx("span",{className:"plugin-bundled-runtime-name",children:e.name}),e.experimental&&s.jsx("span",{className:"plugin-bundled-runtime-badge",children:"Experimental"}),s.jsx("span",{className:`plugin-bundled-runtime-status ${n?"plugin-bundled-runtime-status--installed":"plugin-bundled-runtime-status--available"}`,children:n?"Installed":"Not installed"})]}),s.jsx("button",{className:`btn ${n?"btn-secondary":"btn-primary"} btn-sm`,onClick:()=>{if(n){const d=Y.get(e.id);d&&q(d);return}Q(e)},disabled:I===e.id,children:n?"Manage":I===e.id?"Installing...":`Install ${e.name}`})]},e.id)})})]});return s.jsxs("div",{className:"plugin-manager","data-testid":"plugin-manager",children:[s.jsxs("div",{className:"plugin-manager-header",children:[s.jsx("span",{className:"plugin-manager-header-title",children:"Installed Plugins"}),s.jsxs("div",{className:"plugin-manager-actions",children:[s.jsxs("button",{className:"btn btn-sm",onClick:m,title:"Refresh","aria-label":"Refresh plugin list",children:[s.jsx(te,{size:14,className:S?"spin":""}),"Refresh"]}),s.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>f(!0),children:[s.jsx(A,{size:14})," Install"]})]})]}),H&&s.jsxs("div",{className:"plugin-install-form",children:[s.jsxs("p",{className:"plugin-install-hint",children:["Browse to a plugin package root (contains ",s.jsx("code",{children:"manifest.json"}),") or a built ",s.jsx("code",{children:"dist"})," directory."]}),s.jsx(me,{value:j,onChange:v,placeholder:"Absolute path to plugin directory or dist folder",onInputKeyDown:e=>{e.key==="Enter"&&(e.preventDefault(),z())}}),s.jsxs("div",{className:"plugin-install-actions",children:[s.jsx("button",{className:"btn btn-primary",onClick:z,disabled:C||!j.trim(),children:C?"Installing...":"Install Plugin"}),s.jsx("button",{className:"btn btn-secondary",onClick:()=>{f(!1),v("")},children:"Cancel"})]})]}),S?s.jsx("div",{className:"settings-empty-state",children:"Loading plugins..."}):s.jsxs(s.Fragment,{children:[D.length===0?s.jsxs("div",{className:"settings-empty-state",children:[s.jsx(ie,{size:32,className:"text-muted"}),s.jsx("p",{children:"No plugins installed."}),s.jsx("p",{className:"text-muted",children:"Install a plugin to get started, or use a bundled runtime below."})]}):s.jsx("div",{className:"plugin-list",children:D.map(e=>s.jsxs("div",{className:"plugin-item",children:[s.jsxs("div",{className:"plugin-info",children:[s.jsx("span",{className:"plugin-name",children:e.name}),s.jsxs("span",{className:"plugin-version text-muted",children:["v",e.version]}),s.jsx("span",{className:"plugin-state-badge",style:{color:N[e.state]||N.installed},children:e.state})]}),s.jsxs("div",{className:"plugin-actions",children:[e.state==="started"&&s.jsx("button",{className:"btn-icon",onClick:()=>U(e),disabled:h===e.id,title:"Reload",children:s.jsx(_,{size:14,className:h===e.id?"spin":""})}),s.jsxs("label",{className:"toggle-switch",children:[s.jsx("input",{type:"checkbox",checked:e.enabled,onChange:()=>e.enabled?F(e):B(e)}),s.jsx("span",{className:"toggle-slider"})]}),s.jsx("button",{className:"btn-icon",onClick:()=>q(e),title:"Settings",children:s.jsx(ae,{size:14})}),s.jsx("button",{className:"btn-icon",onClick:()=>L(e),title:"Uninstall",children:s.jsx(M,{size:14})})]})]},e.id))}),Z()]})]})}export{fe as PluginManager,N as STATE_COLORS};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{at as ie,au as ce,s as le,av as oe,aw as de,ax as ue,ay as he,az as me,aA as ve,u as be,aB as xe,E as fe,aC as pe,L as je,S as ge}from"./index-k_85J1DS.js";import"./vendor-xterm-DzcZoU0P.js";const D={webSearch:!0,pageFetch:!0,github:!1,localDocs:!0,llmSynthesis:!0};function W(d){const t=d?.researchGlobalDefaults,u=d?.researchSettings;return{enabled:u?.enabled??d?.researchEnabled??d?.researchGlobalEnabled??!0,searchProvider:u?.searchProvider??t?.searchProvider,synthesisProvider:u?.synthesisProvider??t?.synthesisProvider,synthesisModelId:u?.synthesisModelId??t?.synthesisModelId,enabledSources:{webSearch:u?.enabledSources?.webSearch??t?.enabledSources?.webSearch??D.webSearch,pageFetch:u?.enabledSources?.pageFetch??t?.enabledSources?.pageFetch??D.pageFetch,github:u?.enabledSources?.github??t?.enabledSources?.github??D.github,localDocs:u?.enabledSources?.localDocs??t?.enabledSources?.localDocs??D.localDocs,llmSynthesis:u?.enabledSources?.llmSynthesis??t?.enabledSources?.llmSynthesis??D.llmSynthesis},limits:{maxConcurrentRuns:u?.limits?.maxConcurrentRuns??d?.researchMaxConcurrentRuns??d?.researchGlobalMaxConcurrentRuns??3,maxSourcesPerRun:u?.limits?.maxSourcesPerRun??t?.maxSourcesPerRun??d?.researchMaxSourcesPerRun??d?.researchGlobalMaxSourcesPerRun??20,maxDurationMs:u?.limits?.maxDurationMs??d?.researchDefaultTimeout??d?.researchGlobalDefaultTimeout??3e5,requestTimeoutMs:u?.limits?.requestTimeoutMs??d?.researchFetchTimeoutMs??3e4},defaultExportFormat:t?.defaultExportFormat??"markdown"}}const ye=300,Se=4e3;function _e(d){const t=d?.projectId,[u,x]=a.useState([]),[m,r]=a.useState(null),[I,g]=a.useState(null),[f,S]=a.useState({available:!0}),[R,N]=a.useState(!0),[M,k]=a.useState(null),[y,C]=a.useState(""),_=a.useRef(0),E=a.useRef(0),T=a.useRef(t);a.useEffect(()=>{T.current!==t&&(T.current=t,E.current++)},[t]);const p=a.useCallback(async(c=y)=>{const l=++_.current,i=t;k(null);try{const n=await ie({q:c||void 0,limit:100},i);if(l!==_.current||i!==t)return;x(n.runs),S(n.availability),m&&!n.runs.some(b=>b.id===m)&&(r(null),g(null))}catch(n){if(l!==_.current||i!==t)return;k(n instanceof Error?n.message:"Failed to load research runs")}finally{l===_.current&&N(!1)}},[t,y,m]),j=a.useCallback(async c=>{const l=await ce(c,t);return g(l.run),S(l.availability),l.run},[t]);return a.useEffect(()=>{N(!0);const c=window.setTimeout(()=>{p(y)},ye);return()=>window.clearTimeout(c)},[p,y]),a.useEffect(()=>{if(!m){g(null);return}j(m)},[j,m]),a.useEffect(()=>{const c=E.current,l=()=>E.current!==c,i=t?`?projectId=${encodeURIComponent(t)}`:"";let n=!0;const b=()=>{!n||l()||(p(),m&&j(m))},L=le(`/api/events${i}`,{events:{"research:run:created":b,"research:run:updated":b,"research:run:completed":b,"research:run:failed":b,"research:run:cancelled":b},onReconnect:b}),q=window.setInterval(b,Se);return()=>{n=!1,L(),window.clearInterval(q)}},[t,p,m,j]),{runs:u,selectedRun:I,selectedRunId:m,setSelectedRunId:r,availability:f,loading:R,error:M,searchQuery:y,setSearchQuery:C,refresh:p,createRun:c=>ve(c,t),cancelRun:async c=>{const l=await me(c,t);return m===c&&g(l.run),await p(),l},retryRun:async c=>{const l=await he(c,t);return m===c&&g(l.run),await p(),l},exportRun:(c,l)=>ue(c,l,t),createTaskFromRun:(c,l,i,n,b,L)=>de(c,{title:l,findingId:i,description:n,priority:b,attachExport:L},t),attachRunToTask:(c,l,i,n)=>oe(c,{taskId:l,findingId:i,attachExport:n},t),statusCounts:u.reduce((c,l)=>(c[l.status]+=1,c),{queued:0,running:0,cancelling:0,retry_waiting:0,completed:0,failed:0,cancelled:0,timed_out:0,retry_exhausted:0})}}function Re({open:d,mode:t,run:u,finding:x,projectId:m,onClose:r,onConfirm:I}){be(d);const[g,f]=a.useState(!1),[S,R]=a.useState(""),[N,M]=a.useState(""),[k,y]=a.useState("normal"),[C,_]=a.useState(""),[E,T]=a.useState([]),[p,j]=a.useState(!1),[c,l]=a.useState(!1),i=a.useMemo(()=>{const n=(x.content??"").split(/(?<=[.!?])\s+/)[0]??"";return`${x.heading||"Research finding"} — ${n}`.trim()},[x.content,x.heading]);return a.useEffect(()=>{d&&(f(!1),R(`Research: ${x.heading||u.title}`),M(i),y("normal"),_(""),t==="enrich"&&(j(!0),xe(50,0,m).then(n=>T(n.filter(b=>b.column!=="archived"))).finally(()=>j(!1))))},[d,t,m,x.heading,i,u.title]),d?e.jsx("div",{className:"modal-overlay open",role:"presentation",onClick:r,children:e.jsxs("div",{className:"modal modal-lg research-task-action-modal",role:"dialog","aria-modal":"true",onClick:n=>n.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:t==="create"?"Create task from finding":"Enrich existing task"}),e.jsx("button",{className:"modal-close",type:"button","aria-label":"Close",onClick:r,children:"×"})]}),e.jsxs("div",{className:"research-task-action-modal__body",children:[e.jsxs("div",{className:"card research-task-action-modal__preview",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Run:"})," ",u.id]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Finding:"})," ",x.id,x.heading?` — ${x.heading}`:""]}),e.jsx("p",{children:i||"No preview available."})]}),t==="create"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"research-task-action-modal__field",children:["Title",e.jsx("input",{className:"input",value:S,onChange:n=>R(n.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Description",e.jsx("textarea",{className:"input research-task-action-modal__textarea",value:N,onChange:n=>M(n.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Priority",e.jsxs("select",{className:"select",value:k,onChange:n=>y(n.target.value),children:[e.jsx("option",{value:"low",children:"Low"}),e.jsx("option",{value:"normal",children:"Normal"}),e.jsx("option",{value:"high",children:"High"}),e.jsx("option",{value:"urgent",children:"Urgent"})]})]})]}):e.jsxs("label",{className:"research-task-action-modal__field",children:["Target task",e.jsx("input",{className:"input",list:"research-task-action-task-list",value:C,placeholder:p?"Loading tasks…":"Enter task ID",onChange:n=>_(n.target.value)}),e.jsx("datalist",{id:"research-task-action-task-list",children:E.map(n=>e.jsx("option",{value:n.id,children:n.title},n.id))})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:g,onChange:n=>f(n.target.checked)}),e.jsx("span",{children:"Attach markdown export artifact"})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:r,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",type:"button",disabled:c||t==="enrich"&&!C,onClick:()=>{l(!0),I({taskId:t==="enrich"?C:void 0,title:t==="create"?S.trim():void 0,description:t==="create"?N.trim():void 0,priority:t==="create"?k:void 0,attachExport:g}).finally(()=>l(!1))},children:t==="create"?"Create Task":"Enrich Task"})]})]})}):null}const we=["web-search","page-fetch","github","local-docs","llm-synthesis"],Ne={"web-search":"webSearch","page-fetch":"pageFetch",github:"github","local-docs":"localDocs","llm-synthesis":"llmSynthesis"},ke={"web-search":"Web Search","page-fetch":"Page Fetch",github:"GitHub","local-docs":"Local Docs","llm-synthesis":"LLM Synthesis"};function Te({projectId:d,addToast:t,onOpenSettings:u,readinessVersion:x=0}){const{runs:m,selectedRun:r,selectedRunId:I,setSelectedRunId:g,availability:f,loading:S,error:R,searchQuery:N,setSearchQuery:M,createRun:k,cancelRun:y,retryRun:C,exportRun:_,createTaskFromRun:E,attachRunToTask:T,statusCounts:p,refresh:j}=_e({projectId:d}),[c,l]=a.useState(""),[i,n]=a.useState(()=>W(void 0)),[b,L]=a.useState([]),[q,Q]=a.useState(!1),[Y,X]=a.useState([]),[A,O]=a.useState(null),[P,$]=a.useState(null),B=f.supportedProviders??we,U=s=>i.enabledSources[Ne[s]];a.useEffect(()=>{const s=B.filter(o=>U(o));X(o=>{const v=o.filter(h=>s.includes(h));return v.length>0?v:s})},[i.enabledSources,B]),a.useEffect(()=>{let s=!1;return Promise.all([fe(d),pe().catch(()=>({providers:[]}))]).then(([o,v])=>{s||(n(W(o)),L(v.providers.filter(h=>h.type==="api_key").map(h=>({id:h.id,authenticated:h.authenticated}))))}).catch(()=>{s||n(W(void 0))}),()=>{s=!0}},[d,x]);const re=a.useMemo(()=>r?r.status:"No run selected",[r]),ae=a.useMemo(()=>r?r.status==="queued"||r.status==="retry_waiting"?"status-dot status-dot--pending":r.status==="running"?"status-dot status-dot--connecting":r.status==="completed"?"status-dot status-dot--online":r.status==="failed"||r.status==="cancelled"?"status-dot status-dot--error":"status-dot":"status-dot",[r]),H=f.supportedExportFormats??["markdown","json","html"],V=i.searchProvider,Z=i.enabledSources.webSearch&&!V,ee=i.enabledSources.llmSynthesis&&(!i.synthesisProvider||!i.synthesisModelId),z=a.useMemo(()=>new Map(b.map(s=>[s.id,s.authenticated])),[b]),K=a.useMemo(()=>{const s=new Set;return i.enabledSources.webSearch&&V&&s.add(V),i.enabledSources.llmSynthesis&&i.synthesisProvider&&s.add(i.synthesisProvider),[...s].filter(o=>z.has(o))},[i.enabledSources.llmSynthesis,i.enabledSources.webSearch,i.synthesisProvider,V,z]).find(s=>z.get(s)!==!0),F=a.useMemo(()=>f.available?i.enabled?Z||ee?{reason:"Research defaults are incomplete.",details:"Select the required provider/model defaults in Research settings.",settingsSection:"research-global"}:K?{reason:`Missing API key for ${K}.`,details:"Add provider credentials in Authentication settings.",settingsSection:"authentication"}:null:{reason:"Research is disabled for this project.",details:"Enable project research settings to create runs.",settingsSection:"research-project"}:{reason:f.reason??"Research is unavailable for this project.",details:f.setupInstructions,settingsSection:"research-project"},[f.available,f.reason,f.setupInstructions,i.enabled,K,Z,ee]),G=async(s,o,v)=>{O(s);try{await o(),t?.(v,"success"),await j()}catch(h){t?.(h instanceof Error?h.message:"Action failed","error")}finally{O(null)}},J=async s=>{if(r){O(`export-${s}`);try{const o=await _(r.id,s),v=new Blob([o.content],{type:"text/plain;charset=utf-8"}),h=URL.createObjectURL(v),w=document.createElement("a");w.href=h,w.download=o.filename,document.body.appendChild(w),w.click(),w.remove(),URL.revokeObjectURL(h),t?.(`Exported ${o.filename}`,"success")}catch(o){t?.(o instanceof Error?o.message:"Export failed","error")}finally{O(null)}}},ne=async()=>{if(c.trim()){Q(!0);try{const s=Y.filter(v=>U(v));if(s.length===0){Q(!1),t?.("No enabled research sources are available for this project.","error");return}const o=await k({query:c.trim(),providers:s});g(o.run.id),l(""),t?.("Research run created","success"),await j()}catch(s){t?.(s instanceof Error?s.message:"Failed to create run","error")}finally{Q(!1)}}};return e.jsxs("section",{className:"research-view","aria-label":"Research view",children:[e.jsxs("header",{className:"research-view__header",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"research-view__title",children:"Research"}),e.jsx("p",{className:"research-view__subtitle",children:"Create and track research runs with cited findings."})]}),e.jsx("button",{className:"btn",type:"button",onClick:()=>void j(),children:"Refresh"})]}),F?e.jsxs("div",{className:"research-view__state research-view__state--error card","data-testid":"research-state-unavailable",children:[e.jsx("p",{children:F.reason}),F.details&&e.jsx("p",{children:F.details}),e.jsxs("p",{children:["Current defaults: provider ",i.searchProvider??"(not set)",", max sources ",i.limits.maxSourcesPerRun]}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:()=>void j(),children:"Refresh"}),e.jsx("button",{className:"btn btn-primary",type:"button",onClick:()=>u?.(F.settingsSection),children:"Open Settings"})]})]}):e.jsxs("div",{className:"research-view__layout",children:[e.jsxs("aside",{className:"research-view__sidebar card",children:[e.jsxs("div",{className:"research-view__form",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-query",children:"Query"}),e.jsx("textarea",{id:"research-query",className:"input research-view__textarea",value:c,onChange:s=>l(s.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Providers"}),e.jsx("div",{className:"research-view__providers",children:B.map(s=>e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:Y.includes(s),disabled:!U(s),onChange:()=>{U(s)&&X(o=>o.includes(s)?o.filter(v=>v!==s):[...o,s])}}),e.jsx("span",{children:ke[s]??s})]},s))})]}),e.jsxs("button",{className:"btn btn-primary",type:"button",disabled:!c.trim()||q,onClick:()=>void ne(),children:[q?e.jsx(je,{className:"animate-spin",size:14}):null,"Create Run"]})]}),e.jsxs("div",{className:"research-view__history-header form-group",children:[e.jsx("label",{htmlFor:"research-run-search",children:"Search"}),e.jsxs("div",{className:"research-view__history-search-row",children:[e.jsx(ge,{size:14}),e.jsx("input",{id:"research-run-search",className:"input",placeholder:"Search runs",value:N,onChange:s=>M(s.target.value)})]})]}),e.jsx("div",{className:"research-view__history","data-testid":"research-state-running",children:m.map(s=>e.jsxs("button",{type:"button",className:`research-view__history-item card${I===s.id?" research-view__history-item--active":""}`,onClick:()=>g(s.id),children:[e.jsx("span",{className:"card-id",children:s.id}),e.jsx("span",{children:s.title})]},s.id))})]}),e.jsxs("div",{className:"research-view__reader card",children:[S&&e.jsx("p",{"data-testid":"research-state-loading",children:"Loading research runs…"}),!S&&R&&e.jsx("p",{"data-testid":"research-state-error",children:R}),!S&&!R&&m.length===0&&e.jsx("p",{"data-testid":"research-state-empty",children:"No research runs yet"}),r&&e.jsxs("div",{children:[e.jsxs("div",{className:"research-view__status-row",children:[e.jsx("span",{className:ae}),e.jsx("strong",{children:re})]}),e.jsx("h3",{className:"research-view__run-title",children:r.title}),e.jsx("p",{className:"research-view__run-query",children:r.query}),e.jsx("p",{className:"research-view__run-summary","data-testid":"research-state-results",children:r.results?.summary??"No summary yet."}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",disabled:A==="cancel",onClick:()=>void G("cancel",()=>y(r.id),"Run cancelled"),children:"Cancel"}),e.jsx("button",{className:"btn",type:"button",disabled:A==="retry",onClick:()=>void G("retry",()=>C(r.id),"Run retried"),children:"Retry"}),H.includes("markdown")&&e.jsx("button",{className:"btn",type:"button",disabled:A==="export-markdown",onClick:()=>void J("markdown"),children:"Export MD"}),H.includes("json")&&e.jsx("button",{className:"btn",type:"button",disabled:A==="export-json",onClick:()=>void J("json"),children:"Export JSON"}),H.includes("html")&&e.jsx("button",{className:"btn",type:"button",disabled:A==="export-html",onClick:()=>void J("html"),children:"Export HTML"})]}),r.error&&e.jsx("p",{className:"research-view__error",children:r.error}),Array.isArray(r.results?.findings)&&r.results.findings.length>0&&e.jsx("div",{className:"research-view__findings",children:r.results.findings.map((s,o)=>{const h=s.id?.trim()||`finding-${o+1}`;return e.jsxs("article",{className:"research-view__finding card",children:[e.jsx("h4",{children:s.heading}),e.jsx("p",{children:s.content}),e.jsxs("div",{className:"research-view__actions research-view__finding-actions",children:[e.jsx("button",{className:"btn btn-primary btn-sm",type:"button",onClick:()=>$({mode:"create",findingId:h}),children:"Create Task"}),e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>$({mode:"enrich",findingId:h}),children:"Enrich Task"})]})]},h)})}),Array.isArray(r.results?.citations)&&r.results.citations.length>0&&e.jsx("ul",{className:"research-view__citations",children:r.results.citations.map(s=>e.jsx("li",{children:e.jsx("a",{href:s,target:"_blank",rel:"noreferrer",children:s})},s))}),r.events.length>0&&e.jsxs("details",{children:[e.jsx("summary",{children:"Run history"}),e.jsx("ul",{className:"research-view__events",children:r.events.map(s=>e.jsx("li",{children:s.message},s.id))})]})]}),!r&&m.length>0&&e.jsx("p",{children:"Select a run to view details."}),e.jsxs("div",{className:"research-view__stats",children:[e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Running"}),e.jsx("div",{className:"research-view__stat-value",children:p.running})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Completed"}),e.jsx("div",{className:"research-view__stat-value",children:p.completed})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Failed"}),e.jsx("div",{className:"research-view__stat-value",children:p.failed})]})]})]})]}),r&&P&&(()=>{const s=r.results?.findings?.findIndex((v,h)=>(v.id?.trim()||`finding-${h+1}`)===P.findingId)??-1,o=s>=0?r.results.findings[s]:null;return o?e.jsx(Re,{open:!0,mode:P.mode,run:r,finding:{id:P.findingId,heading:o.heading,content:o.content},projectId:d,onClose:()=>$(null),onConfirm:async({taskId:v,title:h,description:w,priority:se,attachExport:te})=>{P.mode==="create"?await G("create-task",()=>E(r.id,h,P.findingId,w,se,te),"Task created from research"):v&&await G("attach-task",()=>T(r.id,v,P.findingId,te),"Task enriched from research"),$(null)}}):null})()]})}export{Te as ResearchView};
|