agent-dag 1.35.23 → 1.35.24

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.
@@ -69,7 +69,7 @@ Claude Code turns only. The sound is a Stop hook Claude Code runs itself when a
69
69
 
70
70
  ${n.clash} sound hook${n.clash>1?"s":""} of your own in settings.json also run${n.clash>1?"":"s"} here.`:"",l=n.parked>0?`
71
71
 
72
- ${n.parked} of your own sound hook${n.parked>1?"s were":" was"} set aside so this switch actually controls the sound. Nothing was deleted — shift-click to put ${n.parked>1?"them":"it"} back.`:"";return r+i+o+l}function $T(e){const n=Math.max(0,Math.floor(e));return`${n} event${n===1?"":"s"}`}function N5(e){return e.connected?e.paused?{tone:"paused",label:"paused",title:e.held>0?`Connected — ${$T(e.held)} held until you resume (Space)`:"Connected — updates held until you resume (Space)"}:{tone:"live",label:"live",title:"Receiving events"}:{tone:"dead",label:"offline",title:e.paused?"SSE disconnected — and the canvas is paused, so resuming will not bring events back until it reconnects":"SSE disconnected"}}function C5(e){return e.paused?e.held<=0?{label:"Resume",title:"Nothing has arrived since you paused. Resume to follow the canvas again (Space)"}:{label:`Resume · ${e.held} held`,title:`${$T(e.held)} arrived while paused and will be applied in order when you resume (Space)`}:{label:"Pause",title:"Pause live updates — events keep arriving and are applied when you resume (Space)"}}function qT(e,n){return e!==""&&n>0}function T5(e,n,r){return e===""?{active:!1,matched:n,total:r,count:null,empty:!1,message:null,dim:!1}:{active:!0,matched:n,total:r,count:`${n} of ${r}`,empty:n===0,message:n===0?`No agents match “${e}”`:null,dim:qT(e,n)}}const R5="Search agents, tools, model…";function DT(e,n){var i,o,l,u;if(!n)return!0;const r=n.toLowerCase();if(e.label.toLowerCase().includes(r)||(i=e.cwd)!=null&&i.toLowerCase().includes(r)||(o=e.cwdBasename)!=null&&o.toLowerCase().includes(r)||e.sessionId.toLowerCase().includes(r)||(l=e.firstPrompt)!=null&&l.toLowerCase().includes(r)||e.model&&(e.model.toLowerCase().includes(r)||js(e.model).toLowerCase().includes(r))||(u=e.provider)!=null&&u.toLowerCase().startsWith(r))return!0;for(const c of e.tools)if(c.name.toLowerCase().includes(r))return!0;return!1}function Lv(e){const n=Math.max(0,Math.floor(e/1e3));return n<60?"just now":n<3600?`${Math.floor(n/60)}m ago`:n<86400?`${Math.floor(n/3600)}h ago`:`${Math.floor(n/86400)}d ago`}function j5(e,n){return e.getFullYear()===n.getFullYear()&&e.getMonth()===n.getMonth()&&e.getDate()===n.getDate()}function A5(e,n,r){const i=new Date(e),o=Lv(n-e);return{label:j5(i,new Date(n))?o:`${o} · ${i.toLocaleDateString(r,{month:"short",day:"numeric"})}`,title:i.toLocaleString(r,{dateStyle:"medium",timeStyle:"medium"})}}function ua(e){return typeof window>"u"?"":getComputedStyle(document.documentElement).getPropertyValue(e).trim()||""}const I5={agent:ZP,sessionGroup:fL},FT="react-flow__node";function PE(e){var n,r;return!!e&&((r=(n=e.classList)==null?void 0:n.contains)==null?void 0:r.call(n,FT))===!0}function M5(e){try{const n=document.querySelector(`.${FT}[data-id="${CSS.escape(e)}"]`);n==null||n.focus({preventScroll:!0})}catch{}}const O5=["a[href]","button:not(:disabled)","input:not(:disabled)","select:not(:disabled)","textarea:not(:disabled)","summary","[tabindex]"].join(","),P5=420,au=18,L5=200,$5=5*6e4,q5=6,D5=2*6e4,Ey="agent-dag.layout",Ny="agent-dag.viewport",zT="agent-dag.summariesDismissed",BT="agent-dag.sessionListOpen",UT="agent-dag.detailOpen",HT="agent-dag.usagePanelOpen",LE="agent-dag.accountsPanelOpen",$E="agent-dag.versionNoticeDismissed",qE="agent-dag.oldNameNoticeDismissed",F5=15*6e4,DE={git_checkout:"this deck runs from a git checkout — pull instead:",npx:"npx runs from a cache that cannot be upgraded in place — run:",not_writable:"the install directory is not writable by this user — run:",opted_out:"installs are off (AGENTS_DECK_NO_INSTALL=1) — run:"},FE="agent-dag.autoRestart",zE="agent-dag.bundleReloadedFor";function z5(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(BT)==="1"}catch{return!1}}function B5(e){if(!(typeof window>"u"))try{window.localStorage.setItem(BT,e?"1":"0")}catch{}}function U5(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(UT)==="1"}catch{return!1}}function H5(e){if(!(typeof window>"u"))try{window.localStorage.setItem(UT,e?"1":"0")}catch{}}function W5(){const e=OC(HT);return e===null?!0:e==="1"}function V5(e){if(!(typeof window>"u"))try{window.localStorage.setItem(HT,e?"1":"0")}catch{}}function G5(){if(typeof window>"u")return new Set;try{const e=window.localStorage.getItem(zT);if(!e)return new Set;const n=JSON.parse(e);return new Set(Array.isArray(n)?n.filter(r=>typeof r=="string"):[])}catch{return new Set}}function BE(e){if(!(typeof window>"u"))try{const n=Array.from(e),r=n.length>200?n.slice(-200):n;window.localStorage.setItem(zT,JSON.stringify(r))}catch{}}function Y5(){const e={positions:[],pins:[]};if(typeof window>"u")return e;try{const n=window.localStorage.getItem(Ey);if(!n)return e;const r=JSON.parse(n);if(!("v"in r)){const o=Object.entries(r).filter(([,l])=>l&&typeof l.x=="number"&&typeof l.y=="number");return{positions:o,pins:o.map(([l])=>l)}}return{positions:Object.entries(r.positions??{}).filter(([,o])=>o&&typeof o.x=="number"&&typeof o.y=="number"),pins:Array.isArray(r.pins)?r.pins:[]}}catch{return e}}function fv(e,n){if(!(typeof window>"u"))try{const r={};for(const[i,o]of e)r[i]=o;for(const[i,o]of n)r[i]=o;window.localStorage.setItem(Ey,JSON.stringify({v:2,positions:r,pins:Array.from(n.keys())}))}catch{}}function K5(){if(typeof window>"u")return null;try{const e=window.localStorage.getItem(Ny);if(!e)return null;const n=JSON.parse(e);return typeof(n==null?void 0:n.x)!="number"||typeof(n==null?void 0:n.y)!="number"||typeof(n==null?void 0:n.zoom)!="number"?null:n}catch{return null}}function X5(e){if(!(typeof window>"u"))try{window.localStorage.setItem(Ny,JSON.stringify(e))}catch{}}function UE(){if(!(typeof window>"u")){try{window.localStorage.removeItem(Ey)}catch{}try{window.localStorage.removeItem(Ny)}catch{}}}function Q5(e,n){const r=e.agents.get(n);if(!r)return;const i=[];for(const d of e.agents.values())d.sessionId===n&&i.push(d);const o={schemaVersion:1,exportedAt:new Date().toISOString(),sessionId:n,label:r.label,cwd:r.cwd,startedAt:r.startedAt,endedAt:r.endedAt,model:r.model,agents:i.map(d=>({id:d.id,kind:d.kind,label:d.label,parentId:d.parentId,state:d.state,startedAt:d.startedAt,endedAt:d.endedAt,model:d.model,cwd:d.cwd,usage:d.usage,prompts:d.prompts,tools:d.tools.map(m=>({id:m.id,name:m.name,inputPreview:m.inputPreview,startedAt:m.startedAt,endedAt:m.endedAt,ok:m.ok,errorPreview:m.errorPreview,usage:m.usage}))}))},l=JSON.stringify(o,null,2),u=new Blob([l],{type:"application/json"}),c=URL.createObjectURL(u),h=document.createElement("a"),p=(r.label||"session").replace(/[^a-z0-9._-]/gi,"_");h.href=c,h.download=`${Gt}-${p}-${n.slice(0,8)}.json`,document.body.appendChild(h),h.click(),document.body.removeChild(h),setTimeout(()=>URL.revokeObjectURL(c),1e3)}const $v={file:"📁",shell:"⚡",web:"🌐",agent:"🤖",task:"📋",plan:"🧭",mcp:"🔌",other:"✨"},qv={file:"file",shell:"shell",web:"web",agent:"agent",task:"task",plan:"plan",mcp:"mcp",other:"other"},WT=EC;function Z5(e,n){if(!n)return null;const r=new Set([n]);let i=n;for(;i;){const l=e.agents.get(i);if(!(l!=null&&l.parentId)||r.has(l.parentId))break;r.add(l.parentId),i=l.parentId}let o=!0;for(;o;){o=!1;for(const l of e.agents.values())l.parentId&&r.has(l.parentId)&&!r.has(l.id)&&(r.add(l.id),o=!0)}return r}function J5(e,n,r,i,o,l,u,c,h,p,d,m,y,w,N,_,b,S,k){const E=[],T=[],I=new Set;if(l)for(const B of e.agents.values())S.has(B.id)&&DT(B,l)&&I.add(B.id);const O=qT(l,I.size);for(const B of e.agents.values()){if(!S.has(B.id))continue;const C=O&&!I.has(B.id),q=B.exitAt!=null,L=b!=null&&!b.has(B.id),re=[C?"rf-dim":"",q?"rf-exiting":"",L?"rf-spotlit-out":""].filter(Boolean).join(" ")||void 0,J=u.get(B.id);if(E.push({id:B.id,type:"agent",position:{x:0,y:0},data:{...B,now:n,onOpenContext:k},className:re,...J?{width:J.width,height:J.height}:null}),B.parentId&&S.has(B.parentId)){const W=ry(B.sessionId),Z=l&&!I.has(B.id)&&!I.has(B.parentId),M=q,G=_.size>0&&(_.has(B.id)||_.has(B.parentId)),K=b!=null&&!b.has(B.id)&&!b.has(B.parentId),$=B.state==="active"?2:1.5,Q=G?$+1.5:$,ne=Z||M?.2:K?.12:1,ae=["sess-edge",B.state==="active"?"sess-live":"sess-idle",M?"rf-edge-exiting":"",G?"rf-edge-selected":""].filter(Boolean).join(" ");T.push({id:`e:${B.parentId}->${B.id}`,source:B.parentId,target:B.id,animated:(B.state==="active"||G)&&!Z&&!M,type:"smoothstep",style:{"--session-hue":W,strokeWidth:Q,opacity:ne,transition:"var(--edge-transition)"},className:ae})}}const A=new Map;for(const B of e.agents.values())B.tools.length>0&&A.set(B.id,Math.min(4,B.tools.length));const U=`${w}#lanes:${r5(A)}`,z=E.filter(B=>p$(B.id,o,m,y));if(z.length>0||U!==N.current){if(z.length>0){const B=i5(E,T,{direction:"LR",pinned:o,measured:u,availableWidth:r,availableHeight:i,lanes:A});for(const C of B)MC(C.id,m,y)&&g$(C.id,C.position,m,y);a5(E,m,o,u,new Set(z.map(C=>C.id)),A)}o5(E,m,o,u,A),N.current=U}const P=l5(E,m,o,u,c,!p||d,A);P.length>0&&h(P),ru(m,e.agents),ru(y,e.agents),ru(o,e.agents),ru(u,h$(e.agents.values()));const D=[];let V=!1;for(const B of E){let C=o.get(B.id)??m.get(B.id);C||(C=m$(B.id,m,y),V=!0),D.push({...B,position:C})}return V&&(N.current=""),{nodes:D,edges:T}}function eF(){return g.jsx(ny,{children:g.jsx(tF,{})})}function tF(){var Va,Ga,Ya,Ka;const e=ja(),n=j.useRef(Rv()),[,r]=j.useState(0),i=j.useCallback(()=>r(H=>H+1),[]),[o,l]=j.useState(()=>new Set),[u,c]=j.useState(null),[h,p]=j.useState(null),d=j.useCallback((H,Y)=>{l(oe=>{if(!Y)return new Set([H]);const de=new Set(oe);return de.has(H)?de.delete(H):de.add(H),de}),c(oe=>Y&&oe===H?oe:H)},[]),m=j.useCallback(()=>{l(new Set),c(null)},[]),[y,w]=j.useState(null),[N,_]=j.useState(null),b=j.useCallback(H=>_(H),[]),[S,k]=j.useState(!1),E=j.useRef(G5()),[T,I]=j.useState(z5);j.useEffect(()=>{B5(T)},[T]);const[O,A]=j.useState(U5);j.useEffect(()=>{H5(O)},[O]);const[U,z]=j.useState(W5);j.useEffect(()=>{V5(U)},[U]);const[P,D]=j.useState(()=>{try{const H=window.localStorage.getItem(LE);return H===null?!0:H==="1"}catch{return!0}});j.useEffect(()=>{try{window.localStorage.setItem(LE,P?"1":"0")}catch{}},[P]);const[V,B]=j.useState(null),[C,q]=j.useState(!1),[L,re]=j.useState(0),[J,W]=j.useState(0);j.useEffect(()=>{fetch("/api/sound-hook").then(H=>H.ok?H.json():null).then(H=>{H!=null&&H.ok&&(B(H.enabled===!0),re((H.foreign??[]).filter(Y=>Y.worksHere).length),W(typeof H.parked=="number"?H.parked:0))}).catch(()=>{})},[]);const Z=j.useCallback(async()=>{q(!0);try{const Y=await(await fetch("/api/sound-hook",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({enabled:!V})})).json().catch(()=>null);Y!=null&&Y.ok&&B(Y.enabled===!0),fetch("/api/sound-hook").then(oe=>oe.ok?oe.json():null).then(oe=>{oe!=null&&oe.ok&&(re((oe.foreign??[]).filter(de=>de.worksHere).length),W(typeof oe.parked=="number"?oe.parked:0))}).catch(()=>{})}catch{}finally{q(!1)}},[V]),[M,G]=j.useState(!1),[K,$]=j.useState(null),[Q,ne]=j.useState(()=>{if(typeof window>"u")return"";try{return window.localStorage.getItem($E)??""}catch{return""}}),[ae,fe]=j.useState(!1),te=j.useRef(0),[ce,Ce]=j.useState(!1),ve=j.useCallback((H=!1)=>{H&&(te.current=Date.now(),Ce(!0)),fetch(H?"/api/version?refresh=1":"/api/version").then(Y=>Y.ok?Y.json():null).then(Y=>{Y&&$(Y)}).catch(()=>{}).finally(()=>{H&&Ce(!1)})},[]),je=j.useCallback(()=>{ve(Date.now()-te.current>=F5)},[ve]);j.useEffect(()=>{ve();const H=window.setInterval(je,5*6e4),Y=()=>{document.visibilityState==="visible"&&je()};return document.addEventListener("visibilitychange",Y),()=>{window.clearInterval(H),document.removeEventListener("visibilitychange",Y)}},[ve,je]),j.useEffect(()=>{M&&ve()},[M,ve]);const ye=(K==null?void 0:K.notice)??null,[Ee,Ye]=j.useState(null),[we,_e]=j.useState(Pv);j.useEffect(()=>{let H=!1;return fetch("/api/health").then(Y=>Y.ok?Y.json():null).then(Y=>{H||(_e(w5(Y)),!(!Y||typeof Y.workspace!="string")&&Ye(Y.workspace))}).catch(()=>{}),()=>{H=!0}},[M]);const Be=j.useRef(we);Be.current=we;const it=ye?`${ye.kind}:${ye.to}`:"",ft=ye!=null&&Q!==it,Ze=j.useCallback(()=>{if(!ye)return;const H=Q===it?"":it;ne(H);try{window.localStorage.setItem($E,H)}catch{}},[ye,it,Q]),[De,Je]=j.useState(()=>{if(typeof window>"u")return"";try{return window.localStorage.getItem(qE)??""}catch{return""}}),Xe=K!=null&&K.invokedAs&&K.invokedAs!==Gt?K.invokedAs:null,Mt=Xe!=null&&De!==Xe,lt=j.useCallback(()=>{if(Xe){Je(Xe);try{window.localStorage.setItem(qE,Xe)}catch{}}},[Xe]),Qe=((Va=K==null?void 0:K.upgrade)==null?void 0:Va.state)??"idle",Ot=n$(K==null?void 0:K.upgrade),zt=j.useCallback(async()=>{try{await fetch("/api/upgrade",{method:"POST"})}catch{}ve()},[ve]);j.useEffect(()=>{if(Qe!=="running")return;const H=window.setInterval(ve,3e3);return()=>window.clearInterval(H)},[Qe,ve]);const et=j.useCallback(async()=>{var oe;const H=K==null?void 0:K.command;if(!H)return;let Y=!1;try{Y=await Promise.race([((oe=navigator.clipboard)==null?void 0:oe.writeText(H).then(()=>!0))??Promise.resolve(!1),new Promise(de=>window.setTimeout(()=>de(!1),500))])}catch{Y=!1}if(!Y)try{const de=document.createElement("textarea");de.value=H,de.setAttribute("readonly",""),de.style.cssText="position:fixed;top:0;left:0;opacity:0",document.body.appendChild(de),de.select(),Y=document.execCommand("copy"),de.remove()}catch{Y=!1}Y&&(fe(!0),window.setTimeout(()=>fe(!1),1600))},[K==null?void 0:K.command]),bt=j.useCallback(()=>{I(H=>(H||D(!1),!H))},[]),ht=j.useCallback(()=>{D(H=>(H||I(!1),!H))},[]),[vt,hn]=j.useState(!1),[Yt,Pt]=j.useState(0),bn=j.useRef(null),[gr,Sn]=j.useState(!1),Bt=j.useRef(null),[Fn,pn]=j.useState(0),vr=j.useRef(x$()),[Hr,xi]=j.useState(!1),Wr=j.useCallback(()=>{const H=vr.current,Y=H.setPaused(!H.paused);for(const oe of Y)n.current=zx(n.current,oe);xi(H.paused)},[]),[ut,_i]=j.useState(Date.now()),[mn,Is]=j.useState(()=>{if(typeof window>"u")return!0;try{return window.localStorage.getItem(FE)!=="0"}catch{return!0}}),yr=j.useCallback(()=>{Is(H=>{const Y=!H;try{window.localStorage.setItem(FE,Y?"1":"0")}catch{}return Y})},[]),[zn,kn]=j.useState(!1),[Vr,Gr]=j.useState("restart"),[Yr,bi]=j.useState(null),sr=j.useRef(!1),Ms=j.useRef(null),En=j.useRef(0),wr=j.useCallback(async H=>{if(sr.current)return;const Y=(H==null?void 0:H.upgrade)===!0;sr.current=!0,Ms.current=Ot;const oe=++En.current;Gr(Y?"npx":"restart"),kn(!0);try{window.sessionStorage.setItem("agent-dag.restartPending",(ye==null?void 0:ye.to)??"")}catch{}try{await fetch("/api/restart",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({upgrade:Y})})}catch{}window.setTimeout(()=>{if(En.current===oe&&sr.current){sr.current=!1,kn(!1);try{window.sessionStorage.removeItem("agent-dag.restartPending")}catch{}}},Y?18e4:3e4)},[ye==null?void 0:ye.to,Ot]),Os=j.useRef(null);j.useEffect(()=>{let H=!1;for(const oe of n.current.agents.values())if(oe.state==="active"){H=!0;break}const Y=s$({enabled:mn,kind:ye==null?void 0:ye.kind,canRestart:(K==null?void 0:K.canRestart)===!0,busy:H,idleSince:Os.current,now:ut});Os.current=Y.idleSince,Y.restart&&wr()},[mn,ye==null?void 0:ye.kind,K==null?void 0:K.canRestart,ut,wr]),j.useEffect(()=>{const H=K==null?void 0:K.running;let Y=null,oe=null;try{Y=window.sessionStorage.getItem("agent-dag.restartPending"),oe=window.sessionStorage.getItem(zE)}catch{return}const de=t$({bundle:"1.35.23",running:H,pending:Y,lastTried:oe});if(de==="reload"){try{window.sessionStorage.setItem(zE,H??"")}catch{return}window.location.reload();return}if(de!=="confirm")return;try{window.sessionStorage.removeItem("agent-dag.restartPending")}catch{}sr.current=!1,kn(!1),bi(H??null);const xe=window.setTimeout(()=>bi(null),6e3);return()=>window.clearTimeout(xe)},[K==null?void 0:K.running]),j.useEffect(()=>{if(zn&&r$({asked:Ms.current,reported:Ot})){try{window.sessionStorage.removeItem("agent-dag.restartPending")}catch{}sr.current=!1,kn(!1)}},[zn,Ot]);const Ps=j.useRef(Y5()).current;j.useRef(!1);const Tt=j.useRef(new Map(Ps.positions.filter(([H])=>Ps.pins.includes(H)))),xr=j.useRef(null),_r=j.useState(()=>K5())[0],[Kt,Kr]=j.useState(""),[Si,nt]=j.useState(()=>new Set),[br,Xr]=j.useState(E$),[Ls,Qr]=j.useState(!1),Zr=j.useRef(null);j.useEffect(()=>{document.documentElement.dataset.theme=br;try{window.localStorage.setItem(PC,br)}catch{}},[br]),j.useEffect(()=>{if(!_r)return;const H=window.setTimeout(()=>{try{e.setViewport(_r,{duration:0})}catch{}},60);return()=>window.clearTimeout(H)},[e,_r]);const $s=j.useRef(!0);j.useEffect(()=>{const H=new EventSource("/events"),Y=w$(i,{now:()=>Date.now(),setTimeout:(oe,de)=>window.setTimeout(oe,de),clearTimeout:oe=>window.clearTimeout(oe)});return H.addEventListener("open",()=>{G(!0),Qr(!0)}),H.addEventListener("error",()=>G(!1)),H.addEventListener("replay-end",()=>{$s.current=!1,Y.flush()}),H.addEventListener("hook",oe=>{try{const de=JSON.parse(oe.data);if(!vr.current.accept(de))return;n.current=zx(n.current,de),de.replay===!0||$s.current||Date.now()-de.receivedAt>3e4?Y.replay():Y.live()}catch{}}),()=>{H.close(),Y.cancel()}},[i]),j.useEffect(()=>{const H=setInterval(()=>{const Y=Date.now();_i(Y);let oe=gP(n.current,Y,Fx);vP(n.current,Y,Fx)&&(oe=!0),pP(n.current,Y,L5,$5)&&(oe=!0),mP(n.current,Y,q5,D5)&&(oe=!0),oe&&i()},250);return()=>clearInterval(H)},[i]);const ir=j.useRef(null),St=j.useRef(0),qs=420,pt=j.useCallback((H=500)=>{try{const Se=document.querySelector(".canvas-wrap"),Pe=Array.from(document.querySelectorAll(".react-flow__node")).filter(wt=>wt.offsetWidth>0);if(!Se||Pe.length===0)return;const Fe=Se.getBoundingClientRect(),Ge=e.getViewport();if(!Number.isFinite(Ge.zoom)||Ge.zoom<=0)return;const We=wt=>(wt-Fe.left-Ge.x)/Ge.zoom,ze=wt=>(wt-Fe.top-Ge.y)/Ge.zoom,Tn=Pe.map(wt=>wt.getBoundingClientRect()),Ys=Math.min(...Tn.map(wt=>We(wt.left))),Ao=Math.max(...Tn.map(wt=>We(wt.right))),Ks=Math.min(...Tn.map(wt=>ze(wt.top))),Io=Math.max(...Tn.map(wt=>ze(wt.bottom))),Xa=Ao-Ys,us=Io-Ks;if(!(Xa>0&&us>0))return;const Zt=Math.max(.2,Math.min(1,(Fe.width-160)/(Xa+qs)*.86,(Fe.height-160)/us*.86));e.setViewport({x:80-Ys*Zt,y:Math.max(80,(Fe.height-us*Zt)/2)-Ks*Zt,zoom:Zt},{duration:H}),St.current=Date.now(),window.setTimeout(()=>{try{const wt={x:80-Ys*Zt,y:Math.max(80,(Fe.height-us*Zt)/2)-Ks*Zt,zoom:Zt},Mo=e.getViewport();(Math.abs(Mo.zoom-Zt)>.01||Math.abs(Mo.x-wt.x)>2)&&e.setViewport(wt,{duration:0})}catch{}},H+60)}catch{}},[e]),ko=j.useRef(""),Eo=j.useRef(null),qa=j.useRef(0),Sr=j.useCallback(()=>{qa.current=Date.now()},[]),Jr="agent-dag.autoFitDisabled",gn=j.useRef((()=>{if(typeof window>"u")return!1;try{return window.localStorage.getItem(Jr)==="1"}catch{return!1}})()),[Ds,Da]=j.useState(gn.current),Fa=j.useCallback(()=>{if(!gn.current){gn.current=!0,Da(!0);try{window.localStorage.setItem(Jr,"1")}catch{}}},[]),No=j.useCallback(()=>{gn.current=!1,Da(!1);try{window.localStorage.removeItem(Jr)}catch{}pt(400)},[e,pt]);j.useEffect(()=>{const H=setInterval(()=>{if(gn.current||Date.now()-qa.current<800)return;const Y=n.current,oe=Date.now(),de=[];for(const We of Y.agents.values())Ov(We,oe)&&de.push({id:We.id});if(de.length===0)return;const xe=e.getViewport(),Se=window.innerWidth-360,Pe=window.innerHeight-52;let Fe=!1,Ge=!1;for(const{id:We}of de){const ze=or.current.get(We),Tn=Tt.current.get(We)??Xt.current.get(We);if(!ze||!Tn)continue;Ge=!0;const Ys=Tn.x*xe.zoom+xe.x,Ao=Tn.y*xe.zoom+xe.y,Ks=(Tn.x+ze.width)*xe.zoom+xe.x,Io=(Tn.y+ze.height)*xe.zoom+xe.y;if(Ks>0&&Ys<Se&&Io>0&&Ao<Pe){Fe=!0;break}}Ge&&!Fe&&pt(600)},1500);return()=>clearInterval(H)},[e]);const ki=j.useRef(!1),or=j.useRef(new Map),es=j.useRef(0),ec=j.useCallback(H=>{const Y=or.current;let oe=!1;for(const de of H.nodeInternals.values()){const xe=de.width,Se=de.height;if(xe==null||Se==null)continue;const Pe=Y.get(de.id);Pe?(Math.abs(Pe.height-Se)>4||Math.abs(Pe.width-xe)>4)&&(Y.set(de.id,{width:xe,height:Se}),oe=!0):(Y.set(de.id,{width:xe,height:Se}),oe=!0)}return oe&&(es.current+=1),es.current},[]),Ei=Ke(ec),[He,za]=j.useState(0);j.useEffect(()=>{let H=0;const Y=()=>{const de=or.current;let xe=!1;for(const Se of document.querySelectorAll(".react-flow__node[data-id]")){const Pe=Se.getAttribute("data-id");if(!Pe)continue;const Fe=Se.offsetWidth,Ge=Se.offsetHeight;if(!Fe||!Ge)continue;const We=de.get(Pe);(!We||Math.abs(We.width-Fe)>4||Math.abs(We.height-Ge)>4)&&(de.set(Pe,{width:Fe,height:Ge}),xe=!0)}xe&&za(Se=>Se+1)};if(ki.current)return;let oe=0;return document.visibilityState==="hidden"?oe=window.setTimeout(Y,32):H=requestAnimationFrame(Y),()=>{cancelAnimationFrame(H),window.clearTimeout(oe)}});const Xt=j.useRef(new Map(Ps.positions)),Co=j.useRef(new Set),Ni=j.useRef(""),kr=j.useMemo(()=>{const H=[];for(const Y of n.current.agents.values())Ov(Y,ut)&&H.push(Y.id+(Y.parentId?`>${Y.parentId}`:""));return H.sort(),`${H.join("|")}#sv${Ei}.${He}`},[n.current,n.current.lastSeq,ut,Ei,He]),ts=j.useRef(null);j.useEffect(()=>(ts.current!=null&&window.clearTimeout(ts.current),ts.current=window.setTimeout(()=>{fv(Xt.current,Tt.current)},1500),()=>{ts.current!=null&&window.clearTimeout(ts.current)}),[kr]),j.useEffect(()=>{if(ko.current===kr)return;const H=ko.current;if(ko.current=kr,!H||gn.current)return;Date.now()-St.current>1200&&pt(400),ir.current&&window.clearTimeout(ir.current),ir.current=window.setTimeout(()=>{gn.current||pt(500)},280)},[kr,e,pt]);const Fs=j.useMemo(()=>{if(o.size===0)return null;const H=new Set;for(const Y of o){const oe=Z5(n.current,Y);if(oe)for(const de of oe)H.add(de)}return H.size>0?H:null},[n.current,n.current.lastSeq,o]),Nn=j.useMemo(()=>c5(n.current,ut),[n.current,n.current.lastSeq,ut]),Bn=j.useRef(null),[vn,Un]=j.useState({w:0,h:0});j.useEffect(()=>{const H=Bn.current;if(!H||typeof ResizeObserver>"u")return;const Y=new ResizeObserver(oe=>{var xe;const de=(xe=oe[0])==null?void 0:xe.contentRect;de&&Un(Se=>Math.abs(Se.w-de.width)>40||Math.abs(Se.h-de.height)>40?{w:de.width,h:de.height}:Se)});return Y.observe(H),Un({w:H.clientWidth,h:H.clientHeight}),()=>Y.disconnect()},[]);const zs=j.useCallback(H=>{var oe,de;const Y=H.target;!(Y!=null&&Y.closest)||Y.closest(O5)!==H.currentTarget||(H.preventDefault(),(de=(oe=document.activeElement)==null?void 0:oe.blur)==null||de.call(oe))},[]),Bs=j.useRef(new Map),[Hn,tc]=j.useState(!1);j.useEffect(()=>{const H=window.setTimeout(()=>tc(!0),2500);return()=>window.clearTimeout(H)},[]);const[Ba,Er]=j.useState(!1),ar=j.useRef(null),[Ci,Us]=j.useState(!1),Ua=j.useCallback(()=>{ar.current&&(window.clearTimeout(ar.current),ar.current=null),Er(!1)},[]),nc=j.useCallback(H=>{H.length!==0&&queueMicrotask(()=>{Er(!0),ar.current&&window.clearTimeout(ar.current),ar.current=window.setTimeout(()=>Er(!1),P5+80)})},[]);j.useEffect(()=>()=>{ar.current&&window.clearTimeout(ar.current)},[]);const ns=vn.w>0?vn.w*.92:0,rs=vn.h>0?vn.h:0,{nodes:Qt,edges:Ti}=j.useMemo(()=>J5(n.current,ut,ns,rs,Tt.current,Kt,or.current,Bs.current,nc,Hn,Ci,Xt.current,Co.current,kr,Ni,o,Fs,Nn,b),[n.current,n.current.lastSeq,ut,ns,rs,Hn,Ci,Kt,kr,o,Fs,Nn,b,Yt]),Ha=j.useMemo(()=>{const H=new Map;for(const oe of Qt){const de=oe.data;if(!(de!=null&&de.sessionId)||de.exitAt!=null)continue;const xe=oe.width,Se=oe.height;if(xe==null||Se==null)continue;const Pe=oe.position.x,Fe=oe.position.y,Ge=Pe+xe,We=Fe+Se,ze=H.get(de.sessionId);ze?(ze.minX=Math.min(ze.minX,Pe),ze.minY=Math.min(ze.minY,Fe),ze.maxX=Math.max(ze.maxX,Ge),ze.maxY=Math.max(ze.maxY,We)):H.set(de.sessionId,{minX:Pe,minY:Fe,maxX:Ge,maxY:We})}const Y=[];for(const[oe,de]of H){const xe=de.maxX-de.minX+au*2,Se=de.maxY-de.minY+au*2;Y.push({id:`group:${oe}`,type:LT,position:{x:de.minX-au,y:de.minY-au},data:{sessionId:oe,w:xe,h:Se},width:xe,height:Se,style:{width:xe,height:Se},zIndex:-1,draggable:!0,selectable:!1,focusable:!1,deletable:!1,connectable:!1})}return Y},[Qt,ut]),rc=j.useMemo(()=>{const H=[...Ha,...Qt],Y=Bt.current;return!Y||Y.size===0?H:H.map(oe=>{const de=Y.get(oe.id);return de?{...oe,position:de}:oe})},[Ha,Qt,Fn]),Nr=j.useMemo(()=>{if(!Kt)return null;const H=new Set;for(const Y of n.current.agents.values())Nn.has(Y.id)&&DT(Y,Kt)&&H.add(Y.id);return H},[n.current,n.current.lastSeq,Kt,Nn]),Cn=j.useMemo(()=>T5(Kt,(Nr==null?void 0:Nr.size)??0,Nn.size),[Kt,Nr,Nn]),ss=j.useMemo(()=>{const H=new Set;for(const Y of n.current.agents.values())for(const oe of Y.tools)H.add(WT(oe.name));return Object.keys($v).filter(Y=>H.has(Y))},[n.current,n.current.lastSeq]);j.useEffect(()=>{if(ss.length<=1){Sn(!1);return}let H=0;const Y=()=>{const oe=bn.current;if(oe&&!document.hidden){const de=oe.getBoundingClientRect(),xe=Array.from(document.querySelectorAll(".react-flow__node, .tool-burst")).map(Pe=>Pe.getBoundingClientRect()),Se=f5(de,xe,8);Sn(Pe=>Pe===Se?Pe:Se)}H=window.setTimeout(Y,300)};return Y(),()=>window.clearTimeout(H)},[ss.length]);const is=j.useMemo(()=>{const H=new Map;for(const oe of n.current.agents.values())for(const de of oe.tools){if(!de.name.startsWith("mcp__"))continue;const xe=de.name.slice(5),Se=xe.indexOf("__"),Pe=Se>0?xe.slice(0,Se):xe;H.set(Pe,(H.get(Pe)??0)+1)}const Y=[];for(const[oe,de]of H){let xe=5381;for(let Se=0;Se<oe.length;Se++)xe=(xe<<5)+xe^oe.charCodeAt(Se);Y.push({server:oe,count:de,hue:Math.abs(xe)%360})}return Y.sort((oe,de)=>de.count-oe.count),Y},[n.current,n.current.lastSeq]),lr=j.useCallback(H=>{nt(Y=>{const oe=new Set(Y);return oe.has(H)?oe.delete(H):oe.add(H),oe})},[]),Rt=u?n.current.agents.get(u):null,os=h?Array.from(n.current.agents.values()).flatMap(H=>H.tools).find(H=>H.id===h)??null:null,To=j.useCallback(async()=>{try{await fetch("/api/clear",{method:"POST"})}catch{}n.current=Rv(),Tt.current.clear(),or.current.clear(),Xt.current.clear(),Ni.current="",UE(),m(),i()},[i,m]),Hs=j.useRef(S);Hs.current=S;const Ws=j.useRef(!1);Ws.current=os!=null||vt||N!=null||y!=null;const Vs=j.useCallback(H=>{const Y=o$(H,{confirmOpen:Hs.current,modalOpen:Ws.current});Y==="confirm"?k(!0):Y==="clear"&&(k(!1),To())},[To]),Lt=j.useCallback(()=>{Tt.current.clear(),Xt.current.clear(),Ni.current="",UE(),i(),window.setTimeout(()=>pt(500),80)},[i,e,pt]),Cr=j.useCallback(()=>pt(500),[pt]),as=j.useRef(Qt);as.current=Qt;const ls=j.useRef(u);ls.current=u;const Ro=j.useCallback(H=>{const Y=as.current,oe=l$(Y.map(Se=>({id:Se.id,x:Se.position.x,y:Se.position.y})),ls.current,H),de=oe?Y.find(Se=>Se.id===oe):void 0;if(!de)return;const xe=PE(document.activeElement);d(de.id,!1),window.setTimeout(()=>{try{e.fitView({padding:.35,duration:350,nodes:[de]})}catch{}St.current=Date.now(),xe&&M5(de.id)},30)},[d,e]),Ri=j.useCallback(H=>{d(H,!1),window.setTimeout(()=>{try{const Y=as.current.find(oe=>oe.id===H);Y&&e.fitView({padding:.3,duration:500,nodes:[Y]}),St.current=Date.now()}catch{}},60)},[d,e]);j.useEffect(()=>{const H=Y=>{var Fe,Ge,We;const oe=Y.target,de={tagName:oe==null?void 0:oe.tagName,isContentEditable:oe==null?void 0:oe.isContentEditable,role:(Fe=oe==null?void 0:oe.getAttribute)==null?void 0:Fe.call(oe,"role"),type:oe==null?void 0:oe.type};if(Y.key==="Escape"){const ze=LP({overlayOpen:Eu.depth()>0,typing:sy(de)});ze==="dismiss"?Eu.dismissTop():ze==="blur"?oe==null||oe.blur():(f$(de)&&(oe==null||oe.blur()),m());return}if(bC(Y))return;const xe=PE(oe)?(Ge=oe==null?void 0:oe.getAttribute)==null?void 0:Ge.call(oe,"data-id"):null,Se=xe&&as.current.some(ze=>ze.id===xe)?xe:null,Pe=c$(Y,Se);if(Pe.kind==="activate"){Y.preventDefault(),d(Pe.nodeId,Pe.additive);return}if(Pe.kind!=="node"&&!(Pe.nodeId==null&&HP(de))){if(Y.key==="/"){Y.preventDefault(),(We=Zr.current)==null||We.focus();return}Y.key===" "&&(Y.preventDefault(),Wr()),(Y.key==="c"||Y.key==="C")&&Vs("shortcut"),(Y.key==="r"||Y.key==="R")&&Lt(),(Y.key==="f"||Y.key==="F")&&Cr(),(Y.key==="l"||Y.key==="L")&&bt(),(Y.key==="h"||Y.key==="H")&&hn(ze=>!ze),(Y.key==="u"||Y.key==="U")&&z(ze=>!ze),(Y.key==="a"||Y.key==="A")&&Be.current.claude&&ht(),(Y.key==="j"||Y.key==="J")&&Ro(1),(Y.key==="k"||Y.key==="K")&&Ro(-1),(Y.key==="t"||Y.key==="T")&&Xr(ze=>ze==="dark"?"light":"dark")}};return window.addEventListener("keydown",H),()=>window.removeEventListener("keydown",H)},[Vs,Lt,Cr,m,d,Ro,Wr]);const Tr=n.current.agents.size,Gs=new Set(Array.from(n.current.agents.values()).map(H=>H.sessionId)).size,tn=j.useMemo(()=>e3(n.current.agents.values()),[n.current,n.current.lastSeq]),jo=j.useMemo(()=>t3(n.current.agents.values()),[n.current,n.current.lastSeq]),Wa=j.useRef(null);j.useEffect(()=>{const H=N$({waiting:tn.length,running:jo}),Y=Wa.current;if(Wa.current=H,(Y==null?void 0:Y.title)!==H.title&&(document.title=H.title),(Y==null?void 0:Y.icon)!==H.icon){const oe=document.querySelector('link[rel="icon"]');oe&&(oe.href=C$[H.icon])}},[tn.length,jo]);const[sc,ic]=j.useState(""),ji=R$(tn);j.useEffect(()=>{ic(H=>j$(H,ji))},[ji]);const nn=j.useMemo(()=>{let H=0,Y=0,oe=0,de=0,xe=0,Se=0,Pe=0,Fe=0,Ge=0;for(const We of n.current.agents.values()){H+=We.usage.inputTokens,Y+=We.usage.outputTokens,oe+=We.usage.cacheReadTokens,de+=We.usage.cacheCreateTokens;const ze=dn(We.usage,We.model);xe+=ze.total,Se+=ze.input,Pe+=ze.output,Fe+=ze.cacheRead,Ge+=ze.cacheWrite}return{inT:H,outT:Y,cacheR:oe,cacheC:de,sum:H+Y,cost:{total:xe,input:Se,output:Pe,cacheRead:Fe,cacheWrite:Ge}}},[n.current,n.current.lastSeq]);return g.jsxs("div",{className:"app",children:[g.jsx("a",{className:"skip-link",href:"#canvas",children:"Skip to the canvas"}),g.jsxs("header",{className:"topbar",children:[g.jsxs("div",{className:"brand",children:[g.jsx("span",{className:"logo"}),g.jsx("h1",{children:Gt}),ye?g.jsxs("button",{type:"button",className:"v stale",onClick:Ze,"aria-label":v5({...ye,open:ft}),title:ye.kind==="restart"?`Running v${ye.from}; v${ye.to} is installed on disk. Restart to pick it up.`:`Running v${ye.from}; v${ye.to} is on npm.`,children:["v",ye.from,g.jsx("span",{className:"v-dot","aria-hidden":!0})]}):(()=>{const H={running:(K==null?void 0:K.running)??"1.35.23",latest:K==null?void 0:K.latest,latestPending:K==null?void 0:K.latestPending,checkedAgo:K!=null&&K.checkedAt?Lv(ut-K.checkedAt):null,checkDisabled:K==null?void 0:K.checkDisabled,checking:ce};return g.jsxs("button",{type:"button",className:ce?"v checking":"v",onClick:()=>ve(!0),"aria-busy":ce||void 0,"aria-label":g5(H),title:m5(H),children:["v",H.running]})})()]}),Rt&&(()=>{const H=dn(Rt.usage,Rt.model),Y=Math.max(0,((Rt.endedAt??ut)-Rt.startedAt)/1e3),oe=Rt.state==="active"?ku(H.total,Y):null,de=o.size-1;return g.jsxs("button",{type:"button",className:"selected-ribbon",title:`Fit view to ${Rt.label}`,onClick:()=>{try{const xe=Qt.find(Se=>Se.id===Rt.id);xe&&e.fitView({padding:.35,duration:500,nodes:[xe]}),St.current=Date.now()}catch{}},children:[g.jsx("span",{className:`state-pill state-${Rt.state}`,children:Rt.state==="active"?"live":Rt.state}),g.jsx("span",{className:"selected-label",children:Rt.label}),H.total>0&&g.jsxs("span",{className:"selected-cost",children:[qe(H.total),oe?g.jsxs("span",{className:"selected-rate",children:[" · ",oe]}):null]}),de>0&&g.jsxs("span",{className:"selected-extra",children:["+",de]}),g.jsx("span",{"aria-hidden":!0,className:"selected-close",onClick:xe=>{xe.stopPropagation(),m()},children:"×"})]})})(),g.jsxs("div",{className:"actions",children:[g.jsxs("div",{className:"search",children:[g.jsx("span",{className:"search-icon","aria-hidden":!0,children:"⌕"}),g.jsx("input",{ref:Zr,type:"text",placeholder:R5,value:Kt,onChange:H=>Kr(H.target.value),spellCheck:!1,"aria-label":"Filter the graph"}),Kt?g.jsx("button",{className:"search-clear","aria-label":"Clear search",onClick:()=>Kr(""),children:"×"}):g.jsx("kbd",{className:"search-kbd","aria-hidden":!0,children:"/"}),Cn.count&&g.jsx("span",{className:`search-count${Cn.empty?" none":""}`,"aria-live":"polite",title:`${Cn.count} agents on the canvas match “${Kt}”`,children:Cn.count})]}),g.jsxs("span",{className:"status",children:[(()=>{const H=N5({connected:M,paused:Hr,held:vr.current.size});return g.jsx("span",{className:`pill ${H.tone}`,title:H.title,children:H.label})})(),g.jsxs("span",{className:"stat",title:b5(we),children:[g.jsx("span",{className:"count",children:Gs}),g.jsx("span",{className:"lbl",children:"sessions"})]}),g.jsxs("span",{className:"stat",title:"Total agents (root + subagents)",children:[g.jsx("span",{className:"count",children:Tr}),g.jsx("span",{className:"lbl",children:"agents"})]}),g.jsxs("span",{className:"stat",title:S5(we),children:[g.jsx("span",{className:"count",children:n.current.totalEvents}),g.jsx("span",{className:"lbl",children:"events"})]}),nn.sum>0&&g.jsxs("span",{className:"stat",title:`in:${nn.inT.toLocaleString()} out:${nn.outT.toLocaleString()} cache-r:${nn.cacheR.toLocaleString()} cache-c:${nn.cacheC.toLocaleString()}`,children:[g.jsx("span",{className:"count",children:Dt(nn.sum)}),g.jsx("span",{className:"lbl",children:"tokens"})]}),is.length>0&&g.jsxs("span",{className:"stat mcp-legend",title:`MCP servers seen this session:
72
+ ${n.parked} of your own sound hook${n.parked>1?"s were":" was"} set aside so this switch actually controls the sound. Nothing was deleted — shift-click to put ${n.parked>1?"them":"it"} back.`:"";return r+i+o+l}function $T(e){const n=Math.max(0,Math.floor(e));return`${n} event${n===1?"":"s"}`}function N5(e){return e.connected?e.paused?{tone:"paused",label:"paused",title:e.held>0?`Connected — ${$T(e.held)} held until you resume (Space)`:"Connected — updates held until you resume (Space)"}:{tone:"live",label:"live",title:"Receiving events"}:{tone:"dead",label:"offline",title:e.paused?"SSE disconnected — and the canvas is paused, so resuming will not bring events back until it reconnects":"SSE disconnected"}}function C5(e){return e.paused?e.held<=0?{label:"Resume",title:"Nothing has arrived since you paused. Resume to follow the canvas again (Space)"}:{label:`Resume · ${e.held} held`,title:`${$T(e.held)} arrived while paused and will be applied in order when you resume (Space)`}:{label:"Pause",title:"Pause live updates — events keep arriving and are applied when you resume (Space)"}}function qT(e,n){return e!==""&&n>0}function T5(e,n,r){return e===""?{active:!1,matched:n,total:r,count:null,empty:!1,message:null,dim:!1}:{active:!0,matched:n,total:r,count:`${n} of ${r}`,empty:n===0,message:n===0?`No agents match “${e}”`:null,dim:qT(e,n)}}const R5="Search agents, tools, model…";function DT(e,n){var i,o,l,u;if(!n)return!0;const r=n.toLowerCase();if(e.label.toLowerCase().includes(r)||(i=e.cwd)!=null&&i.toLowerCase().includes(r)||(o=e.cwdBasename)!=null&&o.toLowerCase().includes(r)||e.sessionId.toLowerCase().includes(r)||(l=e.firstPrompt)!=null&&l.toLowerCase().includes(r)||e.model&&(e.model.toLowerCase().includes(r)||js(e.model).toLowerCase().includes(r))||(u=e.provider)!=null&&u.toLowerCase().startsWith(r))return!0;for(const c of e.tools)if(c.name.toLowerCase().includes(r))return!0;return!1}function Lv(e){const n=Math.max(0,Math.floor(e/1e3));return n<60?"just now":n<3600?`${Math.floor(n/60)}m ago`:n<86400?`${Math.floor(n/3600)}h ago`:`${Math.floor(n/86400)}d ago`}function j5(e,n){return e.getFullYear()===n.getFullYear()&&e.getMonth()===n.getMonth()&&e.getDate()===n.getDate()}function A5(e,n,r){const i=new Date(e),o=Lv(n-e);return{label:j5(i,new Date(n))?o:`${o} · ${i.toLocaleDateString(r,{month:"short",day:"numeric"})}`,title:i.toLocaleString(r,{dateStyle:"medium",timeStyle:"medium"})}}function ua(e){return typeof window>"u"?"":getComputedStyle(document.documentElement).getPropertyValue(e).trim()||""}const I5={agent:ZP,sessionGroup:fL},FT="react-flow__node";function PE(e){var n,r;return!!e&&((r=(n=e.classList)==null?void 0:n.contains)==null?void 0:r.call(n,FT))===!0}function M5(e){try{const n=document.querySelector(`.${FT}[data-id="${CSS.escape(e)}"]`);n==null||n.focus({preventScroll:!0})}catch{}}const O5=["a[href]","button:not(:disabled)","input:not(:disabled)","select:not(:disabled)","textarea:not(:disabled)","summary","[tabindex]"].join(","),P5=420,au=18,L5=200,$5=5*6e4,q5=6,D5=2*6e4,Ey="agent-dag.layout",Ny="agent-dag.viewport",zT="agent-dag.summariesDismissed",BT="agent-dag.sessionListOpen",UT="agent-dag.detailOpen",HT="agent-dag.usagePanelOpen",LE="agent-dag.accountsPanelOpen",$E="agent-dag.versionNoticeDismissed",qE="agent-dag.oldNameNoticeDismissed",F5=15*6e4,DE={git_checkout:"this deck runs from a git checkout — pull instead:",npx:"npx runs from a cache that cannot be upgraded in place — run:",not_writable:"the install directory is not writable by this user — run:",opted_out:"installs are off (AGENTS_DECK_NO_INSTALL=1) — run:"},FE="agent-dag.autoRestart",zE="agent-dag.bundleReloadedFor";function z5(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(BT)==="1"}catch{return!1}}function B5(e){if(!(typeof window>"u"))try{window.localStorage.setItem(BT,e?"1":"0")}catch{}}function U5(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(UT)==="1"}catch{return!1}}function H5(e){if(!(typeof window>"u"))try{window.localStorage.setItem(UT,e?"1":"0")}catch{}}function W5(){const e=OC(HT);return e===null?!0:e==="1"}function V5(e){if(!(typeof window>"u"))try{window.localStorage.setItem(HT,e?"1":"0")}catch{}}function G5(){if(typeof window>"u")return new Set;try{const e=window.localStorage.getItem(zT);if(!e)return new Set;const n=JSON.parse(e);return new Set(Array.isArray(n)?n.filter(r=>typeof r=="string"):[])}catch{return new Set}}function BE(e){if(!(typeof window>"u"))try{const n=Array.from(e),r=n.length>200?n.slice(-200):n;window.localStorage.setItem(zT,JSON.stringify(r))}catch{}}function Y5(){const e={positions:[],pins:[]};if(typeof window>"u")return e;try{const n=window.localStorage.getItem(Ey);if(!n)return e;const r=JSON.parse(n);if(!("v"in r)){const o=Object.entries(r).filter(([,l])=>l&&typeof l.x=="number"&&typeof l.y=="number");return{positions:o,pins:o.map(([l])=>l)}}return{positions:Object.entries(r.positions??{}).filter(([,o])=>o&&typeof o.x=="number"&&typeof o.y=="number"),pins:Array.isArray(r.pins)?r.pins:[]}}catch{return e}}function fv(e,n){if(!(typeof window>"u"))try{const r={};for(const[i,o]of e)r[i]=o;for(const[i,o]of n)r[i]=o;window.localStorage.setItem(Ey,JSON.stringify({v:2,positions:r,pins:Array.from(n.keys())}))}catch{}}function K5(){if(typeof window>"u")return null;try{const e=window.localStorage.getItem(Ny);if(!e)return null;const n=JSON.parse(e);return typeof(n==null?void 0:n.x)!="number"||typeof(n==null?void 0:n.y)!="number"||typeof(n==null?void 0:n.zoom)!="number"?null:n}catch{return null}}function X5(e){if(!(typeof window>"u"))try{window.localStorage.setItem(Ny,JSON.stringify(e))}catch{}}function UE(){if(!(typeof window>"u")){try{window.localStorage.removeItem(Ey)}catch{}try{window.localStorage.removeItem(Ny)}catch{}}}function Q5(e,n){const r=e.agents.get(n);if(!r)return;const i=[];for(const d of e.agents.values())d.sessionId===n&&i.push(d);const o={schemaVersion:1,exportedAt:new Date().toISOString(),sessionId:n,label:r.label,cwd:r.cwd,startedAt:r.startedAt,endedAt:r.endedAt,model:r.model,agents:i.map(d=>({id:d.id,kind:d.kind,label:d.label,parentId:d.parentId,state:d.state,startedAt:d.startedAt,endedAt:d.endedAt,model:d.model,cwd:d.cwd,usage:d.usage,prompts:d.prompts,tools:d.tools.map(m=>({id:m.id,name:m.name,inputPreview:m.inputPreview,startedAt:m.startedAt,endedAt:m.endedAt,ok:m.ok,errorPreview:m.errorPreview,usage:m.usage}))}))},l=JSON.stringify(o,null,2),u=new Blob([l],{type:"application/json"}),c=URL.createObjectURL(u),h=document.createElement("a"),p=(r.label||"session").replace(/[^a-z0-9._-]/gi,"_");h.href=c,h.download=`${Gt}-${p}-${n.slice(0,8)}.json`,document.body.appendChild(h),h.click(),document.body.removeChild(h),setTimeout(()=>URL.revokeObjectURL(c),1e3)}const $v={file:"📁",shell:"⚡",web:"🌐",agent:"🤖",task:"📋",plan:"🧭",mcp:"🔌",other:"✨"},qv={file:"file",shell:"shell",web:"web",agent:"agent",task:"task",plan:"plan",mcp:"mcp",other:"other"},WT=EC;function Z5(e,n){if(!n)return null;const r=new Set([n]);let i=n;for(;i;){const l=e.agents.get(i);if(!(l!=null&&l.parentId)||r.has(l.parentId))break;r.add(l.parentId),i=l.parentId}let o=!0;for(;o;){o=!1;for(const l of e.agents.values())l.parentId&&r.has(l.parentId)&&!r.has(l.id)&&(r.add(l.id),o=!0)}return r}function J5(e,n,r,i,o,l,u,c,h,p,d,m,y,w,N,_,b,S,k){const E=[],T=[],I=new Set;if(l)for(const B of e.agents.values())S.has(B.id)&&DT(B,l)&&I.add(B.id);const O=qT(l,I.size);for(const B of e.agents.values()){if(!S.has(B.id))continue;const C=O&&!I.has(B.id),q=B.exitAt!=null,L=b!=null&&!b.has(B.id),re=[C?"rf-dim":"",q?"rf-exiting":"",L?"rf-spotlit-out":""].filter(Boolean).join(" ")||void 0,J=u.get(B.id);if(E.push({id:B.id,type:"agent",position:{x:0,y:0},data:{...B,now:n,onOpenContext:k},className:re,...J?{width:J.width,height:J.height}:null}),B.parentId&&S.has(B.parentId)){const W=ry(B.sessionId),Z=l&&!I.has(B.id)&&!I.has(B.parentId),M=q,G=_.size>0&&(_.has(B.id)||_.has(B.parentId)),K=b!=null&&!b.has(B.id)&&!b.has(B.parentId),$=B.state==="active"?2:1.5,Q=G?$+1.5:$,ne=Z||M?.2:K?.12:1,ae=["sess-edge",B.state==="active"?"sess-live":"sess-idle",M?"rf-edge-exiting":"",G?"rf-edge-selected":""].filter(Boolean).join(" ");T.push({id:`e:${B.parentId}->${B.id}`,source:B.parentId,target:B.id,animated:(B.state==="active"||G)&&!Z&&!M,type:"smoothstep",style:{"--session-hue":W,strokeWidth:Q,opacity:ne,transition:"var(--edge-transition)"},className:ae})}}const A=new Map;for(const B of e.agents.values())B.tools.length>0&&A.set(B.id,Math.min(4,B.tools.length));const U=`${w}#lanes:${r5(A)}`,z=E.filter(B=>p$(B.id,o,m,y));if(z.length>0||U!==N.current){if(z.length>0){const B=i5(E,T,{direction:"LR",pinned:o,measured:u,availableWidth:r,availableHeight:i,lanes:A});for(const C of B)MC(C.id,m,y)&&g$(C.id,C.position,m,y);a5(E,m,o,u,new Set(z.map(C=>C.id)),A)}o5(E,m,o,u,A),N.current=U}const P=l5(E,m,o,u,c,!p||d,A);P.length>0&&h(P),ru(m,e.agents),ru(y,e.agents),ru(o,e.agents),ru(u,h$(e.agents.values()));const D=[];let V=!1;for(const B of E){let C=o.get(B.id)??m.get(B.id);C||(C=m$(B.id,m,y),V=!0),D.push({...B,position:C})}return V&&(N.current=""),{nodes:D,edges:T}}function eF(){return g.jsx(ny,{children:g.jsx(tF,{})})}function tF(){var Va,Ga,Ya,Ka;const e=ja(),n=j.useRef(Rv()),[,r]=j.useState(0),i=j.useCallback(()=>r(H=>H+1),[]),[o,l]=j.useState(()=>new Set),[u,c]=j.useState(null),[h,p]=j.useState(null),d=j.useCallback((H,Y)=>{l(oe=>{if(!Y)return new Set([H]);const de=new Set(oe);return de.has(H)?de.delete(H):de.add(H),de}),c(oe=>Y&&oe===H?oe:H)},[]),m=j.useCallback(()=>{l(new Set),c(null)},[]),[y,w]=j.useState(null),[N,_]=j.useState(null),b=j.useCallback(H=>_(H),[]),[S,k]=j.useState(!1),E=j.useRef(G5()),[T,I]=j.useState(z5);j.useEffect(()=>{B5(T)},[T]);const[O,A]=j.useState(U5);j.useEffect(()=>{H5(O)},[O]);const[U,z]=j.useState(W5);j.useEffect(()=>{V5(U)},[U]);const[P,D]=j.useState(()=>{try{const H=window.localStorage.getItem(LE);return H===null?!0:H==="1"}catch{return!0}});j.useEffect(()=>{try{window.localStorage.setItem(LE,P?"1":"0")}catch{}},[P]);const[V,B]=j.useState(null),[C,q]=j.useState(!1),[L,re]=j.useState(0),[J,W]=j.useState(0);j.useEffect(()=>{fetch("/api/sound-hook").then(H=>H.ok?H.json():null).then(H=>{H!=null&&H.ok&&(B(H.enabled===!0),re((H.foreign??[]).filter(Y=>Y.worksHere).length),W(typeof H.parked=="number"?H.parked:0))}).catch(()=>{})},[]);const Z=j.useCallback(async()=>{q(!0);try{const Y=await(await fetch("/api/sound-hook",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({enabled:!V})})).json().catch(()=>null);Y!=null&&Y.ok&&B(Y.enabled===!0),fetch("/api/sound-hook").then(oe=>oe.ok?oe.json():null).then(oe=>{oe!=null&&oe.ok&&(re((oe.foreign??[]).filter(de=>de.worksHere).length),W(typeof oe.parked=="number"?oe.parked:0))}).catch(()=>{})}catch{}finally{q(!1)}},[V]),[M,G]=j.useState(!1),[K,$]=j.useState(null),[Q,ne]=j.useState(()=>{if(typeof window>"u")return"";try{return window.localStorage.getItem($E)??""}catch{return""}}),[ae,fe]=j.useState(!1),te=j.useRef(0),[ce,Ce]=j.useState(!1),ve=j.useCallback((H=!1)=>{H&&(te.current=Date.now(),Ce(!0)),fetch(H?"/api/version?refresh=1":"/api/version").then(Y=>Y.ok?Y.json():null).then(Y=>{Y&&$(Y)}).catch(()=>{}).finally(()=>{H&&Ce(!1)})},[]),je=j.useCallback(()=>{ve(Date.now()-te.current>=F5)},[ve]);j.useEffect(()=>{ve();const H=window.setInterval(je,5*6e4),Y=()=>{document.visibilityState==="visible"&&je()};return document.addEventListener("visibilitychange",Y),()=>{window.clearInterval(H),document.removeEventListener("visibilitychange",Y)}},[ve,je]),j.useEffect(()=>{M&&ve()},[M,ve]);const ye=(K==null?void 0:K.notice)??null,[Ee,Ye]=j.useState(null),[we,_e]=j.useState(Pv);j.useEffect(()=>{let H=!1;return fetch("/api/health").then(Y=>Y.ok?Y.json():null).then(Y=>{H||(_e(w5(Y)),!(!Y||typeof Y.workspace!="string")&&Ye(Y.workspace))}).catch(()=>{}),()=>{H=!0}},[M]);const Be=j.useRef(we);Be.current=we;const it=ye?`${ye.kind}:${ye.to}`:"",ft=ye!=null&&Q!==it,Ze=j.useCallback(()=>{if(!ye)return;const H=Q===it?"":it;ne(H);try{window.localStorage.setItem($E,H)}catch{}},[ye,it,Q]),[De,Je]=j.useState(()=>{if(typeof window>"u")return"";try{return window.localStorage.getItem(qE)??""}catch{return""}}),Xe=K!=null&&K.invokedAs&&K.invokedAs!==Gt?K.invokedAs:null,Mt=Xe!=null&&De!==Xe,lt=j.useCallback(()=>{if(Xe){Je(Xe);try{window.localStorage.setItem(qE,Xe)}catch{}}},[Xe]),Qe=((Va=K==null?void 0:K.upgrade)==null?void 0:Va.state)??"idle",Ot=n$(K==null?void 0:K.upgrade),zt=j.useCallback(async()=>{try{await fetch("/api/upgrade",{method:"POST"})}catch{}ve()},[ve]);j.useEffect(()=>{if(Qe!=="running")return;const H=window.setInterval(ve,3e3);return()=>window.clearInterval(H)},[Qe,ve]);const et=j.useCallback(async()=>{var oe;const H=K==null?void 0:K.command;if(!H)return;let Y=!1;try{Y=await Promise.race([((oe=navigator.clipboard)==null?void 0:oe.writeText(H).then(()=>!0))??Promise.resolve(!1),new Promise(de=>window.setTimeout(()=>de(!1),500))])}catch{Y=!1}if(!Y)try{const de=document.createElement("textarea");de.value=H,de.setAttribute("readonly",""),de.style.cssText="position:fixed;top:0;left:0;opacity:0",document.body.appendChild(de),de.select(),Y=document.execCommand("copy"),de.remove()}catch{Y=!1}Y&&(fe(!0),window.setTimeout(()=>fe(!1),1600))},[K==null?void 0:K.command]),bt=j.useCallback(()=>{I(H=>(H||D(!1),!H))},[]),ht=j.useCallback(()=>{D(H=>(H||I(!1),!H))},[]),[vt,hn]=j.useState(!1),[Yt,Pt]=j.useState(0),bn=j.useRef(null),[gr,Sn]=j.useState(!1),Bt=j.useRef(null),[Fn,pn]=j.useState(0),vr=j.useRef(x$()),[Hr,xi]=j.useState(!1),Wr=j.useCallback(()=>{const H=vr.current,Y=H.setPaused(!H.paused);for(const oe of Y)n.current=zx(n.current,oe);xi(H.paused)},[]),[ut,_i]=j.useState(Date.now()),[mn,Is]=j.useState(()=>{if(typeof window>"u")return!0;try{return window.localStorage.getItem(FE)!=="0"}catch{return!0}}),yr=j.useCallback(()=>{Is(H=>{const Y=!H;try{window.localStorage.setItem(FE,Y?"1":"0")}catch{}return Y})},[]),[zn,kn]=j.useState(!1),[Vr,Gr]=j.useState("restart"),[Yr,bi]=j.useState(null),sr=j.useRef(!1),Ms=j.useRef(null),En=j.useRef(0),wr=j.useCallback(async H=>{if(sr.current)return;const Y=(H==null?void 0:H.upgrade)===!0;sr.current=!0,Ms.current=Ot;const oe=++En.current;Gr(Y?"npx":"restart"),kn(!0);try{window.sessionStorage.setItem("agent-dag.restartPending",(ye==null?void 0:ye.to)??"")}catch{}try{await fetch("/api/restart",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({upgrade:Y})})}catch{}window.setTimeout(()=>{if(En.current===oe&&sr.current){sr.current=!1,kn(!1);try{window.sessionStorage.removeItem("agent-dag.restartPending")}catch{}}},Y?18e4:3e4)},[ye==null?void 0:ye.to,Ot]),Os=j.useRef(null);j.useEffect(()=>{let H=!1;for(const oe of n.current.agents.values())if(oe.state==="active"){H=!0;break}const Y=s$({enabled:mn,kind:ye==null?void 0:ye.kind,canRestart:(K==null?void 0:K.canRestart)===!0,busy:H,idleSince:Os.current,now:ut});Os.current=Y.idleSince,Y.restart&&wr()},[mn,ye==null?void 0:ye.kind,K==null?void 0:K.canRestart,ut,wr]),j.useEffect(()=>{const H=K==null?void 0:K.running;let Y=null,oe=null;try{Y=window.sessionStorage.getItem("agent-dag.restartPending"),oe=window.sessionStorage.getItem(zE)}catch{return}const de=t$({bundle:"1.35.24",running:H,pending:Y,lastTried:oe});if(de==="reload"){try{window.sessionStorage.setItem(zE,H??"")}catch{return}window.location.reload();return}if(de!=="confirm")return;try{window.sessionStorage.removeItem("agent-dag.restartPending")}catch{}sr.current=!1,kn(!1),bi(H??null);const xe=window.setTimeout(()=>bi(null),6e3);return()=>window.clearTimeout(xe)},[K==null?void 0:K.running]),j.useEffect(()=>{if(zn&&r$({asked:Ms.current,reported:Ot})){try{window.sessionStorage.removeItem("agent-dag.restartPending")}catch{}sr.current=!1,kn(!1)}},[zn,Ot]);const Ps=j.useRef(Y5()).current;j.useRef(!1);const Tt=j.useRef(new Map(Ps.positions.filter(([H])=>Ps.pins.includes(H)))),xr=j.useRef(null),_r=j.useState(()=>K5())[0],[Kt,Kr]=j.useState(""),[Si,nt]=j.useState(()=>new Set),[br,Xr]=j.useState(E$),[Ls,Qr]=j.useState(!1),Zr=j.useRef(null);j.useEffect(()=>{document.documentElement.dataset.theme=br;try{window.localStorage.setItem(PC,br)}catch{}},[br]),j.useEffect(()=>{if(!_r)return;const H=window.setTimeout(()=>{try{e.setViewport(_r,{duration:0})}catch{}},60);return()=>window.clearTimeout(H)},[e,_r]);const $s=j.useRef(!0);j.useEffect(()=>{const H=new EventSource("/events"),Y=w$(i,{now:()=>Date.now(),setTimeout:(oe,de)=>window.setTimeout(oe,de),clearTimeout:oe=>window.clearTimeout(oe)});return H.addEventListener("open",()=>{G(!0),Qr(!0)}),H.addEventListener("error",()=>G(!1)),H.addEventListener("replay-end",()=>{$s.current=!1,Y.flush()}),H.addEventListener("hook",oe=>{try{const de=JSON.parse(oe.data);if(!vr.current.accept(de))return;n.current=zx(n.current,de),de.replay===!0||$s.current||Date.now()-de.receivedAt>3e4?Y.replay():Y.live()}catch{}}),()=>{H.close(),Y.cancel()}},[i]),j.useEffect(()=>{const H=setInterval(()=>{const Y=Date.now();_i(Y);let oe=gP(n.current,Y,Fx);vP(n.current,Y,Fx)&&(oe=!0),pP(n.current,Y,L5,$5)&&(oe=!0),mP(n.current,Y,q5,D5)&&(oe=!0),oe&&i()},250);return()=>clearInterval(H)},[i]);const ir=j.useRef(null),St=j.useRef(0),qs=420,pt=j.useCallback((H=500)=>{try{const Se=document.querySelector(".canvas-wrap"),Pe=Array.from(document.querySelectorAll(".react-flow__node")).filter(wt=>wt.offsetWidth>0);if(!Se||Pe.length===0)return;const Fe=Se.getBoundingClientRect(),Ge=e.getViewport();if(!Number.isFinite(Ge.zoom)||Ge.zoom<=0)return;const We=wt=>(wt-Fe.left-Ge.x)/Ge.zoom,ze=wt=>(wt-Fe.top-Ge.y)/Ge.zoom,Tn=Pe.map(wt=>wt.getBoundingClientRect()),Ys=Math.min(...Tn.map(wt=>We(wt.left))),Ao=Math.max(...Tn.map(wt=>We(wt.right))),Ks=Math.min(...Tn.map(wt=>ze(wt.top))),Io=Math.max(...Tn.map(wt=>ze(wt.bottom))),Xa=Ao-Ys,us=Io-Ks;if(!(Xa>0&&us>0))return;const Zt=Math.max(.2,Math.min(1,(Fe.width-160)/(Xa+qs)*.86,(Fe.height-160)/us*.86));e.setViewport({x:80-Ys*Zt,y:Math.max(80,(Fe.height-us*Zt)/2)-Ks*Zt,zoom:Zt},{duration:H}),St.current=Date.now(),window.setTimeout(()=>{try{const wt={x:80-Ys*Zt,y:Math.max(80,(Fe.height-us*Zt)/2)-Ks*Zt,zoom:Zt},Mo=e.getViewport();(Math.abs(Mo.zoom-Zt)>.01||Math.abs(Mo.x-wt.x)>2)&&e.setViewport(wt,{duration:0})}catch{}},H+60)}catch{}},[e]),ko=j.useRef(""),Eo=j.useRef(null),qa=j.useRef(0),Sr=j.useCallback(()=>{qa.current=Date.now()},[]),Jr="agent-dag.autoFitDisabled",gn=j.useRef((()=>{if(typeof window>"u")return!1;try{return window.localStorage.getItem(Jr)==="1"}catch{return!1}})()),[Ds,Da]=j.useState(gn.current),Fa=j.useCallback(()=>{if(!gn.current){gn.current=!0,Da(!0);try{window.localStorage.setItem(Jr,"1")}catch{}}},[]),No=j.useCallback(()=>{gn.current=!1,Da(!1);try{window.localStorage.removeItem(Jr)}catch{}pt(400)},[e,pt]);j.useEffect(()=>{const H=setInterval(()=>{if(gn.current||Date.now()-qa.current<800)return;const Y=n.current,oe=Date.now(),de=[];for(const We of Y.agents.values())Ov(We,oe)&&de.push({id:We.id});if(de.length===0)return;const xe=e.getViewport(),Se=window.innerWidth-360,Pe=window.innerHeight-52;let Fe=!1,Ge=!1;for(const{id:We}of de){const ze=or.current.get(We),Tn=Tt.current.get(We)??Xt.current.get(We);if(!ze||!Tn)continue;Ge=!0;const Ys=Tn.x*xe.zoom+xe.x,Ao=Tn.y*xe.zoom+xe.y,Ks=(Tn.x+ze.width)*xe.zoom+xe.x,Io=(Tn.y+ze.height)*xe.zoom+xe.y;if(Ks>0&&Ys<Se&&Io>0&&Ao<Pe){Fe=!0;break}}Ge&&!Fe&&pt(600)},1500);return()=>clearInterval(H)},[e]);const ki=j.useRef(!1),or=j.useRef(new Map),es=j.useRef(0),ec=j.useCallback(H=>{const Y=or.current;let oe=!1;for(const de of H.nodeInternals.values()){const xe=de.width,Se=de.height;if(xe==null||Se==null)continue;const Pe=Y.get(de.id);Pe?(Math.abs(Pe.height-Se)>4||Math.abs(Pe.width-xe)>4)&&(Y.set(de.id,{width:xe,height:Se}),oe=!0):(Y.set(de.id,{width:xe,height:Se}),oe=!0)}return oe&&(es.current+=1),es.current},[]),Ei=Ke(ec),[He,za]=j.useState(0);j.useEffect(()=>{let H=0;const Y=()=>{const de=or.current;let xe=!1;for(const Se of document.querySelectorAll(".react-flow__node[data-id]")){const Pe=Se.getAttribute("data-id");if(!Pe)continue;const Fe=Se.offsetWidth,Ge=Se.offsetHeight;if(!Fe||!Ge)continue;const We=de.get(Pe);(!We||Math.abs(We.width-Fe)>4||Math.abs(We.height-Ge)>4)&&(de.set(Pe,{width:Fe,height:Ge}),xe=!0)}xe&&za(Se=>Se+1)};if(ki.current)return;let oe=0;return document.visibilityState==="hidden"?oe=window.setTimeout(Y,32):H=requestAnimationFrame(Y),()=>{cancelAnimationFrame(H),window.clearTimeout(oe)}});const Xt=j.useRef(new Map(Ps.positions)),Co=j.useRef(new Set),Ni=j.useRef(""),kr=j.useMemo(()=>{const H=[];for(const Y of n.current.agents.values())Ov(Y,ut)&&H.push(Y.id+(Y.parentId?`>${Y.parentId}`:""));return H.sort(),`${H.join("|")}#sv${Ei}.${He}`},[n.current,n.current.lastSeq,ut,Ei,He]),ts=j.useRef(null);j.useEffect(()=>(ts.current!=null&&window.clearTimeout(ts.current),ts.current=window.setTimeout(()=>{fv(Xt.current,Tt.current)},1500),()=>{ts.current!=null&&window.clearTimeout(ts.current)}),[kr]),j.useEffect(()=>{if(ko.current===kr)return;const H=ko.current;if(ko.current=kr,!H||gn.current)return;Date.now()-St.current>1200&&pt(400),ir.current&&window.clearTimeout(ir.current),ir.current=window.setTimeout(()=>{gn.current||pt(500)},280)},[kr,e,pt]);const Fs=j.useMemo(()=>{if(o.size===0)return null;const H=new Set;for(const Y of o){const oe=Z5(n.current,Y);if(oe)for(const de of oe)H.add(de)}return H.size>0?H:null},[n.current,n.current.lastSeq,o]),Nn=j.useMemo(()=>c5(n.current,ut),[n.current,n.current.lastSeq,ut]),Bn=j.useRef(null),[vn,Un]=j.useState({w:0,h:0});j.useEffect(()=>{const H=Bn.current;if(!H||typeof ResizeObserver>"u")return;const Y=new ResizeObserver(oe=>{var xe;const de=(xe=oe[0])==null?void 0:xe.contentRect;de&&Un(Se=>Math.abs(Se.w-de.width)>40||Math.abs(Se.h-de.height)>40?{w:de.width,h:de.height}:Se)});return Y.observe(H),Un({w:H.clientWidth,h:H.clientHeight}),()=>Y.disconnect()},[]);const zs=j.useCallback(H=>{var oe,de;const Y=H.target;!(Y!=null&&Y.closest)||Y.closest(O5)!==H.currentTarget||(H.preventDefault(),(de=(oe=document.activeElement)==null?void 0:oe.blur)==null||de.call(oe))},[]),Bs=j.useRef(new Map),[Hn,tc]=j.useState(!1);j.useEffect(()=>{const H=window.setTimeout(()=>tc(!0),2500);return()=>window.clearTimeout(H)},[]);const[Ba,Er]=j.useState(!1),ar=j.useRef(null),[Ci,Us]=j.useState(!1),Ua=j.useCallback(()=>{ar.current&&(window.clearTimeout(ar.current),ar.current=null),Er(!1)},[]),nc=j.useCallback(H=>{H.length!==0&&queueMicrotask(()=>{Er(!0),ar.current&&window.clearTimeout(ar.current),ar.current=window.setTimeout(()=>Er(!1),P5+80)})},[]);j.useEffect(()=>()=>{ar.current&&window.clearTimeout(ar.current)},[]);const ns=vn.w>0?vn.w*.92:0,rs=vn.h>0?vn.h:0,{nodes:Qt,edges:Ti}=j.useMemo(()=>J5(n.current,ut,ns,rs,Tt.current,Kt,or.current,Bs.current,nc,Hn,Ci,Xt.current,Co.current,kr,Ni,o,Fs,Nn,b),[n.current,n.current.lastSeq,ut,ns,rs,Hn,Ci,Kt,kr,o,Fs,Nn,b,Yt]),Ha=j.useMemo(()=>{const H=new Map;for(const oe of Qt){const de=oe.data;if(!(de!=null&&de.sessionId)||de.exitAt!=null)continue;const xe=oe.width,Se=oe.height;if(xe==null||Se==null)continue;const Pe=oe.position.x,Fe=oe.position.y,Ge=Pe+xe,We=Fe+Se,ze=H.get(de.sessionId);ze?(ze.minX=Math.min(ze.minX,Pe),ze.minY=Math.min(ze.minY,Fe),ze.maxX=Math.max(ze.maxX,Ge),ze.maxY=Math.max(ze.maxY,We)):H.set(de.sessionId,{minX:Pe,minY:Fe,maxX:Ge,maxY:We})}const Y=[];for(const[oe,de]of H){const xe=de.maxX-de.minX+au*2,Se=de.maxY-de.minY+au*2;Y.push({id:`group:${oe}`,type:LT,position:{x:de.minX-au,y:de.minY-au},data:{sessionId:oe,w:xe,h:Se},width:xe,height:Se,style:{width:xe,height:Se},zIndex:-1,draggable:!0,selectable:!1,focusable:!1,deletable:!1,connectable:!1})}return Y},[Qt,ut]),rc=j.useMemo(()=>{const H=[...Ha,...Qt],Y=Bt.current;return!Y||Y.size===0?H:H.map(oe=>{const de=Y.get(oe.id);return de?{...oe,position:de}:oe})},[Ha,Qt,Fn]),Nr=j.useMemo(()=>{if(!Kt)return null;const H=new Set;for(const Y of n.current.agents.values())Nn.has(Y.id)&&DT(Y,Kt)&&H.add(Y.id);return H},[n.current,n.current.lastSeq,Kt,Nn]),Cn=j.useMemo(()=>T5(Kt,(Nr==null?void 0:Nr.size)??0,Nn.size),[Kt,Nr,Nn]),ss=j.useMemo(()=>{const H=new Set;for(const Y of n.current.agents.values())for(const oe of Y.tools)H.add(WT(oe.name));return Object.keys($v).filter(Y=>H.has(Y))},[n.current,n.current.lastSeq]);j.useEffect(()=>{if(ss.length<=1){Sn(!1);return}let H=0;const Y=()=>{const oe=bn.current;if(oe&&!document.hidden){const de=oe.getBoundingClientRect(),xe=Array.from(document.querySelectorAll(".react-flow__node, .tool-burst")).map(Pe=>Pe.getBoundingClientRect()),Se=f5(de,xe,8);Sn(Pe=>Pe===Se?Pe:Se)}H=window.setTimeout(Y,300)};return Y(),()=>window.clearTimeout(H)},[ss.length]);const is=j.useMemo(()=>{const H=new Map;for(const oe of n.current.agents.values())for(const de of oe.tools){if(!de.name.startsWith("mcp__"))continue;const xe=de.name.slice(5),Se=xe.indexOf("__"),Pe=Se>0?xe.slice(0,Se):xe;H.set(Pe,(H.get(Pe)??0)+1)}const Y=[];for(const[oe,de]of H){let xe=5381;for(let Se=0;Se<oe.length;Se++)xe=(xe<<5)+xe^oe.charCodeAt(Se);Y.push({server:oe,count:de,hue:Math.abs(xe)%360})}return Y.sort((oe,de)=>de.count-oe.count),Y},[n.current,n.current.lastSeq]),lr=j.useCallback(H=>{nt(Y=>{const oe=new Set(Y);return oe.has(H)?oe.delete(H):oe.add(H),oe})},[]),Rt=u?n.current.agents.get(u):null,os=h?Array.from(n.current.agents.values()).flatMap(H=>H.tools).find(H=>H.id===h)??null:null,To=j.useCallback(async()=>{try{await fetch("/api/clear",{method:"POST"})}catch{}n.current=Rv(),Tt.current.clear(),or.current.clear(),Xt.current.clear(),Ni.current="",UE(),m(),i()},[i,m]),Hs=j.useRef(S);Hs.current=S;const Ws=j.useRef(!1);Ws.current=os!=null||vt||N!=null||y!=null;const Vs=j.useCallback(H=>{const Y=o$(H,{confirmOpen:Hs.current,modalOpen:Ws.current});Y==="confirm"?k(!0):Y==="clear"&&(k(!1),To())},[To]),Lt=j.useCallback(()=>{Tt.current.clear(),Xt.current.clear(),Ni.current="",UE(),i(),window.setTimeout(()=>pt(500),80)},[i,e,pt]),Cr=j.useCallback(()=>pt(500),[pt]),as=j.useRef(Qt);as.current=Qt;const ls=j.useRef(u);ls.current=u;const Ro=j.useCallback(H=>{const Y=as.current,oe=l$(Y.map(Se=>({id:Se.id,x:Se.position.x,y:Se.position.y})),ls.current,H),de=oe?Y.find(Se=>Se.id===oe):void 0;if(!de)return;const xe=PE(document.activeElement);d(de.id,!1),window.setTimeout(()=>{try{e.fitView({padding:.35,duration:350,nodes:[de]})}catch{}St.current=Date.now(),xe&&M5(de.id)},30)},[d,e]),Ri=j.useCallback(H=>{d(H,!1),window.setTimeout(()=>{try{const Y=as.current.find(oe=>oe.id===H);Y&&e.fitView({padding:.3,duration:500,nodes:[Y]}),St.current=Date.now()}catch{}},60)},[d,e]);j.useEffect(()=>{const H=Y=>{var Fe,Ge,We;const oe=Y.target,de={tagName:oe==null?void 0:oe.tagName,isContentEditable:oe==null?void 0:oe.isContentEditable,role:(Fe=oe==null?void 0:oe.getAttribute)==null?void 0:Fe.call(oe,"role"),type:oe==null?void 0:oe.type};if(Y.key==="Escape"){const ze=LP({overlayOpen:Eu.depth()>0,typing:sy(de)});ze==="dismiss"?Eu.dismissTop():ze==="blur"?oe==null||oe.blur():(f$(de)&&(oe==null||oe.blur()),m());return}if(bC(Y))return;const xe=PE(oe)?(Ge=oe==null?void 0:oe.getAttribute)==null?void 0:Ge.call(oe,"data-id"):null,Se=xe&&as.current.some(ze=>ze.id===xe)?xe:null,Pe=c$(Y,Se);if(Pe.kind==="activate"){Y.preventDefault(),d(Pe.nodeId,Pe.additive);return}if(Pe.kind!=="node"&&!(Pe.nodeId==null&&HP(de))){if(Y.key==="/"){Y.preventDefault(),(We=Zr.current)==null||We.focus();return}Y.key===" "&&(Y.preventDefault(),Wr()),(Y.key==="c"||Y.key==="C")&&Vs("shortcut"),(Y.key==="r"||Y.key==="R")&&Lt(),(Y.key==="f"||Y.key==="F")&&Cr(),(Y.key==="l"||Y.key==="L")&&bt(),(Y.key==="h"||Y.key==="H")&&hn(ze=>!ze),(Y.key==="u"||Y.key==="U")&&z(ze=>!ze),(Y.key==="a"||Y.key==="A")&&Be.current.claude&&ht(),(Y.key==="j"||Y.key==="J")&&Ro(1),(Y.key==="k"||Y.key==="K")&&Ro(-1),(Y.key==="t"||Y.key==="T")&&Xr(ze=>ze==="dark"?"light":"dark")}};return window.addEventListener("keydown",H),()=>window.removeEventListener("keydown",H)},[Vs,Lt,Cr,m,d,Ro,Wr]);const Tr=n.current.agents.size,Gs=new Set(Array.from(n.current.agents.values()).map(H=>H.sessionId)).size,tn=j.useMemo(()=>e3(n.current.agents.values()),[n.current,n.current.lastSeq]),jo=j.useMemo(()=>t3(n.current.agents.values()),[n.current,n.current.lastSeq]),Wa=j.useRef(null);j.useEffect(()=>{const H=N$({waiting:tn.length,running:jo}),Y=Wa.current;if(Wa.current=H,(Y==null?void 0:Y.title)!==H.title&&(document.title=H.title),(Y==null?void 0:Y.icon)!==H.icon){const oe=document.querySelector('link[rel="icon"]');oe&&(oe.href=C$[H.icon])}},[tn.length,jo]);const[sc,ic]=j.useState(""),ji=R$(tn);j.useEffect(()=>{ic(H=>j$(H,ji))},[ji]);const nn=j.useMemo(()=>{let H=0,Y=0,oe=0,de=0,xe=0,Se=0,Pe=0,Fe=0,Ge=0;for(const We of n.current.agents.values()){H+=We.usage.inputTokens,Y+=We.usage.outputTokens,oe+=We.usage.cacheReadTokens,de+=We.usage.cacheCreateTokens;const ze=dn(We.usage,We.model);xe+=ze.total,Se+=ze.input,Pe+=ze.output,Fe+=ze.cacheRead,Ge+=ze.cacheWrite}return{inT:H,outT:Y,cacheR:oe,cacheC:de,sum:H+Y,cost:{total:xe,input:Se,output:Pe,cacheRead:Fe,cacheWrite:Ge}}},[n.current,n.current.lastSeq]);return g.jsxs("div",{className:"app",children:[g.jsx("a",{className:"skip-link",href:"#canvas",children:"Skip to the canvas"}),g.jsxs("header",{className:"topbar",children:[g.jsxs("div",{className:"brand",children:[g.jsx("span",{className:"logo"}),g.jsx("h1",{children:Gt}),ye?g.jsxs("button",{type:"button",className:"v stale",onClick:Ze,"aria-label":v5({...ye,open:ft}),title:ye.kind==="restart"?`Running v${ye.from}; v${ye.to} is installed on disk. Restart to pick it up.`:`Running v${ye.from}; v${ye.to} is on npm.`,children:["v",ye.from,g.jsx("span",{className:"v-dot","aria-hidden":!0})]}):(()=>{const H={running:(K==null?void 0:K.running)??"1.35.24",latest:K==null?void 0:K.latest,latestPending:K==null?void 0:K.latestPending,checkedAgo:K!=null&&K.checkedAt?Lv(ut-K.checkedAt):null,checkDisabled:K==null?void 0:K.checkDisabled,checking:ce};return g.jsxs("button",{type:"button",className:ce?"v checking":"v",onClick:()=>ve(!0),"aria-busy":ce||void 0,"aria-label":g5(H),title:m5(H),children:["v",H.running]})})()]}),Rt&&(()=>{const H=dn(Rt.usage,Rt.model),Y=Math.max(0,((Rt.endedAt??ut)-Rt.startedAt)/1e3),oe=Rt.state==="active"?ku(H.total,Y):null,de=o.size-1;return g.jsxs("button",{type:"button",className:"selected-ribbon",title:`Fit view to ${Rt.label}`,onClick:()=>{try{const xe=Qt.find(Se=>Se.id===Rt.id);xe&&e.fitView({padding:.35,duration:500,nodes:[xe]}),St.current=Date.now()}catch{}},children:[g.jsx("span",{className:`state-pill state-${Rt.state}`,children:Rt.state==="active"?"live":Rt.state}),g.jsx("span",{className:"selected-label",children:Rt.label}),H.total>0&&g.jsxs("span",{className:"selected-cost",children:[qe(H.total),oe?g.jsxs("span",{className:"selected-rate",children:[" · ",oe]}):null]}),de>0&&g.jsxs("span",{className:"selected-extra",children:["+",de]}),g.jsx("span",{"aria-hidden":!0,className:"selected-close",onClick:xe=>{xe.stopPropagation(),m()},children:"×"})]})})(),g.jsxs("div",{className:"actions",children:[g.jsxs("div",{className:"search",children:[g.jsx("span",{className:"search-icon","aria-hidden":!0,children:"⌕"}),g.jsx("input",{ref:Zr,type:"text",placeholder:R5,value:Kt,onChange:H=>Kr(H.target.value),spellCheck:!1,"aria-label":"Filter the graph"}),Kt?g.jsx("button",{className:"search-clear","aria-label":"Clear search",onClick:()=>Kr(""),children:"×"}):g.jsx("kbd",{className:"search-kbd","aria-hidden":!0,children:"/"}),Cn.count&&g.jsx("span",{className:`search-count${Cn.empty?" none":""}`,"aria-live":"polite",title:`${Cn.count} agents on the canvas match “${Kt}”`,children:Cn.count})]}),g.jsxs("span",{className:"status",children:[(()=>{const H=N5({connected:M,paused:Hr,held:vr.current.size});return g.jsx("span",{className:`pill ${H.tone}`,title:H.title,children:H.label})})(),g.jsxs("span",{className:"stat",title:b5(we),children:[g.jsx("span",{className:"count",children:Gs}),g.jsx("span",{className:"lbl",children:"sessions"})]}),g.jsxs("span",{className:"stat",title:"Total agents (root + subagents)",children:[g.jsx("span",{className:"count",children:Tr}),g.jsx("span",{className:"lbl",children:"agents"})]}),g.jsxs("span",{className:"stat",title:S5(we),children:[g.jsx("span",{className:"count",children:n.current.totalEvents}),g.jsx("span",{className:"lbl",children:"events"})]}),nn.sum>0&&g.jsxs("span",{className:"stat",title:`in:${nn.inT.toLocaleString()} out:${nn.outT.toLocaleString()} cache-r:${nn.cacheR.toLocaleString()} cache-c:${nn.cacheC.toLocaleString()}`,children:[g.jsx("span",{className:"count",children:Dt(nn.sum)}),g.jsx("span",{className:"lbl",children:"tokens"})]}),is.length>0&&g.jsxs("span",{className:"stat mcp-legend",title:`MCP servers seen this session:
73
73
  ${is.map(H=>` ${H.server}: ${H.count} call${H.count===1?"":"s"}`).join(`
74
74
  `)}`,children:[is.slice(0,6).map(H=>g.jsx("span",{className:"mcp-dot",style:{"--mcp-hue":H.hue}},H.server)),is.length>6&&g.jsxs("span",{className:"mcp-more",children:["+",is.length-6]}),g.jsx("span",{className:"lbl",children:"mcp"})]}),nn.cost.total>0&&(()=>{let H=0,Y=0;for(const xe of n.current.agents.values()){if(xe.state!=="active")continue;const Se=dn(xe.usage,xe.model);H+=Se.total,Y=Math.max(Y,((xe.endedAt??ut)-xe.startedAt)/1e3)}const oe=Y>0?ku(H,Y):null,de=`input ${qe(nn.cost.input)} + output ${qe(nn.cost.output)} + cache r ${qe(nn.cost.cacheRead)} + cache w ${qe(nn.cost.cacheWrite)}${oe?`
75
75
  active burn: ${oe}`:""}`;return g.jsxs("span",{className:"stat",title:de,children:[g.jsx("span",{className:"count",children:qe(nn.cost.total)}),g.jsxs("span",{className:"lbl",children:["cost",oe?` · ${oe}`:""]})]})})()]}),g.jsx("div",{className:"vis-hidden",role:"status","aria-atomic":"true",children:sc}),tn.length>0&&g.jsxs("button",{type:"button",className:"waiting-stat",onClick:()=>Ri(tn[0].id),title:`Blocked waiting for you — click to go to the one that has been stuck longest:
