pikiloom 0.4.14 → 0.4.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dashboard/dist/assets/AgentTab-CKoy_-w4.js +1 -0
  2. package/dashboard/dist/assets/{DirBrowser-B5hxg2zn.js → DirBrowser-DpbuN0OL.js} +1 -1
  3. package/dashboard/dist/assets/{ExtensionsTab-C2FAUsui.js → ExtensionsTab-ymr7K8dU.js} +1 -1
  4. package/dashboard/dist/assets/{IMAccessTab-CS-2-ENn.js → IMAccessTab-CaTtCn3l.js} +1 -1
  5. package/dashboard/dist/assets/{Modal-BF2CycPZ.js → Modal-DA-9kJxp.js} +1 -1
  6. package/dashboard/dist/assets/{Modals-BHYtxTUE.js → Modals-BkLIRnNK.js} +1 -1
  7. package/dashboard/dist/assets/Select-B0pZtuzF.js +1 -0
  8. package/dashboard/dist/assets/SessionPanel-CYQtZZNX.js +1 -0
  9. package/dashboard/dist/assets/{SystemTab-B_hq7KIo.js → SystemTab-B9TcGMzc.js} +1 -1
  10. package/dashboard/dist/assets/codex-C6EwIzap.png +0 -0
  11. package/dashboard/dist/assets/deepseek-DOQzDJ-4.ico +0 -0
  12. package/dashboard/dist/assets/hermes-ClPe1RPI.png +0 -0
  13. package/dashboard/dist/assets/{index-Dws-2k-J.js → index-BCYshErN.js} +3 -3
  14. package/dashboard/dist/assets/index-C5irxzzD.js +23 -0
  15. package/dashboard/dist/assets/logo-wordmark-B0Z6VgSZ.png +0 -0
  16. package/dashboard/dist/assets/logo-wordmark-light-D9FCWeOH.png +0 -0
  17. package/dashboard/dist/assets/playwright-GP3HuCap.ico +0 -0
  18. package/dashboard/dist/assets/qwen-DKVAROae.png +0 -0
  19. package/dashboard/dist/assets/shared-i_XUH0xm.js +1 -0
  20. package/dashboard/dist/index.html +1 -1
  21. package/dashboard/dist/logo.png +0 -0
  22. package/dist/agent/auto-update.js +99 -4
  23. package/dist/agent/drivers/claude.js +6 -26
  24. package/dist/agent/drivers/codex.js +4 -26
  25. package/dist/agent/drivers/gemini.js +4 -26
  26. package/dist/agent/drivers/hermes.js +4 -26
  27. package/dist/agent/index.js +1 -1
  28. package/dist/agent/session.js +16 -3
  29. package/dist/agent/stream.js +37 -3
  30. package/dist/bot/bot.js +18 -5
  31. package/dist/channels/telegram/bot.js +2 -2
  32. package/dist/channels/telegram/render.js +47 -1
  33. package/dist/core/constants.js +8 -0
  34. package/dist/dashboard/routes/models.js +9 -1
  35. package/dist/dashboard/routes/sessions.js +25 -0
  36. package/dist/dashboard/server.js +8 -0
  37. package/dist/model/index.js +1 -1
  38. package/dist/model/injector.js +42 -0
  39. package/dist/model/responses-bridge.js +129 -88
  40. package/package.json +1 -1
  41. package/dashboard/dist/assets/AgentTab-Ce9nOgKB.js +0 -1
  42. package/dashboard/dist/assets/Select--CwQ1vbY.js +0 -1
  43. package/dashboard/dist/assets/SessionPanel-D0h4d0Nw.js +0 -1
  44. package/dashboard/dist/assets/codex-DYadqqp0.png +0 -0
  45. package/dashboard/dist/assets/deepseek-BeYNZEk0.ico +0 -0
  46. package/dashboard/dist/assets/hermes-BAarh-tH.png +0 -0
  47. package/dashboard/dist/assets/index-jCpvbF9B.js +0 -23
  48. package/dashboard/dist/assets/logo-wordmark-FzeBAUsd.png +0 -0
  49. package/dashboard/dist/assets/logo-wordmark-light-snSpARTN.png +0 -0
  50. package/dashboard/dist/assets/playwright-BldPFZgC.ico +0 -0
  51. package/dashboard/dist/assets/qwen-xykkX0_y.png +0 -0
  52. package/dashboard/dist/assets/shared-D1ruCzXL.js +0 -1
