@runfusion/fusion 0.1.2 → 0.2.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/README.md +2 -0
- package/dist/bin.js +4055 -1755
- package/dist/client/assets/AgentDetailView-CDZED6Dy.css +1 -0
- package/dist/client/assets/AgentDetailView-zycSdnO8.js +28 -0
- package/dist/client/assets/AgentsView-DoQkkDLf.css +1 -0
- package/dist/client/assets/AgentsView-pO7WiBS5.js +522 -0
- package/dist/client/assets/ChatView-BOd-sxbT.js +1 -0
- package/dist/client/assets/DevServerView-09GQf34f.js +11 -0
- package/dist/client/assets/DevServerView-ZeBGQkLI.css +1 -0
- package/dist/client/assets/DirectoryPicker-CcdN1Zs7.js +1 -0
- package/dist/client/assets/DocumentsView-CS8aiwtz.js +1 -0
- package/dist/client/assets/DocumentsView-Co9to4Zp.css +1 -0
- package/dist/client/assets/InsightsView-Bu9Cv8Ol.js +11 -0
- package/dist/client/assets/InsightsView-Egu71gmh.css +1 -0
- package/dist/client/assets/MemoryView-CtqgDtV9.js +2 -0
- package/dist/client/assets/MemoryView-DhinauGs.css +1 -0
- package/dist/client/assets/NodesView-BInPcedy.js +14 -0
- package/dist/client/assets/NodesView-DlQZHGXA.css +1 -0
- package/dist/client/assets/PiExtensionsManager-COxkYM2m.js +11 -0
- package/dist/client/assets/PiExtensionsManager-CPgmJgDk.css +1 -0
- package/dist/client/assets/PluginManager-CXUWZBOc.js +1 -0
- package/dist/client/assets/PluginManager-D64RIzmL.css +1 -0
- package/dist/client/assets/RoadmapsView-BOYnyMCh.css +1 -0
- package/dist/client/assets/RoadmapsView-BbCexaoi.js +6 -0
- package/dist/client/assets/SetupWizardModal-Cakxqkad.js +1 -0
- package/dist/client/assets/SkillsView-Cytf009Z.css +1 -0
- package/dist/client/assets/SkillsView-D3iqYCVf.js +1 -0
- package/dist/client/assets/folder-open-kO5Hsk66.js +6 -0
- package/dist/client/assets/index-BiSuUXCa.css +1 -0
- package/dist/client/assets/index-y194HxzU.js +644 -0
- package/dist/client/assets/upload-DHBQat92.js +6 -0
- package/dist/client/index.html +2 -2
- package/dist/client/sw.js +45 -1
- package/dist/client/theme-data.css +109 -0
- package/dist/extension.js +969 -408
- package/dist/pi-claude-cli/index.ts +131 -0
- package/dist/pi-claude-cli/package.json +39 -0
- package/dist/pi-claude-cli/src/__tests__/control-handler.test.ts +191 -0
- package/dist/pi-claude-cli/src/__tests__/event-bridge.test.ts +1244 -0
- package/dist/pi-claude-cli/src/__tests__/mcp-config.test.ts +272 -0
- package/dist/pi-claude-cli/src/__tests__/process-manager.test.ts +619 -0
- package/dist/pi-claude-cli/src/__tests__/prompt-builder.test.ts +1067 -0
- package/dist/pi-claude-cli/src/__tests__/provider.test.ts +1902 -0
- package/dist/pi-claude-cli/src/__tests__/stream-parser.test.ts +188 -0
- package/dist/pi-claude-cli/src/__tests__/thinking-config.test.ts +141 -0
- package/dist/pi-claude-cli/src/__tests__/tool-mapping.test.ts +252 -0
- package/dist/pi-claude-cli/src/control-handler.ts +68 -0
- package/dist/pi-claude-cli/src/event-bridge.ts +386 -0
- package/dist/pi-claude-cli/src/mcp-config.ts +111 -0
- package/dist/pi-claude-cli/src/mcp-schema-server.cjs +49 -0
- package/dist/pi-claude-cli/src/process-manager.ts +218 -0
- package/dist/pi-claude-cli/src/prompt-builder.ts +536 -0
- package/dist/pi-claude-cli/src/provider.ts +354 -0
- package/dist/pi-claude-cli/src/stream-parser.ts +37 -0
- package/dist/pi-claude-cli/src/thinking-config.ts +83 -0
- package/dist/pi-claude-cli/src/tool-mapping.ts +147 -0
- package/dist/pi-claude-cli/src/types.ts +87 -0
- package/package.json +11 -4
- package/skill/fusion/SKILL.md +5 -3
- package/skill/fusion/references/cli-commands.md +22 -22
- package/skill/fusion/references/extension-tools.md +3 -1
- package/skill/fusion/references/fusion-capabilities.md +28 -35
- package/skill/fusion/references/task-structure.md +4 -4
- package/skill/fusion/workflows/dashboard-cli.md +6 -6
- package/skill/fusion/workflows/specifications.md +5 -3
- package/skill/fusion/workflows/task-lifecycle.md +1 -1
- package/skill/fusion/workflows/task-management.md +3 -1
- package/dist/client/assets/index-Djv5vKo0.css +0 -1
- package/dist/client/assets/index-zfXYuUXG.js +0 -1241
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{i as Le,ax as lt,g as ct,ay as rt,a as ot,az as dt,aA as ut,aB as ht,aC as mt,aD as gt,aE as ft,s as pt,aF as xt,aG as St,f as vt,w as Pe,S as bt,I as Be,aj as wt,aH as Nt,B as Ce,aI as kt,aJ as Ct,aK as Mt,aL as jt,aM as yt,aN as Tt,h as At,j as $t}from"./index-y194HxzU.js";import"./vendor-xterm-DzcZoU0P.js";const Re="kb-chat-active-session";function Dt(n){const i=n?.toolCalls;if(!Array.isArray(i))return;const r=i.map(l=>{if(!l||typeof l!="object")return null;const c=l,x=typeof c.toolName=="string"?c.toolName:"";if(!x)return null;const b=c.args;return{toolName:x,...b&&typeof b=="object"?{args:b}:{},isError:!!c.isError,result:c.result,status:"completed"}}).filter(l=>l!==null);return r.length>0?r:void 0}function He(n){return{id:n.id,sessionId:n.sessionId,role:n.role,content:n.content,thinkingOutput:n.thinkingOutput,toolCalls:Dt(n.metadata),createdAt:n.createdAt}}function Et(n){const[i,r]=s.useState([]),[l,c]=s.useState(null),[x,b]=s.useState(!0),[M,w]=s.useState([]),[X,z]=s.useState(!1),[O,L]=s.useState(!1),[re,D]=s.useState(""),[V,T]=s.useState(""),[pe,E]=s.useState([]),[S,P]=s.useState(""),[Z,U]=s.useState(""),[A,B]=s.useState(!0),[q,ne]=s.useState(new Map),k=s.useRef(null),J=s.useRef(!1),K=s.useRef(""),xe=s.useRef(i),H=s.useRef(l),we=s.useRef(O);xe.current=i,H.current=l,we.current=O,s.useEffect(()=>{K.current=S},[S]);const ae=s.useRef(new Set),ee=s.useRef(0),Ne=s.useRef(n);Ne.current!==n&&(Ne.current=n,ee.current++),s.useEffect(()=>{const o=ee.current;Le(void 0,n).then(h=>{if(ee.current!==o)return;const u=new Map;for(const N of h)u.set(N.id,N);ne(u)}).catch(()=>{})},[n]);const te=s.useCallback(async()=>{b(!0);try{const h=[...(await lt(n)).sessions].sort((u,N)=>new Date(N.updatedAt).getTime()-new Date(u.updatedAt).getTime());r(h)}catch{}finally{b(!1)}},[n]);s.useEffect(()=>{te()},[te]);const Q=s.useRef(()=>{});s.useEffect(()=>{if(x)return;const o=ct(Re,n);o&&i.find(u=>u.id===o)&&Q.current(o)},[x,i,n]);const I=s.useCallback(async(o,h)=>{z(!0);try{const u=await rt(o,{limit:50,...h},n),N=u.messages.map(He);h?.offset&&h.offset>0?w(W=>[...N,...W]):w(N),B(u.messages.length>=50)}catch{}finally{z(!1)}},[n]),oe=s.useCallback(o=>{k.current&&(k.current.close(),k.current=null);const h=i.find(u=>u.id===o);c(h||null),D(""),T(""),E([]),L(!1),B(!0),o?I(o):w([]),o?ot(Re,o,n):dt(Re,n)},[i,I,n]);Q.current=oe;const de=s.useCallback(async o=>{const h=await ut(o,n),u={id:h.session.id,title:h.session.title,agentId:h.session.agentId,status:h.session.status,modelProvider:h.session.modelProvider,modelId:h.session.modelId,createdAt:h.session.createdAt,updatedAt:h.session.updatedAt};return r(N=>[u,...N]),c(u),w([]),D(""),T(""),E([]),L(!1),B(!0),u},[n]),ue=s.useCallback(async o=>{await ht(o,{status:"archived"},n),r(h=>h.filter(u=>u.id!==o)),l?.id===o&&(c(null),w([]))},[l,n]),ie=s.useCallback(async o=>{l?.id===o&&k.current&&(k.current.close(),k.current=null),await mt(o,n),r(h=>h.filter(u=>u.id!==o)),l?.id===o&&(c(null),w([]))},[l,n]),he=s.useCallback(async()=>{!l||!A||await I(l.id,{offset:M.length})},[l,A,I,M.length]),se=s.useCallback(()=>{l&&(J.current=!0,k.current?.close(),k.current=null,gt(l.id,n).catch(()=>{}),L(!1),D(""),T(""),E([]))},[l,n]),_=s.useCallback(()=>{K.current="",P("")},[]),G=s.useCallback(o=>{if(!l)return;if(O){K.current=o,P(o);return}J.current=!1,k.current&&(k.current.close(),k.current=null);const h=`temp-${Date.now()}`,u={id:h,sessionId:l.id,role:"user",content:o,createdAt:new Date().toISOString()};w(p=>[...p,u]),D(""),T(""),E([]),L(!0);let N="",W="",R=[];const m={onThinking:p=>{W+=p,T(W)},onText:p=>{N+=p,D(N)},onToolStart:p=>{R=[...R,{toolName:p.toolName,args:p.args,isError:!1,status:"running"}],E(R)},onToolEnd:p=>{const C=[...R];for(let g=C.length-1;g>=0;g--){const v=C[g];if(v?.toolName===p.toolName&&v.status==="running"){C[g]={...v,status:"completed",isError:p.isError,result:p.result},R=C,E(C);return}}R=[...C,{toolName:p.toolName,isError:p.isError,result:p.result,status:"completed"}],E(R)},onDone:p=>{const C={id:p.messageId||`msg-${Date.now()}`,sessionId:l.id,role:"assistant",content:N,thinkingOutput:W,toolCalls:R.length>0?R:void 0,createdAt:new Date().toISOString()};ae.current.add(C.id),w(v=>[...v,C]),D(""),T(""),E([]),L(!1),k.current=null,setTimeout(()=>{ae.current.delete(C.id)},1e3),te();const g=K.current.trim();g&&(K.current="",P(""),G(g))},onError:p=>{if(w(C=>C.filter(g=>g.id!==h)),D(""),T(""),E([]),L(!1),k.current=null,console.error("[useChat] Stream error:",p),!J.current){const C=K.current.trim();C&&(K.current="",P(""),G(C))}}};k.current=ft(l.id,o,m,n)},[l,O,n,te]),Se=Z?i.filter(o=>o.title?.toLowerCase().includes(Z.toLowerCase())||o.agentId.toLowerCase().includes(Z.toLowerCase())):i;return s.useEffect(()=>{const o=ee.current,h=n?`?projectId=${encodeURIComponent(n)}`:"",u=()=>ee.current!==o,N=g=>{if(u())return;const v=JSON.parse(g.data);r(f=>f.some(j=>j.id===v.id)?f:[v,...f])},W=g=>{if(u())return;const v=JSON.parse(g.data);r(f=>[...f.map(ve=>ve.id===v.id?v:ve)]),H.current?.id===v.id&&c(v)},R=g=>{if(u())return;const{id:v}=JSON.parse(g.data);r(f=>f.filter(j=>j.id!==v)),H.current?.id===v&&(c(null),w([]))},m=g=>{if(u())return;const v=JSON.parse(g.data),f=He(v);ae.current.has(f.id)||H.current?.id===f.sessionId&&!we.current&&w(j=>j.some(ve=>ve.id===f.id)?j:[...j,f])},p=g=>{if(u())return;const{id:v}=JSON.parse(g.data);w(f=>f.filter(j=>j.id!==v))};return pt(`/api/events${h}`,{events:{"chat:session:created":N,"chat:session:updated":W,"chat:session:deleted":R,"chat:message:added":m,"chat:message:deleted":p}})},[n]),s.useEffect(()=>()=>{k.current&&(k.current.close(),k.current=null)},[]),{sessions:i,activeSession:l,sessionsLoading:x,messages:M,messagesLoading:X,isStreaming:O,streamingText:re,streamingThinking:V,streamingToolCalls:pe,pendingMessage:S,selectSession:oe,createSession:de,archiveSession:ue,deleteSession:ie,sendMessage:G,stopStreaming:se,clearPendingMessage:_,loadMoreMessages:he,hasMoreMessages:A,searchQuery:Z,setSearchQuery:U,filteredSessions:Se,refreshSessions:te,agentsMap:q}}function _e(n){const i=new Date(n),l=new Date().getTime()-i.getTime(),c=Math.floor(l/1e3),x=Math.floor(c/60),b=Math.floor(x/60),M=Math.floor(b/24);return c<60?"just now":x<60?`${x}m ago`:b<24?`${b}h ago`:M<7?`${M}d ago`:i.toLocaleDateString()}function Ge(n,i){if(!n||!i)return null;const r=i.toLowerCase();if(r.includes("claude")){let c=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 c=c.replace(/\s+/g," "),c.length>30?c.slice(0,30)+"…":c}if(r.includes("gpt")||r.includes("openai")){const c=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 c.length>30?c.slice(0,30)+"…":c}if(r.includes("gemini")){const c=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 c.length>30?c.slice(0,30)+"…":c}const l=i.replace(/-/g," ").replace(/^\w/,c=>c.toUpperCase()).replace(/\s+/g," ").trim();return l.length>30?l.slice(0,30)+"…":l}function Me(n,i){return n.length>i?`${n.slice(0,i)}…`:n}function Pt(n){if(!n)return null;const i=Object.entries(n);return i.length===0?null:i.map(([r,l])=>{let c="";if(typeof l=="string")c=l;else try{c=JSON.stringify(l)}catch{c=String(l)}return`${r}=${Me(c,50)}`}).join(", ")}function Rt(n){if(n===void 0)return null;if(typeof n=="string")return Me(n,200);try{return Me(JSON.stringify(n),200)}catch{return Me(String(n),200)}}function Ue(n){return!n||n.length===0?null:e.jsxs("div",{className:"chat-tool-calls","data-testid":"chat-tool-calls",children:[e.jsxs("div",{className:"chat-tool-calls-header",children:[e.jsx(Tt,{size:12,"aria-hidden":"true"}),e.jsx("span",{children:"Tool calls"})]}),n.map((i,r)=>{const l=i.status==="running",c=i.status==="completed"&&i.isError,x=Pt(i.args),b=Rt(i.result),M=l?x:b?`result: ${b}`:x?`args: ${x}`:null,w=l?"running":c?"error":"completed";return e.jsxs("details",{className:`chat-tool-call${l?" chat-tool-call--running":""}${c?" chat-tool-call--error":""}`,open:l,children:[e.jsxs("summary",{children:[e.jsx("span",{className:"chat-tool-call-status-dot","aria-hidden":"true"}),e.jsx("span",{className:"chat-tool-call-name",children:i.toolName}),M&&e.jsx("span",{className:"chat-tool-call-preview",title:M,children:M}),e.jsx("span",{className:"chat-tool-call-status-text",children:w})]}),e.jsxs("div",{className:"chat-tool-call-content",children:[x&&e.jsxs("div",{className:"chat-tool-call-row",children:[e.jsx("span",{className:"chat-tool-call-label",children:"args"}),e.jsx("span",{className:"chat-tool-call-value",children:x})]}),b&&e.jsxs("div",{className:`chat-tool-call-row${c?" chat-tool-call-row--error":""}`,children:[e.jsx("span",{className:"chat-tool-call-label",children:"result"}),e.jsx("span",{className:"chat-tool-call-value",children:b})]})]})]},`${i.toolName}-${r}`)})]})}const je="__fn_agent__";function qe(n){const i=/(^|[\s])\/([^\s]*)$/.exec(n);if(!i)return null;const r=i[1]??"",l=i[2]??"",c=i.index+r.length;return{filter:l,start:c,end:n.length}}function Lt(n,i){const r=n.slice(0,i),l=/(^|[\s\n])@([\w-]*)$/.exec(r);if(!l)return null;const c=l[2]??"",x=r.length-c.length-1;return{filter:c,start:x,end:i}}function It({projectId:n,onClose:i,onCreate:r}){const[l,c]=s.useState("agent"),[x,b]=s.useState([]),[M,w]=s.useState(!0),[X,z]=s.useState(""),[O,L]=s.useState([]),[re,D]=s.useState(!0),[V,T]=s.useState("");s.useEffect(()=>{let S=!1;return w(!0),Le(void 0,n).then(P=>{S||b(P)}).catch(()=>{S||b([])}).finally(()=>{S||w(!1)}),()=>{S=!0}},[n]),s.useEffect(()=>{D(!0),At().then(S=>{L(S.models)}).catch(()=>{L([])}).finally(()=>{D(!1)})},[]);const pe=S=>{if(S.preventDefault(),l==="agent"){if(!X)return;r({agentId:X});return}if(!V)return;const P=V.indexOf("/");if(P<=0)return;const Z=V.slice(0,P),U=V.slice(P+1);r({agentId:je,modelProvider:Z,modelId:U})},E=l==="agent"?!X:!V;return e.jsx("div",{className:"chat-new-dialog-backdrop",onClick:i,role:"dialog","aria-modal":"true",children:e.jsxs("div",{className:"chat-new-dialog",onClick:S=>S.stopPropagation(),children:[e.jsx("h3",{children:"New Chat"}),e.jsxs("div",{className:"chat-new-dialog-mode-toggle","data-testid":"chat-new-dialog-mode-toggle",children:[e.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${l==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{c("agent"),T("")},children:"Agent"}),e.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${l==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{c("model"),z("")},children:"Model"})]}),e.jsxs("form",{onSubmit:pe,children:[l==="agent"&&e.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",M?e.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):x.length===0?e.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):e.jsx("div",{className:"chat-new-dialog-agent-list",children:x.map(S=>e.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${X===S.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>z(S.id),"data-testid":`agent-option-${S.id}`,children:[e.jsx(Ce,{size:16}),e.jsx("span",{className:"chat-new-dialog-agent-name",children:S.name}),e.jsx("span",{className:"chat-new-dialog-agent-role",children:S.role})]},S.id))})]}),l==="model"&&e.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:re?e.jsx("div",{className:"chat-new-dialog-loading",children:"Loading models..."}):e.jsx($t,{models:O,value:V,onChange:T,label:"Model",placeholder:"Select a model"})}),e.jsxs("div",{className:"chat-new-dialog-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:i,children:"Cancel"}),e.jsx("button",{type:"submit",className:"btn btn-sm btn-primary",disabled:E,children:"Create"})]})]})]})})}function Vt({projectId:n,addToast:i}){const{activeSession:r,sessionsLoading:l,messages:c,messagesLoading:x,isStreaming:b,streamingText:M,streamingThinking:w,streamingToolCalls:X,selectSession:z,createSession:O,archiveSession:L,deleteSession:re,sendMessage:D,stopStreaming:V,pendingMessage:T,clearPendingMessage:pe,searchQuery:E,setSearchQuery:S,filteredSessions:P}=Et(n),[Z,U]=s.useState(!1),[A,B]=s.useState(""),[q,ne]=s.useState(null),[k,J]=s.useState(null),[K,xe]=s.useState(!0),[H,we]=s.useState(new Map),[ae,ee]=s.useState([]),[Ne,te]=s.useState(!0),[Q,I]=s.useState(!1),[oe,de]=s.useState(""),[ue,ie]=s.useState(0),[he,se]=s.useState(""),[_,G]=s.useState(!1),[Se,o]=s.useState(0),[h,u]=s.useState(-1),[,N]=s.useState(!1),[W,R]=s.useState({top:0,left:0}),m=xt({projectId:n}),p=s.useCallback(t=>{if(!t||!m.mentionActive)return;const a=t.getBoundingClientRect();R({top:a.top-260,left:a.left+8})},[m.mentionActive]),C=s.useRef(null),g=s.useRef(null),v=s.useRef(null),f=s.useRef(null),j=s.useRef(0),me=St()==="mobile",F=s.useMemo(()=>{const t=oe.trim().toLowerCase();return(t?ae.filter(d=>d.name.toLowerCase().includes(t)):ae).slice(0,10)},[ae,oe]),ge=s.useMemo(()=>Array.from(H.values()),[H]),le=s.useMemo(()=>{const t=he.trim().toLowerCase();return t?ge.filter(a=>a.name.toLowerCase().includes(t)):ge},[ge,he]),Ie=s.useMemo(()=>{const t=new Map;for(const a of ge)t.set(a.name.toLowerCase(),a);return t},[ge]);s.useEffect(()=>{ie(0)},[F]),s.useEffect(()=>{o(0)},[he,_]),s.useEffect(()=>()=>{g.current!==null&&window.clearTimeout(g.current)},[]),s.useEffect(()=>{C.current?.scrollIntoView({behavior:"smooth"})},[c,M]),s.useEffect(()=>{const t=()=>ne(null);if(q)return document.addEventListener("click",t),()=>document.removeEventListener("click",t)},[q]),s.useEffect(()=>{let t=!1;const a=n;return Le(void 0,n).then(d=>{if(t||a!==n)return;const y=new Map;for(const $ of d)y.set($.id,$);we(y)}).catch(()=>{}),()=>{t=!0}},[n]),s.useEffect(()=>{let t=!1;return te(!0),vt(n).then(a=>{t||ee(a)}).catch(()=>{t||ee([])}).finally(()=>{t||te(!1)}),()=>{t=!0}},[n]);const Je=s.useCallback(async t=>{try{await O(t),U(!1),me&&xe(!1)}catch{i("Failed to create chat session","error")}},[O,i,me]),ye=s.useCallback(()=>{const t=A.trim();!t||!r||(B(""),I(!1),de(""),G(!1),se(""),u(-1),D(t))},[A,r,D]),Te=s.useCallback(t=>{B(a=>{const d=qe(a);if(!d)return a;const y=`/skill:${t.name} `,$=a.slice(0,d.start)+y+a.slice(d.end);return window.requestAnimationFrame(()=>{f.current&&(f.current.style.height="auto",f.current.style.height=`${Math.min(f.current.scrollHeight,120)}px`,f.current.focus())}),$}),I(!1),de(""),ie(0)},[]),Ae=s.useCallback(t=>{const a=f.current;if(!a||h<0)return;const d=a.selectionStart??j.current,y=a.selectionEnd??d,$=Math.max(d,y),be=Math.min(h,$),ce=`${`@${t.name.replace(/\s+/g,"_")}`} `,Ee=A.slice(0,be)+ce+A.slice($),fe=be+ce.length;B(Ee),G(!1),se(""),o(0),u(-1),window.requestAnimationFrame(()=>{f.current&&(f.current.style.height="auto",f.current.style.height=`${Math.min(f.current.scrollHeight,120)}px`,f.current.focus(),f.current.setSelectionRange(fe,fe))})},[h,A]),Fe=s.useCallback(t=>{const a=/@([\w-]+)/g,d=[];let y=0,$=a.exec(t);for(;$;){const[be,Ve=""]=$,ce=$.index;ce>y&&d.push(t.slice(y,ce));const Ee=Ve.replace(/_/g," ").toLowerCase(),fe=Ie.get(Ee);fe?d.push(e.jsxs("span",{className:"chat-mention-chip",children:["@",fe.name.replace(/\s+/g,"_")]},`${fe.id}-${ce}`)):d.push(be),y=ce+be.length,$=a.exec(t)}return y<t.length&&d.push(t.slice(y)),d.length===0?t:d},[Ie]),Ke=s.useCallback(t=>{if(j.current=t.currentTarget.selectionStart??j.current,m.mentionActive&&m.files.length>0){if(m.handleKeyDown(t,A),t.key==="Enter"||t.key==="Tab"){const a=m.files[m.selectedIndex];if(a){const d=m.selectFile(a,A);B(d),m.dismissMention(),N(!1)}}return}if(_&&t.key==="ArrowDown"){t.preventDefault(),le.length>0&&o(a=>(a+1)%le.length);return}if(_&&t.key==="ArrowUp"){t.preventDefault(),le.length>0&&o(a=>a===0?le.length-1:a-1);return}if(_&&t.key==="Enter"){t.preventDefault();const a=le[Se]??le[0];a&&Ae(a);return}if(_&&t.key==="Escape"){t.preventDefault(),G(!1),se(""),u(-1);return}if(Q&&t.key==="ArrowDown"){t.preventDefault(),F.length>0&&ie(a=>(a+1)%F.length);return}if(Q&&t.key==="ArrowUp"){t.preventDefault(),F.length>0&&ie(a=>a===0?F.length-1:a-1);return}if(Q&&(t.key==="Enter"||t.key==="Tab")&&F.length>0){t.preventDefault();const a=F[ue]??F[0];a&&Te(a);return}if(Q&&t.key==="Escape"){t.preventDefault(),I(!1);return}t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),ye())},[_,le,Se,Ae,Q,F,ue,Te,ye,m,A]),ke=s.useCallback((t,a)=>{const d=Lt(t,a);if(d){G(!0),se(d.filter),u(d.start);return}G(!1),se(""),u(-1)},[]),Qe=s.useCallback(t=>{const a=t.target,d=a.value,y=a.selectionStart??d.length;j.current=y,B(d);const $=qe(d);$?(I(!0),de($.filter)):(I(!1),de("")),ke(d,y),m.detectMention(d,y),N(m.mentionActive),m.mentionActive&&p(a),a.style.height="auto",a.style.height=`${Math.min(a.scrollHeight,120)}px`},[ke]),$e=s.useCallback(t=>{const a=t.currentTarget,d=a.selectionStart??a.value.length;j.current=d,ke(a.value,d),m.detectMention(a.value,d),N(m.mentionActive),m.mentionActive&&p(a)},[ke,m,p]),We=s.useCallback(t=>{t.key!=="Escape"&&$e(t)},[$e]),Ye=s.useCallback(()=>{g.current!==null&&window.clearTimeout(g.current),g.current=window.setTimeout(()=>{I(!1),G(!1),se(""),u(-1),N(!1),m.dismissMention(),g.current=null},120)},[m]),Xe=s.useCallback(()=>{g.current!==null&&(window.clearTimeout(g.current),g.current=null)},[]),Ze=s.useCallback(async t=>{ne(null);try{await L(t),i("Conversation archived","success")}catch{i("Failed to archive conversation","error")}},[L,i]),et=s.useCallback(async t=>{J(null),ne(null);try{await re(t),i("Conversation deleted","success")}catch{i("Failed to delete conversation","error")}},[re,i]),tt=s.useCallback(t=>{z(t),me&&xe(!1)},[z,me]),st=s.useCallback(()=>{z(""),xe(!0)},[z]),nt=()=>e.jsxs("div",{className:"chat-empty-state",children:[e.jsx(yt,{size:48,strokeWidth:1.5}),e.jsx("h2",{children:"Start a new conversation"}),e.jsxs("button",{className:"btn btn-primary",onClick:()=>U(!0),children:[e.jsx(Pe,{size:16}),"New Chat"]})]}),Y=Ge(r?.modelProvider,r?.modelId),ze=r?.agentId===je?Y??"Fusion":r?.title||H.get(r?.agentId??"")?.name||r?.agentId||"Chat",at=!!(Y&&Y!==ze),De=H.get(r?.agentId??"")?.name||(r?.agentId===je?Y??"Fusion":r?.agentId?.slice(0,30)??"Fusion"),Oe=!!(Y&&Y!==De),it=T.length>50?`${T.slice(0,50)}…`:T;return e.jsxs("div",{className:"chat-view",children:[e.jsxs("div",{className:`chat-sidebar${K?"":" chat-sidebar--hidden"}`,children:[e.jsx("div",{className:"chat-sidebar-header",children:e.jsxs("button",{className:"btn btn-sm btn-primary",onClick:()=>U(!0),"data-testid":"chat-new-btn",children:[e.jsx(Pe,{size:14}),"New Chat"]})}),e.jsx("div",{className:"chat-sidebar-search",children:e.jsxs("div",{className:"chat-sidebar-search-wrapper",children:[e.jsx(bt,{size:14,className:"chat-sidebar-search-icon"}),e.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:E,onChange:t=>S(t.target.value),"data-testid":"chat-search-input"})]})}),e.jsx("div",{className:"chat-session-list chat-sidebar-list",children:l?e.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"Loading..."}):P.length===0?e.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"No conversations yet"}):P.map(t=>e.jsxs("div",{className:`chat-session-item${r?.id===t.id?" chat-session-item--active":""}`,onClick:()=>tt(t.id),onContextMenu:a=>{a.preventDefault(),ne({sessionId:t.id,x:a.clientX,y:a.clientY})},"data-testid":`chat-session-${t.id}`,children:[e.jsx("button",{className:"chat-session-delete-btn",onClick:a=>{a.stopPropagation(),J(t.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:e.jsx(Be,{size:14})}),e.jsx("div",{className:"chat-session-title",children:t.title||"Untitled"}),e.jsx("div",{className:"chat-session-preview",children:t.lastMessagePreview||"No messages"}),e.jsxs("div",{className:"chat-session-meta",children:[e.jsx("span",{children:H.get(t.agentId)?.name||(t.agentId===je?Ge(t.modelProvider,t.modelId)??"Fusion":t.agentId.slice(0,30))}),e.jsx("span",{children:t.updatedAt?_e(t.updatedAt):""})]})]},t.id))}),e.jsx("div",{className:"chat-sidebar-footer",children:e.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>U(!0),"data-testid":"chat-new-btn-mobile",children:[e.jsx(Pe,{size:14}),"New Chat"]})})]}),q&&e.jsxs("div",{className:"chat-session-context-menu",style:{top:q.y,left:q.x},onClick:t=>t.stopPropagation(),children:[e.jsxs("button",{onClick:()=>Ze(q.sessionId),"data-testid":"chat-context-archive",children:[e.jsx(wt,{size:14}),"Archive"]}),e.jsxs("button",{onClick:()=>{ne(null),J(q.sessionId)},"data-testid":"chat-context-delete",children:[e.jsx(Be,{size:14}),"Delete"]})]}),k&&e.jsx("div",{className:"chat-new-dialog-backdrop",onClick:()=>J(null),children:e.jsxs("div",{className:"chat-new-dialog",onClick:t=>t.stopPropagation(),children:[e.jsx("h3",{children:"Delete Conversation?"}),e.jsx("p",{style:{fontSize:"14px",color:"var(--text-secondary)",marginBottom:"16px"},children:"This action cannot be undone. All messages in this conversation will be permanently deleted."}),e.jsxs("div",{className:"chat-new-dialog-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>J(null),children:"Cancel"}),e.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void et(k),children:"Delete"})]})]})}),e.jsxs("div",{className:"chat-thread",children:[(r||!me)&&e.jsxs("div",{className:"chat-thread-header",children:[me&&r&&e.jsx("button",{className:"btn-icon",onClick:st,"data-testid":"chat-back-btn",children:e.jsx(Nt,{size:16})}),e.jsx(Ce,{size:16}),e.jsx("span",{className:"chat-thread-header-title",children:ze}),at&&e.jsx("span",{className:"chat-model-tag",children:Y})]}),e.jsxs("div",{className:"chat-messages",ref:v,children:[x?e.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):c.length===0&&!r?nt():c.length===0&&r?e.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):e.jsxs(e.Fragment,{children:[c.map(t=>e.jsxs("div",{className:`chat-message chat-message--${t.role}`,"data-testid":`chat-message-${t.id}`,children:[t.role==="assistant"&&e.jsxs("div",{className:"chat-message-avatar",children:[e.jsx(Ce,{size:14}),e.jsx("span",{children:De}),Oe&&e.jsx("span",{className:"chat-model-tag",children:Y})]}),e.jsx("div",{className:"chat-message-content",children:Fe(t.content)}),Ue(t.toolCalls),t.thinkingOutput&&e.jsxs("details",{className:"chat-message-thinking",children:[e.jsx("summary",{children:"Thinking"}),e.jsx("pre",{className:"chat-message-thinking-content",children:t.thinkingOutput})]}),e.jsx("div",{className:"chat-message-time",children:_e(t.createdAt)})]},t.id)),b&&e.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[e.jsxs("div",{className:"chat-message-avatar",children:[e.jsx(Ce,{size:14}),e.jsx("span",{children:De}),Oe&&e.jsx("span",{className:"chat-model-tag",children:Y})]}),M?e.jsx("div",{className:"chat-message-content",children:Fe(M)}):e.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:w?"Thinking…":"Connecting…"}),Ue(X),w&&e.jsxs("details",{className:"chat-message-thinking",children:[e.jsx("summary",{children:"Thinking"}),e.jsx("pre",{className:"chat-message-thinking-content",children:w})]}),e.jsxs("div",{className:"chat-typing-indicator",children:[e.jsx("span",{}),e.jsx("span",{}),e.jsx("span",{})]})]})]}),e.jsx("div",{ref:C})]}),r&&e.jsxs("div",{className:"chat-input-area",children:[Q&&e.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:Ne?e.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):F.length===0?e.jsx("div",{className:"chat-skill-menu-empty",children:oe?"No skills found":"No skills available"}):F.map((t,a)=>e.jsxs("button",{type:"button",role:"option","aria-selected":a===ue,className:`chat-skill-menu-item${a===ue?" chat-skill-menu-item--highlighted":""}`,onMouseDown:d=>d.preventDefault(),onMouseEnter:()=>ie(a),onClick:()=>Te(t),children:[e.jsx("span",{className:"chat-skill-menu-item-name",children:t.name}),e.jsx("span",{className:"chat-skill-menu-item-description",title:t.relativePath,children:t.relativePath})]},t.id))}),e.jsxs("div",{className:"chat-input-wrapper",children:[e.jsx("textarea",{ref:f,className:"chat-input-textarea",placeholder:"Type a message...",value:A,onChange:Qe,onKeyDown:Ke,onKeyUp:We,onClick:$e,onBlur:Ye,onFocus:Xe,rows:1,"data-testid":"chat-input"}),e.jsx(kt,{agents:ge,filter:he,highlightedIndex:Se,visible:_,onSelect:Ae,position:"below"}),e.jsx(Ct,{visible:m.mentionActive&&!_,position:W,files:m.files,selectedIndex:m.selectedIndex,onSelect:t=>{const a=m.selectFile(t,A);B(a),m.dismissMention(),N(!1),f.current?.focus()},loading:m.loading}),T&&e.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[e.jsx("span",{children:`Queued: ${it}`}),e.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:pe,children:"×"})]})]}),b?e.jsx("button",{className:"chat-input-stop",onClick:V,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:e.jsx(Mt,{size:14})}):e.jsx("button",{className:"chat-input-send",onClick:()=>void ye(),disabled:!A.trim(),"data-testid":"chat-send-btn",children:e.jsx(jt,{size:16})})]})]}),Z&&e.jsx(It,{projectId:n,onClose:()=>U(!1),onCreate:Je})]})}export{Vt as ChatView};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{r,j as t}from"./vendor-react-K0fH_qHe.js";import{c as De,bo as Me,bp as de,bq as et,br as ue,s as Ue,bs as ge,bt as we,bu as xe,bv as ye,bw as tt,bx as ae,by as rt,bz as st,bA as nt,bB as at,bC as it,bD as ie,L as ee,S as lt,bE as ct,bF as ot,K as dt,T as Ae,bG as ut,E as vt,aK as mt,a3 as ft,ai as pt,R as ht}from"./index-y194HxzU.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 bt=[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]],gt=De("rotate-cw",bt);/**
|
|
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 wt=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"M12 8v4",key:"1got3b"}],["path",{d:"M12 16h.01",key:"1drbdi"}]],Pe=De("shield-alert",wt),ve=500,xt=3e3;function B(e){return e instanceof Error?e.message:String(e)}function Te(e){return e.length<=ve?e:e.slice(-ve)}function le(e,i){return Te([...e,i])}function I(e){try{return JSON.parse(e)}catch{return null}}function Q(e){const i=e.text??"";return e.stream==="stderr"?`[stderr] ${i}`:i}function yt(e){return e?.previewUrl??null}async function Ne(e){return rt(e)}async function Se(e,i){return st(e,i)}async function Nt(e){return nt(e)}async function St(e){return at(e)}async function ke(e){return it(e)}function V(e){try{return e()}catch{return null}}function ce(){return typeof V(()=>de)=="function"&&typeof V(()=>Me)=="function"}function W(e){return{config:{id:e.id??"default",name:e.name??"Dev Server",command:e.command??"",cwd:e.cwd??"."},status:e.status,runtime:e.pid?{pid:e.pid,startedAt:e.startedAt??new Date().toISOString(),exitCode:e.exitCode??void 0,previewUrl:e.previewUrl}:void 0,previewUrl:e.previewUrl??e.detectedUrl??e.manualUrl??void 0,logHistory:(e.logs??[]).map(i=>({timestamp:new Date().toISOString(),stream:i.startsWith("[stderr]")?"stderr":"stdout",text:i.replace(/^\[stderr\]\s*/,"")}))}}function kt(e){const[i,o]=r.useState(null),[b,y]=r.useState([]),[w,f]=r.useState([]),[j,M]=r.useState([]),[C,P]=r.useState(!0),[N,u]=r.useState(null),n=r.useRef(0),[d,U]=r.useState(null),R=r.useCallback(a=>{if(o(a),a?.logHistory){const s=a.logHistory.slice(-ve).map(Q);f(s)}},[]),A=r.useCallback(async()=>{const a=n.current;try{if(ce())if(d){const s=await Me(d,e);if(n.current!==a)return;R(s)}else{const s=await de(e);if(n.current!==a)return;y(s),s.length>0&&(U(s[0].config.id),R(s[0]))}else{const s=await Ne(e);if(n.current!==a)return;const c=W(s);y([c]),R(c)}u(null)}catch(s){if(n.current!==a)return;u(B(s))}},[R,e,d]);r.useEffect(()=>{n.current+=1;const a=n.current;o(null),y([]),f([]),M([]),P(!0),u(null),U(null),(async()=>{try{const[c,l]=await Promise.allSettled([ce()?de(e):Ne(e).then(S=>[W(S)]),typeof V(()=>ae)=="function"?ae(e):ke(e).then(S=>S.map(g=>({name:g.name,command:g.command,cwd:g.cwd,scriptName:g.scriptName,packagePath:g.packagePath})))]);if(n.current!==a)return;let v=null;if(c.status==="fulfilled"){const S=c.value;if(y(S),S.length>0){const g=S[0];ce()&&U(g.config.id),R(g)}}else v=B(c.reason);l.status==="fulfilled"&&M(l.value),v&&u(v)}catch(c){if(n.current!==a)return;u(B(c))}finally{n.current===a&&P(!1)}})()},[R,e]),r.useEffect(()=>{const a=d?et(d,e):typeof V(()=>ue)=="function"?ue(e):null;if(!a)return;const s=n.current,c=Ue(a,{events:{history:l=>{if(n.current!==s)return;const v=I(l.data);if(v?.lines){const S=v.lines.map(Q);f(Te(S))}},log:l=>{if(n.current!==s)return;const v=I(l.data);if(v){const S=typeof v.line=="string"?v.line:Q(v);f(g=>le(g,S))}},"dev-server:log":l=>{if(n.current!==s)return;const v=I(l.data);if(v){const S=typeof v.line=="string"?v.line:Q(v);f(g=>le(g,S))}},"dev-server:output":l=>{if(n.current!==s)return;const v=I(l.data);v?.line&&f(S=>le(S,v.line))},status:l=>{if(n.current!==s)return;const v=I(l.data),S=v?.status;S&&o(g=>g&&{...g,status:S,runtime:v.pid?{...g.runtime??{startedAt:new Date().toISOString()},pid:v.pid}:g.runtime})},"dev-server:status":l=>{if(n.current!==s)return;const v=I(l.data);if(v?.status){const S=W(v);o(S),y([S])}},stopped:()=>{n.current},failed:()=>{n.current}},onReconnect:()=>{n.current===s&&A()},onError:()=>{n.current===s&&u(l=>l??"Lost log stream connection.")}});return()=>{c()}},[e,A,d]),r.useEffect(()=>{if(i?.status!=="running"&&i?.status!=="starting")return;const a=setInterval(()=>{A()},xt);return()=>{clearInterval(a)}},[A,i?.status]);const _=r.useCallback(async(a,s)=>{n.current+=1;const c=n.current;try{let l;if(d&&typeof V(()=>ge)=="function")l=await ge(d,e);else{const v=await Se({command:a,cwd:s},e);l=W(v)}if(n.current!==c)return;o(l),u(null)}catch(l){if(n.current!==c)return;throw u(B(l)),l}},[e,d]),D=r.useCallback(async()=>{n.current+=1;const a=n.current;try{let s;if(d&&typeof V(()=>we)=="function")s=await we(d,e);else{const c=await Nt(e);s=W(c)}if(n.current!==a)return;o(s),u(null)}catch(s){if(n.current!==a)return;throw u(B(s)),s}},[e,d]),k=r.useCallback(async()=>{n.current+=1;const a=n.current;try{let s;if(d&&typeof V(()=>xe)=="function")s=await xe(d,e);else{const c=await St(e);s=W(c)}if(n.current!==a)return;o(s),u(null)}catch(s){if(n.current!==a)return;throw u(B(s)),s}},[e,d]),T=r.useCallback(async a=>{n.current+=1;const s=n.current;try{let c;if(d&&typeof V(()=>ye)=="function")c=await ye(d,a,e);else{const l=await tt({url:a},e);c={url:l.manualUrl??l.previewUrl??l.detectedUrl??null,source:l.manualUrl?"manual":"auto"}}if(n.current!==s)return;o(l=>l?{...l,previewUrl:c.url??void 0}:null),u(null)}catch(c){if(n.current!==s)return;throw u(B(c)),c}},[e,d]),h=r.useCallback(async()=>{n.current+=1;const a=n.current;try{let s;try{s=await ae(e)}catch{s=(await ke(e)).map(l=>({name:l.name,command:l.command,cwd:l.cwd,scriptName:l.scriptName,packagePath:l.packagePath}))}if(n.current!==a)return;M(s),u(null)}catch(s){if(n.current!==a)return;throw u(B(s)),s}},[e]),p=r.useCallback(async(a,s)=>{if(typeof a!="string"&&!d)try{const v=a,S=await Se({command:v.command,cwd:v.cwd,scriptName:v.scriptName,packagePath:v.packagePath??v.cwd},e),g=W(S);o(g),y([g]),u(null);return}catch(v){throw u(B(v)),v}const c=typeof a=="string"?a:a.command,l=typeof a=="string"?s:a.cwd;await _(c,l)},[e,_,d]),E=r.useCallback(async()=>{await D()},[D]),L=r.useCallback(async()=>{await k()},[k]),z=r.useCallback(async a=>{await T(a)},[T]),$=r.useCallback(async()=>{await h()},[h]),O=r.useCallback(async()=>{await A()},[A]),H=yt(i),x=i?{...i,pid:i.runtime?.pid}:null;return{session:i,sessions:b,logs:w,detectedCommands:j,previewUrl:H,isLoading:C,error:N,startServer:_,stopServer:D,restartServer:k,setPreviewUrl:T,detectCommands:h,refresh:A,candidates:j,serverState:x,loading:C,start:p,stop:E,restart:L,setManualUrl:z,detect:$,refreshStatus:O}}const je=500,Ce=100;function ze(e){return e.length>je?e.slice(-je):e}function Fe(e){return e==="stderr"?"stderr":"stdout"}function Y(e){try{return JSON.parse(e.data)}catch{return null}}function Z(e,i){return{id:typeof e.id=="number"&&Number.isFinite(e.id)?e.id:i,text:typeof e.text=="string"?e.text:"",stream:Fe(e.stream),timestamp:typeof e.timestamp=="string"?e.timestamp:""}}function jt(e,i){return{id:i,text:e,stream:"stdout",timestamp:""}}function oe(e,i){if(i.length===0)return e;const o=[...e],b=new Set(e.map(y=>y.id));for(const y of i)b.has(y.id)||(b.add(y.id),o.push(y));return o.sort((y,w)=>y.id-w.id),ze(o)}function Ct(e,i){const[o,b]=r.useState([]),[y,w]=r.useState(!1),[f,j]=r.useState(!1),[M,C]=r.useState(!1),[P,N]=r.useState(null),u=r.useRef(null),n=r.useRef(!1),d=r.useRef(0),U=r.useRef(0),R=r.useRef(e),A=r.useRef(i),_=r.useRef(0),D=r.useRef(1);(R.current!==e||A.current!==i)&&(R.current=e,A.current=i,d.current++,n.current=!0,_.current=0,D.current=1,b([]),w(!1),j(!1),C(!1),N(null),u.current&&(u.current(),u.current=null)),r.useEffect(()=>{if(!i){u.current&&(u.current(),u.current=null);return}const E=d.current,L=++U.current;n.current=!1,w(!0);const z=(x,a)=>{const s=ze(x);b(s),N(a),C(a!==null?a>s.length:!1);const c=s.length>0?s[s.length-1].id:0;_.current=c,D.current=c+1},$=x=>{if(n.current||d.current!==E||!x||typeof x!="object")return;const a=x.lines;if(!Array.isArray(a))return;if(a.length>0&&typeof a[0]=="string"){const c=a.filter(l=>typeof l=="string").map((l,v)=>jt(l,v+1));z(c,c.length);return}const s=a.filter(c=>!!c&&typeof c=="object").map((c,l)=>Z(c,l+1));z(s,s.length)},O=x=>{if(n.current||d.current!==E)return;const a=typeof x.text=="string"?x.text:typeof x.line=="string"?x.line:null;if(!a)return;const s=D.current,c=typeof x.id=="number"&&Number.isFinite(x.id)?x.id:s,l={id:c,text:a,stream:Fe(x.stream),timestamp:typeof x.timestamp=="string"?x.timestamp:""};_.current=Math.max(_.current,c),D.current=Math.max(D.current,c+1),b(v=>oe(v,[l])),N(v=>v===null?v:Math.max(v+1,l.id))};async function H(){try{const a=await ie({maxLines:Ce},e);if(n.current||d.current!==E||U.current!==L)return;const s=a.lines.map((c,l)=>Z(c,l+1));z(s,a.totalLines)}catch{if(n.current||d.current!==E||U.current!==L)return;z([],null)}finally{!n.current&&d.current===E&&U.current===L&&w(!1)}const x=ue(e);u.current=Ue(x,{events:{"dev-server:log":a=>{const s=Y(a);s&&O(s)},log:a=>{const s=Y(a);s&&O(s)},history:a=>{const s=Y(a);$(s)},"dev-server:history":a=>{const s=Y(a);$(s)}},onReconnect:()=>{n.current||d.current!==E||ie({lastEventId:_.current,maxLines:50},e).then(a=>{if(n.current||d.current!==E)return;const s=a.lines.map((c,l)=>Z(c,D.current+l));if(s.length>0){const c=s[s.length-1].id;_.current=Math.max(_.current,c),D.current=Math.max(D.current,c+1)}b(c=>oe(c,s)),N(a.totalLines)}).catch(()=>{})}})}return H(),()=>{n.current=!0,u.current&&(u.current(),u.current=null)}},[i,e]);const T=r.useCallback(async()=>{if(!i||f)return;const E=d.current,L=o.length;j(!0);try{const z=await ie({maxLines:Ce,offset:L},e);if(n.current||d.current!==E)return;const $=z.lines.map((O,H)=>Z(O,H+1));b(O=>oe($,O)),C(z.totalLines>L+$.length),N(z.totalLines)}catch{}finally{j(!1)}},[i,o.length,f,e]),h=r.useCallback(()=>{b([])},[]),p=u.current!==null&&!y&&!n.current;return{entries:o,loading:y,loadingMore:f,hasMore:M,total:P,loadMore:T,clear:h,logs:o,isStreaming:p,clearLogs:h}}const Et="This preview appears to block iframe embedding. Open it in a new tab instead.",Lt="The preview URL could not be loaded. Verify the server is running and the URL is correct.",Rt="Preview is taking longer than expected and may block iframe embedding.";function _t(e){return e==="blocked"?Et:e==="error"?Lt:null}function Dt(e,i={}){const{loadTimeoutMs:o=1e4,detectionMethod:b=null}=i,y=r.useRef(null),w=r.useRef(null),[f,j]=r.useState("unknown"),[M,C]=r.useState(null),[P]=r.useState(b),N=r.useCallback(()=>{w.current!==null&&(window.clearTimeout(w.current),w.current=null)},[]),u=r.useCallback(k=>{j(k),C(_t(k))},[]),n=r.useCallback(()=>{j("blocked"),C(Rt)},[]);r.useEffect(()=>{if(N(),!e){j("unknown"),C(null);return}j("unknown"),C(null);let k=!1;return queueMicrotask(()=>{k||(j("loading"),C(null))}),()=>{k=!0,N()}},[N,e]),r.useEffect(()=>{if(f!=="loading"){N();return}const k=setTimeout(()=>{w.current=null,n()},o);return w.current=k,()=>{clearTimeout(k),w.current===k&&(w.current=null)}},[N,f,o,n]);const d=r.useCallback(()=>{const k=y.current;if(!k){u("embedded");return}try{if(k.contentWindow?.location?.href==="about:blank"&&k.src!=="about:blank"){u("blocked");return}}catch{}u("embedded")},[u]),U=r.useCallback(()=>{u("error")},[u]);r.useEffect(()=>{if(N(),!e){j("unknown"),C(null);return}j("unknown"),C(null)},[N]);const R=r.useCallback(()=>{N(),j("unknown"),C(null)},[N]),A=R,_=r.useMemo(()=>f==="embedded",[f]),D=r.useMemo(()=>f==="blocked"||f==="error",[f]);return{embedStatus:f,isEmbedded:_,isBlocked:D,blockReason:M,detectionMethod:P,iframeRef:y,resetEmbedStatus:R,setEmbedStatus:u,retry:A,embedContext:M,handleIframeLoad:d,handleIframeError:U}}const Mt=/\x1b\[[0-9;]*m/g;function me(e){return e.replace(Mt,"")}function Ut(e){if(!e)return"";const i=new Date(e);return Number.isNaN(i.getTime())?"":i.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})}function At(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Pt(e){if(e.stream==="stderr")return"error";const i=me(e.text).toLowerCase();return/\b(warn|warning)\b/.test(i)?"warn":/\b(error|fatal)\b/.test(i)?"error":"info"}function Tt(e,i){if(!i)return e;const o=new RegExp(`(${At(i)})`,"ig"),b=e.split(o),y=i.toLowerCase();return t.jsx(t.Fragment,{children:b.map((w,f)=>w.toLowerCase()===y?t.jsx("mark",{children:w},`${w}-${f}`):t.jsx("span",{children:w},`${w}-${f}`))})}function zt({entries:e,loading:i,loadingMore:o,hasMore:b,total:y,onLoadMore:w,isRunning:f}){const j=r.useRef(null),M=r.useRef(e.length),C=r.useRef(f),[P,N]=r.useState(!1),[u,n]=r.useState(!1),[d,U]=r.useState(""),[R,A]=r.useState("all"),_=r.useMemo(()=>R==="all"?e:e.filter(p=>Pt(p)===R),[e,R]),D=r.useMemo(()=>{const p=d.trim().toLowerCase();return p?_.filter(E=>me(E.text).toLowerCase().includes(p)):_},[_,d]),k=D.length,T=r.useCallback(()=>{const p=j.current;p&&(p.scrollTop=p.scrollHeight,n(!1))},[]);r.useEffect(()=>{const p=C.current,E=M.current,L=e.length>E;f&&(!p||!u&&L)&&T(),C.current=f,M.current=e.length},[e.length,f,u,T]);const h=r.useCallback(()=>{const p=j.current;if(!p)return;const L=p.scrollTop+p.clientHeight>=p.scrollHeight-50;n(!L)},[]);return r.useEffect(()=>{i||e.length===0||!u&&f&&T()},[e,f,u,i,T]),i&&e.length===0?t.jsx("section",{className:"devserver-log-viewer","data-testid":"devserver-log-viewer",children:t.jsxs("div",{className:"devserver-log-viewer__loading","data-testid":"devserver-log-loading",children:[t.jsx(ee,{size:16,className:"devserver-log-viewer__spinner"}),t.jsx("span",{children:"Loading logs…"})]})}):t.jsxs("section",{className:`devserver-log-viewer${P?" devserver-log-viewer--fullscreen":""}`,"data-testid":"devserver-log-viewer",children:[t.jsxs("header",{className:"devserver-log-viewer__toolbar",children:[t.jsxs("div",{className:"devserver-log-viewer__toolbar-meta",children:[t.jsx("span",{className:"devserver-log-viewer__title",children:"Logs"}),t.jsxs("span",{className:"devserver-log-viewer__count","data-testid":"devserver-log-count",children:[y!==null?`${e.length}/${y}`:`${e.length}`," lines"]})]}),t.jsxs("div",{className:"devserver-log-viewer__toolbar-actions",children:[t.jsxs("label",{className:"devserver-log-viewer__severity",htmlFor:"devserver-log-severity-filter",children:[t.jsx("span",{className:"visually-hidden",children:"Filter logs by severity"}),t.jsxs("select",{id:"devserver-log-severity-filter",className:"select devserver-log-viewer__severity-select",value:R,onChange:p=>A(p.target.value),"data-testid":"devserver-log-severity-filter","aria-label":"Filter logs by severity",children:[t.jsx("option",{value:"all",children:"All severities"}),t.jsx("option",{value:"info",children:"Info"}),t.jsx("option",{value:"warn",children:"Warn"}),t.jsx("option",{value:"error",children:"Error"})]})]}),t.jsxs("label",{className:"devserver-log-viewer__search",htmlFor:"devserver-log-search",children:[t.jsx("span",{className:"visually-hidden",children:"Search logs"}),t.jsx(lt,{size:14}),t.jsx("input",{id:"devserver-log-search",className:"input devserver-log-viewer__search-input",type:"text",value:d,onChange:p=>U(p.target.value),placeholder:"Search logs","data-testid":"devserver-log-search-input","aria-label":"Search logs"})]}),d.trim().length>0&&t.jsxs("span",{className:"devserver-log-viewer__matches","data-testid":"devserver-log-match-count",children:[k," match",k===1?"":"es"]}),t.jsx("button",{type:"button",className:"btn btn-sm btn-icon",onClick:()=>N(p=>!p),"data-testid":"devserver-log-fullscreen-toggle","aria-label":P?"Exit fullscreen logs":"Enter fullscreen logs",children:P?t.jsx(ct,{size:14}):t.jsx(ot,{size:14})})]})]}),t.jsxs("div",{className:"devserver-log-viewer__body",children:[b&&t.jsx("div",{className:"devserver-log-viewer__load-more","data-testid":"devserver-log-load-more",children:t.jsx("button",{type:"button",className:"btn btn-sm touch-target",onClick:w,disabled:o,"data-testid":"devserver-log-load-more-button",children:o?t.jsxs(t.Fragment,{children:[t.jsx(ee,{size:14,className:"devserver-log-viewer__spinner"}),"Loading older logs…"]}):"Load older logs"})}),t.jsxs("div",{ref:j,className:"devserver-log-viewer__content",onScroll:h,"data-testid":"devserver-log-content",children:[!i&&D.length===0&&t.jsx("p",{className:"devserver-log-viewer__empty","data-testid":"devserver-log-empty",children:e.length===0?"No logs yet. Start the dev server to see output.":_.length===0?"No log lines match the selected severity.":"No log lines match your search."}),D.map(p=>{const E=me(p.text),L=Ut(p.timestamp);return t.jsxs("div",{className:"devserver-log-line",children:[L&&t.jsx("span",{className:"devserver-log-timestamp","data-testid":"devserver-log-timestamp",children:L}),p.stream==="stderr"&&t.jsx("span",{className:"devserver-log-stream-badge","data-testid":"devserver-log-stderr-badge",children:"ERR"}),t.jsx("span",{className:"devserver-log-text",children:Tt(E,d.trim())})]},p.id)})]}),u&&f&&t.jsxs("button",{type:"button",className:"btn btn-sm devserver-log-viewer__new-logs-button",onClick:T,"data-testid":"devserver-log-jump-button",children:[t.jsx(dt,{size:14}),"New logs"]})]})]})}const Ft="devserver-preview-iframe";function $t({url:e,embedStatus:i,onEmbedStatusChange:o,iframeRef:b,blockReason:y,onRetry:w,className:f=Ft,embedContext:j}){const M=y??j??null,[C,P]=r.useState(0);r.useEffect(()=>{!e||i!=="unknown"||(P(d=>d+1),o("loading"))},[i,o,e]);const N=r.useCallback(()=>{const d=b.current;if(!d){o("embedded");return}try{if(d.contentWindow?.location?.href==="about:blank"&&d.src!=="about:blank"){o("blocked");return}}catch{}o("embedded")},[b,o]),u=r.useCallback(d=>{d.stopPropagation(),o("error")},[o]),n=r.useCallback(()=>{e&&window.open(e,"_blank","noopener,noreferrer")},[e]);return e?t.jsxs("div",{className:"devserver-preview-iframe-shell",children:[t.jsx("iframe",{src:e,ref:b,sandbox:"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox",className:f,title:"Dev server preview",onLoad:N,onError:u,onErrorCapture:u,"data-testid":"devserver-preview-iframe"},`${e}-${C}`),i==="loading"&&t.jsxs("div",{className:"devserver-preview-overlay","data-testid":"devserver-preview-loading",children:[t.jsx(ee,{size:16,className:"dev-server-spin"}),t.jsx("span",{children:"Loading preview..."})]}),i==="blocked"&&t.jsxs("div",{className:"devserver-preview-blocked-panel",role:"alert","data-testid":"devserver-preview-blocked-panel",children:[t.jsx(Pe,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}),t.jsxs("div",{children:[t.jsx("p",{className:"devserver-preview-blocked-title",children:"Preview cannot be embedded"}),M&&t.jsx("p",{className:"devserver-preview-blocked-context",children:M})]}),t.jsx("p",{className:"devserver-preview-blocked-description",children:"You can view the preview in a separate browser tab."}),t.jsxs("div",{className:"devserver-preview-blocked-actions",children:[t.jsx("button",{type:"button",className:"btn btn-primary",onClick:n,children:"Open in new tab"}),w&&t.jsx("button",{type:"button",className:"btn btn-sm",onClick:w,children:"Retry"})]})]}),i==="error"&&t.jsxs("div",{className:"devserver-preview-error-panel",role:"alert","data-testid":"devserver-preview-error-panel",children:[t.jsx(Ae,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}),t.jsxs("div",{children:[t.jsx("p",{className:"devserver-preview-blocked-title",children:"Unable to load preview"}),M&&t.jsx("p",{className:"devserver-preview-blocked-context",children:M})]}),t.jsx("p",{className:"devserver-preview-blocked-description",children:"You can view the preview in a separate browser tab."}),t.jsxs("div",{className:"devserver-preview-blocked-actions",children:[t.jsx("button",{type:"button",className:"btn btn-primary",onClick:n,children:"Open in new tab"}),w&&t.jsx("button",{type:"button",className:"btn btn-sm",onClick:w,children:"Retry"})]})]})]}):null}const Ee={stopped:{className:"dev-server-status-badge--stopped",label:"Stopped"},starting:{className:"dev-server-status-badge--starting",label:"Starting..."},running:{className:"dev-server-status-badge--running",label:"Running"},stopping:{className:"dev-server-status-badge--starting",label:"Stopping..."},failed:{className:"dev-server-status-badge--failed",label:"Failed"}};function Le(e){return e instanceof Error?e.message:String(e)}function $e(e){return e==="."?"root":e}function Re(e){return e?e==="root"?".":e:null}function _e(e,i,o){return!i||e.scriptName!==i?!1:o?$e(e.cwd)===o:!0}function Ot(e){return e.cwd==="."?"root":e.cwd}function Bt(e){return e.length<=60?e:`${e.slice(0,60)}…`}function Wt({addToast:e,projectId:i}){const{session:o,detectedCommands:b,previewUrl:y,isLoading:w,error:f,startServer:j,stopServer:M,restartServer:C,setPreviewUrl:P,detectCommands:N,refresh:u}=kt(i),n=o?.status??"stopped",d=n==="running"||n==="starting",U=Ee[n]??Ee.stopped,{entries:R,loading:A,loadingMore:_,hasMore:D,total:k,loadMore:T}=Ct(i,!!i),h=y,p=o?.config?.cwd??null,[E,L]=r.useState(!0),[z,$]=r.useState(""),[O,H]=r.useState(""),[x,a]=r.useState(null),[s,c]=r.useState(null),[l,v]=r.useState("embedded"),S=l==="embedded"?h:null,{embedStatus:g,setEmbedStatus:Oe,resetEmbedStatus:X,iframeRef:G,isEmbedded:Be,isBlocked:te,blockReason:re,retry:fe}=Dt(S),[pe,q]=r.useState(!1),he=r.useRef(g);r.useEffect(()=>{const m=he.current!==g;te&&m&&q(!0),g==="embedded"&&q(!1),he.current=g},[g,te]),r.useEffect(()=>{q(!1)},[h]);const J=r.useMemo(()=>{if(!x)return null;const m=Re(p);return b.find(F=>!(F.scriptName!==x||m&&F.cwd!==m||o?.config?.command&&F.command!==o.config.command))??b.find(F=>_e(F,x,p))??null},[b,o?.config?.command,x,p]);r.useEffect(()=>{typeof N=="function"&&N().catch(m=>{e(Le(m),"error")})},[e,N]),r.useEffect(()=>{if(x){L(!1);return}L(!0)},[x]),r.useEffect(()=>{if(o?.status==="running"||o?.status==="starting"){o.config?.command?.trim().length>0&&$(o.config.command);return}if(J){$(J.command);return}b.length>0&&$(m=>m.trim().length>0?m:b[0]?.command??"")},[b,J,o?.config?.command,o?.status]),r.useEffect(()=>{H(h??"")},[h]);const se=r.useCallback(()=>{h&&window.open(h,"_blank","noopener,noreferrer")},[h]),be=r.useCallback(()=>{q(!1),fe()},[fe]),He=r.useCallback(()=>{try{const m=G.current;if(m?.contentWindow){m.contentWindow.location.reload(),q(!1),X();return}}catch{}if(!(!h||!G.current))try{const m=new URL(h);m.searchParams.set("_t",Date.now().toString()),G.current.src=m.toString(),q(!1),X()}catch{G.current.src=h,q(!1),X()}},[h,G,X]),K=r.useCallback(async(m,F,ne)=>{c(m);try{await F(),e(ne,"success")}catch(Ze){e(Le(Ze),"error")}finally{c(null)}},[e]),Ve=r.useCallback(m=>{a(m.scriptName),L(!1),$(m.command),e(`Selected ${m.scriptName} script.`,"success")},[e]),qe=r.useCallback(()=>{a(null),L(!0),e("Cleared selected dev server script.","success")},[e]),We=()=>{const m=z.trim();if(m.length===0){e("Enter a command before starting the dev server.","warning");return}const F=Re(p)??".",ne=J?.cwd??F;K("start",()=>j(m,ne),"Dev server started.")},Ge=()=>{K("stop",M,"Dev server stopped.")},Ie=()=>{K("restart",C,"Dev server restarted.")},Xe=()=>{const m=O.trim(),F=m.length>0?m:null;K("preview",()=>P(F),F?"Preview URL updated.":"Preview URL override cleared.")},Je=r.useCallback(()=>{f&&u()},[f,u]),Ke=n==="starting"||n==="running"||s!==null,Qe=n==="stopped"||s!==null,Ye=n==="stopped"||n==="starting"||s!==null;return t.jsxs("div",{className:"dev-server-view","data-testid":"dev-server-view",children:[t.jsxs("section",{className:"dev-server-header","aria-label":"Dev server controls header",children:[t.jsxs("div",{className:"dev-server-header-title",children:[t.jsx(ut,{size:16}),t.jsx("h2",{children:"Dev Server"}),t.jsx("span",{className:`dev-server-status-badge ${U.className}`,"data-testid":"dev-server-status-badge",children:U.label})]}),t.jsxs("div",{className:"dev-server-header-actions",children:[t.jsxs("button",{type:"button",className:"btn btn-primary btn-sm",onClick:We,disabled:Ke,"data-testid":"dev-server-start-button",children:[t.jsx(vt,{size:14}),t.jsx("span",{children:s==="start"?"Starting...":"Start"})]}),t.jsxs("button",{type:"button",className:"btn btn-danger btn-sm",onClick:Ge,disabled:Qe,"data-testid":"dev-server-stop-button",children:[t.jsx(mt,{size:14}),t.jsx("span",{children:s==="stop"?"Stopping...":"Stop"})]}),t.jsxs("button",{type:"button",className:"btn btn-sm",onClick:Ie,disabled:Ye,"data-testid":"dev-server-restart-button",children:[t.jsx(gt,{size:14}),t.jsx("span",{children:s==="restart"?"Restarting...":"Restart"})]})]})]}),t.jsxs("section",{className:"dev-server-panel dev-server-config","aria-label":"Dev server configuration",children:[t.jsxs("div",{className:"dev-server-section-header",children:[t.jsx("h3",{children:"Configuration"}),w&&t.jsx("span",{className:"dev-server-muted",children:"Loading..."})]}),w&&!o&&b.length===0&&t.jsxs("div",{className:"dev-server-loading-state","data-testid":"dev-server-loading-state",children:[t.jsx(ee,{size:16,className:"dev-server-spin"}),t.jsx("span",{children:"Loading dev server configuration..."})]}),f&&t.jsxs("div",{className:"dev-server-error-box",role:"alert","data-testid":"dev-server-error-box",children:[t.jsx("p",{children:f}),t.jsx("button",{type:"button",className:"btn btn-sm",onClick:Je,children:"Retry"})]}),t.jsxs("div",{className:"dev-server-section",children:[t.jsx("h3",{children:"Script Selection"}),x&&t.jsxs("div",{className:"dev-server-selected","data-testid":"dev-server-selected-summary",children:[t.jsx("span",{className:"dev-server-candidate-name",children:x}),t.jsx("span",{className:"dev-server-candidate-source",children:p??"root"}),t.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>L(!0),"data-testid":"dev-server-change-selection",children:"Change"}),t.jsx("button",{type:"button",className:"btn btn-danger btn-sm",onClick:qe,"data-testid":"dev-server-clear-selection",children:"Clear"})]}),E&&b.length===0&&t.jsxs("p",{className:"dev-server-empty-state","data-testid":"dev-server-empty-candidates",children:["No dev server scripts detected. Check that your project has a ",t.jsx("code",{children:"package.json"})," with a ",t.jsx("code",{children:"dev"}),", ",t.jsx("code",{children:"start"}),", or similar script."]}),E&&b.length>0&&t.jsx("div",{className:"dev-server-candidates","data-testid":"dev-server-candidates",children:b.map(m=>{const F=_e(m,x,p);return t.jsxs("button",{type:"button",className:`dev-server-candidate ${F?"dev-server-candidate--selected":""}`,onClick:()=>Ve(m),"data-testid":`dev-server-candidate-${m.scriptName}-${$e(m.cwd)}`,children:[t.jsx("span",{className:"dev-server-candidate-name",children:m.scriptName}),t.jsx("span",{className:"dev-server-candidate-command",children:Bt(m.command)}),t.jsx("span",{className:"dev-server-candidate-source",children:Ot(m)})]},`${m.cwd}::${m.scriptName}::${m.command}`)})})]}),t.jsxs("div",{className:"dev-server-field-group",children:[t.jsx("label",{htmlFor:"dev-server-command",className:"dev-server-label",children:"Command"}),t.jsx("input",{id:"dev-server-command",className:"input",value:z,onChange:m=>$(m.target.value),placeholder:"pnpm dev","data-testid":"dev-server-command-input",readOnly:n==="running"||n==="starting"})]}),(n==="running"||n==="starting")&&o&&t.jsxs("div",{className:"dev-server-current-command","data-testid":"dev-server-current-command",children:[t.jsx("span",{className:"dev-server-label",children:"Running command"}),t.jsx("code",{children:o.config?.command??z})]}),t.jsxs("div",{className:"dev-server-preview-override",children:[t.jsx("label",{htmlFor:"dev-server-preview-input",className:"dev-server-label",children:"Preview URL Override"}),t.jsx("input",{id:"dev-server-preview-input",className:"input",type:"url",value:O,onChange:m=>H(m.target.value),placeholder:"http://localhost:3000","data-testid":"dev-server-preview-input"}),t.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:Xe,disabled:s==="preview","data-testid":"dev-server-set-preview",children:"Save"})]}),h&&t.jsxs("p",{className:"dev-server-preview-hint",children:["Auto-detected: ",h]})]}),t.jsxs("div",{className:"dev-server-content",children:[t.jsxs("section",{className:"dev-server-panel dev-server-logs-panel","data-testid":"dev-server-logs-panel","aria-label":"Dev server logs",children:[t.jsxs("div",{className:"dev-server-section-header",children:[t.jsx("h3",{children:"Logs"}),t.jsxs("span",{className:"dev-server-muted",children:[k??R.length," lines"]})]}),t.jsx("div",{className:"dev-server-logs-viewer","data-testid":"dev-server-log-viewer",children:t.jsx(zt,{entries:R,loading:A,loadingMore:_,hasMore:D,total:k,onLoadMore:T,isRunning:d})})]}),t.jsxs("section",{className:"dev-server-panel devserver-preview-panel","data-testid":"devserver-preview-panel","aria-label":"Dev server preview",children:[t.jsxs("div",{className:"devserver-preview-header",children:[t.jsxs("div",{className:"devserver-preview-title",children:[t.jsx(ft,{size:14}),t.jsx("span",{children:"Preview"})]}),t.jsxs("span",{className:"devserver-preview-url-badge devserver-preview-url-badge--auto",title:h??"No preview URL","data-testid":"devserver-preview-url-badge",children:["Auto",h?` · ${h}`:" · Not available"]}),t.jsxs("div",{className:"devserver-preview-actions",children:[t.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>v(m=>m==="embedded"?"external":"embedded"),"data-testid":"devserver-preview-mode-toggle",children:l==="embedded"?"External only":"Embedded"}),t.jsx("button",{type:"button",className:"btn btn-sm btn-icon",title:"Open in new tab",onClick:se,disabled:!h,"data-testid":"devserver-preview-open-tab",children:t.jsx(pt,{size:14})}),t.jsx("button",{type:"button",className:"btn btn-sm btn-icon",title:"Refresh preview",onClick:He,disabled:!h,"data-testid":"devserver-preview-refresh",children:t.jsx(ht,{size:14})})]})]}),t.jsxs("div",{className:"devserver-preview-container","data-embed-status":g,"data-embedded":Be?"true":"false",children:[!h&&!d&&t.jsx("p",{className:"devserver-preview-empty",children:"Start a dev server to see a live preview here."}),!h&&d&&t.jsx("p",{className:"devserver-preview-empty",children:"No preview URL detected. Start the dev server or set a manual URL to preview your app."}),h&&l==="external"&&t.jsxs("div",{className:"devserver-preview-external-only","data-testid":"devserver-preview-external-only",children:[t.jsx("p",{children:"Embedded preview is disabled. Open your app in a separate browser tab."}),t.jsx("button",{type:"button",className:"btn btn-primary btn-sm touch-target",onClick:se,"data-testid":"devserver-preview-external-open-tab",children:"Open in new tab"})]}),h&&l==="embedded"&&pe&&te&&t.jsxs("div",{className:g==="error"?"devserver-preview-error-panel":"devserver-preview-blocked-panel","data-testid":"devserver-preview-fallback",role:"alert",children:[g==="error"?t.jsx(Ae,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}):t.jsx(Pe,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}),t.jsxs("div",{children:[t.jsx("p",{className:"devserver-preview-blocked-title",children:g==="error"?"Preview failed":"Preview blocked"}),re&&t.jsx("p",{className:"devserver-preview-blocked-context",children:re})]}),t.jsx("p",{className:"devserver-preview-blocked-description",children:"Open the preview in a new tab, or retry embedded mode after checking your server settings."}),t.jsxs("div",{className:"devserver-preview-blocked-actions",children:[t.jsx("button",{type:"button",className:"btn btn-primary",onClick:se,"data-testid":"devserver-preview-fallback-open-tab",children:"Open preview in new tab"}),t.jsx("button",{type:"button",className:"btn btn-sm",onClick:be,"data-testid":"devserver-preview-fallback-retry",children:"Retry embedded preview"})]})]}),h&&l==="embedded"&&!pe&&t.jsx($t,{url:h,embedStatus:g,onEmbedStatusChange:Oe,iframeRef:G,blockReason:re,onRetry:be})]})]})]})]})}export{Wt as DevServerView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.dev-server-view{display:flex;flex-direction:column;gap:var(--space-md);padding:var(--space-lg);min-height:0;height:100%;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain}.dev-server-header{display:flex;justify-content:space-between;align-items:center;gap:var(--space-md);padding:var(--space-md);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--card)}.dev-server-header-title{display:flex;align-items:center;gap:var(--space-sm)}.dev-server-header-title h2{margin:0;font-size:1.125rem;font-weight:600;color:var(--text)}.dev-server-header-actions{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-sm)}.dev-server-status-badge{display:inline-flex;align-items:center;justify-content:center;border:1px solid transparent;border-radius:var(--radius-pill);padding:var(--space-xs) var(--space-sm);font-family:var(--font-mono)}.dev-server-status-badge--stopped{color:var(--color-muted);background:color-mix(in srgb,var(--color-muted) 16%,transparent);border-color:color-mix(in srgb,var(--color-muted) 40%,transparent)}.dev-server-status-badge--starting{color:var(--color-warning);background:color-mix(in srgb,var(--color-warning) 16%,transparent);border-color:color-mix(in srgb,var(--color-warning) 40%,transparent)}.dev-server-status-badge--running{color:var(--color-success);background:color-mix(in srgb,var(--color-success) 16%,transparent);border-color:color-mix(in srgb,var(--color-success) 40%,transparent)}.dev-server-status-badge--failed{color:var(--color-error);background:color-mix(in srgb,var(--color-error) 16%,transparent);border-color:color-mix(in srgb,var(--color-error) 40%,transparent)}.dev-server-panel{display:flex;flex-direction:column;gap:var(--space-md);min-height:0;padding:var(--space-md);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--card);cursor:default;user-select:text;touch-action:auto}.dev-server-config{flex:0 0 auto;min-height:0;max-height:min(52vh,calc(var(--space-2xl) * 16));overflow-y:auto;overscroll-behavior:contain}.dev-server-section-header{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm)}.dev-server-section-header h3{margin:0}.dev-server-muted{color:var(--text-muted);font-family:var(--font-mono)}.dev-server-field-group{display:flex;flex-direction:column;gap:var(--space-xs)}.dev-server-label{color:var(--text-muted)}.dev-server-empty-state{margin:0;color:var(--text-muted)}.dev-server-empty-state code{font-family:var(--font-mono)}.dev-server-section{display:flex;flex-direction:column;gap:var(--space-md);min-height:0;padding:var(--space-xl);max-width:calc(var(--space-2xl) * 25);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface)}.dev-server-section h3{margin:0}.dev-server-candidates{display:flex;flex-direction:column;gap:var(--space-sm);min-height:0;max-height:min(36vh,calc(var(--space-2xl) * 9));overflow-y:auto;overscroll-behavior:contain}.dev-server-candidate{display:flex;align-items:center;gap:var(--space-md);width:100%;padding:var(--space-lg);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--card);color:var(--text);text-align:left;cursor:pointer;transition:background var(--transition-fast),border-color var(--transition-fast),box-shadow var(--transition-fast)}.dev-server-candidate:hover{background:var(--card-hover)}.dev-server-candidate:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.dev-server-candidate--selected{border-left:calc(var(--btn-border-width) * 3) solid var(--todo);background:var(--status-todo-bg)}.dev-server-candidate-name{font-family:var(--font-mono);font-size:.8125rem;font-weight:600}.dev-server-candidate-command{color:var(--text-muted);font-family:var(--font-mono);font-size:.75rem;max-width:calc(var(--space-2xl) * 9 + var(--space-md));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dev-server-candidate-source{margin-left:auto;color:var(--text-dim);font-size:.6875rem}.dev-server-selected{display:flex;align-items:center;gap:var(--space-md);padding:var(--space-lg);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface)}.dev-server-selected .btn{margin-left:0}.dev-server-preview-override{display:flex;align-items:center;gap:var(--space-sm);margin-top:var(--space-xl)}.dev-server-preview-override .input{flex:1}.dev-server-preview-hint{margin:0;color:var(--text-muted)}.dev-server-loading-state{display:flex;align-items:center;gap:var(--space-sm);color:var(--text-muted)}.dev-server-error-box{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm);padding:var(--space-sm);border:1px solid color-mix(in srgb,var(--color-error) 40%,transparent);border-radius:var(--radius-sm);background:color-mix(in srgb,var(--color-error) 10%,transparent);color:var(--color-error)}.dev-server-error-box p{margin:0}.dev-server-current-command{display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface)}.dev-server-current-command code{font-family:var(--font-mono);white-space:pre-wrap;word-break:break-word}.dev-server-error{margin:0;padding:var(--space-sm);border-radius:var(--radius-sm);border:1px solid color-mix(in srgb,var(--color-error) 40%,transparent);color:var(--color-error);background:color-mix(in srgb,var(--color-error) 10%,transparent)}.dev-server-content{flex:1;min-height:0;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--space-md)}.dev-server-logs-panel,.dev-server-preview{min-height:0}.dev-server-logs-viewer{flex:1;min-height:0}.dev-server-logs{flex:1;min-height:clamp(calc(var(--space-2xl) * 3 + var(--space-xs)),28vh,calc(var(--space-2xl) * 5));max-height:clamp(calc(var(--space-2xl) * 8),55vh,calc(var(--space-2xl) * 14));padding:var(--space-md);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg);overflow-y:auto;font-family:var(--font-mono)}.dev-server-log-line{margin:0;white-space:pre-wrap;word-break:break-word}.devserver-preview-panel{display:flex;flex-direction:column;border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;background:var(--surface)}.devserver-preview-header{display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) var(--space-md);border-bottom:1px solid var(--border)}.devserver-preview-title{display:flex;align-items:center;gap:var(--space-xs);font-size:.8125rem;font-weight:600;color:var(--text)}.devserver-preview-url-badge{flex:1 1 auto;min-width:0;max-width:calc(var(--space-2xl) * 9);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:var(--space-xs) var(--space-sm);border-radius:var(--radius-pill);font-family:var(--font-mono);font-size:.6875rem}.devserver-preview-url-badge--manual{color:var(--color-info);background:color-mix(in srgb,var(--color-info) 14%,transparent)}.devserver-preview-url-badge--auto{color:var(--text-muted);background:color-mix(in srgb,var(--surface) 70%,var(--text))}.devserver-preview-actions{display:flex;gap:var(--space-xs);margin-left:auto}.devserver-preview-container{position:relative;flex:1;min-height:clamp(calc(var(--space-2xl) * 4),42vh,calc(var(--space-2xl) * 9 + var(--space-sm)));max-height:clamp(calc(var(--space-2xl) * 10),72vh,calc(var(--space-2xl) * 18 + var(--space-lg)));overflow:hidden}.devserver-preview-iframe-shell{position:relative;width:100%;height:100%}.devserver-preview-iframe{width:100%;height:100%;border:none;background:var(--surface)}.devserver-preview-overlay{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-md);background:color-mix(in srgb,var(--bg) 85%,transparent);color:var(--text-muted)}.devserver-preview-blocked-panel,.devserver-preview-error-panel{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100%;gap:var(--space-md);padding:var(--space-xl);text-align:center;border-radius:var(--radius-lg)}.devserver-preview-blocked-panel{background:color-mix(in srgb,var(--color-warning) 8%,transparent);border:1px solid color-mix(in srgb,var(--color-warning) 20%,transparent)}.devserver-preview-error-panel{background:color-mix(in srgb,var(--color-error) 8%,transparent);border:1px solid color-mix(in srgb,var(--color-error) 20%,transparent)}.devserver-preview-blocked-icon{width:calc(var(--space-2xl) + var(--space-lg));height:calc(var(--space-2xl) + var(--space-lg));color:var(--color-warning)}.devserver-preview-error-panel .devserver-preview-blocked-icon{color:var(--color-error)}.devserver-preview-blocked-title{margin:0 0 var(--space-xs);font-size:1rem;font-weight:600;color:var(--text)}.devserver-preview-blocked-context{margin:0;font-size:.75rem;color:var(--text-muted);font-family:var(--font-mono);background:color-mix(in srgb,var(--bg) 80%,transparent);padding:var(--space-xs) var(--space-sm);border-radius:var(--radius-sm)}.devserver-preview-blocked-description{margin:0;color:var(--text-muted);font-size:.8125rem}.devserver-preview-blocked-actions{display:flex;gap:var(--space-sm);flex-wrap:wrap;justify-content:center}.devserver-preview-empty{margin:0;padding:var(--space-2xl);text-align:center;color:var(--text-dim);font-size:.8125rem}.devserver-preview-external-only{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-md);min-height:100%;padding:var(--space-lg);text-align:center;color:var(--text-muted);background:color-mix(in srgb,var(--surface) 80%,var(--text))}.devserver-preview-external-only p{margin:0}.dev-server-preview-fallback{border:1px solid color-mix(in srgb,var(--color-warning) 40%,transparent);background:color-mix(in srgb,var(--color-warning) 10%,transparent)}.dev-server-preview-external-only{border:1px solid var(--border);background:var(--surface)}.dev-server-spin{animation:dev-server-spin 1s linear infinite}@media(max-width:768px){.dev-server-view{padding:var(--space-md)}.dev-server-header{flex-direction:column;align-items:flex-start}.dev-server-header-actions{width:100%}.dev-server-content{grid-template-columns:minmax(0,1fr)}.devserver-preview-header{flex-wrap:wrap}.devserver-preview-url-badge{flex:1 1 auto;min-width:0}.devserver-preview-actions{width:100%;margin-left:0;justify-content:flex-end}.dev-server-preview-override{flex-direction:column;align-items:stretch}.dev-server-candidate,.dev-server-selected{flex-wrap:wrap}.dev-server-config{max-height:min(48vh,calc(var(--space-2xl) * 13))}.dev-server-candidates{max-height:min(32vh,calc(var(--space-2xl) * 7))}.dev-server-candidate-source{margin-left:0}.dev-server-header-actions .btn,.devserver-preview-actions .btn,.dev-server-preview-override .btn,.devserver-preview-external-only .btn,.devserver-preview-blocked-panel .btn,.devserver-preview-error-panel .btn,.devserver-log-viewer__load-more .btn{min-height:calc(var(--space-lg) + var(--space-lg) + var(--space-xs))}.devserver-preview-actions .btn-icon{min-width:calc(var(--space-lg) + var(--space-lg) + var(--space-xs));min-height:calc(var(--space-lg) + var(--space-lg) + var(--space-xs))}.devserver-log-viewer__toolbar{flex-wrap:wrap;padding:var(--space-xs) var(--space-sm)}.devserver-log-viewer__toolbar-actions{width:100%;justify-content:space-between}.devserver-log-viewer__search{flex:1}.devserver-log-viewer__search-input{min-width:0;width:100%}.devserver-log-viewer__content{padding:var(--space-xs);font-size:.6875rem}.devserver-log-viewer__new-logs-button{bottom:var(--space-lg);min-height:calc(var(--space-lg) + var(--space-lg) + var(--space-xs))}.dev-server-logs,.devserver-preview-container,.devserver-preview-iframe{min-height:calc(var(--space-2xl) * 4 + var(--space-md))}.devserver-preview-blocked-panel,.devserver-preview-error-panel,.devserver-preview-external-only{word-break:break-word}.devserver-preview-blocked-panel,.devserver-preview-error-panel{padding:var(--space-md)}.devserver-preview-blocked-actions .btn{min-height:calc(var(--space-lg) + var(--space-md) + var(--space-sm))}.chat-tool-calls-header,.chat-tool-call summary,.chat-tool-call-content,.chat-tool-call-preview,.chat-tool-call-value{font-size:.6875rem}.chat-tool-call summary{padding:var(--space-xs)}.chat-tool-call-content{margin:var(--space-xs);padding:var(--space-xs)}.chat-tool-call-status-text{font-size:.625rem}}.devserver-log-viewer{display:flex;flex-direction:column;height:100%;min-height:0;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface);overflow:hidden}.devserver-log-viewer--fullscreen{position:fixed;inset:0;z-index:120;border-radius:0}.devserver-log-viewer__toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm);padding:var(--space-sm) var(--space-md);border-bottom:1px solid var(--border);background:var(--card)}.devserver-log-viewer__toolbar-meta{display:flex;align-items:baseline;gap:var(--space-sm)}.devserver-log-viewer__title{color:var(--text);font-weight:600}.devserver-log-viewer__count{color:var(--text-muted);font-family:var(--font-mono);font-size:.75rem}.devserver-log-viewer__toolbar-actions{display:flex;align-items:center;gap:var(--space-sm)}.devserver-log-viewer__severity,.devserver-log-viewer__search{display:inline-flex;align-items:center;gap:var(--space-xs);color:var(--text-muted)}.devserver-log-viewer__severity-select{min-height:calc(var(--space-lg) + var(--space-md));min-width:calc(var(--space-2xl) * 3);font-size:.75rem}.devserver-log-viewer__search-input{min-height:calc(var(--space-lg) + var(--space-md));min-width:calc(var(--space-2xl) * 4);font-size:.75rem}.devserver-log-viewer__matches{color:var(--text-muted);font-family:var(--font-mono);font-size:.6875rem}.devserver-log-viewer__body{position:relative;display:flex;flex:1;flex-direction:column;min-height:0}.devserver-log-viewer__load-more{display:flex;justify-content:center;padding:var(--space-sm);border-bottom:1px solid var(--border);background:color-mix(in srgb,var(--surface) 95%,var(--text))}.devserver-log-viewer__content{flex:1;min-height:0;overflow-y:auto;padding:var(--space-sm);font-family:var(--font-mono);font-size:.75rem;line-height:1.5;background:var(--surface)}.devserver-log-viewer__loading,.devserver-log-viewer__empty{display:flex;align-items:center;justify-content:center;gap:var(--space-sm);min-height:calc(var(--space-2xl) * 4);margin:0;color:var(--text-muted)}.devserver-log-viewer__spinner{animation:dev-server-spin 1s linear infinite}.devserver-log-line{padding:var(--space-xs) var(--space-sm);border-radius:var(--radius-sm);white-space:pre-wrap;word-break:break-all}.devserver-log-line:nth-child(2n){background:color-mix(in srgb,var(--surface) 95%,var(--text))}.devserver-log-timestamp{margin-right:var(--space-sm);color:var(--text-dim);font-size:.6875rem}.devserver-log-stream-badge{margin-right:var(--space-sm);padding:0 var(--space-xs);border-radius:var(--radius-pill);background:color-mix(in srgb,var(--color-error) 15%,transparent);color:var(--color-error);font-size:.625rem;font-weight:600}.devserver-log-text{color:var(--text)}.devserver-log-text mark{border-radius:var(--radius-sm);background:color-mix(in srgb,var(--todo) 40%,transparent);color:var(--text)}.devserver-log-viewer__new-logs-button{position:absolute;left:50%;bottom:var(--space-xl);transform:translate(-50%);z-index:10;border-color:var(--border);background:var(--card);box-shadow:var(--shadow-md)}.devserver-log-viewer__new-logs-button:active{transform:translate(-50%) scale(.97)}@keyframes dev-server-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media(max-width:480px){.devserver-preview-blocked-actions{width:100%;flex-direction:column}.devserver-preview-blocked-actions .btn{width:100%;min-height:calc(var(--space-lg) + var(--space-lg) + var(--space-xs))}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as t,j as r}from"./vendor-react-K0fH_qHe.js";import{bV as f,bW as b,D as x,a7 as g,a2 as P,a3 as C,L as H,ae as O}from"./index-y194HxzU.js";import{F as v}from"./folder-open-kO5Hsk66.js";function S({value:d,onChange:l,placeholder:y,onInputKeyDown:j,nodeId:h,localNodeId:p}){const[e,a]=t.useState({isOpen:!1,loading:!1,error:null,currentPath:"",parentPath:null,entries:[],showHidden:!1}),c=t.useCallback(async(s,n=!1)=>{a(i=>({...i,loading:!0,error:null}));try{const i=await f(s,n,h,p);a(u=>({...u,loading:!1,currentPath:i.currentPath,parentPath:i.parentPath,entries:i.entries}))}catch(i){a(u=>({...u,loading:!1,error:i instanceof Error?i.message:"Failed to browse directory"}))}},[h,p]),k=t.useCallback(()=>{a(s=>s.isOpen?{...s,isOpen:!1}:{...s,isOpen:!0})},[]);t.useEffect(()=>{e.isOpen&&!e.loading&&e.entries.length===0&&!e.error&&c(d||void 0,e.showHidden)},[e.isOpen,e.loading,e.entries.length,e.error,d,e.showHidden,c,h,p]);const o=t.useCallback(s=>{c(s,e.showHidden)},[c,e.showHidden]),w=t.useCallback(()=>{l(e.currentPath),a(s=>({...s,isOpen:!1}))},[e.currentPath,l]),N=t.useCallback(()=>{a(s=>{const n=!s.showHidden;return{...s,showHidden:n}})},[]);t.useEffect(()=>{e.isOpen&&e.currentPath&&c(e.currentPath,e.showHidden)},[e.showHidden]);const m=e.currentPath?e.currentPath.split("/").filter(Boolean):[];return r.jsxs("div",{className:"directory-picker",children:[r.jsxs("div",{className:"directory-picker-input-row",children:[r.jsx("input",{type:"text",className:"directory-picker-input",value:d,onChange:s=>l(s.target.value),onKeyDown:j,placeholder:y||"/path/to/your/project"}),r.jsxs("button",{type:"button",className:"directory-picker-browse-btn",onClick:k,"aria-label":e.isOpen?"Close directory browser":"Browse directories",children:[e.isOpen?r.jsx(v,{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.jsxs("div",{className:"directory-picker-breadcrumbs",children:[r.jsx("button",{className:"directory-picker-breadcrumb",onClick:()=>o("/"),title:"Root",children:"/"}),m.map((s,n)=>{const i="/"+m.slice(0,n+1).join("/");return r.jsxs("span",{className:"directory-picker-breadcrumb-item",children:[r.jsx(x,{size:12,className:"directory-picker-breadcrumb-sep"}),r.jsx("button",{className:"directory-picker-breadcrumb",onClick:()=>o(i),title:i,children:s})]},i)})]}),r.jsxs("div",{className:"directory-picker-toolbar",children:[e.parentPath&&r.jsxs("button",{className:"directory-picker-up-btn",onClick:()=>o(e.parentPath),"aria-label":"Go to parent directory",title:"Parent directory",children:[r.jsx(g,{size:14}),r.jsx("span",{children:"Up"})]}),r.jsxs("button",{className:"directory-picker-hidden-toggle",onClick:N,"aria-label":e.showHidden?"Hide hidden directories":"Show hidden directories",title:e.showHidden?"Hide hidden":"Show hidden",children:[e.showHidden?r.jsx(P,{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(H,{size:20,className:"animate-spin"}),r.jsx("span",{children:"Loading…"})]}):e.error?r.jsxs("div",{className:"directory-picker-error",children:[r.jsx(O,{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",{className:"directory-picker-entry",onClick:()=>o(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(x,{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",{className:"btn-primary directory-picker-select-btn",onClick:w,children:"Select"})]})]})]})}export{S as D};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{Y as oe,$ as G,a0 as le,a1 as ie,F as z,a2 as de,a3 as ue,S as me,X as he,R as pe,a4 as fe,a5 as W,a6 as V,K as X,D as je,a7 as xe}from"./index-y194HxzU.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?G(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 G(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 Y(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:Y(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:_,refresh:B}=we({projectId:n,searchQuery:T||void 0,includeProjectFiles:!1}),{files:S,loading:$,error:J,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"?J:_,ae=s.useCallback(async()=>{if(a==="project"){await O();return}await B()},[a,O,B]),q=a==="project"?A.length:N.length,K=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-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:K,value:l,onChange:Z,"aria-label":K}),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)," · ",Y(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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.documents-view{display:flex;flex-direction:column;height:100%;min-height:0}.documents-view-header{padding:var(--space-lg);border-bottom:1px solid var(--border);background:var(--surface)}.documents-view-title-row{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--space-md)}.documents-view-title{display:flex;align-items:center;gap:var(--space-sm);font-size:18px;font-weight:600;margin:0;color:var(--text)}.documents-view-title svg{color:var(--todo)}.documents-view-count{font-size:14px;color:var(--text-muted)}.documents-tab-bar{display:flex;align-items:center;gap:var(--space-sm);margin-bottom:var(--space-md)}.documents-tab{display:inline-flex;align-items:center;gap:var(--space-sm);border:1px solid var(--border);background:var(--surface);color:var(--text-muted)}.documents-tab:hover{background:var(--card-hover);color:var(--text)}.documents-tab.active{color:var(--todo);border-color:var(--todo);background:color-mix(in srgb,var(--todo) 12%,transparent)}.documents-tab:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.documents-tab-count{display:inline-flex;align-items:center;justify-content:center;min-width:20px;padding:0 var(--space-xs);border-radius:var(--radius-pill);background:color-mix(in srgb,var(--text) 10%,transparent);color:inherit;font-size:11px;font-family:var(--font-mono)}.documents-hidden-toggle{align-self:flex-start;margin-bottom:var(--space-sm)}.documents-hidden-toggle[aria-pressed=true]{color:var(--todo);border-color:var(--todo);background:color-mix(in srgb,var(--todo) 12%,transparent)}.documents-search{position:relative;display:flex;align-items:center}.documents-search-icon{position:absolute;left:var(--space-sm);color:var(--text-muted);pointer-events:none}.documents-search-input{width:100%;max-width:420px;padding:var(--space-sm) var(--space-sm) var(--space-sm) calc(var(--space-sm) + 24px);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg);color:var(--text);font-size:14px;transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.documents-search-input:focus-visible{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring-strong)}.documents-search-input::placeholder{color:var(--text-dim)}.documents-search-clear{position:absolute;right:var(--space-sm);display:flex;align-items:center;justify-content:center;background:none;border:none;color:var(--text-muted);cursor:pointer;padding:var(--space-xs);border-radius:var(--radius-sm);transition:color var(--transition-fast),background var(--transition-fast)}.documents-search-clear:hover{color:var(--text);background:var(--card-hover)}.documents-search-clear:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.documents-view-content{flex:1;min-height:0;overflow:auto;padding:var(--space-lg)}.documents-view-loading,.documents-view-empty,.documents-view-error{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:var(--space-2xl);color:var(--text-muted);min-height:200px}.documents-view-empty-icon{margin-bottom:var(--space-md);color:var(--text-dim)}.documents-view-empty-hint{font-size:13px;color:var(--text-dim);margin-top:var(--space-xs)}.documents-view-error{color:var(--color-error)}.documents-view-error .btn{margin-top:var(--space-md)}.documents-project-layout{display:grid;grid-template-columns:minmax(280px,320px) minmax(0,1fr);min-height:0;height:100%;border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;background:var(--card)}.documents-project-layout--mobile{grid-template-columns:1fr}.documents-view-sidebar{width:100%;min-width:0;overflow-y:auto;border-right:1px solid var(--border);background:var(--surface)}.markdown-file-list{margin:0;padding:0;list-style:none}.markdown-file-list-item{margin:0}.markdown-file-item{width:100%;display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-xs);border:none;border-left:3px solid transparent;border-bottom:1px solid var(--border);padding:var(--space-md);background:transparent;color:var(--text);text-align:left;cursor:pointer;transition:background var(--transition-fast),border-color var(--transition-fast)}.markdown-file-list-item:last-child .markdown-file-item{border-bottom:none}.markdown-file-item:hover{background:var(--card-hover)}.markdown-file-item:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.markdown-file-item--selected{border-left-color:var(--todo);background:color-mix(in srgb,var(--todo) 12%,transparent)}.markdown-file-item-name{font-size:13px;font-weight:600;color:var(--text)}.markdown-file-item-path{font-size:12px;color:var(--text-muted);font-family:var(--font-mono);word-break:break-word}.markdown-file-item-meta{font-size:12px;color:var(--text-dim)}.documents-view-main{min-width:0;overflow-y:auto;background:var(--card);padding:var(--space-lg)}.documents-mobile-back{margin-bottom:var(--space-md)}.documents-content-viewer{display:flex;flex-direction:column;gap:var(--space-md);margin:0 auto;width:min(100%,880px)}.documents-content-header{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm)}.documents-file-path-header{margin:0;padding:var(--space-sm) var(--space-md);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface);color:var(--text-muted);font-family:var(--font-mono);font-size:12px;word-break:break-word;flex:1}.documents-content-viewer-text,.documents-content-markdown{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface);padding:var(--space-md);min-height:220px}.documents-content-state{margin:0;color:var(--text-muted)}.documents-content-state--error{color:var(--color-error)}.documents-task-list-wrap{width:min(100%,960px);margin:0 auto}.documents-view-list{display:flex;flex-direction:column;gap:var(--space-md)}.documents-group{border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;background:var(--card)}.documents-group-header{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:var(--space-sm);padding:var(--space-sm) var(--space-md);background:var(--surface);border-bottom:1px solid var(--border)}.documents-group-toggle-btn{display:flex;align-items:center;gap:var(--space-sm);min-width:0;border:none;background:none;color:var(--text);text-align:left;padding:var(--space-xs) var(--space-sm);border-radius:var(--radius-md);cursor:pointer;transition:background var(--transition-fast);min-height:36px}.documents-group-toggle-btn:hover{background:var(--card-hover)}.documents-group-toggle-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.documents-group-toggle{display:flex;align-items:center;justify-content:center;color:var(--text-muted);flex-shrink:0}.documents-group-task-id{font-family:var(--font-mono);font-size:12px;color:var(--text-muted);flex-shrink:0}.documents-group-task-title{font-size:14px;font-weight:500;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.documents-group-count{font-size:12px;color:var(--text-dim);justify-self:end}.documents-group-task-link{border:1px solid var(--border);background:var(--card);color:var(--text-muted);padding:var(--space-xs) var(--space-sm);border-radius:var(--radius-md);cursor:pointer;transition:border-color var(--transition-fast),color var(--transition-fast),background var(--transition-fast);min-height:36px}.documents-group-task-link:hover{border-color:var(--todo);color:var(--todo);background:color-mix(in srgb,var(--todo) 10%,transparent)}.documents-group-task-link:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.documents-group-content{padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-sm)}.document-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden;transition:border-color var(--transition-fast)}.document-card:hover{border-color:var(--text-dim)}.document-card-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-sm) var(--space-md);background:var(--surface);border-bottom:1px solid var(--border)}.document-card-key{display:flex;align-items:center;gap:var(--space-xs);color:var(--text)}.document-card-key svg{color:var(--text-muted);flex-shrink:0}.document-card-key-text{font-family:var(--font-mono);font-size:13px;font-weight:500}.document-card-revision-badge{font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted);background:var(--surface);padding:var(--space-xs) var(--space-sm);border-radius:var(--radius-pill);border:1px solid var(--border)}.document-card-expand-btn{padding:var(--space-xs);color:var(--text-muted)}.document-card-expand-btn:hover{color:var(--text)}.document-card-actions{display:flex;align-items:center;gap:var(--space-xs)}.document-mode-toggle{padding:var(--space-xs) var(--space-sm);font-size:11px;font-weight:500;color:var(--text-muted);background:var(--card);border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;transition:var(--transition-fast);line-height:1}.document-mode-toggle:hover{background:var(--card-hover);color:var(--text)}.document-mode-toggle:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.document-mode-toggle[aria-pressed=true]{background:var(--accent);color:var(--text-on-accent);border-color:var(--accent)}.document-card-content-header{display:flex;justify-content:flex-end;margin-bottom:var(--space-sm)}.document-card-meta{display:flex;align-items:center;gap:var(--space-xs);padding:var(--space-xs) var(--space-md);font-size:12px;color:var(--text-dim);border-bottom:1px solid var(--border)}.document-card-separator{color:var(--border)}.document-card-content{padding:var(--space-md)}.document-card-preview{margin:0;font-size:13px;color:var(--text-muted);line-height:1.5;word-break:break-word}.document-card-preview-truncated{margin:0;font-size:13px;color:var(--text-dim)}.document-card-content--expanded .document-card-preview,.document-card-content--expanded .document-card-preview-truncated{display:none}.document-card-content-text{margin:0;font-size:13px;color:var(--text);line-height:1.5;white-space:pre-wrap;word-break:break-word;font-family:var(--font-primary)}@media(max-width:768px){.agent-board{grid-template-columns:1fr}.agent-board-actions .btn,.agent-card-actions .btn{min-height:calc(var(--space-2xl) + var(--space-xs))}.agent-card-details-btn{margin-left:auto}.agent-controls-panel{left:var(--space-md);right:var(--space-md);top:calc(var(--header-height) + var(--space-sm));width:auto;max-height:calc(100dvh - var(--header-height) - var(--space-2xl));overflow-y:auto}.agent-controls{flex-direction:column;align-items:stretch;gap:var(--space-sm)}.agent-controls-filters{flex-direction:column;align-items:stretch;width:100%;padding:var(--space-sm)}.agent-controls-actions{display:flex;flex-direction:column;gap:var(--space-sm)}.agent-controls-actions .btn{width:100%;min-height:calc(var(--space-2xl) + var(--space-xs))}.agent-controls-panel .agent-controls-actions{justify-content:flex-start}.agent-state-filter,.agent-system-filter{width:100%;min-height:calc(var(--space-2xl) + var(--space-xs))}.agent-state-filter-select{width:100%}.agent-heartbeat-control{align-items:flex-start}.agent-heartbeat-select{min-height:calc(var(--space-2xl) + var(--space-xs))}.heartbeat-multiplier-controls{flex-direction:column;align-items:stretch}.heartbeat-multiplier-value{text-align:left}.agent-global-controls{padding:var(--space-sm)}.heartbeat-multiplier-label{margin-bottom:var(--space-sm)}.agents-view-content{padding:var(--space-md)}.skills-view-header{padding:var(--space-sm) var(--space-md);flex-wrap:wrap}.skills-view-title h2{font-size:16px}.skills-view-count{font-size:12px}.skills-view-actions{min-height:36px;display:flex;align-items:center}.skills-view-actions .btn{min-height:36px}.skills-view-content{padding:var(--space-md)}.skills-view-section{margin-bottom:var(--space-md)}.skills-view-section-title{font-size:13px}.skills-view-search .form-input{max-width:none;width:100%}.skills-view-grid{grid-template-columns:1fr}.skills-view-item{flex-wrap:wrap;gap:var(--space-sm);padding:var(--space-md);min-height:36px}.skills-view-item-info{width:100%}.skills-view-item-toggle{padding:var(--space-sm)}.skills-view-toggle-slider{min-width:40px;min-height:22px}.skills-view-card{padding:var(--space-sm)}.skills-view-card-title{font-size:13px}.skills-view-card-description{font-size:12px}.skills-view-empty,.skills-view-error{padding:var(--space-lg)}.skills-view-loading{padding:var(--space-md)}.skills-view-item--selected{border-color:var(--todo)}.skills-view-detail{padding:var(--space-md);border-left-width:2px}.skills-view-detail-content{font-size:11px;max-height:calc(60dvh - 200px);-webkit-overflow-scrolling:touch}.skills-view-detail-close{min-height:36px;min-width:36px}.agent-tree__indent--1{padding-left:var(--space-lg)}.agent-tree__indent--2{padding-left:calc(var(--space-lg) * 2)}.agent-tree__indent--3{padding-left:calc(var(--space-lg) * 3)}.agent-tree__indent--4{padding-left:calc(var(--space-lg) * 4)}.agent-tree__toggle{min-width:calc(var(--space-lg) * 2 + var(--space-xs));min-height:calc(var(--space-lg) * 2 + var(--space-xs))}.rating-summary-card{padding:16px}.rating-average{font-size:28px}.category-breakdown{grid-template-columns:1fr}.rating-history{max-height:250px}.documents-view-header{padding:var(--space-md)}.documents-view-title-row{flex-direction:column;align-items:flex-start;gap:var(--space-sm)}.documents-view-title{font-size:16px}.documents-tab-bar{width:100%}.documents-tab{flex:1;justify-content:center;min-height:44px}.documents-hidden-toggle{width:100%;justify-content:center;min-height:44px}.documents-search-input{max-width:none;width:100%}.documents-view-content{padding:var(--space-md)}.documents-project-layout,.documents-project-layout--mobile{display:flex;flex-direction:column;min-height:0}.documents-view-sidebar{border-right:none;border-bottom:1px solid var(--border);max-height:none}.markdown-file-item{min-height:44px;padding:var(--space-sm) var(--space-md)}.documents-view-main{padding:var(--space-md)}.documents-content-viewer{width:100%}.documents-content-viewer-text{min-height:160px}.documents-group-header{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"toggle count" "link link";row-gap:var(--space-xs)}.documents-group-toggle-btn{grid-area:toggle}.documents-group-count{grid-area:count;justify-self:end}.documents-group-task-link{grid-area:link;width:100%;justify-self:stretch;min-height:44px}.documents-group-task-title{max-width:180px}.document-card-key-text{font-size:12px}}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{r as c,j as s}from"./vendor-react-K0fH_qHe.js";import{c as U,a8 as Q,a9 as V,aa as W,ab as X,ac as J,ad as x,X as T,R as j,C as q,ae as F,af as G,ag as _,ah as K,w as B,ai as Z,aj as ss,ak as P}from"./index-y194HxzU.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 es=[["path",{d:"M12 10h.01",key:"1nrarc"}],["path",{d:"M12 14h.01",key:"1etili"}],["path",{d:"M12 6h.01",key:"1vi96p"}],["path",{d:"M16 10h.01",key:"1m94wz"}],["path",{d:"M16 14h.01",key:"1gbofw"}],["path",{d:"M16 6h.01",key:"1x0f13"}],["path",{d:"M8 10h.01",key:"19clt8"}],["path",{d:"M8 14h.01",key:"6423bh"}],["path",{d:"M8 6h.01",key:"1dz90k"}],["path",{d:"M9 22v-3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3",key:"cabbwy"}],["rect",{x:"4",y:"2",width:"16",height:"20",rx:"2",key:"1uxh74"}]],ts=U("building",es);/**
|
|
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 is=[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"m19 9-5 5-4-4-3 3",key:"2osh9i"}]],as=U("chart-line",is),A=["architecture","quality","workflow","performance","reliability","security","ux","testability","documentation","dependency","features","competitive_analysis","research","trends","other"],O={quality:"Quality",performance:"Performance",architecture:"Architecture",security:"Security",reliability:"Reliability",ux:"User Experience",testability:"Testability",documentation:"Documentation",dependency:"Dependencies",workflow:"Workflow",other:"Other",features:"Features",competitive_analysis:"Competitive Analysis",research:"Research",trends:"Trends"};function ns(h){const[l,b]=c.useState(()=>A.map(t=>({category:t,label:O[t]??t,items:[],isLoading:!1,error:null}))),[k,S]=c.useState(!0),[N,v]=c.useState(null),[u,w]=c.useState(null),[M,C]=c.useState(!1),[I,p]=c.useState(null),[R,f]=c.useState(new Map),[z,y]=c.useState(new Map),m=c.useCallback(async()=>{S(!0),v(null);try{const t=await Q({status:void 0,limit:1e3},h),a=new Map;for(const i of A)a.set(i,[]);for(const i of t.insights)if(i.status!=="dismissed"){const r=a.get(i.category)??[];a.set(i.category,[...r,i])}b(A.map(i=>({category:i,label:O[i]??i,items:a.get(i)??[],isLoading:!1,error:null})));const e=await V(h);e.runs.length>0&&w(e.runs[0])}catch(t){const a=t instanceof Error?t.message:"Failed to fetch insights";v(a)}finally{S(!1)}},[h]),o=c.useCallback(async()=>{C(!0),p(null);try{const t=await W("manual",void 0,h);w(t),t.status==="completed"?await m():t.status==="failed"&&t.error&&p(t.error)}catch(t){const a=t instanceof Error?t.message:"Failed to generate insights";throw p(a),t}finally{C(!1)}},[h,m]),g=c.useCallback(async t=>{f(a=>{const e=new Map(a);return e.set(t,{running:!0,error:null}),e});try{await X(t,h),b(a=>a.map(e=>({...e,items:e.items.filter(i=>i.id!==t)}))),f(a=>{const e=new Map(a);return e.set(t,{running:!1,error:null}),e})}catch(a){const e=a instanceof Error?a.message:"Failed to dismiss insight";throw f(i=>{const r=new Map(i);return r.set(t,{running:!1,error:e}),r}),a}},[h]),d=c.useCallback(async t=>{y(a=>{const e=new Map(a);return e.set(t,{running:!0,error:null}),e});try{const a=await J(t,h);return y(e=>{const i=new Map(e);return i.set(t,{running:!1,error:null}),i}),{title:a.suggestedTitle,description:a.suggestedDescription}}catch(a){const e=a instanceof Error?a.message:"Failed to create task";throw y(i=>{const r=new Map(i);return r.set(t,{running:!1,error:e}),r}),a}},[h]),E=c.useMemo(()=>l.reduce((t,a)=>t+a.items.length,0),[l]),D=c.useMemo(()=>0,[l]);return c.useMemo(()=>{m()},[]),{sections:l,loading:k,error:N,latestRun:u,isRunInFlight:M,runError:I,refresh:m,runInsights:o,dismiss:g,createTask:d,dismissStates:R,createTaskStates:z,totalCount:E,dismissedCount:D}}const rs={architecture:ts,quality:q,workflow:P,performance:G,reliability:j,security:F,ux:_,testability:ss,documentation:Z,dependency:B,features:K,competitive_analysis:_,research:as,trends:G,other:x};function hs({projectId:h,addToast:l,onClose:b,onCreateTask:k}){const{sections:S,loading:N,error:v,latestRun:u,isRunInFlight:w,runError:M,refresh:C,runInsights:I,dismiss:p,createTask:R,dismissStates:f,createTaskStates:z,totalCount:y}=ns(h),[m,o]=c.useState(null),[g,d]=c.useState("info");c.useEffect(()=>{if(m){const e=setTimeout(()=>o(null),5e3);return()=>clearTimeout(e)}},[m]);const E=c.useCallback(async()=>{try{o("Generating insights..."),d("info"),await I(),o("Insight generation started"),d("success"),l("Insight generation started","success")}catch(e){const i=e instanceof Error?e.message:"Failed to start generation";o(i),d("error"),l(i,"error")}},[I,l]),D=c.useCallback(async(e,i)=>{try{o(`Dismissing "${i}"...`),d("info"),await p(e),o(`Dismissed "${i}"`),d("success"),l(`Insight dismissed: ${i}`,"success")}catch(r){const n=r instanceof Error?r.message:"Failed to dismiss insight";o(n),d("error"),l(n,"error")}},[p,l]),t=c.useCallback(async(e,i)=>{try{o(`Creating task from "${i}"...`),d("info");const r=await R(e);r&&k&&k(r.title,r.description),o(`Task created from "${i}"`),d("success"),l(`Task created: ${r?.title??i}`,"success")}catch(r){const n=r instanceof Error?r.message:"Failed to create task";o(n),d("error"),l(n,"error")}},[R,k,l]),a=e=>{const i=rs[e.category]??x,r=e.items.some(n=>f.get(n.id)?.running||z.get(n.id)?.running)??!1;return s.jsxs("section",{className:"insights-section","data-testid":`insights-section-${e.category}`,children:[s.jsx("div",{className:"insights-section-header",children:s.jsxs("div",{className:"insights-section-title",children:[s.jsx(i,{size:18,className:"insights-section-icon"}),s.jsx("h3",{children:e.label}),s.jsx("span",{className:"insights-section-count",children:e.items.length})]})}),s.jsx("div",{className:"insights-section-content",children:e.items.length===0?s.jsx("div",{className:"insights-empty-section","data-testid":`insights-empty-${e.category}`,children:s.jsx("p",{children:"No insights in this category"})}):s.jsx("ul",{className:"insights-list",children:e.items.map(n=>{const Y=f.get(n.id),H=z.get(n.id),L=Y?.running??!1,$=H?.running??!1;return s.jsxs("li",{className:"insight-item","data-insight-id":n.id,children:[s.jsxs("div",{className:"insight-item-header",children:[s.jsx("h4",{className:"insight-item-title",children:n.title}),s.jsxs("div",{className:"insight-item-actions",children:[s.jsx("button",{className:"btn btn-sm btn-icon",onClick:()=>void t(n.id,n.title),disabled:$||r,title:"Create task from this insight","aria-label":"Create task from this insight","data-testid":`create-task-${n.id}`,children:$?s.jsx(j,{size:14,className:"spin"}):s.jsx(B,{size:14})}),s.jsx("button",{className:"btn btn-sm btn-icon",onClick:()=>void D(n.id,n.title),disabled:L||r,title:"Dismiss this insight","aria-label":"Dismiss this insight","data-testid":`dismiss-${n.id}`,children:L?s.jsx(j,{size:14,className:"spin"}):s.jsx(T,{size:14})})]})]}),n.content&&s.jsx("p",{className:"insight-item-content",children:n.content}),s.jsxs("div",{className:"insight-item-meta",children:[s.jsx("span",{className:`insight-item-status insight-item-status--${n.status}`,children:n.status}),n.createdAt&&s.jsxs("span",{className:"insight-item-date",children:[s.jsx(P,{size:12}),new Date(n.createdAt).toLocaleDateString()]})]})]},n.id)})})})]},e.category)};return s.jsxs("div",{className:"insights-view","data-testid":"insights-view",children:[s.jsxs("div",{className:"insights-view-header",children:[s.jsxs("div",{className:"insights-view-title",children:[s.jsxs("h2",{children:[s.jsx(x,{size:20}),"Insights"]}),s.jsxs("span",{className:"insights-view-count",children:[y," total"]})]}),s.jsxs("div",{className:"insights-view-actions",children:[b&&s.jsx("button",{className:"btn btn-icon insights-view-close",onClick:b,"aria-label":"Close insights view",children:s.jsx(T,{size:16})}),s.jsxs("button",{className:"btn btn-sm",onClick:()=>void C(),disabled:N,"aria-label":"Refresh insights","data-testid":"refresh-insights",children:[s.jsx(j,{size:14,className:N?"spin":""}),"Refresh"]}),s.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>void E(),disabled:w,"aria-label":"Generate new insights","data-testid":"run-insights",children:w?s.jsxs(s.Fragment,{children:[s.jsx(j,{size:14,className:"spin"}),"Generating..."]}):s.jsxs(s.Fragment,{children:[s.jsx(x,{size:14}),"Generate Insights"]})})]})]}),s.jsx("div",{className:"insights-status-region","aria-live":"polite","data-testid":"insights-status",children:m&&s.jsxs("div",{className:`insights-status-message insights-status-message--${g}`,role:g==="error"?"alert":void 0,children:[g==="success"&&s.jsx(q,{size:16}),g==="error"&&s.jsx(F,{size:16}),g==="info"&&s.jsx(x,{size:16}),s.jsx("span",{children:m})]})}),M&&s.jsxs("div",{className:"insights-error-callout",role:"alert","data-testid":"run-error",children:[s.jsx(F,{size:16}),s.jsx("span",{children:M})]}),u&&s.jsx("div",{className:"insights-run-info","data-testid":"latest-run",children:s.jsxs("span",{className:"insights-run-status",children:["Latest run: ",u.status,u.status==="completed"&&s.jsxs(s.Fragment,{children:[" — ",u.insightsCreated," created, ",u.insightsUpdated," updated"]}),u.status==="failed"&&u.error&&s.jsxs(s.Fragment,{children:[" — ",u.error]})]})}),N?s.jsxs("div",{className:"insights-loading","data-testid":"insights-loading",children:[s.jsx(j,{size:24,className:"spin"}),s.jsx("p",{children:"Loading insights..."})]}):v?s.jsxs("div",{className:"insights-error","data-testid":"insights-error",children:[s.jsx(F,{size:24}),s.jsx("p",{children:v}),s.jsx("button",{className:"btn btn-sm",onClick:()=>void C(),children:"Retry"})]}):y===0?s.jsxs("div",{className:"insights-empty","data-testid":"insights-empty",children:[s.jsx(x,{size:48}),s.jsx("h3",{children:"No insights yet"}),s.jsx("p",{children:"Generate insights to get AI-powered recommendations for your project."}),s.jsxs("button",{className:"btn btn-primary",onClick:()=>void E(),children:[s.jsx(x,{size:14}),"Generate First Insights"]})]}):s.jsx("div",{className:"insights-sections",children:S.map(a)})]})}export{hs as InsightsView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.insights-view{display:flex;flex-direction:column;height:100%;overflow:hidden}.insights-view-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-lg);border-bottom:1px solid var(--border);background:var(--surface);flex-shrink:0}.insights-view-title{display:flex;align-items:center;gap:var(--space-sm)}.insights-view-title h2{margin:0;font-size:18px;font-weight:600;display:flex;align-items:center;gap:var(--space-sm)}.insights-view-count{font-size:13px;color:var(--text-muted);font-weight:400}.insights-view-actions{display:flex;align-items:center;gap:var(--space-sm)}.insights-view-close{color:var(--text-muted)}.insights-view-close:hover{color:var(--text)}.insights-status-region{padding:var(--space-md) var(--space-lg);flex-shrink:0}.insights-status-message{display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) var(--space-md);border-radius:var(--radius-md);font-size:13px}.insights-status-message--success{background:color-mix(in srgb,var(--color-success) 10%,transparent);color:var(--color-success)}.insights-status-message--error{background:color-mix(in srgb,var(--color-error) 10%,transparent);color:var(--color-error)}.insights-status-message--info{background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--accent)}.insights-error-callout{display:flex;align-items:center;gap:var(--space-sm);margin:0 var(--space-lg) var(--space-md);padding:var(--space-md);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-md);color:var(--color-error);font-size:13px}.insights-run-info{padding:0 var(--space-lg) var(--space-md);flex-shrink:0}.insights-run-status{font-size:12px;color:var(--text-muted)}.insights-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-md);padding:var(--space-2xl);color:var(--text-muted)}.insights-error{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-md);padding:var(--space-2xl);text-align:center}.insights-error p{color:var(--text-muted);margin:0}.insights-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-md);padding:var(--space-2xl);text-align:center;flex:1}.insights-empty h3{margin:0;font-size:18px;color:var(--text)}.insights-empty p{color:var(--text-muted);margin:0;max-width:400px}.insights-sections{display:flex;flex-direction:column;gap:var(--space-lg);padding:var(--space-lg);overflow-y:auto;flex:1}.insights-section{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden}.insights-section-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-md) var(--space-lg);background:var(--surface);border-bottom:1px solid var(--border)}.insights-section-title{display:flex;align-items:center;gap:var(--space-sm)}.insights-section-title h3{margin:0;font-size:15px;font-weight:600}.insights-section-icon{color:var(--accent)}.insights-section-count{font-size:12px;color:var(--text-muted);background:var(--surface-elevated);padding:2px 8px;border-radius:var(--radius-pill);border:1px solid var(--border)}.insights-section-content{padding:var(--space-md)}.insights-empty-section{padding:var(--space-lg);text-align:center;color:var(--text-muted);font-size:13px}.insights-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-md)}.insight-item{padding:var(--space-md);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);transition:border-color var(--transition-fast)}.insight-item:hover{border-color:var(--accent)}.insight-item-header{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-sm)}.insight-item-title{margin:0;font-size:14px;font-weight:600;color:var(--text);line-height:1.4}.insight-item-actions{display:flex;align-items:center;gap:var(--space-xs);flex-shrink:0}.insight-item-content{margin:var(--space-sm) 0 0;font-size:13px;color:var(--text-muted);line-height:1.5;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.insight-item-meta{display:flex;align-items:center;gap:var(--space-md);margin-top:var(--space-sm);font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted)}.insight-item-status{padding:2px 6px;border-radius:var(--radius-sm);text-transform:capitalize;font-weight:500}.insight-item-status--generated{background:color-mix(in srgb,var(--accent) 15%,transparent);color:var(--accent)}.insight-item-status--confirmed{background:color-mix(in srgb,var(--color-success) 15%,transparent);color:var(--color-success)}.insight-item-status--stale{background:color-mix(in srgb,var(--warning) 15%,transparent);color:var(--warning)}.insight-item-status--dismissed{background:color-mix(in srgb,var(--text-dim) 15%,transparent);color:var(--text-dim)}.insight-item-date{display:flex;align-items:center;gap:4px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.spin{animation:spin 1s linear infinite}@media(max-width:768px){.insights-view-header{flex-wrap:wrap;gap:var(--space-md);padding:var(--space-md)}.insights-view-title h2{font-size:16px}.insights-view-actions{width:100%;justify-content:flex-end;flex-wrap:wrap}.insights-sections{padding:var(--space-md);gap:var(--space-md)}.insights-section-header{padding:var(--space-sm) var(--space-md)}.insights-section-content,.insight-item{padding:var(--space-sm)}.insight-item-title{word-break:break-word}.insight-item-header{flex-direction:column;gap:var(--space-sm)}.insight-item-meta{flex-wrap:wrap;gap:var(--space-sm)}.insight-item-actions{align-self:flex-end}.insight-item-actions .btn-icon{min-width:36px;min-height:36px}.post-onboarding-recommendations{flex-direction:column;align-items:stretch;gap:var(--space-sm);padding:var(--space-md)}.post-onboarding-recommendations__main{width:100%}.post-onboarding-recommendations__item{align-items:flex-start;flex-wrap:wrap}.post-onboarding-recommendations .btn.btn-sm{margin-left:auto;min-height:calc(var(--space-lg) * 2 + var(--space-xs))}.post-onboarding-recommendations__dismiss{align-self:flex-end;min-width:calc(var(--space-lg) * 2 + var(--space-xs));min-height:calc(var(--space-lg) * 2 + var(--space-xs))}.insights-view-actions .btn{min-height:36px}.insights-view-close{min-height:36px;min-width:36px}.insights-view-count{font-size:12px}.chat-session-delete-btn{opacity:1}}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{b9 as Ae,ba as je,bb as Se,bc as Fe,o as ze,bd as De,be as Ie,bf as Le,bg as Ne,bh as Ce,bi as Re,bj as Te,bk as Ee,bl as We,n as qe,bm as Pe,L as w,bn as ke}from"./index-y194HxzU.js";import"./vendor-xterm-DzcZoU0P.js";const U=".fusion/memory/MEMORY.md",_e=5e4,Oe="0 3 * * *",Ue="0 4 * * *";function oe(i){return{memoryEnabled:i.memoryEnabled!==!1,memoryAutoSummarizeEnabled:i.memoryAutoSummarizeEnabled??!1,memoryAutoSummarizeThresholdChars:i.memoryAutoSummarizeThresholdChars??_e,memoryAutoSummarizeSchedule:i.memoryAutoSummarizeSchedule??Oe,memoryDreamsEnabled:i.memoryDreamsEnabled??!1,memoryDreamsSchedule:i.memoryDreamsSchedule??Ue}}function Me(i,t){return i.some(m=>m.path===t)?t:i.find(m=>m.path===U)?.path??i[0]?.path??U}function Qe(i={}){const{projectId:t}=i,[m,x]=a.useState(""),[A,N]=a.useState(!0),[j,S]=a.useState(!1),[h,y]=a.useState(!1),[n,g]=a.useState(null),[Q,J]=a.useState(!0),[X,F]=a.useState(!1),[b,R]=a.useState(()=>oe({})),[C,ee]=a.useState(!0),[ce,B]=a.useState(!1),[c,f]=a.useState([]),[se,z]=a.useState(!0),[o,E]=a.useState(U),[T,u]=a.useState(""),[d,te]=a.useState(!1),[H,p]=a.useState(!1),[ae,$]=a.useState(!1),[ne,Y]=a.useState(!1),[G,W]=a.useState(null),[k,q]=a.useState(!0),[de,D]=a.useState(!1),[ue,V]=a.useState(!1),[re,Z]=a.useState(null),{status:K,loading:v,refresh:ie}=Ae({projectId:t}),I=a.useCallback(s=>{u(s),p(!0)},[]),P=a.useCallback(async s=>{te(!0);try{const{content:r}=await je(s,t);E(s),u(r),p(!1)}finally{te(!1)}},[t]),M=a.useCallback(async()=>{z(!0);try{const{files:s}=await Se(t);if(f(s),s.length===0){E(U),u(""),p(!1);return}const r=Me(s,o);r!==o&&await P(r)}finally{z(!1)}},[t,o,P]);a.useEffect(()=>{let s=!1;async function r(){try{const l=await We(t);s||(x(l.content),N(!1))}catch{s||(x(""),N(!1))}}return r(),()=>{s=!0}},[t]),a.useEffect(()=>{let s=!1;async function r(){try{const l=await Ce(t);s||(g(l.content),F(l.exists),J(!1))}catch{s||(g(null),F(!1),J(!1))}}return r(),()=>{s=!0}},[t]),a.useEffect(()=>{let s=!1;async function r(){ee(!0);try{const l=await qe(t);s||R(oe(l))}catch{s||R(oe({}))}finally{s||ee(!1)}}return r(),()=>{s=!0}},[t]),a.useEffect(()=>{let s=!1;async function r(){z(!0);try{const{files:l}=await Se(t);if(s)return;if(f(l),l.length===0){E(U),u(""),p(!1);return}const me=Me(l,o),{content:we}=await je(me,t);if(s)return;E(me),u(we),p(!1)}catch{s||(f([]),E(U),u(""),p(!1))}finally{s||z(!1)}}return r(),()=>{s=!0}},[t,o]),a.useEffect(()=>{let s=!1;async function r(){try{const l=await Ne(t);s||(W(l),q(!1))}catch{s||(W(null),q(!1))}}return r(),()=>{s=!0}},[t]),a.useEffect(()=>{let s=!1;async function r(){try{const l=await Pe(t);s||Z(l)}catch{s||Z(null)}}return r(),()=>{s=!0}},[t]);const le=a.useCallback(s=>{x(s),S(!0)},[]),he=a.useCallback(async()=>{if(j){y(!0);try{await Fe(m,t),S(!1)}finally{y(!1)}}},[m,j,t]),ye=a.useCallback(async s=>{B(!0);try{const r=await ze(s,t);R(oe(r))}finally{B(!1)}},[t]),ge=a.useCallback(async s=>{await P(s)},[P]),pe=a.useCallback(async()=>{if(H){$(!0);try{await De(o,T,t),p(!1),await M()}finally{$(!1)}}},[T,H,o,t,M]),xe=a.useCallback(async()=>{V(!0);try{const s=await Ie(t);return await ie(),s}finally{V(!1)}},[t,ie]),be=a.useCallback(async s=>Le(s,t),[t]),_=a.useCallback(async()=>{try{const s=await Ne(t);W(s)}catch{W(null)}},[t]),L=a.useCallback(async()=>{try{const s=await Ce(t);g(s.content),F(s.exists)}catch{g(null),F(!1)}},[t]),fe=a.useCallback(async s=>{await Re(s,t),await L()},[t,L]),ve=a.useCallback(async()=>{Y(!0);try{const s=await Te(t);return await Promise.all([L(),_()]),{success:s.success,summary:s.summary}}finally{Y(!1)}},[t,L,_]),O=a.useCallback(async s=>{D(!0);try{const r=s?await Ee(s,t):await Ee(t);if(s){const l=r.path??s;E(l),u(r.content),p(!1),await M();return}x(r.content),S(!0)}finally{D(!1)}},[t,M]);return{workingMemory:m,workingMemoryLoading:A,workingMemoryDirty:j,setWorkingMemory:le,saveWorkingMemory:he,savingWorkingMemory:h,insightsContent:n,insightsLoading:Q,insightsExists:X,refreshInsights:L,saveInsights:fe,memorySettings:b,settingsLoading:C,savingMemorySettings:ce,saveMemorySettings:ye,memoryFiles:c,memoryFilesLoading:se,selectedFilePath:o,selectedFileContent:T,selectedFileLoading:d,selectedFileDirty:H,setSelectedFileContent:I,selectFile:ge,saveSelectedFile:pe,savingSelectedFile:ae,reloadMemoryFiles:M,backendStatus:K,backendLoading:v,extractInsights:ve,extracting:ne,auditReport:G,auditLoading:k,refreshAudit:_,compactMemory:O,compacting:de,installQmdAction:xe,installingQmd:ue,testRetrieval:be,stats:re}}const Be={Patterns:"pattern",Principles:"principle",Conventions:"convention",Pitfalls:"pitfall",Context:"context"},He={"long-term":"Long-term",daily:"Daily",dreams:"Dreams"},$e={"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."};function Ye(i){if(!i)return[];const t=[],m=i.split(/(?=^## )/m);for(const x of m){const A=x.trim();if(!A)continue;const N=A.match(/^##\s+(.+?)(\n|$)/);if(N){const j=N[1].trim(),S=Be[j]??j.toLowerCase(),h=A.slice(N[0].length).trim(),y=h.split(`
|
|
2
|
+
`).map(n=>n.replace(/^-\s+/,"").trim()).filter(n=>n.length>0&&(n.startsWith("- ")||n.startsWith("* ")));(y.length>0||h.length>0)&&t.push({name:j,key:S,items:y.length>0?y:h.length>0?[h]:[],expanded:!0})}}return t}function Ge(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 Ve(i){return i.reduce((t,m)=>t+m.items.length,0)}function Ze(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 Ke(i){switch(i){case"healthy":return"Healthy";case"warning":return"Warning";case"issues":return"Issues Found"}}function ss({projectId:i,addToast:t}){const[m,x]=a.useState("working"),[A,N]=a.useState(new Set),[j,S]=a.useState(!1),[h,y]=a.useState(null),[n,g]=a.useState({memoryEnabled:!0,memoryAutoSummarizeEnabled:!1,memoryAutoSummarizeThresholdChars:5e4,memoryAutoSummarizeSchedule:"0 3 * * *",memoryDreamsEnabled:!1,memoryDreamsSchedule:"0 4 * * *"}),[Q,J]=a.useState(""),[X,F]=a.useState(!1),[b,R]=a.useState(null),{insightsContent:C,insightsLoading:ee,insightsExists:ce,saveInsights:B,memorySettings:c,settingsLoading:f,saveMemorySettings:se,savingMemorySettings:z,backendStatus:o,backendLoading:E,extractInsights:T,extracting:u,auditReport:d,auditLoading:te,refreshAudit:H,compactMemory:p,compacting:ae,installQmdAction:$,installingQmd:ne,testRetrieval:Y,memoryFiles:G,memoryFilesLoading:W,selectedFilePath:k,selectedFileContent:q,selectedFileLoading:de,selectedFileDirty:D,setSelectedFileContent:ue,selectFile:V,saveSelectedFile:re,savingSelectedFile:Z}=Qe({projectId:i});a.useEffect(()=>{g(c)},[c]);const K=a.useMemo(()=>n.memoryEnabled!==c.memoryEnabled||n.memoryAutoSummarizeEnabled!==c.memoryAutoSummarizeEnabled||n.memoryAutoSummarizeThresholdChars!==c.memoryAutoSummarizeThresholdChars||n.memoryAutoSummarizeSchedule!==c.memoryAutoSummarizeSchedule||n.memoryDreamsEnabled!==c.memoryDreamsEnabled||n.memoryDreamsSchedule!==c.memoryDreamsSchedule,[n,c]),v=a.useMemo(()=>G.find(s=>s.path===k),[G,k]),ie=v?$e[v.layer]:"Edits the selected memory file.",I=a.useMemo(()=>Ye(C),[C]),P=a.useMemo(()=>Ve(I),[I]),M=a.useMemo(()=>Ge(C),[C]),le=a.useCallback(s=>{N(r=>{const l=new Set(r);return l.has(s)?l.delete(s):l.add(s),l})},[]),he=a.useCallback(async s=>{try{await V(s)}catch{t("Failed to load memory file","error")}},[V,t]),ye=a.useCallback(async()=>{try{await re(),t("Memory saved","success")}catch{t("Failed to save memory","error")}},[re,t]),ge=a.useCallback(async()=>{if(!K)return;const s={};n.memoryEnabled!==c.memoryEnabled&&(s.memoryEnabled=n.memoryEnabled),n.memoryAutoSummarizeEnabled!==c.memoryAutoSummarizeEnabled&&(s.memoryAutoSummarizeEnabled=n.memoryAutoSummarizeEnabled),n.memoryAutoSummarizeThresholdChars!==c.memoryAutoSummarizeThresholdChars&&(s.memoryAutoSummarizeThresholdChars=n.memoryAutoSummarizeThresholdChars),n.memoryAutoSummarizeSchedule!==c.memoryAutoSummarizeSchedule&&(s.memoryAutoSummarizeSchedule=n.memoryAutoSummarizeSchedule),n.memoryDreamsEnabled!==c.memoryDreamsEnabled&&(s.memoryDreamsEnabled=n.memoryDreamsEnabled),n.memoryDreamsSchedule!==c.memoryDreamsSchedule&&(s.memoryDreamsSchedule=n.memoryDreamsSchedule);try{await se(s),t("Memory settings saved","success")}catch{t("Failed to save memory settings","error")}},[K,n,c,se,t]),pe=a.useCallback(async()=>{try{const s=await $();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")}},[$,t]),xe=a.useCallback(async()=>{F(!0),R(null);try{const s=await Y(Q);R(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{F(!1)}},[Q,Y,t]),be=a.useCallback(async()=>{try{await p(k),t("Memory file compacted","success")}catch{t("Failed to compact memory","error")}},[p,k,t]),_=a.useCallback(async()=>{try{const s=await T();t(s.summary,"success")}catch(s){t(s instanceof Error?s.message:"Failed to extract insights","error")}},[T,t]),L=a.useCallback(async()=>{if(h!==null)try{await B(h),S(!1),y(null),t("Insights saved","success")}catch{t("Failed to save insights","error")}},[h,B,t]),fe=a.useCallback(()=>{y(C??""),S(!0)},[C]),ve=a.useCallback(()=>{S(!1),y(null)},[]),O=o?.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:()=>x("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:()=>x("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:()=>x("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:[!O&&e.jsx("div",{className:"memory-readonly-banner",children:"This memory backend is read-only. Changes cannot be saved."}),W||de?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:k,onChange:s=>{he(s.target.value)},disabled:D,children:G.map(s=>e.jsxs("option",{value:s.path,children:[s.label," - ",s.path]},s.path))}),e.jsx("small",{children:D?"Save or discard the current edits before switching files.":"Choose any project memory file to view or edit."})]}),v&&e.jsxs("div",{className:"memory-file-summary",children:[e.jsx("span",{children:He[v.layer]}),e.jsx("strong",{children:v.path}),e.jsxs("small",{children:[v.size.toLocaleString()," bytes · updated ",new Date(v.updatedAt).toLocaleString()]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:v?.label||"Memory Editor"}),e.jsx("small",{children:ie}),e.jsx("div",{className:"memory-editor-container",children:e.jsx(ke,{content:q,onChange:ue,readOnly:!O,filePath:k})})]})]}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsxs("span",{className:"memory-char-count",children:[q.length," characters"]}),e.jsx("div",{style:{flex:1}}),O&&q.length>0&&e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:be,disabled:ae||D,children:ae?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Compacting…"]}):"Compact Selected File"}),D&&O&&e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:ye,disabled:Z,children:Z?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:n.memoryDreamsEnabled,onChange:s=>{g(r=>({...r,memoryDreamsEnabled:s.target.checked}))},disabled:!n.memoryEnabled||f}),"Process dreams from daily memory"]}),e.jsx("small",{children:"Turns daily notes into DREAMS.md and promotes reusable lessons into MEMORY.md."})]}),n.memoryEnabled&&n.memoryDreamsEnabled&&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:n.memoryDreamsSchedule,onChange:s=>{g(r=>({...r,memoryDreamsSchedule:s.target.value}))},placeholder:"0 4 * * *",disabled:f}),e.jsx("small",{children:"Cron expression for dream processing."})]})]}),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:n.memoryAutoSummarizeEnabled,onChange:s=>{g(r=>({...r,memoryAutoSummarizeEnabled:s.target.checked}))},disabled:!n.memoryEnabled||f}),"Auto-Summarize Memory"]}),e.jsx("small",{children:"Automatically compact memory when it exceeds the threshold on a schedule"})]}),n.memoryEnabled&&n.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:n.memoryAutoSummarizeThresholdChars,onChange:s=>{g(r=>({...r,memoryAutoSummarizeThresholdChars:parseInt(s.target.value,10)||5e4}))},min:1e3,disabled:f}),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:n.memoryAutoSummarizeSchedule,onChange:s=>{g(r=>({...r,memoryAutoSummarizeSchedule:s.target.value}))},placeholder:"0 3 * * *",disabled:f}),e.jsx("small",{children:"Cron expression for auto-summarize schedule (default: daily at 3 AM)"})]})]})]}),!n.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:ge,disabled:z||f,children:z?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…"})]}):j?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"memory-editor-container",children:e.jsx(ke,{content:h??"",onChange:y,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:ve,children:"Cancel"}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:L,children:"Save Insights"})]})]}):!ce||I.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",onClick:_,disabled:u,style:{marginTop:"var(--space-md)"},children:u?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:P}),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:I.length}),e.jsx("div",{className:"memory-stat-label",children:"Categories"})]}),M&&e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value",style:{fontSize:"16px"},children:M}),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:_,disabled:u,children:u?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:fe,children:"Edit Raw"})]}),e.jsx("div",{className:"memory-categories-list",children:I.map(s=>{const r=!A.has(s.key);return e.jsxs("div",{className:"memory-category-section",children:[e.jsxs("div",{className:"memory-category-header",onClick:()=>le(s.key),role:"button",tabIndex:0,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),le(s.key))},children:[e.jsx("h4",{children:s.name}),e.jsx("span",{className:"memory-category-count",children:s.items.length})]}),r&&e.jsx("div",{className:"memory-category-items",children:s.items.map((l,me)=>e.jsx("div",{className:"memory-insight-item",children:l.replace(/^-\s+/,"").replace(/^\*\s+/,"")},me))})]},s.key)})})]})}),m==="engines"&&e.jsx("div",{className:"memory-engines-tab",children:E||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"}),o?.qmdAvailable?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."})]}):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:o?.qmdInstallCommand||"bun install -g @tobilu/qmd"})]}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:pe,disabled:ne,children:ne?"Installing…":"Install qmd"})]}),e.jsxs("div",{style:{display:"flex",gap:"var(--space-xs)",marginTop:"var(--space-sm)",flexWrap:"wrap"},children:[o?.capabilities?.readable&&e.jsx("span",{className:"memory-capability-badge",children:"Readable"}),o?.capabilities?.writable&&e.jsx("span",{className:"memory-capability-badge",children:"Writable"}),o?.capabilities?.supportsAtomicWrite&&e.jsx("span",{className:"memory-capability-badge",children:"Atomic Writes"}),o?.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:Q,onChange:s=>J(s.target.value),placeholder:"Search memory with qmd"}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:xe,disabled:X,children:X?"Testing…":"Test Retrieval"})]}),e.jsx("small",{className:"settings-muted",children:"Runs the same qmd-backed memory_search path agents use."}),b&&e.jsxs("div",{className:"memory-test-result",children:[e.jsxs("strong",{children:[b.results.length," result",b.results.length===1?"":"s"," ",'for "',b.query,'"']}),e.jsxs("small",{children:["qmd ",b.qmdAvailable?"available":"missing"," · ",b.usedFallback?"local fallback used":"qmd path used"]}),b.results.length>0?e.jsx("ul",{children:b.results.map((s,r)=>e.jsxs("li",{children:[e.jsxs("span",{children:[s.path,":",s.lineStart]}),e.jsx("p",{children:s.snippet})]},`${s.path}-${s.lineStart}-${r}`))}):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",{style:{fontWeight:500},children:Ze(o?.currentBackend??"unknown")})}),e.jsxs("div",{style:{display:"flex",gap:"var(--space-xs)",marginTop:"var(--space-sm)",flexWrap:"wrap"},children:[o?.capabilities?.readable&&e.jsx("span",{className:"memory-capability-badge",children:"Readable"}),o?.capabilities?.writable&&e.jsx("span",{className:"memory-capability-badge",children:"Writable"}),o?.capabilities?.supportsAtomicWrite&&e.jsx("span",{className:"memory-capability-badge",children:"Atomic Writes"}),o?.capabilities?.persistent&&e.jsx("span",{className:"memory-capability-badge",children:"Persistent"})]})]}),d&&e.jsxs("div",{className:"memory-engine-card",children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"var(--space-md)"},children:[e.jsx("h3",{children:"Health Status"}),e.jsx("span",{className:`memory-health-badge memory-health-badge--${d.health}`,children:Ke(d.health)})]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"var(--space-md)"},children:[e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:"12px",color:"var(--text-muted)",textTransform:"uppercase",marginBottom:"var(--space-xs)"},children:"Working Memory"}),e.jsxs("div",{style:{fontWeight:500},children:[d.workingMemory.size," chars"]}),e.jsxs("div",{style:{fontSize:"13px",color:"var(--text-muted)"},children:[d.workingMemory.sectionCount," sections"]})]}),e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:"12px",color:"var(--text-muted)",textTransform:"uppercase",marginBottom:"var(--space-xs)"},children:"Insights Memory"}),e.jsxs("div",{style:{fontWeight:500},children:[d.insightsMemory.size," chars"]}),e.jsxs("div",{style:{fontSize:"13px",color:"var(--text-muted)"},children:[d.insightsMemory.insightCount," insights"]})]})]}),e.jsxs("div",{style:{marginTop:"var(--space-md)",paddingTop:"var(--space-md)",borderTop:"1px solid var(--border)"},children:[e.jsx("div",{style:{fontSize:"12px",color:"var(--text-muted)",textTransform:"uppercase",marginBottom:"var(--space-xs)"},children:"Last Extraction"}),e.jsx("div",{style:{fontWeight:500},children:d.extraction.success?e.jsx("span",{style:{color:"var(--color-success)"},children:"Success"}):e.jsx("span",{style:{color:"var(--color-error)"},children:"Failed"})}),e.jsx("div",{style:{fontSize:"13px",color:"var(--text-muted)"},children:d.extraction.summary||`${d.extraction.insightCount} insights extracted`})]}),e.jsxs("div",{style:{marginTop:"var(--space-md)",paddingTop:"var(--space-md)",borderTop:"1px solid var(--border)"},children:[e.jsx("div",{style:{fontSize:"12px",color:"var(--text-muted)",textTransform:"uppercase",marginBottom:"var(--space-xs)"},children:"Pruning"}),e.jsx("div",{style:{fontWeight:500},children:d.pruning.applied?e.jsx("span",{style:{color:"var(--color-warning)"},children:"Applied"}):e.jsx("span",{style:{color:"var(--text-muted)"},children:"Not needed"})}),d.pruning.applied&&e.jsx("div",{style:{fontSize:"13px",color:"var(--text-muted)"},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",{style:{flex:1},children:[e.jsx("div",{style:{fontWeight:500},children:s.name}),e.jsx("div",{style:{fontSize:"13px",color:"var(--text-muted)"},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",{style:{marginTop:"var(--space-lg)",fontSize:"13px",color:"var(--text-muted)"},children:["Note: Change backend type in"," ",e.jsx("span",{style:{cursor:"pointer",textDecoration:"underline"},onClick:()=>{t("Open Settings → Memory to change backend type","info")},children:"Settings → Memory"})]})]})})]})]})}export{ss as MemoryView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.memory-view{display:flex;flex-direction:column;height:100%;padding:var(--space-lg);overflow:hidden}.memory-view-header{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start;margin-bottom:var(--space-lg)}.memory-view-header h2{font-size:18px;color:var(--text);margin:0}.memory-view-description{color:var(--text-muted);font-size:13px;margin:var(--space-xs) 0 0 0}.memory-view-tabs{display:flex;flex-direction:row;gap:var(--space-xs);border-bottom:1px solid var(--border);margin-bottom:var(--space-lg)}.memory-view-tab{padding:var(--space-sm) var(--space-md);border-radius:var(--radius-sm) var(--radius-sm) 0 0;color:var(--text-muted);background:transparent;border:none;cursor:pointer;font-size:13px;transition:background var(--transition-fast),color var(--transition-fast)}.memory-view-tab:hover{background:var(--card-hover);color:var(--text)}.memory-view-tab:focus-visible{outline:none;box-shadow:var(--focus-ring)}.memory-view-tab--active{color:var(--text);border-bottom:2px solid var(--todo);font-weight:500}.memory-view-content{flex:1;overflow-y:auto}.memory-editor-container{border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden;display:flex;flex-direction:column;height:calc(100vh - var(--header-height) - 180px)}.memory-category-section{margin-bottom:var(--space-lg)}.memory-category-header{display:flex;flex-direction:row;justify-content:space-between;align-items:center;cursor:pointer;padding:var(--space-sm) 0;border-bottom:1px solid var(--border);transition:opacity var(--transition-fast)}.memory-category-header:hover{opacity:.8}.memory-category-header h4{font-size:14px;font-weight:500;margin:0;color:var(--text)}.memory-category-count{font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted);background:color-mix(in srgb,var(--text-muted) 15%,transparent);padding:2px 8px;border-radius:var(--radius-pill)}.memory-category-items{padding-top:var(--space-sm)}.memory-insight-item{padding:var(--space-xs) var(--space-sm);margin-bottom:var(--space-xs);border-left:3px solid var(--border);font-size:13px;color:var(--text);line-height:1.5}.memory-engine-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--space-xl);margin-bottom:var(--space-lg)}.memory-engine-card h3{font-size:14px;font-weight:500;margin:0 0 var(--space-md) 0;color:var(--text)}.memory-engine-status{display:flex;flex-direction:row;align-items:center;gap:var(--space-sm)}.memory-health-badge{display:inline-block;padding:2px 10px;border-radius:var(--radius-pill);font-size:12px}.memory-health-badge--healthy{background:color-mix(in srgb,var(--color-success) 15%,transparent);color:var(--color-success)}.memory-health-badge--warning{background:color-mix(in srgb,var(--color-warning) 15%,transparent);color:var(--color-warning)}.memory-health-badge--issues{background:color-mix(in srgb,var(--color-error) 15%,transparent);color:var(--color-error)}.memory-action-bar{display:flex;flex-direction:row;gap:var(--space-sm);margin-top:var(--space-md);align-items:center}.memory-empty-state{color:var(--text-muted);padding:var(--space-2xl);text-align:center;display:flex;flex-direction:column;align-items:center;gap:var(--space-sm)}.memory-stats-row{display:flex;flex-direction:row;gap:var(--space-lg);margin-bottom:var(--space-lg)}.memory-stat-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-md) var(--space-lg);flex:1}.memory-stat-value{font-size:24px;font-weight:600;color:var(--text);margin-bottom:var(--space-xs)}.memory-stat-label{font-size:12px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px}.memory-audit-check{display:flex;flex-direction:row;padding:var(--space-sm) 0;border-bottom:1px solid var(--border);gap:var(--space-sm)}.memory-audit-check:last-child{border-bottom:none}.memory-audit-check-passed{color:var(--color-success);font-weight:600}.memory-audit-check-failed{color:var(--color-error);font-weight:600}.memory-capability-badge{font-size:11px;padding:2px 8px;border-radius:var(--radius-pill);background:color-mix(in srgb,var(--todo) 15%,transparent);color:var(--text-muted)}.memory-readonly-banner{background:color-mix(in srgb,var(--color-warning) 10%,transparent);border:1px solid color-mix(in srgb,var(--color-warning) 30%,transparent);border-radius:var(--radius-md);padding:var(--space-md);color:var(--color-warning);font-size:13px;margin-bottom:var(--space-md)}.memory-char-count{font-size:12px;color:var(--text-muted)}.memory-categories-list{margin-top:var(--space-lg)}.memory-config-section{margin-top:var(--space-lg);padding-top:var(--space-lg);border-top:1px solid var(--border);display:flex;flex-direction:column;gap:var(--space-md)}.memory-settings-group{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface);padding:var(--space-sm) 0}.memory-qmd-card{border-style:solid}.memory-retrieval-card{display:flex;flex-direction:column;gap:var(--space-sm)}.memory-retrieval-input-row{display:flex;align-items:center;gap:var(--space-sm)}.memory-retrieval-input-row .input{flex:1}.memory-retrieval-card .memory-test-result{margin-top:var(--space-sm)}@media(max-width:768px){.memory-view{padding:var(--space-md)}.memory-view-header{flex-direction:column;gap:var(--space-sm)}.memory-editor-container{height:calc(100vh - var(--header-height) - var(--mobile-nav-height) - 200px)}.memory-stats-row{flex-wrap:wrap}.memory-stat-card{min-width:calc(50% - var(--space-sm))}.memory-view-tab{min-height:36px;padding:var(--space-sm)}.memory-engine-card{padding:var(--space-md)}.memory-retrieval-input-row{flex-direction:column;align-items:stretch}.memory-settings-group{padding:var(--space-xs) 0}.memory-config-section{margin-top:var(--space-md);padding-top:var(--space-md)}}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import{r as n,j as e}from"./vendor-react-K0fH_qHe.js";import{c as Y,al as xe,am as ge,an as pe,ao as je,ap as Z,aq as Q,A as T,ar as _e,I as Ne,K as be,as as ee,at as ve,au as Ce,X as B,av as ke,aw as Se,R as J,w as G,G as we}from"./index-y194HxzU.js";import{U as se}from"./upload-DHBQat92.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 Ae=[["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"}]],Me=Y("wifi-off",Ae);/**
|
|
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 Ee=[["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"}]],Re=Y("wifi",Ee);function U(t){const{lastSyncAt:l,remoteReachable:s,diff:r}=t,f=r.global.length+r.project.length;return l===null?{syncState:"never-synced",lastSyncAt:l,diffCount:0}:s?f>0?{syncState:"diff",lastSyncAt:l,diffCount:f}:{syncState:"synced",lastSyncAt:l,diffCount:0}:{syncState:"error",lastSyncAt:l,diffCount:f}}function te(t){if(t===null)return"Never synced";const l=new Date(t);if(Number.isNaN(l.getTime()))return"Never synced";const r=Date.now()-l.getTime(),f=Math.floor(r/1e3),m=Math.floor(f/60),c=Math.floor(m/60),u=Math.floor(c/24);return m<1?"Synced just now":m<60?`Synced ${m}m ago`:c<24?`Synced ${c}h ago`:`Synced ${u}d ago`}function ae(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 Pe=3e4;function $e(){const[t,l]=n.useState({}),[s,r]=n.useState(!1),[f,m]=n.useState({}),[c,u]=n.useState(null),o=n.useRef(new Set),y=n.useRef(!1),g=n.useRef(null),j=n.useRef(null),C=n.useCallback(async(h,d)=>{try{const p=await xe(h);l(z=>({...z,[h]:p})),u(null)}catch(p){console.error(`Failed to fetch sync status for node ${h}:`,p),u(p instanceof Error?p.message:"Failed to fetch sync status")}},[]),_=n.useCallback(async()=>{const h=Array.from(o.current);if(h.length===0)return;g.current&&g.current.abort(),g.current=new AbortController;const d=!y.current;d&&r(!0),u(null);try{const p=await Promise.allSettled(h.map(L=>C(L,d)));y.current=!0,p.filter(L=>L.status==="rejected").length>0&&u("Some sync status requests failed")}catch(p){if(p instanceof Error&&p.name==="AbortError")return;u(p instanceof Error?p.message:"Failed to fetch sync status"),y.current=!0}finally{r(!1)}},[C]),S=n.useCallback(()=>{j.current&&clearInterval(j.current),j.current=setInterval(()=>{_()},Pe)},[_]),A=n.useCallback(()=>{j.current&&(clearInterval(j.current),j.current=null)},[]);n.useEffect(()=>(_(),S(),()=>{A(),g.current&&g.current.abort()}),[_,S,A]);const a=n.useCallback(h=>{o.current.has(h)||(o.current.add(h),C(h,!y.current))},[C]),i=n.useCallback(h=>{o.current.delete(h),l(d=>{const p={...d};return delete p[h],p}),o.current.size===0&&A()},[A]),x=n.useCallback(async h=>{m(d=>({...d,[h]:!0})),u(null);try{const d=await ge(h);return C(h,!1),!d.success&&d.error&&u(d.error),d}catch(d){const p=d instanceof Error?d.message:"Push settings failed";throw u(p),d}finally{m(d=>{const p={...d};return delete p[h],p})}},[C]),b=n.useCallback(async h=>{m(d=>({...d,[h]:!0})),u(null);try{const d=await pe(h);return C(h,!1),!d.success&&d.error&&u(d.error),d}catch(d){const p=d instanceof Error?d.message:"Pull settings failed";throw u(p),d}finally{m(d=>{const p={...d};return delete p[h],p})}},[C]),w=n.useCallback(async h=>{m(d=>({...d,[h]:!0})),u(null);try{return await je(h)}catch(d){const p=d instanceof Error?d.message:"Auth sync failed";throw u(p),d}finally{m(d=>{const p={...d};return delete p[h],p})}},[]),$=n.useCallback(h=>t[h]?.authMatch,[t]),v=n.useCallback(h=>t[h]?.authDiff,[t]);return{syncStatusMap:t,loading:s,actionLoading:f,error:c,refresh:_,trackNode:a,untrackNode:i,pushSettings:x,pullSettings:b,syncAuth:w,getAuthSyncState:$,getAuthProviders:v}}function Le(t,l){return l.type==="remote"?t.nodeId===l.id:t.nodeId===l.id||t.nodeId===void 0||t.nodeId===null}function ne(t,l){return t.filter(s=>Le(s,l))}function H(t,l){return ne(t,l).length}const ze={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"}},De={match:"var(--color-success)",differs:"var(--color-warning)","not-synced":"var(--text-muted)"};function Oe(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 s=Object.entries(l).filter(([,r])=>r==="differs").map(([r])=>r);if(s.length>0)return`Auth credentials differ: ${s.join(", ")}`}return"Auth credentials differ"}function Fe(t,l=42){return t.length<=l?t:`${t.slice(0,l-3)}...`}function Ie(t,l){const s=t.node,r=l.node;if(s.id!==r.id||s.name!==r.name||s.type!==r.type||s.url!==r.url||s.status!==r.status||s.maxConcurrent!==r.maxConcurrent||s.updatedAt!==r.updatedAt||t.isLoading!==l.isLoading)return!1;const f=t.syncStatus,m=l.syncStatus;if(!(!f&&!m)){if(!f||!m)return!1;if(f.syncState!==m.syncState||f.lastSyncAt!==m.lastSyncAt||f.diffCount!==m.diffCount)return!1}if(t.authSyncState!==l.authSyncState)return!1;const c=t.authSyncProviders,u=l.authSyncProviders;if(c!==u){if(!c||!u)return!1;{const g=Object.keys(c),j=Object.keys(u);if(g.length!==j.length||g.some(C=>c[C]!==u[C]))return!1}}const o=H(t.projects,s),y=H(l.projects,r);return o===y}function Ke({node:t,projects:l,onHealthCheck:s,onEdit:r,onRemove:f,isLoading:m=!1,syncStatus:c,authSyncState:u,authSyncProviders:o}){const[y,g]=n.useState(!1),j=ze[t.status],C=n.useMemo(()=>H(l,t),[l,t]),_=n.useCallback(()=>{r(t)},[r,t]),S=n.useCallback(x=>{x.stopPropagation(),s(t.id)},[s,t.id]),A=n.useCallback(x=>{x.stopPropagation(),r(t)},[r,t]),a=n.useCallback(x=>{if(x.stopPropagation(),!y){g(!0);return}f(t.id),g(!1)},[y,f,t.id]),i=n.useCallback(x=>{(x.key==="Enter"||x.key===" ")&&(x.preventDefault(),r(t))},[r,t]);return e.jsxs("article",{className:`node-card ${m?"node-card--loading":""}`,"data-node-id":t.id,role:"button",tabIndex:0,onClick:_,onKeyDown:i,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(Z,{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 ${j.className}`,style:{color:j.color},"data-status":t.status,children:[e.jsx("span",{className:"node-card__status-indicator",style:{backgroundColor:j.color},"aria-hidden":!0}),j.label]}),t.type==="remote"&&u&&e.jsx("span",{className:`node-card__auth-indicator node-card__auth-indicator--${u}`,title:Oe(u,o),"aria-label":`Auth sync: ${u==="match"?"credentials match":u==="differs"?"credentials differ":"not synced"}`,style:{color:De[u]},children:e.jsx(Q,{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:Fe(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"&&c&&e.jsxs("div",{className:"node-card__sync","data-sync-state":c.syncState,"data-testid":"node-card-sync",children:[e.jsx("span",{className:"node-card__sync-dot",style:{backgroundColor:ae(c.syncState)},"aria-hidden":!0}),e.jsx("span",{className:"node-card__sync-time",children:te(c.lastSyncAt)})]})]}),e.jsxs("footer",{className:"node-card__actions",children:[e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:S,disabled:m,"aria-label":"Run node health check",title:"Health Check",children:[e.jsx(T,{size:14}),e.jsx("span",{children:"Health"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:A,disabled:m,"aria-label":"Edit node",title:"Edit",children:[e.jsx(_e,{size:14}),e.jsx("span",{children:"Edit"})]}),e.jsxs("button",{className:`btn btn-sm node-card__action node-card__action--remove ${y?"btn-danger is-armed":""}`,type:"button",onClick:a,disabled:m,"aria-label":y?"Confirm remove node":"Remove node",title:y?"Confirm remove":"Remove",children:[e.jsx(Ne,{size:14}),e.jsx("span",{children:y?"Confirm":"Remove"})]})]})]})}const Ue=n.memo(Ke,Ie),O={online:"var(--success, var(--color-success))",offline:"var(--text-dim)",connecting:"var(--triage)",error:"var(--color-error)"},D=28,W=12,Ve=300,Be=120;function He({nodes:t,className:l}){const s=n.useMemo(()=>t.find(o=>o.type==="local")??t[0],[t]),r=n.useMemo(()=>t.filter(o=>o.type==="remote"),[t]),f=n.useMemo(()=>{const o=Ve,y=Math.max(0,r.length-4)*20;return o+y},[r.length]),m=f/2,c=f/2,u=n.useMemo(()=>{if(r.length===0)return[];const o=Math.min(Be,f/2-D-10),y=2*Math.PI/r.length,g=-Math.PI/2;return r.map((j,C)=>{const _=g+C*y;return{node:j,x:m+o*Math.cos(_),y:c+o*Math.sin(_)}})},[r,f,m,c]);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 ${f} ${f}`,preserveAspectRatio:"xMidYMid meet","aria-label":"Node mesh topology visualization",children:[u.map(o=>e.jsx("line",{className:"mesh-topology__link",x1:m,y1:c,x2:o.x,y2:o.y},`link-${o.node.id}`)),s&&e.jsxs("g",{className:"mesh-topology__node",transform:`translate(${m}, ${c})`,children:[e.jsx("circle",{className:"mesh-topology__node-circle",r:D,fill:O[s.status],"aria-label":`${s.name} (${s.status})`}),e.jsx("text",{className:"mesh-topology__node-label",y:D+W,textAnchor:"middle",children:s.name.length>12?`${s.name.slice(0,10)}…`:s.name}),e.jsxs("g",{className:"mesh-topology__node-type",transform:`translate(0 ${-D-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:s.type==="local"?"L":"R"})]})]}),u.map(o=>e.jsxs("g",{className:"mesh-topology__node",transform:`translate(${o.x}, ${o.y})`,children:[e.jsx("circle",{className:"mesh-topology__node-circle",r:D,fill:O[o.node.status],"aria-label":`${o.node.name} (${o.node.status})`}),e.jsx("text",{className:"mesh-topology__node-label",y:D+W,textAnchor:"middle",children:o.node.name.length>12?`${o.node.name.slice(0,10)}…`:o.node.name}),e.jsxs("g",{className:"mesh-topology__node-type",transform:`translate(0 ${-D-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:o.node.type==="local"?"L":"R"})]})]},o.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:O.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:O.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:O.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:O.error}}),e.jsx("span",{children:"Error"})]})]}),e.jsx("p",{className:"mesh-topology__notice",children:"Peer-to-peer discovery data unavailable."})]})}const qe=n.memo(He),q=1,X=10;function Xe(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<q||t.maxConcurrent>X)&&(l.maxConcurrent=`Concurrency must be between ${q} and ${X}`),l}function Je({isOpen:t,onClose:l,onSubmit:s,addToast:r}){const[f,m]=n.useState(""),[c,u]=n.useState("local"),[o,y]=n.useState(""),[g,j]=n.useState(""),[C,_]=n.useState(2),[S,A]=n.useState({}),[a,i]=n.useState(!1),x=n.useCallback(()=>{m(""),u("local"),y(""),j(""),_(2),A({}),i(!1)},[]),b=n.useCallback(()=>{a||(x(),l())},[a,l,x]);n.useEffect(()=>{if(!t){x();return}const v=h=>{h.key==="Escape"&&(h.preventDefault(),b())};return document.addEventListener("keydown",v),()=>{document.removeEventListener("keydown",v)}},[b,t,x]);const w=n.useMemo(()=>({name:f.trim(),type:c,url:c==="remote"&&o.trim()||void 0,apiKey:c==="remote"&&g||void 0,maxConcurrent:C}),[g,C,f,c,o]),$=n.useCallback(async()=>{if(a)return;const v=Xe(w);if(A(v),!(Object.keys(v).length>0)){i(!0);try{await s(w),r(`Node "${w.name}" registered`,"success"),b()}catch(h){const d=h instanceof Error?h.message:"Failed to register node";r(d,"error")}finally{i(!1)}}},[r,b,w,a,s]);return t?e.jsx("div",{className:"modal-overlay open",onClick:b,children:e.jsxs("div",{className:"modal modal-md add-node-modal",onClick:v=>v.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:b,disabled:a,"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 a node to distribute task execution across machines."}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Name"}),e.jsx("input",{className:"input",type:"text",value:f,onChange:v=>m(v.target.value),placeholder:"Build Machine",disabled:a,"aria-invalid":!!S.name,autoFocus:!0}),S.name&&e.jsx("span",{className:"form-error add-node-modal__error",children:S.name})]}),e.jsxs("div",{className:"add-node-modal__type-toggle",children:[e.jsx("button",{type:"button",className:`add-node-modal__type-btn ${c==="local"?"active":""}`,"data-type":"local",onClick:()=>u("local"),disabled:a,"aria-pressed":c==="local",children:"Local"}),e.jsx("button",{type:"button",className:`add-node-modal__type-btn ${c==="remote"?"active":""}`,"data-type":"remote",onClick:()=>u("remote"),disabled:a,"aria-pressed":c==="remote",children:"Remote"})]}),e.jsxs("div",{className:"add-node-modal__remote-fields","data-testid":"remote-fields-container","data-visible":c==="remote",children:[e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"URL"}),e.jsx("input",{className:"input",type:"text",value:o,onChange:v=>y(v.target.value),placeholder:"https://node.example.com",disabled:a,"aria-invalid":!!S.url}),S.url&&e.jsx("span",{className:"form-error add-node-modal__error",children:S.url})]}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"API Key"}),e.jsx("input",{className:"input",type:"password",value:g,onChange:v=>j(v.target.value),placeholder:"Optional",disabled:a})]})]}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Max Concurrent"}),e.jsx("input",{className:"input",type:"number",min:q,max:X,value:C,onChange:v=>_(Number(v.target.value)),disabled:a,"aria-invalid":!!S.maxConcurrent}),e.jsx("span",{className:"add-node-modal__hint",children:"Max simultaneous task agents (1–10)"}),S.maxConcurrent&&e.jsx("span",{className:"form-error add-node-modal__error",children:S.maxConcurrent})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:b,disabled:a,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary btn-sm","data-testid":"add-node-submit",onClick:$,disabled:a,children:a?"Adding...":"Add Node"})]})]})}):null}function Ge({nodeId:t,entries:l,loading:s=!1,singleNode:r=!1}){const[f,m]=n.useState(!1),[c,u]=n.useState("all"),[o,y]=n.useState("all"),g=n.useCallback(()=>{m(a=>!a)},[]),j=n.useMemo(()=>{const a=new Set;for(const i of l)a.add(i.nodeName);return Array.from(a).sort()},[l]),C=n.useMemo(()=>{let a=[...l];return c!=="all"&&(a=a.filter(i=>i.direction===c)),!r&&o!=="all"&&(a=a.filter(i=>i.nodeName===o)),a.sort((i,x)=>{const b=new Date(i.timestamp).getTime();return new Date(x.timestamp).getTime()-b}),a},[l,c,o,r]),_=n.useCallback(a=>new Date(a).toLocaleString(),[]),S=n.useCallback(a=>{switch(a){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""}},[]),A=n.useCallback(a=>{switch(a){case"success":return"Success";case"conflict":return"Conflict";case"error":return"Error";default:return a}},[]);return e.jsxs("div",{className:"settings-sync-log",children:[e.jsxs("button",{className:"settings-sync-log__header",type:"button",onClick:g,"aria-expanded":f,"data-testid":"settings-sync-log-header",children:[e.jsx(be,{size:16,className:`settings-sync-log__chevron ${f?"settings-sync-log__chevron--expanded":""}`}),e.jsxs("span",{children:[l.length," ",l.length===1?"entry":"entries"]})]}),f&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"settings-sync-log__filters",children:[e.jsxs("label",{children:["Direction:",e.jsxs("select",{value:c,onChange:a=>u(a.target.value),children:[e.jsx("option",{value:"all",children:"All"}),e.jsx("option",{value:"push",children:"Push"}),e.jsx("option",{value:"pull",children:"Pull"})]})]}),!r&&e.jsxs("label",{children:["Node:",e.jsxs("select",{value:o,onChange:a=>y(a.target.value),children:[e.jsx("option",{value:"all",children:"All Nodes"}),j.map(a=>e.jsx("option",{value:a,children:a},a))]})]})]}),s&&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(a=>e.jsxs("div",{className:"settings-sync-log__entry",children:[e.jsx("span",{className:"settings-sync-log__entry-timestamp",children:_(a.timestamp)}),e.jsx("span",{className:"settings-sync-log__entry-direction",children:a.direction==="push"?e.jsx(se,{size:14,"data-testid":"upload-icon"}):e.jsx(ee,{size:14,"data-testid":"download-icon"})}),e.jsx("span",{className:`settings-sync-log__entry-result ${S(a.result)}`,children:A(a.result)}),!r&&e.jsx("span",{className:"settings-sync-log__entry-node",children:a.nodeName}),a.details&&e.jsx("span",{className:"settings-sync-log__entry-details",title:a.details,children:a.details})]},a.id))})]})]})}function We(t,l){const s=typeof t=="string"?t:JSON.stringify(t,null,2),r=typeof l=="string"?l:JSON.stringify(l,null,2);if(s===r)return s;const f=s.split(`
|
|
12
|
+
`),m=r.split(`
|
|
13
|
+
`),c=[],u=Math.max(f.length,m.length);for(let o=0;o<u;o++){const y=f[o],g=m[o];y!==void 0&&y!==g&&c.push(`- ${y}`),g!==void 0&&g!==y&&c.push(`+ ${g}`),y!==void 0&&y===g&&c.push(` ${y}`)}return c.join(`
|
|
14
|
+
`)}function Ye({isOpen:t,onClose:l,onResolve:s,conflicts:r,localNodeName:f,remoteNodeName:m,addToast:c}){const[u,o]=n.useState({}),[y,g]=n.useState(!1);n.useEffect(()=>{const a={};for(const i of r)u[i.key]||(a[i.key]={resolution:"local"});Object.keys(a).length>0&&o(i=>({...i,...a}))},[r,u]),n.useEffect(()=>{if(!t)return;const a=i=>{i.key==="Escape"&&(i.preventDefault(),l())};return document.addEventListener("keydown",a),()=>document.removeEventListener("keydown",a)},[t,l]);const j=n.useCallback((a,i)=>{o(x=>{const b=x[a]??{};return i==="manual"?{...x,[a]:{resolution:"manual",manualValue:b.manualValue??JSON.stringify(r.find(w=>w.key===a)?.localValue??null,null,2)}}:{...x,[a]:{resolution:i}}})},[r]),C=n.useCallback((a,i)=>{o(x=>({...x,[a]:{...x[a],resolution:"manual",manualValue:i}}))},[]),_=n.useCallback(a=>{const i={};for(const x of r)i[x.key]={resolution:a};o(i)},[r]),S=n.useCallback(async()=>{g(!0);try{const a=r.map(i=>{const x=u[i.key]??{resolution:"local"};let b;switch(x.resolution){case"remote":b=i.remoteValue;break;case"manual":try{b=JSON.parse(x.manualValue??"null")}catch{b=x.manualValue??null}break;case"local":default:b=i.localValue;break}return{key:i.key,value:b}});await s(a),c("Settings conflicts resolved successfully","success"),l()}catch(a){const i=a instanceof Error?a.message:"Failed to resolve conflicts";c(i,"error")}finally{g(!1)}},[c,r,l,s,u]),A=n.useMemo(()=>{const a={};for(const i of r)a[i.key]=We(i.localValue,i.remoteValue);return a},[r]);return!t||r.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:a=>a.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:r.map(a=>{const i=u[a.key]??{resolution:"local"},x=A[a.key];return e.jsxs("div",{className:"settings-sync-conflict-modal__conflict-item",children:[e.jsx("div",{className:"settings-sync-conflict-modal__key",children:a.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:f}),e.jsx("div",{className:"settings-sync-conflict-modal__diff-content",children:e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap"},children:x})})]}),e.jsxs("div",{className:"settings-sync-conflict-modal__diff-side",children:[e.jsx("div",{className:"settings-sync-conflict-modal__diff-label",children:m}),e.jsx("div",{className:"settings-sync-conflict-modal__diff-content",children:e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap"},children:x})})]})]}),e.jsxs("div",{className:"settings-sync-conflict-modal__resolution",children:[e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${a.key}`,checked:i.resolution==="local",onChange:()=>j(a.key,"local")}),"Keep Local"]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${a.key}`,checked:i.resolution==="remote",onChange:()=>j(a.key,"remote")}),"Keep Remote"]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${a.key}`,checked:i.resolution==="manual",onChange:()=>j(a.key,"manual")}),"Merge Manually"]})]}),i.resolution==="manual"&&e.jsx("textarea",{className:"settings-sync-conflict-modal__manual-input",value:i.manualValue??"",onChange:b=>C(a.key,b.target.value),placeholder:"Enter JSON value..."})]},a.key)})}),e.jsxs("div",{className:"settings-sync-conflict-modal__bulk-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>_("local"),type:"button",children:"Resolve All: Keep Local"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>_("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:S,disabled:y,children:y?"Resolving...":"Confirm"})]})]})})}function V(t){if(!t)return"—";const l=new Date(t);return Number.isNaN(l.getTime())?"—":l.toLocaleString()}function Ze({isOpen:t,onClose:l,node:s,projects:r,onUpdate:f,onHealthCheck:m,addToast:c,syncStatus:u,onPushSettings:o,onPullSettings:y,onSyncAuth:g,syncHistory:j=[],onResolveConflicts:C}){const _=n.useRef(!0),[S,A]=n.useState(!1),[a,i]=n.useState(""),[x,b]=n.useState(""),[w,$]=n.useState(""),[v,h]=n.useState(2),[d,p]=n.useState(!1),[z,L]=n.useState(!1),[k,M]=n.useState(!1),[P,F]=n.useState(!1),[I,E]=n.useState(null),[le,re]=n.useState(!1),[ce]=n.useState([]);n.useEffect(()=>(_.current=!0,()=>{_.current=!1}),[]),n.useEffect(()=>{if(!s||!t){A(!1);return}i(s.name),b(s.url??""),$(s.apiKey??""),h(s.maxConcurrent),A(!1)},[t,s]),n.useEffect(()=>{if(!t)return;const N=R=>{R.key==="Escape"&&(R.preventDefault(),l())};return document.addEventListener("keydown",N),()=>document.removeEventListener("keydown",N)},[t,l]);const K=n.useMemo(()=>s?ne(r,s):[],[s,r]),oe=n.useCallback(async()=>{if(s)try{if(await m(s.id),!_.current)return;c(`Health check completed for ${s.name}`,"success")}catch(N){if(!_.current)return;const R=N instanceof Error?N.message:"Health check failed";c(R,"error")}},[c,s,m]),ie=n.useCallback(async()=>{if(!(!s||!o)){E(null),L(!0);try{if(await o(s.id),!_.current)return;c("Settings pushed successfully","success")}catch(N){if(!_.current)return;const R=N instanceof Error?N.message:"Push settings failed";E(R),c(R,"error")}finally{_.current&&L(!1)}}},[c,s,o]),de=n.useCallback(async()=>{if(!(!s||!y)){E(null),M(!0);try{if(await y(s.id),!_.current)return;c("Settings pulled successfully","success")}catch(N){if(!_.current)return;const R=N instanceof Error?N.message:"Pull settings failed";E(R),c(R,"error")}finally{_.current&&M(!1)}}},[c,s,y]),ue=n.useCallback(async()=>{if(!(!s||!g)){E(null),F(!0);try{if(await g(s.id),!_.current)return;c("Auth credentials synced successfully","success")}catch(N){if(!_.current)return;const R=N instanceof Error?N.message:"Auth sync failed";E(R),c(R,"error")}finally{_.current&&F(!1)}}},[c,s,g]),me=n.useCallback(()=>{E(null)},[]),he=n.useCallback(async()=>{if(!s||d)return;const N=a.trim();if(!N){c("Name is required","error");return}if(s.type==="remote"&&!x.trim()){c("URL is required for remote nodes","error");return}if(!Number.isFinite(v)||v<1){c("Concurrency must be at least 1","error");return}p(!0);try{await f(s.id,{name:N,url:s.type==="remote"&&x.trim()||void 0,apiKey:s.type==="remote"&&w||void 0,maxConcurrent:v}),c(`Updated ${N}`,"success"),A(!1)}catch(R){const ye=R instanceof Error?R.message:"Failed to update node";c(ye,"error")}finally{p(!1)}},[c,w,d,v,a,s,f,x]),fe=n.useCallback(()=>{s&&(i(s.name),b(s.url??""),$(s.apiKey??""),h(s.maxConcurrent),A(!1))},[s]);return!t||!s?null:e.jsxs("div",{className:"modal-overlay open",onClick:l,children:[e.jsxs("div",{className:"modal modal-lg node-detail-modal",onClick:N=>N.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":`Node details for ${s.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"}),!S&&e.jsxs("button",{className:"btn btn-sm",onClick:()=>A(!0),children:[e.jsx(ve,{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"}),S?e.jsx("input",{className:"input",value:a,onChange:N=>i(N.target.value),disabled:d}):e.jsx("strong",{children:s.name})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Type"}),e.jsx("strong",{children:s.type==="local"?"Local":"Remote"})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Status"}),e.jsx("strong",{children:s.status})]}),e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Max Concurrent"}),S?e.jsx("input",{className:"input",type:"number",min:1,max:10,value:v,onChange:N=>h(Number(N.target.value)),disabled:d}):e.jsx("strong",{children:s.maxConcurrent})]}),s.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"}),S?e.jsx("input",{className:"input",value:x,onChange:N=>b(N.target.value),disabled:d}):e.jsx("strong",{children:s.url??"—"})]}),e.jsxs("label",{className:"node-detail-modal__field node-detail-modal__field--full",children:[e.jsx("span",{children:"API Key"}),S?e.jsx("input",{className:"input",type:"password",value:w,onChange:N=>$(N.target.value),placeholder:"Leave blank to keep unchanged",disabled:d}):e.jsx("strong",{children:s.apiKey?"••••••••":"Not configured"})]})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Created"}),e.jsx("strong",{children:V(s.createdAt)})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Updated"}),e.jsx("strong",{children:V(s.updatedAt)})]})]}),S&&e.jsxs("div",{className:"node-detail-modal__edit-actions",children:[e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:he,disabled:d,children:[e.jsx(Ce,{size:14}),d?"Saving...":"Save"]}),e.jsxs("button",{className:"btn btn-sm",onClick:fe,disabled:d,children:[e.jsx(B,{size:14}),"Cancel"]})]})]}),e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsxs("h4",{children:[s.type==="local"?"Projects":"Assigned Projects"," (",K.length,")"]}),K.length===0?e.jsx("p",{className:"node-detail-modal__empty",children:s.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:K.map(N=>e.jsxs("li",{className:"node-detail-modal__project-item",children:[e.jsx("span",{children:N.name}),e.jsx("code",{children:N.id})]},N.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:s.status})]}),e.jsxs("span",{children:["Last check: ",e.jsx("strong",{children:V(s.updatedAt)})]})]})]}),s.type==="remote"&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Settings Sync"}),u&&e.jsxs("div",{className:"node-detail-modal__sync-status",children:[e.jsx("span",{className:"node-detail-modal__sync-dot",style:{backgroundColor:ae(u.syncState)},"aria-hidden":!0}),e.jsxs("span",{children:["Last sync:"," ",e.jsx("strong",{children:u.lastSyncAt?te(u.lastSyncAt):"Never synced"})]}),u.diffCount>0&&e.jsxs("span",{className:"node-detail-modal__sync-diff",children:["Differences: ",e.jsx("strong",{children:u.diffCount})]})]}),e.jsxs("div",{className:"node-detail-modal__sync-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:ie,disabled:z||!o,children:[e.jsx(se,{size:14}),z?"Pushing...":"Push Settings"]}),e.jsxs("button",{className:"btn btn-sm",onClick:de,disabled:k||!y,children:[e.jsx(ee,{size:14}),k?"Pulling...":"Pull Settings"]}),e.jsxs("button",{className:"btn btn-sm",onClick:ue,disabled:P||!g,children:[e.jsx(Q,{size:14}),P?"Syncing...":"Sync Auth"]})]}),I&&e.jsxs("div",{className:"node-detail-modal__sync-error",children:[e.jsx("span",{children:I}),e.jsx("button",{className:"node-detail-modal__sync-error-dismiss",onClick:me,"aria-label":"Dismiss error",children:e.jsx(B,{size:14})})]})]}),s.type==="remote"&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Sync History"}),e.jsx(Ge,{nodeId:s.id,entries:j,singleNode:!0})]})]}),e.jsxs("div",{className:"modal-actions node-detail-modal__actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:oe,children:[e.jsx(T,{size:14}),"Health Check"]}),e.jsx("button",{className:"btn btn-sm",onClick:l,children:"Close"})]})]}),s.type==="remote"&&e.jsx(Ye,{isOpen:le,onClose:()=>re(!1),onResolve:C??(async()=>{}),conflicts:ce,localNodeName:"Local",remoteNodeName:s.name,addToast:c})]})}function ts({addToast:t,onClose:l}){const{nodes:s,loading:r,error:f,refresh:m,register:c,update:u,unregister:o,healthCheck:y}=ke(),{projects:g}=Se(),{syncStatusMap:j,pushSettings:C,pullSettings:_,syncAuth:S,trackNode:A,getAuthSyncState:a,getAuthProviders:i}=$e(),[x,b]=n.useState(!1),[w,$]=n.useState(null);n.useEffect(()=>{const k=s.filter(M=>M.type==="remote");for(const M of k)A(M.id)},[s,A]),n.useEffect(()=>{if(!w)return;const k=s.find(M=>M.id===w.id)??null;$(k)},[s,w]);const v=n.useMemo(()=>{const k=s.length,M=s.filter(E=>E.status==="online").length,P=s.filter(E=>E.status==="offline"||E.status==="error").length,F=s.filter(E=>E.type==="remote").length,I=s.filter(E=>E.type==="remote"&&j[E.id]&&U(j[E.id]).syncState==="synced").length;return{total:k,online:M,offline:P,remote:F,synced:I}},[s,j]),h=n.useCallback(async k=>{await c(k)},[c]),d=n.useCallback(async()=>{try{await m()}catch{t("Failed to refresh nodes","error")}},[t,m]),p=n.useCallback(async k=>{try{await y(k),t("Node health check complete","success")}catch(M){const P=M instanceof Error?M.message:"Health check failed";t(P,"error")}},[t,y]),z=n.useCallback(async k=>{try{await o(k),t("Node removed","success"),w?.id===k&&$(null)}catch(M){const P=M instanceof Error?M.message:"Failed to remove node";t(P,"error")}},[t,w?.id,o]),L=n.useCallback(async(k,M)=>{await u(k,M)},[u]);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(Z,{size:20}),"Nodes"]}),e.jsxs("span",{className:"nodes-view-count",children:[s.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(B,{size:16})}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>void d(),disabled:r,children:[e.jsx(J,{size:14,className:r?"spin":""}),"Refresh"]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>b(!0),children:[e.jsx(G,{size:14}),"Add 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:v.total})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--online","data-testid":"nodes-stat-online",children:[e.jsxs("span",{children:[e.jsx(Re,{size:14})," Online"]}),e.jsx("strong",{children:v.online})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--offline","data-testid":"nodes-stat-offline",children:[e.jsxs("span",{children:[e.jsx(Me,{size:14})," Offline"]}),e.jsx("strong",{children:v.offline})]}),e.jsxs("div",{className:"nodes-view-stat","data-testid":"nodes-stat-remote",children:[e.jsxs("span",{children:[e.jsx(we,{size:14})," Remote"]}),e.jsx("strong",{children:v.remote})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--synced","data-testid":"nodes-stat-synced",children:[e.jsxs("span",{children:[e.jsx(J,{size:14})," Synced"]}),e.jsx("strong",{children:v.synced})]})]}),f&&e.jsx("div",{className:"nodes-view-error",children:f}),!r&&s.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(qe,{nodes:s})]}),r?e.jsx("div",{className:"nodes-view-grid",children:Array.from({length:4}).map((k,M)=>e.jsx("div",{className:"node-card node-card--loading","aria-hidden":!0},M))}):s.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:()=>b(!0),children:[e.jsx(G,{size:14}),"Add First Node"]})]}):e.jsx("div",{className:"nodes-view-grid",children:s.map(k=>{const M=k.type==="remote"&&j[k.id]?U(j[k.id]):void 0;return e.jsx(Ue,{node:k,projects:g,onHealthCheck:P=>{p(P)},onEdit:P=>$(P),onRemove:P=>{z(P)},isLoading:r,syncStatus:M,authSyncState:k.type==="remote"?a(k.id):void 0,authSyncProviders:k.type==="remote"?i(k.id):void 0},k.id)})}),e.jsx(Je,{isOpen:x,onClose:()=>b(!1),onSubmit:h,addToast:t}),e.jsx(Ze,{isOpen:w!==null,onClose:()=>$(null),node:w,projects:g,onUpdate:L,onHealthCheck:p,addToast:t,syncStatus:w?.type==="remote"&&w&&j[w.id]?U(j[w.id]):void 0,onPushSettings:C,onPullSettings:_,onSyncAuth:S})]})}export{ts as NodesView};
|