@@ -40,7 +40,7 @@
40
40
  document.documentElement.setAttribute("data-theme", stored === "light" ? "light" : "dark");
41
41
  })();
42
42
  </script>
43
- <script type="module" crossorigin src="/assets/index-jfKKRYet.js"></script>
43
+ <script type="module" crossorigin src="/assets/index-C6UkIHdv.js"></script>
44
44
  <link rel="stylesheet" crossorigin href="/assets/index-hLBidJXz.css">
45
45
  </head>
46
46
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-dag",
3
- "version": "1.35.23",
3
+ "version": "1.35.24",
4
4
  "description": "Live deck of Claude Code and Codex agents — watch tool calls, token spend and every Claude Code subagent on one calm canvas. Also available as npx ccdeck and npx agent-dag.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -66,6 +66,16 @@ let persistPath = null; // absolute path to events.jsonl, or null
66
66
  // same way. A session is recorded unless we have been told someone else owns
67
67
  // it, so a lone deck — and a deck the hook is too old to flag — still writes
68
68
  // everything.
69
+ //
70
+ // THIS COVERS THE CLAUDE SIDE ONLY, and that is worth stating because reading it
71
+ // as the general answer is what produced #447. The only thing that ever fills
72
+ // the set is noteLogWriter, called from handleEventIngest — a hook POST. Codex
73
+ // events are read off the rollout files inside this process and never reach an
74
+ // HTTP handler, and Codex hooks are not installed any more, so a Codex session
75
+ // id cannot get in here and writesLogFor answers "mine" for every one of them on
76
+ // every deck. The Codex half is decided by writesCodexLog in the watcher's scan
77
+ // loop instead, and every event derived from a rollout — including the memory
78
+ // scan's ContextObserved — has to carry that verdict explicitly.
69
79
  const foreignSessions = new Set(); // session ids another deck is logging
