pikiloom 0.4.47 → 0.4.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/dist/assets/{AgentTab-1PB5sNiV.js → AgentTab-Y8SMF_cv.js} +1 -1
- package/dashboard/dist/assets/{ConnectionModal-MKdYiyph.js → ConnectionModal-D1dVCA1F.js} +1 -1
- package/dashboard/dist/assets/{DirBrowser-CrTtSp7T.js → DirBrowser-BQY3TDwt.js} +1 -1
- package/dashboard/dist/assets/{ExtensionsTab-CpbFbTbu.js → ExtensionsTab-DRNBSp8n.js} +1 -1
- package/dashboard/dist/assets/{IMAccessTab-DnoYQxhx.js → IMAccessTab-Bvit2BeM.js} +1 -1
- package/dashboard/dist/assets/{Modal-BxMOpH7q.js → Modal-CIPxcnQp.js} +1 -1
- package/dashboard/dist/assets/{Modals-CgChd_Yq.js → Modals-Dq4NKdFh.js} +1 -1
- package/dashboard/dist/assets/{Select-th1z50AY.js → Select-DIWylim1.js} +1 -1
- package/dashboard/dist/assets/{SessionPanel-DTGtpuIp.js → SessionPanel-C1nonT-C.js} +1 -1
- package/dashboard/dist/assets/{SystemTab-DYLYxrRz.js → SystemTab-CTrzAdQY.js} +1 -1
- package/dashboard/dist/assets/index-BGne9zh7.js +3 -0
- package/dashboard/dist/assets/{index-DwmXPtDd.css → index-BcPBJtn2.css} +1 -1
- package/dashboard/dist/assets/{index-Bqx1Oo38.js → index-DjHeF3yU.js} +3 -3
- package/dashboard/dist/assets/{shared-D5m7uSRI.js → shared-Bj_Anfvt.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dist/agent/accounts.js +33 -1
- package/dist/agent/drivers/claude.js +90 -19
- package/dist/agent/kernel-bridge.js +20 -9
- package/dist/agent/utils.js +3 -1
- package/dist/bot/commands.js +13 -7
- package/dist/bot/render-shared.js +49 -6
- package/dist/dashboard/routes/accounts.js +14 -5
- package/package.json +1 -1
- package/packages/kernel/dist/drivers/claude.d.ts +4 -0
- package/packages/kernel/dist/drivers/claude.js +104 -8
- package/packages/kernel/dist/index.d.ts +1 -1
- package/packages/kernel/dist/index.js +1 -1
- package/dashboard/dist/assets/index-CnZm1BHw.js +0 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/SessionPanel-
|
|
2
|
-
import{c as L,a as re,u as ie,i as Ut,f as _t,A as js,s as zt,S as fe,B as ct,g as dn,w as ws,b as ks,C as fn,d as ys,r as Ln,e as In,h as Ns,n as Ss,j as Cs,k as Pn,l as Ot,m as We,D as Gt,o as Ls,p as Wn,_ as Bn,T as Is,q as Ts}from"./index-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/SessionPanel-C1nonT-C.js","assets/react-vendor-C7Sl8SE7.js","assets/index-BGne9zh7.js","assets/router-DHISdpPk.js","assets/index-BcPBJtn2.css","assets/Modal-CIPxcnQp.js","assets/Select-DIWylim1.js","assets/DirBrowser-BQY3TDwt.js","assets/markdown-DxQYQFeH.js","assets/ExtensionsTab-DRNBSp8n.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{c as L,a as re,u as ie,i as Ut,f as _t,A as js,s as zt,S as fe,B as ct,g as dn,w as ws,b as ks,C as fn,d as ys,r as Ln,e as In,h as Ns,n as Ss,j as Cs,k as Pn,l as Ot,m as We,D as Gt,o as Ls,p as Wn,_ as Bn,T as Is,q as Ts}from"./index-BGne9zh7.js";import{j as e,r as o,a as gn}from"./react-vendor-C7Sl8SE7.js";import{I as Es}from"./Select-DIWylim1.js";import{M as Kt,a as Ht}from"./Modal-CIPxcnQp.js";import{D as Ms}from"./DirBrowser-BQY3TDwt.js";import{n as As,r as _s,M as mn}from"./markdown-DxQYQFeH.js";import{WorkspaceExtensionsBody as Rs}from"./ExtensionsTab-DRNBSp8n.js";function Ps({open:t,className:n}){return e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:L("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 dt({open:t,onToggle:n,dot:s,label:l,preview:r,badge:c,collapsedContent:p,children:d,className:m}){return e.jsxs("div",{className:L("rounded-md border border-edge bg-panel overflow-hidden","shadow-[0_2px_8px_rgba(0,0,0,0.06)]",m),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:L("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:l}),e.jsx("span",{className:"flex-1 min-w-0 overflow-hidden",children:r}),c,e.jsx(Ps,{open:t})]}),!t&&p,t&&d&&e.jsx("div",{className:"border-t border-edge",children:d})]})}const Ws=5e3,Bs=15e3,Dt=8,Ft=30,$s=1,at=new Map,Ce=new Map,on=new Set,$n=[];let Rt=0;function ln(t){return typeof t=="number"&&Number.isFinite(t)}function qe(t,n,s,l){for(t.delete(n),t.set(n,s);t.size>l;){const r=t.keys().next().value;if(!r)break;t.delete(r)}}function On(t,n){const s=t.get(n);return!s?.value||s.expiresAt<=Date.now()?null:(qe(t,n,s,t===Ce?Ft:Dt),s.value)}function Dn(t){return{workdir:t.workdir,agent:t.agent,sessionId:t.sessionId,rich:t.rich??!0,lastNTurns:ln(t.lastNTurns)?t.lastNTurns:void 0,turnOffset:ln(t.turnOffset)?t.turnOffset:void 0,turnLimit:ln(t.turnLimit)?t.turnLimit:void 0}}function bn(t){const n=Dn(t);return[n.workdir,n.agent,n.sessionId,n.rich?"rich":"plain",n.lastNTurns??"",n.turnOffset??"",n.turnLimit??""].join("::")}function Fn(){for(;Rt<$s;){const t=$n.shift();if(!t)return;Rt+=1,t().finally(()=>{Rt=Math.max(0,Rt-1),Fn()})}}async function Os(t,n={}){const s=t;if(!n.force){const c=On(at,s);if(c)return c}const l=at.get(s);if(l?.promise)return l.promise;const r=re.getWorkspaceSessions(t,n.request).then(c=>(qe(at,s,{value:c,expiresAt:c.ok?Date.now()+Ws:0},Dt),c)).finally(()=>{const c=at.get(s);c?.promise&&qe(at,s,{value:c.value,expiresAt:c.expiresAt},Dt)});return qe(at,s,{value:l?.value,expiresAt:l?.expiresAt??0,promise:r},Dt),r}function Ds(t,n={}){const s=bn(t),l=Ce.get(s);return l?.value?.ok&&(n.allowStale||l.expiresAt>Date.now())?l.value:null}async function Fs(t,n={}){const s=Dn(t),l=bn(s);if(!n.force){const p=On(Ce,l);if(p?.ok)return p}const r=Ce.get(l);if(r?.promise)return r.promise;const c=re.getSessionMessages(s.workdir,s.agent,s.sessionId,{rich:s.rich,lastNTurns:s.lastNTurns,turnOffset:s.turnOffset,turnLimit:s.turnLimit},n.request).then(p=>(qe(Ce,l,{value:p,expiresAt:p.ok?Date.now()+Bs:0},Ft),p)).finally(()=>{const p=Ce.get(l);p?.promise&&qe(Ce,l,{value:p.value,expiresAt:p.expiresAt},Ft)});return qe(Ce,l,{value:r?.value,expiresAt:r?.expiresAt??0,promise:c},Ft),c}function Us(t){const n=bn(t);Ds(t)||on.has(n)||Ce.get(n)?.promise||(on.add(n),$n.push(async()=>{try{await Fs(t)}catch{}finally{on.delete(n)}}),Fn())}function yo(t){const n=t.streaming||t.liveStreamPhase==="streaming",s=t.queuedTaskCount>0||t.pendingQueuedCount>0||t.streamPhase==="queued";return n||s}function No(t){const{pendingTaskId:n,streamTaskId:s,queuedTaskIds:l}=t;return!n||n===s?!1:!!l&&l.includes(n)}function zs(t){const{queuedTaskIds:n,streamPhase:s,streamTaskId:l,localTaskId:r}=t,c=[];n&&n.length&&c.push(...n),s==="queued"&&l&&!c.includes(l)&&c.unshift(l),r&&!c.includes(r)&&(s==="queued"||!s)&&c.push(r);const p=s==="streaming"?l??null:null;return p?c.filter(d=>d!==p):c}function So(t,n){return t==null||n==null?!0:t===n}function ut(t){return(t||"").replace(/\s+/g," ").trim()}function Ks(t,n){return ut(t)===ut(n)}function Hs(t,n){const s=ut(t),l=ut(n);return!!s&&!!l&&s!==l&&s.endsWith(l)}function Co(t,n){return n&&(!t||Hs(n,t))?n:t||n||null}function Lo(t,n){if(Ks(t,n))return!0;const s=ut(t),l=ut(n);if(!s||!l||s.length>=l.length||!/(?:\.\.\.|…)$/.test(s))return!1;const r=s.replace(/(?:\s*(?:\.\.\.|…))+$/,"").trim(),c=r.length-4;return c<32?!1:l.startsWith(r.slice(0,c))}function Io(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=Gs(n),l=Math.max(t.window?.totalTurns??t.totalTurns??s.length,s.length),r=t.window?.endTurn??l,c=t.window?.startTurn??Math.max(0,r-s.length);return{turns:s,startTurn:c,endTurn:r,totalTurns:l,hasOlder:t.window?.hasOlder??c>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 Eo(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 Vs(t,n){const s=[t.text,n.text].filter(Boolean);return{role:t.role,text:s.join(`
|
|
3
3
|
|
|
4
4
|
`),blocks:[...t.blocks,...n.blocks],usage:n.usage??t.usage??null}}function Gs(t){const n=[];let s={user:null,assistant:null};for(const l of t)if(l.role==="user"){if(s.assistant&&Un(l.text))continue;(s.user||s.assistant)&&(n.push(s),s={user:null,assistant:null}),s.user=l}else s.assistant?s.assistant=Vs(s.assistant,l):s.assistant=l;return(s.user||s.assistant)&&n.push(s),n}const qs=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"]),Qs=["continued from a previous","summary below covers","earlier portion of the conversation","Summary:","Key Technical Concepts"];function Un(t){const s=t.trim().match(/^<([a-z][a-z0-9_-]*)\b/i);return s&&qs.has(s[1].toLowerCase())?!0:Qs.some(l=>t.includes(l))}function vn(t){return t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${(t/1e3).toFixed(1)}k`:`${t}`}function zn(t){return`${vn(t)} tok`}function Kn(t){return t>=85?"bg-rose-400/70":t>=60?"bg-amber-400/70":"bg-emerald-400/70"}function Ys(t){const n=Math.floor(t/1e3);if(n<60)return`${n}s`;const s=Math.floor(n/60),l=n%60;return s<60?`${s}m${l.toString().padStart(2,"0")}s`:`${Math.floor(s/60)}h${(s%60).toString().padStart(2,"0")}m`}function Hn(t,n){const s=t.split(`
|
|
5
5
|
`).filter(l=>l.trim());return s.length<=n?s.join(`
|
|
@@ -19,5 +19,5 @@ import{c as L,a as re,u as ie,i as Ut,f as _t,A as js,s as zt,S as fe,B as ct,g
|
|
|
19
19
|
`),[d,m]=o.useState(null),b=o.useMemo(()=>qt({workdir:s}),[s]);return!p.trim()&&r.length===0&&c.length===0?null:e.jsxs(e.Fragment,{children:[p.trim()&&e.jsx("div",{className:"session-md text-[13.5px] leading-[1.75] text-fg-2",children:e.jsx(mn,{remarkPlugins:jn,components:b,children:p})}),r.length>0&&e.jsx("div",{className:"flex flex-wrap gap-3 mt-2",children:r.map((g,v)=>e.jsx($r,{block:g,onLightbox:m,t:n},v))}),c.length>0&&e.jsx("div",{className:"flex flex-col gap-2 mt-2",children:c.map((g,v)=>e.jsx(Jn,{url:g.content,fileName:g.fileName||"file",fileSize:g.fileSize,caption:g.fileCaption},v))}),d&&e.jsx(rs,{src:d,onClose:()=>m(null)})]})}const _o=o.memo(function({turn:n,turnIndex:s,agent:l,meta:r,model:c,effort:p,providerName:d,t:m,workdir:b,onResend:g,onEdit:v,onFork:k}){const y=n.user&&Un(n.user.text),$=k&&typeof s=="number"?()=>k(s):void 0,A=o.useMemo(()=>qt({workdir:b}),[b]),W=!!n.assistant&&Ar(n.assistant);return e.jsxs("div",{className:"session-turn",children:[n.user&&!y&&e.jsx(os,{text:n.user.text,blocks:n.user.blocks,t:m,onResend:g,onEdit:v,onFork:$}),y&&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(mn,{remarkPlugins:jn,components:A,children:n.user.text})}),W&&e.jsxs(e.Fragment,{children:[e.jsx(zr,{agent:l,meta:r,model:c,effort:p,providerName:d,previewMeta:n.assistant.usage??null}),e.jsx("div",{className:"mb-6",children:e.jsx(Mr,{message:n.assistant,t:m,workdir:b})})]})]})});function rs({src:t,onClose:n}){return o.useEffect(()=>{const s=l=>{l.key==="Escape"&&n()};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[n]),gn.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 Dr=1500,Fr=16,Mn=8;function Ur(t){const n=t.split(`
|
|
20
20
|
`);return n.length<=Mn?t:n.slice(0,Mn).join(`
|
|
21
21
|
`)}function os({text:t,blocks:n,t:s,onResend:l,onEdit:r,onFork:c}){const[p,d]=o.useState(!1),[m,b]=o.useState(!1),[g,v]=o.useState(null),k=t?t.split(`
|
|
22
|
-
`).length:0,y=!!t&&(t.length>Dr||k>Fr),[$,A]=o.useState(!1),W=t?y&&!$?Ur(t):t:"",O=!!(l||r||c),K=n?.filter(T=>T.type==="image")||[],H=()=>{navigator.clipboard.writeText(t).then(()=>{b(!0),setTimeout(()=>b(!1),1500)}).catch(()=>{})},Z=s("hub.expand").replace("{chars}",t?t.length.toLocaleString():"0").replace("{lines}",String(k));return e.jsxs("div",{className:"flex flex-col items-end mb-5 group/bubble",onMouseEnter:()=>d(!0),onMouseLeave:()=>d(!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:[W,y&&!$&&e.jsx("span",{className:"text-fg-5/60",children:"…"})]}),y&&e.jsx("button",{type:"button",onClick:()=>A(T=>!T),className:"mt-2 text-[11.5px] text-fg-4 hover:text-fg-2 underline decoration-fg-5/40 underline-offset-2 transition-colors",children:$?s("hub.collapse"):Z}),K.length>0&&e.jsx("div",{className:L("flex flex-wrap gap-2",t&&"mt-2"),children:K.map((T,V)=>e.jsx("img",{src:T.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:()=>v(T.content)},V))})]}),g&&e.jsx(rs,{src:g,onClose:()=>v(null)}),O&&e.jsxs("div",{className:L("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(Pt,{label:s(m?"hub.copied":"hub.copy"),onClick:H,children:m?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"})]})}),l&&e.jsx(Pt,{label:s("hub.rerun"),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("polyline",{points:"23 4 23 10 17 10"}),e.jsx("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"})]})}),r&&e.jsx(Pt,{label:s("hub.edit"),onClick:()=>r(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"})]})}),c&&e.jsx(Pt,{label:s("hub.fork"),onClick:c,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 Pt({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 zr({agent:t,meta:n,model:s,effort:l,providerName:r,previewMeta:c,hideContextUsage:p}){const d=p?null:c?.contextPercent??null,m=p?0:c?.contextUsedTokens??0,b=p?0:c?.turnOutputTokens??0,g=d!=null||m>0||b>0,v=c?.providerName??r??null;return e.jsxs("div",{className:"flex items-center gap-1.5 mt-1 mb-3",children:[e.jsx(ct,{brand:t,size:13}),e.jsx("span",{style:{color:n.color},className:"text-[12px] font-semibold opacity-70",children:n.label}),(s||l)&&e.jsxs("span",{className:"text-[10px] font-mono text-fg-5/50",children:[s||"",s&&l?" · ":"",l||""]}),v&&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 ${v} (BYOK), not the agent CLI's native auth.`,children:["via ",v]}),g&&e.jsxs("span",{className:"ml-auto inline-flex items-center gap-1 text-[10px] font-mono text-fg-5/55",title:Kr(c),children:[d!=null&&e.jsx(Hr,{pct:d}),e.jsx("span",{children:d!=null?`${d.toFixed(1)}%`:""}),m>0&&e.jsxs("span",{className:"text-fg-5/40",children:["· ",zn(m)]}),b>0&&e.jsxs("span",{className:"text-fg-5/40",children:["· ↑",vn(b)]})]})]})}function Kr(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 Hr({pct:t}){return e.jsx("span",{className:`h-1.5 w-1.5 rounded-full ${Kn(t)}`})}function An(t,n,s){return t==="zh-CN"?n:s}function Vr({open:t,onClose:n,workdir:s}){const l=ie(c=>c.locale),r=s.split("/").pop()||s;return e.jsxs(Kt,{open:t,onClose:n,wide:!0,children:[e.jsx(Ht,{title:An(l,`${r} — 项目扩展`,`${r} — Project Extensions`),description:An(l,"仅对当前工作区生效。直接操作项目目录中的 .mcp.json 与 .pikiloom/skills/。","Project-scoped only. Operates directly on .mcp.json and .pikiloom/skills/ in the workspace directory."),onClose:n}),t?e.jsx(Rs,{workdir:s}):null]})}let _n=Bn(()=>import("./SessionPanel-DTGtpuIp.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9]));function hn(){return _n??=Bn(()=>import("./SessionPanel-DTGtpuIp.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9])),_n}const Gr=o.lazy(async()=>({default:(await hn()).SessionPanel})),cn=5,qr=240,Qr=120,Yr=12,Xr=900*1e3,q=(t,n)=>`${t}:${n}`;function Zr(t){const n=new Map;for(const d of t)n.set(q(d.agent||"",d.sessionId),d);const s=new Map,l=new Set;for(const d of t){const m=d.migratedFrom;if(!m||m.kind!=="fork"||!m.sessionId)continue;const b=q(m.agent||d.agent||"",m.sessionId);n.has(b)&&(l.add(q(d.agent||"",d.sessionId)),s.has(b)||s.set(b,[]),s.get(b).push(d))}const r=[],c=new Set,p=(d,m)=>{const b=q(d.agent||"",d.sessionId);if(c.has(b))return;c.add(b),r.push(Object.assign({},d,{__forkDepth:m}));const g=s.get(b);if(g)for(const v of g)p(v,m+1)};for(const d of t){const m=q(d.agent||"",d.sessionId);l.has(m)||p(d,0)}for(const d of t)p(d,0);return r}let Jr=0;function Wt(){return`mk-${Date.now().toString(36)}-${(++Jr).toString(36)}`}function Bt(t){try{const n=localStorage.getItem(t);if(n!=null)return n;const s=sessionStorage.getItem(t);if(s!=null){try{localStorage.setItem(t,s),sessionStorage.removeItem(t)}catch{}return s}}catch{}return null}function $t(t,n){try{localStorage.setItem(t,n)}catch{}}const eo=[1,2,3,6],pn=6;function to(t){for(const n of eo)if(n>=t)return n;return pn}function Rn(){const t=typeof window<"u"?window.innerWidth:1280;return t>=1920?3:t>=1280?2:1}function Ge(t,n){const s=to(t);return s>n?s:n}function no(t){return t==="vscode"||t==="cursor"||t==="windsurf"||t==="finder"||t==="default"}function so(t,n){const s=String(t||"").toLowerCase();return s.includes("cursor")?"cursor":s.includes("windsurf")?"windsurf":s.includes("code")||n==="darwin"?"vscode":"default"}function is(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 ro=o.memo(function({active:n=!0}){const s=ie(i=>i.locale),l=ie(i=>i.state?.runtimeWorkdir??null),r=o.useMemo(()=>ys(s),[s]),[c,p]=o.useState([]),[d,m]=o.useState({}),[b,g]=o.useState({}),[v,k]=o.useState(!0),[y,$]=o.useState(()=>{const i=Bt("pikiloom-layout-mode");return i==="1"||i==="2"||i==="3"||i==="6"?Number(i):Rn()}),[A,W]=o.useState(()=>{const i=Bt("pikiloom-layout-floor");return i==="1"||i==="2"||i==="3"||i==="6"?Number(i):Rn()}),[O,K]=o.useState(()=>{try{const i=Bt("pikiloom-open-sessions");if(i){const h=JSON.parse(i);if(Array.isArray(h))return h.map(u=>({...u,mountKey:u.mountKey||Wt()}))}}catch{}return[]}),[H,Z]=o.useState(()=>{const i=Bt("pikiloom-active-slot");if(i!=null){const h=Number(i);if(Number.isFinite(h)&&h>=0)return h}return 0}),T=o.useCallback(i=>{$(i),$t("pikiloom-layout-mode",String(i))},[]),V=o.useCallback(i=>{W(i),$t("pikiloom-layout-floor",String(i))},[]),_=o.useCallback(i=>{K(h=>{const u=typeof i=="function"?i(h):i,x=u.map(({pendingPrompt:w,pendingImageUrls:N,...S})=>S);return $t("pikiloom-open-sessions",JSON.stringify(x)),u})},[]),D=o.useCallback(i=>{Z(h=>{const u=typeof i=="function"?i(h):i;return $t("pikiloom-active-slot",String(u)),u})},[]),C=o.useCallback(i=>{T(i),V(i)},[T,V]);o.useEffect(()=>{_(i=>i.length>y?i.slice(0,y):i),D(i=>i>=y?y-1:i)},[y]);const[E,he]=o.useState(!1),le=o.useRef(y);le.current=y;const Q=o.useRef(A);Q.current=A;const Le=o.useRef(H);Le.current=H;const G=o.useRef(O);G.current=O;const vt=o.useRef(-1),ge=O[H]??null,pt=o.useCallback(i=>{if(!i){_([]),D(0);return}const h=i.mountKey?i:{...i,mountKey:Wt()};_(u=>{const x=u.findIndex(N=>N.agent===h.agent&&N.sessionId===h.sessionId);if(x>=0)return D(x),u;if(u.length<le.current){const N=[...u,h];return D(N.length-1),N}if(le.current<pn){const N=[...u,h];return T(Ge(N.length,Q.current)),D(N.length-1),N}const w=[...u];return w[Le.current]=h,w})},[_,D,T]),[Qe,Ye]=o.useState(!1),[te,$e]=o.useState(null),[Oe,Xe]=o.useState(""),[ne,De]=o.useState("all"),[me,Ze]=o.useState({}),[Ie,jt]=o.useState({}),be=o.useDeferredValue(Oe),ae=o.useRef(!1),Je=o.useRef({}),Te=o.useRef(d);Te.current=d;const wt=o.useRef(me);wt.current=me;const Ee=o.useRef(new Set),ve=o.useRef({});o.useEffect(()=>()=>{for(const i of Object.values(ve.current))clearTimeout(i)},[]),o.useEffect(()=>{_(i=>{let h=!1;const u=i.map(x=>{const w=Ie[x.workdir];if(!w)return x;const N=Ln(w,x.agent,x.sessionId);return N===x.sessionId?x:(h=!0,{...x,sessionId:N})});return h?u:i})},[Ie,_]);const je=o.useCallback(async()=>{try{const i=await re.getWorkspaces(),h=i.ok?i.workspaces:[];h.length&&p(u=>u.length===h.length&&u.every((x,w)=>x.path===h[w].path&&x.name===h[w].name)?u:h),ae.current=!0}catch{ae.current=!0}finally{k(!1)}},[]);o.useEffect(()=>{je()},[je]);const M=o.useCallback(async(i,h={})=>{if(!Je.current[i]){Je.current[i]=!0,h.background||g(u=>({...u,[i]:!0}));try{const u=await Os(i,{force:h.force});o.startTransition(()=>{jt(x=>{const w=u.promotions||{},N=x[i];return N&&Object.keys(N).length===Object.keys(w).length&&Object.entries(w).every(([S,R])=>N[S]===R)?x:{...x,[i]:w}}),m(x=>{const w=u.sessions||[],N=x[i]||[],S=new Set(w.map(U=>q(U.agent||"",U.sessionId))),R=N.filter(U=>{if(U.runState!=="running")return!1;const P=q(U.agent||"",U.sessionId);if(S.has(P))return!1;const F=wt.current[P];return!(F?.resolvedKey&&F.resolvedKey!==P)});return{...x,[i]:R.length?[...R,...w]:w}})})}catch{h.background||o.startTransition(()=>{m(u=>({...u,[i]:[]}))})}finally{Je.current[i]=!1,h.background||g(u=>({...u,[i]:!1}))}}},[]),pe=o.useRef(l);o.useEffect(()=>{l!==pe.current&&(pe.current=l,!(!l||!ae.current)&&je().then(()=>{M(l,{force:!0})}))},[l,je,M]);const J=o.useCallback((i,h)=>{const u=i.agent||"";!u||!i.sessionId||(hn(),Us({workdir:h,agent:u,sessionId:i.sessionId,rich:!0,turnOffset:0,turnLimit:Yr}))},[]),kt=o.useCallback((i,h,u=Qr)=>{const x=`${h}:${q(i.agent||"",i.sessionId)}`,w=ve.current[x];w&&clearTimeout(w),ve.current[x]=setTimeout(()=>{delete ve.current[x],J(i,h)},u)},[J]),Me=o.useCallback((i,h)=>{const u=`${h}:${q(i.agent||"",i.sessionId)}`,x=ve.current[u];x&&(clearTimeout(x),delete ve.current[u])},[]);o.useEffect(()=>{n&&hn()},[n]),o.useEffect(()=>{if(!n)return;const i=[];return c.forEach((h,u)=>{if(d[h.path]||b[h.path])return;const x=setTimeout(()=>{M(h.path)},u*90);i.push(x)}),()=>{for(const h of i)clearTimeout(h)}},[n,M,b,d,c]);const et=o.useRef(new Map);In(n&&ae.current&&c.length>0?"sessions-changed":null,o.useCallback(i=>{if(typeof document<"u"&&document.visibilityState==="hidden")return;const h=i.key,u=h?c.filter(N=>(Te.current[N.path]||[]).some(S=>q(S.agent||"",S.sessionId)===h)):c,x=u.length?u:c,w=et.current;for(const N of x)w.has(N.path)&&clearTimeout(w.get(N.path)),w.set(N.path,setTimeout(()=>{w.delete(N.path),M(N.path,{background:!0,force:!0})},300))},[c,M]));const Fe=o.useCallback(i=>{const h=i.agent||"";return!h||!i.sessionId?i:Ns(i,me[q(h,i.sessionId)]||null)},[me]);In("stream-update",o.useCallback(i=>{const h=i.key;if(!h)return;const u=Ss(h,i.snapshot??null);Ze(x=>{if(!u){const P=x[h];return!P||P.phase==="done"?x:{...x,[h]:{...P,phase:"done",updatedAt:Date.now()}}}const w=(P,F)=>!!P&&!!F&&P.phase===F.phase&&P.resolvedKey===F.resolvedKey&&P.sessionId===F.sessionId&&P.incomplete===F.incomplete&&P.error===F.error,N=w(x[h],u),S=u.resolvedKey===h||w(x[u.resolvedKey],{...u,key:u.resolvedKey});if(N&&S)return x;const R=Date.now()-Xr,U={};for(const[P,F]of Object.entries(x))F.phase==="done"&&F.updatedAt<R||(U[P]=F);return U[h]=u,u.resolvedKey!==h&&(U[u.resolvedKey]={...u,key:u.resolvedKey}),U})},[])),Cs(o.useCallback(()=>{if(!(!n||!ae.current||c.length===0))for(const i of c)M(i.path,{background:!0,force:!0})},[n,c,M])),o.useEffect(()=>{if(!n||!ae.current||c.length===0)return;const i=()=>{if(!(typeof document<"u"&&document.visibilityState==="hidden"))for(const u of c)M(u.path,{background:!0,force:!0})};if(i(),typeof document>"u"||typeof window>"u")return;const h=()=>{document.visibilityState==="visible"&&i()};return document.addEventListener("visibilitychange",h),window.addEventListener("focus",h),()=>{document.removeEventListener("visibilitychange",h),window.removeEventListener("focus",h)}},[n,M,c]),o.useEffect(()=>{if(!n)return;const i=[];return c.forEach((h,u)=>{const x=(d[h.path]||[])[0];if(!x)return;const w=`${h.path}:${q(x.agent||"",x.sessionId)}`;if(Ee.current.has(w))return;const N=setTimeout(()=>{Ee.current.add(w),J(x,h.path)},qr+u*120);i.push(N)}),()=>{for(const h of i)clearTimeout(h)}},[n,d,J,c]);const Qt=o.useCallback(async i=>{try{(await re.addWorkspace(i)).ok&&(Ye(!1),await je(),M(i))}catch{}},[je,M]),[xe,we]=o.useState(null),[ke,yt]=o.useState(!1),[ce,Ue]=o.useState(null),tt=o.useCallback(i=>{we(i)},[]),nt=o.useCallback(async()=>{const i=xe;if(i){yt(!0);try{await re.removeWorkspace(i),p(h=>h.filter(u=>u.path!==i)),m(h=>{const u={...h};return delete u[i],u}),_(h=>{const u=h.filter(x=>x.workdir!==i);return u.length!==h.length&&T(Ge(u.length,Q.current)),u}),D(0),we(null)}catch{}finally{yt(!1)}}},[xe]),st=o.useCallback(i=>{M(i,{force:!0})},[M]),[Ae,ye]=o.useState(null),[ze,xt]=o.useState(!1),[de,rt]=o.useState(!1),ot=ie(i=>i.toast),[oe,_e]=o.useState(null),Nt=o.useCallback((i,h,u)=>{_e({anchor:{right:i.right,bottom:i.bottom},target:{workdir:u,agent:h.agent||"",sessionId:h.sessionId,title:Pn(h).slice(0,120)||h.sessionId.slice(0,16)}})},[]);o.useEffect(()=>{if(!oe)return;const i=()=>_e(null),h=u=>{u.key==="Escape"&&i()};return window.addEventListener("mousedown",i),window.addEventListener("scroll",i,!0),window.addEventListener("resize",i),window.addEventListener("keydown",h),()=>{window.removeEventListener("mousedown",i),window.removeEventListener("scroll",i,!0),window.removeEventListener("resize",i),window.removeEventListener("keydown",h)}},[oe]);const ft=o.useCallback(i=>{xt(!1),ye(i),_e(null)},[]),Ne=o.useCallback(async()=>{const i=Ae;if(i){rt(!0);try{const h=await re.deleteSession(i.workdir,i.agent,i.sessionId,ze);if(!h.ok){const u=h.error?.includes("still running")?r("session.deleteRunningError"):h.error||r("session.deleteFailed");ot(u,!1);return}m(u=>{const x=u[i.workdir];if(!x)return u;const w=x.filter(N=>!(N.agent===i.agent&&N.sessionId===i.sessionId));return w.length===x.length?u:{...u,[i.workdir]:w}}),_(u=>{const x=u.filter(w=>!(w.workdir===i.workdir&&w.agent===i.agent&&w.sessionId===i.sessionId));return x.length!==u.length&&T(Ge(x.length,Q.current)),x}),ye(null)}catch(h){ot(h?.message||r("session.deleteFailed"),!1)}finally{rt(!1)}}},[Ae,ze,r,ot]),St=o.useCallback(i=>{_(h=>{let u=!1;const x=h.map(w=>w.mountKey===i&&(w.pendingPrompt!=null||w.pendingImageUrls)?(u=!0,{...w,pendingPrompt:null,pendingImageUrls:void 0}):w);return u?x:h})},[_]),Ke=o.useCallback((i,h,u)=>{J({agent:i.agent,sessionId:i.sessionId,runState:"running"},i.workdir),m(N=>{const S=N[i.workdir]||[];if(S.some(P=>P.sessionId===i.sessionId&&P.agent===i.agent))return N;const U={sessionId:i.sessionId,agent:i.agent,runState:"running",lastQuestion:h,createdAt:new Date().toISOString(),runUpdatedAt:new Date().toISOString()};return{...N,[i.workdir]:[U,...S]}});const x=vt.current,w={...i,mountKey:Wt(),pendingPrompt:h||null,pendingImageUrls:u&&u.length?u:void 0};o.startTransition(()=>{$e(null),_(N=>{if(x>=N.length)return[...N,w];const S=[...N];return S[x]=w,S}),D(x>=0?x:0)}),M(i.workdir,{background:!0,force:!0})},[M,J,_,D]),Ct=o.useCallback(i=>{G.current.length>=le.current&&le.current<pn&&T(Ge(le.current+1,Q.current)),$e(i)},[T]),Lt=o.useCallback(()=>{$e(null),T(Ge(G.current.length,Q.current))},[T]),It=o.useCallback((i,h)=>{J(i,h);const u=i.agent||"";G.current.some(x=>x.agent===u&&x.sessionId===i.sessionId)&&T(Ge(G.current.length,Q.current)),$e(null),o.startTransition(()=>{pt({agent:u,sessionId:i.sessionId,workdir:h})})},[J,T]),Tt=o.useCallback((i,h)=>{J({agent:i.agent,sessionId:i.sessionId,runState:"running"},i.workdir),o.startTransition(()=>{h!=null?(_(u=>{if(h>=u.length)return u;const x=[...u];return x[h]={...u[h],agent:i.agent,sessionId:i.sessionId,workdir:i.workdir},x}),D(h)):pt({...i,mountKey:Wt()})}),M(i.workdir,{background:!0,force:!0})},[M,J]),ue=o.useCallback(i=>{let h=i;if(ne==="running"?h=h.filter(u=>Ot(u)==="running"):ne==="review"&&(h=h.filter(u=>Ot(u)==="incomplete")),be.trim()){const u=be.toLowerCase();h=h.filter(x=>(x.lastMessageText||"").toLowerCase().includes(u)||(x.lastQuestion||"").toLowerCase().includes(u)||(x.lastAnswer||"").toLowerCase().includes(u)||(x.title||"").toLowerCase().includes(u)||(x.agent||"").toLowerCase().includes(u))}return h},[be,ne]),Et=o.useMemo(()=>{const i={};for(const h of c){const u=(d[h.path]||[]).map(Fe),x=Ie[h.path],w=new Map;for(const S of u){const R=q(S.agent||"",S.sessionId),U=me[R],P=x?Ln(x,S.agent||"",S.sessionId):S.sessionId,F=U?.resolvedKey&&U.resolvedKey!==R?U.resolvedKey:P!==S.sessionId?q(S.agent||"",P):R,Re=w.get(F);if(!Re){w.set(F,S);continue}q(Re.agent||"",Re.sessionId)!==F&&R===F&&w.set(F,S)}const N=ue([...w.values()]);i[h.path]=Zr(N)}return i},[c,d,me,Ie,ue,Fe]),gt=o.useCallback(i=>{const h=(d[i.workdir]||[]).find(u=>u.sessionId===i.sessionId&&u.agent===i.agent)??{sessionId:i.sessionId,agent:i.agent,runState:"running"};return Fe(h)},[Fe,d]),Yt=o.useMemo(()=>new Set(O.map(i=>q(i.agent,i.sessionId))),[O]),Xt=ge?q(ge.agent,ge.sessionId):null,it=o.useCallback(i=>{_(h=>{const u=h.filter((x,w)=>w!==i);return u.length===0?D(0):Le.current>=u.length&&D(u.length-1),T(Ge(u.length,Q.current)),u})},[_,D,T]);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:Oe,onChange:i=>Xe(i.target.value),placeholder:r("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"}),Oe&&e.jsx("button",{onClick:()=>Xe(""),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:()=>De(i),className:L("flex-1 px-2 py-[5px] rounded-md text-[11px] font-medium transition-all duration-200",ne===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:r(`hub.filter${i[0].toUpperCase()+i.slice(1)}`)},i))})]}),e.jsx("div",{className:"flex-1 overflow-y-auto",children:v?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(fe,{className:"h-4 w-4 text-fg-5"})}):c.length===0&&!Qe?e.jsx("div",{className:"py-12 text-center text-[13px] text-fg-5",children:r("hub.noWorkspaces")}):c.map(i=>e.jsx(ao,{workspace:i,sessions:Et[i.path]||[],loading:!!b[i.path]||!(i.path in d),isActive:i.path===l,selectedKey:Xt,openSessionKeys:Yt,onSelectSession:It,onNewSession:Ct,onRefresh:st,onRemove:tt,onExtensions:Ue,onWarmSession:kt,onCancelWarmSession:Me,onSessionMenuOpen:Nt,t:r},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:()=>C(i),className:L("flex-1 flex items-center justify-center p-1.5 rounded transition-all",y===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:r(`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(We,{variant:"ghost",size:"sm",onClick:()=>Ye(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"})]}),r("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(${y===6?3:y}, 1fr)`,gridTemplateRows:y===6?"repeat(2, 1fr)":"1fr"},children:(()=>{const i=te?O.length<y?O.length:H:-1;return vt.current=i,Array.from({length:y},(h,u)=>{if(te&&u===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(io,{workdir:te,workspaceName:c.find(S=>S.path===te)?.name||te.split("/").pop()||"",onSessionCreated:Ke,onClose:Lt,t:r},te)},`new-${te}`);const x=O[u]??null;if(!x)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:r("hub.emptySlot")})]})},`empty-${u}`);const w=gt(x),N=u===H;return e.jsxs("div",{className:L("min-w-0 overflow-hidden rounded-xl border bg-panel flex flex-col transition-[border-color,box-shadow] duration-200",N?"border-primary/40 ring-[3px] ring-primary/[0.06]":"border-edge hover:border-edge-h"),style:{boxShadow:N?"var(--th-card-shadow), 0 0 0 1px rgba(14,165,233,0.08)":"var(--th-card-shadow)"},onClick:()=>D(u),children:[e.jsxs("div",{className:L("shrink-0 flex items-center gap-2 px-2.5 h-8 border-b border-edge/30",N?"bg-primary/[0.03]":"bg-panel/60"),children:[(()=>{const S=Ot(w);return e.jsx(Gt,{variant:S==="running"?"ok":S==="waiting"?"info":S==="incomplete"?"warn":"idle",pulse:S==="running"||S==="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:x.workdir.split("/").pop()||x.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)||(Ut(x.sessionId)?r("hub.newSession"):x.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:r("hub.created"),children:Ls(w.createdAt)}),w.runUpdatedAt&&e.jsx("span",{title:r("hub.updated"),children:Wn(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:S=>{S.stopPropagation(),he(R=>!R)},className:L("p-0.5 rounded transition-colors",E?"text-fg-3 bg-panel-h":"text-fg-5/40 hover:text-fg-3 hover:bg-panel-h"),title:r("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:S=>{S.stopPropagation(),it(u)},className:"p-0.5 rounded text-fg-5/40 hover:text-fg-2 hover:bg-panel-h transition-colors",title:r("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(o.Suspense,{fallback:e.jsx("div",{className:"h-full"}),children:e.jsx(Gr,{session:w,workdir:x.workdir,active:n&&N,onSessionChange:S=>Tt(S,u),initialPendingPrompt:x.pendingPrompt??null,initialPendingImageUrls:x.pendingImageUrls,onPendingPromptConsumed:()=>St(x.mountKey)},x.mountKey)})})]},x.mountKey||q(x.agent,x.sessionId))})})()})}),E&&ge&&e.jsx(uo,{workdir:ge.workdir,onClose:()=>he(!1),t:r}),e.jsx(oo,{open:Qe,initialPath:l||void 0,onAdd:Qt,onClose:()=>Ye(!1),t:r}),e.jsxs(Kt,{open:!!xe,onClose:()=>!ke&&we(null),children:[e.jsx(Ht,{title:r("hub.removeWorkspace"),onClose:()=>!ke&&we(null)}),e.jsx("div",{className:"text-[13px] text-fg-3 leading-relaxed",children:r("modal.confirmRemoveWorkspace")}),e.jsx("div",{className:"mt-1 text-[12px] text-fg-5",children:r("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(We,{variant:"ghost",onClick:()=>we(null),disabled:ke,children:r("modal.cancel")}),e.jsx(We,{variant:"primary",onClick:nt,disabled:ke,className:"!bg-red-500/90 !border-red-500/50 hover:!bg-red-500 !text-white",children:r(ke?"modal.removing":"modal.remove")})]})]}),oe&&(()=>{const h=Math.max(8,Math.min(oe.anchor.right-160,window.innerWidth-160-8)),u=Math.min(oe.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:h,top:u,boxShadow:"0 8px 24px rgba(0,0,0,0.20), 0 2px 6px rgba(0,0,0,0.10)"},onMouseDown:x=>x.stopPropagation(),role:"menu",children:e.jsxs("button",{type:"button",role:"menuitem",onClick:()=>ft(oe.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"})]}),r("session.delete")]})})})(),e.jsxs(Kt,{open:!!Ae,onClose:()=>!de&&ye(null),children:[e.jsx(Ht,{title:r("session.deleteTitle"),onClose:()=>!de&&ye(null)}),e.jsx("div",{className:"text-[13px] text-fg-3 leading-relaxed",children:r("session.deleteHint")}),Ae&&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:Ae.agent}),e.jsx("span",{className:"mx-1.5 text-fg-5/50",children:"·"}),e.jsx("span",{children:Ae.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:!ze,onChange:()=>xt(!1),disabled:de,className:"mt-0.5"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"text-[12px] text-fg-2",children:r("session.deletePikiloomOnly")}),e.jsx("div",{className:"text-[11px] text-fg-5 leading-snug mt-0.5",children:r("session.deletePikiloomOnlyHint")})]})]}),e.jsxs("label",{className:"flex items-start gap-2 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"delete-session-scope",checked:ze,onChange:()=>xt(!0),disabled:de,className:"mt-0.5"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"text-[12px] text-fg-2",children:r("session.deletePurgeNative")}),e.jsx("div",{className:"text-[11px] text-fg-5 leading-snug mt-0.5",children:r("session.deletePurgeNativeHint")})]})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-4",children:[e.jsx(We,{variant:"ghost",onClick:()=>ye(null),disabled:de,children:r("modal.cancel")}),e.jsx(We,{variant:"primary",onClick:Ne,disabled:de,className:"!bg-red-500/90 !border-red-500/50 hover:!bg-red-500 !text-white",children:r(de?"session.deleting":"modal.remove")})]})]}),e.jsx(Vr,{open:!!ce,onClose:()=>Ue(null),workdir:ce||""})]})});function oo({open:t,initialPath:n,onAdd:s,onClose:l,t:r}){const[c,p]=o.useState(""),d=o.useCallback(m=>p(m),[]);return o.useEffect(()=>{t&&p("")},[t]),e.jsxs(Kt,{open:t,onClose:l,children:[e.jsx(Ht,{title:r("hub.addWorkspace"),onClose:l}),e.jsx(Ms,{initialPath:n,maxHeight:360,minHeight:200,onSelect:d,t:r}),e.jsxs("div",{className:"flex gap-2 mt-4",children:[e.jsx(We,{disabled:!c,onClick:()=>c&&s(c),className:"flex-1",children:r("hub.add")}),e.jsx(We,{variant:"secondary",onClick:l,className:"flex-1",children:r("hub.cancel")})]})]})}function io({workdir:t,workspaceName:n,onSessionCreated:s,onClose:l,t:r}){const[c,p]=o.useState(null),[d,m]=o.useState([]),b=o.useRef(null),g=o.useRef([]),v=o.useMemo(()=>({sessionId:"",agent:"",runState:"completed"}),[]),k=o.useCallback(()=>{},[]),y=o.useCallback((W,O)=>{p(W||null),b.current=W||null;const K=O||[];m(K),g.current=K},[]),$=o.useCallback(W=>{const O=g.current;g.current=[],s(W,b.current||void 0,O.length?O:void 0)},[s]),A=!!c||d.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:r("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(Gt,{variant:A?"ok":"idle",pulse:A}),!A&&e.jsx("button",{onClick:l,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:A?e.jsxs("div",{className:"max-w-[900px] mx-auto px-6 py-6 space-y-0",children:[e.jsx(os,{text:c||"",blocks:d.map(W=>({type:"image",content:W})),t:r}),e.jsx("div",{className:"mt-3 mb-4 animate-in",children:e.jsx(ts,{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:r("hub.newSessionHint")})})})}),e.jsx(hr,{session:v,workdir:t,onStreamQueued:k,onSendStart:y,onSessionChange:$,t:r,streamPhase:null})]})}function lo({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(`
|
|
22
|
+
`).length:0,y=!!t&&(t.length>Dr||k>Fr),[$,A]=o.useState(!1),W=t?y&&!$?Ur(t):t:"",O=!!(l||r||c),K=n?.filter(T=>T.type==="image")||[],H=()=>{navigator.clipboard.writeText(t).then(()=>{b(!0),setTimeout(()=>b(!1),1500)}).catch(()=>{})},Z=s("hub.expand").replace("{chars}",t?t.length.toLocaleString():"0").replace("{lines}",String(k));return e.jsxs("div",{className:"flex flex-col items-end mb-5 group/bubble",onMouseEnter:()=>d(!0),onMouseLeave:()=>d(!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:[W,y&&!$&&e.jsx("span",{className:"text-fg-5/60",children:"…"})]}),y&&e.jsx("button",{type:"button",onClick:()=>A(T=>!T),className:"mt-2 text-[11.5px] text-fg-4 hover:text-fg-2 underline decoration-fg-5/40 underline-offset-2 transition-colors",children:$?s("hub.collapse"):Z}),K.length>0&&e.jsx("div",{className:L("flex flex-wrap gap-2",t&&"mt-2"),children:K.map((T,V)=>e.jsx("img",{src:T.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:()=>v(T.content)},V))})]}),g&&e.jsx(rs,{src:g,onClose:()=>v(null)}),O&&e.jsxs("div",{className:L("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(Pt,{label:s(m?"hub.copied":"hub.copy"),onClick:H,children:m?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"})]})}),l&&e.jsx(Pt,{label:s("hub.rerun"),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("polyline",{points:"23 4 23 10 17 10"}),e.jsx("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"})]})}),r&&e.jsx(Pt,{label:s("hub.edit"),onClick:()=>r(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"})]})}),c&&e.jsx(Pt,{label:s("hub.fork"),onClick:c,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 Pt({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 zr({agent:t,meta:n,model:s,effort:l,providerName:r,previewMeta:c,hideContextUsage:p}){const d=p?null:c?.contextPercent??null,m=p?0:c?.contextUsedTokens??0,b=p?0:c?.turnOutputTokens??0,g=d!=null||m>0||b>0,v=c?.providerName??r??null;return e.jsxs("div",{className:"flex items-center gap-1.5 mt-1 mb-3",children:[e.jsx(ct,{brand:t,size:13}),e.jsx("span",{style:{color:n.color},className:"text-[12px] font-semibold opacity-70",children:n.label}),(s||l)&&e.jsxs("span",{className:"text-[10px] font-mono text-fg-5/50",children:[s||"",s&&l?" · ":"",l||""]}),v&&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 ${v} (BYOK), not the agent CLI's native auth.`,children:["via ",v]}),g&&e.jsxs("span",{className:"ml-auto inline-flex items-center gap-1 text-[10px] font-mono text-fg-5/55",title:Kr(c),children:[d!=null&&e.jsx(Hr,{pct:d}),e.jsx("span",{children:d!=null?`${d.toFixed(1)}%`:""}),m>0&&e.jsxs("span",{className:"text-fg-5/40",children:["· ",zn(m)]}),b>0&&e.jsxs("span",{className:"text-fg-5/40",children:["· ↑",vn(b)]})]})]})}function Kr(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 Hr({pct:t}){return e.jsx("span",{className:`h-1.5 w-1.5 rounded-full ${Kn(t)}`})}function An(t,n,s){return t==="zh-CN"?n:s}function Vr({open:t,onClose:n,workdir:s}){const l=ie(c=>c.locale),r=s.split("/").pop()||s;return e.jsxs(Kt,{open:t,onClose:n,wide:!0,children:[e.jsx(Ht,{title:An(l,`${r} — 项目扩展`,`${r} — Project Extensions`),description:An(l,"仅对当前工作区生效。直接操作项目目录中的 .mcp.json 与 .pikiloom/skills/。","Project-scoped only. Operates directly on .mcp.json and .pikiloom/skills/ in the workspace directory."),onClose:n}),t?e.jsx(Rs,{workdir:s}):null]})}let _n=Bn(()=>import("./SessionPanel-C1nonT-C.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9]));function hn(){return _n??=Bn(()=>import("./SessionPanel-C1nonT-C.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9])),_n}const Gr=o.lazy(async()=>({default:(await hn()).SessionPanel})),cn=5,qr=240,Qr=120,Yr=12,Xr=900*1e3,q=(t,n)=>`${t}:${n}`;function Zr(t){const n=new Map;for(const d of t)n.set(q(d.agent||"",d.sessionId),d);const s=new Map,l=new Set;for(const d of t){const m=d.migratedFrom;if(!m||m.kind!=="fork"||!m.sessionId)continue;const b=q(m.agent||d.agent||"",m.sessionId);n.has(b)&&(l.add(q(d.agent||"",d.sessionId)),s.has(b)||s.set(b,[]),s.get(b).push(d))}const r=[],c=new Set,p=(d,m)=>{const b=q(d.agent||"",d.sessionId);if(c.has(b))return;c.add(b),r.push(Object.assign({},d,{__forkDepth:m}));const g=s.get(b);if(g)for(const v of g)p(v,m+1)};for(const d of t){const m=q(d.agent||"",d.sessionId);l.has(m)||p(d,0)}for(const d of t)p(d,0);return r}let Jr=0;function Wt(){return`mk-${Date.now().toString(36)}-${(++Jr).toString(36)}`}function Bt(t){try{const n=localStorage.getItem(t);if(n!=null)return n;const s=sessionStorage.getItem(t);if(s!=null){try{localStorage.setItem(t,s),sessionStorage.removeItem(t)}catch{}return s}}catch{}return null}function $t(t,n){try{localStorage.setItem(t,n)}catch{}}const eo=[1,2,3,6],pn=6;function to(t){for(const n of eo)if(n>=t)return n;return pn}function Rn(){const t=typeof window<"u"?window.innerWidth:1280;return t>=1920?3:t>=1280?2:1}function Ge(t,n){const s=to(t);return s>n?s:n}function no(t){return t==="vscode"||t==="cursor"||t==="windsurf"||t==="finder"||t==="default"}function so(t,n){const s=String(t||"").toLowerCase();return s.includes("cursor")?"cursor":s.includes("windsurf")?"windsurf":s.includes("code")||n==="darwin"?"vscode":"default"}function is(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 ro=o.memo(function({active:n=!0}){const s=ie(i=>i.locale),l=ie(i=>i.state?.runtimeWorkdir??null),r=o.useMemo(()=>ys(s),[s]),[c,p]=o.useState([]),[d,m]=o.useState({}),[b,g]=o.useState({}),[v,k]=o.useState(!0),[y,$]=o.useState(()=>{const i=Bt("pikiloom-layout-mode");return i==="1"||i==="2"||i==="3"||i==="6"?Number(i):Rn()}),[A,W]=o.useState(()=>{const i=Bt("pikiloom-layout-floor");return i==="1"||i==="2"||i==="3"||i==="6"?Number(i):Rn()}),[O,K]=o.useState(()=>{try{const i=Bt("pikiloom-open-sessions");if(i){const h=JSON.parse(i);if(Array.isArray(h))return h.map(u=>({...u,mountKey:u.mountKey||Wt()}))}}catch{}return[]}),[H,Z]=o.useState(()=>{const i=Bt("pikiloom-active-slot");if(i!=null){const h=Number(i);if(Number.isFinite(h)&&h>=0)return h}return 0}),T=o.useCallback(i=>{$(i),$t("pikiloom-layout-mode",String(i))},[]),V=o.useCallback(i=>{W(i),$t("pikiloom-layout-floor",String(i))},[]),_=o.useCallback(i=>{K(h=>{const u=typeof i=="function"?i(h):i,x=u.map(({pendingPrompt:w,pendingImageUrls:N,...S})=>S);return $t("pikiloom-open-sessions",JSON.stringify(x)),u})},[]),D=o.useCallback(i=>{Z(h=>{const u=typeof i=="function"?i(h):i;return $t("pikiloom-active-slot",String(u)),u})},[]),C=o.useCallback(i=>{T(i),V(i)},[T,V]);o.useEffect(()=>{_(i=>i.length>y?i.slice(0,y):i),D(i=>i>=y?y-1:i)},[y]);const[E,he]=o.useState(!1),le=o.useRef(y);le.current=y;const Q=o.useRef(A);Q.current=A;const Le=o.useRef(H);Le.current=H;const G=o.useRef(O);G.current=O;const vt=o.useRef(-1),ge=O[H]??null,pt=o.useCallback(i=>{if(!i){_([]),D(0);return}const h=i.mountKey?i:{...i,mountKey:Wt()};_(u=>{const x=u.findIndex(N=>N.agent===h.agent&&N.sessionId===h.sessionId);if(x>=0)return D(x),u;if(u.length<le.current){const N=[...u,h];return D(N.length-1),N}if(le.current<pn){const N=[...u,h];return T(Ge(N.length,Q.current)),D(N.length-1),N}const w=[...u];return w[Le.current]=h,w})},[_,D,T]),[Qe,Ye]=o.useState(!1),[te,$e]=o.useState(null),[Oe,Xe]=o.useState(""),[ne,De]=o.useState("all"),[me,Ze]=o.useState({}),[Ie,jt]=o.useState({}),be=o.useDeferredValue(Oe),ae=o.useRef(!1),Je=o.useRef({}),Te=o.useRef(d);Te.current=d;const wt=o.useRef(me);wt.current=me;const Ee=o.useRef(new Set),ve=o.useRef({});o.useEffect(()=>()=>{for(const i of Object.values(ve.current))clearTimeout(i)},[]),o.useEffect(()=>{_(i=>{let h=!1;const u=i.map(x=>{const w=Ie[x.workdir];if(!w)return x;const N=Ln(w,x.agent,x.sessionId);return N===x.sessionId?x:(h=!0,{...x,sessionId:N})});return h?u:i})},[Ie,_]);const je=o.useCallback(async()=>{try{const i=await re.getWorkspaces(),h=i.ok?i.workspaces:[];h.length&&p(u=>u.length===h.length&&u.every((x,w)=>x.path===h[w].path&&x.name===h[w].name)?u:h),ae.current=!0}catch{ae.current=!0}finally{k(!1)}},[]);o.useEffect(()=>{je()},[je]);const M=o.useCallback(async(i,h={})=>{if(!Je.current[i]){Je.current[i]=!0,h.background||g(u=>({...u,[i]:!0}));try{const u=await Os(i,{force:h.force});o.startTransition(()=>{jt(x=>{const w=u.promotions||{},N=x[i];return N&&Object.keys(N).length===Object.keys(w).length&&Object.entries(w).every(([S,R])=>N[S]===R)?x:{...x,[i]:w}}),m(x=>{const w=u.sessions||[],N=x[i]||[],S=new Set(w.map(U=>q(U.agent||"",U.sessionId))),R=N.filter(U=>{if(U.runState!=="running")return!1;const P=q(U.agent||"",U.sessionId);if(S.has(P))return!1;const F=wt.current[P];return!(F?.resolvedKey&&F.resolvedKey!==P)});return{...x,[i]:R.length?[...R,...w]:w}})})}catch{h.background||o.startTransition(()=>{m(u=>({...u,[i]:[]}))})}finally{Je.current[i]=!1,h.background||g(u=>({...u,[i]:!1}))}}},[]),pe=o.useRef(l);o.useEffect(()=>{l!==pe.current&&(pe.current=l,!(!l||!ae.current)&&je().then(()=>{M(l,{force:!0})}))},[l,je,M]);const J=o.useCallback((i,h)=>{const u=i.agent||"";!u||!i.sessionId||(hn(),Us({workdir:h,agent:u,sessionId:i.sessionId,rich:!0,turnOffset:0,turnLimit:Yr}))},[]),kt=o.useCallback((i,h,u=Qr)=>{const x=`${h}:${q(i.agent||"",i.sessionId)}`,w=ve.current[x];w&&clearTimeout(w),ve.current[x]=setTimeout(()=>{delete ve.current[x],J(i,h)},u)},[J]),Me=o.useCallback((i,h)=>{const u=`${h}:${q(i.agent||"",i.sessionId)}`,x=ve.current[u];x&&(clearTimeout(x),delete ve.current[u])},[]);o.useEffect(()=>{n&&hn()},[n]),o.useEffect(()=>{if(!n)return;const i=[];return c.forEach((h,u)=>{if(d[h.path]||b[h.path])return;const x=setTimeout(()=>{M(h.path)},u*90);i.push(x)}),()=>{for(const h of i)clearTimeout(h)}},[n,M,b,d,c]);const et=o.useRef(new Map);In(n&&ae.current&&c.length>0?"sessions-changed":null,o.useCallback(i=>{if(typeof document<"u"&&document.visibilityState==="hidden")return;const h=i.key,u=h?c.filter(N=>(Te.current[N.path]||[]).some(S=>q(S.agent||"",S.sessionId)===h)):c,x=u.length?u:c,w=et.current;for(const N of x)w.has(N.path)&&clearTimeout(w.get(N.path)),w.set(N.path,setTimeout(()=>{w.delete(N.path),M(N.path,{background:!0,force:!0})},300))},[c,M]));const Fe=o.useCallback(i=>{const h=i.agent||"";return!h||!i.sessionId?i:Ns(i,me[q(h,i.sessionId)]||null)},[me]);In("stream-update",o.useCallback(i=>{const h=i.key;if(!h)return;const u=Ss(h,i.snapshot??null);Ze(x=>{if(!u){const P=x[h];return!P||P.phase==="done"?x:{...x,[h]:{...P,phase:"done",updatedAt:Date.now()}}}const w=(P,F)=>!!P&&!!F&&P.phase===F.phase&&P.resolvedKey===F.resolvedKey&&P.sessionId===F.sessionId&&P.incomplete===F.incomplete&&P.error===F.error,N=w(x[h],u),S=u.resolvedKey===h||w(x[u.resolvedKey],{...u,key:u.resolvedKey});if(N&&S)return x;const R=Date.now()-Xr,U={};for(const[P,F]of Object.entries(x))F.phase==="done"&&F.updatedAt<R||(U[P]=F);return U[h]=u,u.resolvedKey!==h&&(U[u.resolvedKey]={...u,key:u.resolvedKey}),U})},[])),Cs(o.useCallback(()=>{if(!(!n||!ae.current||c.length===0))for(const i of c)M(i.path,{background:!0,force:!0})},[n,c,M])),o.useEffect(()=>{if(!n||!ae.current||c.length===0)return;const i=()=>{if(!(typeof document<"u"&&document.visibilityState==="hidden"))for(const u of c)M(u.path,{background:!0,force:!0})};if(i(),typeof document>"u"||typeof window>"u")return;const h=()=>{document.visibilityState==="visible"&&i()};return document.addEventListener("visibilitychange",h),window.addEventListener("focus",h),()=>{document.removeEventListener("visibilitychange",h),window.removeEventListener("focus",h)}},[n,M,c]),o.useEffect(()=>{if(!n)return;const i=[];return c.forEach((h,u)=>{const x=(d[h.path]||[])[0];if(!x)return;const w=`${h.path}:${q(x.agent||"",x.sessionId)}`;if(Ee.current.has(w))return;const N=setTimeout(()=>{Ee.current.add(w),J(x,h.path)},qr+u*120);i.push(N)}),()=>{for(const h of i)clearTimeout(h)}},[n,d,J,c]);const Qt=o.useCallback(async i=>{try{(await re.addWorkspace(i)).ok&&(Ye(!1),await je(),M(i))}catch{}},[je,M]),[xe,we]=o.useState(null),[ke,yt]=o.useState(!1),[ce,Ue]=o.useState(null),tt=o.useCallback(i=>{we(i)},[]),nt=o.useCallback(async()=>{const i=xe;if(i){yt(!0);try{await re.removeWorkspace(i),p(h=>h.filter(u=>u.path!==i)),m(h=>{const u={...h};return delete u[i],u}),_(h=>{const u=h.filter(x=>x.workdir!==i);return u.length!==h.length&&T(Ge(u.length,Q.current)),u}),D(0),we(null)}catch{}finally{yt(!1)}}},[xe]),st=o.useCallback(i=>{M(i,{force:!0})},[M]),[Ae,ye]=o.useState(null),[ze,xt]=o.useState(!1),[de,rt]=o.useState(!1),ot=ie(i=>i.toast),[oe,_e]=o.useState(null),Nt=o.useCallback((i,h,u)=>{_e({anchor:{right:i.right,bottom:i.bottom},target:{workdir:u,agent:h.agent||"",sessionId:h.sessionId,title:Pn(h).slice(0,120)||h.sessionId.slice(0,16)}})},[]);o.useEffect(()=>{if(!oe)return;const i=()=>_e(null),h=u=>{u.key==="Escape"&&i()};return window.addEventListener("mousedown",i),window.addEventListener("scroll",i,!0),window.addEventListener("resize",i),window.addEventListener("keydown",h),()=>{window.removeEventListener("mousedown",i),window.removeEventListener("scroll",i,!0),window.removeEventListener("resize",i),window.removeEventListener("keydown",h)}},[oe]);const ft=o.useCallback(i=>{xt(!1),ye(i),_e(null)},[]),Ne=o.useCallback(async()=>{const i=Ae;if(i){rt(!0);try{const h=await re.deleteSession(i.workdir,i.agent,i.sessionId,ze);if(!h.ok){const u=h.error?.includes("still running")?r("session.deleteRunningError"):h.error||r("session.deleteFailed");ot(u,!1);return}m(u=>{const x=u[i.workdir];if(!x)return u;const w=x.filter(N=>!(N.agent===i.agent&&N.sessionId===i.sessionId));return w.length===x.length?u:{...u,[i.workdir]:w}}),_(u=>{const x=u.filter(w=>!(w.workdir===i.workdir&&w.agent===i.agent&&w.sessionId===i.sessionId));return x.length!==u.length&&T(Ge(x.length,Q.current)),x}),ye(null)}catch(h){ot(h?.message||r("session.deleteFailed"),!1)}finally{rt(!1)}}},[Ae,ze,r,ot]),St=o.useCallback(i=>{_(h=>{let u=!1;const x=h.map(w=>w.mountKey===i&&(w.pendingPrompt!=null||w.pendingImageUrls)?(u=!0,{...w,pendingPrompt:null,pendingImageUrls:void 0}):w);return u?x:h})},[_]),Ke=o.useCallback((i,h,u)=>{J({agent:i.agent,sessionId:i.sessionId,runState:"running"},i.workdir),m(N=>{const S=N[i.workdir]||[];if(S.some(P=>P.sessionId===i.sessionId&&P.agent===i.agent))return N;const U={sessionId:i.sessionId,agent:i.agent,runState:"running",lastQuestion:h,createdAt:new Date().toISOString(),runUpdatedAt:new Date().toISOString()};return{...N,[i.workdir]:[U,...S]}});const x=vt.current,w={...i,mountKey:Wt(),pendingPrompt:h||null,pendingImageUrls:u&&u.length?u:void 0};o.startTransition(()=>{$e(null),_(N=>{if(x>=N.length)return[...N,w];const S=[...N];return S[x]=w,S}),D(x>=0?x:0)}),M(i.workdir,{background:!0,force:!0})},[M,J,_,D]),Ct=o.useCallback(i=>{G.current.length>=le.current&&le.current<pn&&T(Ge(le.current+1,Q.current)),$e(i)},[T]),Lt=o.useCallback(()=>{$e(null),T(Ge(G.current.length,Q.current))},[T]),It=o.useCallback((i,h)=>{J(i,h);const u=i.agent||"";G.current.some(x=>x.agent===u&&x.sessionId===i.sessionId)&&T(Ge(G.current.length,Q.current)),$e(null),o.startTransition(()=>{pt({agent:u,sessionId:i.sessionId,workdir:h})})},[J,T]),Tt=o.useCallback((i,h)=>{J({agent:i.agent,sessionId:i.sessionId,runState:"running"},i.workdir),o.startTransition(()=>{h!=null?(_(u=>{if(h>=u.length)return u;const x=[...u];return x[h]={...u[h],agent:i.agent,sessionId:i.sessionId,workdir:i.workdir},x}),D(h)):pt({...i,mountKey:Wt()})}),M(i.workdir,{background:!0,force:!0})},[M,J]),ue=o.useCallback(i=>{let h=i;if(ne==="running"?h=h.filter(u=>Ot(u)==="running"):ne==="review"&&(h=h.filter(u=>Ot(u)==="incomplete")),be.trim()){const u=be.toLowerCase();h=h.filter(x=>(x.lastMessageText||"").toLowerCase().includes(u)||(x.lastQuestion||"").toLowerCase().includes(u)||(x.lastAnswer||"").toLowerCase().includes(u)||(x.title||"").toLowerCase().includes(u)||(x.agent||"").toLowerCase().includes(u))}return h},[be,ne]),Et=o.useMemo(()=>{const i={};for(const h of c){const u=(d[h.path]||[]).map(Fe),x=Ie[h.path],w=new Map;for(const S of u){const R=q(S.agent||"",S.sessionId),U=me[R],P=x?Ln(x,S.agent||"",S.sessionId):S.sessionId,F=U?.resolvedKey&&U.resolvedKey!==R?U.resolvedKey:P!==S.sessionId?q(S.agent||"",P):R,Re=w.get(F);if(!Re){w.set(F,S);continue}q(Re.agent||"",Re.sessionId)!==F&&R===F&&w.set(F,S)}const N=ue([...w.values()]);i[h.path]=Zr(N)}return i},[c,d,me,Ie,ue,Fe]),gt=o.useCallback(i=>{const h=(d[i.workdir]||[]).find(u=>u.sessionId===i.sessionId&&u.agent===i.agent)??{sessionId:i.sessionId,agent:i.agent,runState:"running"};return Fe(h)},[Fe,d]),Yt=o.useMemo(()=>new Set(O.map(i=>q(i.agent,i.sessionId))),[O]),Xt=ge?q(ge.agent,ge.sessionId):null,it=o.useCallback(i=>{_(h=>{const u=h.filter((x,w)=>w!==i);return u.length===0?D(0):Le.current>=u.length&&D(u.length-1),T(Ge(u.length,Q.current)),u})},[_,D,T]);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:Oe,onChange:i=>Xe(i.target.value),placeholder:r("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"}),Oe&&e.jsx("button",{onClick:()=>Xe(""),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:()=>De(i),className:L("flex-1 px-2 py-[5px] rounded-md text-[11px] font-medium transition-all duration-200",ne===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:r(`hub.filter${i[0].toUpperCase()+i.slice(1)}`)},i))})]}),e.jsx("div",{className:"flex-1 overflow-y-auto",children:v?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(fe,{className:"h-4 w-4 text-fg-5"})}):c.length===0&&!Qe?e.jsx("div",{className:"py-12 text-center text-[13px] text-fg-5",children:r("hub.noWorkspaces")}):c.map(i=>e.jsx(ao,{workspace:i,sessions:Et[i.path]||[],loading:!!b[i.path]||!(i.path in d),isActive:i.path===l,selectedKey:Xt,openSessionKeys:Yt,onSelectSession:It,onNewSession:Ct,onRefresh:st,onRemove:tt,onExtensions:Ue,onWarmSession:kt,onCancelWarmSession:Me,onSessionMenuOpen:Nt,t:r},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:()=>C(i),className:L("flex-1 flex items-center justify-center p-1.5 rounded transition-all",y===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:r(`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(We,{variant:"ghost",size:"sm",onClick:()=>Ye(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"})]}),r("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(${y===6?3:y}, 1fr)`,gridTemplateRows:y===6?"repeat(2, 1fr)":"1fr"},children:(()=>{const i=te?O.length<y?O.length:H:-1;return vt.current=i,Array.from({length:y},(h,u)=>{if(te&&u===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(io,{workdir:te,workspaceName:c.find(S=>S.path===te)?.name||te.split("/").pop()||"",onSessionCreated:Ke,onClose:Lt,t:r},te)},`new-${te}`);const x=O[u]??null;if(!x)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:r("hub.emptySlot")})]})},`empty-${u}`);const w=gt(x),N=u===H;return e.jsxs("div",{className:L("min-w-0 overflow-hidden rounded-xl border bg-panel flex flex-col transition-[border-color,box-shadow] duration-200",N?"border-primary/40 ring-[3px] ring-primary/[0.06]":"border-edge hover:border-edge-h"),style:{boxShadow:N?"var(--th-card-shadow), 0 0 0 1px rgba(14,165,233,0.08)":"var(--th-card-shadow)"},onClick:()=>D(u),children:[e.jsxs("div",{className:L("shrink-0 flex items-center gap-2 px-2.5 h-8 border-b border-edge/30",N?"bg-primary/[0.03]":"bg-panel/60"),children:[(()=>{const S=Ot(w);return e.jsx(Gt,{variant:S==="running"?"ok":S==="waiting"?"info":S==="incomplete"?"warn":"idle",pulse:S==="running"||S==="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:x.workdir.split("/").pop()||x.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)||(Ut(x.sessionId)?r("hub.newSession"):x.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:r("hub.created"),children:Ls(w.createdAt)}),w.runUpdatedAt&&e.jsx("span",{title:r("hub.updated"),children:Wn(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:S=>{S.stopPropagation(),he(R=>!R)},className:L("p-0.5 rounded transition-colors",E?"text-fg-3 bg-panel-h":"text-fg-5/40 hover:text-fg-3 hover:bg-panel-h"),title:r("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:S=>{S.stopPropagation(),it(u)},className:"p-0.5 rounded text-fg-5/40 hover:text-fg-2 hover:bg-panel-h transition-colors",title:r("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(o.Suspense,{fallback:e.jsx("div",{className:"h-full"}),children:e.jsx(Gr,{session:w,workdir:x.workdir,active:n&&N,onSessionChange:S=>Tt(S,u),initialPendingPrompt:x.pendingPrompt??null,initialPendingImageUrls:x.pendingImageUrls,onPendingPromptConsumed:()=>St(x.mountKey)},x.mountKey)})})]},x.mountKey||q(x.agent,x.sessionId))})})()})}),E&&ge&&e.jsx(uo,{workdir:ge.workdir,onClose:()=>he(!1),t:r}),e.jsx(oo,{open:Qe,initialPath:l||void 0,onAdd:Qt,onClose:()=>Ye(!1),t:r}),e.jsxs(Kt,{open:!!xe,onClose:()=>!ke&&we(null),children:[e.jsx(Ht,{title:r("hub.removeWorkspace"),onClose:()=>!ke&&we(null)}),e.jsx("div",{className:"text-[13px] text-fg-3 leading-relaxed",children:r("modal.confirmRemoveWorkspace")}),e.jsx("div",{className:"mt-1 text-[12px] text-fg-5",children:r("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(We,{variant:"ghost",onClick:()=>we(null),disabled:ke,children:r("modal.cancel")}),e.jsx(We,{variant:"primary",onClick:nt,disabled:ke,className:"!bg-red-500/90 !border-red-500/50 hover:!bg-red-500 !text-white",children:r(ke?"modal.removing":"modal.remove")})]})]}),oe&&(()=>{const h=Math.max(8,Math.min(oe.anchor.right-160,window.innerWidth-160-8)),u=Math.min(oe.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:h,top:u,boxShadow:"0 8px 24px rgba(0,0,0,0.20), 0 2px 6px rgba(0,0,0,0.10)"},onMouseDown:x=>x.stopPropagation(),role:"menu",children:e.jsxs("button",{type:"button",role:"menuitem",onClick:()=>ft(oe.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"})]}),r("session.delete")]})})})(),e.jsxs(Kt,{open:!!Ae,onClose:()=>!de&&ye(null),children:[e.jsx(Ht,{title:r("session.deleteTitle"),onClose:()=>!de&&ye(null)}),e.jsx("div",{className:"text-[13px] text-fg-3 leading-relaxed",children:r("session.deleteHint")}),Ae&&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:Ae.agent}),e.jsx("span",{className:"mx-1.5 text-fg-5/50",children:"·"}),e.jsx("span",{children:Ae.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:!ze,onChange:()=>xt(!1),disabled:de,className:"mt-0.5"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"text-[12px] text-fg-2",children:r("session.deletePikiloomOnly")}),e.jsx("div",{className:"text-[11px] text-fg-5 leading-snug mt-0.5",children:r("session.deletePikiloomOnlyHint")})]})]}),e.jsxs("label",{className:"flex items-start gap-2 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"delete-session-scope",checked:ze,onChange:()=>xt(!0),disabled:de,className:"mt-0.5"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"text-[12px] text-fg-2",children:r("session.deletePurgeNative")}),e.jsx("div",{className:"text-[11px] text-fg-5 leading-snug mt-0.5",children:r("session.deletePurgeNativeHint")})]})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-4",children:[e.jsx(We,{variant:"ghost",onClick:()=>ye(null),disabled:de,children:r("modal.cancel")}),e.jsx(We,{variant:"primary",onClick:Ne,disabled:de,className:"!bg-red-500/90 !border-red-500/50 hover:!bg-red-500 !text-white",children:r(de?"session.deleting":"modal.remove")})]})]}),e.jsx(Vr,{open:!!ce,onClose:()=>Ue(null),workdir:ce||""})]})});function oo({open:t,initialPath:n,onAdd:s,onClose:l,t:r}){const[c,p]=o.useState(""),d=o.useCallback(m=>p(m),[]);return o.useEffect(()=>{t&&p("")},[t]),e.jsxs(Kt,{open:t,onClose:l,children:[e.jsx(Ht,{title:r("hub.addWorkspace"),onClose:l}),e.jsx(Ms,{initialPath:n,maxHeight:360,minHeight:200,onSelect:d,t:r}),e.jsxs("div",{className:"flex gap-2 mt-4",children:[e.jsx(We,{disabled:!c,onClick:()=>c&&s(c),className:"flex-1",children:r("hub.add")}),e.jsx(We,{variant:"secondary",onClick:l,className:"flex-1",children:r("hub.cancel")})]})]})}function io({workdir:t,workspaceName:n,onSessionCreated:s,onClose:l,t:r}){const[c,p]=o.useState(null),[d,m]=o.useState([]),b=o.useRef(null),g=o.useRef([]),v=o.useMemo(()=>({sessionId:"",agent:"",runState:"completed"}),[]),k=o.useCallback(()=>{},[]),y=o.useCallback((W,O)=>{p(W||null),b.current=W||null;const K=O||[];m(K),g.current=K},[]),$=o.useCallback(W=>{const O=g.current;g.current=[],s(W,b.current||void 0,O.length?O:void 0)},[s]),A=!!c||d.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:r("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(Gt,{variant:A?"ok":"idle",pulse:A}),!A&&e.jsx("button",{onClick:l,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:A?e.jsxs("div",{className:"max-w-[900px] mx-auto px-6 py-6 space-y-0",children:[e.jsx(os,{text:c||"",blocks:d.map(W=>({type:"image",content:W})),t:r}),e.jsx("div",{className:"mt-3 mb-4 animate-in",children:e.jsx(ts,{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:r("hub.newSessionHint")})})})}),e.jsx(hr,{session:v,workdir:t,onStreamQueued:k,onSendStart:y,onSessionChange:$,t:r,streamPhase:null})]})}function lo({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
23
|
`);return e.jsx(Is,{content:n,className:L("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 ao=o.memo(function({workspace:n,sessions:s,loading:l,isActive:r,selectedKey:c,openSessionKeys:p,onSelectSession:d,onNewSession:m,onRefresh:b,onRemove:g,onExtensions:v,onWarmSession:k,onCancelWarmSession:y,onSessionMenuOpen:$,t:A}){const[W,O]=o.useState(!0),[K,H]=o.useState(cn);o.useEffect(()=>{H(cn)},[s.length]);const Z=s.slice(0,K),T=s.length-K,V=n.path,[_,D]=o.useState(null),C=o.useCallback(()=>{re.getWorkspaceGit(V).then(E=>D(E.git)).catch(()=>D(null))},[V]);return o.useEffect(()=>{C()},[C]),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:()=>O(E=>!E),children:[e.jsx("svg",{width:"9",height:"9",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:L("shrink-0 text-fg-5 transition-transform duration-150",W&&"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:L("min-w-0 truncate text-[12px] font-semibold",r?"text-primary":"text-fg-3"),children:n.name}),e.jsx(lo,{git:_})]}),r&&e.jsx(Gt,{variant:"ok"}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[e.jsx("button",{onClick:E=>{E.stopPropagation(),m(V)},className:"p-1 rounded text-fg-5 hover:text-primary hover:bg-panel-h/60 transition-colors",title:A("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:E=>{E.stopPropagation(),v(V)},className:"p-1 rounded text-fg-5 hover:text-primary hover:bg-panel-h/60 transition-colors",title:A("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:E=>{E.stopPropagation(),b(V),C()},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"})]})}),!r&&e.jsx("button",{onClick:E=>{E.stopPropagation(),g(V)},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"})]})})]})]}),W&&e.jsx("div",{className:"pb-1",children:l?e.jsx("div",{className:"flex items-center justify-center py-4",children:e.jsx(fe,{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:A("sessions.noSessions")}):e.jsxs(e.Fragment,{children:[Z.map(E=>{const he=q(E.agent||"",E.sessionId),le=E.__forkDepth||0;return e.jsx(co,{session:E,isSelected:c===he,isOpen:p?.has(he)??!1,forkDepth:le,onClick:()=>d(E,V),onWarm:()=>k(E,V),onCancelWarm:()=>y(E,V),onShowMenu:Q=>$(Q,E,V),menuLabel:A("session.openActions")},he)}),T>0&&e.jsxs("button",{onClick:()=>H(E=>E+cn),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:["+ ",A("hub.nMore").replace("{n}",String(T))]}),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"})})]})]})})]})}),co=o.memo(function({session:n,isSelected:s,isOpen:l,forkDepth:r=0,onClick:c,onWarm:p,onCancelWarm:d,onShowMenu:m,menuLabel:b}){const g=dn(n.agent||""),v=Ot(n),k=Pn(n).slice(0,500)||(Ut(n.sessionId)?"":n.sessionId.slice(0,16)),y=Ts(n,k).slice(0,500),$=n.model?zt(n.model):null,A=r>0?Math.min(r,3)*14:0,W=l?10:12,O=o.useRef(null);return e.jsxs("div",{className:"relative group",children:[e.jsxs("button",{onClick:c,onMouseEnter:p,onFocus:p,onMouseLeave:d,onBlur:d,className:L("w-full pr-3 py-2 text-left transition-all duration-100",s?"bg-selected hover:bg-selected-h":l?"bg-panel-h/30 hover:bg-panel-h/50":"hover:bg-panel-h/50"),style:{paddingLeft:W+A,...l?{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:[r>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(ct,{brand:n.agent||"",size:10}),e.jsx("span",{className:"font-medium shrink-0",style:{color:g.color},children:g.shortLabel}),$&&e.jsx("span",{className:"truncate max-w-[72px] font-mono text-fg-5/40 text-[9px]",children:$}),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:Wn(n.runUpdatedAt||n.createdAt)})]})]}),e.jsxs("div",{className:"mt-1 flex items-center gap-1.5",children:[e.jsx(Gt,{variant:v==="running"?"ok":v==="waiting"?"info":v==="incomplete"?"warn":"idle",pulse:v==="running"||v==="waiting"}),e.jsx("span",{className:"truncate text-[12px] leading-snug text-fg-2",children:k})]}),y&&e.jsx("div",{className:"mt-0.5 pl-[11px]",children:e.jsx("span",{className:"block truncate text-[10px] leading-snug text-fg-5",children:y})})]}),e.jsx("button",{ref:O,type:"button","aria-label":b,"aria-haspopup":"menu",onMouseDown:K=>{K.stopPropagation()},onClick:K=>{K.stopPropagation(),K.preventDefault(),O.current&&m(O.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"})]})})]})}),uo=o.memo(function({workdir:n,onClose:s,t:l}){const r=ie(g=>g.state?.hostApp??null),c=ie(g=>g.state?.platform??null),p=ie(g=>g.toast),[d,m]=o.useState(()=>so(r,c)),b=o.useCallback(async g=>{try{const v=await re.openInEditor(g,d);if(!v.ok)throw new Error(v.error||`Failed to open ${g}`)}catch(v){p(v?.message||String(v),!1)}},[d,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:l("hub.files")}),e.jsx("button",{onClick:s,className:"p-0.5 rounded text-fg-5/40 hover:text-fg-2 transition-colors",title:l("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(Es,{value:d,options:(c==="darwin"?["vscode","finder"]:["vscode"]).map(g=>({value:g,label:l(is(g))})),onChange:g=>{no(g)&&m(g)},renderIcon:g=>e.jsx(ls,{target:g,size:14})}),e.jsx(We,{size:"sm",variant:"ghost",onClick:()=>b(n),className:"flex-1 min-w-0 text-[11px]",children:l("hub.openProject")})]}),e.jsx("div",{className:"flex-1 overflow-y-auto px-1 py-1.5",children:e.jsx(ho,{basePath:n,openTarget:d,onOpenPath:b,t:l})})]})});function ls({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(ct,{brand:t,size:n})}function ho({basePath:t,includeHidden:n=!1,openTarget:s,onOpenPath:l,t:r}){const[c,p]=o.useState([]),[d,m]=o.useState(!0);o.useEffect(()=>{let g=!1;return m(!0),re.lsDir(t,!0,n).then(v=>{!g&&v.ok&&p(v.dirs.slice(0,50).map(k=>({entry:k,expanded:!1,children:null,loading:!1})))}).catch(()=>{}).finally(()=>{g||m(!1)}),()=>{g=!0}},[t,n]);const b=o.useCallback(g=>{const v=k=>k.map(y=>y.entry.path===g?y.expanded?{...y,expanded:!1}:y.children===null?(re.lsDir(g,!0,n).then($=>{$.ok&&p(A=>xn(A,g,{children:$.dirs.slice(0,50).map(W=>({entry:W,expanded:!1,children:null,loading:!1})),loading:!1}))}).catch(()=>{p($=>xn($,g,{children:[],loading:!1}))}),{...y,loading:!0,expanded:!0}):{...y,expanded:!0}:y.children?{...y,children:v(y.children)}:y);p(k=>v(k))},[n]);return d?e.jsx("div",{className:"flex justify-center py-3",children:e.jsx(fe,{className:"h-3 w-3 text-fg-5"})}):c.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(as,{nodes:c,depth:0,onToggle:b,openTarget:s,onOpenPath:l,t:r})})}function as({nodes:t,depth:n,onToggle:s,openTarget:l,onOpenPath:r,t:c}){return e.jsx(e.Fragment,{children:t.map(p=>e.jsx(po,{node:p,depth:n,onToggle:s,openTarget:l,onOpenPath:r,t:c},p.entry.path))})}function po({node:t,depth:n,onToggle:s,openTarget:l,onOpenPath:r,t:c}){const{entry:p,expanded:d,children:m,loading:b}=t,g=n*14,[v,k]=o.useState(!1),y=c(is(l)),$=c("hub.openWithTarget").replace("{target}",y);return e.jsxs(e.Fragment,{children:[e.jsxs("div",{onClick:p.isDir?()=>s(p.path):void 0,onMouseEnter:()=>k(!0),onMouseLeave:()=>k(!1),className:L("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?b?e.jsx(fe,{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:L("shrink-0 text-fg-5/40 transition-transform duration-150",d&&"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}),v&&e.jsxs("div",{className:"flex items-center gap-0.5 shrink-0",children:[e.jsx("button",{onClick:A=>{A.stopPropagation(),r(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:$,children:e.jsx(ls,{target:l,subtle:!0})}),!p.isDir&&e.jsx(xo,{filePath:p.path,t:c})]})]}),p.isDir&&d&&m&&m.length>0&&e.jsx(as,{nodes:m,depth:n+1,onToggle:s,openTarget:l,onOpenPath:r,t:c})]})}function xo({filePath:t,t:n}){const[s,l]=o.useState(!1);return e.jsx("button",{onClick:r=>{r.stopPropagation(),navigator.clipboard.writeText(t).then(()=>{l(!0),setTimeout(()=>l(!1),1500)}).catch(()=>{})},className:L("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 xn(t,n,s){return t.map(l=>l.entry.path===n?{...l,...s}:l.children?{...l,children:xn(l.children,n,s)}:l)}const Ro=Object.freeze(Object.defineProperty({__proto__:null,SessionWorkspace:ro},Symbol.toStringTag,{value:"Module"}));export{hr as I,Ao as L,Sr as R,_o as T,os as U,To as a,es as b,Ks as c,So as d,Co as e,Hs as f,Lo as g,ts as h,Mo as i,zr as j,Ro as k,Fs as l,Eo as m,Io as n,No as o,Ds as p,yo as s};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as s}from"./react-vendor-C7Sl8SE7.js";import{O as t,m as i,S as a}from"./index-
|
|
1
|
+
import{j as s}from"./react-vendor-C7Sl8SE7.js";import{O as t,m as i,S as a}from"./index-BGne9zh7.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,10 +6,10 @@
|
|
|
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-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-BGne9zh7.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
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
12
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BcPBJtn2.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<div id="root"></div>
|
package/dist/agent/accounts.js
CHANGED
|
@@ -8,7 +8,7 @@ import { randomUUID } from 'node:crypto';
|
|
|
8
8
|
import { loadUserConfig, saveUserConfig } from '../core/config/user-config.js';
|
|
9
9
|
import { persistSecret, forgetSecret, resolveCredential, isCredentialRef } from '../core/secrets/index.js';
|
|
10
10
|
import { loadKernel } from './kernel-bridge.js';
|
|
11
|
-
import { claudeUsageForToken } from './drivers/claude.js';
|
|
11
|
+
import { claudeUsageForToken, claudeNativeUsage } from './drivers/claude.js';
|
|
12
12
|
import { agentWarn } from './utils.js';
|
|
13
13
|
// Agents whose local accounts are switched by a token (kept in sync with the kernel).
|
|
14
14
|
const ACCOUNT_AGENTS = new Set(['claude']);
|
|
@@ -169,6 +169,38 @@ export function warmAccountUsages(agent) {
|
|
|
169
169
|
for (const rec of listAccounts(agent))
|
|
170
170
|
void probeAccountUsage(agent, rec.id);
|
|
171
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* THE query channel for "who can this agent run as, and how much quota does each identity have".
|
|
174
|
+
* Every consumer (dashboard header popover, accounts panel, IM /status) reads through here so all
|
|
175
|
+
* rows come from one pass and share one freshness policy. `fresh: true` is for surfaces the user
|
|
176
|
+
* is actively looking at: it re-probes past the short fresh window (20s tokens / 15s native)
|
|
177
|
+
* instead of the 5min background TTL — the debounce lives in the driver-level caches, so callers
|
|
178
|
+
* can request fresh on every view without stampeding probes.
|
|
179
|
+
*/
|
|
180
|
+
export async function getAccountsUsageSnapshot(agent, opts) {
|
|
181
|
+
if (!accountAgentSupported(agent))
|
|
182
|
+
return { supported: false, activeAccountId: null, accounts: [], native: null };
|
|
183
|
+
const recs = listAccounts(agent);
|
|
184
|
+
const activeId = getActiveAccountId(agent);
|
|
185
|
+
const fresh = opts?.fresh === true;
|
|
186
|
+
const [native, ...usages] = await Promise.all([
|
|
187
|
+
claudeNativeUsage({ fresh }).catch(() => null),
|
|
188
|
+
...recs.map(rec => probeAccountUsage(agent, rec.id, { fresh }).catch(() => getCachedAccountUsage(agent, rec.id))),
|
|
189
|
+
]);
|
|
190
|
+
return {
|
|
191
|
+
supported: true,
|
|
192
|
+
activeAccountId: activeId,
|
|
193
|
+
accounts: recs.map((rec, i) => ({
|
|
194
|
+
id: rec.id,
|
|
195
|
+
label: rec.label,
|
|
196
|
+
createdAt: rec.createdAt,
|
|
197
|
+
lastUsedAt: rec.lastUsedAt ?? null,
|
|
198
|
+
active: rec.id === activeId,
|
|
199
|
+
usage: usages[i] ?? getCachedAccountUsage(agent, rec.id),
|
|
200
|
+
})),
|
|
201
|
+
native,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
172
204
|
/** Compact "5h 100% · 7d 19%" summary from the cached usage, or null. */
|
|
173
205
|
export function accountUsageSummary(agent, id) {
|
|
174
206
|
const usage = getCachedAccountUsage(agent, id);
|
|
@@ -195,10 +195,25 @@ function recomputeClaudeContextUsed(s) {
|
|
|
195
195
|
input: s.inputTokens,
|
|
196
196
|
cached: s.cachedInputTokens,
|
|
197
197
|
cacheCreation: s.cacheCreationInputTokens,
|
|
198
|
-
|
|
198
|
+
// While a message is still streaming, the CLI's live thinking estimate is often the only
|
|
199
|
+
// output signal (subscription accounts stream no plaintext thinking and no usage until the
|
|
200
|
+
// message settles); the real output_tokens supersedes it at message_delta.
|
|
201
|
+
output: Math.max(s.outputTokens ?? 0, s.thinkingEstTokens ?? 0),
|
|
199
202
|
});
|
|
200
203
|
s.contextUsedTokens = total > 0 ? total : null;
|
|
201
204
|
}
|
|
205
|
+
// Accumulate the CLI's live thinking-token estimate (system/thinking_tokens events). Prefer the
|
|
206
|
+
// per-event delta (correct whether the CLI's running total is per-message or per-turn); fall back
|
|
207
|
+
// to a monotonic max of the running total.
|
|
208
|
+
function applyClaudeThinkingEstimate(s, ev) {
|
|
209
|
+
const prev = s.thinkingEstTokens ?? 0;
|
|
210
|
+
const delta = Number(ev?.estimated_tokens_delta);
|
|
211
|
+
const total = Number(ev?.estimated_tokens);
|
|
212
|
+
if (Number.isFinite(delta) && delta > 0)
|
|
213
|
+
s.thinkingEstTokens = prev + delta;
|
|
214
|
+
else if (Number.isFinite(total))
|
|
215
|
+
s.thinkingEstTokens = Math.max(prev, total);
|
|
216
|
+
}
|
|
202
217
|
const CLAUDE_FILE_READING_TOOLS = new Set(['Read']);
|
|
203
218
|
function isClaudeFileReadingTool(toolName) {
|
|
204
219
|
return !!toolName && CLAUDE_FILE_READING_TOOLS.has(toolName);
|
|
@@ -410,16 +425,25 @@ export function claudeParse(ev, s) {
|
|
|
410
425
|
const advertised = claudeContextWindowFromModel(s.model);
|
|
411
426
|
s.contextWindow = claudeEffectiveContextWindow(advertised) ?? s.contextWindow;
|
|
412
427
|
}
|
|
428
|
+
// Live thinking progress: during extended thinking a subscription account streams no
|
|
429
|
+
// plaintext (signature_delta only) and no usage until the message settles — these estimates
|
|
430
|
+
// are the only sign the model is working.
|
|
431
|
+
if (ev.subtype === 'thinking_tokens') {
|
|
432
|
+
applyClaudeThinkingEstimate(s, ev);
|
|
433
|
+
recomputeClaudeContextUsed(s);
|
|
434
|
+
}
|
|
413
435
|
}
|
|
414
436
|
if (t === 'stream_event') {
|
|
415
437
|
const inner = ev.event || {};
|
|
416
438
|
if (inner.type === 'message_start') {
|
|
417
439
|
const u = inner.message?.usage;
|
|
418
|
-
|
|
440
|
+
// A message that never delivered real output_tokens keeps its thinking estimate as the carry.
|
|
441
|
+
s.turnOutputTokensBase = (s.turnOutputTokensBase ?? 0) + Math.max(s.outputTokens ?? 0, s.thinkingEstTokens ?? 0);
|
|
419
442
|
s.inputTokens = u?.input_tokens ?? 0;
|
|
420
443
|
s.cachedInputTokens = u?.cache_read_input_tokens ?? 0;
|
|
421
444
|
s.cacheCreationInputTokens = u?.cache_creation_input_tokens ?? 0;
|
|
422
445
|
s.outputTokens = 0;
|
|
446
|
+
s.thinkingEstTokens = 0;
|
|
423
447
|
recomputeClaudeContextUsed(s);
|
|
424
448
|
}
|
|
425
449
|
if (inner.type === 'content_block_start') {
|
|
@@ -449,8 +473,11 @@ export function claudeParse(ev, s) {
|
|
|
449
473
|
s.cachedInputTokens = u.cache_read_input_tokens;
|
|
450
474
|
if (u.cache_creation_input_tokens != null)
|
|
451
475
|
s.cacheCreationInputTokens = u.cache_creation_input_tokens;
|
|
452
|
-
|
|
476
|
+
// Real reported output supersedes the live thinking estimate for this message.
|
|
477
|
+
if (u.output_tokens != null) {
|
|
453
478
|
s.outputTokens = u.output_tokens;
|
|
479
|
+
s.thinkingEstTokens = 0;
|
|
480
|
+
}
|
|
454
481
|
recomputeClaudeContextUsed(s);
|
|
455
482
|
}
|
|
456
483
|
}
|
|
@@ -684,6 +711,7 @@ export function createClaudeStreamState(opts) {
|
|
|
684
711
|
cachedInputTokens: null,
|
|
685
712
|
cacheCreationInputTokens: null,
|
|
686
713
|
turnOutputTokensBase: 0,
|
|
714
|
+
thinkingEstTokens: 0,
|
|
687
715
|
turnUsageMsgId: null,
|
|
688
716
|
contextWindow: byokWindow,
|
|
689
717
|
byokContextWindow: byokWindow,
|
|
@@ -719,6 +747,7 @@ function resetClaudeTurnState(s, note) {
|
|
|
719
747
|
s.inputTokens = null;
|
|
720
748
|
s.outputTokens = null;
|
|
721
749
|
s.turnOutputTokensBase = 0;
|
|
750
|
+
s.thinkingEstTokens = 0;
|
|
722
751
|
s.turnUsageMsgId = null;
|
|
723
752
|
s.cachedInputTokens = null;
|
|
724
753
|
s.cacheCreationInputTokens = null;
|
|
@@ -1586,7 +1615,11 @@ function getClaudeSessionMessages(opts) {
|
|
|
1586
1615
|
displayText = rawText.replace(CLAUDE_AT_MENTION_IMAGE_RE, (full, leading, p) => recoveredPaths.has(p) ? (leading || '') : full);
|
|
1587
1616
|
}
|
|
1588
1617
|
}
|
|
1589
|
-
|
|
1618
|
+
// Preserve the user's line breaks: this is the actual message body shown in the bubble
|
|
1619
|
+
// (whitespace-pre-wrap), not a one-line preview. Collapsing \s+ here flattened multi-line
|
|
1620
|
+
// prompts into a single run once the turn hit the transcript. Session-list titles/previews
|
|
1621
|
+
// are sanitized separately via sanitizeSessionUserPreviewText.
|
|
1622
|
+
const text = displayText.replace(SESSION_PREVIEW_IMAGE_PLACEHOLDER_RE, '').replace(/\r\n?/g, '\n').trim();
|
|
1590
1623
|
if (text || imageBlocks.length) {
|
|
1591
1624
|
pendingRole = 'user';
|
|
1592
1625
|
pendingTextParts = text ? [text] : [];
|
|
@@ -1852,6 +1885,42 @@ async function fetchClaudeUsageFromOAuth(tokenOverride) {
|
|
|
1852
1885
|
clearTimeout(timer);
|
|
1853
1886
|
}
|
|
1854
1887
|
}
|
|
1888
|
+
// Single read channel for the native / default-login quota (`/api/oauth/usage` with the keychain
|
|
1889
|
+
// token). The read costs no inference tokens but the endpoint RATE-LIMITS aggressive polling
|
|
1890
|
+
// (observed: `rate_limit_error` payloads, which parse to null) — so `fresh` re-reads only after
|
|
1891
|
+
// 15s, and a failed read backs off 60s serving the last good result. Concurrent callers share
|
|
1892
|
+
// one request.
|
|
1893
|
+
const NATIVE_USAGE_FRESH_TTL_MS = 15_000;
|
|
1894
|
+
const NATIVE_USAGE_RETRY_TTL_MS = 60_000;
|
|
1895
|
+
const claudeNativeUsageLive = { at: 0, failedAt: 0, inflight: null };
|
|
1896
|
+
export function claudeNativeUsage(opts) {
|
|
1897
|
+
const maxAge = opts?.fresh ? NATIVE_USAGE_FRESH_TTL_MS : CLAUDE_USAGE_QUERY_TTL_MS;
|
|
1898
|
+
const now = Date.now();
|
|
1899
|
+
if (claudeUsageCache.lastGood && now - claudeNativeUsageLive.at < maxAge) {
|
|
1900
|
+
return Promise.resolve(claudeUsageCache.lastGood);
|
|
1901
|
+
}
|
|
1902
|
+
if (now - claudeNativeUsageLive.failedAt < NATIVE_USAGE_RETRY_TTL_MS) {
|
|
1903
|
+
return Promise.resolve(claudeUsageCache.lastGood);
|
|
1904
|
+
}
|
|
1905
|
+
if (claudeNativeUsageLive.inflight)
|
|
1906
|
+
return claudeNativeUsageLive.inflight;
|
|
1907
|
+
const p = fetchClaudeUsageFromOAuth()
|
|
1908
|
+
.then(fresh => {
|
|
1909
|
+
if (fresh) {
|
|
1910
|
+
claudeUsageCache.lastGood = fresh;
|
|
1911
|
+
claudeUsageCache.lastAttemptAt = Date.now();
|
|
1912
|
+
claudeNativeUsageLive.at = Date.now();
|
|
1913
|
+
claudeNativeUsageLive.failedAt = 0;
|
|
1914
|
+
}
|
|
1915
|
+
else {
|
|
1916
|
+
claudeNativeUsageLive.failedAt = Date.now();
|
|
1917
|
+
}
|
|
1918
|
+
return fresh ?? claudeUsageCache.lastGood;
|
|
1919
|
+
})
|
|
1920
|
+
.finally(() => { claudeNativeUsageLive.inflight = null; });
|
|
1921
|
+
claudeNativeUsageLive.inflight = p;
|
|
1922
|
+
return p;
|
|
1923
|
+
}
|
|
1855
1924
|
// Per-account usage for a specific account's `claude setup-token`.
|
|
1856
1925
|
//
|
|
1857
1926
|
// IMPORTANT: setup-tokens are minted with the `user:inference` scope only — they do NOT carry
|
|
@@ -1860,10 +1929,15 @@ async function fetchClaudeUsageFromOAuth(tokenOverride) {
|
|
|
1860
1929
|
// there because it's a full login. So for account tokens we read the limit state from the
|
|
1861
1930
|
// `anthropic-ratelimit-unified-*` *response headers* of a tiny inference call instead — those
|
|
1862
1931
|
// headers come back on every `/v1/messages` response regardless of scope, and are exactly what
|
|
1863
|
-
// Claude Code itself uses to learn 5h / 7d limits. Cost is ~1 output token per probe,
|
|
1864
|
-
//
|
|
1865
|
-
//
|
|
1932
|
+
// Claude Code itself uses to learn 5h / 7d limits. Cost is ~1 output token per probe, so reads
|
|
1933
|
+
// are tiered by how fresh the caller needs to be:
|
|
1934
|
+
// default -> 5min TTL (background warmers, non-interactive surfaces)
|
|
1935
|
+
// fresh -> 20s min re-probe interval (user is actively looking at the numbers)
|
|
1936
|
+
// force -> bypass everything (identity just changed, e.g. account switch)
|
|
1937
|
+
// Failures back off 60s on the default/fresh tiers (force still retries), and in-flight de-dup
|
|
1938
|
+
// makes concurrent surfaces (cards + header + IM) share one probe.
|
|
1866
1939
|
const TOKEN_USAGE_OK_TTL_MS = CLAUDE_USAGE_QUERY_TTL_MS;
|
|
1940
|
+
const TOKEN_USAGE_FRESH_TTL_MS = 20_000;
|
|
1867
1941
|
const TOKEN_USAGE_RETRY_TTL_MS = 60_000;
|
|
1868
1942
|
const CLAUDE_USAGE_PROBE_MODEL = 'claude-haiku-4-5-20251001';
|
|
1869
1943
|
const claudeTokenUsageCache = new Map();
|
|
@@ -1935,7 +2009,9 @@ export function claudeUsageForToken(token, opts) {
|
|
|
1935
2009
|
const now = Date.now();
|
|
1936
2010
|
const cached = claudeTokenUsageCache.get(t);
|
|
1937
2011
|
if (cached && !opts?.force) {
|
|
1938
|
-
const ttl = cached.ok
|
|
2012
|
+
const ttl = cached.ok
|
|
2013
|
+
? (opts?.fresh ? TOKEN_USAGE_FRESH_TTL_MS : TOKEN_USAGE_OK_TTL_MS)
|
|
2014
|
+
: TOKEN_USAGE_RETRY_TTL_MS;
|
|
1939
2015
|
if (now - cached.at < ttl)
|
|
1940
2016
|
return Promise.resolve(cached.value);
|
|
1941
2017
|
}
|
|
@@ -2226,21 +2302,16 @@ class ClaudeDriver {
|
|
|
2226
2302
|
}
|
|
2227
2303
|
return claudeUsageCache.lastGood ?? telemetry();
|
|
2228
2304
|
}
|
|
2229
|
-
// Live usage for the agent-status surface. Unlike getUsage it ignores the 5-min query TTL
|
|
2230
|
-
//
|
|
2231
|
-
// reflected promptly instead of serving the previous
|
|
2232
|
-
// the caller's usage timeout,
|
|
2305
|
+
// Live usage for the agent-status surface. Unlike getUsage it ignores the 5-min query TTL
|
|
2306
|
+
// (modulo the short fresh window that coalesces bursts), so a freshly-switched login (the
|
|
2307
|
+
// keychain default-login token changed) is reflected promptly instead of serving the previous
|
|
2308
|
+
// account's frozen `lastGood`. Bounded by the caller's usage timeout, cached value as fallback.
|
|
2233
2309
|
async getUsageLive(opts) {
|
|
2234
2310
|
const home = getHome();
|
|
2235
2311
|
if (!home)
|
|
2236
2312
|
return emptyUsage('claude', 'HOME is not set.');
|
|
2237
|
-
const fresh = await
|
|
2238
|
-
|
|
2239
|
-
claudeUsageCache.lastGood = fresh;
|
|
2240
|
-
claudeUsageCache.lastAttemptAt = Date.now();
|
|
2241
|
-
return fresh;
|
|
2242
|
-
}
|
|
2243
|
-
return claudeUsageCache.lastGood
|
|
2313
|
+
const fresh = await claudeNativeUsage({ fresh: true });
|
|
2314
|
+
return fresh
|
|
2244
2315
|
?? getClaudeUsageFromTelemetry(home, opts.model)
|
|
2245
2316
|
?? emptyUsage('claude', 'No recent Claude usage data found.');
|
|
2246
2317
|
}
|
|
@@ -125,6 +125,21 @@ export function toPikiloomPlan(plan) {
|
|
|
125
125
|
.filter((st) => st.step.trim());
|
|
126
126
|
return steps.length ? { explanation: typeof plan.explanation === 'string' ? plan.explanation : null, steps } : null;
|
|
127
127
|
}
|
|
128
|
+
// Final-result token projection (kernel UniversalUsage -> StreamResult fields). contextPercent
|
|
129
|
+
// must flow through: the IM final footer (feishu/telegram formatFinalFooter) reads
|
|
130
|
+
// result.contextPercent, so nulling it here showed the % on the live footer (preview meta carries
|
|
131
|
+
// it) but dropped it from the finished message. Pure + exported for regression testing.
|
|
132
|
+
export function kernelUsageToResultFields(u) {
|
|
133
|
+
return {
|
|
134
|
+
inputTokens: u?.inputTokens ?? null,
|
|
135
|
+
outputTokens: u?.outputTokens ?? null,
|
|
136
|
+
cachedInputTokens: u?.cachedInputTokens ?? null,
|
|
137
|
+
cacheCreationInputTokens: null,
|
|
138
|
+
contextWindow: null,
|
|
139
|
+
contextUsedTokens: u?.contextUsedTokens ?? null,
|
|
140
|
+
contextPercent: u?.contextPercent ?? null,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
128
143
|
let _kernel = null;
|
|
129
144
|
export async function loadKernel() {
|
|
130
145
|
if (_kernel)
|
|
@@ -240,7 +255,7 @@ export async function kernelStream(opts) {
|
|
|
240
255
|
const finalError = (opts.agent === 'codex' && result.error)
|
|
241
256
|
? (humanizeCodexError(result.error) ?? result.error)
|
|
242
257
|
: (result.error ?? null);
|
|
243
|
-
const
|
|
258
|
+
const usageFields = kernelUsageToResultFields(result.usage || snapshot.usage || {});
|
|
244
259
|
return {
|
|
245
260
|
ok: !!result.ok,
|
|
246
261
|
// Empty-text fallback (mirrors the legacy driver): a clean turn with no prose reads
|
|
@@ -251,7 +266,9 @@ export async function kernelStream(opts) {
|
|
|
251
266
|
|| finalError
|
|
252
267
|
|| (result.stopReason === 'background'
|
|
253
268
|
? 'Work is now running in the background — I’ll report back here once it finishes. (Send any message to check on it.)'
|
|
254
|
-
: result.
|
|
269
|
+
: result.stopReason === 'stalled'
|
|
270
|
+
? 'The turn stopped responding after tool use without producing a reply (the model or provider may have stalled). Send any message to continue.'
|
|
271
|
+
: result.ok ? '(no textual response)' : '(no output)'),
|
|
255
272
|
thinking: (result.reasoning || snapshot.reasoning || '').trim() || null,
|
|
256
273
|
plan: toPikiloomPlan(snapshot.plan),
|
|
257
274
|
sessionId: finalSessionId,
|
|
@@ -259,13 +276,7 @@ export async function kernelStream(opts) {
|
|
|
259
276
|
model: input.model ?? null,
|
|
260
277
|
thinkingEffort: opts.thinkingEffort,
|
|
261
278
|
elapsedS: (Date.now() - start) / 1000,
|
|
262
|
-
|
|
263
|
-
outputTokens: u.outputTokens ?? null,
|
|
264
|
-
cachedInputTokens: u.cachedInputTokens ?? null,
|
|
265
|
-
cacheCreationInputTokens: null,
|
|
266
|
-
contextWindow: null,
|
|
267
|
-
contextUsedTokens: u.contextUsedTokens ?? null,
|
|
268
|
-
contextPercent: null,
|
|
279
|
+
...usageFields,
|
|
269
280
|
codexCumulative: null,
|
|
270
281
|
error: finalError,
|
|
271
282
|
stopReason: result.stopReason ?? null,
|