@@ -0,0 +1,23 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/SessionPanel-CYQtZZNX.js","assets/react-vendor-C7Sl8SE7.js","assets/index-BCYshErN.js","assets/router-DHISdpPk.js","assets/index-FD86DEDF.css","assets/Modal-DA-9kJxp.js","assets/Select-B0pZtuzF.js","assets/DirBrowser-DpbuN0OL.js","assets/markdown-DxQYQFeH.js","assets/ExtensionsTab-ymr7K8dU.js"])))=>i.map(i=>d[i]);
2
+ import{c as E,a as J,u as je,i as mn,f as Lt,A as as,s as rn,S as pe,B as Je,g as Zt,w as ls,b as cs,E as Gt,C as on,d as ds,e as us,n as hs,h as Sn,j as Rt,k as Te,D as $t,l as ps,m as Cn,_ as Tn,T as xs,o as fs}from"./index-BCYshErN.js";import{j as e,r,a as an}from"./react-vendor-C7Sl8SE7.js";import{I as gs}from"./Select-B0pZtuzF.js";import{M as Wt,a as Bt}from"./Modal-DA-9kJxp.js";import{D as ms}from"./DirBrowser-DpbuN0OL.js";import{n as bs,r as vs,M as ln}from"./markdown-DxQYQFeH.js";import{WorkspaceExtensionsBody as js}from"./ExtensionsTab-ymr7K8dU.js";function ws({open:t,className:n}){return e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:E("shrink-0 text-fg-5/40 transition-transform duration-200",t&&"rotate-180",n),children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})}function Ye({open:t,onToggle:n,dot:s,label:a,preview:l,badge:d,collapsedContent:p,children:c,className:b}){return e.jsxs("div",{className:E("rounded-md border border-edge bg-panel overflow-hidden","shadow-[0_2px_8px_rgba(0,0,0,0.06)]",b),children:[e.jsxs("button",{onClick:n,className:"w-full flex items-center gap-2.5 px-3.5 py-2.5 text-left hover:bg-panel-h/40 transition-colors",children:[s&&e.jsx("span",{className:E("h-[7px] w-[7px] shrink-0 rounded-full",s.color,s.pulse&&"animate-pulse")}),e.jsx("span",{className:"text-[10.5px] font-semibold uppercase tracking-[0.14em] text-fg-5",children:a}),e.jsx("span",{className:"flex-1 min-w-0 overflow-hidden",children:l}),d,e.jsx(ws,{open:t})]}),!t&&p,t&&c&&e.jsx("div",{className:"border-t border-edge",children:c})]})}const ks=5e3,ys=15e3,_t=8,Pt=30,Ns=1,Qe=new Map,ve=new Map,qt=new Set,En=[];let Mt=0;function Qt(t){return typeof t=="number"&&Number.isFinite(t)}function Oe(t,n,s,a){for(t.delete(n),t.set(n,s);t.size>a;){const l=t.keys().next().value;if(!l)break;t.delete(l)}}function Ln(t,n){const s=t.get(n);return!s?.value||s.expiresAt<=Date.now()?null:(Oe(t,n,s,t===ve?Pt:_t),s.value)}function Mn(t){return{workdir:t.workdir,agent:t.agent,sessionId:t.sessionId,rich:t.rich??!0,lastNTurns:Qt(t.lastNTurns)?t.lastNTurns:void 0,turnOffset:Qt(t.turnOffset)?t.turnOffset:void 0,turnLimit:Qt(t.turnLimit)?t.turnLimit:void 0}}function cn(t){const n=Mn(t);return[n.workdir,n.agent,n.sessionId,n.rich?"rich":"plain",n.lastNTurns??"",n.turnOffset??"",n.turnLimit??""].join("::")}function In(){for(;Mt<Ns;){const t=En.shift();if(!t)return;Mt+=1,t().finally(()=>{Mt=Math.max(0,Mt-1),In()})}}async function Ss(t,n={}){const s=t;if(!n.force){const d=Ln(Qe,s);if(d)return d}const a=Qe.get(s);if(a?.promise)return a.promise;const l=J.getWorkspaceSessions(t,n.request).then(d=>(Oe(Qe,s,{value:d,expiresAt:d.ok?Date.now()+ks:0},_t),d)).finally(()=>{const d=Qe.get(s);d?.promise&&Oe(Qe,s,{value:d.value,expiresAt:d.expiresAt},_t)});return Oe(Qe,s,{value:a?.value,expiresAt:a?.expiresAt??0,promise:l},_t),l}function Cs(t,n={}){const s=cn(t),a=ve.get(s);return a?.value?.ok&&(n.allowStale||a.expiresAt>Date.now())?a.value:null}async function Ts(t,n={}){const s=Mn(t),a=cn(s);if(!n.force){const p=Ln(ve,a);if(p?.ok)return p}const l=ve.get(a);if(l?.promise)return l.promise;const d=J.getSessionMessages(s.workdir,s.agent,s.sessionId,{rich:s.rich,lastNTurns:s.lastNTurns,turnOffset:s.turnOffset,turnLimit:s.turnLimit},n.request).then(p=>(Oe(ve,a,{value:p,expiresAt:p.ok?Date.now()+ys:0},Pt),p)).finally(()=>{const p=ve.get(a);p?.promise&&Oe(ve,a,{value:p.value,expiresAt:p.expiresAt},Pt)});return Oe(ve,a,{value:l?.value,expiresAt:l?.expiresAt??0,promise:d},Pt),d}function Es(t){const n=cn(t);Cs(t)||qt.has(n)||ve.get(n)?.promise||(qt.add(n),En.push(async()=>{try{await Ts(t)}catch{}finally{qt.delete(n)}}),In())}const bt=new Map,en=new Set;let De=null,Ee=0,bn=!1,Xe=null,mt=500;const Ls=8e3;function Ms(t){const n=bt.get(t.type);if(n)for(const s of n)s(t)}function Is(){const t=window.location;return`${t.protocol==="https:"?"wss:":"ws:"}//${t.host}/ws`}function dn(){if(De)return;An();const t=new WebSocket(Is());t.onopen=()=>{const n=bn;if(bn=!0,mt=500,n)for(const s of en)s()},t.onmessage=n=>{try{const s=JSON.parse(n.data);if(s.type==="pong")return;Ms(s)}catch{}},t.onclose=()=>{De=null,Ee>0&&Rs()},t.onerror=()=>{},De=t}function As(){An(),De&&(De.close(),De=null)}function An(){Xe&&(clearTimeout(Xe),Xe=null)}function Rs(){Xe||(Xe=setTimeout(()=>{Xe=null,Ee>0&&dn()},mt),mt=Math.min(mt*2,Ls))}function _s(t,n){let s=bt.get(t);s||(s=new Set,bt.set(t,s)),s.add(n),Ee++,Ee===1&&dn()}function Ps(t,n){const s=bt.get(t);s&&(s.delete(n),s.size===0&&bt.delete(t)),Ee=Math.max(0,Ee-1),Ee===0&&As()}typeof document<"u"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&Ee>0&&!De&&(mt=500,dn())});function vn(t,n){const s=r.useRef(n);s.current=n,r.useEffect(()=>{if(!t)return;const a=l=>s.current(l);return _s(t,a),()=>Ps(t,a)},[t])}function Ws(t){const n=r.useRef(t);n.current=t,r.useEffect(()=>{const s=()=>n.current();return en.add(s),()=>{en.delete(s)}},[])}function eo(t){const n=t.richMessages?.length?t.richMessages:t.messages?.map(p=>({role:p.role,text:p.text,blocks:[{type:"text",content:p.text}]}))||[],s=$s(n),a=Math.max(t.window?.totalTurns??t.totalTurns??s.length,s.length),l=t.window?.endTurn??a,d=t.window?.startTurn??Math.max(0,l-s.length);return{turns:s,startTurn:d,endTurn:l,totalTurns:a,hasOlder:t.window?.hasOlder??d>0}}function to(t,n){const s=Math.max(0,t.startTurn-n.startTurn);return{turns:[...n.turns.slice(0,s),...t.turns],startTurn:n.startTurn,endTurn:t.endTurn,totalTurns:Math.max(t.totalTurns,n.totalTurns),hasOlder:n.hasOlder}}function no(t,n){if(n.startTurn<=t.startTurn)return n;const s=Math.max(0,n.startTurn-t.startTurn);return{turns:[...t.turns.slice(0,s),...n.turns],startTurn:t.startTurn,endTurn:n.endTurn,totalTurns:n.totalTurns,hasOlder:t.startTurn>0}}function Bs(t,n){const s=[t.text,n.text].filter(Boolean);return{role:t.role,text:s.join(`
3
+
4
+ `),blocks:[...t.blocks,...n.blocks],usage:n.usage??t.usage??null}}function $s(t){const n=[];let s={user:null,assistant:null};for(const a of t)if(a.role==="user"){if(s.assistant&&Rn(a.text))continue;(s.user||s.assistant)&&(n.push(s),s={user:null,assistant:null}),s.user=a}else s.assistant?s.assistant=Bs(s.assistant,a):s.assistant=a;return(s.user||s.assistant)&&n.push(s),n}const Os=new Set(["task-notification","system-reminder","persisted-output","local-command-stdout","local-command-caveat","local-command-stderr","ide_opened_file","ide_diagnostics","ide_selection","event","analysis","case_id","tool-use-id","output-file"]),Ds=["continued from a previous","summary below covers","earlier portion of the conversation","Summary:","Key Technical Concepts"];function Rn(t){const s=t.trim().match(/^<([a-z][a-z0-9_-]*)\b/i);return s&&Os.has(s[1].toLowerCase())?!0:Ds.some(a=>t.includes(a))}function _n(t,n){const s=t.split(`
5
+ `).filter(a=>a.trim());return s.length<=n?s.join(`
6
+ `):s.slice(-n).join(`
7
+ `)}function Fs(t){const n=String(t||"").trim().toLowerCase();return n?n.startsWith("interrupted by user")?"interrupted":n.startsWith("timed out")||n.startsWith("stopped before completion")||n.includes("max tokens")?"incomplete":"error":"error"}function Jt(t){return{id:`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,file:t,previewUrl:URL.createObjectURL(t)}}function Us(t){for(const n of t)URL.revokeObjectURL(n.previewUrl)}function Hs(t){if(!Number.isFinite(t)||t<=0)return"0 B";if(t<1024)return`${t} B`;const n=t/1024;if(n<1024)return`${n.toFixed(n>=100?0:1)} KB`;const s=n/1024;return`${s.toFixed(s>=100?0:1)} MB`}async function zs(t){if(typeof ClipboardItem>"u"||!navigator.clipboard?.write)return!1;try{return await navigator.clipboard.write([new ClipboardItem({[t.type||"image/png"]:t})]),!0}catch{return!1}}function Q(t,n=120){if(t==null)return"";const a=(typeof t=="string"?t:String(t)).replace(/\s+/g," ").trim();return a.length<=n?a:a.slice(0,Math.max(0,n-1))+"…"}function Ks(t){if(!t)return null;try{const n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function Pn(t){const n=String(t.toolName||"").trim()||"Tool",s=Ks(t.content);if(!s)return n;const a=Q(s.description,120);switch(n){case"Read":{const l=Q(s.file_path||s.path,140);return l?`Read ${l}`:"Read"}case"Edit":{const l=Q(s.file_path||s.path,140);return l?`Edit ${l}`:"Edit"}case"Write":{const l=Q(s.file_path||s.path,140);return l?`Write ${l}`:"Write"}case"Glob":{const l=Q(s.pattern||s.glob,120);return l?`Glob ${l}`:"Glob"}case"Grep":{const l=Q(s.pattern||s.query,120);return l?`Grep ${l}`:"Grep"}case"WebFetch":{const l=Q(s.url,120);return l?`WebFetch ${l}`:"WebFetch"}case"WebSearch":{const l=Q(s.query,120);return l?`WebSearch ${l}`:"WebSearch"}case"TodoWrite":return"Update plan";case"AskUserQuestion":{const d=(Array.isArray(s.questions)?s.questions:[])[0],p=Q(d?.question||s.question,120);return p?`Ask user: ${p}`:"Ask user"}case"Task":{const l=Q(s.description||s.prompt,120);return l?`Task: ${l}`:"Task"}case"Bash":{if(a)return`Bash: ${a}`;const l=Q(s.command,120);return l?`Bash: ${l}`:"Bash"}default:{const l=n.match(/^mcp__[^_]+__(.+)$/),d=l?l[1]:n;if(d==="im_send_file"){const c=Q(s.path,120);return c?`Send file: ${c}`:"Send file"}if(d==="im_list_files")return"List workspace files";if(a)return`${n}: ${a}`;const p=Q(s.file_path||s.path||s.command||s.query||s.pattern||s.url,120);return p?`${n}: ${p}`:n}}}function Vs(t){const n=(t.content||"").trim();if(!n)return"result";const s=n.split(`
8
+ `).map(a=>a.trim()).find(Boolean)||"";return s?Q(s,140):"result"}function Gs(t){const n=t.indexOf(":");if(n<=0)return null;const s=t.slice(0,n).trim(),a=t.slice(n+1).trim();return!s||!a?null:{agent:s,sessionId:a}}const gt=new Map;function qs(t,n){return`${t}:${n}`}function Qs(t){const n=(()=>{try{return new URL(t.baseURL).host.toLowerCase()}catch{return""}})();return n.includes("openrouter")?"openrouter":n.includes("anthropic")?"anthropic":n.includes("deepseek")?"deepseek":n.includes("googleapis")||n.includes("vertex")?"google":n.includes("openai.com")?"openai":n.includes("dashscope")||n.includes("qwen")||n.includes("aliyun")?"qwen":n.includes("volces")||n.includes("volcengine")||n.includes("doubao")?"doubao":n.includes("bigmodel")||n.includes("zhipu")||n.includes("z.ai")?"glm":n.includes("minimax")?"minimax":t.kind==="anthropic"?"anthropic":t.kind==="google"?"google":t.kind==="openai"?"openai":"custom"}const Js=r.memo(function({session:n,workdir:s,onStreamQueued:a,onSendStart:l,onSendTaskAssigned:d,onSessionChange:p,t:c,streamPhase:b,streamTaskId:v,queuedTaskIds:g,queuedTasks:j,pendingQueuedSends:T,onRecall:k,onSteer:I,onStopAll:L,editDraft:S,onEditDraftConsumed:R,onSelectionChange:D}){const[H,P]=r.useState(""),[A,F]=r.useState(!1),[z,ae]=r.useState(null),[ee,M]=r.useState(()=>new Set),[K,Le]=r.useState(()=>new Set),de=r.useRef({prompt:"",files:[]}),we=je(o=>o.agentStatus?.agents??null),[$,Fe]=r.useState(we||[]),[Me,et]=r.useState(""),[ke,vt]=r.useState(""),[ue,jt]=r.useState(""),[te,ne]=r.useState([]),[Ue,Ie]=r.useState(null),[He,tt]=r.useState(null),[se,le]=r.useState(null),[W,ye]=r.useState(null),[X,Ae]=r.useState(null),[Re,wt]=r.useState(void 0),[B,re]=r.useState("closed"),[xe,Ne]=r.useState(null),oe=r.useRef(null),_e=r.useRef(!1),nt=r.useRef(null),kt=r.useRef(null),ze=r.useRef(null),st=r.useRef([]),[rt,Se]=r.useState([]),[V,fe]=r.useState(!1),[Ce,ie]=r.useState(0),Pe=r.useRef(null),We=je(o=>o.refreshAgentStatus),[he,ot]=r.useState([]),[it,Ot]=r.useState([]),[yt,Dt]=r.useState({}),at=r.useCallback(async()=>{try{const[o,x,m]=await Promise.all([fetch("/api/models/providers").then(N=>N.json()),fetch("/api/models/profiles").then(N=>N.json()),fetch("/api/models/agents").then(N=>N.json())]);if(o?.ok&&Ot(o.providers||[]),x?.ok&&ot(x.profiles||[]),m?.ok){const N={};for(const _ of m.bindings||[])N[_.agent]=_.activeProfileId;Dt(N)}}catch{}},[]);r.useEffect(()=>{we?.length&&Fe(we)},[we]),r.useEffect(()=>{st.current=te},[te]);const Be=qs(n.agent||"",n.sessionId),Ke=r.useRef(Be);Ke.current=Be,r.useEffect(()=>{const o=gt.get(Be);return o&&(gt.delete(Be),o.text&&P(o.text),o.files.length&&ne(o.files.map(Jt))),()=>{const x=oe.current?.value||"",m=st.current.map(N=>N.file);for(const N of st.current)URL.revokeObjectURL(N.previewUrl);x||m.length?gt.set(Ke.current,{text:x,files:m}):gt.delete(Ke.current)}},[Be]);const lt=r.useRef({agent:n.agent||"",sessionId:n.sessionId});r.useEffect(()=>{const o=lt.current,x={agent:n.agent||"",sessionId:n.sessionId};lt.current=x,!(o.agent===x.agent&&mn(o.sessionId)&&!mn(x.sessionId))&&(et(""),vt(""),jt(""),le(null),ye(null),Ae(null),re("closed"))},[n.agent,n.sessionId]),r.useEffect(()=>{S!=null&&(P(S),R?.(),requestAnimationFrame(()=>{const o=oe.current;o&&(o.focus(),o.setSelectionRange(S.length,S.length))}))},[S,R]),r.useEffect(()=>{if(!s)return;let o=!1;return J.getSkills(s).then(x=>{!o&&x.ok&&Se(x.skills)}).catch(()=>{}),()=>{o=!0}},[s]);const ct=V?(()=>{const o=H.match(/^\/(\S*)$/);return o?o[1].toLowerCase():null})():null,ge=ct!==null?rt.filter(o=>o.name.toLowerCase().includes(ct)||o.label&&o.label.toLowerCase().includes(ct)):[];r.useEffect(()=>{ie(0)},[V,H]),r.useEffect(()=>{if(!V||!Pe.current)return;const o=Pe.current.querySelector(`[data-skill-idx="${Ce}"]`);o&&o.scrollIntoView({block:"nearest"})},[Ce,V]),r.useEffect(()=>{if(!V)return;const o=x=>{Pe.current?.contains(x.target)||oe.current?.contains(x.target)||fe(!1)};return document.addEventListener("mousedown",o),()=>document.removeEventListener("mousedown",o)},[V]),r.useEffect(()=>{if(B==="closed")return;const o=x=>{const m=x.target;ze.current?.contains(m)||document.getElementById("cascade-portal")?.contains(m)||(re("closed"),le(null),ye(null),Ae(null))};return document.addEventListener("mousedown",o),()=>document.removeEventListener("mousedown",o)},[B]),r.useLayoutEffect(()=>{if(B==="closed"||!ze.current){Ne(null);return}const o=ze.current.getBoundingClientRect();Ne({left:o.left,bottom:window.innerHeight-o.top+8})},[B]);const Nt=g&&g.length?g[0]:null;r.useEffect(()=>{z&&(Nt||b!==null&&b!=="queued")&&ae(null)},[b,z,Nt]),r.useEffect(()=>{const o=oe.current;o&&(o.style.height="auto",o.style.height=Math.min(o.scrollHeight,200)+"px")},[H]);const dt=r.useCallback(o=>{const x=Array.from(o||[]).filter(m=>m.type.startsWith("image/"));x.length&&ne(m=>[...m,...x.map(Jt)])},[]),St=r.useCallback(()=>{Ie(null),ne(o=>(Us(o),[]))},[]),i=r.useCallback(o=>{ne(x=>{const m=x.find(N=>N.id===o);return m&&URL.revokeObjectURL(m.previewUrl),x.filter(N=>N.id!==o)}),Ie(x=>x===o?null:x)},[]),u=r.useCallback(()=>{const o=H.trim(),x=te.map(q=>q.file);if(!o&&x.length===0||A)return;const m=Me||n.agent||$.find(q=>q.isDefault)?.agent||"";if(!m)return;const N=$.find(q=>q.agent===m)||null,_=!!n.agent&&m===n.agent,me=(ke||_&&n.model||""||N?.selectedModel||"").trim()||null,be=m==="gemini"?null:(ue||(_?Lt(m,n.thinkingEffort,n.workflowEnabled):"")||Lt(m,N?.selectedEffort,N?.workflowEnabled)||"").trim()||null,Z=m!==n.agent,Vt=Z?"":n.sessionId,rs=Z&&n.agent?n.agent:null,os=Z&&n.sessionId?n.sessionId:null;F(!0),de.current={prompt:o,files:x},P(""),gt.delete(Ke.current);const is=x.length?x.map(q=>URL.createObjectURL(q)):void 0;St(),l(o,is),a(),J.sendSessionMessage(s,m,Vt,o,{attachments:x,model:me,effort:be,previousAgent:rs,previousSessionId:os}).then(q=>{if(q.taskId&&(ae(q.taskId),d?.(q.taskId)),!q.ok)return;const ft=typeof q.sessionKey=="string"?Gs(q.sessionKey):null;ft&&(ft.agent!==n.agent||ft.sessionId!==n.sessionId)&&ft&&p?.({...ft,workdir:s})}).catch(()=>{}).finally(()=>F(!1))},[$,St,te,H,l,d,p,a,Me,ue,ke,A,n.agent,n.sessionId,s]),h=b==="streaming",f=(()=>{const o=[];return g&&g.length&&o.push(...g),b==="queued"&&v&&!o.includes(v)&&o.unshift(v),z&&!o.includes(z)&&(b==="queued"||!b)&&o.push(z),o})(),w=f[f.length-1]||null,y=f.length>0,C=y||h;r.useEffect(()=>{const o=x=>f.includes(x)||x===v;M(x=>{let m=!1;const N=new Set;for(const _ of x)o(_)?N.add(_):m=!0;return m?N:x}),Le(x=>{let m=!1;const N=new Set;for(const _ of x)o(_)?N.add(_):m=!0;return m?N:x})},[f,v]),r.useEffect(()=>{!y&&de.current.files.length&&(de.current={prompt:"",files:[]})},[y]);const G=r.useCallback(o=>{if(!ee.has(o)){if(M(x=>{const m=new Set(x);return m.add(o),m}),o===w){const x=de.current;x.prompt&&P(x.prompt),x.files.length&&ne(x.files.map(Jt)),de.current={prompt:"",files:[]}}k?.(o),o===z&&ae(null)}},[ee,w,z,k]),[O,Y]=r.useState(!1),ut=r.useCallback(async()=>{if(!(O||!L)){Y(!0);try{await L()}finally{Y(!1)}}},[O,L]),Vn=r.useCallback(o=>{K.has(o)||(Le(x=>{const m=new Set(x);return m.add(o),m}),I?.(o),o===z&&ae(null))},[K,z,I]),pn=r.useCallback(o=>{P(`/${o.name} `),fe(!1),requestAnimationFrame(()=>{const x=oe.current;x&&(x.focus(),x.setSelectionRange(x.value.length,x.value.length))})},[]),Gn=r.useCallback(o=>{P(o);const x=/^\/\S*$/.test(o)&&rt.length>0;fe(x)},[rt.length]),qn=o=>{if(V&&ge.length>0){if(o.key==="ArrowDown"){o.preventDefault(),ie(x=>(x+1)%ge.length);return}if(o.key==="ArrowUp"){o.preventDefault(),ie(x=>(x-1+ge.length)%ge.length);return}if(o.key==="Tab"||o.key==="Enter"&&!o.shiftKey&&!_e.current){o.preventDefault(),pn(ge[Ce]);return}if(o.key==="Escape"){o.preventDefault(),fe(!1);return}}o.key==="Enter"&&!o.shiftKey&&!_e.current&&(o.preventDefault(),u())},Qn=r.useCallback(o=>{const x=Array.from(o.clipboardData?.items||[]).filter(m=>m.kind==="file"&&m.type.startsWith("image/")).map(m=>m.getAsFile()).filter(m=>!!m);x.length&&(o.preventDefault(),dt(x))},[dt]),ce=Me||n.agent||$.find(o=>o.isDefault)?.agent||$.find(o=>o.installed)?.agent||$[0]?.agent||"",Ct=$.find(o=>o.agent===ce)||null,ht=se||ce,pt=$.find(o=>o.agent===ht)||Ct,Tt=r.useMemo(()=>{if(!pt)return[];const o=[];for(const m of pt.models||[])o.push({id:m.id,label:m.id,kind:"native",description:m.alias&&m.alias.toLowerCase()!==m.id.toLowerCase()?m.alias:void 0});const x=new Set(as[ht]||[]);for(const m of he){const N=it.find(me=>me.id===m.providerId);if(!N||!x.has(N.kind))continue;const _=m.name.trim().toLowerCase()!==m.modelId.trim().toLowerCase();o.push({id:m.modelId,label:m.name,kind:"profile",profileId:m.id,description:_?`${N.name} · ${m.modelId}`:N.name})}return o},[pt,ht,he,it]),Jn=r.useMemo(()=>Tt.findIndex(o=>o.kind==="profile"),[Tt]),Xn=yt[ht]||null,xn=!!n.agent&&ce===n.agent,xt=ke||xn&&n.model||""||Ct?.selectedModel||"",Et=ce==="gemini"?"":ue||(xn?Lt(ce,n.thinkingEffort,n.workflowEnabled):"")||Lt(ce,Ct?.selectedEffort,Ct?.workflowEnabled)||"";r.useEffect(()=>{D?.({model:xt||null,effort:Et||null})},[xt,Et,D]);const Yn=Gt[ht]||[],$e=Ue&&te.find(o=>o.id===Ue)||null,Zn=$e?{key:$e.id,url:$e.previewUrl,name:$e.file.name,size:$e.file.size,file:$e.file,onRemove:()=>i($e.id)}:He?{key:He,url:He}:null,fn=(!!H.trim()||te.length>0)&&!A&&!!ce,Ft=()=>{le(null),ye(null),Ae(null),wt(void 0)},Ut=r.useCallback(async(o,x,m)=>{const N=o==="gemini"?"":m||"";if(Re!==void 0)try{await fetch(`/api/models/agents/${o}/active`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({profileId:Re})}),at(),We()}catch{}et(o),vt(x),jt(N),Ft(),re("closed")},[Re,at,We]),es=()=>{B==="closed"?(Ft(),We(),at(),re("agent")):(Ft(),re("closed"))},Ht=se||ce,gn=Zt(Ht),zt=W??xt,Ve=X??Et,ts=zt?rn(zt):"",Ge=(()=>{const o=yt[Ht];return o?he.find(x=>x.id===o)??null:null})(),qe=Ge?it.find(o=>o.id===Ge.providerId)??null:null,ns=qe?Qs(qe):null,Kt=Ge&&Ge.name.trim().toLowerCase()!==Ge.modelId.trim().toLowerCase()?Ge.name:ts,ss=[gn.shortLabel,qe?qe.name:null,Kt||null,Ve?Ve.charAt(0).toUpperCase()+Ve.slice(1):null].filter(Boolean).join(" / ");return e.jsxs("div",{className:"shrink-0",ref:kt,children:[e.jsxs("div",{className:"max-w-[680px] mx-auto px-5 pb-4 pt-2",children:[C&&e.jsxs("div",{className:"mb-2 space-y-1.5",children:[h&&e.jsxs("div",{className:"flex items-center gap-2.5 rounded-lg border border-primary/20 bg-primary/[0.04] px-3.5 py-1.5 transition-colors",children:[e.jsx(pe,{className:"h-3 w-3 text-primary shrink-0"}),e.jsx("span",{className:"flex-1 min-w-0 text-[12px] font-medium text-fg-3 truncate",children:c("hub.running")}),e.jsxs("button",{onClick:ut,disabled:O,title:c("hub.stopHint"),className:"flex items-center gap-1 px-2 py-1 rounded-md text-[11px] font-medium text-fg-4 hover:text-err hover:bg-err/10 transition-colors disabled:opacity-30 disabled:pointer-events-none shrink-0",children:[O?e.jsx(pe,{className:"h-2.5 w-2.5"}):e.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"currentColor",children:e.jsx("rect",{x:"4",y:"4",width:"16",height:"16",rx:"2"})}),c("hub.stop")]})]}),f.map((o,x)=>{const m=x===f.length-1,N=f.length>1?`${c("hub.queued")} #${x+1}`:c("hub.queued"),_=T?.find(Z=>Z.taskId===o)||(m?T?.find(Z=>!Z.taskId):void 0),me=j?.find(Z=>Z.taskId===o)?.prompt||_?.prompt||null,be=_?.imageUrls?.length?_.imageUrls:[];return e.jsxs("div",{className:"flex items-center gap-2.5 rounded-lg border border-warn/25 bg-warn/[0.04] px-3.5 py-1.5 transition-colors",children:[e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-warn animate-pulse shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-0 flex items-center gap-2",children:[e.jsx("span",{className:"text-[12px] font-medium text-warn shrink-0",children:N}),be.length>0&&e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[be.slice(0,3).map((Z,Vt)=>e.jsx("button",{type:"button",onClick:()=>tt(Z),title:c("hub.previewImage"),className:"block h-5 w-5 shrink-0 overflow-hidden rounded border border-warn/30 transition-opacity hover:opacity-80",children:e.jsx("img",{src:Z,alt:"",className:"h-full w-full object-cover"})},`${Z}-${Vt}`)),be.length>3&&e.jsxs("span",{className:"text-[10px] text-fg-5/60",children:["+",be.length-3]})]}),me&&e.jsx("span",{className:"text-[11px] text-fg-5/60 truncate",children:me})]}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[e.jsxs("button",{onClick:()=>Vn(o),disabled:K.has(o),title:c("hub.steerHint"),className:"flex items-center gap-1 px-2 py-1 rounded-md text-[11px] font-medium text-fg-4 hover:text-blue-400 hover:bg-blue-400/10 transition-colors disabled:opacity-30 disabled:pointer-events-none",children:[K.has(o)?e.jsx(pe,{className:"h-2.5 w-2.5"}):e.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",children:e.jsx("polyline",{points:"9 6 15 12 9 18"})}),c("hub.steer")]}),e.jsxs("button",{onClick:()=>G(o),disabled:ee.has(o),title:c("hub.recallHint"),className:"flex items-center gap-1 px-2 py-1 rounded-md text-[11px] font-medium text-fg-4 hover:text-err hover:bg-err/10 transition-colors disabled:opacity-30 disabled:pointer-events-none",children:[ee.has(o)?e.jsx(pe,{className:"h-2.5 w-2.5"}):e.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",children:[e.jsx("path",{d:"M18 6 6 18"}),e.jsx("path",{d:"M6 6l12 12"})]}),c("hub.recall")]})]})]},o)})]}),e.jsxs("div",{className:"relative rounded-xl border border-edge/40 bg-panel shadow-sm transition-[border-color,box-shadow] duration-200 focus-within:border-fg-5/40 focus-within:shadow-md",children:[e.jsx("input",{ref:nt,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:o=>{dt(o.target.files),o.target.value=""}}),te.length>0&&e.jsx("div",{className:"px-3 pt-3",children:e.jsx("div",{className:"flex gap-2 overflow-x-auto pb-1",children:te.map(o=>e.jsxs("div",{className:"relative shrink-0",children:[e.jsxs("button",{type:"button",onClick:()=>Ie(o.id),title:c("hub.previewImage"),className:"group relative h-[72px] w-[72px] overflow-hidden rounded-lg border border-edge/30 bg-panel-alt/30",children:[e.jsx("img",{src:o.previewUrl,alt:o.file.name,className:"h-full w-full object-cover transition-transform duration-200 group-hover:scale-[1.03]"}),e.jsx("div",{className:"pointer-events-none absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/60 via-black/10 to-transparent px-1.5 pb-1 pt-3 text-left",children:e.jsx("div",{className:"truncate text-[8px] font-medium text-white/90 leading-tight",children:o.file.name})})]}),e.jsx("button",{type:"button",onClick:x=>{x.stopPropagation(),i(o.id)},title:c("hub.removeImage"),className:"absolute -right-1 -top-1 flex h-5 w-5 items-center justify-center rounded-full border border-white/10 bg-black/65 text-white/75 transition-colors hover:bg-black/80 hover:text-white",children:e.jsxs("svg",{width:"9",height:"9",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",children:[e.jsx("path",{d:"M18 6 6 18"}),e.jsx("path",{d:"M6 6l12 12"})]})})]},o.id))})}),V&&ge.length>0&&e.jsxs("div",{ref:Pe,className:"absolute bottom-full left-0 right-0 mb-1.5 z-50 max-h-[200px] overflow-y-auto rounded-xl border border-edge/40 bg-[var(--th-dropdown)] backdrop-blur-xl shadow-lg animate-in",children:[e.jsx("div",{className:"px-3 pt-2 pb-1 border-b border-edge/20",children:e.jsx("span",{className:"text-[10px] font-semibold text-fg-5 uppercase tracking-wider",children:c("hub.skills")})}),e.jsx("div",{className:"py-1",children:ge.map((o,x)=>e.jsxs("button",{"data-skill-idx":x,onMouseDown:m=>{m.preventDefault(),pn(o)},onMouseEnter:()=>ie(x),className:E("flex flex-col w-full px-3 py-1.5 text-left transition-colors",x===Ce?"bg-panel-h text-fg":"text-fg-3 hover:bg-panel-alt/50"),children:[e.jsxs("span",{className:"text-[12.5px] font-medium",children:["/",o.name]}),(o.label||o.description)&&e.jsx("span",{className:"text-[11px] text-fg-5 truncate",children:o.label||o.description})]},o.name))})]}),e.jsx("textarea",{ref:oe,value:H,onChange:o=>Gn(o.target.value),onPaste:Qn,onKeyDown:qn,onCompositionStart:()=>{_e.current=!0},onCompositionEnd:()=>{_e.current=!1},placeholder:c("hub.inputPlaceholder"),rows:1,className:"w-full resize-none bg-transparent px-4 pt-3 pb-1 text-[13.5px] text-fg outline-none placeholder:text-fg-5/25 leading-[1.6]",style:{maxHeight:200,overflow:H.split(`
9
+ `).length>6?"auto":"hidden"}}),e.jsxs("div",{className:"flex items-center gap-1.5 px-2.5 pb-2 pt-1",children:[e.jsx("button",{type:"button",onClick:()=>nt.current?.click(),title:c("hub.addImages"),className:"flex h-7 w-7 items-center justify-center rounded-lg text-fg-5/50 transition-colors hover:bg-panel-h/60 hover:text-fg-3",children:e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.1",strokeLinecap:"round",children:[e.jsx("path",{d:"M12 5v14"}),e.jsx("path",{d:"M5 12h14"})]})}),e.jsxs("button",{ref:ze,onClick:es,disabled:!$.length,title:$.length?ss:void 0,className:E("flex items-center gap-1.5 h-[28px] px-2.5 rounded-lg text-[11px] font-medium transition-all duration-200 select-none",B!=="closed"?"bg-panel-h border border-edge-h text-fg-3":"text-fg-5/60 hover:text-fg-4 hover:bg-panel-h/50 border border-transparent"),children:[$.length?e.jsx(Je,{brand:Ht,size:12}):e.jsx(pe,{className:"h-3 w-3"}),$.length?e.jsxs("span",{className:"flex items-center gap-1 max-w-[460px] min-w-0 truncate",children:[e.jsx("span",{className:"shrink-0",children:gn.shortLabel}),qe&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-fg-5/40 shrink-0",children:"/"}),e.jsx(Je,{brand:ns||"custom",size:12}),e.jsx("span",{className:"shrink-0 truncate max-w-[140px]",children:qe.name})]}),Kt&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-fg-5/40 shrink-0",children:"/"}),e.jsx("span",{className:"truncate",title:zt||void 0,children:Kt})]}),Ve&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-fg-5/40 shrink-0",children:"/"}),e.jsx("span",{className:"shrink-0",children:Ve.charAt(0).toUpperCase()+Ve.slice(1)})]})]}):e.jsx("span",{className:"max-w-[420px] truncate",children:c("hub.selectAgent")}),e.jsx("svg",{width:"9",height:"9",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:E("text-fg-5/30 transition-transform duration-200",B!=="closed"&&"rotate-180"),children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})]}),B!=="closed"&&xe&&an.createPortal(e.jsxs("div",{id:"cascade-portal",className:"fixed z-[200] w-[300px] rounded-xl border border-edge/40 bg-[var(--th-dropdown)] backdrop-blur-xl shadow-lg overflow-hidden animate-in",style:{left:xe.left,bottom:xe.bottom},children:[e.jsxs("div",{className:"flex items-center gap-2 px-3 pt-2.5 pb-1.5 border-b border-edge/20",children:[B!=="agent"&&e.jsx("button",{onClick:()=>{if(B==="effort"){const o=pt?.capabilities?.modelSwitch!==!1;re(o?"model":"agent")}else re("agent")},className:"p-0.5 rounded text-fg-5/50 hover:text-fg-3 transition-colors",children:e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",children:e.jsx("polyline",{points:"15 18 9 12 15 6"})})}),e.jsx("span",{className:"text-[10px] font-semibold text-fg-5 uppercase tracking-wider",children:c(B==="agent"?"hub.selectAgent":B==="model"?"hub.selectModel":"hub.selectEffort")}),e.jsx("div",{className:"ml-auto flex items-center gap-0.5",children:(()=>{const x=pt?.capabilities?.modelSwitch!==!1?["agent","model","effort"]:["agent","effort"],m=x.indexOf(B);return x.map((N,_)=>e.jsx("span",{className:E("w-1.5 h-1.5 rounded-full transition-colors",B===N?"bg-primary":_<m?"bg-primary/40":"bg-fg-5/15")},N))})()})]}),e.jsxs("div",{className:"max-h-[200px] overflow-y-auto py-1",children:[B==="agent"&&$.filter(o=>o.installed).map(o=>{const x=Zt(o.agent),m=ls(o.usage),N=m?cs(m):"ok";return e.jsxs(Xt,{selected:o.agent===(se||ce),onClick:()=>{if(le(o.agent),ye(o.selectedModel||""),Ae(o.selectedEffort||""),!(o.capabilities?.modelSwitch!==!1)){(Gt[o.agent]||[]).length?re("effort"):Ut(o.agent,o.selectedModel||"",null);return}re("model")},children:[e.jsx(Je,{brand:o.agent,size:14}),e.jsx("span",{style:{color:x.color},children:x.label}),m&&e.jsxs("span",{className:E("ml-auto font-mono text-[10px]",N==="err"?"text-err":N==="warn"?"text-warn":"text-fg-5"),children:[m.label," ",Math.round(m.usedPercent??0),"%"]})]},o.agent)}),B==="model"&&e.jsxs(e.Fragment,{children:[Tt.map((o,x)=>{const m=x===0&&o.kind==="native",N=x===Jn&&o.kind==="profile",_=Re!==void 0?Re:Xn,me=o.kind==="profile"?!!o.profileId&&o.profileId===_:!_&&o.id===(W??xt);return e.jsxs("div",{children:[m&&e.jsx("div",{className:"px-3 pb-1 pt-1.5 text-[10px] font-medium uppercase tracking-wide text-fg-5",children:c("hub.modelGroupNative")}),N&&e.jsx("div",{className:"px-3 pb-1 pt-2 text-[10px] font-medium uppercase tracking-wide text-fg-5",children:c("hub.modelGroupProfiles")}),e.jsx(Xt,{selected:me,onClick:()=>{const be=se||ce;if(ye(o.id),wt(o.profileId??null),Gt[be]?.length){re("effort");return}Ut(be,o.id,null)},children:e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:E("truncate text-[11.5px]",o.kind==="native"&&"font-mono text-[11px]"),title:o.id,children:o.label}),o.description&&e.jsx("div",{className:"truncate text-[10px] text-fg-5/80",children:o.description})]})})]},`${o.kind}:${o.profileId||o.id}`)}),Tt.length===0&&e.jsx("div",{className:"px-3 py-3 text-[11px] text-fg-5 text-center",children:c("config.noModel")})]}),B==="effort"&&Yn.map(o=>e.jsx(Xt,{selected:o===(X||Et),onClick:()=>{Ae(o),Ut(se||ce,W??xt,o)},children:o.charAt(0).toUpperCase()+o.slice(1)},o))]})]}),document.body),e.jsx("div",{className:"flex-1"}),e.jsx("button",{onClick:u,disabled:!fn,className:E("flex items-center justify-center w-[30px] h-[30px] rounded-lg transition-all duration-200",fn?"bg-primary text-primary-fg hover:brightness-110 shadow-sm":"bg-fg/6 text-fg-5/20"),children:A?e.jsx(pe,{className:"h-3.5 w-3.5"}):e.jsxs("svg",{width:"15",height:"15",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("line",{x1:"12",y1:"19",x2:"12",y2:"5"}),e.jsx("polyline",{points:"5 12 12 5 19 12"})]})})]})]})]}),e.jsx(Xs,{source:Zn,onClose:()=>{Ie(null),tt(null)},t:c})]})});function Xs({source:t,onClose:n,t:s}){const[a,l]=r.useState(!1);if(r.useEffect(()=>{l(!1)},[t?.key]),r.useEffect(()=>{if(!t)return;const c=b=>{b.key==="Escape"&&n()};return document.addEventListener("keydown",c),()=>document.removeEventListener("keydown",c)},[t,n]),!t)return null;const d=t.file,p=t.onRemove;return an.createPortal(e.jsx("div",{className:"fixed inset-0 z-[220] flex items-center justify-center bg-black/72 px-4 py-6 backdrop-blur-sm",onClick:n,children:e.jsxs("div",{className:"w-full max-w-[1024px]",onClick:c=>c.stopPropagation(),children:[e.jsxs("div",{className:"mb-3 flex items-center gap-2 text-[11px] text-white/72",children:[t.name&&e.jsx("span",{className:"truncate font-medium text-white/90",children:t.name}),typeof t.size=="number"&&e.jsx("span",{children:Hs(t.size)}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[d&&e.jsx("button",{type:"button",onClick:async()=>{await zs(d)&&(l(!0),window.setTimeout(()=>l(!1),1600))},className:"rounded-lg border border-white/12 bg-white/10 px-3 py-1.5 text-[11px] font-medium text-white/88 transition-colors hover:bg-white/14",children:s(a?"hub.copied":"hub.copyImage")}),p&&e.jsx("button",{type:"button",onClick:p,className:"rounded-lg border border-white/12 bg-white/10 px-3 py-1.5 text-[11px] font-medium text-white/88 transition-colors hover:bg-white/14",children:s("hub.removeImage")}),e.jsx("button",{type:"button",onClick:n,className:"flex h-9 w-9 items-center justify-center rounded-full border border-white/12 bg-white/10 text-white/88 transition-colors hover:bg-white/14",children:e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.2",strokeLinecap:"round",children:[e.jsx("path",{d:"M18 6 6 18"}),e.jsx("path",{d:"M6 6l12 12"})]})})]})]}),e.jsx("div",{className:"overflow-hidden rounded-xl border border-white/10 bg-black/35 shadow-[0_20px_70px_rgba(0,0,0,0.45)]",children:e.jsx("img",{src:t.url,alt:t.name||"",className:"max-h-[80vh] w-full object-contain"})})]})}),document.body)}function Xt({selected:t,onClick:n,children:s}){return e.jsxs("button",{onClick:n,className:E("flex items-center gap-2 w-full px-3 py-2 text-[12px] text-left transition-colors",t?"text-fg bg-panel-h font-medium":"text-fg-3 hover:bg-panel-alt/50 hover:text-fg-2"),children:[s,t&&e.jsx("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:"ml-auto text-ok",children:e.jsx("polyline",{points:"20 6 9 17 4 12"})}),!t&&e.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"ml-auto text-fg-5/20",children:e.jsx("polyline",{points:"9 6 15 12 9 18"})})]})}function Ys(){return function(t){bs(t)}}const un=[vs,Ys],Zs=t=>/^https?:\/\//.test(t),jn=t=>/^(\/|~\/|\.\.?\/)/.test(t);function er({text:t}){const[n,s]=r.useState(!1),a=()=>{navigator.clipboard.writeText(t).then(()=>{s(!0),setTimeout(()=>s(!1),2e3)}).catch(()=>{})};return e.jsx("button",{onClick:a,className:"flex items-center text-fg-5/50 hover:text-fg-3 transition-colors",children:n?e.jsx("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"#34d399",strokeWidth:"2",children:e.jsx("polyline",{points:"20 6 9 17 4 12"})}):e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[e.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2"}),e.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})})}function wn(t){const n=/^[.~/].*\.\w+$/.test(t)||/^[a-z][\w-]*\//.test(t),s=/^(npm |npx |git |python|pip |yarn |pnpm |cargo |go |make )/.test(t);return n?"bg-blue-500/8 border-blue-400/12 text-blue-300/90":s?"bg-amber-500/8 border-amber-400/10 text-amber-300/80":"bg-[rgba(255,255,255,0.06)] border-edge/20 text-fg-3"}const hn={h1:({children:t})=>e.jsx("h2",{className:"text-[16px] font-bold text-fg mt-4 mb-2",children:t}),h2:({children:t})=>e.jsx("h3",{className:"text-[14.5px] font-semibold text-fg mt-4 mb-1.5",children:t}),h3:({children:t})=>e.jsx("h4",{className:"text-[13.5px] font-semibold text-fg mt-3 mb-1",children:t}),p:({children:t})=>e.jsx("p",{className:"my-1.5 whitespace-pre-wrap break-words",children:t}),strong:({children:t})=>e.jsx("strong",{className:"font-semibold text-fg",children:t}),em:({children:t})=>e.jsx("em",{className:"italic text-fg-3",children:t}),a:({href:t,children:n})=>t&&Zs(t)?e.jsx("a",{href:t,target:"_blank",rel:"noopener noreferrer",className:"text-blue-400 underline underline-offset-2 decoration-blue-400/30 cursor-pointer hover:text-blue-300 transition-colors",children:n}):t&&jn(t)?e.jsx("span",{className:"text-blue-400 underline underline-offset-2 decoration-blue-400/30 cursor-pointer hover:text-blue-300 transition-colors",onClick:()=>J.openInEditor(t),children:n}):e.jsx("span",{className:"text-blue-400 underline underline-offset-2 decoration-blue-400/30",children:n}),ul:({children:t})=>e.jsx("ul",{className:"space-y-1 my-2 ml-1",children:t}),ol:({children:t})=>e.jsx("ol",{className:"space-y-1 my-2 ml-1 list-decimal list-inside",children:t}),li:({children:t})=>e.jsxs("li",{className:"flex gap-2 items-start",children:[e.jsx("span",{className:"shrink-0 mt-[10px] w-[5px] h-[5px] rounded-full bg-fg-5/40"}),e.jsx("span",{className:"flex-1",children:t})]}),blockquote:({children:t})=>e.jsx("blockquote",{className:"border-l-2 border-fg-5/30 pl-3 my-2 text-fg-4 italic",children:t}),hr:()=>e.jsx("hr",{className:"border-edge/30 my-4"}),code:({className:t,children:n,...s})=>{const a=String(n).replace(/\n$/,""),l=/language-(\w+)/.exec(t||"");if(!l&&!t&&!a.includes(`
10
+ `))return jn(a)?e.jsx("code",{className:E("px-1.5 py-[1px] rounded text-[12px] font-mono border cursor-pointer hover:brightness-125 transition-all",wn(a)),onClick:()=>J.openInEditor(a),children:a}):e.jsx("code",{className:E("px-1.5 py-[1px] rounded text-[12px] font-mono border",wn(a)),children:a});const d=l?.[1]||"";return e.jsxs("div",{className:"rounded-lg overflow-hidden border border-edge/30 bg-[rgba(0,0,0,0.25)] my-3 not-prose",children:[e.jsxs("div",{className:"flex items-center justify-between px-3.5 py-1.5 border-b border-edge/15 bg-[rgba(0,0,0,0.12)]",children:[e.jsx("span",{className:"text-[10px] font-mono text-fg-5/50",children:d||"text"}),e.jsx(er,{text:a})]}),e.jsx("pre",{className:"px-3.5 py-3 text-[12px] leading-[1.65] text-fg-3 font-mono whitespace-pre-wrap break-words overflow-x-auto",children:e.jsx("code",{children:a})})]})},pre:({children:t})=>e.jsx(e.Fragment,{children:t}),table:({children:t})=>e.jsx("div",{className:"my-3 overflow-x-auto rounded-lg border border-edge/30",children:e.jsx("table",{className:"w-full text-[12.5px]",children:t})}),thead:({children:t})=>e.jsx("thead",{className:"bg-[rgba(0,0,0,0.1)]",children:t}),th:({children:t})=>e.jsx("th",{className:"px-3 py-1.5 text-left font-semibold text-fg-3 border-b border-edge/30",children:t}),td:({children:t})=>e.jsx("td",{className:"px-3 py-1.5 text-fg-4 border-t border-edge/12",children:t}),tr:({children:t})=>e.jsx("tr",{className:"even:bg-[rgba(255,255,255,0.015)]",children:t})};function Ze(t){return!!t?.steps?.length}function tr(t,n){let s=t;for(const[a,l]of Object.entries(n))s=s.replace(new RegExp(`\\{${a}\\}`,"g"),l);return s}function nr({status:t}){return t==="completed"?e.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",className:"text-ok",children:e.jsx("polyline",{points:"20 6 9 17 4 12"})}):t==="inProgress"?e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-cyan-400 animate-pulse"}):e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-fg-5/25"})}function Wn({plan:t,t:n,className:s}){const[a,l]=r.useState(!1);if(!Ze(t))return null;const d=t.steps.length,p=t.steps.filter(v=>v.status==="completed").length,c=d>0&&p===d,b=tr(n("hub.planProgress"),{done:String(p),total:String(d)});return e.jsx(Ye,{open:a,onToggle:()=>l(v=>!v),dot:{color:c?"bg-emerald-400/60":"bg-cyan-400/60",pulse:!c},label:b,preview:t.explanation?e.jsx("span",{className:"text-[11.5px] text-fg-4 truncate",children:t.explanation}):void 0,badge:e.jsx("span",{className:E("rounded-md border px-1.5 py-0.5 text-[10px] font-mono",c?"border-ok/20 text-ok":"border-edge text-fg-5"),children:n(c?"hub.planDone":"hub.planInProgress")}),className:s,children:e.jsx("div",{className:"px-3.5 py-2.5 space-y-1",children:t.steps.map((v,g)=>{const j=v.status==="completed"?"text-fg-5 line-through decoration-fg-5/40":v.status==="inProgress"?"text-fg-3":"text-fg-4";return e.jsxs("div",{className:"flex items-center gap-2 py-[2px]",children:[e.jsx("span",{className:"shrink-0 flex items-center justify-center w-[10px]",children:e.jsx(nr,{status:v.status})}),e.jsx("span",{className:E("text-[12px] leading-[1.5]",j),children:v.step})]},`${g}:${v.step}`)})})})}function Bn(t){return!!t.text||!!t.thinking||!!(t.activity&&t.activity.split(`
11
+ `).filter(Boolean).length)||!!t.previewMeta?.toolCalls?.length||Ze(t.plan)||!!(t.subAgents&&t.subAgents.length)}function so(t){return Bn(t)||t.phase==="streaming"?!0:t.phase==="done"&&!!t.error}function sr(t){return t.phase!=="done"||!t.error?null:Bn(t)?"hub.streamErrored":"hub.streamFailed"}function rr({detail:t,t:n,className:s}){const a=Fs(t);if(a==="interrupted")return e.jsxs("div",{className:E("flex items-center gap-1.5 text-[11px] text-fg-5/55",s),children:[e.jsx("span",{className:"inline-block h-2 w-2 rounded-[2px] bg-fg-5/45 shrink-0"}),e.jsx("span",{children:n("hub.turnStopped")})]});const l=a==="error"?{dot:"bg-rose-400/55",text:"text-rose-300/65"}:{dot:"bg-fg-5/40",text:"text-fg-5/55"};return e.jsxs("div",{className:E("flex items-start gap-1.5 text-[11px] leading-[1.6]",l.text,s),children:[e.jsx("span",{className:E("mt-[5px] h-1 w-1 rounded-full shrink-0",l.dot)}),e.jsx("span",{className:"min-w-0 break-words",children:t})]})}const or=64;function ir(t,n){const[s,a]=r.useState(t),l=r.useRef(0),d=r.useRef(null);return r.useEffect(()=>{if(n<=0)return;const p=Date.now()-l.current,c=()=>{l.current=Date.now(),a(t)};return p>=n?c():(d.current&&clearTimeout(d.current),d.current=window.setTimeout(c,n-p)),()=>{d.current&&clearTimeout(d.current)}},[t,n]),n<=0?t:s}function ro({stream:t,t:n}){const s=Ze(t.plan),[a,l]=r.useState(!1),[d,p]=r.useState(!1),c=r.useRef(null),b=r.useRef(null),v=sr(t),g=r.useMemo(()=>(t.activity||"").split(`
12
+ `).filter(Boolean),[t.activity]),j=t.previewMeta?.toolCalls??[],T=g[g.length-1]||j[j.length-1]?.summary||"";r.useLayoutEffect(()=>{const S=c.current;S&&a&&(S.scrollTop=S.scrollHeight)},[a,t.activity,j.length]),r.useLayoutEffect(()=>{const S=b.current;S&&d&&(S.scrollTop=S.scrollHeight)},[d,t.thinking]);const k=t.subAgents??null,I=ir(t.text,t.phase==="streaming"?or:0),L=r.useMemo(()=>e.jsx(ln,{remarkPlugins:un,components:hn,children:I}),[I]);return e.jsxs("div",{className:"space-y-3 animate-in",children:[s&&e.jsx(Wn,{plan:t.plan,t:n,className:"mb-1 max-w-[760px]"}),k&&k.length>0&&k.map(S=>e.jsx($n,{sub:S,t:n},S.id)),(j.length>0||g.length>0)&&e.jsx(Ye,{open:a,onToggle:()=>l(S=>!S),dot:{color:"bg-cyan-400/60",pulse:!0},label:n("hub.activity"),preview:e.jsx("span",{className:"text-[12px] text-fg-4 truncate",children:T}),badge:(j.length||g.length)>1?e.jsx(on,{children:j.length||g.length}):void 0,children:e.jsx("div",{ref:c,className:"px-3.5 py-2.5 space-y-0.5 max-h-[280px] overflow-y-auto",children:j.length>0?j.map(S=>e.jsx(ar,{call:S},S.id)):g.map((S,R)=>e.jsxs("div",{className:"flex items-center gap-1.5 py-[2px]",children:[e.jsx("span",{className:"w-1 h-1 rounded-full shrink-0 bg-fg-5/30"}),e.jsx("span",{className:"text-[11px] font-mono text-fg-5/60 truncate",children:S})]},R))})}),t.thinking&&e.jsx(Ye,{open:d,onToggle:()=>p(S=>!S),dot:{color:"bg-violet-400/50",pulse:!0},label:n("hub.thinking"),collapsedContent:e.jsx("div",{className:"px-3.5 pb-2.5 -mt-0.5 text-[12px] text-fg-4 leading-[1.65] whitespace-pre-wrap break-words line-clamp-3",children:_n(t.thinking,3)}),children:e.jsx("div",{ref:b,className:"px-3.5 py-3 text-[12px] text-fg-4 leading-[1.7] whitespace-pre-wrap break-words max-h-[280px] overflow-y-auto",children:t.thinking})}),t.text&&e.jsxs("div",{className:"session-md text-[13.5px] leading-[1.75] text-fg-2",children:[L,t.phase==="streaming"&&e.jsx(tn,{className:"ml-1 inline-flex align-text-bottom text-fg-4"})]}),!t.text&&t.phase==="streaming"&&e.jsx("div",{className:"py-1",children:e.jsx(tn,{className:"text-fg-5"})}),t.phase==="streaming"&&(t.generatingImages??0)>0&&e.jsxs("div",{className:"flex items-center gap-2 text-[12px] text-fg-4",children:[e.jsxs("span",{className:"relative inline-flex items-center justify-center w-3 h-3",children:[e.jsx("span",{className:"absolute inline-flex w-3 h-3 rounded-full bg-cyan-400/40 animate-ping"}),e.jsx("span",{className:"relative inline-block w-1.5 h-1.5 rounded-full bg-cyan-400/80"})]}),e.jsx("span",{children:t.generatingImages===1?"Generating image…":`Generating ${t.generatingImages} images…`})]}),v&&t.error&&e.jsx(rr,{detail:t.error,t:n,className:"pt-0.5"})]})}function ar({call:t}){const[n,s]=r.useState(!1),a=!!(t.input||t.result),l=t.status==="failed"?"bg-rose-400/70":t.status==="running"?"bg-cyan-400/70":"bg-fg-5/30";return e.jsxs("div",{children:[e.jsxs("button",{type:"button",onClick:()=>a&&s(d=>!d),className:`flex w-full items-center gap-1.5 py-[2px] text-left min-w-0 ${a?"cursor-pointer hover:bg-white/[0.03] rounded":"cursor-default"}`,title:a?void 0:t.summary,children:[e.jsx("span",{className:`w-1 h-1 rounded-full shrink-0 ${l} ${t.status==="running"?"animate-pulse":""}`}),e.jsx("span",{className:"text-[11px] font-mono text-fg-5/60 truncate flex-1",children:t.summary}),a&&e.jsx("span",{className:`shrink-0 text-[9px] text-fg-5/40 transition-transform ${n?"rotate-90":""}`,children:"▸"})]}),n&&e.jsxs("div",{className:"ml-2.5 mt-0.5 mb-1 space-y-1 border-l border-white/[0.06] pl-2.5",children:[t.input&&e.jsx("pre",{className:"whitespace-pre-wrap break-words text-[10.5px] font-mono leading-[1.55] text-fg-4/80 max-h-[140px] overflow-y-auto",children:t.input}),t.result&&e.jsx("pre",{className:"whitespace-pre-wrap break-words text-[10.5px] font-mono leading-[1.55] text-fg-5/70 max-h-[140px] overflow-y-auto border-t border-white/[0.04] pt-1",children:t.result})]})]})}function tn({className:t}){return e.jsxs("span",{className:`thinking-dots inline-flex items-center gap-[3px] ${t||""}`,children:[e.jsx("span",{}),e.jsx("span",{}),e.jsx("span",{})]})}function $n({sub:t,t:n}){const[s,a]=r.useState(!1),l=t.status,d=l==="failed"?"bg-rose-400/60":l==="done"?"bg-emerald-400/55":"bg-amber-400/60",p=l==="running",c=t.tools,b=r.useMemo(()=>{const j=new Set,T=[];for(const k of c)j.has(k.name)||(j.add(k.name),T.push(k.name));return T},[c]),v=t.kind?`${n("hub.subAgent")||"Sub-agent"} · ${t.kind}`:n("hub.subAgent")||"Sub-agent",g=t.model?rn(t.model):null;return e.jsx(Ye,{open:s,onToggle:()=>a(j=>!j),dot:{color:d,pulse:p},label:v,preview:e.jsxs("span",{className:"flex items-center gap-1.5 min-w-0 text-[12px] text-fg-4",children:[t.description&&e.jsx("span",{className:"truncate",children:t.description}),g&&e.jsx("span",{className:"text-[10px] font-mono text-fg-5/55 shrink-0",children:g}),!t.description&&b.length>0&&e.jsx("span",{className:"font-mono text-fg-5/60 truncate",children:b.join(" · ")})]}),badge:c.length>0?e.jsx(on,{children:c.length}):void 0,children:e.jsxs("div",{className:"px-3.5 py-2.5 space-y-1 max-h-[260px] overflow-y-auto",children:[t.description&&e.jsx("div",{className:"mb-1.5 text-[12px] text-fg-3 leading-[1.55]",children:t.description}),c.length===0?e.jsxs("div",{className:"text-[11px] font-mono text-fg-5/50",children:["— ",n("hub.subAgentWaiting")||"waiting for first tool…"]}):c.map(j=>e.jsxs("div",{className:"flex items-center gap-1.5 py-[2px]",children:[e.jsx("span",{className:"w-1 h-1 rounded-full shrink-0 bg-fg-5/30"}),e.jsx("span",{className:"text-[11px] font-mono text-fg-5/65 truncate",children:j.summary})]},j.id))]})})}function lr({message:t,t:n}){const{activityBlocks:s,thinkingBlocks:a,planBlocks:l,subAgentBlocks:d,outputBlocks:p,noticeBlocks:c}=On(t.blocks),b=[...l].reverse().find(g=>Ze(g.plan));return s.length>0||d.length>0||!!b?.plan||a.length>0||p.length>0||c.length>0?e.jsxs("div",{className:"space-y-3",children:[s.length>0&&e.jsx(ur,{blocks:s,t:n}),d.map(g=>g.subAgent?e.jsx($n,{sub:g.subAgent,t:n},g.toolId||g.subAgent.id):null),b?.plan&&e.jsx(Wn,{plan:b.plan,t:n,className:"max-w-[760px]"}),a.length>0&&e.jsx(pr,{blocks:a,t:n}),p.length>0&&e.jsx(gr,{blocks:p,t:n}),c.length>0&&e.jsx(dr,{blocks:c,t:n})]}):null}function cr(t){const{activityBlocks:n,thinkingBlocks:s,planBlocks:a,subAgentBlocks:l,outputBlocks:d,noticeBlocks:p}=On(t.blocks);return d.length>0||n.length>0||l.length>0||s.length>0||a.some(c=>Ze(c.plan))||p.length>0}function On(t){const n=t.filter(s=>s.type==="plan"||s.type==="tool_use"||s.type==="tool_result"||s.type==="image"||s.type==="sub_agent"||!!s.content.trim());return{activityBlocks:n.filter(s=>s.type==="tool_use"||s.type==="tool_result"),thinkingBlocks:n.filter(s=>s.type==="thinking"),planBlocks:n.filter(s=>s.type==="plan"&&Ze(s.plan)),subAgentBlocks:n.filter(s=>s.type==="sub_agent"),outputBlocks:n.filter(s=>s.type==="text"||s.type==="image"),noticeBlocks:n.filter(s=>s.type==="system_notice")}}function dr({blocks:t,t:n}){const s=t.map(a=>a.content).filter(Boolean).join(`
13
+
14
+ `).trim();return s?e.jsxs("div",{className:"flex items-start gap-2 rounded-md border border-amber-500/30 bg-amber-500/[0.06] px-3 py-2 text-[12.5px] leading-[1.7] text-fg-3",children:[e.jsx("span",{className:"mt-[6px] h-1.5 w-1.5 rounded-full bg-amber-400/70 shrink-0"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-[11px] font-mono uppercase tracking-wide text-amber-300/80",children:n("hub.systemNotice")||"Agent notice"}),e.jsx("div",{className:"mt-0.5 break-words whitespace-pre-wrap",children:s})]})]}):null}function ur({blocks:t,t:n}){const[s,a]=r.useState(!1),l=t.filter(b=>b.type==="tool_use"),d=l.length,p=l[l.length-1],c=p?Pn(p):"";return e.jsx(Ye,{open:s,onToggle:()=>a(b=>!b),dot:{color:"bg-cyan-400/60"},label:n("hub.activity"),preview:e.jsx("span",{className:"text-[11.5px] font-mono text-fg-4 truncate",children:c}),badge:d>0?e.jsx(on,{children:d}):void 0,children:e.jsx("div",{className:"px-3.5 py-2.5 space-y-0.5",children:t.map((b,v)=>e.jsx(hr,{block:b},v))})})}function hr({block:t}){const[n,s]=r.useState(!1),a=t.type==="tool_use",l=a?Pn(t):Vs(t);return e.jsxs("div",{children:[e.jsxs("button",{onClick:()=>t.content&&s(d=>!d),className:E("flex items-center gap-2 py-[3px] w-full text-left group rounded-sm transition-colors",t.content&&"hover:bg-panel-h/30"),children:[e.jsx("span",{className:E("h-1.5 w-1.5 rounded-full shrink-0",a?"bg-fg-5/40":"bg-ok/40")}),e.jsx("span",{className:"text-[11px] font-mono text-fg-5/60 group-hover:text-fg-3 transition-colors truncate",children:l})]}),n&&t.content&&e.jsx("pre",{className:"ml-3 mt-1 mb-2 p-3 rounded-md bg-inset border border-edge text-[11px] leading-[1.6] text-fg-4 font-mono whitespace-pre-wrap break-words max-h-[240px] overflow-y-auto",children:t.content.length>3e3?t.content.slice(0,3e3)+`
15
+ …`:t.content})]})}function pr({blocks:t,t:n}){const[s,a]=r.useState(!1),l=r.useRef(null),d=t.map(c=>c.content).filter(Boolean).join(`
16
+
17
+ `).trim();if(!d)return null;const p=_n(d,3);return e.jsx(Ye,{open:s,onToggle:()=>a(c=>!c),dot:{color:"bg-violet-400/50"},label:n("hub.thinking"),collapsedContent:p?e.jsx("div",{className:"px-3.5 pb-2.5 -mt-0.5 text-[12px] text-fg-4 leading-[1.65] whitespace-pre-wrap break-words line-clamp-3",children:p}):void 0,children:e.jsx(xr,{scrollRef:l,text:d})})}function xr({scrollRef:t,text:n}){return r.useLayoutEffect(()=>{const s=t.current;s&&(s.scrollTop=s.scrollHeight)},[t]),e.jsx("div",{ref:t,className:"px-3.5 py-3 text-[12px] text-fg-4 leading-[1.7] whitespace-pre-wrap break-words max-h-[320px] overflow-y-auto",children:n})}function fr({block:t,onLightbox:n,t:s}){const a=t.imageCaption?.trim()||"",[l,d]=r.useState(!1);return e.jsxs("figure",{className:"flex flex-col gap-1.5 max-w-[400px]",children:[e.jsx("img",{src:t.content,alt:a||"",className:"max-w-[400px] max-h-[300px] rounded-md border border-fg-6/50 object-contain cursor-zoom-in hover:opacity-90 transition-opacity",onClick:()=>n(t.content)}),a&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{type:"button",onClick:()=>d(p=>!p),"aria-expanded":l,className:E("self-start inline-flex items-center gap-1 px-2 py-[3px] rounded-md","text-[11px] font-medium tracking-wide","border border-fg-6/40 bg-fg-6/[0.06] text-fg-3","hover:bg-fg-6/[0.12] hover:text-fg-2 hover:border-fg-6/60","transition-colors"),title:s(l?"hub.imagePromptHide":"hub.imagePromptShow"),children:[e.jsx("span",{"aria-hidden":!0,className:"text-[9px] leading-none",children:l?"▾":"▸"}),e.jsx("span",{children:s("hub.imagePrompt")})]}),l&&e.jsx("div",{className:"rounded-md border border-fg-6/30 bg-fg-6/[0.05] px-3 py-2 max-w-[400px] max-h-[260px] overflow-y-auto",children:e.jsx("div",{className:"text-[11.5px] leading-[1.65] text-fg-3 whitespace-pre-wrap break-words",children:a})})]})]})}function gr({blocks:t,t:n}){const s=t.filter(c=>c.type==="text"),a=t.filter(c=>c.type==="image"),l=s.map(c=>c.content).filter(Boolean).join(`
18
+
19
+ `),[d,p]=r.useState(null);return!l.trim()&&a.length===0?null:e.jsxs(e.Fragment,{children:[l.trim()&&e.jsx("div",{className:"session-md text-[13.5px] leading-[1.75] text-fg-2",children:e.jsx(ln,{remarkPlugins:un,components:hn,children:l})}),a.length>0&&e.jsx("div",{className:"flex flex-wrap gap-3 mt-2",children:a.map((c,b)=>e.jsx(fr,{block:c,onLightbox:p,t:n},b))}),d&&e.jsx(Dn,{src:d,onClose:()=>p(null)})]})}const oo=r.memo(function({turn:n,turnIndex:s,agent:a,meta:l,model:d,effort:p,providerName:c,t:b,onResend:v,onEdit:g,onFork:j}){const T=n.user&&Rn(n.user.text),k=j&&typeof s=="number"?()=>j(s):void 0,I=!!n.assistant&&cr(n.assistant);return e.jsxs("div",{className:"session-turn",children:[n.user&&!T&&e.jsx(Fn,{text:n.user.text,blocks:n.user.blocks,t:b,onResend:v,onEdit:g,onFork:k}),T&&n.user&&!n.assistant&&e.jsx("div",{className:"mb-4 px-4 py-3 rounded-lg bg-[rgba(255,255,255,0.02)] border border-edge/20 text-[12.5px] leading-[1.7] text-fg-4",children:e.jsx(ln,{remarkPlugins:un,components:hn,children:n.user.text})}),I&&e.jsxs(e.Fragment,{children:[e.jsx(jr,{agent:a,meta:l,model:d,effort:p,providerName:c,previewMeta:n.assistant.usage??null}),e.jsx("div",{className:"mb-6",children:e.jsx(lr,{message:n.assistant,t:b})})]})]})});function Dn({src:t,onClose:n}){return r.useEffect(()=>{const s=a=>{a.key==="Escape"&&n()};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[n]),an.createPortal(e.jsx("div",{className:"fixed inset-0 z-[9999] flex items-center justify-center bg-black/80 backdrop-blur-sm cursor-zoom-out",onClick:n,children:e.jsx("img",{src:t,className:"max-w-[90vw] max-h-[90vh] object-contain rounded-lg shadow-2xl",onClick:s=>s.stopPropagation()})}),document.body)}const mr=1500,br=16,kn=8;function vr(t){const n=t.split(`
20
+ `);return n.length<=kn?t:n.slice(0,kn).join(`
21
+ `)}function Fn({text:t,blocks:n,t:s,onResend:a,onEdit:l,onFork:d}){const[p,c]=r.useState(!1),[b,v]=r.useState(!1),[g,j]=r.useState(null),T=t?t.split(`
22
+ `).length:0,k=!!t&&(t.length>mr||T>br),[I,L]=r.useState(!1),S=t?k&&!I?vr(t):t:"",R=!!(a||l||d),D=n?.filter(A=>A.type==="image")||[],H=()=>{navigator.clipboard.writeText(t).then(()=>{v(!0),setTimeout(()=>v(!1),1500)}).catch(()=>{})},P=s("hub.expand").replace("{chars}",t?t.length.toLocaleString():"0").replace("{lines}",String(T));return e.jsxs("div",{className:"flex flex-col items-end mb-5 group/bubble",onMouseEnter:()=>c(!0),onMouseLeave:()=>c(!1),children:[e.jsxs("div",{className:"max-w-[72%] rounded-md border border-fg-6 bg-panel px-4 py-3 text-[13.5px] leading-[1.72] text-fg shadow-sm",children:[t&&e.jsxs("div",{className:"whitespace-pre-wrap break-words",children:[S,k&&!I&&e.jsx("span",{className:"text-fg-5/60",children:"…"})]}),k&&e.jsx("button",{type:"button",onClick:()=>L(A=>!A),className:"mt-2 text-[11.5px] text-fg-4 hover:text-fg-2 underline decoration-fg-5/40 underline-offset-2 transition-colors",children:I?s("hub.collapse"):P}),D.length>0&&e.jsx("div",{className:E("flex flex-wrap gap-2",t&&"mt-2"),children:D.map((A,F)=>e.jsx("img",{src:A.content,className:"max-w-[280px] max-h-[200px] rounded border border-fg-6/50 object-cover cursor-zoom-in hover:opacity-90 transition-opacity",onClick:()=>j(A.content)},F))})]}),g&&e.jsx(Dn,{src:g,onClose:()=>j(null)}),R&&e.jsxs("div",{className:E("flex items-center gap-1 mt-1.5 mr-1 transition-all duration-200",p?"opacity-100 translate-y-0":"opacity-0 -translate-y-1 pointer-events-none"),children:[e.jsx(It,{label:s(b?"hub.copied":"hub.copy"),onClick:H,children:b?e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"#34d399",strokeWidth:"2",children:e.jsx("polyline",{points:"20 6 9 17 4 12"})}):e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[e.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2"}),e.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})}),a&&e.jsx(It,{label:s("hub.rerun"),onClick:()=>a(t),children:e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[e.jsx("polyline",{points:"23 4 23 10 17 10"}),e.jsx("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"})]})}),l&&e.jsx(It,{label:s("hub.edit"),onClick:()=>l(t),children:e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[e.jsx("path",{d:"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"}),e.jsx("path",{d:"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"})]})}),d&&e.jsx(It,{label:s("hub.fork"),onClick:d,children:e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[e.jsx("circle",{cx:"6",cy:"6",r:"2"}),e.jsx("circle",{cx:"18",cy:"6",r:"2"}),e.jsx("circle",{cx:"12",cy:"20",r:"2"}),e.jsx("path",{d:"M6 8v3a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3V8"}),e.jsx("path",{d:"M12 14v4"})]})})]})]})}function It({label:t,onClick:n,children:s}){return e.jsx("button",{onClick:n,title:t,className:"flex items-center justify-center w-7 h-7 rounded border border-fg-6 bg-panel text-fg-4 shadow-sm hover:text-fg-2 hover:border-edge-h hover:bg-panel-h transition-colors",children:s})}function jr({agent:t,meta:n,model:s,effort:a,providerName:l,previewMeta:d,liveStartedAt:p}){const c=d?.contextPercent??null,b=d?.contextUsedTokens??0,v=d?.turnOutputTokens??0,g=c!=null||b>0||v>0,j=p!=null&&p>0,T=d?.providerName??l??null;return e.jsxs("div",{className:"flex items-center gap-1.5 mt-1 mb-3",children:[e.jsx(Je,{brand:t,size:13}),e.jsx("span",{style:{color:n.color},className:"text-[12px] font-semibold opacity-70",children:n.label}),(s||a)&&e.jsxs("span",{className:"text-[10px] font-mono text-fg-5/50",children:[s||"",s&&a?" · ":"",a||""]}),T&&e.jsxs("span",{className:"text-[10px] font-mono text-fg-5/70 px-1.5 py-px rounded bg-fg-5/8",title:`This turn is routed through ${T} (BYOK), not the agent CLI's native auth.`,children:["via ",T]}),(g||j)&&e.jsxs("span",{className:"ml-auto inline-flex items-center gap-1 text-[10px] font-mono text-fg-5/55",title:Nr(d),children:[c!=null&&e.jsx(Sr,{pct:c}),e.jsx("span",{children:c!=null?`${c.toFixed(1)}%`:""}),b>0&&e.jsxs("span",{className:"text-fg-5/40",children:["· ",yr(b)]}),v>0&&e.jsxs("span",{className:"text-fg-5/40",children:["· ↑",Un(v)]}),j&&e.jsx(wr,{startedAt:p,leadingDot:g})]})]})}function wr({startedAt:t,leadingDot:n}){const[,s]=r.useState(0);r.useEffect(()=>{const l=setInterval(()=>s(d=>d+1),1e3);return()=>clearInterval(l)},[]);const a=Math.max(0,Date.now()-t);return e.jsxs("span",{className:"text-fg-5/55 tabular-nums",title:"Elapsed time of the running turn",children:[n?"· ":"",kr(a)]})}function kr(t){const n=Math.floor(t/1e3);if(n<60)return`${n}s`;const s=Math.floor(n/60),a=n%60;return s<60?`${s}m${a.toString().padStart(2,"0")}s`:`${Math.floor(s/60)}h${(s%60).toString().padStart(2,"0")}m`}function yr(t){return`${Un(t)} tok`}function Un(t){return t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${(t/1e3).toFixed(1)}k`:`${t}`}function Nr(t){if(!t)return"";const n=[];return t.contextPercent!=null&&n.push(`Context: ${t.contextPercent.toFixed(1)}%`),t.inputTokens!=null&&n.push(`Input: ${t.inputTokens.toLocaleString()}`),t.turnOutputTokens!=null?n.push(`Output (turn): ${t.turnOutputTokens.toLocaleString()}`):t.outputTokens!=null&&n.push(`Output: ${t.outputTokens.toLocaleString()}`),t.cachedInputTokens!=null&&n.push(`Cached: ${t.cachedInputTokens.toLocaleString()}`),n.join(" · ")}function Sr({pct:t}){const n=t>=85?"bg-rose-400/70":t>=60?"bg-amber-400/70":"bg-emerald-400/70";return e.jsx("span",{className:`h-1.5 w-1.5 rounded-full ${n}`})}function yn(t,n,s){return t==="zh-CN"?n:s}function Cr({open:t,onClose:n,workdir:s}){const a=je(d=>d.locale),l=s.split("/").pop()||s;return e.jsxs(Wt,{open:t,onClose:n,wide:!0,children:[e.jsx(Bt,{title:yn(a,`${l} — 项目扩展`,`${l} — Project Extensions`),description:yn(a,"仅对当前工作区生效。直接操作项目目录中的 .mcp.json 与 .pikiloom/skills/。","Project-scoped only. Operates directly on .mcp.json and .pikiloom/skills/ in the workspace directory."),onClose:n}),t?e.jsx(js,{workdir:s}):null]})}let Nn=Tn(()=>import("./SessionPanel-CYQtZZNX.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9]));function nn(){return Nn??=Tn(()=>import("./SessionPanel-CYQtZZNX.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9])),Nn}const Tr=r.lazy(async()=>({default:(await nn()).SessionPanel})),Yt=5,Er=240,Lr=120,Mr=12,Ir=900*1e3,U=(t,n)=>`${t}:${n}`;function Ar(t){const n=new Map;for(const c of t)n.set(U(c.agent||"",c.sessionId),c);const s=new Map,a=new Set;for(const c of t){const b=c.migratedFrom;if(!b||b.kind!=="fork"||!b.sessionId)continue;const v=U(b.agent||c.agent||"",b.sessionId);n.has(v)&&(a.add(U(c.agent||"",c.sessionId)),s.has(v)||s.set(v,[]),s.get(v).push(c))}const l=[],d=new Set,p=(c,b)=>{const v=U(c.agent||"",c.sessionId);if(d.has(v))return;d.add(v),l.push(Object.assign({},c,{__forkDepth:b}));const g=s.get(v);if(g)for(const j of g)p(j,b+1)};for(const c of t){const b=U(c.agent||"",c.sessionId);a.has(b)||p(c,0)}for(const c of t)p(c,0);return l}let Rr=0;function At(){return`mk-${Date.now().toString(36)}-${(++Rr).toString(36)}`}function _r(t){return t==="vscode"||t==="cursor"||t==="windsurf"||t==="finder"||t==="default"}function Pr(t,n){const s=String(t||"").toLowerCase();return s.includes("cursor")?"cursor":s.includes("windsurf")?"windsurf":s.includes("code")||n==="darwin"?"vscode":"default"}function Hn(t){switch(t){case"cursor":return"hub.openTargetCursor";case"windsurf":return"hub.openTargetWindsurf";case"finder":return"hub.openTargetFinder";case"default":return"hub.openTargetDefault";default:return"hub.openTargetVsCode"}}const Wr=r.memo(function({active:n=!0}){const s=je(i=>i.locale),a=je(i=>i.state?.runtimeWorkdir??null),l=r.useMemo(()=>ds(s),[s]),[d,p]=r.useState([]),[c,b]=r.useState({}),[v,g]=r.useState({}),[j,T]=r.useState(!0),[k,I]=r.useState(()=>{try{const u=sessionStorage.getItem("pikiloom-layout-mode");if(u==="1"||u==="2"||u==="3"||u==="6")return Number(u)}catch{}const i=window.innerWidth;return i>=1920?3:i>=1280?2:1}),[L,S]=r.useState(()=>{try{const i=sessionStorage.getItem("pikiloom-open-sessions");if(i){const u=JSON.parse(i);if(Array.isArray(u))return u.map(h=>({...h,mountKey:h.mountKey||At()}))}}catch{}return[]}),[R,D]=r.useState(()=>{try{const i=sessionStorage.getItem("pikiloom-active-slot");if(i!=null){const u=Number(i);if(Number.isFinite(u)&&u>=0)return u}}catch{}return 0}),H=r.useCallback(i=>{I(i);try{sessionStorage.setItem("pikiloom-layout-mode",String(i))}catch{}},[]),P=r.useCallback(i=>{S(u=>{const h=typeof i=="function"?i(u):i;try{const f=h.map(({pendingPrompt:w,pendingImageUrls:y,...C})=>C);sessionStorage.setItem("pikiloom-open-sessions",JSON.stringify(f))}catch{}return h})},[]),A=r.useCallback(i=>{D(u=>{const h=typeof i=="function"?i(u):i;try{sessionStorage.setItem("pikiloom-active-slot",String(h))}catch{}return h})},[]);r.useEffect(()=>{P(i=>i.length>k?i.slice(0,k):i),A(i=>i>=k?k-1:i)},[k]);const[F,z]=r.useState(!1),ae=r.useRef(k);ae.current=k;const ee=r.useRef(R);ee.current=R;const M=r.useRef(-1),K=L[R]??null,Le=r.useCallback(i=>{if(!i){P([]),A(0);return}const u=i.mountKey?i:{...i,mountKey:At()};P(h=>{const f=h.findIndex(y=>y.agent===u.agent&&y.sessionId===u.sessionId);if(f>=0)return A(f),h;if(h.length<ae.current){const y=[...h,u];return A(y.length-1),y}const w=[...h];return w[ee.current]=u,w})},[]),[de,we]=r.useState(!1),[$,Fe]=r.useState(null),[Me,et]=r.useState(""),[ke,vt]=r.useState("all"),[ue,jt]=r.useState({}),te=r.useDeferredValue(Me),ne=r.useRef(!1),Ue=r.useRef({}),Ie=r.useRef(c);Ie.current=c;const He=r.useRef(ue);He.current=ue;const tt=r.useRef(new Set),se=r.useRef({});r.useEffect(()=>()=>{for(const i of Object.values(se.current))clearTimeout(i)},[]);const le=r.useCallback(async()=>{try{const i=await J.getWorkspaces(),u=i.ok?i.workspaces:[];u.length&&p(h=>h.length===u.length&&h.every((f,w)=>f.path===u[w].path&&f.name===u[w].name)?h:u),ne.current=!0}catch{ne.current=!0}finally{T(!1)}},[]);r.useEffect(()=>{le()},[le]);const W=r.useCallback(async(i,u={})=>{if(!Ue.current[i]){Ue.current[i]=!0,u.background||g(h=>({...h,[i]:!0}));try{const h=await Ss(i,{force:u.force});r.startTransition(()=>{b(f=>{const w=h.sessions||[],y=f[i]||[],C=new Set(w.map(O=>U(O.agent||"",O.sessionId))),G=y.filter(O=>{if(O.runState!=="running")return!1;const Y=U(O.agent||"",O.sessionId);if(C.has(Y))return!1;const ut=He.current[Y];return!(ut?.resolvedKey&&ut.resolvedKey!==Y)});return{...f,[i]:G.length?[...G,...w]:w}})})}catch{u.background||r.startTransition(()=>{b(h=>({...h,[i]:[]}))})}finally{Ue.current[i]=!1,u.background||g(h=>({...h,[i]:!1}))}}},[]),ye=r.useRef(a);r.useEffect(()=>{a!==ye.current&&(ye.current=a,!(!a||!ne.current)&&le().then(()=>{W(a,{force:!0})}))},[a,le,W]);const X=r.useCallback((i,u)=>{const h=i.agent||"";!h||!i.sessionId||(nn(),Es({workdir:u,agent:h,sessionId:i.sessionId,rich:!0,turnOffset:0,turnLimit:Mr}))},[]),Ae=r.useCallback((i,u,h=Lr)=>{const f=`${u}:${U(i.agent||"",i.sessionId)}`,w=se.current[f];w&&clearTimeout(w),se.current[f]=setTimeout(()=>{delete se.current[f],X(i,u)},h)},[X]),Re=r.useCallback((i,u)=>{const h=`${u}:${U(i.agent||"",i.sessionId)}`,f=se.current[h];f&&(clearTimeout(f),delete se.current[h])},[]);r.useEffect(()=>{n&&nn()},[n]),r.useEffect(()=>{if(!n)return;const i=[];return d.forEach((u,h)=>{if(c[u.path]||v[u.path])return;const f=setTimeout(()=>{W(u.path)},h*90);i.push(f)}),()=>{for(const u of i)clearTimeout(u)}},[n,W,v,c,d]);const wt=r.useRef(new Map);vn(n&&ne.current&&d.length>0?"sessions-changed":null,r.useCallback(i=>{if(typeof document<"u"&&document.visibilityState==="hidden")return;const u=i.key,h=u?d.filter(y=>(Ie.current[y.path]||[]).some(C=>U(C.agent||"",C.sessionId)===u)):d,f=h.length?h:d,w=wt.current;for(const y of f)w.has(y.path)&&clearTimeout(w.get(y.path)),w.set(y.path,setTimeout(()=>{w.delete(y.path),W(y.path,{background:!0,force:!0})},300))},[d,W]));const B=r.useCallback(i=>{const u=i.agent||"";return!u||!i.sessionId?i:us(i,ue[U(u,i.sessionId)]||null)},[ue]);vn("stream-update",r.useCallback(i=>{const u=i.key;u&&jt(h=>{const f={},w=Date.now()-Ir;for(const[C,G]of Object.entries(h))G.updatedAt>=w&&(f[C]=G);const y=hs(u,i.snapshot??null);if(!y){const C=f[u];return C&&C.phase!=="done"&&(f[u]={...C,phase:"done",updatedAt:Date.now()}),f}return f[u]=y,y.resolvedKey!==u&&(f[y.resolvedKey]={...y,key:y.resolvedKey}),f})},[])),Ws(r.useCallback(()=>{if(!(!n||!ne.current||d.length===0))for(const i of d)W(i.path,{background:!0,force:!0})},[n,d,W])),r.useEffect(()=>{if(!n||!ne.current||d.length===0)return;const i=()=>{if(!(typeof document<"u"&&document.visibilityState==="hidden"))for(const h of d)W(h.path,{background:!0,force:!0})};if(i(),typeof document>"u"||typeof window>"u")return;const u=()=>{document.visibilityState==="visible"&&i()};return document.addEventListener("visibilitychange",u),window.addEventListener("focus",u),()=>{document.removeEventListener("visibilitychange",u),window.removeEventListener("focus",u)}},[n,W,d]),r.useEffect(()=>{if(!n)return;const i=[];return d.forEach((u,h)=>{const f=(c[u.path]||[])[0];if(!f)return;const w=`${u.path}:${U(f.agent||"",f.sessionId)}`;if(tt.current.has(w))return;const y=setTimeout(()=>{tt.current.add(w),X(f,u.path)},Er+h*120);i.push(y)}),()=>{for(const u of i)clearTimeout(u)}},[n,c,X,d]);const re=r.useCallback(async i=>{try{(await J.addWorkspace(i)).ok&&(we(!1),await le(),W(i))}catch{}},[le,W]),[xe,Ne]=r.useState(null),[oe,_e]=r.useState(!1),[nt,kt]=r.useState(null),ze=r.useCallback(i=>{Ne(i)},[]),st=r.useCallback(async()=>{const i=xe;if(i){_e(!0);try{await J.removeWorkspace(i),p(u=>u.filter(h=>h.path!==i)),b(u=>{const h={...u};return delete h[i],h}),P(u=>u.filter(h=>h.workdir!==i)),A(0),Ne(null)}catch{}finally{_e(!1)}}},[xe]),rt=r.useCallback(i=>{W(i,{force:!0})},[W]),[Se,V]=r.useState(null),[fe,Ce]=r.useState(!1),[ie,Pe]=r.useState(!1),We=je(i=>i.toast),[he,ot]=r.useState(null),it=r.useCallback((i,u,h)=>{ot({anchor:{right:i.right,bottom:i.bottom},target:{workdir:h,agent:u.agent||"",sessionId:u.sessionId,title:Sn(u).slice(0,120)||u.sessionId.slice(0,16)}})},[]);r.useEffect(()=>{if(!he)return;const i=()=>ot(null),u=h=>{h.key==="Escape"&&i()};return window.addEventListener("mousedown",i),window.addEventListener("scroll",i,!0),window.addEventListener("resize",i),window.addEventListener("keydown",u),()=>{window.removeEventListener("mousedown",i),window.removeEventListener("scroll",i,!0),window.removeEventListener("resize",i),window.removeEventListener("keydown",u)}},[he]);const Ot=r.useCallback(i=>{Ce(!1),V(i),ot(null)},[]),yt=r.useCallback(async()=>{const i=Se;if(i){Pe(!0);try{const u=await J.deleteSession(i.workdir,i.agent,i.sessionId,fe);if(!u.ok){const h=u.error?.includes("still running")?l("session.deleteRunningError"):u.error||l("session.deleteFailed");We(h,!1);return}b(h=>{const f=h[i.workdir];if(!f)return h;const w=f.filter(y=>!(y.agent===i.agent&&y.sessionId===i.sessionId));return w.length===f.length?h:{...h,[i.workdir]:w}}),P(h=>h.filter(f=>!(f.workdir===i.workdir&&f.agent===i.agent&&f.sessionId===i.sessionId))),V(null)}catch(u){We(u?.message||l("session.deleteFailed"),!1)}finally{Pe(!1)}}},[Se,fe,l,We]),Dt=r.useCallback(i=>{P(u=>{let h=!1;const f=u.map(w=>w.mountKey===i&&(w.pendingPrompt!=null||w.pendingImageUrls)?(h=!0,{...w,pendingPrompt:null,pendingImageUrls:void 0}):w);return h?f:u})},[P]),at=r.useCallback((i,u,h)=>{X({agent:i.agent,sessionId:i.sessionId,runState:"running"},i.workdir),b(y=>{const C=y[i.workdir]||[];if(C.some(Y=>Y.sessionId===i.sessionId&&Y.agent===i.agent))return y;const O={sessionId:i.sessionId,agent:i.agent,runState:"running",lastQuestion:u,createdAt:new Date().toISOString(),runUpdatedAt:new Date().toISOString()};return{...y,[i.workdir]:[O,...C]}});const f=M.current,w={...i,mountKey:At(),pendingPrompt:u||null,pendingImageUrls:h&&h.length?h:void 0};r.startTransition(()=>{Fe(null),P(y=>{if(f>=y.length)return[...y,w];const C=[...y];return C[f]=w,C}),A(f>=0?f:0)}),W(i.workdir,{background:!0,force:!0})},[W,X,P,A]),Be=r.useCallback((i,u)=>{X(i,u),Fe(null),r.startTransition(()=>{Le({agent:i.agent||"",sessionId:i.sessionId,workdir:u})})},[X]),Ke=r.useCallback((i,u)=>{X({agent:i.agent,sessionId:i.sessionId,runState:"running"},i.workdir),r.startTransition(()=>{u!=null?(P(h=>{if(u>=h.length)return h;const f=[...h];return f[u]={...h[u],agent:i.agent,sessionId:i.sessionId,workdir:i.workdir},f}),A(u)):Le({...i,mountKey:At()})}),W(i.workdir,{background:!0,force:!0})},[W,X]),lt=r.useCallback(i=>{let u=i;if(ke==="running"?u=u.filter(h=>Rt(h)==="running"):ke==="review"&&(u=u.filter(h=>Rt(h)==="incomplete")),te.trim()){const h=te.toLowerCase();u=u.filter(f=>(f.lastMessageText||"").toLowerCase().includes(h)||(f.lastQuestion||"").toLowerCase().includes(h)||(f.lastAnswer||"").toLowerCase().includes(h)||(f.title||"").toLowerCase().includes(h)||(f.agent||"").toLowerCase().includes(h))}return u},[te,ke]),ct=r.useMemo(()=>{const i={};for(const u of d){const h=(c[u.path]||[]).map(B),f=new Map;for(const y of h){const C=U(y.agent||"",y.sessionId),G=ue[C],O=G?.resolvedKey&&G.resolvedKey!==C?G.resolvedKey:C,Y=f.get(O);if(!Y){f.set(O,y);continue}U(Y.agent||"",Y.sessionId)!==O&&C===O&&f.set(O,y)}const w=lt([...f.values()]);i[u.path]=Ar(w)}return i},[d,c,ue,lt,B]),ge=r.useCallback(i=>{const u=(c[i.workdir]||[]).find(h=>h.sessionId===i.sessionId&&h.agent===i.agent)??{sessionId:i.sessionId,agent:i.agent,runState:"running"};return B(u)},[B,c]),Nt=r.useMemo(()=>new Set(L.map(i=>U(i.agent,i.sessionId))),[L]),dt=K?U(K.agent,K.sessionId):null,St=r.useCallback(i=>{P(u=>{const h=u.filter((f,w)=>w!==i);return h.length===0?A(0):ee.current>=h.length&&A(h.length-1),h})},[]);return e.jsxs("div",{className:"h-full overflow-hidden p-4 flex gap-3 mx-auto",children:[e.jsxs("div",{className:"panel-isolated w-[252px] shrink-0 flex flex-col overflow-hidden rounded-xl border border-edge bg-panel backdrop-blur-sm",style:{boxShadow:"var(--th-card-shadow)"},children:[e.jsxs("div",{className:"px-3 pt-3 pb-2 space-y-2",children:[e.jsxs("div",{className:"relative group",children:[e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",className:"absolute left-2.5 top-1/2 -translate-y-1/2 text-fg-5/40 group-focus-within:text-fg-4 transition-colors",children:[e.jsx("circle",{cx:"11",cy:"11",r:"8"}),e.jsx("line",{x1:"21",y1:"21",x2:"16.65",y2:"16.65"})]}),e.jsx("input",{value:Me,onChange:i=>et(i.target.value),placeholder:l("hub.search"),className:"w-full rounded-lg border border-edge/40 bg-inset/50 pl-8 pr-7 py-1.5 text-[12px] text-fg outline-none placeholder:text-fg-5/30 focus:border-primary/30 focus:bg-inset focus:shadow-[0_0_0_3px_rgba(99,102,241,0.06)] transition-all duration-200"}),Me&&e.jsx("button",{onClick:()=>et(""),className:"absolute right-2 top-1/2 -translate-y-1/2 p-0.5 rounded text-fg-5/30 hover:text-fg-4 transition-colors",children:e.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:[e.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),e.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),e.jsx("div",{className:"flex items-center rounded-lg bg-inset/30 border border-edge/20 p-0.5",children:["all","running","review"].map(i=>e.jsx("button",{onClick:()=>vt(i),className:E("flex-1 px-2 py-[5px] rounded-md text-[11px] font-medium transition-all duration-200",ke===i?"bg-panel-h text-fg-2 shadow-[0_1px_2px_rgba(0,0,0,0.1),inset_0_1px_0_rgba(255,255,255,0.04)]":"text-fg-5/60 hover:text-fg-4"),children:l(`hub.filter${i[0].toUpperCase()+i.slice(1)}`)},i))})]}),e.jsx("div",{className:"flex-1 overflow-y-auto",children:j?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(pe,{className:"h-4 w-4 text-fg-5"})}):d.length===0&&!de?e.jsx("div",{className:"py-12 text-center text-[13px] text-fg-5",children:l("hub.noWorkspaces")}):d.map(i=>e.jsx(Dr,{workspace:i,sessions:ct[i.path]||[],loading:!!v[i.path]||!(i.path in c),isActive:i.path===a,selectedKey:dt,openSessionKeys:Nt,onSelectSession:Be,onNewSession:Fe,onRefresh:rt,onRemove:ze,onExtensions:kt,onWarmSession:Ae,onCancelWarmSession:Re,onSessionMenuOpen:it,t:l},i.path))}),e.jsxs("div",{className:"shrink-0 border-t border-edge/20 px-3 py-2 space-y-1.5",children:[e.jsx("div",{className:"flex items-center rounded-md bg-inset/30 border border-edge/20 p-0.5",children:[1,2,3,6].map(i=>e.jsx("button",{onClick:()=>H(i),className:E("flex-1 flex items-center justify-center p-1.5 rounded transition-all",k===i?"bg-panel-h text-fg-2 shadow-[0_1px_2px_rgba(0,0,0,0.1)]":"text-fg-5/40 hover:text-fg-4"),title:l(`hub.layout${i}`),children:i===1?e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e.jsx("rect",{x:"2",y:"2",width:"12",height:"12",rx:"1.5"})}):i===2?e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[e.jsx("rect",{x:"1",y:"2",width:"6",height:"12",rx:"1.5"}),e.jsx("rect",{x:"9",y:"2",width:"6",height:"12",rx:"1.5"})]}):i===3?e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[e.jsx("rect",{x:"0.5",y:"2",width:"4",height:"12",rx:"1"}),e.jsx("rect",{x:"6",y:"2",width:"4",height:"12",rx:"1"}),e.jsx("rect",{x:"11.5",y:"2",width:"4",height:"12",rx:"1"})]}):e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.2",children:[e.jsx("rect",{x:"0.5",y:"1",width:"4",height:"5.5",rx:"0.8"}),e.jsx("rect",{x:"6",y:"1",width:"4",height:"5.5",rx:"0.8"}),e.jsx("rect",{x:"11.5",y:"1",width:"4",height:"5.5",rx:"0.8"}),e.jsx("rect",{x:"0.5",y:"9.5",width:"4",height:"5.5",rx:"0.8"}),e.jsx("rect",{x:"6",y:"9.5",width:"4",height:"5.5",rx:"0.8"}),e.jsx("rect",{x:"11.5",y:"9.5",width:"4",height:"5.5",rx:"0.8"})]})},i))}),e.jsxs(Te,{variant:"ghost",size:"sm",onClick:()=>we(i=>!i),className:"w-full",children:[e.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",children:[e.jsx("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),e.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"})]}),l("hub.addWorkspace")]})]})]}),e.jsx("div",{className:"flex-1 min-w-0 flex flex-col overflow-hidden gap-0",children:e.jsx("div",{className:"flex-1 min-h-0 grid gap-3",style:{gridTemplateColumns:`repeat(${k===6?3:k}, 1fr)`,gridTemplateRows:k===6?"repeat(2, 1fr)":"1fr"},children:(()=>{const i=$?L.length<k?L.length:R:-1;return M.current=i,Array.from({length:k},(u,h)=>{if($&&h===i)return e.jsx("div",{className:"min-w-0 overflow-hidden rounded-xl border border-edge bg-panel flex flex-col",style:{boxShadow:"var(--th-card-shadow)"},children:e.jsx($r,{workdir:$,workspaceName:d.find(C=>C.path===$)?.name||$.split("/").pop()||"",onSessionCreated:at,onClose:()=>Fe(null),t:l},$)},`new-${$}`);const f=L[h]??null;if(!f)return e.jsx("div",{className:"min-w-0 overflow-hidden rounded-xl border border-dashed border-edge/40 bg-panel/30 flex items-center justify-center",children:e.jsxs("div",{className:"text-center px-4",children:[e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",className:"mx-auto text-fg-5/20 mb-2",children:[e.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2"}),e.jsx("line",{x1:"12",y1:"8",x2:"12",y2:"16"}),e.jsx("line",{x1:"8",y1:"12",x2:"16",y2:"12"})]}),e.jsx("div",{className:"text-[12px] text-fg-5/40",children:l("hub.emptySlot")})]})},`empty-${h}`);const w=ge(f),y=h===R;return e.jsxs("div",{className:E("min-w-0 overflow-hidden rounded-xl border bg-panel flex flex-col transition-[border-color,box-shadow] duration-200",y?"border-primary/40 ring-[3px] ring-primary/[0.06]":"border-edge hover:border-edge-h"),style:{boxShadow:y?"var(--th-card-shadow), 0 0 0 1px rgba(14,165,233,0.08)":"var(--th-card-shadow)"},onClick:()=>A(h),children:[e.jsxs("div",{className:E("shrink-0 flex items-center gap-2 px-2.5 h-8 border-b border-edge/30",y?"bg-primary/[0.03]":"bg-panel/60"),children:[(()=>{const C=Rt(w);return e.jsx($t,{variant:C==="running"?"ok":C==="waiting"?"info":C==="incomplete"?"warn":"idle",pulse:C==="running"||C==="waiting"})})(),e.jsxs("div",{className:"flex-1 min-w-0 flex items-center gap-0",children:[e.jsx("span",{className:"shrink-0 text-[10px] font-medium text-fg-5",children:f.workdir.split("/").pop()||f.workdir}),e.jsx("span",{className:"shrink-0 text-fg-6 text-[10px] mx-1",children:"/"}),e.jsx("span",{className:"min-w-0 truncate text-[11px] font-medium text-fg-3",children:w.title||w.lastQuestion?.slice(0,60)||f.sessionId.slice(0,12)})]}),e.jsxs("div",{className:"shrink-0 flex items-center gap-2.5 pl-4 text-[9px] text-fg-5/50 tabular-nums",children:[e.jsx("span",{title:l("hub.created"),children:ps(w.createdAt)}),w.runUpdatedAt&&e.jsx("span",{title:l("hub.updated"),children:Cn(w.runUpdatedAt)}),!!w.numTurns&&e.jsxs("span",{className:"flex items-center gap-0.5",children:[e.jsx("svg",{width:"9",height:"9",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",className:"opacity-60",children:e.jsx("path",{d:"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"})}),w.numTurns]}),e.jsx("button",{"data-filetree-toggle":!0,onClick:C=>{C.stopPropagation(),z(G=>!G)},className:E("p-0.5 rounded transition-colors",F?"text-fg-3 bg-panel-h":"text-fg-5/40 hover:text-fg-3 hover:bg-panel-h"),title:l("hub.files"),children:e.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",children:e.jsx("path",{d:"M2 6a2 2 0 012-2h5l2 2h9a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"})})}),e.jsx("button",{onClick:C=>{C.stopPropagation(),St(h)},className:"p-0.5 rounded text-fg-5/40 hover:text-fg-2 hover:bg-panel-h transition-colors",title:l("hub.closePanel"),children:e.jsxs("svg",{width:"9",height:"9",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:[e.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),e.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]})]}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(r.Suspense,{fallback:e.jsx("div",{className:"h-full"}),children:e.jsx(Tr,{session:w,workdir:f.workdir,active:n&&y,onSessionChange:C=>Ke(C,h),initialPendingPrompt:f.pendingPrompt??null,initialPendingImageUrls:f.pendingImageUrls,onPendingPromptConsumed:()=>Dt(f.mountKey)},f.mountKey)})})]},f.mountKey||U(f.agent,f.sessionId))})})()})}),F&&K&&e.jsx(Ur,{workdir:K.workdir,onClose:()=>z(!1),t:l}),e.jsx(Br,{open:de,initialPath:a||void 0,onAdd:re,onClose:()=>we(!1),t:l}),e.jsxs(Wt,{open:!!xe,onClose:()=>!oe&&Ne(null),children:[e.jsx(Bt,{title:l("hub.removeWorkspace"),onClose:()=>!oe&&Ne(null)}),e.jsx("div",{className:"text-[13px] text-fg-3 leading-relaxed",children:l("modal.confirmRemoveWorkspace")}),e.jsx("div",{className:"mt-1 text-[12px] text-fg-5",children:l("modal.confirmRemoveWorkspaceHint")}),xe&&e.jsx("div",{className:"mt-3 rounded-md bg-inset/50 border border-edge/30 px-3 py-2 font-mono text-[11px] text-fg-4 break-all",children:xe}),e.jsxs("div",{className:"flex justify-end gap-2 mt-4",children:[e.jsx(Te,{variant:"ghost",onClick:()=>Ne(null),disabled:oe,children:l("modal.cancel")}),e.jsx(Te,{variant:"primary",onClick:st,disabled:oe,className:"!bg-red-500/90 !border-red-500/50 hover:!bg-red-500 !text-white",children:l(oe?"modal.removing":"modal.remove")})]})]}),he&&(()=>{const u=Math.max(8,Math.min(he.anchor.right-160,window.innerWidth-160-8)),h=Math.min(he.anchor.bottom+4,window.innerHeight-60);return e.jsx("div",{className:"fixed z-[60] min-w-[160px] rounded-md border border-edge bg-panel/95 backdrop-blur-md py-1",style:{left:u,top:h,boxShadow:"0 8px 24px rgba(0,0,0,0.20), 0 2px 6px rgba(0,0,0,0.10)"},onMouseDown:f=>f.stopPropagation(),role:"menu",children:e.jsxs("button",{type:"button",role:"menuitem",onClick:()=>Ot(he.target),className:"w-full flex items-center gap-2 px-3 py-1.5 text-left text-[12px] text-fg-2 hover:bg-panel-h/60 hover:text-red-400 transition-colors",children:[e.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("polyline",{points:"3 6 5 6 21 6"}),e.jsx("path",{d:"M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6"}),e.jsx("path",{d:"M10 11v6"}),e.jsx("path",{d:"M14 11v6"}),e.jsx("path",{d:"M9 6V4a2 2 0 012-2h2a2 2 0 012 2v2"})]}),l("session.delete")]})})})(),e.jsxs(Wt,{open:!!Se,onClose:()=>!ie&&V(null),children:[e.jsx(Bt,{title:l("session.deleteTitle"),onClose:()=>!ie&&V(null)}),e.jsx("div",{className:"text-[13px] text-fg-3 leading-relaxed",children:l("session.deleteHint")}),Se&&e.jsxs("div",{className:"mt-3 rounded-md bg-inset/50 border border-edge/30 px-3 py-2 text-[11px] text-fg-4 break-all",children:[e.jsx("span",{className:"font-mono text-fg-5",children:Se.agent}),e.jsx("span",{className:"mx-1.5 text-fg-5/50",children:"·"}),e.jsx("span",{children:Se.title})]}),e.jsxs("div",{className:"mt-4 space-y-2",children:[e.jsxs("label",{className:"flex items-start gap-2 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"delete-session-scope",checked:!fe,onChange:()=>Ce(!1),disabled:ie,className:"mt-0.5"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"text-[12px] text-fg-2",children:l("session.deletePikiloomOnly")}),e.jsx("div",{className:"text-[11px] text-fg-5 leading-snug mt-0.5",children:l("session.deletePikiloomOnlyHint")})]})]}),e.jsxs("label",{className:"flex items-start gap-2 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"delete-session-scope",checked:fe,onChange:()=>Ce(!0),disabled:ie,className:"mt-0.5"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"text-[12px] text-fg-2",children:l("session.deletePurgeNative")}),e.jsx("div",{className:"text-[11px] text-fg-5 leading-snug mt-0.5",children:l("session.deletePurgeNativeHint")})]})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-4",children:[e.jsx(Te,{variant:"ghost",onClick:()=>V(null),disabled:ie,children:l("modal.cancel")}),e.jsx(Te,{variant:"primary",onClick:yt,disabled:ie,className:"!bg-red-500/90 !border-red-500/50 hover:!bg-red-500 !text-white",children:l(ie?"session.deleting":"modal.remove")})]})]}),e.jsx(Cr,{open:!!nt,onClose:()=>kt(null),workdir:nt||""})]})});function Br({open:t,initialPath:n,onAdd:s,onClose:a,t:l}){const[d,p]=r.useState(""),c=r.useCallback(b=>p(b),[]);return r.useEffect(()=>{t&&p("")},[t]),e.jsxs(Wt,{open:t,onClose:a,children:[e.jsx(Bt,{title:l("hub.addWorkspace"),onClose:a}),e.jsx(ms,{initialPath:n,maxHeight:360,minHeight:200,onSelect:c,t:l}),e.jsxs("div",{className:"flex gap-2 mt-4",children:[e.jsx(Te,{disabled:!d,onClick:()=>d&&s(d),className:"flex-1",children:l("hub.add")}),e.jsx(Te,{variant:"secondary",onClick:a,className:"flex-1",children:l("hub.cancel")})]})]})}function $r({workdir:t,workspaceName:n,onSessionCreated:s,onClose:a,t:l}){const[d,p]=r.useState(null),[c,b]=r.useState([]),v=r.useRef(null),g=r.useRef([]),j=r.useMemo(()=>({sessionId:"",agent:"",runState:"completed"}),[]),T=r.useCallback(()=>{},[]),k=r.useCallback((S,R)=>{p(S||null),v.current=S||null;const D=R||[];b(D),g.current=D},[]),I=r.useCallback(S=>{const R=g.current;g.current=[],s(S,v.current||void 0,R.length?R:void 0)},[s]),L=!!d||c.length>0;return e.jsxs("div",{className:"flex flex-col h-full overflow-hidden",children:[e.jsxs("div",{className:"shrink-0 flex items-center gap-2 px-4 h-10 border-b border-edge/50 bg-panel/40 backdrop-blur-md z-10",children:[e.jsx("span",{className:"flex-1 min-w-0 text-[13px] font-medium text-fg truncate",children:l("hub.newSession")}),e.jsxs("span",{className:"flex items-center gap-1 text-[10px] text-fg-5/60 shrink-0",children:[e.jsx("svg",{width:"9",height:"9",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",className:"opacity-60",children:e.jsx("path",{d:"M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z"})}),e.jsx("span",{className:"max-w-[80px] truncate",children:n})]}),e.jsx($t,{variant:L?"ok":"idle",pulse:L}),!L&&e.jsx("button",{onClick:a,className:"p-1 rounded text-fg-5 hover:text-fg-2 transition-colors",children:e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),e.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),e.jsx("div",{className:"flex-1 overflow-y-auto",children:L?e.jsxs("div",{className:"max-w-[900px] mx-auto px-6 py-6 space-y-0",children:[e.jsx(Fn,{text:d||"",blocks:c.map(S=>({type:"image",content:S})),t:l}),e.jsx("div",{className:"mt-3 mb-4 animate-in",children:e.jsx(tn,{className:"text-fg-5"})})]}):e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx("div",{className:"text-center space-y-1.5",children:e.jsx("div",{className:"text-[13px] text-fg-5",children:l("hub.newSessionHint")})})})}),e.jsx(Js,{session:j,workdir:t,onStreamQueued:T,onSendStart:k,onSessionChange:I,t:l,streamPhase:null})]})}function Or({git:t}){if(!t)return null;const n=[t.detached?`detached HEAD${t.shortSha?` @ ${t.shortSha}`:""}`:`branch ${t.branch??"?"}`,t.upstream?`upstream ${t.upstream}`:t.detached?"":"no upstream",t.ahead||t.behind?`↑${t.ahead} ahead · ↓${t.behind} behind`:"",t.changed>0?`${t.changed} changed (${t.staged} staged · ${t.unstaged} unstaged · ${t.untracked} untracked)`:"clean"].filter(Boolean).join(`
23
+ `);return e.jsx(xs,{content:n,className:E("shrink-0 items-center",t.changed>0?"text-amber-400/80":t.ahead||t.behind?"text-sky-400/70":"text-fg-5/50"),onClick:s=>s.stopPropagation(),children:e.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("circle",{cx:"6",cy:"6",r:"2.5"}),e.jsx("circle",{cx:"6",cy:"18",r:"2.5"}),e.jsx("circle",{cx:"18",cy:"8",r:"2.5"}),e.jsx("path",{d:"M6 8.5v7"}),e.jsx("path",{d:"M18 10.5c0 4.5-6 3-6 7.5"})]})})}const Dr=r.memo(function({workspace:n,sessions:s,loading:a,isActive:l,selectedKey:d,openSessionKeys:p,onSelectSession:c,onNewSession:b,onRefresh:v,onRemove:g,onExtensions:j,onWarmSession:T,onCancelWarmSession:k,onSessionMenuOpen:I,t:L}){const[S,R]=r.useState(!0),[D,H]=r.useState(Yt);r.useEffect(()=>{H(Yt)},[s.length]);const P=s.slice(0,D),A=s.length-D,F=n.path,[z,ae]=r.useState(null),ee=r.useCallback(()=>{J.getWorkspaceGit(F).then(M=>ae(M.git)).catch(()=>ae(null))},[F]);return r.useEffect(()=>{ee()},[ee]),e.jsxs("div",{className:"border-b border-edge/30",children:[e.jsxs("div",{className:"flex items-center gap-2 px-3 py-2 cursor-pointer hover:bg-panel-h/50 transition-colors",onClick:()=>R(M=>!M),children:[e.jsx("svg",{width:"9",height:"9",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:E("shrink-0 text-fg-5 transition-transform duration-150",S&&"rotate-90"),children:e.jsx("polyline",{points:"9 6 15 12 9 18"})}),e.jsxs("div",{className:"flex-1 min-w-0 flex items-center gap-1.5",children:[e.jsx("span",{className:E("min-w-0 truncate text-[12px] font-semibold",l?"text-primary":"text-fg-3"),children:n.name}),e.jsx(Or,{git:z})]}),l&&e.jsx($t,{variant:"ok"}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[e.jsx("button",{onClick:M=>{M.stopPropagation(),b(F)},className:"p-1 rounded text-fg-5 hover:text-primary hover:bg-panel-h/60 transition-colors",title:L("hub.newSession"),children:e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",children:[e.jsx("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),e.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"})]})}),e.jsx("button",{onClick:M=>{M.stopPropagation(),j(F)},className:"p-1 rounded text-fg-5 hover:text-primary hover:bg-panel-h/60 transition-colors",title:L("hub.extensions"),children:e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M12 22v-5"}),e.jsx("path",{d:"M9 8V2"}),e.jsx("path",{d:"M15 8V2"}),e.jsx("path",{d:"M18 8v5a6 6 0 0 1-12 0V8z"})]})}),e.jsx("button",{onClick:M=>{M.stopPropagation(),v(F),ee()},className:"p-1 rounded text-fg-5 hover:text-fg-2 hover:bg-panel-h/60 transition-colors",children:e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",children:[e.jsx("polyline",{points:"23 4 23 10 17 10"}),e.jsx("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"})]})}),!l&&e.jsx("button",{onClick:M=>{M.stopPropagation(),g(F)},className:"p-1 rounded text-fg-5 hover:text-red-400 hover:bg-panel-h/60 transition-colors",children:e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),e.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]})]}),S&&e.jsx("div",{className:"pb-1",children:a?e.jsx("div",{className:"flex items-center justify-center py-4",children:e.jsx(pe,{className:"h-3 w-3 text-fg-5"})}):s.length===0?e.jsx("div",{className:"py-3 text-center text-[11px] text-fg-5",children:L("sessions.noSessions")}):e.jsxs(e.Fragment,{children:[P.map(M=>{const K=U(M.agent||"",M.sessionId),Le=M.__forkDepth||0;return e.jsx(Fr,{session:M,isSelected:d===K,isOpen:p?.has(K)??!1,forkDepth:Le,onClick:()=>c(M,F),onWarm:()=>T(M,F),onCancelWarm:()=>k(M,F),onShowMenu:de=>I(de,M,F),menuLabel:L("session.openActions")},K)}),A>0&&e.jsxs("button",{onClick:()=>H(M=>M+Yt),className:"flex items-center gap-1.5 w-full px-3 py-1.5 text-[11px] text-fg-5 hover:text-fg-3 hover:bg-panel-h/50 transition-colors",children:[e.jsxs("span",{children:["+ ",L("hub.nMore").replace("{n}",String(A))]}),e.jsx("svg",{width:"8",height:"8",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})]})]})})]})}),Fr=r.memo(function({session:n,isSelected:s,isOpen:a,forkDepth:l=0,onClick:d,onWarm:p,onCancelWarm:c,onShowMenu:b,menuLabel:v}){const g=Zt(n.agent||""),j=Rt(n),T=Sn(n).slice(0,500)||n.sessionId.slice(0,16),k=fs(n,T).slice(0,500),I=n.model?rn(n.model):null,L=l>0?Math.min(l,3)*14:0,S=a?10:12,R=r.useRef(null);return e.jsxs("div",{className:"relative group",children:[e.jsxs("button",{onClick:d,onMouseEnter:p,onFocus:p,onMouseLeave:c,onBlur:c,className:E("w-full pr-3 py-2 text-left transition-all duration-100",s?"bg-selected hover:bg-selected-h":a?"bg-panel-h/30 hover:bg-panel-h/50":"hover:bg-panel-h/50"),style:{paddingLeft:S+L,...a?{borderLeft:`2px solid ${s?g.color:`${g.color}30`}`}:{}},children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-[10px] text-fg-5",children:[l>0&&e.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"text-fg-5/60 shrink-0","aria-label":"Fork",children:[e.jsx("circle",{cx:"6",cy:"6",r:"2"}),e.jsx("circle",{cx:"18",cy:"6",r:"2"}),e.jsx("circle",{cx:"12",cy:"20",r:"2"}),e.jsx("path",{d:"M6 8v3a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3V8"}),e.jsx("path",{d:"M12 14v4"})]}),e.jsx(Je,{brand:n.agent||"",size:10}),e.jsx("span",{className:"font-medium shrink-0",style:{color:g.color},children:g.shortLabel}),I&&e.jsx("span",{className:"truncate max-w-[72px] font-mono text-fg-5/40 text-[9px]",children:I}),e.jsxs("div",{className:"ml-auto flex items-center gap-1.5 shrink-0 transition-opacity group-hover:opacity-0 group-focus-within:opacity-0",children:[!!n.numTurns&&e.jsxs("span",{className:"flex items-center gap-0.5 text-fg-5/50 tabular-nums",children:[e.jsx("svg",{width:"9",height:"9",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",className:"opacity-50",children:e.jsx("path",{d:"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"})}),n.numTurns]}),e.jsx("span",{className:"tabular-nums",children:Cn(n.runUpdatedAt||n.createdAt)})]})]}),e.jsxs("div",{className:"mt-1 flex items-center gap-1.5",children:[e.jsx($t,{variant:j==="running"?"ok":j==="waiting"?"info":j==="incomplete"?"warn":"idle",pulse:j==="running"||j==="waiting"}),e.jsx("span",{className:"truncate text-[12px] leading-snug text-fg-2",children:T})]}),k&&e.jsx("div",{className:"mt-0.5 pl-[11px]",children:e.jsx("span",{className:"block truncate text-[10px] leading-snug text-fg-5",children:k})})]}),e.jsx("button",{ref:R,type:"button","aria-label":v,"aria-haspopup":"menu",onMouseDown:D=>{D.stopPropagation()},onClick:D=>{D.stopPropagation(),D.preventDefault(),R.current&&b(R.current.getBoundingClientRect())},className:"absolute top-1.5 right-1.5 p-1 rounded text-fg-5 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 hover:bg-panel-h hover:text-fg-2 transition-opacity",children:e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":"true",children:[e.jsx("circle",{cx:"12",cy:"5",r:"1.5"}),e.jsx("circle",{cx:"12",cy:"12",r:"1.5"}),e.jsx("circle",{cx:"12",cy:"19",r:"1.5"})]})})]})}),Ur=r.memo(function({workdir:n,onClose:s,t:a}){const l=je(g=>g.state?.hostApp??null),d=je(g=>g.state?.platform??null),p=je(g=>g.toast),[c,b]=r.useState(()=>Pr(l,d)),v=r.useCallback(async g=>{try{const j=await J.openInEditor(g,c);if(!j.ok)throw new Error(j.error||`Failed to open ${g}`)}catch(j){p(j?.message||String(j),!1)}},[c,p]);return e.jsxs("div",{className:"fixed z-50 w-[280px] max-h-[calc(100vh-100px)] flex flex-col rounded-xl border border-edge bg-panel/95 backdrop-blur-md overflow-hidden",style:{boxShadow:"0 8px 32px rgba(0,0,0,0.18), 0 2px 8px rgba(0,0,0,0.12)",right:16,top:80},children:[e.jsxs("div",{className:"shrink-0 flex items-center gap-1.5 px-2.5 py-1.5 border-b border-edge/30",children:[e.jsx("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",className:"shrink-0 text-fg-5",children:e.jsx("path",{d:"M2 6a2 2 0 012-2h5l2 2h9a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"})}),e.jsx("span",{className:"flex-1 text-[10px] font-semibold text-fg-4 uppercase tracking-wider",children:a("hub.files")}),e.jsx("button",{onClick:s,className:"p-0.5 rounded text-fg-5/40 hover:text-fg-2 transition-colors",title:a("hub.closePanel"),children:e.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:[e.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),e.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),e.jsxs("div",{className:"shrink-0 px-2.5 py-1.5 border-b border-edge/20 flex items-center gap-2",children:[e.jsx(gs,{value:c,options:(d==="darwin"?["vscode","finder"]:["vscode"]).map(g=>({value:g,label:a(Hn(g))})),onChange:g=>{_r(g)&&b(g)},renderIcon:g=>e.jsx(zn,{target:g,size:14})}),e.jsx(Te,{size:"sm",variant:"ghost",onClick:()=>v(n),className:"flex-1 min-w-0 text-[11px]",children:a("hub.openProject")})]}),e.jsx("div",{className:"flex-1 overflow-y-auto px-1 py-1.5",children:e.jsx(Hr,{basePath:n,openTarget:c,onOpenPath:v,t:a})})]})});function zn({target:t,size:n=16}){return t==="default"?e.jsxs("svg",{width:n,height:n,viewBox:"0 0 16 16",className:"shrink-0 text-fg-4",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M6 3H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-2"}),e.jsx("path",{d:"M9 2h5v5"}),e.jsx("path",{d:"M14 2L7 9"})]}):e.jsx(Je,{brand:t,size:n})}function Hr({basePath:t,includeHidden:n=!1,openTarget:s,onOpenPath:a,t:l}){const[d,p]=r.useState([]),[c,b]=r.useState(!0);r.useEffect(()=>{let g=!1;return b(!0),J.lsDir(t,!0,n).then(j=>{!g&&j.ok&&p(j.dirs.slice(0,50).map(T=>({entry:T,expanded:!1,children:null,loading:!1})))}).catch(()=>{}).finally(()=>{g||b(!1)}),()=>{g=!0}},[t,n]);const v=r.useCallback(g=>{const j=T=>T.map(k=>k.entry.path===g?k.expanded?{...k,expanded:!1}:k.children===null?(J.lsDir(g,!0,n).then(I=>{I.ok&&p(L=>sn(L,g,{children:I.dirs.slice(0,50).map(S=>({entry:S,expanded:!1,children:null,loading:!1})),loading:!1}))}).catch(()=>{p(I=>sn(I,g,{children:[],loading:!1}))}),{...k,loading:!0,expanded:!0}):{...k,expanded:!0}:k.children?{...k,children:j(k.children)}:k);p(T=>j(T))},[n]);return c?e.jsx("div",{className:"flex justify-center py-3",children:e.jsx(pe,{className:"h-3 w-3 text-fg-5"})}):d.length===0?e.jsx("div",{className:"py-3 text-center text-[11px] text-fg-5",children:"—"}):e.jsx("div",{className:"space-y-px",children:e.jsx(Kn,{nodes:d,depth:0,onToggle:v,openTarget:s,onOpenPath:a,t:l})})}function Kn({nodes:t,depth:n,onToggle:s,openTarget:a,onOpenPath:l,t:d}){return e.jsx(e.Fragment,{children:t.map(p=>e.jsx(zr,{node:p,depth:n,onToggle:s,openTarget:a,onOpenPath:l,t:d},p.entry.path))})}function zr({node:t,depth:n,onToggle:s,openTarget:a,onOpenPath:l,t:d}){const{entry:p,expanded:c,children:b,loading:v}=t,g=n*14,[j,T]=r.useState(!1),k=d(Hn(a)),I=d("hub.openWithTarget").replace("{target}",k);return e.jsxs(e.Fragment,{children:[e.jsxs("div",{onClick:p.isDir?()=>s(p.path):void 0,onMouseEnter:()=>T(!0),onMouseLeave:()=>T(!1),className:E("flex items-center gap-1.5 py-1 rounded text-[11px] text-fg-3 transition-colors",p.isDir?"hover:bg-panel-h/50 cursor-pointer":"hover:bg-panel-h/50 cursor-default"),style:{paddingLeft:8+g,paddingRight:8},children:[p.isDir?v?e.jsx(pe,{className:"h-2 w-2 text-fg-5 shrink-0"}):e.jsx("svg",{width:"8",height:"8",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:E("shrink-0 text-fg-5/40 transition-transform duration-150",c&&"rotate-90"),children:e.jsx("polyline",{points:"9 6 15 12 9 18"})}):e.jsx("span",{className:"w-2 shrink-0"}),p.isDir?e.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",className:"shrink-0 text-blue-400/70",children:e.jsx("path",{d:"M2 6a2 2 0 012-2h5l2 2h9a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V6z",fill:"currentColor",opacity:"0.25",stroke:"currentColor",strokeWidth:"1.5"})}):e.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",className:"shrink-0 text-fg-5",children:[e.jsx("path",{d:"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"}),e.jsx("polyline",{points:"14 2 14 8 20 8"})]}),e.jsx("span",{className:"truncate flex-1",children:p.name}),j&&e.jsxs("div",{className:"flex items-center gap-0.5 shrink-0",children:[e.jsx("button",{onClick:L=>{L.stopPropagation(),l(p.path)},className:"inline-flex items-center gap-1 rounded px-1 py-0.5 text-fg-5 hover:text-blue-400 transition-colors",title:I,children:e.jsx(zn,{target:a,subtle:!0})}),!p.isDir&&e.jsx(Kr,{filePath:p.path,t:d})]})]}),p.isDir&&c&&b&&b.length>0&&e.jsx(Kn,{nodes:b,depth:n+1,onToggle:s,openTarget:a,onOpenPath:l,t:d})]})}function Kr({filePath:t,t:n}){const[s,a]=r.useState(!1);return e.jsx("button",{onClick:l=>{l.stopPropagation(),navigator.clipboard.writeText(t).then(()=>{a(!0),setTimeout(()=>a(!1),1500)}).catch(()=>{})},className:E("p-0.5 rounded transition-colors",s?"text-ok":"text-fg-5 hover:text-fg-3"),title:n("hub.copied"),children:s?e.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:e.jsx("polyline",{points:"20 6 9 17 4 12"})}):e.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[e.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2"}),e.jsx("path",{d:"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"})]})})}function sn(t,n,s){return t.map(a=>a.entry.path===n?{...a,...s}:a.children?{...a,children:sn(a.children,n,s)}:a)}const io=Object.freeze(Object.defineProperty({__proto__:null,SessionWorkspace:Wr},Symbol.toStringTag,{value:"Module"}));export{Js as I,ro as L,rr as R,oo as T,Fn as U,to as a,Bn as b,Ws as c,tn as d,so as e,jr as f,io as i,Ts as l,no as m,eo as n,Cs as p,vn as u};
@@ -0,0 +1 @@
1
+ import{j as s}from"./react-vendor-C7Sl8SE7.js";import{K as t,k as i,S as a}from"./index-BCYshErN.js";function o({primary:e,secondary:l,tertiary:n}){return s.jsxs("div",{className:"flex flex-col gap-2 pt-1 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e&&s.jsxs(i,{tone:"primary",onClick:e.onClick,disabled:e.disabled,children:[e.loading&&s.jsx(a,{}),e.label]}),l&&s.jsx(i,{tone:"secondary",onClick:l.onClick,disabled:l.disabled,children:l.label})]}),n&&s.jsx("div",{className:"text-xs leading-relaxed text-fg-4",children:n})]})}function c({children:e,className:l}){return s.jsx(t,{padding:"md",elevation:"flat",className:l,children:e})}export{o as A,c as S};
@@ -6,7 +6,7 @@
6
6
  <link rel="icon" type="image/png" href="/logo.png">
7
7
  <title>Pikiloom</title>
8
8
  <link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet">
9
- <script type="module" crossorigin src="/assets/index-Dws-2k-J.js"></script>
9
+ <script type="module" crossorigin src="/assets/index-BCYshErN.js"></script>
10
10
  <link rel="modulepreload" crossorigin href="/assets/react-vendor-C7Sl8SE7.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/router-DHISdpPk.js">
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-FD86DEDF.css">
Binary file
@@ -28,6 +28,101 @@ export function getAllAgentUpdateStates() {
28
28
  result[key] = value;
29
29
  return result;
30
30
  }
31
+ // ---------------------------------------------------------------------------
32
+ // Spawn coordination
33
+ //
34
+ // A CLI reinstall (`npm install -g` / `brew upgrade`) briefly tears down and
35
+ // rewrites the bin symlink, so an agent spawn that races it execs into
36
+ // "/bin/sh: <cli>: command not found" (exit 127). The updating process drops a
37
+ // per-agent marker file for the duration of the destructive step; the spawn
38
+ // path waits while it's held. The marker is cross-process (this worker AND the
39
+ // `npx pikiloom@latest` self-bootstrap both update + spawn), and carries the
40
+ // updater's pid so a marker orphaned by a crashed updater is detected via
41
+ // liveness and cleaned up — a spawn never hangs on a stale marker, and a
42
+ // genuinely-missing CLI (no marker) fails fast instead of waiting.
43
+ // ---------------------------------------------------------------------------
44
+ /** Path of the in-flight-reinstall marker for `agent` (one file per agent). */
45
+ export function agentUpdateMarkerPath(agent) {
46
+ return path.join(os.homedir(), STATE_DIR_NAME, `agent-update-${agent}.installing`);
47
+ }
48
+ /**
49
+ * True when a live updater is mid-reinstall of `agent`. Reads the marker's pid
50
+ * and probes liveness with `kill(pid, 0)`; an orphaned marker (writer gone) is
51
+ * removed and reported idle so spawns don't hang on a crashed updater.
52
+ */
53
+ function agentReinstallInFlight(agent) {
54
+ const marker = agentUpdateMarkerPath(agent);
55
+ let raw;
56
+ try {
57
+ raw = fs.readFileSync(marker, 'utf8');
58
+ }
59
+ catch {
60
+ return false; // no marker — nothing updating
61
+ }
62
+ const pid = Number.parseInt(raw.trim(), 10);
63
+ if (Number.isInteger(pid) && pid > 0) {
64
+ try {
65
+ process.kill(pid, 0); // throws ESRCH if the updater is gone
66
+ return true;
67
+ }
68
+ catch {
69
+ try {
70
+ fs.rmSync(marker, { force: true });
71
+ }
72
+ catch { }
73
+ return false;
74
+ }
75
+ }
76
+ // Unreadable pid — fall back to mtime so a corrupt marker still ages out.
77
+ try {
78
+ return Date.now() - fs.statSync(marker).mtimeMs <= AGENT_UPDATE_COMMAND_TIMEOUT_MS;
79
+ }
80
+ catch {
81
+ return false;
82
+ }
83
+ }
84
+ /**
85
+ * Marks `agent` as mid-reinstall (cross-process) for the duration of
86
+ * `install()` so concurrent spawns can wait it out. Always clears the marker,
87
+ * even when the install throws.
88
+ */
89
+ export async function withAgentUpdateGate(agent, install) {
90
+ const id = String(agent || '').trim();
91
+ if (!id)
92
+ return install();
93
+ const marker = agentUpdateMarkerPath(id);
94
+ try {
95
+ fs.mkdirSync(path.dirname(marker), { recursive: true });
96
+ fs.writeFileSync(marker, `${process.pid}\n`);
97
+ }
98
+ catch { }
99
+ try {
100
+ return await install();
101
+ }
102
+ finally {
103
+ try {
104
+ fs.rmSync(marker, { force: true });
105
+ }
106
+ catch { }
107
+ }
108
+ }
109
+ /**
110
+ * Resolves once no live reinstall of `agent` is in flight, or after
111
+ * `timeoutMs`. No-op (returns immediately) when nothing is updating. Called
112
+ * from the spawn path so we never exec a half-swapped CLI binary.
113
+ */
114
+ export async function awaitAgentUpdateIdle(agent, timeoutMs) {
115
+ const id = String(agent || '').trim();
116
+ if (!id)
117
+ return;
118
+ const deadline = Date.now() + Math.max(0, timeoutMs);
119
+ while (agentReinstallInFlight(id)) {
120
+ const remaining = deadline - Date.now();
121
+ if (remaining <= 0)
122
+ return;
123
+ await new Promise(resolve => setTimeout(resolve, Math.min(AGENT_UPDATE_TIMEOUTS.spawnWaitPoll, remaining)));
124
+ }
125
+ }
31
126
  function updaterLockPath() {
32
127
  return path.join(os.homedir(), STATE_DIR_NAME, 'agent-auto-update.lock');
33
128
  }
@@ -335,8 +430,8 @@ export function startAgentAutoUpdate(opts) {
335
430
  setUpdateState(id, { latestVersion, updateAvailable: true, status: 'updating' });
336
431
  opts.log(`agent auto-update: updating ${label} ${currentVersion || 'unknown'} -> ${latestVersion} via ${strategy.kind}`);
337
432
  const result = strategy.kind === 'brew'
338
- ? await updateViaBrew(strategy.cask)
339
- : await updateViaNpm(strategy.pkg);
433
+ ? await withAgentUpdateGate(id, () => updateViaBrew(strategy.cask))
434
+ : await withAgentUpdateGate(id, () => updateViaNpm(strategy.pkg));
340
435
  if (result.ok) {
341
436
  opts.log(`agent auto-update: ${label} update completed`);
342
437
  setUpdateState(id, { updateAvailable: false, status: 'updated', detail: null, checkedAt: Date.now() });
@@ -408,11 +503,11 @@ export async function manualAgentUpdate(agent, log) {
408
503
  let result;
409
504
  if (brewCask) {
410
505
  log(`manual update: updating ${label} via brew upgrade --cask ${brewCask}`);
411
- result = await updateViaBrew(brewCask);
506
+ result = await withAgentUpdateGate(id, () => updateViaBrew(brewCask));
412
507
  }
413
508
  else {
414
509
  log(`manual update: updating ${label} via npm install -g ${pkg}@latest`);
415
- result = await updateViaNpm(pkg);
510
+ result = await withAgentUpdateGate(id, () => updateViaNpm(pkg));
416
511
  }
417
512
  if (result.ok) {
418
513
  log(`manual update: ${label} update completed`);
@@ -8,7 +8,7 @@ import { createInterface } from 'node:readline';
8
8
  import { registerDriver } from '../driver.js';
9
9
  import {
10
10
  // shared helpers
11
- Q, run, agentError, agentLog, agentWarn, buildStreamPreviewMeta, computeContext, pushRecentActivity, summarizeClaudeToolUse, summarizeClaudeToolResult, joinErrorMessages, parseTodoWriteAsPlan, previewToolCallInput, previewToolCallResult, detectClaudeApiError, isRetryableClaudeApiError, detectClaudeModelError, claudeModelErrorMessage, emitSessionIdUpdate, IMAGE_EXTS, mimeForExt, listPikiloomSessions, mergeManagedAndNativeSessions, readTailLines, stripInjectedPrompts, sanitizeSessionUserPreviewText, SESSION_PREVIEW_IMAGE_PLACEHOLDER_RE, CLAUDE_AT_MENTION_IMAGE_RE, extractClaudeAtMentionImagePaths, attachAgentImage, applyTurnWindow, shortValue, roundPercent, modelFamily, normalizeClaudeModelId, emptyUsage, normalizeUsageStatus, collapseSkillPrompt, } from '../index.js';
11
+ Q, run, agentError, agentLog, agentWarn, buildStreamPreviewMeta, computeContext, pushRecentActivity, summarizeClaudeToolUse, summarizeClaudeToolResult, joinErrorMessages, parseTodoWriteAsPlan, previewToolCallInput, previewToolCallResult, detectClaudeApiError, isRetryableClaudeApiError, detectClaudeModelError, claudeModelErrorMessage, emitSessionIdUpdate, IMAGE_EXTS, mimeForExt, listPikiloomSessions, mergeManagedAndNativeSessions, managedRecordToSessionInfo, readTailLines, stripInjectedPrompts, sanitizeSessionUserPreviewText, SESSION_PREVIEW_IMAGE_PLACEHOLDER_RE, CLAUDE_AT_MENTION_IMAGE_RE, extractClaudeAtMentionImagePaths, attachAgentImage, applyTurnWindow, shortValue, roundPercent, modelFamily, normalizeClaudeModelId, emptyUsage, normalizeUsageStatus, collapseSkillPrompt, } from '../index.js';
12
12
  import { AGENT_STREAM_HARD_KILL_GRACE_MS, AGENT_GRACEFUL_ABORT_GRACE_MS, SESSION_RUNNING_THRESHOLD_MS } from '../../core/constants.js';
13
13
  import { terminateProcessTree } from '../../core/process-control.js';
14
14
  import { getHome, IS_MAC, encodePathAsDirName } from '../../core/platform.js';
@@ -1612,31 +1612,11 @@ function getNativeClaudeSessions(workdir, limit) {
1612
1612
  function getClaudeSessions(workdir, limit) {
1613
1613
  const resolvedWorkdir = path.resolve(workdir);
1614
1614
  // Merge pikiloom-tracked sessions with native Claude sessions
1615
- const pikiloomSessions = listPikiloomSessions(resolvedWorkdir, 'claude').map(record => ({
1616
- sessionId: record.sessionId,
1617
- agent: 'claude',
1618
- workdir: record.workdir,
1619
- workspacePath: record.workspacePath,
1620
- threadId: record.threadId,
1621
- model: record.model,
1622
- createdAt: record.createdAt,
1623
- title: record.title,
1624
- running: record.runState === 'running',
1625
- runState: record.runState,
1626
- runDetail: record.runDetail,
1627
- runUpdatedAt: record.runUpdatedAt,
1628
- runPid: record.runPid,
1629
- classification: record.classification,
1630
- userStatus: record.userStatus,
1631
- userNote: record.userNote,
1632
- lastQuestion: record.lastQuestion,
1633
- lastAnswer: record.lastAnswer,
1634
- lastMessageText: record.lastMessageText,
1635
- migratedFrom: record.migratedFrom,
1636
- migratedTo: record.migratedTo,
1637
- linkedSessions: record.linkedSessions,
1638
- numTurns: record.numTurns ?? null,
1639
- }));
1615
+ // Canonical record→SessionInfo mapper (single source of truth). Hand-rolling
1616
+ // this projection silently dropped pikiloom-owned metadata (thinkingEffort,
1617
+ // workflowEnabled, profileId), so the merged list lost the user's per-session
1618
+ // effort / Workflow / BYOK choices. Centralizing it keeps every field in sync.
1619
+ const pikiloomSessions = listPikiloomSessions(resolvedWorkdir, 'claude').map(managedRecordToSessionInfo);
1640
1620
  const nativeSessions = getNativeClaudeSessions(resolvedWorkdir, limit);
1641
1621
  const merged = mergeManagedAndNativeSessions(pikiloomSessions, nativeSessions);
1642
1622
  const sessions = typeof limit === 'number' ? merged.slice(0, limit) : merged;
@@ -8,7 +8,7 @@ import { registerDriver } from '../driver.js';
8
8
  import { terminateProcessTree } from '../../core/process-control.js';
9
9
  import { mimeForExt,
10
10
  // shared helpers
11
- agentLog, agentWarn, buildStreamPreviewMeta, pushRecentActivity, normalizeActivityLine, firstNonEmptyLine, shortValue, numberOrNull, normalizeStreamPreviewPlan, IMAGE_EXTS, listPikiloomSessions, findPikiloomSession, mergeManagedAndNativeSessions, stripInjectedPrompts, sanitizeSessionUserPreviewText, computeContext, readTailLines, applyTurnWindow, roundPercent, toIsoFromEpochSeconds, labelFromWindowMinutes, usageWindowFromRateLimit, parseJsonTail, emptyUsage, attachAgentImage, codexHome, Q, } from '../index.js';
11
+ agentLog, agentWarn, buildStreamPreviewMeta, pushRecentActivity, normalizeActivityLine, firstNonEmptyLine, shortValue, numberOrNull, normalizeStreamPreviewPlan, IMAGE_EXTS, listPikiloomSessions, findPikiloomSession, mergeManagedAndNativeSessions, managedRecordToSessionInfo, stripInjectedPrompts, sanitizeSessionUserPreviewText, computeContext, readTailLines, applyTurnWindow, roundPercent, toIsoFromEpochSeconds, labelFromWindowMinutes, usageWindowFromRateLimit, parseJsonTail, emptyUsage, attachAgentImage, codexHome, Q, } from '../index.js';
12
12
  import { CODEX_APPSERVER_SPAWN_TIMEOUT_MS as _CODEX_APPSERVER_SPAWN_TIMEOUT_MS, CODEX_STREAM_HARD_KILL_GRACE_MS, SESSION_RUNNING_THRESHOLD_MS, } from '../../core/constants.js';
13
13
  import { getHome } from '../../core/platform.js';
14
14
  // ---------------------------------------------------------------------------
@@ -1614,31 +1614,9 @@ function getCodexSessionTailFromRollout(opts) {
1614
1614
  function getCodexSessions(workdir, limit) {
1615
1615
  const resolvedWorkdir = path.resolve(workdir);
1616
1616
  // Merge pikiloom-tracked sessions with native Codex sessions
1617
- const pikiloomSessions = listPikiloomSessions(resolvedWorkdir, 'codex').map(record => ({
1618
- sessionId: record.sessionId,
1619
- agent: 'codex',
1620
- workdir: record.workdir,
1621
- workspacePath: record.workspacePath,
1622
- threadId: record.threadId,
1623
- model: record.model,
1624
- createdAt: record.createdAt,
1625
- title: record.title,
1626
- running: record.runState === 'running',
1627
- runState: record.runState,
1628
- runDetail: record.runDetail,
1629
- runUpdatedAt: record.runUpdatedAt,
1630
- runPid: record.runPid,
1631
- classification: record.classification,
1632
- userStatus: record.userStatus,
1633
- userNote: record.userNote,
1634
- lastQuestion: record.lastQuestion,
1635
- lastAnswer: record.lastAnswer,
1636
- lastMessageText: record.lastMessageText,
1637
- migratedFrom: record.migratedFrom,
1638
- migratedTo: record.migratedTo,
1639
- linkedSessions: record.linkedSessions,
1640
- numTurns: record.numTurns ?? null,
1641
- }));
1617
+ // Canonical record→SessionInfo mapper (single source of truth) see claude.ts.
1618
+ // Hand-rolling dropped thinkingEffort/workflowEnabled/profileId from the merge.
1619
+ const pikiloomSessions = listPikiloomSessions(resolvedWorkdir, 'codex').map(managedRecordToSessionInfo);
1642
1620
  const nativeSessions = getNativeCodexSessions(resolvedWorkdir, limit);
1643
1621
  const merged = mergeManagedAndNativeSessions(pikiloomSessions, nativeSessions);
1644
1622
  const sessions = typeof limit === 'number' ? merged.slice(0, limit) : merged;
@@ -10,7 +10,7 @@ import os from 'node:os';
10
10
  import path from 'node:path';
11
11
  import { execSync } from 'node:child_process';
12
12
  import { GEMINI_USAGE_TIMEOUTS, SESSION_RUNNING_THRESHOLD_MS } from '../../core/constants.js';
13
- import { run, agentLog, appendSystemPrompt, pushRecentActivity, firstNonEmptyLine, shortValue, normalizeErrorMessage, sanitizeSessionUserPreviewText, emitSessionIdUpdate, listPikiloomSessions, mergeManagedAndNativeSessions, applyTurnWindow, stripInjectedPrompts, attachAgentImage, roundPercent, emptyUsage, Q, } from '../index.js';
13
+ import { run, agentLog, appendSystemPrompt, pushRecentActivity, firstNonEmptyLine, shortValue, normalizeErrorMessage, sanitizeSessionUserPreviewText, emitSessionIdUpdate, listPikiloomSessions, mergeManagedAndNativeSessions, managedRecordToSessionInfo, applyTurnWindow, stripInjectedPrompts, attachAgentImage, roundPercent, emptyUsage, Q, } from '../index.js';
14
14
  import { getHome } from '../../core/platform.js';
15
15
  // ---------------------------------------------------------------------------
16
16
  // Command & parser
@@ -740,31 +740,9 @@ function getNativeGeminiSessions(workdir) {
740
740
  function getGeminiSessions(workdir, limit) {
741
741
  const resolvedWorkdir = path.resolve(workdir);
742
742
  // Merge pikiloom-tracked sessions with native Gemini sessions
743
- const pikiloomSessions = listPikiloomSessions(resolvedWorkdir, 'gemini').map(record => ({
744
- sessionId: record.sessionId,
745
- agent: 'gemini',
746
- workdir: record.workdir,
747
- workspacePath: record.workspacePath,
748
- threadId: record.threadId,
749
- model: record.model,
750
- createdAt: record.createdAt,
751
- title: record.title,
752
- running: record.runState === 'running',
753
- runState: record.runState,
754
- runDetail: record.runDetail,
755
- runUpdatedAt: record.runUpdatedAt,
756
- runPid: record.runPid,
757
- classification: record.classification,
758
- userStatus: record.userStatus,
759
- userNote: record.userNote,
760
- lastQuestion: record.lastQuestion,
761
- lastAnswer: record.lastAnswer,
762
- lastMessageText: record.lastMessageText,
763
- migratedFrom: record.migratedFrom,
764
- migratedTo: record.migratedTo,
765
- linkedSessions: record.linkedSessions,
766
- numTurns: record.numTurns ?? null,
767
- }));
743
+ // Canonical record→SessionInfo mapper (single source of truth) see claude.ts.
744
+ // Hand-rolling dropped thinkingEffort/workflowEnabled/profileId from the merge.
745
+ const pikiloomSessions = listPikiloomSessions(resolvedWorkdir, 'gemini').map(managedRecordToSessionInfo);
768
746
  const nativeSessions = getNativeGeminiSessions(resolvedWorkdir);
769
747
  const merged = mergeManagedAndNativeSessions(pikiloomSessions, nativeSessions);
770
748
  const sessions = typeof limit === 'number' ? merged.slice(0, limit) : merged;