70
80
  const MAX_FOREIGN_SESSIONS = 512; // bound: insertion order = oldest first
71
81
 
@@ -738,8 +748,27 @@ const pendingCodexMemoryReads = new Set();
738
748
  * session happened first, on a panel whose whole purpose is to say what is in
739
749
  * the window. ContextModal says so in the slot those counts would have used;
740
750
  * see codex-approval.ts for the same move on a different unanswerable question.
751
+ *
752
+ * WHY `persist` IS A PARAMETER (#447). Every other event the rollout watcher
753
+ * produces goes out through emitCodexEvent, which carries the per-batch verdict
754
+ * of writesCodexLog: several decks tailing one rollout all DRAW it, and exactly
755
+ * one of them appends it to the events.jsonl they share. This function pushed
756
+ * with no opts at all, so pushEvent fell back to writesLogFor — and that answers
757
+ * from `foreignSessions`, a set only ever filled by noteLogWriter off an
758
+ * incoming hook POST marked `?persist=0`. A Codex rollout never touches an HTTP
759
+ * handler and Codex hooks are not installed any more (installer.mjs keeps the
760
+ * provider for uninstall only), so a Codex session id can never appear in that
761
+ * set and every deck answered "yes, mine" for this one event. The caller already
762
+ * holds the verdict for the whole batch, so it is threaded in rather than
763
+ * re-derived: recomputing it here would cost a second directory listing and
764
+ * could disagree with the roots and tool calls the same batch just emitted.
765
+ *
766
+ * Omitting the argument keeps the old behaviour — write. That is the same
767
+ * fail-safe writesCodexLog itself takes when a deck cannot find its own
768
+ * discovery record: a line written twice is recoverable, a deck that quietly
769
+ * records nothing is not.
741
770
  */
742
- function maybeResolveCodexMemory(sid, cwd) {
771
+ function maybeResolveCodexMemory(sid, cwd, persist) {
743
772
  if (!sid || !cwd) return;
744
773
  if (pendingCodexMemoryReads.has(sid)) return;
745
774
  const now = Date.now();
@@ -754,12 +783,16 @@ function maybeResolveCodexMemory(sid, cwd) {
754
783
  // would only ever overwrite a real one with nothing. A repo that grows its
755
784
  // first AGENTS.md mid-session is picked up by the next throttled pass.
756
785
  if (!memoryFiles.length) return;
786
+ // `persist` false means another deck tailing this same rollout was elected
787
+ // to record it. The event is still buffered and broadcast from here, so
788
+ // every deck's context modal lists the AGENTS.md files — it is only the
789
+ // second copy on disk that is dropped, exactly as emitCodexEvent does it.
757
790
  pushEvent({
758
791
  hook_event_name: "ContextObserved",
759
792
  session_id: sid,
760
793
  provider: "codex",
761
794
  context: { memoryFiles },
762
- }, "internal");
795
+ }, "internal", { persist });
763
796
  })
764
797
  .catch(() => {})
765
798
  .finally(() => pendingCodexMemoryReads.delete(sid));
@@ -1452,7 +1485,13 @@ async function codexScanOnce(firstRun) {
1452
1485
  // existing so a session the deck has decided not to draw does not cost a
1453
1486
  // directory walk, and repeated rather than done once at root creation so
1454
1487
  // an AGENTS.md written after the session started is still found (#399).
1455
- if (state.rootEmitted) maybeResolveCodexMemory(state.sid, state.cwd);
1488
+ //
1489
+ // Carries the same `persist` verdict as every emit in the loop above, and
1490
+ // for the same reason: this is one more event about this batch of appended
1491
+ // lines, and a batch whose roots and tool calls went to one deck's log
1492
+ // while its memory list went to every deck's is the split the election
1493
+ // exists to prevent (#447).
1494
+ if (state.rootEmitted) maybeResolveCodexMemory(state.sid, state.cwd, persist);
1456
1495
  }
1457
1496
 
1458
1497
  // Rollout files fall out of the newest-2-days listing and never come back,