@av-pi-studio/web-client 0.0.33 → 0.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/web/assets/{BinaryFallbackViewer-DcdvHipL.js → BinaryFallbackViewer-CtNuXHUk.js} +2 -2
  3. package/dist/web/assets/{BinaryFallbackViewer-DcdvHipL.js.map → BinaryFallbackViewer-CtNuXHUk.js.map} +1 -1
  4. package/dist/web/assets/ChatPanel-BxmhC02j.css +1 -0
  5. package/dist/web/assets/ChatPanel-DgWlIJic.js +3 -0
  6. package/dist/web/assets/ChatPanel-DgWlIJic.js.map +1 -0
  7. package/dist/web/assets/{CodeView-CHtX3XUo.js → CodeView-DBAtguCy.js} +2 -2
  8. package/dist/web/assets/{CodeView-CHtX3XUo.js.map → CodeView-DBAtguCy.js.map} +1 -1
  9. package/dist/web/assets/{FilePanel-DFrjCgQW.js → FilePanel-BGAxlnTJ.js} +3 -3
  10. package/dist/web/assets/{FilePanel-DFrjCgQW.js.map → FilePanel-BGAxlnTJ.js.map} +1 -1
  11. package/dist/web/assets/{ImageViewer-BU0ZsYF9.js → ImageViewer-CLqpRK4l.js} +2 -2
  12. package/dist/web/assets/{ImageViewer-BU0ZsYF9.js.map → ImageViewer-CLqpRK4l.js.map} +1 -1
  13. package/dist/web/assets/{MarkdownFileViewer-n81kPpQE.js → MarkdownFileViewer-UJPP7vox.js} +2 -2
  14. package/dist/web/assets/{MarkdownFileViewer-n81kPpQE.js.map → MarkdownFileViewer-UJPP7vox.js.map} +1 -1
  15. package/dist/web/assets/{TerminalPanel-yVOy1dbu.js → TerminalPanel-C9bP_u5_.js} +2 -2
  16. package/dist/web/assets/{TerminalPanel-yVOy1dbu.js.map → TerminalPanel-C9bP_u5_.js.map} +1 -1
  17. package/dist/web/assets/{TextViewer-DjulYYEe.js → TextViewer-DD2_TH2C.js} +2 -2
  18. package/dist/web/assets/{TextViewer-DjulYYEe.js.map → TextViewer-DD2_TH2C.js.map} +1 -1
  19. package/dist/web/assets/{VideoViewer-CWUu0A0W.js → VideoViewer-D6cldFSO.js} +2 -2
  20. package/dist/web/assets/{VideoViewer-CWUu0A0W.js.map → VideoViewer-D6cldFSO.js.map} +1 -1
  21. package/dist/web/assets/index-CwYwO1IN.js +3 -0
  22. package/dist/web/assets/index-CwYwO1IN.js.map +1 -0
  23. package/dist/web/assets/{index-ZP_-GPM5.css → index-D_2xgUa4.css} +1 -1
  24. package/dist/web/assets/{use-file-download-BxA_7HBl.js → use-file-download-DRdPYoQk.js} +2 -2
  25. package/dist/web/assets/{use-file-download-BxA_7HBl.js.map → use-file-download-DRdPYoQk.js.map} +1 -1
  26. package/dist/web/assets/{vendor-icons-BJD_eLBz.js → vendor-icons-BouiMPVM.js} +68 -38
  27. package/dist/web/assets/vendor-icons-BouiMPVM.js.map +1 -0
  28. package/dist/web/index.html +3 -3
  29. package/package.json +3 -3
  30. package/dist/web/assets/ChatPanel-C5cHHrg2.js +0 -3
  31. package/dist/web/assets/ChatPanel-C5cHHrg2.js.map +0 -1
  32. package/dist/web/assets/ChatPanel-DRMI3PJR.css +0 -1
  33. package/dist/web/assets/index-B_Wls_vp.js +0 -3
  34. package/dist/web/assets/index-B_Wls_vp.js.map +0 -1
  35. package/dist/web/assets/vendor-icons-BJD_eLBz.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@av-pi-studio/web-client",
3
- "version": "0.0.33",
3
+ "version": "0.0.35",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -14,8 +14,8 @@
14
14
  "clean": "rm -rf dist *.tsbuildinfo"
15
15
  },
16
16
  "dependencies": {
17
- "@av-pi-studio/client": "^0.0.33",
18
- "@av-pi-studio/protocol": "^0.0.33",
17
+ "@av-pi-studio/client": "^0.0.35",
18
+ "@av-pi-studio/protocol": "^0.0.35",
19
19
  "@codemirror/language": "^6.12.4",
20
20
  "@codemirror/language-data": "^6.5.2",
21
21
  "@codemirror/state": "^6.7.1",
@@ -1,3 +0,0 @@
1
- import{j as t,r as g}from"./vendor-react-BoIQBqDW.js";import{c as q,d as te,m as ne}from"./vendor-query-AtKBh_Yt.js";import{t as U,u as x,a as H,D as se,T as re,B as S}from"./index-B_Wls_vp.js";import{k as ae,l as ie,m as oe,n as le,o as ce,p as ue,T as L,C as de,q as me,N as ge,r as pe,s as _e}from"./vendor-icons-BJD_eLBz.js";import{M as K}from"./markdown-D9FuaV1m.js";import{C as $}from"./vendor--os7hw7d.js";import{D as fe}from"./DiffView-DlVCPvLc.js";import"./vendor-overlays-UwLNGk04.js";import"./vendor-dnd-D9kA7FgH.js";import"./vendor-highlight-DCzuSv8g.js";import"./vendor-markdown-B8HSIhaA.js";const he="_badge_jtokc_3",xe={badge:he};function ye(e){switch(e){case"success":return{token:"statusSuccess"};case"error":return{token:"statusDanger"};case"muted":return{token:"foregroundMuted"}}}function be({label:e,variant:n,className:s}){const{token:o}=ye(n),i=`var(--pi-color-${o})`;return t.jsx("span",{className:`${xe.badge}${s?` ${s}`:""}`,style:{backgroundColor:`color-mix(in srgb, ${i} 18%, transparent)`,borderColor:`color-mix(in srgb, ${i} 45%, transparent)`,color:i},children:e})}const je={shell:L,read:ue,edit:ce,write:le,search:oe,fetch:ie,task:ae};function ve(e){return je[e.kind]??L}function ke(e){return e.kind}function we(e){switch(e.kind){case"read":case"write":case"edit":return e.path??null;default:return null}}function Ne(e){return e.kind==="write"||e.kind==="edit"||e.kind==="shell"}function Ie(e){const n=[];if(e.kind==="edit"&&e.diff)n.push({kind:"diff",patch:e.diff});else{const s=U(e);s&&n.push({kind:"code",text:s})}return e.output&&n.push({kind:"code",text:e.output}),n}function Se(e){const n=U(e);if(!n)return"";switch(e.kind){case"read":case"write":case"edit":{const s=n.split("/");return s[s.length-1]||n}case"shell":return n.split(`
2
- `,1)[0]??n;default:return n}}const Ce=500;let E;function De(e,n,s,o){clearTimeout(E),E=setTimeout(()=>{E=void 0,e.invalidateQueries({queryKey:["file"]}),e.invalidateQueries({queryKey:["explorer"]}),n&&s&&n.connection.request("checkout_refresh_request",{cwd:s}).catch(()=>{})},Ce)}function Te(e){let n=null;return s=>{if(n===null){if(s.event.kind!=="user_message"||s.event.messageId!==e)return!1;n=s.agentId}return s.agentId===n}}function W({sessionId:e,event:n,client:s,queryClient:o}){const i=x.getState();switch(i.applyStreamEvent(e,n),n.kind){case"turn_started":i.setStatus(e,"running");break;case"turn_completed":i.setStatus(e,"idle");break;case"turn_failed":i.setStatus(e,"error");break;case"turn_canceled":i.setStatus(e,"idle");break;case"tool_call":{if(n.status==="completed"&&Ne(n.tool)){const l=i.sessions[e],u=(l==null?void 0:l.cwd)||null;De(o,s,u,we(n.tool))}break}}}function $e(e){const n=H(i=>i.client),s=x(i=>{var l;return((l=i.sessions[e])==null?void 0:l.agentId)??null}),o=q();g.useEffect(()=>!n||!s?void 0:n.agent(s).timeline.subscribe(l=>{W({sessionId:e,event:l,client:n,queryClient:o})}),[n,s,e,o])}const Ee="_row_1yibt_3",Be="_who_1yibt_13",Re="_queuedBadge_1yibt_22",Ae="_user_1yibt_38",Fe="_userPending_1yibt_45",Pe="_userFailed_1yibt_49",ze="_userImages_1yibt_55",Oe="_userImage_1yibt_55",Me="_imageDialog_1yibt_71",qe="_imageDialogPreview_1yibt_75",Ue="_assistant_1yibt_84",He="_streaming_1yibt_91",Le="_streamingText_1yibt_95",Ke="_cursor_1yibt_100",We="_blink_1yibt_1",Ge="_reasoning_1yibt_115",Ve="_tool_1yibt_125",Qe="_toolHeader_1yibt_135",Xe="_toolChevron_1yibt_153",Ye="_toolChevronOpen_1yibt_159",Je="_toolInlineDetail_1yibt_163",Ze="_toolBody_1yibt_173",et="_toolCode_1yibt_179",tt="_toolIcon_1yibt_190",nt="_running_1yibt_196",st="_pulse_1yibt_1",rt="_completed_1yibt_201",at="_error_1yibt_205",it="_toolLabel_1yibt_215",ot="_toolBadge_1yibt_220",lt="_system_1yibt_233",r={row:Ee,who:Be,queuedBadge:Re,user:Ae,userPending:Fe,userFailed:Pe,userImages:ze,userImage:Oe,imageDialog:Me,imageDialogPreview:qe,assistant:Ue,streaming:He,streamingText:Le,cursor:Ke,blink:We,reasoning:Ge,tool:Ve,toolHeader:Qe,toolChevron:Xe,toolChevronOpen:Ye,toolInlineDetail:Je,toolBody:Ze,toolCode:et,toolIcon:tt,running:nt,pulse:st,completed:rt,error:at,toolLabel:it,toolBadge:ot,system:lt};function ct({row:e}){return t.jsxs("div",{className:`${r.row} ${r.assistant}${e.streaming?` ${r.streaming}`:""}`,children:[t.jsx("span",{className:r.who,children:"assistant"}),e.streaming?t.jsxs("span",{className:r.streamingText,children:[e.text,t.jsx("span",{className:r.cursor,children:"▍"})]}):t.jsx(K,{text:e.text})]})}function ut({row:e}){return t.jsxs("div",{className:`${r.row} ${r.reasoning}`,children:[t.jsx("span",{className:r.who,children:"thinking"}),e.streaming?t.jsxs("span",{className:r.streamingText,children:[e.text,t.jsx("span",{className:r.cursor,children:"▍"})]}):t.jsx(K,{text:e.text})]})}const dt={running:"muted",completed:"success",error:"error"};function mt({row:e}){const[n,s]=g.useState(!1),o=ve(e.tool),i=Se(e.tool),l=Ie(e.tool),u=l.length>0;return t.jsxs("div",{className:$(r.row,r.tool),children:[t.jsxs("button",{type:"button",className:r.toolHeader,onClick:()=>u&&s(d=>!d),"aria-expanded":u?n:void 0,disabled:!u,children:[u&&t.jsx(de,{size:12,className:$(r.toolChevron,n&&r.toolChevronOpen)}),t.jsx("span",{className:$(r.toolIcon,r[e.status]),children:t.jsx(o,{size:14})}),t.jsx("span",{className:r.toolLabel,children:ke(e.tool)}),i&&t.jsx("span",{className:r.toolInlineDetail,title:i,children:i}),t.jsx(be,{className:r.toolBadge,label:e.status,variant:dt[e.status]})]}),n&&u&&t.jsx("div",{className:r.toolBody,children:l.map((d,c)=>d.kind==="diff"?t.jsx(fe,{patch:d.patch},c):t.jsx("pre",{className:r.toolCode,children:d.text},c))})]})}function gt({row:e}){const[n,s]=g.useState(null),o=e.failed?r.userFailed:e.pending?r.userPending:"";return t.jsxs("div",{className:`${r.row} ${r.user}${o?` ${o}`:""}`,children:[t.jsxs("span",{className:r.who,children:["you",e.failed?" · failed to send":"",e.queued&&!e.failed&&t.jsx("span",{className:r.queuedBadge,children:"queued"})]}),e.text,e.images&&e.images.length>0&&t.jsx("div",{className:r.userImages,children:e.images.map((i,l)=>{const u=`data:${i.mimeType??"image/png"};base64,${i.data??""}`;return t.jsx("img",{className:r.userImage,src:u,alt:"",role:"button",tabIndex:0,onClick:()=>s(u),onKeyDown:d=>{(d.key==="Enter"||d.key===" ")&&s(u)}},l)})}),t.jsx(se,{open:n!==null,onOpenChange:i=>{i||s(null)},title:"Image",width:"auto",bare:!0,className:r.imageDialog,children:n&&t.jsx("img",{className:r.imageDialogPreview,src:n,alt:""})})]})}function pt({row:e}){return t.jsxs("div",{className:`${r.row} ${r.error}`,children:[t.jsx("span",{className:r.who,children:"error"}),e.text]})}function _t({row:e}){return t.jsx("div",{className:`${r.row} ${r.system}`,children:e.text})}const ft="_viewport_1byko_3",ht="_inner_1byko_10",xt="_rowWrap_1byko_15",yt="_empty_1byko_25",bt="_working_1byko_34",jt="_workingDots_1byko_43",f={viewport:ft,inner:ht,rowWrap:xt,empty:yt,working:bt,workingDots:jt},vt=40;function kt(e){switch(e.kind){case"user":return t.jsx(gt,{row:e});case"assistant":return t.jsx(ct,{row:e});case"reasoning":return t.jsx(ut,{row:e});case"tool":return t.jsx(mt,{row:e});case"error":return t.jsx(pt,{row:e});case"system":return t.jsx(_t,{row:e})}}function wt({session:e}){const n=e.timeline.rows,s=e.status==="running",o=g.useRef(null),i=g.useRef(!0),l=g.useRef(0),u=te({count:n.length,getScrollElement:()=>o.current,estimateSize:()=>48,overscan:8,getItemKey:c=>{var m;return((m=n[c])==null?void 0:m.id)??c},measureElement:(c,m,_)=>{if(c.offsetParent!==null)return ne(c,m,_);const j=_.indexFromElement(c),w=_.options.getItemKey(j);return _.itemSizeCache.get(w)??_.options.estimateSize(j)}});function d(){const c=o.current;if(!c)return;const m=c.scrollHeight-c.scrollTop-c.clientHeight;i.current=m<vt}return g.useEffect(()=>{const c=n.length>l.current;l.current=n.length,c&&i.current&&u.scrollToIndex(n.length-1,{align:"end"})},[n.length,u]),n.length===0?t.jsx("div",{className:f.viewport,ref:o,children:s?t.jsxs("div",{className:f.working,role:"status","aria-live":"polite",children:[t.jsxs("span",{className:f.workingDots,"aria-hidden":"true",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]}),"Agent is working…"]}):t.jsx("div",{className:f.empty,children:"No messages yet — say something to start."})}):t.jsxs("div",{className:f.viewport,ref:o,onScroll:d,children:[t.jsx("div",{className:f.inner,style:{height:u.getTotalSize()},children:u.getVirtualItems().map(c=>{const m=n[c.index];return m?t.jsx("div",{ref:u.measureElement,"data-index":c.index,className:f.rowWrap,style:{transform:`translateY(${c.start}px)`},children:kt(m)},c.key):null})}),s&&t.jsxs("div",{className:f.working,role:"status","aria-live":"polite",children:[t.jsxs("span",{className:f.workingDots,"aria-hidden":"true",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]}),"Agent is working…"]})]})}const Nt="_strip_5sm81_4",It="_thumb_5sm81_11",St="_remove_5sm81_28",B={strip:Nt,thumb:It,remove:St};function Ct({images:e,onRemove:n}){return e.length===0?null:t.jsx("div",{className:B.strip,children:e.map((s,o)=>t.jsxs("div",{className:B.thumb,children:[t.jsx("img",{src:s.thumbUrl,alt:""}),t.jsx("button",{type:"button",className:B.remove,title:"Remove",onClick:()=>n(o),children:"×"})]},o))})}function Dt(e){const{promise:n,resolve:s,reject:o}=Promise.withResolvers(),i=new FileReader;return i.onload=()=>{const l=i.result;if(typeof l!="string"){o(new Error("Unexpected FileReader result"));return}const u=l.indexOf(","),d=u>=0?l.slice(u+1):l;s({mimeType:e.type,data:d,thumbUrl:l})},i.onerror=()=>o(i.error??new Error("Failed to read file")),i.readAsDataURL(e),n}const Tt="_composer_1ll3p_1",$t="_inputArea_1ll3p_13",Et="_textarea_1ll3p_21",Bt="_attachBtn_1ll3p_28",Rt="_hiddenFileInput_1ll3p_32",At="_actions_1ll3p_36",k={composer:Tt,inputArea:$t,textarea:Et,attachBtn:Bt,hiddenFileInput:Rt,actions:At},Ft=160;function M(e){e.style.height="auto",e.style.height=`${Math.min(e.scrollHeight,Ft)}px`}function Pt(e){return typeof e!="object"||e===null||!("type"in e)||e.type!=="agent_stream"?!1:"agentId"in e&&typeof e.agentId=="string"&&"event"in e}function zt(e){return typeof e=="object"&&e!==null&&"ok"in e&&e.ok===!1}function Ot({sessionId:e}){const n=H(a=>a.client),s=x(a=>a.sessions[e]),o=x(a=>a.bindAgent),i=x(a=>a.addOptimisticUserMessage),l=x(a=>a.markUserMessageFailed),u=x(a=>a.setCwd),d=q(),[c,m]=g.useState(""),[_,j]=g.useState([]),[w,A]=g.useState(!1),C=g.useRef(null),F=g.useRef(null),N=(s==null?void 0:s.status)==="running",P=!!n&&!w&&(c.trim().length>0||_.length>0);async function z(a){if(a.type.startsWith("image/"))try{const p=await Dt(a);j(h=>[...h,p])}catch{}}function G(a){for(const p of a.target.files??[])z(p);a.target.value=""}function V(a){for(const p of a.clipboardData.items)if(p.type.startsWith("image/")){a.preventDefault();const h=p.getAsFile();h&&z(h)}}function Q(a){j(p=>p.filter((h,v)=>v!==a))}function X(a){m(a.target.value),M(a.target)}function Y(a){a.key==="Enter"&&!a.shiftKey&&(a.preventDefault(),D(N?"steer":"send"))}async function D(a){if(!n||!s||w||a==="steer"&&!s.agentId)return;const p=c.trim();if(!p&&_.length===0)return;m(""),C.current&&M(C.current);const h=_;j([]);const v=p||"Describe this image",I=h.length>0?h.map(b=>({mimeType:b.mimeType,data:b.data})):void 0,y=crypto.randomUUID();i(e,y,v,I,a==="steer"),A(!0);try{if(a==="steer"){const b=await n.agent(s.agentId).steer(v,{clientMessageId:y,images:I});zt(b)&&l(e,y)}else if(s.agentId)await n.agent(s.agentId).send(v,{clientMessageId:y,images:I});else{const b=s.cwd||"~";u(e,b);const Z=Te(y),ee=n.connection.onSessionMessage(T=>{!Pt(T)||!Z(T)||W({sessionId:e,event:T.event,client:n,queryClient:d})});let O;try{O=await n.createAgent({config:{provider:"pi",cwd:b},initialPrompt:v,clientMessageId:y,images:I,labels:{}})}finally{ee()}o(e,O.agentId)}}catch{l(e,y)}finally{A(!1)}}function J(){s!=null&&s.agentId&&(n==null||n.agent(s.agentId).interrupt())}return t.jsxs("div",{className:k.composer,children:[t.jsxs("div",{className:k.inputArea,children:[t.jsx(re,{ref:C,className:k.textarea,rows:1,value:c,placeholder:N?"Steer the running turn… (Enter to steer, Shift+Enter for newline)":"Ask anything… (Enter to send, Shift+Enter for newline)",onChange:X,onKeyDown:Y,onPaste:V}),t.jsx(Ct,{images:_,onRemove:Q})]}),t.jsx(S,{className:k.attachBtn,variant:"ghost",size:"md",iconOnly:!0,title:"Attach image",onClick:()=>{var a;return(a=F.current)==null?void 0:a.click()},children:t.jsx(me,{size:16})}),t.jsx("input",{ref:F,className:k.hiddenFileInput,type:"file",accept:"image/*",multiple:!0,onChange:G}),t.jsxs("div",{className:k.actions,children:[N?t.jsx(S,{size:"sm",disabled:!P,onClick:()=>void D("steer"),leftIcon:t.jsx(ge,{size:14}),children:"Steer"}):t.jsx(S,{size:"sm",disabled:!P,onClick:()=>void D("send"),leftIcon:t.jsx(pe,{size:14}),children:"Send"}),N&&t.jsx(S,{size:"sm",variant:"destructive",onClick:J,leftIcon:t.jsx(_e,{size:14}),children:"Stop"})]})]})}const Mt="_panel_12s9l_1",qt="_empty_12s9l_8",R={panel:Mt,empty:qt};function Zt({tab:e}){const{sessionId:n}=e.data,s=x(o=>o.sessions[n]);return $e(n),s?t.jsxs("div",{className:R.panel,children:[t.jsx(wt,{session:s}),t.jsx(Ot,{sessionId:s.id})]}):t.jsx("div",{className:R.panel,children:t.jsx("div",{className:R.empty,children:"Session not found."})})}export{Zt as ChatPanel};
3
- //# sourceMappingURL=ChatPanel-C5cHHrg2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ChatPanel-C5cHHrg2.js","sources":["../../../src/ui/status-badge.ts","../../../src/components/primitives/StatusBadge.tsx","../../../src/timeline/tool-mapping.ts","../../../src/lib/connection/files-changed.ts","../../../src/hooks/agent-stream-events.ts","../../../src/hooks/use-agent-stream.ts","../../../src/features/chat/rows/AssistantRow.tsx","../../../src/features/chat/rows/ReasoningRow.tsx","../../../src/features/chat/rows/ToolCard.tsx","../../../src/features/chat/rows/UserRow.tsx","../../../src/features/chat/rows/ErrorRow.tsx","../../../src/features/chat/rows/SystemRow.tsx","../../../src/features/chat/Timeline.tsx","../../../src/features/chat/Attachments.tsx","../../../src/features/chat/Composer.tsx","../../../src/features/chat/ChatPanel.tsx"],"sourcesContent":["// StatusBadge + Alert variant contracts.\n// ui-components.md § Surfaces / badges / chips / avatars\n\nexport type StatusBadgeVariant = \"success\" | \"error\" | \"muted\";\n\n// Single semantic token per variant — text color AND a translucent tint of the SAME token as\n// background (matches `ChangesPanel.module.css`'s `.added`/`.modified`/`.deleted` convention).\n// Never split bg/border/text across different token families (e.g. `success` vs `statusSuccess`)\n// — they can diverge in the theme (dark mode's `success` aliases the blue accent, not green),\n// producing a badge with mismatched border/background colors.\nexport type BadgeTokens = {\n token: string;\n};\n\nexport function statusBadgeTokens(variant: StatusBadgeVariant): BadgeTokens {\n switch (variant) {\n case \"success\":\n return { token: \"statusSuccess\" };\n case \"error\":\n return { token: \"statusDanger\" };\n case \"muted\":\n return { token: \"foregroundMuted\" };\n }\n}\n\nexport type AlertVariant = \"default\" | \"info\" | \"success\" | \"warning\" | \"error\";\n\nexport type AlertIconInfo = {\n /** Lucide icon name string for the alert variant. */\n icon: string;\n /** Theme token key for the icon/border/title accent color. */\n accentToken: string;\n};\n\nexport function alertIconInfo(variant: AlertVariant): AlertIconInfo {\n switch (variant) {\n case \"default\":\n return { icon: \"info\", accentToken: \"foregroundMuted\" };\n case \"info\":\n return { icon: \"info\", accentToken: \"accent\" };\n case \"success\":\n return { icon: \"check-circle\", accentToken: \"success\" };\n case \"warning\":\n return { icon: \"triangle-alert\", accentToken: \"statusWarning\" };\n case \"error\":\n return { icon: \"circle-x\", accentToken: \"destructive\" };\n }\n}\n\n// AttachmentPill remove-button visibility — mirrors hover-to-show pattern.\nexport function attachmentPillRemoveVisible(\n isNativeCtx: boolean,\n isCompact: boolean,\n hovered: boolean,\n): boolean {\n return isNativeCtx || isCompact || hovered;\n}\n","/**\n * StatusBadge — small rounded pill with variant coloring.\n * ui-components.md § Surfaces / badges / chips / avatars\n */\n\nimport { type ReactNode } from \"react\";\nimport styles from \"./StatusBadge.module.css\";\nimport { statusBadgeTokens, type StatusBadgeVariant } from \"@pi-studio-ui/ui/status-badge.js\";\n\nexport interface StatusBadgeProps {\n label: ReactNode;\n variant: StatusBadgeVariant;\n className?: string;\n}\n\nexport function StatusBadge({ label, variant, className }: StatusBadgeProps) {\n const { token } = statusBadgeTokens(variant);\n const color = `var(--pi-color-${token})`;\n return (\n <span\n className={`${styles.badge}${className ? ` ${className}` : \"\"}`}\n style={{\n backgroundColor: `color-mix(in srgb, ${color} 18%, transparent)`,\n borderColor: `color-mix(in srgb, ${color} 45%, transparent)`,\n color,\n }}\n >\n {label}\n </span>\n );\n}\n","/**\n * tool.kind → display label + icon. Scoped to the protocol's `ToolCallDetail` union\n * (shell/read/edit/write/search/fetch/task) — POC_TO_APP_PLAN_UI.md §3 `timeline/tool-mapping.ts`.\n */\n\nimport type { ToolCallDetail } from \"@av-pi-studio/protocol\";\nimport {\n Terminal,\n Eye,\n Pencil,\n FilePlus,\n Search,\n Globe,\n ListTree,\n type LucideIcon,\n} from \"lucide-react\";\nimport { toolDetailText } from \"./row-model.js\";\n\nconst ICON_BY_KIND: Record<ToolCallDetail[\"kind\"], LucideIcon> = {\n shell: Terminal,\n read: Eye,\n edit: Pencil,\n write: FilePlus,\n search: Search,\n fetch: Globe,\n task: ListTree,\n};\n\nexport function toolIcon(tool: ToolCallDetail): LucideIcon {\n return ICON_BY_KIND[tool.kind] ?? Terminal;\n}\n\n/** Human label for a tool card header, e.g. \"shell\", \"edit\". */\nexport function toolLabel(tool: ToolCallDetail): string {\n return tool.kind;\n}\n\n/** One-line detail summary for a tool card (POC: `t.command || t.path || t.query || …`). */\nexport function toolSummary(tool: ToolCallDetail): string {\n return toolDetailText(tool);\n}\n\n/** File path a tool touched, if any — used to target `filesChanged` invalidation (§4.5). */\nexport function toolFilePath(tool: ToolCallDetail): string | null {\n switch (tool.kind) {\n case \"read\":\n case \"write\":\n case \"edit\":\n return tool.path ?? null;\n default:\n return null;\n }\n}\n\n/** True for tool kinds whose completion should invalidate open file/diff/explorer/git queries. */\nexport function toolMutatesFiles(tool: ToolCallDetail): boolean {\n return tool.kind === \"write\" || tool.kind === \"edit\" || tool.kind === \"shell\";\n}\n\n/**\n * Expandable detail body for a tool card, as an ordered list of sections. `diff` renders as a\n * `<DiffView>`; `code` renders in a monospace block. Order: input detail (command/path/query/…)\n * first, then tool output (stdout, file content, etc.) if present. Empty array = header-only card\n * with nothing worth expanding.\n */\nexport type ToolBodySection = { kind: \"diff\"; patch: string } | { kind: \"code\"; text: string };\n\nexport function toolBody(tool: ToolCallDetail): ToolBodySection[] {\n const sections: ToolBodySection[] = [];\n if (tool.kind === \"edit\" && tool.diff) sections.push({ kind: \"diff\", patch: tool.diff });\n else {\n const text = toolDetailText(tool);\n if (text) sections.push({ kind: \"code\", text });\n }\n if (tool.output) sections.push({ kind: \"code\", text: tool.output });\n return sections;\n}\n\n/** Concise inline label shown in the collapsed header (basename for paths, first line for commands). */\nexport function toolInlineDetail(tool: ToolCallDetail): string {\n const text = toolDetailText(tool);\n if (!text) return \"\";\n switch (tool.kind) {\n case \"read\":\n case \"write\":\n case \"edit\": {\n const parts = text.split(\"/\");\n return parts[parts.length - 1] || text;\n }\n case \"shell\": {\n const firstLine = text.split(\"\\n\", 1)[0] ?? text;\n return firstLine;\n }\n default:\n return text;\n }\n}\n","/**\n * `filesChanged` signal — invalidates the file/diff/explorer query caches after a completed\n * write/edit/shell tool call (POC `scheduleFileRefresh`/`reloadOpenFileTabs`, chat.html\n * ~line 1070-1092, POC_TO_APP_PLAN_UI.md §4.3/§4.5/§5). Debounced ~500ms to coalesce a burst of\n * tool completions (POC used `setTimeout(...,600)`/`400`).\n *\n * The daemon does NOT push a `checkout_status_update` automatically after a git-affecting tool\n * completion, so this module also fires an explicit `checkout_refresh_request` for the active\n * cwd — `ChangesPanel`/`FileExplorer` then pick up the resulting push/refetch reactively, since\n * they're already subscribed (`use-checkout-status.ts`) or query-cache-driven (`use-explorer.ts`).\n *\n * NOTE (follow-up, cross-slice): this module only *exports* the invalidation function. The actual\n * call site — wiring this into the timeline reducer's `tool_call` handling on `status:\"completed\"`\n * for `toolMutatesFiles(tool) === true` — belongs to the chat/session-store slice (built in\n * parallel) or the top-level app wiring; do not import/call it from `timeline/reducer.ts` here,\n * that file is a shared contract file owned across slices.\n */\n\nimport type { QueryClient } from \"@tanstack/react-query\";\nimport type { PiStudioClient } from \"@av-pi-studio/client\";\n\nconst DEBOUNCE_MS = 500;\nlet pendingTimer: ReturnType<typeof setTimeout> | undefined;\n\n/**\n * Invalidate file/diff/explorer TanStack Query caches and refresh git status for `cwd`.\n * Debounced: repeated calls within `DEBOUNCE_MS` coalesce into a single invalidation pass.\n *\n * `toolFilePath` is accepted for future path-scoped invalidation (POC `reloadOpenFileTabs`\n * matched by path suffix) but the current pass invalidates the whole `file`/`explorer` query\n * families — TanStack Query dedupes refetches for inactive queries, so this is cheap and correct\n * even when the path is unknown.\n */\nexport function invalidateAfterToolCompletion(\n queryClient: QueryClient,\n client: PiStudioClient | null,\n cwd: string | null,\n _toolFilePath: string | null,\n): void {\n clearTimeout(pendingTimer);\n pendingTimer = setTimeout(() => {\n pendingTimer = undefined;\n void queryClient.invalidateQueries({ queryKey: [\"file\"] });\n void queryClient.invalidateQueries({ queryKey: [\"explorer\"] });\n if (client && cwd) {\n void client.connection.request(\"checkout_refresh_request\", { cwd }).catch(() => {});\n }\n }, DEBOUNCE_MS);\n}\n","/**\n * Shared `AgentStreamEvent` → store-update logic, used both by the live subscription\n * (`use-agent-stream.ts`) and by the live first-turn apply in `Composer.tsx` (see its comment for\n * why: `create_agent_request` blocks until the whole first turn completes, so the timeline is fed\n * from the raw broadcast as events arrive rather than from a not-yet-attached subscription).\n */\n\nimport type { PiStudioClient } from \"@av-pi-studio/client\";\nimport type { AgentStreamEvent } from \"@av-pi-studio/protocol\";\nimport type { QueryClient } from \"@tanstack/react-query\";\nimport { useSessionStore } from \"@pi-studio-ui/stores/session-store.js\";\nimport { toolMutatesFiles, toolFilePath } from \"@pi-studio-ui/timeline/tool-mapping.js\";\nimport { invalidateAfterToolCompletion } from \"@pi-studio-ui/lib/connection/files-changed.js\";\n\nexport interface ApplyAgentStreamEventArgs {\n sessionId: string;\n event: AgentStreamEvent;\n client: PiStudioClient;\n queryClient: QueryClient;\n}\n\n/**\n * Correlates first-turn `agent_stream` broadcasts with the agent a specific `createAgent` call\n * just spawned. `create_agent_request` doesn't resolve with the new `agentId` until the whole\n * first turn completes, so `Composer.handleSend` watches the raw broadcast and applies frames as\n * they arrive — but the socket is shared across every open session, and another session's agent\n * can be mid-turn concurrently. The first `agent_stream` frame observed after subscribing is\n * therefore NOT necessarily this call's own agent. Only latch onto an `agentId` once its\n * canonical `user_message` echo is seen (`messageId === clientMessageId`, minted by this call and\n * echoed back verbatim by the daemon — `agent-service.ts` `runTurn`), then accept only further\n * frames carrying that same `agentId`. Returns a predicate reporting whether a given frame belongs\n * to this turn and should be applied.\n */\nexport function createFirstTurnGate(\n clientMessageId: string,\n): (msg: { agentId: string; event: AgentStreamEvent }) => boolean {\n let liveAgentId: string | null = null;\n return (msg) => {\n if (liveAgentId === null) {\n if (msg.event.kind !== \"user_message\" || msg.event.messageId !== clientMessageId) return false;\n liveAgentId = msg.agentId;\n }\n return msg.agentId === liveAgentId;\n };\n}\n\nexport function applyAgentStreamEvent({\n sessionId,\n event,\n client,\n queryClient,\n}: ApplyAgentStreamEventArgs): void {\n const sessionStore = useSessionStore.getState();\n sessionStore.applyStreamEvent(sessionId, event);\n switch (event.kind) {\n case \"turn_started\":\n sessionStore.setStatus(sessionId, \"running\");\n break;\n case \"turn_completed\":\n sessionStore.setStatus(sessionId, \"idle\");\n break;\n case \"turn_failed\":\n sessionStore.setStatus(sessionId, \"error\");\n break;\n case \"turn_canceled\":\n sessionStore.setStatus(sessionId, \"idle\");\n break;\n case \"tool_call\": {\n if (event.status === \"completed\" && toolMutatesFiles(event.tool)) {\n const session = sessionStore.sessions[sessionId];\n const cwd = session?.cwd || null;\n invalidateAfterToolCompletion(queryClient, client, cwd, toolFilePath(event.tool));\n }\n break;\n }\n default:\n break;\n }\n}\n","/**\n * Live timeline subscription for a chat session. Subscribes to\n * `client.agent(agentId).timeline.subscribe` whenever both the connection's `client` and the\n * session's `agentId` are available, routing every event through `applyAgentStreamEvent`\n * (POC_TO_APP_PLAN_UI.md §4.3). Also mirrors the POC's `handleAgentStream` turn-lifecycle →\n * `session.status` transitions so the Composer's Stop button and the session-list status dot\n * stay live.\n *\n * NOTE: this only covers events that arrive *after* the subscription attaches, which requires a\n * bound `agentId`. The daemon runs the whole first turn of a brand-new agent *before*\n * `create_agent_request` resolves, so `Composer.handleSend` applies that first turn live from the\n * raw broadcast (latching the agent id from the first `agent_stream` frame it sees) and only\n * calls `bindAgent` once the RPC resolves — after the turn is already applied. This hook therefore\n * attaches only in time for *follow-up* turns, which is exactly what avoids double-applying the\n * first turn (the reducer is not event-id-idempotent).\n */\n\nimport { useEffect } from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useConnectionStore } from \"@pi-studio-ui/lib/connection/connection-store.js\";\nimport { useSessionStore } from \"@pi-studio-ui/stores/session-store.js\";\nimport { applyAgentStreamEvent } from \"./agent-stream-events.js\";\n\nexport function useAgentStream(sessionId: string): void {\n const client = useConnectionStore((s) => s.client);\n const agentId = useSessionStore((s) => s.sessions[sessionId]?.agentId ?? null);\n const queryClient = useQueryClient();\n\n useEffect(() => {\n if (!client || !agentId) return;\n\n const unsubscribe = client.agent(agentId).timeline.subscribe((event) => {\n applyAgentStreamEvent({ sessionId, event, client, queryClient });\n });\n\n return unsubscribe;\n }, [client, agentId, sessionId, queryClient]);\n}\n","/**\n * Assistant message row (POC `.msg.assistant`, POC_TO_APP_PLAN_UI.md §4.3). While streaming,\n * renders plain text with a blinking cursor — re-parsing markdown on every token would be\n * wasteful (§6 Performance strategy). Once `turn_completed` finalizes the row (`streaming:\n * false`), it renders through `<Markdown>`.\n */\n\nimport type { AssistantRow as AssistantRowModel } from \"@pi-studio-ui/timeline/row-model.js\";\nimport { Markdown } from \"@pi-studio-ui/timeline/markdown.js\";\nimport styles from \"./rows.module.css\";\n\nexport interface AssistantRowProps {\n row: AssistantRowModel;\n}\n\nexport function AssistantRow({ row }: AssistantRowProps) {\n return (\n <div className={`${styles.row} ${styles.assistant}${row.streaming ? ` ${styles.streaming}` : \"\"}`}>\n <span className={styles.who}>assistant</span>\n {row.streaming ? (\n <span className={styles.streamingText}>\n {row.text}\n <span className={styles.cursor}>▍</span>\n </span>\n ) : (\n <Markdown text={row.text} />\n )}\n </div>\n );\n}\n","/**\n * Reasoning row — dimmer/italic styling, visually distinct from assistant replies (POC\n * `.msg.reasoning`, POC_TO_APP_PLAN_UI.md §4.3). Streams as plain text with a cursor, same\n * rationale as `AssistantRow`.\n */\n\nimport type { ReasoningRow as ReasoningRowModel } from \"@pi-studio-ui/timeline/row-model.js\";\nimport { Markdown } from \"@pi-studio-ui/timeline/markdown.js\";\nimport styles from \"./rows.module.css\";\n\nexport interface ReasoningRowProps {\n row: ReasoningRowModel;\n}\n\nexport function ReasoningRow({ row }: ReasoningRowProps) {\n return (\n <div className={`${styles.row} ${styles.reasoning}`}>\n <span className={styles.who}>thinking</span>\n {row.streaming ? (\n <span className={styles.streamingText}>\n {row.text}\n <span className={styles.cursor}>▍</span>\n </span>\n ) : (\n <Markdown text={row.text} />\n )}\n </div>\n );\n}\n","/**\n * Tool call card — icon + label + inline detail + status badge header, with an expandable body\n * (POC `.msg.tool`, POC_TO_APP_PLAN_UI.md §4.3). Collapsed by default; clicking the header reveals\n * the full detail as an ordered list of sections: input detail (`edit` diffs render through the\n * shared `<DiffView>`; shell command/path/query/url/task description render in a monospace block)\n * followed by tool output (stdout, file content, etc.), when present. Cards with no expandable\n * sections (`toolBody` → `[]`) show only the header. The virtualized timeline re-measures on\n * expand via `measureElement`, so height changes need no special handling here.\n */\n\nimport { useState } from \"react\";\nimport { ChevronRight } from \"lucide-react\";\nimport { clsx } from \"clsx\";\nimport { StatusBadge } from \"@pi-studio-ui/components/primitives/StatusBadge.js\";\nimport { DiffView } from \"@pi-studio-ui/features/files/DiffView.js\";\nimport { toolIcon, toolLabel, toolInlineDetail, toolBody } from \"@pi-studio-ui/timeline/tool-mapping.js\";\nimport type { ToolRow } from \"@pi-studio-ui/timeline/row-model.js\";\nimport styles from \"./rows.module.css\";\n\nexport interface ToolCardProps {\n row: ToolRow;\n}\n\nconst BADGE_VARIANT = {\n running: \"muted\",\n completed: \"success\",\n error: \"error\",\n} as const;\n\nexport function ToolCard({ row }: ToolCardProps) {\n const [expanded, setExpanded] = useState(false);\n const Icon = toolIcon(row.tool);\n const inlineDetail = toolInlineDetail(row.tool);\n const body = toolBody(row.tool);\n const hasBody = body.length > 0;\n\n return (\n <div className={clsx(styles.row, styles.tool)}>\n <button\n type=\"button\"\n className={styles.toolHeader}\n onClick={() => hasBody && setExpanded((v) => !v)}\n aria-expanded={hasBody ? expanded : undefined}\n disabled={!hasBody}\n >\n {hasBody && (\n <ChevronRight\n size={12}\n className={clsx(styles.toolChevron, expanded && styles.toolChevronOpen)}\n />\n )}\n <span className={clsx(styles.toolIcon, styles[row.status])}>\n <Icon size={14} />\n </span>\n <span className={styles.toolLabel}>{toolLabel(row.tool)}</span>\n {inlineDetail && (\n <span className={styles.toolInlineDetail} title={inlineDetail}>\n {inlineDetail}\n </span>\n )}\n <StatusBadge className={styles.toolBadge} label={row.status} variant={BADGE_VARIANT[row.status]} />\n </button>\n {expanded && hasBody && (\n <div className={styles.toolBody}>\n {body.map((section, i) =>\n section.kind === \"diff\" ? (\n <DiffView key={i} patch={section.patch} />\n ) : (\n <pre key={i} className={styles.toolCode}>\n {section.text}\n </pre>\n ),\n )}\n </div>\n )}\n </div>\n );\n}\n","/**\n * User message row — plain text + optional image thumbnails (POC `.msg.user`,\n * POC_TO_APP_PLAN_UI.md §4.3/§4.4). Images render at up to 200×150, matching the POC's inline\n * `userBubble.appendChild(img)` styling. Clicking a thumbnail opens it full-size in a `Dialog`.\n *\n * `row.pending` (optimistic echo not yet confirmed by the server's `user_message` broadcast —\n * see Composer.tsx) dims the row via CSS; `row.failed` (the RPC rejected before confirmation\n * ever arrived) tints it toward the error color and appends a \"failed to send\" label instead.\n * `row.queued` (steered mid-turn, not yet handed to the LLM — cleared by a `queue_update` stream\n * event, see `timeline/reducer.ts`'s `onQueueUpdate`) shows a small \"queued\" pill next to the\n * sender label. All three are terminal/transient states set by the reducer — this component only\n * reflects them.\n */\n\nimport { useState } from \"react\";\nimport { Dialog } from \"@pi-studio-ui/components/primitives/Dialog.js\";\nimport type { UserRow as UserRowModel } from \"@pi-studio-ui/timeline/row-model.js\";\nimport styles from \"./rows.module.css\";\n\nexport interface UserRowProps {\n row: UserRowModel;\n}\n\nexport function UserRow({ row }: UserRowProps) {\n const [openedSrc, setOpenedSrc] = useState<string | null>(null);\n\n const stateClass = row.failed ? styles.userFailed : row.pending ? styles.userPending : \"\";\n\n return (\n <div className={`${styles.row} ${styles.user}${stateClass ? ` ${stateClass}` : \"\"}`}>\n <span className={styles.who}>\n you{row.failed ? \" · failed to send\" : \"\"}\n {row.queued && !row.failed && <span className={styles.queuedBadge}>queued</span>}\n </span>\n {row.text}\n {row.images && row.images.length > 0 && (\n <div className={styles.userImages}>\n {row.images.map((img, i) => {\n const src = `data:${img.mimeType ?? \"image/png\"};base64,${img.data ?? \"\"}`;\n return (\n <img\n key={i}\n className={styles.userImage}\n src={src}\n alt=\"\"\n role=\"button\"\n tabIndex={0}\n onClick={() => setOpenedSrc(src)}\n onKeyDown={(ev) => {\n if (ev.key === \"Enter\" || ev.key === \" \") setOpenedSrc(src);\n }}\n />\n );\n })}\n </div>\n )}\n <Dialog\n open={openedSrc !== null}\n onOpenChange={(open) => {\n if (!open) setOpenedSrc(null);\n }}\n title=\"Image\"\n width=\"auto\"\n bare\n className={styles.imageDialog}\n >\n {openedSrc && <img className={styles.imageDialogPreview} src={openedSrc} alt=\"\" />}\n </Dialog>\n </div>\n );\n}\n","/**\n * Error row — red-tinted block (POC `.msg.err`, POC_TO_APP_PLAN_UI.md §4.3), used for\n * `turn_failed`/`error` stream events.\n */\n\nimport type { ErrorRow as ErrorRowModel } from \"@pi-studio-ui/timeline/row-model.js\";\nimport styles from \"./rows.module.css\";\n\nexport interface ErrorRowProps {\n row: ErrorRowModel;\n}\n\nexport function ErrorRow({ row }: ErrorRowProps) {\n return (\n <div className={`${styles.row} ${styles.error}`}>\n <span className={styles.who}>error</span>\n {row.text}\n </div>\n );\n}\n","/**\n * System row — muted/italic styling (POC's `turn_canceled` \"(canceled)\" reasoning-styled bubble,\n * POC_TO_APP_PLAN_UI.md §4.3), used for canceled-turn markers and other system notices.\n */\n\nimport type { SystemRow as SystemRowModel } from \"@pi-studio-ui/timeline/row-model.js\";\nimport styles from \"./rows.module.css\";\n\nexport interface SystemRowProps {\n row: SystemRowModel;\n}\n\nexport function SystemRow({ row }: SystemRowProps) {\n return <div className={`${styles.row} ${styles.system}`}>{row.text}</div>;\n}\n","/**\n * Virtualized timeline viewport — TanStack Virtual over `session.timeline.rows` with\n * variable-size rows (POC `.chat-area`, POC_TO_APP_PLAN_UI.md §4.3/§6). Auto-scrolls to the\n * bottom on new rows unless the user has scrolled up more than 40px from the bottom; re-sticks\n * whenever the row count grows from a user's own send (POC's forced `scrollTop = scrollHeight`,\n * fixed to respect manual scroll-up).\n */\n\nimport { useEffect, useRef } from \"react\";\nimport { measureElement as measureElementDefault, useVirtualizer } from \"@tanstack/react-virtual\";\nimport type { SessionEntry } from \"@pi-studio-ui/stores/session-store.js\";\nimport type { TimelineRow } from \"@pi-studio-ui/timeline/row-model.js\";\nimport { AssistantRow } from \"./rows/AssistantRow.js\";\nimport { ReasoningRow } from \"./rows/ReasoningRow.js\";\nimport { ToolCard } from \"./rows/ToolCard.js\";\nimport { UserRow } from \"./rows/UserRow.js\";\nimport { ErrorRow } from \"./rows/ErrorRow.js\";\nimport { SystemRow } from \"./rows/SystemRow.js\";\nimport styles from \"./Timeline.module.css\";\n\nexport interface TimelineProps {\n session: SessionEntry;\n}\n\nconst STICK_THRESHOLD_PX = 40;\n\nfunction renderRow(row: TimelineRow) {\n switch (row.kind) {\n case \"user\":\n return <UserRow row={row} />;\n case \"assistant\":\n return <AssistantRow row={row} />;\n case \"reasoning\":\n return <ReasoningRow row={row} />;\n case \"tool\":\n return <ToolCard row={row} />;\n case \"error\":\n return <ErrorRow row={row} />;\n case \"system\":\n return <SystemRow row={row} />;\n }\n}\n\nexport function Timeline({ session }: TimelineProps) {\n const rows = session.timeline.rows;\n const running = session.status === \"running\";\n const scrollRef = useRef<HTMLDivElement>(null);\n const stickToBottomRef = useRef(true);\n // Init to 0 (not `rows.length`) so a freshly-mounted tab with existing history — a brand-new\n // chat tab switch or a session restored from disk — still counts as \"grew\" on its first effect\n // run and scrolls to the last message, instead of opening at the top.\n const prevRowCountRef = useRef(0);\n\n const virtualizer = useVirtualizer({\n count: rows.length,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => 48,\n overscan: 8,\n getItemKey: (index) => rows[index]?.id ?? index,\n // `TabPanelHost` keeps inactive chat tabs mounted under `display:none` rather than\n // unmounting them (so switching tabs preserves scroll position — see its own doc comment).\n // But a `display:none` ancestor collapses every row to a 0×0 border box, and the default\n // `measureElement` would cache that bogus 0 height — shrinking `.inner`'s total height to\n // ~0 and permanently clamping the scroll container's `scrollTop` to 0 in the process, which\n // survives the tab becoming visible again (the browser never un-clamps a scroll offset just\n // because content grows back). Skip the measurement while hidden and keep whatever size is\n // already cached (or the `estimateSize` default on first mount) instead.\n measureElement: (element, entry, instance) => {\n if ((element as HTMLElement).offsetParent !== null) return measureElementDefault(element, entry, instance);\n const index = instance.indexFromElement(element);\n const key = instance.options.getItemKey(index);\n return instance.itemSizeCache.get(key) ?? instance.options.estimateSize(index);\n },\n });\n\n function handleScroll(): void {\n const el = scrollRef.current;\n if (!el) return;\n const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;\n stickToBottomRef.current = distanceFromBottom < STICK_THRESHOLD_PX;\n }\n\n useEffect(() => {\n const grew = rows.length > prevRowCountRef.current;\n prevRowCountRef.current = rows.length;\n if (!grew) return;\n if (!stickToBottomRef.current) return;\n virtualizer.scrollToIndex(rows.length - 1, { align: \"end\" });\n }, [rows.length, virtualizer]);\n\n if (rows.length === 0) {\n return (\n <div className={styles.viewport} ref={scrollRef}>\n {running ? (\n <div className={styles.working} role=\"status\" aria-live=\"polite\">\n <span className={styles.workingDots} aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </span>\n Agent is working…\n </div>\n ) : (\n <div className={styles.empty}>No messages yet — say something to start.</div>\n )}\n </div>\n );\n }\n\n return (\n <div className={styles.viewport} ref={scrollRef} onScroll={handleScroll}>\n <div className={styles.inner} style={{ height: virtualizer.getTotalSize() }}>\n {virtualizer.getVirtualItems().map((virtualRow) => {\n const row = rows[virtualRow.index];\n if (!row) return null;\n return (\n <div\n key={virtualRow.key}\n ref={virtualizer.measureElement}\n data-index={virtualRow.index}\n className={styles.rowWrap}\n style={{ transform: `translateY(${virtualRow.start}px)` }}\n >\n {renderRow(row)}\n </div>\n );\n })}\n </div>\n {running && (\n <div className={styles.working} role=\"status\" aria-live=\"polite\">\n <span className={styles.workingDots} aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </span>\n Agent is working…\n </div>\n )}\n </div>\n );\n}\n","/**\n * Attachment preview strip — presentational thumbnail row with remove buttons (POC\n * `renderAttachments`, POC_TO_APP_PLAN_UI.md §4.4). Pending-image state lives in `Composer`;\n * this component only renders `images` and forwards `onRemove(index)`.\n */\n\nimport styles from \"./Attachments.module.css\";\n\nexport interface PendingImage {\n mimeType: string;\n /** Base64 payload, no `data:...;base64,` prefix — sent to the daemon as-is. */\n data: string;\n /** Full data URL, for the thumbnail `<img src>`. */\n thumbUrl: string;\n}\n\nexport interface AttachmentsProps {\n images: PendingImage[];\n onRemove: (index: number) => void;\n}\n\nexport function Attachments({ images, onRemove }: AttachmentsProps) {\n if (images.length === 0) return null;\n\n return (\n <div className={styles.strip}>\n {images.map((img, i) => (\n <div key={i} className={styles.thumb}>\n <img src={img.thumbUrl} alt=\"\" />\n <button\n type=\"button\"\n className={styles.remove}\n title=\"Remove\"\n onClick={() => onRemove(i)}\n >\n ×\n </button>\n </div>\n ))}\n </div>\n );\n}\n\n/** `FileReader.readAsDataURL` wrapped as a promise (POC `addImageFile`). */\nexport function readImageFile(file: File): Promise<PendingImage> {\n const { promise, resolve, reject } = Promise.withResolvers<PendingImage>();\n const reader = new FileReader();\n reader.onload = () => {\n const result = reader.result;\n if (typeof result !== \"string\") {\n reject(new Error(\"Unexpected FileReader result\"));\n return;\n }\n const commaIndex = result.indexOf(\",\");\n const data = commaIndex >= 0 ? result.slice(commaIndex + 1) : result;\n resolve({ mimeType: file.type, data, thumbUrl: result });\n };\n reader.onerror = () => reject(reader.error ?? new Error(\"Failed to read file\"));\n reader.readAsDataURL(file);\n return promise;\n}\n","/**\n * Composer — autosizing textarea + attach/send/stop (POC `initChatPanel`/`send()`,\n * POC_TO_APP_PLAN_UI.md §4.4). Send routing: no `agentId` yet → `client.createAgent(...)` then\n * `sessionStore.bindAgent` on success (the race-free binding point `useAgentStream` reacts to);\n * else → `client.agent(agentId).send(...)`. Stop → `client.agent(agentId).interrupt()`.\n *\n * OPTIMISTIC ECHO: `create_agent_request`/`send_agent_prompt` block server-side until the whole\n * turn finishes, and even the *first* broadcast event for that turn (the canonical `user_message`)\n * only fires once the agent process is booted/warm — for a brand-new session that means a real\n * process-spawn+handshake before anything appears (see AGENTS.md \"First-message latency\"). To hide\n * that, `submit` mints a `clientMessageId` and inserts the user's row into the timeline\n * *synchronously*, before the RPC is even issued. The daemon echoes the same id back verbatim as\n * the `user_message` event's `messageId` (`packages/server/src/agent/agent-service.ts` `runTurn`);\n * the reducer (`timeline/reducer.ts` `onUserMessage`) matches it against the pending row and\n * confirms it in place instead of appending a duplicate.\n *\n * A brand-new agent has no live subscription yet when the first turn's events start arriving —\n * `useAgentStream` only attaches once `bindAgent` sets `agentId`, which happens *after*\n * `createAgent()` resolves. So for the first turn `submit` subscribes to the raw broadcast\n * directly and applies each `agent_stream` event *as it arrives*, latching the new agent's id\n * from *its own* `user_message` echo (`messageId === clientMessageId`) — never from \"the first\n * such event\", since another session's agent can be mid-turn on the same socket concurrently and\n * its frames would otherwise be misattributed here (agent_update frames are top-level and never\n * reach `onSessionMessage`; agent_stream frames are session-wrapped and do). That includes the\n * `user_message` event that reconciles the optimistic row above.\n * `bindAgent` is deferred until the RPC resolves so `useAgentStream` attaches only for follow-up\n * turns and never re-applies the first turn (the reducer is not event-id-idempotent).\n *\n * STEERING: while the agent is running, the primary action becomes **Steer** instead of Send\n * (`send_agent_prompt` is only legal when idle — see AGENTS.md \"Steering\"). Steer reuses the exact\n * optimistic-echo + reconciliation path above (`clientMessageId` in, same `user_message` echo\n * back), just against `client.agent(id).steer(...)` instead of `.send(...)`, and marks the\n * optimistic row `queued: true` so `UserRow` can show a \"queued\" badge until a `queue_update`\n * stream event drops the text from its `steering[]` list (`timeline/reducer.ts`'s\n * `onQueueUpdate`). Follow-up (`.followUp(...)`, delivered only after the turn fully stops) is\n * intentionally not surfaced here — SDK/CLI only for now.\n */\n\nimport { useRef, useState, type ChangeEvent, type ClipboardEvent, type KeyboardEvent } from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { Navigation, Paperclip, Send, Square } from \"lucide-react\";\nimport type { AgentStreamEvent } from \"@av-pi-studio/protocol\";\nimport { Button } from \"@pi-studio-ui/components/primitives/Button.js\";\nimport { TextArea } from \"@pi-studio-ui/components/primitives/TextInput.js\";\nimport { useConnectionStore } from \"@pi-studio-ui/lib/connection/connection-store.js\";\nimport { useSessionStore } from \"@pi-studio-ui/stores/session-store.js\";\nimport { applyAgentStreamEvent, createFirstTurnGate } from \"@pi-studio-ui/hooks/agent-stream-events.js\";\nimport { Attachments, readImageFile, type PendingImage } from \"./Attachments.js\";\nimport styles from \"./Composer.module.css\";\n\nconst MAX_TEXTAREA_HEIGHT = 160;\n\nexport interface ComposerProps {\n sessionId: string;\n}\n\nfunction autoResize(el: HTMLTextAreaElement): void {\n el.style.height = \"auto\";\n el.style.height = `${Math.min(el.scrollHeight, MAX_TEXTAREA_HEIGHT)}px`;\n}\n\ninterface AgentStreamMessage {\n type: \"agent_stream\";\n agentId: string;\n event: AgentStreamEvent;\n}\n\nfunction isAgentStreamMessage(msg: unknown): msg is AgentStreamMessage {\n if (typeof msg !== \"object\" || msg === null) return false;\n if (!(\"type\" in msg) || msg.type !== \"agent_stream\") return false;\n return \"agentId\" in msg && typeof msg.agentId === \"string\" && \"event\" in msg;\n}\n\n/** `steer_agent_response`'s `{ ok: false }` — no live turn, or the provider lacks steering. */\nfunction isOkFalse(value: unknown): boolean {\n return typeof value === \"object\" && value !== null && \"ok\" in value && value.ok === false;\n}\n\nexport function Composer({ sessionId }: ComposerProps) {\n const client = useConnectionStore((s) => s.client);\n const session = useSessionStore((s) => s.sessions[sessionId]);\n const bindAgent = useSessionStore((s) => s.bindAgent);\n const addOptimisticUserMessage = useSessionStore((s) => s.addOptimisticUserMessage);\n const markUserMessageFailed = useSessionStore((s) => s.markUserMessageFailed);\n const setCwd = useSessionStore((s) => s.setCwd);\n const queryClient = useQueryClient();\n\n const [text, setText] = useState(\"\");\n const [images, setImages] = useState<PendingImage[]>([]);\n const [sending, setSending] = useState(false);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const running = session?.status === \"running\";\n const canSubmit = Boolean(client) && !sending && (text.trim().length > 0 || images.length > 0);\n\n async function addImageFile(file: File): Promise<void> {\n if (!file.type.startsWith(\"image/\")) return;\n try {\n const image = await readImageFile(file);\n setImages((prev) => [...prev, image]);\n } catch {\n // Best-effort attachment read — ignore unreadable files (POC has no error UI here either).\n }\n }\n\n function handleFileInputChange(ev: ChangeEvent<HTMLInputElement>): void {\n for (const file of ev.target.files ?? []) void addImageFile(file);\n ev.target.value = \"\";\n }\n\n function handlePaste(ev: ClipboardEvent<HTMLTextAreaElement>): void {\n for (const item of ev.clipboardData.items) {\n if (item.type.startsWith(\"image/\")) {\n ev.preventDefault();\n const file = item.getAsFile();\n if (file) void addImageFile(file);\n }\n }\n }\n\n function handleRemoveImage(index: number): void {\n setImages((prev) => prev.filter((_, i) => i !== index));\n }\n\n function handleTextareaChange(ev: ChangeEvent<HTMLTextAreaElement>): void {\n setText(ev.target.value);\n autoResize(ev.target);\n }\n\n function handleKeyDown(ev: KeyboardEvent<HTMLTextAreaElement>): void {\n if (ev.key === \"Enter\" && !ev.shiftKey) {\n ev.preventDefault();\n void submit(running ? \"steer\" : \"send\");\n }\n }\n\n async function submit(mode: \"send\" | \"steer\"): Promise<void> {\n if (!client || !session || sending) return;\n // Steering only makes sense against a live agent — a running session always has one; bail\n // rather than fall through to the create-agent path below (that path is send-only).\n if (mode === \"steer\" && !session.agentId) return;\n const trimmed = text.trim();\n if (!trimmed && images.length === 0) return;\n\n setText(\"\");\n if (textareaRef.current) autoResize(textareaRef.current);\n const sentImages = images;\n setImages([]);\n\n const prompt = trimmed || \"Describe this image\";\n const rpcImages =\n sentImages.length > 0\n ? sentImages.map((img) => ({ mimeType: img.mimeType, data: img.data }))\n : undefined;\n\n // Optimistic echo: render the user's row synchronously instead of waiting for the daemon's\n // `user_message` broadcast (see file header). `clientMessageId` is round-tripped through the\n // RPC below and echoed back verbatim as the broadcast event's `messageId`, which is how the\n // reducer reconciles this row instead of appending a duplicate once the server confirms it.\n // Steered rows are additionally marked `queued: true` (cleared by a later `queue_update`).\n const clientMessageId = crypto.randomUUID();\n addOptimisticUserMessage(sessionId, clientMessageId, prompt, rpcImages, mode === \"steer\");\n\n setSending(true);\n try {\n if (mode === \"steer\") {\n // Fire-and-forget injection into the live turn — never touches `bindAgent` or the\n // first-turn broadcast gate below (those exist only for the no-agent-yet create path).\n const result = await client.agent(session.agentId!).steer(prompt, { clientMessageId, images: rpcImages });\n if (isOkFalse(result)) markUserMessageFailed(sessionId, clientMessageId);\n } else if (!session.agentId) {\n const cwd = session.cwd || \"~\";\n setCwd(sessionId, cwd);\n // The daemon runs the entire first turn *before* `createAgent()` resolves, broadcasting\n // every `agent_stream` event for it in the meantime (agent-service.ts `runTurn`). If we\n // waited for the RPC to learn our agentId the timeline would stay empty (and show no\n // running indicator) until the whole turn finished — the reported bug. Instead we watch\n // the live broadcast during the call and apply events as they arrive.\n //\n // We latch the agent id from *our own* canonical `user_message` echo (`messageId ===\n // clientMessageId`), never from \"the first `agent_stream` frame we happen to observe\":\n // another session's agent can be mid-turn on this same socket right now, so the first\n // frame to arrive after we subscribe may belong to THAT agent, not ours. Latching onto it\n // would misattribute its events into this session's timeline and then silently drop this\n // turn's real events (mismatched agentId) once they start arriving. `agent_update` frames\n // are broadcast bare/top-level and never reach `onSessionMessage` (only `session`-wrapped\n // frames do), but every `agent_stream` frame IS session-wrapped, including the\n // `user_message` echo — so this key is always observable here.\n //\n // `bindAgent` is deferred until *after* the RPC resolves: binding attaches\n // `useAgentStream`, and since the reducer isn't event-id-idempotent, a mid-turn attach\n // would double every remaining row. Binding post-resolve means this handler is the sole\n // applier for the first turn and `useAgentStream` only ever sees follow-up turns.\n const isOwnTurnEvent = createFirstTurnGate(clientMessageId);\n const unsubscribeLive = client.connection.onSessionMessage((msg) => {\n if (!isAgentStreamMessage(msg) || !isOwnTurnEvent(msg)) return;\n applyAgentStreamEvent({ sessionId, event: msg.event, client, queryClient });\n });\n\n let result: { agentId: string };\n try {\n result = await client.createAgent({\n config: { provider: \"pi\", cwd },\n initialPrompt: prompt,\n clientMessageId,\n images: rpcImages,\n labels: {},\n });\n } finally {\n unsubscribeLive();\n }\n\n bindAgent(sessionId, result.agentId);\n } else {\n await client.agent(session.agentId).send(prompt, { clientMessageId, images: rpcImages });\n }\n } catch {\n // RPC rejection before any `user_message` broadcast arrived (e.g. dropped connection) —\n // the optimistic row would otherwise stay pending forever with no feedback. If the server\n // *did* manage to broadcast `user_message` first (the row is already reconciled), this is\n // a no-op — `markUserMessageFailed` only touches a still-pending row. Turn-level failures\n // that occur after that point still surface via `agent_stream` `error`/`turn_failed`\n // events (POC swallows the RPC rejection the same way; the stream is the source of truth\n // for those).\n markUserMessageFailed(sessionId, clientMessageId);\n } finally {\n setSending(false);\n }\n }\n\n function handleStop(): void {\n if (!session?.agentId) return;\n void client?.agent(session.agentId).interrupt();\n }\n\n return (\n <div className={styles.composer}>\n <div className={styles.inputArea}>\n <TextArea\n ref={textareaRef}\n className={styles.textarea}\n rows={1}\n value={text}\n placeholder={\n running\n ? \"Steer the running turn… (Enter to steer, Shift+Enter for newline)\"\n : \"Ask anything… (Enter to send, Shift+Enter for newline)\"\n }\n onChange={handleTextareaChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n />\n <Attachments images={images} onRemove={handleRemoveImage} />\n </div>\n <Button\n className={styles.attachBtn}\n variant=\"ghost\"\n size=\"md\"\n iconOnly\n title=\"Attach image\"\n onClick={() => fileInputRef.current?.click()}\n >\n <Paperclip size={16} />\n </Button>\n <input\n ref={fileInputRef}\n className={styles.hiddenFileInput}\n type=\"file\"\n accept=\"image/*\"\n multiple\n onChange={handleFileInputChange}\n />\n <div className={styles.actions}>\n {running ? (\n <Button\n size=\"sm\"\n disabled={!canSubmit}\n onClick={() => void submit(\"steer\")}\n leftIcon={<Navigation size={14} />}\n >\n Steer\n </Button>\n ) : (\n <Button size=\"sm\" disabled={!canSubmit} onClick={() => void submit(\"send\")} leftIcon={<Send size={14} />}>\n Send\n </Button>\n )}\n {running && (\n <Button size=\"sm\" variant=\"destructive\" onClick={handleStop} leftIcon={<Square size={14} />}>\n Stop\n </Button>\n )}\n </div>\n </div>\n );\n}\n","/**\n * ChatPanel — the tab content mounted by `panel-registry.ts` for `kind: \"chat\"` tabs. Looks up\n * the session by `tab.data.sessionId`, keeps its timeline live via `useAgentStream`, and renders\n * the virtualized `Timeline` + `Composer` (POC_TO_APP_PLAN_UI.md §4.3/§4.4).\n */\n\nimport { useAgentStream } from \"@pi-studio-ui/hooks/use-agent-stream.js\";\nimport { useSessionStore } from \"@pi-studio-ui/stores/session-store.js\";\nimport type { Tab, ChatTabData } from \"@pi-studio-ui/stores/tab-store.js\";\nimport { Timeline } from \"./Timeline.js\";\nimport { Composer } from \"./Composer.js\";\nimport styles from \"./ChatPanel.module.css\";\n\nexport interface ChatPanelProps {\n tab: Tab;\n}\n\nexport function ChatPanel({ tab }: ChatPanelProps) {\n // `panel-registry.ts` only ever mounts this component for `tab.kind === \"chat\"`, whose `data`\n // is always `ChatTabData` — narrowed here since `Tab[\"data\"]` is a union at the type level.\n const { sessionId } = tab.data as ChatTabData;\n const session = useSessionStore((s) => s.sessions[sessionId]);\n\n useAgentStream(sessionId);\n\n if (!session) {\n return (\n <div className={styles.panel}>\n <div className={styles.empty}>Session not found.</div>\n </div>\n );\n }\n\n return (\n <div className={styles.panel}>\n <Timeline session={session} />\n <Composer sessionId={session.id} />\n </div>\n );\n}\n"],"names":["statusBadgeTokens","variant","StatusBadge","label","className","token","color","jsx","styles","ICON_BY_KIND","Terminal","Eye","Pencil","FilePlus","Search","Globe","ListTree","toolIcon","tool","toolLabel","toolFilePath","toolMutatesFiles","toolBody","sections","text","toolDetailText","toolInlineDetail","parts","DEBOUNCE_MS","pendingTimer","invalidateAfterToolCompletion","queryClient","client","cwd","_toolFilePath","createFirstTurnGate","clientMessageId","liveAgentId","msg","applyAgentStreamEvent","sessionId","event","sessionStore","useSessionStore","session","useAgentStream","useConnectionStore","s","agentId","_a","useQueryClient","useEffect","AssistantRow","row","jsxs","Markdown","ReasoningRow","BADGE_VARIANT","ToolCard","expanded","setExpanded","useState","Icon","inlineDetail","body","hasBody","clsx","v","ChevronRight","section","i","DiffView","UserRow","openedSrc","setOpenedSrc","stateClass","img","src","ev","Dialog","open","ErrorRow","SystemRow","STICK_THRESHOLD_PX","renderRow","Timeline","rows","running","scrollRef","useRef","stickToBottomRef","prevRowCountRef","virtualizer","useVirtualizer","index","element","entry","instance","measureElementDefault","key","handleScroll","el","distanceFromBottom","grew","virtualRow","Attachments","images","onRemove","readImageFile","file","promise","resolve","reject","reader","result","commaIndex","data","MAX_TEXTAREA_HEIGHT","autoResize","isAgentStreamMessage","isOkFalse","value","Composer","bindAgent","addOptimisticUserMessage","markUserMessageFailed","setCwd","setText","setImages","sending","setSending","textareaRef","fileInputRef","canSubmit","addImageFile","image","prev","handleFileInputChange","handlePaste","item","handleRemoveImage","_","handleTextareaChange","handleKeyDown","submit","mode","trimmed","sentImages","prompt","rpcImages","isOwnTurnEvent","unsubscribeLive","handleStop","TextArea","Button","Paperclip","Navigation","Send","Square","ChatPanel","tab"],"mappings":"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"}
@@ -1 +0,0 @@
1
- ._badge_jtokc_3{display:inline-flex;align-items:center;justify-content:center;padding:1px 6px;border-radius:9999px;border:1px solid;font-size:var(--pi-font-size-xs, 12px);font-family:var(--pi-font-ui, system-ui, sans-serif);font-weight:500;white-space:nowrap;line-height:1.5}._row_1yibt_3{padding:8px 12px;border-radius:var(--pi-borderRadius-md, 6px);max-width:85%;white-space:pre-wrap;word-break:break-word;line-height:1.5;font-size:13px}._who_1yibt_13{display:block;font-size:10px;color:var(--pi-color-foregroundMuted, #7a8394);margin-bottom:3px;text-transform:uppercase;letter-spacing:.03em}._queuedBadge_1yibt_22{display:inline-block;margin-left:6px;padding:0 4px;border-radius:3px;font-size:9px;font-weight:600;text-transform:none;letter-spacing:normal;vertical-align:middle;background:color-mix(in srgb,var(--pi-color-accent, #2e5cb8) 22%,transparent);color:var(--pi-color-accent, #2e5cb8)}._user_1yibt_38{background:var(--pi-color-accentMuted, #1e3a5f);color:var(--pi-color-foreground, #dbe9ff);align-self:flex-end;border-bottom-right-radius:2px}._userPending_1yibt_45{opacity:.6}._userFailed_1yibt_49{background:var(--pi-color-destructive, #3a1515);color:var(--pi-color-destructiveForeground, #ff8a80);opacity:1}._userImages_1yibt_55{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}._userImage_1yibt_55{max-width:200px;max-height:150px;border-radius:4px;display:block;object-fit:cover;cursor:pointer}._imageDialog_1yibt_71{max-width:90vw}._imageDialogPreview_1yibt_75{display:block;max-width:90vw;max-height:80vh;object-fit:contain}._assistant_1yibt_84{background:var(--pi-color-surface, #1c1f26);color:var(--pi-color-foreground, #d6dae0);align-self:flex-start;border-bottom-left-radius:2px}._assistant_1yibt_84._streaming_1yibt_91{border-left:2px solid var(--pi-color-accent, #2e5cb8)}._streamingText_1yibt_95{white-space:pre-wrap;word-break:break-word}._cursor_1yibt_100{display:inline-block;margin-left:1px;animation:_blink_1yibt_1 1s step-start infinite;color:var(--pi-color-accentBright, #a2b4d7)}@keyframes _blink_1yibt_1{50%{opacity:0}}._reasoning_1yibt_115{background:var(--pi-color-background, #0f1115);color:var(--pi-color-foregroundMuted, #7a8394);font-style:italic;font-size:12px;align-self:flex-start}._tool_1yibt_125{background:var(--pi-color-surface, #1c1f26);border:1px solid var(--pi-color-border, #2c313b);align-self:flex-start;font-size:12px;max-width:90%;padding:0;overflow:hidden}._toolHeader_1yibt_135{display:flex;align-items:center;gap:6px;width:100%;padding:8px 12px;background:none;border:none;color:inherit;font:inherit;text-align:left;cursor:pointer}._toolHeader_1yibt_135:disabled{cursor:default}._toolChevron_1yibt_153{flex-shrink:0;color:var(--pi-color-foregroundMuted, #7a8394);transition:transform .12s ease}._toolChevronOpen_1yibt_159{transform:rotate(90deg)}._toolInlineDetail_1yibt_163{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--pi-color-foregroundMuted, #9aa0a6);font-family:var(--pi-font-mono, ui-monospace, monospace);min-width:0;flex:1}._toolBody_1yibt_173{border-top:1px solid var(--pi-color-border, #2c313b);max-height:420px;overflow:auto}._toolCode_1yibt_179{margin:0;padding:8px 12px;font-family:var(--pi-font-mono, ui-monospace, monospace);font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word;color:var(--pi-color-foreground, #dbe3f0)}._toolIcon_1yibt_190{display:flex;align-items:center;flex-shrink:0}._toolIcon_1yibt_190._running_1yibt_196{color:var(--pi-color-accentBright, #a2b4d7);animation:_pulse_1yibt_1 1.2s ease-in-out infinite}._toolIcon_1yibt_190._completed_1yibt_201{color:var(--pi-color-statusSuccess, #27ae60)}._toolIcon_1yibt_190._error_1yibt_205{color:var(--pi-color-statusDanger, #c0392b)}@keyframes _pulse_1yibt_1{50%{opacity:.5}}._toolLabel_1yibt_215{font-weight:600;text-transform:capitalize}._toolBadge_1yibt_220{margin-left:auto}._error_1yibt_205{background:var(--pi-color-destructive, #3a1515);color:var(--pi-color-destructiveForeground, #ff8a80);align-self:flex-start}._system_1yibt_233{background:transparent;color:var(--pi-color-foregroundMuted, #7a8394);font-style:italic;align-self:flex-start;padding:4px 12px}._viewport_1byko_3{flex:1 1 auto;overflow-y:auto;min-height:0;padding:16px 20px}._inner_1byko_10{position:relative;width:100%}._rowWrap_1byko_15{position:absolute;top:0;left:0;width:100%;display:flex;flex-direction:column;padding-bottom:4px}._empty_1byko_25{display:flex;align-items:center;justify-content:center;height:100%;color:var(--pi-color-foregroundMuted, #7a8394);font-size:13px}._working_1byko_34{display:flex;align-items:center;gap:8px;padding:8px 2px 4px;color:var(--pi-color-foregroundMuted, #7a8394);font-size:13px}._workingDots_1byko_43{display:inline-flex;gap:4px}._workingDots_1byko_43 span{width:6px;height:6px;border-radius:50%;background:var(--pi-color-accentBright, #a2b4d7);animation:_workingBounce_1byko_1 1.2s ease-in-out infinite}._workingDots_1byko_43 span:nth-child(2){animation-delay:.16s}._workingDots_1byko_43 span:nth-child(3){animation-delay:.32s}@keyframes _workingBounce_1byko_1{0%,80%,to{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}._strip_5sm81_4{display:flex;gap:6px;flex-wrap:wrap;padding:6px 0 0}._thumb_5sm81_11{position:relative;width:48px;height:48px;border-radius:4px;overflow:hidden;border:1px solid var(--pi-color-border, #2c313b);flex-shrink:0}._thumb_5sm81_11 img{width:100%;height:100%;object-fit:cover;display:block}._remove_5sm81_28{position:absolute;top:-2px;right:-2px;width:16px;height:16px;background:var(--pi-color-statusDanger, #c0392b);color:#fff;border:none;border-radius:50%;font-size:10px;line-height:16px;text-align:center;cursor:pointer;padding:0}._composer_1ll3p_1{padding:10px 16px;border-top:1px solid var(--pi-color-border, #2c313b);background:var(--pi-color-surface, #14161a);display:flex;gap:8px;align-items:center;flex-shrink:0}._inputArea_1ll3p_13{flex:1;display:flex;flex-direction:column;gap:0;min-width:0}._textarea_1ll3p_21{resize:none;min-height:38px;max-height:160px;overflow-y:auto}._attachBtn_1ll3p_28{flex-shrink:0}._hiddenFileInput_1ll3p_32{display:none}._actions_1ll3p_36{display:flex;flex-direction:column;gap:4px;flex-shrink:0}._panel_12s9l_1{display:flex;flex-direction:column;height:100%;min-height:0}._empty_12s9l_8{display:flex;align-items:center;justify-content:center;height:100%;color:var(--pi-color-foregroundMuted, #7a8394);font-size:13px}
@@ -1,3 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ChatPanel-C5cHHrg2.js","assets/vendor-react-BoIQBqDW.js","assets/vendor-query-AtKBh_Yt.js","assets/vendor-icons-BJD_eLBz.js","assets/markdown-D9FuaV1m.js","assets/vendor-highlight-DCzuSv8g.js","assets/vendor-markdown-B8HSIhaA.js","assets/vendor--os7hw7d.js","assets/markdown-BQwXm0MF.css","assets/DiffView-DlVCPvLc.js","assets/DiffView-CRbeRztO.css","assets/vendor-overlays-UwLNGk04.js","assets/vendor-dnd-D9kA7FgH.js","assets/ChatPanel-DRMI3PJR.css","assets/FilePanel-DFrjCgQW.js","assets/FilePanel-DIInFr3h.css","assets/TerminalPanel-yVOy1dbu.js","assets/vendor-terminal-BhzX2_ts.js","assets/vendor-terminal-DYP7pi_n.css","assets/TerminalPanel-BQj62G6N.css"])))=>i.map(i=>d[i]);
2
- var sn=Object.defineProperty;var on=(t,e,n)=>e in t?sn(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var I=(t,e,n)=>on(t,typeof e!="symbol"?e+"":e,n);import{r as w,j as i,d as rn}from"./vendor-react-BoIQBqDW.js";import{Q as an,a as cn,u as ln,b as dn,c as Ue,d as un}from"./vendor-query-AtKBh_Yt.js";import{A as c,B as u,C as B,D as _t,E as C,F as ye,G as K,H as j,I as g,J as A,K as D,L as Te,M as ie,N as ce}from"./vendor--os7hw7d.js";import{L as pn,P as fn,a as hn,b as gn,c as mn,E as yt,C as bt,d as _n,F as yn,e as wt,f as bn,S as St,G as wn,g as Sn,M as xt,X as $e,h as vt,i as xn,U as vn,R as kn,j as In,A as Cn}from"./vendor-icons-BJD_eLBz.js";import{R as Ke,T as Ve,P as Ge,C as Je,I as J,S as kt,D as Tn,a as jn,b as En,c as Nn,d as tt,e as De}from"./vendor-overlays-UwLNGk04.js";import{u as Rn,a as qn,D as Bn,c as Mn,S as An,h as $n,P as Dn,b as On,C as Fn}from"./vendor-dnd-D9kA7FgH.js";import{_ as Xe}from"./vendor-highlight-DCzuSv8g.js";import"./vendor-markdown-B8HSIhaA.js";(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))s(o);new MutationObserver(o=>{for(const r of o)if(r.type==="childList")for(const a of r.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&s(a)}).observe(document,{childList:!0,subtree:!0});function n(o){const r={};return o.integrity&&(r.integrity=o.integrity),o.referrerPolicy&&(r.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?r.credentials="include":o.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function s(o){if(o.ep)return;o.ep=!0;const r=n(o);fetch(o.href,r)}})();const Pn=new an;function It(t){const e=t.trim().replace(/^#/,""),n=e.length===3?e.split("").map(s=>s+s).join(""):e;if(n.length!==6||/[^0-9a-fA-F]/.test(n))throw new Error(`Invalid hex color: ${t}`);return{r:parseInt(n.slice(0,2),16),g:parseInt(n.slice(2,4),16),b:parseInt(n.slice(4,6),16)}}function Hn(t){return Math.max(0,Math.min(255,Math.round(t)))}function zn({r:t,g:e,b:n}){const s=o=>Hn(o).toString(16).padStart(2,"0");return`#${s(t)}${s(e)}${s(n)}`}function Wn(t){const{r:e,g:n,b:s}=It(t),o=r=>{const a=r/255;return a<=.03928?a/12.92:((a+.055)/1.055)**2.4};return .2126*o(e)+.7152*o(n)+.0722*o(s)}function Ye(t,e="#18181b",n="#ffffff"){return Wn(t)>.45?e:n}function Ln(t,e){const{r:n,g:s,b:o}=It(t),r=Math.max(0,Math.min(1,e));return zn({r:n+(255-n)*r,g:s+(255-s)*r,b:o+(255-o)*r})}function we(t){const e=t.trim().replace(/^#/,"");return(e.length===3||e.length===6)&&!/[^0-9a-fA-F]/.test(e)}const H=(t,e,n,s,o,r,a,l,d,p,h)=>({50:t,100:e,200:n,300:s,400:o,500:r,600:a,700:l,800:d,900:p,950:h}),m={zinc:H("#fafafa","#f4f4f5","#e4e4e7","#d4d4d8","#a1a1aa","#71717a","#52525b","#3f3f46","#27272a","#18181b","#09090b"),gray:H("#f9fafb","#f3f4f6","#e5e7eb","#d1d5db","#9ca3af","#6b7280","#4b5563","#374151","#1f2937","#111827","#030712"),slate:H("#f8fafc","#f1f5f9","#e2e8f0","#cbd5e1","#94a3b8","#64748b","#475569","#334155","#1e293b","#0f172a","#020617"),blue:H("#eff6ff","#dbeafe","#bfdbfe","#93c5fd","#60a5fa","#3b82f6","#2563eb","#1d4ed8","#1e40af","#1e3a8a","#172554"),green:H("#f0fdf4","#dcfce7","#bbf7d0","#86efac","#4ade80","#22c55e","#16a34a","#15803d","#166534","#14532d","#052e16"),red:H("#fef2f2","#fee2e2","#fecaca","#fca5a5","#f87171","#ef4444","#dc2626","#b91c1c","#991b1b","#7f1d1d","#450a0a"),teal:H("#f0fdfa","#ccfbf1","#99f6e4","#5eead4","#2dd4bf","#14b8a6","#0d9488","#0f766e","#115e59","#134e4a","#042f2e"),amber:H("#fffbeb","#fef3c7","#fde68a","#fcd34d","#fbbf24","#f59e0b","#d97706","#b45309","#92400e","#78350f","#451a03"),yellow:H("#fefce8","#fef9c3","#fef08a","#fde047","#facc15","#eab308","#ca8a04","#a16207","#854d0e","#713f12","#422006"),purple:H("#faf5ff","#f3e8ff","#e9d5ff","#d8b4fe","#c084fc","#a855f7","#9333ea","#7e22ce","#6b21a8","#581c87","#3b0764"),orange:H("#fff7ed","#ffedd5","#fed7aa","#fdba74","#fb923c","#f97316","#ea580c","#c2410c","#9a3412","#7c2d12","#431407"),white:"#ffffff",black:"#000000"},Un={statusSuccess:"#16a34a",statusDanger:"#dc2626",statusWarning:"#f59e0b",statusMerged:"#9333ea"},Kn={statusSuccess:"#15803d",statusDanger:"#b91c1c",statusWarning:"#d97706",statusMerged:"#7c3aed"};function Vn(){return{keyword:m.purple[300],string:m.green[300],number:m.orange[300],boolean:m.orange[300],comment:m.zinc[500],function:m.blue[300],variable:m.zinc[200],type:m.teal[300],class:m.amber[300],constant:m.orange[300],operator:m.zinc[400],punctuation:m.zinc[400],tag:m.red[300],attribute:m.amber[300],property:m.blue[200],regexp:m.teal[300],escape:m.orange[200],heading:m.blue[300],link:m.blue[400],deleted:m.red[400],inserted:m.green[400]}}function Gn(){return{keyword:m.purple[700],string:m.green[700],number:m.orange[700],boolean:m.orange[700],comment:m.zinc[500],function:m.blue[700],variable:m.zinc[800],type:m.teal[700],class:m.amber[700],constant:m.orange[700],operator:m.zinc[600],punctuation:m.zinc[600],tag:m.red[700],attribute:m.amber[700],property:m.blue[700],regexp:m.teal[700],escape:m.orange[700],heading:m.blue[700],link:m.blue[600],deleted:m.red[700],inserted:m.green[700]}}function Ct(t,e,n){return{background:t,foreground:e,cursor:n,cursorAccent:t,selectionBackground:"rgba(255,255,255,0.18)",black:m.zinc[900],red:m.red[500],green:m.green[500],yellow:m.amber[500],blue:m.blue[500],magenta:m.purple[500],cyan:m.teal[500],white:m.zinc[300],brightBlack:m.zinc[600],brightRed:m.red[400],brightGreen:m.green[400],brightYellow:m.amber[400],brightBlue:m.blue[400],brightMagenta:m.purple[400],brightCyan:m.teal[400],brightWhite:m.zinc[50]}}function de(t){const e=m.zinc[50],n=Ye(t.accent);return{surface0:t.surface0,surface1:t.surface1,surface2:t.surface2,surface3:t.surface3,surface4:t.surface4,surfaceDiffEmpty:t.surfaceDiffEmpty,surfaceSidebar:t.surfaceSidebar,surfaceSidebarHover:t.surfaceSidebarHover,surfaceWorkspace:t.surface1,foreground:e,foregroundMuted:t.mutedForeground,accent:t.accent,accentBright:t.accentBright,accentForeground:n,destructive:t.destructive,destructiveForeground:m.white,success:t.accent,successForeground:m.white,border:t.border,borderAccent:t.borderAccent,...Un,diffAddition:m.green[400],diffDeletion:m.red[500],scrollbarHandle:t.scrollbarHandle,background:t.surface0,popover:t.surface2,popoverForeground:e,primary:t.accent,secondary:t.surface2,muted:t.surface2,mutedForeground:t.mutedForeground,input:t.surface2,ring:t.accent,palette:m,syntax:Vn(),terminal:Ct(t.surface0,e,t.accent)}}function Jn(){const t="#1a1a1e",e="#253e6f";return{surface0:"#ffffff",surface1:"#fafafa",surface2:"#f4f4f5",surface3:"#e4e4e7",surface4:"#d4d4d8",surfaceDiffEmpty:"#f6f6f6",surfaceSidebar:"#f4f4f5",surfaceSidebarHover:"#e9e9ec",surfaceWorkspace:"#ffffff",foreground:t,foregroundMuted:"#71717a",accent:e,accentBright:"#2f4f8e",accentForeground:Ye(e),destructive:"#b04138",destructiveForeground:"#ffffff",success:e,successForeground:"#ffffff",border:"#e4e4e7",borderAccent:"#ececf1",...Kn,diffAddition:"#15803d",diffDeletion:"#b91c1c",scrollbarHandle:"#3f3f46",background:"#ffffff",popover:"#ffffff",popoverForeground:t,primary:e,secondary:"#f4f4f5",muted:"#f4f4f5",mutedForeground:"#71717a",input:"#f4f4f5",ring:e,palette:m,syntax:Gn(),terminal:{...Ct("#ffffff",t,e),selectionBackground:"rgba(0,0,0,0.15)",white:"#ffffff",brightWhite:"#fafafa"}}}const Xn={light:"#ffffff",dark:"#3b62b0",zinc:"#808080",midnight:"#4A6BA8",claude:"#D97757",ghostty:"#8caaee"},Tt=["light","dark","zinc","midnight","claude","ghostty"];function Yn(t){if(t==="light")return Jn();switch(t){case"dark":return de({surface0:"#181B1A",surface1:"#1E2120",surface2:"#272A29",surface3:"#434645",surface4:"#595B5B",surfaceDiffEmpty:"#252827",surfaceSidebar:"#141716",surfaceSidebarHover:"#1c1f1e",mutedForeground:"#A1A5A4",scrollbarHandle:"#717574",border:"#252B2A",borderAccent:"#2f3135",accent:"#2e5cb8",accentBright:"#a2b4d7",destructive:"#c64f43"});case"zinc":return de({surface0:"#18181b",surface1:"#1f1f22",surface2:"#27272a",surface3:"#3f3f46",surface4:"#52525b",surfaceDiffEmpty:"#242427",surfaceSidebar:"#131316",surfaceSidebarHover:"#1b1b1e",mutedForeground:"#a1a1aa",scrollbarHandle:"#71717a",border:"#27272a",borderAccent:"#303036",accent:"#e4e4e7",accentBright:"#fafafa",destructive:"#c44a4a"});case"midnight":return de({surface0:"#161820",surface1:"#1c1e27",surface2:"#252731",surface3:"#3c3e4c",surface4:"#535564",surfaceDiffEmpty:"#222430",surfaceSidebar:"#121420",surfaceSidebarHover:"#1a1c28",mutedForeground:"#9a9db0",scrollbarHandle:"#6b6e82",border:"#242636",borderAccent:"#2e3040",accent:"#3b6fcf",accentBright:"#7eaaeb",destructive:"#c44a52"});case"claude":return de({surface0:"#1f1f1e",surface1:"#262523",surface2:"#2f2d2b",surface3:"#4a4745",surface4:"#605d5b",surfaceDiffEmpty:"#2a2826",surfaceSidebar:"#1a1918",surfaceSidebarHover:"#222120",mutedForeground:"#ada9a5",scrollbarHandle:"#78746f",border:"#2c2a27",borderAccent:"#36332f",accent:"#d97757",accentBright:"#e89a7f",destructive:"#cf513e"});case"ghostty":return de({surface0:"#282c34",surface1:"#2f333d",surface2:"#383c48",surface3:"#4a4f5e",surface4:"#5b6175",surfaceDiffEmpty:"#323643",surfaceSidebar:"#21252d",surfaceSidebarHover:"#292d36",mutedForeground:"#c8ccd8",scrollbarHandle:"#a0a4b2",border:"#353a47",borderAccent:"#3f4454",accent:"#89b4fa",accentBright:"#b4d0fc",destructive:"#c44a55"})}}const jt={};for(const t of Tt){const e=t==="light"?"light":"dark";jt[t]={name:t,colorScheme:e,colors:Yn(t),swatch:Xn[t]}}const Qn=jt,Zn={0:0,1:4,"1.5":6,2:8,3:12,4:16,6:24,8:32,12:48,16:64,20:80,24:96,32:128},Et={xs:12,code:12,sm:14,base:16,lg:18,xl:20,"2xl":22,"3xl":26,"4xl":34},es={normal:"400",medium:"500",semibold:"600",bold:"700"},ts={none:0,sm:2,base:4,md:6,lg:8,xl:12,"2xl":16,full:9999},ns={0:0,1:1,2:2},ss={0:0,50:.5,100:1},os={xs:12,sm:14,md:16,lg:20},rs={diff:22},Nt='system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',Rt='ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace';function as(t){const e=t==="dark"?"rgba(0,0,0,0.55)":"rgba(24,24,27,0.12)";return{sm:{color:e,offsetX:0,offsetY:1,radius:2,elevation:1},md:{color:e,offsetX:0,offsetY:3,radius:8,elevation:4},lg:{color:e,offsetX:0,offsetY:10,radius:24,elevation:12}}}function qt(t){const e=Qn[t];return{name:t,colorScheme:e.colorScheme,colors:e.colors,spacing:Zn,fontSize:{...Et},fontFamily:{ui:Nt,mono:Rt},lineHeight:{...rs},iconSize:os,fontWeight:es,borderRadius:ts,borderWidth:ns,opacity:ss,shadow:as(e.colorScheme),swatch:e.swatch}}const is=16,cs=10,ls=24;function ds(t,e){const n=e.themeName??t.name,s=qt(n),o=e.uiFont&&e.uiFont.trim()!==""?e.uiFont:Nt,r=e.monoFont&&e.monoFont.trim()!==""?e.monoFont:Rt;let a={...s.fontSize};if(e.fontSize!=null){const d=Math.max(cs,Math.min(ls,e.fontSize))/is,p=["xs","code","sm","base","lg","xl","2xl","3xl","4xl"];for(const h of p){const _=Et[h];a[h]=Math.round(_*d)}}return{...s,fontSize:a,fontFamily:{ui:o,mono:r}}}function us(t){return qt(t)}const ps="dark";function fs(t){const e={};hs(t.colors,e);for(const[n,s]of Object.entries(t.spacing))e[`--pi-spacing-${n}`]=`${s}px`;for(const[n,s]of Object.entries(t.fontSize))e[`--pi-font-size-${n}`]=`${s}px`;e["--pi-font-ui"]=t.fontFamily.ui,e["--pi-font-mono"]=t.fontFamily.mono,e["--pi-line-height-diff"]=`${t.lineHeight.diff}px`;for(const[n,s]of Object.entries(t.iconSize))e[`--pi-icon-size-${n}`]=`${s}px`;for(const[n,s]of Object.entries(t.fontWeight))e[`--pi-font-weight-${n}`]=String(s);for(const[n,s]of Object.entries(t.borderRadius))e[`--pi-radius-${n}`]=s===9999?"9999px":`${s}px`;for(const[n,s]of Object.entries(t.borderWidth))e[`--pi-border-width-${n}`]=`${s}px`;for(const[n,s]of Object.entries(t.opacity))e[`--pi-opacity-${n}`]=String(s);for(const[n,s]of Object.entries(t.shadow))if(typeof s=="string")e[`--pi-shadow-${n}`]=s;else if(s&&typeof s=="object"){const o=s;e[`--pi-shadow-${n}`]=`${o.offsetX}px ${o.offsetY}px ${o.radius}px ${o.color}`}return e["--pi-color-scheme"]=t.colorScheme,e}function hs(t,e){const{palette:n,syntax:s,terminal:o,...r}=t;for(const[a,l]of Object.entries(r))typeof l=="string"&&(e[`--pi-color-${a}`]=l);s&&gs(s,e),o&&(e["--pi-terminal-bg"]=o.background,e["--pi-terminal-fg"]=o.foreground)}function gs(t,e){for(const[n,s]of Object.entries(t))typeof s=="string"&&(e[`--syntax-${ms(n)}`]=s)}function ms(t){return t.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function _s(t){if(typeof document>"u")return;const e=document.documentElement.style;for(const[s,o]of Object.entries(t))e.setProperty(s,o);const n=t["--pi-color-scheme"];n&&document.documentElement.style.setProperty("color-scheme",n)}function ys(t){const e=fs(t);_s(e)}const ue=c().min(1,"Asset path must not be empty"),bs=u({accent:c().refine(we,{message:"accent must be a valid #rrggbb hex color"}),accentBright:c().refine(we,{message:"accentBright must be a valid #rrggbb hex color"}).optional(),accentForeground:c().refine(we,{message:"accentForeground must be a valid #rrggbb hex color"}).optional(),swatch:c().refine(we,{message:"swatch must be a valid #rrggbb hex color"}).optional()}),ws=u({logoLight:ue,logoDark:ue,logoMark:ue.optional(),icon:ue,splash:ue.optional()}),Ss=u({docs:c().url().optional(),support:c().url().optional(),issues:c().url().optional(),website:c().url().optional()}).optional(),xs=u({copyright:c().optional(),companyName:c().optional()}).optional();u({productName:c().min(1,"productName is required"),shortName:c().optional(),tagline:c().optional(),colors:bs,assets:ws,links:Ss,legal:xs});function vs(t){const e=t.accent,n=t.accentBright??Ln(e,.35),s=t.accentForeground??Ye(e),o=t.swatch??e;return{accent:e,accentBright:n,accentForeground:s,swatch:o}}function ks(t,e){return{...t,colors:{...t.colors,accent:e.accent,accentBright:e.accentBright,accentForeground:e.accentForeground,primary:e.accent,ring:e.accent},swatch:e.swatch}}const nt="pi-studio-appearance";function Is(t,e){let n=l(t),s=null;function o(h){return h==="system"?typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":h}function r(h,_){const f=o(h),x=us(f);let S=ds(x,{..._,themeName:f});if(e!=null&&e.colors){const y=vs(e.colors);S=ks(S,y)}return S}function a(){const h=JSON.stringify({mode:n.mode,settings:n.settings});t.set(nt,h)}function l(h){const _=h.get(nt);let f=ps,x={};if(_)try{const y=JSON.parse(_);y.mode&&(Tt.includes(y.mode)||y.mode==="system")&&(f=y.mode),y.settings&&typeof y.settings=="object"&&(x=y.settings)}catch{}const S=r(f,x);return{mode:f,settings:x,resolvedTheme:S}}function d(){n={...n,resolvedTheme:r(n.mode,n.settings)},a()}const p={getState(){return n},setMode(h){n={...n,mode:h},d(),p.apply()},updateSettings(h){n={...n,settings:{...n.settings,...h}},d(),p.apply()},apply(){ys(n.resolvedTheme)},listen(){if(typeof window>"u")return()=>{};const h=window.matchMedia("(prefers-color-scheme: dark)"),_=()=>{n.mode==="system"&&(d(),p.apply())};return h.addEventListener("change",_),s=()=>h.removeEventListener("change",_),s}};return p}function Cs({store:t,brandConfig:e,children:n}){const s=w.useRef(null);return s.current||(s.current=Is(t,e),s.current.apply()),w.useEffect(()=>s.current.listen(),[]),i.jsx(i.Fragment,{children:n})}const Ts={get(t){var e;try{return((e=globalThis.localStorage)==null?void 0:e.getItem(t))??null}catch{return null}},set(t,e){var n;try{(n=globalThis.localStorage)==null||n.setItem(t,e)}catch{}}};function js({children:t}){return i.jsx(Cs,{store:Ts,children:i.jsx(cn,{client:Pn,children:t})})}const Es="_btn_1chbg_4",Ns="_secondary_1chbg_44",Rs="_outline_1chbg_53",qs="_ghost_1chbg_62",Bs="_destructive_1chbg_72",Ms="_iconOnly_1chbg_82",As="_loadingSpinner_1chbg_89",$s="_piSpin_1chbg_1",Se={btn:Es,default:"_default_1chbg_35",secondary:Ns,outline:Rs,ghost:qs,destructive:Bs,iconOnly:Ms,loadingSpinner:As,piSpin:$s},st={xs:28,sm:32,md:36,lg:40},Ds={xs:12,sm:14,md:16,lg:20},ot={xs:8,sm:10,md:12,lg:16},Os={xs:12,sm:13,md:14,lg:15};function Fs(t){const{disabled:e,loading:n}=t;return e||n?{opacity:.5,isGhostHover:!1}:{opacity:1,isGhostHover:!1}}function z({variant:t="default",size:e="md",loading:n=!1,disabled:s=!1,leftIcon:o,trailing:r,iconOnly:a=!1,children:l,style:d,className:p,...h}){const{opacity:_}=Fs({disabled:s??!1,loading:n}),f=s||n,x=Ds[e];return i.jsxs("button",{className:B(Se.btn,Se[t],a&&Se.iconOnly,p),disabled:f,"aria-busy":n||void 0,style:{minHeight:st[e],paddingLeft:a?void 0:ot[e],paddingRight:a?void 0:ot[e],fontSize:Os[e],opacity:_,...a?{width:st[e]}:{},...d},...h,children:[n?i.jsx(pn,{className:Se.loadingSpinner,size:x,"aria-hidden":!0}):o?i.jsx("span",{"aria-hidden":!0,style:{display:"flex",alignItems:"center",flexShrink:0},children:o}):null,l,r&&!n&&i.jsx("span",{"aria-hidden":!0,style:{display:"flex",alignItems:"center",flexShrink:0},children:r})]})}const Ps="_input_a7qyq_3",Hs="_textarea_a7qyq_32",Oe={input:Ps,textarea:Hs},Fe=w.forwardRef(function({className:e,...n},s){return i.jsx("input",{ref:s,className:B(Oe.input,e),...n})}),jl=w.forwardRef(function({className:e,...n},s){return i.jsx("textarea",{ref:s,className:B(Oe.input,Oe.textarea,e),...n})}),Bt=c().datetime({offset:!0});c().uuid();c().regex(/^[A-Za-z0-9_-]+$/,"expected base64url");const _e=_t([C(),Bt]),zs=ye(["mobile","browser","cli","mcp"]),Ws=u({type:g("hello"),clientId:c(),clientType:zs,protocolVersion:C(),appVersion:c().optional(),capabilities:K(c(),j()).optional()}),Ls=u({status:g("server_info"),serverId:c(),hostname:c().optional(),version:c().optional(),capabilities:K(c(),A()),features:K(c(),A())}),Us=u({type:g("status"),payload:Ls}),Ks=u({type:g("ping"),requestId:c(),clientSentAt:_e.optional()}),Vs=u({type:g("pong"),requestId:c(),clientSentAt:_e.optional(),serverReceivedAt:_e,serverSentAt:_e}),Mt=ye(["initializing","idle","running","error","closed"]),je=u({mimeType:c().optional(),data:c().optional()}).passthrough(),Gs=u({prs:D(A()).optional(),issues:D(A()).optional()}).passthrough(),Js=u({provider:c(),cwd:c(),modeId:c().optional(),model:c().optional(),thinkingOptionId:c().optional(),featureValues:K(c(),A()).optional(),title:c().nullable().optional(),approvalPolicy:c().optional(),sandboxMode:c().optional(),networkAccess:j().optional(),webSearch:j().optional(),extra:u({pi:A().optional()}).passthrough().optional(),systemPrompt:c().optional(),mcpServers:K(c(),A()).optional()}),Xs=u({type:g("create_agent_request"),requestId:c(),config:Js,env:K(c(),c()).optional(),workspaceId:c().optional(),worktreeName:c().optional(),initialPrompt:c().optional(),clientMessageId:c().optional(),outputSchema:K(c(),A()).optional(),images:D(je).optional(),attachments:Gs.optional(),git:A().optional(),worktree:A().optional(),autoArchive:j().optional(),labels:K(c(),c()).default({})}),Ys=u({type:g("create_agent_response"),requestId:c(),payload:u({agentId:c()}).passthrough()}),Qs=u({type:g("agent_update"),agentId:c(),status:Mt.optional(),title:c().nullable().optional(),labels:K(c(),c()).optional()}),Zs=u({type:g("agent_status"),agentId:c(),status:Mt}),eo=u({type:g("agent_list"),agents:D(u({id:c()}).passthrough())}),to=u({type:g("agent_deleted"),agentId:c()}),no=u({type:g("agent_archived"),agentId:c(),archivedAt:Bt.optional()}),At=Te("kind",[u({kind:g("shell"),command:c().optional(),output:c().optional()}),u({kind:g("read"),path:c().optional(),output:c().optional()}),u({kind:g("edit"),path:c().optional(),diff:c().optional(),output:c().optional()}),u({kind:g("write"),path:c().optional(),output:c().optional()}),u({kind:g("search"),query:c().optional(),output:c().optional()}),u({kind:g("fetch"),url:c().optional(),output:c().optional()}),u({kind:g("task"),description:c().optional(),output:c().optional()})]),so=Te("kind",[u({kind:g("user_message"),messageId:c().optional(),text:c().optional(),images:D(je).optional()}),u({kind:g("assistant_message"),messageId:c().optional(),text:c().optional()}),u({kind:g("reasoning"),text:c().optional()}),u({kind:g("tool_call"),callId:c().optional(),tool:At,status:c().optional()}),u({kind:g("turn_started"),turnId:c().optional()}),u({kind:g("turn_completed"),turnId:c().optional()}),u({kind:g("turn_failed"),turnId:c().optional(),error:c().optional()}),u({kind:g("turn_canceled"),turnId:c().optional()}),u({kind:g("error"),message:c().optional()}),u({kind:g("queue_update"),steering:D(c()).optional(),followUp:D(c()).optional()})]),oo=u({type:g("agent_stream"),agentId:c(),seq:C().optional(),timestamp:_e.optional(),event:so}),ro=ye(["before","after"]),ao=u({start:C(),end:C()}),io=u({type:g("fetch_agent_timeline_request"),requestId:c(),agentId:c(),cursor:c().nullable().optional(),direction:ro,limit:C().optional()}),co=u({type:g("fetch_agent_timeline_response"),requestId:c(),agentId:c().optional(),items:D(A()),seqStart:C(),seqEnd:C(),sourceSeqRanges:D(ao),collapsed:j(),hasNewer:j(),startCursor:c().nullable().optional(),endCursor:c().nullable().optional()}),lo=u({type:g("agent_permission_request"),requestId:c(),agentId:c(),toolName:c().optional(),tool:At.optional(),action:A().optional(),responses:D(c()).optional()}),uo=u({type:g("agent_permission_resolved"),requestId:c(),agentId:c(),decision:c().optional()}),po=u({type:g("agent.permission.respond.request"),requestId:c(),permissionRequestId:c(),response:A()}),fo=u({type:g("agent.permission.respond.response"),requestId:c(),payload:u({resolved:j()}).passthrough()}),ho=u({type:g("respond_to_permission"),requestId:c(),permissionRequestId:c(),response:A()}),$t=ye(["conversation","files","both"]),go=u({type:g("agent.rewind.request"),requestId:c(),agentId:c(),messageId:c(),mode:$t}).passthrough(),mo=u({type:g("agent.rewind.response"),requestId:c(),payload:u({agentId:c(),messageId:c(),mode:$t,truncatedAt:c().optional()}).passthrough()}).passthrough(),_o=u({input:C().optional(),output:C().optional(),cacheRead:C().optional(),cacheWrite:C().optional(),total:C().optional()}).passthrough(),yo=u({tokens:C().nullable().optional(),contextWindow:C().optional(),percent:C().nullable().optional()}).passthrough(),bo=u({type:g("agent_session_stats_request"),requestId:c(),agentId:c()}).passthrough(),wo=u({type:g("agent_session_stats_response"),requestId:c(),payload:u({sessionId:c().optional(),sessionFile:c().optional(),userMessages:C().optional(),assistantMessages:C().optional(),toolCalls:C().optional(),toolResults:C().optional(),totalMessages:C().optional(),tokens:_o.optional(),cost:C().optional(),contextUsage:yo.optional()}).passthrough()}).passthrough(),So=u({type:g("agent_compact_request"),requestId:c(),agentId:c(),customInstructions:c().optional()}).passthrough(),xo=u({type:g("agent_compact_response"),requestId:c(),payload:u({summary:c().optional(),firstKeptEntryId:c().optional(),tokensBefore:C().optional(),details:A().optional()}).passthrough()}).passthrough(),vo=u({type:g("agent_new_session_request"),requestId:c(),agentId:c()}).passthrough(),ko=u({type:g("agent_new_session_response"),requestId:c(),payload:u({cancelled:j()}).passthrough()}).passthrough(),Io=u({type:g("agent_switch_session_request"),requestId:c(),agentId:c(),sessionPath:c()}).passthrough(),Co=u({type:g("agent_switch_session_response"),requestId:c(),payload:u({cancelled:j()}).passthrough()}).passthrough(),To=u({type:g("agent_fork_request"),requestId:c(),agentId:c(),entryId:c()}).passthrough(),jo=u({type:g("agent_fork_response"),requestId:c(),payload:u({text:c(),cancelled:j()}).passthrough()}).passthrough(),Eo=u({type:g("agent_fork_messages_request"),requestId:c(),agentId:c()}).passthrough(),No=u({type:g("agent_fork_messages_response"),requestId:c(),payload:u({messages:D(u({entryId:c(),text:c()}).passthrough())}).passthrough()}).passthrough(),Ro=u({type:g("agent_clone_request"),requestId:c(),agentId:c()}).passthrough(),qo=u({type:g("agent_clone_response"),requestId:c(),payload:u({cancelled:j()}).passthrough()}).passthrough(),Bo=u({type:g("agent_set_session_name_request"),requestId:c(),agentId:c(),name:c()}).passthrough(),Mo=u({type:g("agent_set_session_name_response"),requestId:c(),payload:u({}).passthrough().optional()}).passthrough(),Ao=u({type:g("agent_export_html_request"),requestId:c(),agentId:c(),outputPath:c().optional()}).passthrough(),$o=u({type:g("agent_export_html_response"),requestId:c(),payload:u({path:c()}).passthrough()}).passthrough(),Do=u({type:g("agent_set_model_request"),requestId:c(),agentId:c(),provider:c(),modelId:c()}).passthrough(),Oo=u({type:g("agent_set_model_response"),requestId:c(),payload:u({}).passthrough()}).passthrough(),Fo=u({type:g("agent_cycle_model_request"),requestId:c(),agentId:c()}).passthrough(),Po=u({type:g("agent_cycle_model_response"),requestId:c(),payload:u({model:A().nullable().optional(),thinkingLevel:c().optional(),isScoped:j().optional()}).passthrough()}).passthrough(),Ho=u({type:g("agent_last_assistant_text_request"),requestId:c(),agentId:c()}).passthrough(),zo=u({type:g("agent_last_assistant_text_response"),requestId:c(),payload:u({text:c().nullable()}).passthrough()}).passthrough(),Wo=u({type:g("steer_agent_request"),requestId:c(),agentId:c(),message:c(),images:D(je).optional(),clientMessageId:c().optional()}).passthrough(),Lo=u({type:g("steer_agent_response"),requestId:c(),agentId:c(),ok:j()}).passthrough(),Uo=u({type:g("follow_up_agent_request"),requestId:c(),agentId:c(),message:c(),images:D(je).optional(),clientMessageId:c().optional()}).passthrough(),Ko=u({type:g("follow_up_agent_response"),requestId:c(),agentId:c(),ok:j()}).passthrough(),Vo=u({type:g("rpc_error"),requestId:c(),code:c().optional(),message:c().optional(),error:c().optional()}),Go=Te("type",[Xs,Ys,Qs,Zs,eo,to,no,oo,io,co,lo,uo,po,fo,ho,go,mo,bo,wo,So,xo,vo,ko,Io,Co,To,jo,Eo,No,Ro,qo,Bo,Mo,Ao,$o,Do,Oo,Fo,Po,Ho,zo,Wo,Lo,Uo,Ko,Vo]),Jo=u({type:c()}).passthrough(),Xo=u({type:g("session"),message:_t([Go,Jo])});Te("type",[Ws,Us,Ks,Vs,Xo]);const oe={Output:1,Input:2,Resize:3,Snapshot:4,Restore:5},Yo=Object.fromEntries(Object.entries(oe).map(([t,e])=>[e,t])),Dt=u({rows:C().int().nonnegative(),cols:C().int().nonnegative()});class he extends Error{constructor(e){super(e),this.name="TerminalFrameError"}}const Qo=new TextEncoder,Zo=new TextDecoder;function er(t){if(!Number.isInteger(t)||t<0||t>255)throw new he(`slot must be an integer 0–255, got ${t}`)}function pe(t,e,n){const s=new Uint8Array(2+n.length);return s[0]=t,s[1]=e,s.set(n,2),s}function El(t){switch(er(t.slot),t.opcode){case"Output":return pe(oe.Output,t.slot,t.data);case"Input":return pe(oe.Input,t.slot,t.data);case"Snapshot":return pe(oe.Snapshot,t.slot,t.data);case"Restore":return pe(oe.Restore,t.slot,t.data);case"Resize":{const e=JSON.stringify(Dt.parse({rows:t.rows,cols:t.cols}));return pe(oe.Resize,t.slot,Qo.encode(e))}}}function tr(t){if(t.length<2)throw new he(`frame too short: ${t.length} bytes (need ≥ 2)`);const e=t[0],n=t[1],s=Yo[e];if(!s)throw new he(`unknown terminal opcode 0x${e.toString(16)}`);const o=t.subarray(2);if(s==="Resize"){let r;try{r=JSON.parse(Zo.decode(o))}catch{throw new he("resize payload is not valid JSON")}const a=Dt.safeParse(r);if(!a.success)throw new he("resize payload is not { rows, cols }");return{opcode:"Resize",slot:n,rows:a.data.rows,cols:a.data.cols}}return{opcode:s,slot:n,data:o.slice()}}const ae={Begin:16,Chunk:17,End:18,Error:19},nr=Object.fromEntries(Object.entries(ae).map(([t,e])=>[e,t])),Ot=u({transferId:c(),fileName:c().optional(),mimeType:c().optional(),totalBytes:C().int().nonnegative().optional()});class ge extends Error{constructor(e){super(e),this.name="FileTransferFrameError"}}const rt=new TextEncoder,at=new TextDecoder;function sr(t){if(!Number.isInteger(t)||t<0||t>255)throw new ge(`stream must be an integer 0–255, got ${t}`)}function xe(t,e,n){const s=new Uint8Array(2+n.length);return s[0]=t,s[1]=e,s.set(n,2),s}function qe(t){switch(sr(t.stream),t.opcode){case"Begin":return xe(ae.Begin,t.stream,rt.encode(JSON.stringify(Ot.parse(t.meta))));case"Chunk":return xe(ae.Chunk,t.stream,t.data);case"End":return xe(ae.End,t.stream,new Uint8Array([t.ok?1:0]));case"Error":return xe(ae.Error,t.stream,rt.encode(t.message))}}function or(t){if(t.length<2)throw new ge(`frame too short: ${t.length} bytes (need ≥ 2)`);const e=t[0],n=t[1],s=nr[e];if(!s)throw new ge(`unknown file-transfer opcode 0x${e.toString(16)}`);const o=t.subarray(2);switch(s){case"Begin":{let r;try{r=JSON.parse(at.decode(o))}catch{throw new ge("begin payload is not valid JSON")}const a=Ot.safeParse(r);if(!a.success)throw new ge("begin payload is not a valid transfer header");return{opcode:"Begin",stream:n,meta:a.data}}case"Chunk":return{opcode:"Chunk",stream:n,data:o.slice()};case"End":return{opcode:"End",stream:n,ok:(o[0]??1)!==0};case"Error":return{opcode:"Error",stream:n,message:at.decode(o)}}}function rr(t){try{return or(t)}catch{return null}}const ar=c().regex(/^[a-z][a-z0-9-]*$/,"invalid provider id"),ir=ye(["safe","moderate","dangerous","planning"]),cr=u({supportsStreaming:j(),supportsSessionPersistence:j(),supportsDynamicModes:j(),supportsMcpServers:j(),supportsReasoningStream:j(),supportsToolInvocations:j(),supportsRewindConversation:j().optional(),supportsRewindFiles:j().optional(),supportsRewindBoth:j().optional(),supportsSteering:j().optional()}).passthrough(),lr=u({id:c(),label:c().optional(),description:c().optional(),icon:c().optional(),colorTier:ir});u({id:ar,label:c(),description:c().optional(),extends:c().optional(),modes:D(lr),capabilities:cr});function Pe(t){return typeof t=="string"?t:t instanceof Uint8Array||Buffer.isBuffer(t)?t.toString("utf8"):String(t??"")}function Ft(t){let e=null;const n={onMessage:null,onClose:null,onError:null,get isOpen(){return e!==null&&e.readyState===1},connect(s){return new Promise((o,r)=>{const a=t??(()=>new WebSocket(s));try{e=t?a(s):new WebSocket(s)}catch(l){r(l);return}e.onopen=()=>o(),e.onerror=l=>{var d;(e==null?void 0:e.readyState)!==1&&r(l),(d=n.onError)==null||d.call(n,l)},e.onclose=l=>{var d;(d=n.onClose)==null||d.call(n,l.code,Pe(l.reason))},e.onmessage=l=>{var p,h,_,f;const{data:d}=l;d instanceof ArrayBuffer||d instanceof Uint8Array?(p=n.onMessage)==null||p.call(n,d):typeof d=="string"?(h=n.onMessage)==null||h.call(n,d):typeof Blob<"u"&&d instanceof Blob?(_=n.onMessage)==null||_.call(n,d):Buffer.isBuffer(d)&&((f=n.onMessage)==null||f.call(n,d.buffer.slice(d.byteOffset,d.byteOffset+d.byteLength)))}})},sendText(s){e==null||e.send(s)},sendBinary(s){e==null||e.send(s)},close(s=1e3,o=""){e==null||e.close(s,o),e=null}};return n}const me="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function Pt(t){let e="";for(let n=0;n<t.length;n+=3){const s=t[n],o=n+1<t.length,r=n+2<t.length,a=o?t[n+1]:0,l=r?t[n+2]:0;e+=me[s>>2],e+=me[(s&3)<<4|a>>4],e+=o?me[(a&15)<<2|l>>6]:"=",e+=r?me[l&63]:"="}return e}function Ht(t){const e=t.replace(/=+$/,""),n=[];let s=0,o=0;for(const r of e){const a=me.indexOf(r);if(a===-1)throw new Error(`invalid base64 character: ${JSON.stringify(r)}`);s=s<<6|a,o+=6,o>=8&&(o-=8,n.push(s>>o&255))}return new Uint8Array(n)}function dr(t){try{const e=JSON.parse(t);return!e||typeof e.type!="string"?null:e}catch{return null}}const Ce=24;function zt(t,e){const n=ie.randomBytes(Ce),s=ie.box.after(t,n,e),o=new Uint8Array(n.length+s.length);return o.set(n,0),o.set(s,n.length),Pt(o)}function Wt(t,e){let n;try{n=Ht(t)}catch{return null}if(n.length<Ce)return null;const s=n.slice(0,Ce),o=n.slice(Ce);return ie.box.open.after(o,s,e)}function ur(t,e){return zt(new TextEncoder().encode(t),e)}function pr(t,e){const n=Wt(t,e);return n?new TextDecoder().decode(n):null}function fr(t,e,n,s,o,r){let a=!1;return n.onClose(l=>{var d;a=!0,(d=s.onClose)==null||d.call(s,l)}),{handleAppFrame(l){var h,_;if(a)return;const d=o();if(!r()||!d)return;const p=pr(l.frame,d);if(p===null){(h=s.onAuthError)==null||h.call(s,new Error(`relay ${t} channel: message failed authentication`));return}(_=s.onMessage)==null||_.call(s,p)},handleBinaryFrame(l){var h,_;if(a)return;const d=o();if(!r()||!d)return;const p=Wt(l.frame,d);if(p===null){(h=s.onAuthError)==null||h.call(s,new Error(`relay ${t} channel: binary message failed authentication`));return}(_=s.onBinaryMessage)==null||_.call(s,p)},send(l){if(a)throw new Error(`relay ${t} channel: cannot send after close()`);const d=o();if(!r()||!d)throw new Error(`relay ${t} channel: cannot send before the E2EE handshake completes`);n.send(JSON.stringify({type:"e2ee_app",frame:ur(l,d)}))},sendBinary(l){if(a)throw new Error(`relay ${t} channel: cannot send after close()`);const d=o();if(!r()||!d)throw new Error(`relay ${t} channel: cannot send before the E2EE handshake completes`);n.send(JSON.stringify({type:"e2ee_bin",frame:zt(l,d)}))},close(){a||(a=!0,n.close())}}}function hr(t){const{transport:e,attachment:n,daemonPublicKey:s}=t,o=t.events??{},r=ie.box.keyPair(),a=ie.box.before(s,r.secretKey);let l=!1;const d=fr("client",n,e,o,()=>a,()=>l);return e.onMessage(p=>{var _;const h=dr(p);if(h){if(h.type==="e2ee_ready"){if(l)return;l=!0,(_=o.onReady)==null||_.call(o);return}if(h.type==="e2ee_app"){d.handleAppFrame(h);return}h.type==="e2ee_bin"&&d.handleBinaryFrame(h)}}),e.send(JSON.stringify({type:"e2ee_hello",ephemeralPublicKey:Pt(r.publicKey)})),{role:"client",attachment:n,get ready(){return l},send:d.send,sendBinary:d.sendBinary,close:d.close}}const gr=16;function mr(t){const e=ie.hash(t);let n="";for(let s=0;s<gr;s++)n+=e[s].toString(16).padStart(2,"0");return n}function _r(t){const e=t.useTls?"wss":"ws",n=t.endpoint.replace(/^(?:https?|wss?):\/\//,"").replace(/\/+$/,"");return`${e}://${n}`}function yr(t){let e=null,n=null;const s=t.sessionId??mr(t.daemonPublicKey),o={onMessage:null,onClose:null,onError:null,get isOpen(){return e!==null&&e.readyState===1&&n!==null&&n.ready},connect(r){return new Promise((a,l)=>{const d=t.factory??(()=>new WebSocket(r));try{e=t.factory?d(r):new WebSocket(r)}catch(f){l(f);return}const p=e,h=[],_=[];p.onopen=()=>{p.send(JSON.stringify({type:"relay_register",sessionId:s})),n=hr({transport:{send:f=>p.send(f),onMessage:f=>h.push(f),onClose:f=>_.push(f),close:()=>p.close()},attachment:{sessionId:s},daemonPublicKey:t.daemonPublicKey,events:{onReady:()=>a(),onMessage:f=>{var x;return(x=o.onMessage)==null?void 0:x.call(o,f)},onBinaryMessage:f=>{var x;return(x=o.onMessage)==null?void 0:x.call(o,f.slice().buffer)},onAuthError:f=>{var x;return(x=o.onError)==null?void 0:x.call(o,f)}}})},p.onerror=f=>{var x;p.readyState!==1&&l(f),(x=o.onError)==null||x.call(o,f)},p.onclose=f=>{var x;for(const S of _)S(Pe(f.reason));(x=o.onClose)==null||x.call(o,f.code,Pe(f.reason))},p.onmessage=f=>{const{data:x}=f;if(typeof x=="string")for(const S of h)S(x)}})},sendText(r){if(!n||!n.ready)throw new Error("relay transport: cannot send before the E2EE handshake completes");n.send(r)},sendBinary(r){if(!n||!n.ready)throw new Error("relay transport: cannot send before the E2EE handshake completes");n.sendBinary(r)},close(r=1e3,a=""){n==null||n.close(),n=null,e==null||e.close(r,a),e=null}};return o}function br(t){const e=t.indexOf("#"),n=e===-1?t:t.slice(e+1),s=new URLSearchParams(n),o=s.get("offer");if(!o)return null;let r;try{r=Ht(o)}catch{return null}const a=s.get("relay");if(a){const d={endpoint:a,useTls:s.get("relayTls")==="1"};return{publicKeyB64:o,publicKey:r,relay:d}}const l=s.get("host")??void 0;return{publicKeyB64:o,publicKey:r,...l?{host:l}:{}}}const wr=1;function He(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`id-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}class Sr extends Error{constructor(e,n,s){super(e),this.requestId=n,this.code=s,this.name="RpcError"}}class it extends Error{constructor(e){super(`RPC ${e} timed out`),this.requestId=e,this.name="RpcTimeoutError"}}class xr{constructor(e){I(this,"transport");I(this,"rpcTimeoutMs");I(this,"now");I(this,"_state","idle");I(this,"_serverId",null);I(this,"_features",{});I(this,"_serverCapabilities",{});I(this,"pending",new Map);I(this,"sessionHandlers",new Set);I(this,"terminalHandlers",new Set);I(this,"fileTransferHandlers",new Set);I(this,"stateHandlers",new Set);I(this,"helloResolve",null);I(this,"helloReject",null);this.options=e,this.transport=e.transport??Ft(),this.rpcTimeoutMs=e.rpcTimeoutMs??3e4,this.now=e.now??(()=>Date.now()),this.transport.onMessage=n=>this.handleIncoming(n),this.transport.onClose=(n,s)=>this.handleClose(n,s),this.transport.onError=()=>{}}get state(){return this._state}get serverId(){return this._serverId}get features(){return this._features}get serverCapabilities(){return this._serverCapabilities}hasFeature(e){return!!this._features[e]}async connect(){this.setState("connecting"),await this.transport.connect(this.options.url);const e=new Promise((s,o)=>{this.helloResolve=s,this.helloReject=o});this.transport.sendText(JSON.stringify({type:"hello",clientId:this.options.clientId,clientType:this.options.clientType,protocolVersion:this.options.protocolVersion??wr,appVersion:this.options.appVersion,capabilities:this.options.capabilities}));const n=await e;return this._serverId=n.serverId,this._features=n.features,this._serverCapabilities=n.capabilities,this.setState("open"),n}close(e=1e3,n=""){this.setState("closing"),this.transport.close(e,n)}request(e,n={},s){const o=n.requestId??He();return new Promise((r,a)=>{const l=s??this.rpcTimeoutMs,d=l>0?setTimeout(()=>{this.pending.delete(o),a(new it(o))},l):null;this.pending.set(o,{resolve:p=>r(p),reject:a,timer:d}),this.sendSession({type:e,...n,requestId:o})})}sendSession(e){this.transport.sendText(JSON.stringify({type:"session",message:e}))}sendBinary(e){this.transport.sendBinary(e)}ping(e=1e4){const n=He();return new Promise((s,o)=>{const r=e>0?setTimeout(()=>{this.pending.delete(n),o(new it(n))},e):null;this.pending.set(n,{resolve:()=>s(),reject:o,timer:r}),this.transport.sendText(JSON.stringify({type:"ping",requestId:n,clientSentAt:this.now()}))})}onSessionMessage(e){return this.sessionHandlers.add(e),()=>this.sessionHandlers.delete(e)}onTerminalFrame(e){return this.terminalHandlers.add(e),()=>this.terminalHandlers.delete(e)}onFileTransferFrame(e){return this.fileTransferHandlers.add(e),()=>this.fileTransferHandlers.delete(e)}onStateChange(e){return this.stateHandlers.add(e),()=>this.stateHandlers.delete(e)}setState(e){if(this._state!==e){this._state=e;for(const n of this.stateHandlers)n(e)}}handleClose(e,n){this.helloReject&&(this.helloReject(new Error(`socket closed during handshake: ${n}`)),this.helloResolve=null,this.helloReject=null);for(const[,s]of this.pending)s.timer&&clearTimeout(s.timer),s.reject(new Error(`socket closed: ${n}`));this.pending.clear(),this.setState("closed")}handleIncoming(e){if(typeof e=="string"){this.handleTextFrame(e);return}if(e instanceof ArrayBuffer){this.handleBinaryFrame(new Uint8Array(e));return}typeof e.arrayBuffer=="function"&&e.arrayBuffer().then(n=>this.handleBinaryFrame(new Uint8Array(n)))}handleBinaryFrame(e){const n=e[0];if(n!==void 0&&Object.values(ae).includes(n)){const r=rr(e);if(!r)return;for(const a of this.fileTransferHandlers)a(r);return}const o=tr(e);for(const r of this.terminalHandlers)r(o)}handleTextFrame(e){let n;try{n=JSON.parse(e)}catch{return}const s=n;switch(s.type){case"status":this.handleStatus(s);return;case"pong":this.resolvePending(s.requestId,void 0);return;case"ping":this.transport.sendText(JSON.stringify({type:"pong",requestId:s.requestId,serverReceivedAt:this.now(),serverSentAt:this.now()}));return;case"session":this.handleSession(s.message);return;default:return}}handleStatus(e){const n=e.payload;(n==null?void 0:n.status)==="server_info"&&this.helloResolve&&(this.helloResolve(n),this.helloResolve=null,this.helloReject=null)}handleSession(e){if(!e||typeof e!="object")return;const n=e;if(n.type==="rpc_error"&&typeof n.requestId=="string"){const s=this.pending.get(n.requestId);s&&(s.timer&&clearTimeout(s.timer),this.pending.delete(n.requestId),s.reject(new Sr(n.message??n.error??"RPC failed",n.requestId,n.code)));return}if(typeof n.requestId=="string"&&this.pending.has(n.requestId)){const s="payload"in n?n.payload:n;this.resolvePending(n.requestId,s)}for(const s of this.sessionHandlers)s(e)}resolvePending(e,n){const s=this.pending.get(e);s&&(s.timer&&clearTimeout(s.timer),this.pending.delete(e),s.resolve(n))}}class vr{constructor(e){this.daemon=e}get connection(){return this.daemon}async createAgent(e){return await this.daemon.request("create_agent_request",{...e})}agent(e){return new Ir(this.daemon,e)}workspace(e){return new Cr(this.daemon,e)}get providers(){return new Tr(this.daemon)}onAgentUpdate(e){return this.daemon.onSessionMessage(n=>{n.type==="agent_update"&&e(n)})}onWorkspaceUpdate(e){return this.daemon.onSessionMessage(n=>{n.type==="workspace_update"&&e(n)})}}class kr{constructor(e,n){this.daemon=e,this.agentId=n}fetch(e={}){return this.daemon.request("fetch_agent_timeline_request",{agentId:this.agentId,cursor:e.cursor,direction:e.direction,limit:e.limit})}subscribe(e){return this.daemon.onSessionMessage(n=>{const s=n;s.type==="agent_stream"&&s.agentId===this.agentId&&s.event&&e(s.event)})}}class Ir{constructor(e,n){I(this,"timeline");this.daemon=e,this.agentId=n,this.timeline=new kr(e,n)}send(e,n={}){return this.daemon.request("send_agent_prompt",{agentId:this.agentId,prompt:e,clientMessageId:n.clientMessageId,images:n.images})}run(e,n){return this.send(e,n)}interrupt(){return this.daemon.request("interrupt_agent",{agentId:this.agentId})}steer(e,n={}){return this.daemon.request("steer_agent_request",{agentId:this.agentId,message:e,clientMessageId:n.clientMessageId,images:n.images})}followUp(e,n={}){return this.daemon.request("follow_up_agent_request",{agentId:this.agentId,message:e,clientMessageId:n.clientMessageId,images:n.images})}update(e){return this.daemon.request("update_agent",{agentId:this.agentId,...e})}resume(){return this.daemon.request("resume_agent",{agentId:this.agentId})}archive(){return this.daemon.request("archive_agent",{agentId:this.agentId})}delete(){return this.daemon.request("delete_agent",{agentId:this.agentId})}onUpdate(e){return this.daemon.onSessionMessage(n=>{const s=n;s.type==="agent_update"&&s.agentId===this.agentId&&e(s)})}sessionStats(){return this.daemon.request("agent_session_stats_request",{agentId:this.agentId})}compact(e){return this.daemon.request("agent_compact_request",{agentId:this.agentId,customInstructions:e})}newSession(){return this.daemon.request("agent_new_session_request",{agentId:this.agentId})}switchSession(e){return this.daemon.request("agent_switch_session_request",{agentId:this.agentId,sessionPath:e})}fork(e){return this.daemon.request("agent_fork_request",{agentId:this.agentId,entryId:e})}forkMessages(){return this.daemon.request("agent_fork_messages_request",{agentId:this.agentId})}clone(){return this.daemon.request("agent_clone_request",{agentId:this.agentId})}setSessionName(e){return this.daemon.request("agent_set_session_name_request",{agentId:this.agentId,name:e})}exportHtml(e){return this.daemon.request("agent_export_html_request",{agentId:this.agentId,outputPath:e})}setModel(e,n){return this.daemon.request("agent_set_model_request",{agentId:this.agentId,provider:e,modelId:n})}cycleModel(){return this.daemon.request("agent_cycle_model_request",{agentId:this.agentId})}lastAssistantText(){return this.daemon.request("agent_last_assistant_text_request",{agentId:this.agentId})}}class Cr{constructor(e,n){this.daemon=e,this.workspaceId=n}onUpdate(e){return this.daemon.onSessionMessage(n=>{const s=n;s.type==="workspace_update"&&s.workspaceId===this.workspaceId&&e(s)})}}class Tr{constructor(e){this.daemon=e}listProviders(){return this.daemon.request("list_providers",{})}listModels(e){return this.daemon.request("list_provider_models",{provider:e})}listModes(e){return this.daemon.request("list_provider_modes",{provider:e})}refreshSnapshot(){return this.daemon.request("providers.snapshot.refresh.request",{})}}const ct=32*1024;function jr(t){const e=t.reduce((o,r)=>o+r.length,0),n=new Uint8Array(e);let s=0;for(const o of t)n.set(o,s),s+=o.length;return n}class Er{constructor(e){I(this,"pending",new Map);I(this,"nextStream",1);I(this,"detach",null);this.daemon=e}start(){this.detach||(this.detach=this.daemon.onFileTransferFrame(e=>this.dispatch(e)))}stop(){var e;(e=this.detach)==null||e.call(this),this.detach=null;for(const[n,s]of this.pending)s.reject(new Error("file transfer router stopped")),this.pending.delete(n)}async download(e){const n=await this.daemon.request("file_download_token_request",{path:e});if(!n.ok||!n.token)throw new Error(n.error??"failed to issue download token");const s=this.nextStream++,o=new Promise((a,l)=>{this.pending.set(s,{chunks:[],meta:{},resolve:a,reject:l})}),r=await this.daemon.request("file_download_request",{token:n.token,stream:s});if(!r.ok)throw this.pending.delete(s),new Error(r.error??"download request failed");return o}async upload(e,n){const s=He(),o=await this.daemon.request("file_upload_request",{path:e,transferId:s});if(!o.ok||o.stream===void 0)throw new Error(o.error??"upload request failed");const r=o.stream;this.daemon.sendBinary(qe({opcode:"Begin",stream:r,meta:{transferId:s}}));for(let a=0;a<n.length;a+=ct){const l=n.subarray(a,a+ct);this.daemon.sendBinary(qe({opcode:"Chunk",stream:r,data:l}))}this.daemon.sendBinary(qe({opcode:"End",stream:r,ok:!0}))}dispatch(e){const n=this.pending.get(e.stream);if(n)switch(e.opcode){case"Begin":n.meta.fileName=e.meta.fileName,n.meta.mimeType=e.meta.mimeType;return;case"Chunk":n.chunks.push(e.data);return;case"End":this.pending.delete(e.stream),e.ok?n.resolve({bytes:jr(n.chunks),...n.meta}):n.reject(new Error("download failed"));return;case"Error":this.pending.delete(e.stream),n.reject(new Error(e.message));return}}}class Nr{constructor(e,n={}){I(this,"initialDelayMs");I(this,"maxDelayMs");I(this,"factor");I(this,"jitter");I(this,"maxAttempts");I(this,"setTimer");I(this,"clearTimer");I(this,"random");I(this,"attempt",0);I(this,"timer",null);I(this,"active",!1);I(this,"detachState",null);I(this,"reconnectedHandlers",new Set);I(this,"failedHandlers",new Set);this.daemon=e,this.initialDelayMs=n.initialDelayMs??500,this.maxDelayMs=n.maxDelayMs??3e4,this.factor=n.factor??2,this.jitter=n.jitter??.2,this.maxAttempts=n.maxAttempts??Number.POSITIVE_INFINITY,this.setTimer=n.setTimer??((s,o)=>setTimeout(s,o)),this.clearTimer=n.clearTimer??(s=>clearTimeout(s)),this.random=n.random??Math.random}delayForAttempt(e){const n=Math.min(this.maxDelayMs,this.initialDelayMs*this.factor**(e-1)),s=n*this.jitter*(this.random()*2-1);return Math.max(0,Math.round(n+s))}onReconnected(e){return this.reconnectedHandlers.add(e),()=>this.reconnectedHandlers.delete(e)}onReconnectFailed(e){return this.failedHandlers.add(e),()=>this.failedHandlers.delete(e)}start(){this.active||(this.active=!0,this.detachState=this.daemon.onStateChange(e=>{e==="closed"&&this.active&&this.scheduleReconnect(),e==="open"&&(this.attempt=0)}))}stop(){var e;this.active=!1,this.timer&&this.clearTimer(this.timer),this.timer=null,(e=this.detachState)==null||e.call(this),this.detachState=null}get attemptCount(){return this.attempt}scheduleReconnect(){if(!this.active||this.attempt>=this.maxAttempts)return;this.attempt+=1;const e=this.delayForAttempt(this.attempt);this.timer=this.setTimer(()=>{this.timer=null,this.tryReconnect()},e)}async tryReconnect(){if(!this.active)return;const e=this.attempt;try{await this.daemon.connect();for(const n of this.reconnectedHandlers)n({attempt:e,serverId:this.daemon.serverId})}catch(n){for(const s of this.failedHandlers)s(n,e);this.scheduleReconnect()}}}function lt(t){const e=t.trim();if(e==="")return e;const n=e.match(/^([a-z][a-z0-9+.-]*):\/\//i);if(!n)return`ws://${e.replace(/\/+$/,"")}`;const s=n[1].toLowerCase(),o=e.slice(n[0].length).replace(/\/+$/,"");switch(s){case"http":return`ws://${o}`;case"https":return`wss://${o}`;case"ws":case"wss":return`${s}://${o}`;default:return e}}function Rr(t){const e=br(t);return e!=null&&e.relay?{mode:"relay",url:_r(e.relay),daemonPublicKey:e.publicKey}:e!=null&&e.host?{mode:"direct",url:lt(e.host)}:{mode:"direct",url:lt(t)}}function qr(){return"web-"+Math.random().toString(36).slice(2,10)}const E=ce()((t,e)=>({status:"idle",serverInfo:null,error:null,daemon:null,client:null,reconnection:null,async connect(n){e().disconnect();const s=Rr(n.url);let o;s.mode==="relay"?o=yr({daemonPublicKey:s.daemonPublicKey}):n.password&&(o=Ft(d=>new WebSocket(d,[`pi-studio.bearer.${n.password}`])));const r=new xr({url:s.url,clientId:n.clientId??qr(),clientType:"browser",capabilities:{},transport:o,rpcTimeoutMs:1800*1e3}),a=new vr(r),l=new Nr(r);r.onStateChange(d=>t({status:d})),l.onReconnected(()=>t({error:null})),l.onReconnectFailed(d=>{t({error:d instanceof Error?d.message:String(d)})}),t({daemon:r,client:a,reconnection:l,error:null,status:"connecting"});try{const d=await r.connect();t({serverInfo:d}),l.start()}catch(d){throw t({error:d instanceof Error?d.message:String(d)}),d}},disconnect(){const{daemon:n,reconnection:s}=e();s==null||s.stop(),n==null||n.close(),t({status:"idle",serverInfo:null,daemon:null,client:null,reconnection:null})}})),Br=100,Mr=480,Ar=220,$r=280;function ve(t){return Math.min(Mr,Math.max(Br,t))}const v=ce()(t=>({host:"ws://127.0.0.1:6767",password:"",cwd:"~",cwdPickerOpen:!1,sessionMenu:null,fileMenu:null,rightSidebarTab:"files",collapsedWorkspaces:new Set,leftSidebarCollapsed:!1,rightSidebarCollapsed:!1,leftSidebarWidth:Ar,rightSidebarWidth:$r,setHost:e=>t({host:e}),setPassword:e=>t({password:e}),setCwd:e=>t({cwd:e}),openCwdPicker:()=>t({cwdPickerOpen:!0}),closeCwdPicker:()=>t({cwdPickerOpen:!1}),openSessionMenu:(e,n,s)=>t({sessionMenu:{sessionId:e,x:n,y:s}}),closeSessionMenu:()=>t({sessionMenu:null}),openFileMenu:(e,n,s,o)=>t({fileMenu:{path:e,isDirectory:n,x:s,y:o}}),closeFileMenu:()=>t({fileMenu:null}),setRightSidebarTab:e=>t({rightSidebarTab:e}),toggleWorkspaceCollapsed:e=>t(n=>{const s=new Set(n.collapsedWorkspaces);return s.has(e)?s.delete(e):s.add(e),{collapsedWorkspaces:s}}),toggleLeftSidebar:()=>t(e=>({leftSidebarCollapsed:!e.leftSidebarCollapsed})),toggleRightSidebar:()=>t(e=>({rightSidebarCollapsed:!e.rightSidebarCollapsed})),setLeftSidebarWidth:e=>t({leftSidebarWidth:ve(e)}),setRightSidebarWidth:e=>t({rightSidebarWidth:ve(e)}),resizeLeftSidebar:e=>t(n=>({leftSidebarWidth:ve(n.leftSidebarWidth+e)})),resizeRightSidebar:e=>t(n=>({rightSidebarWidth:ve(n.rightSidebarWidth+e)}))})),Dr="_wrap_emmus_1",Or="_dot_emmus_8",Fr="_open_emmus_15",Pr="_connecting_emmus_18",Hr="_closed_emmus_21",zr="_idle_emmus_22",Wr="_closing_emmus_23",Be={wrap:Dr,dot:Or,open:Fr,connecting:Pr,closed:Hr,idle:zr,closing:Wr},Lr={idle:"disconnected",connecting:"connecting…",open:"connected",closing:"disconnecting…",closed:"disconnected"};function Ur(){const t=E(n=>n.status),e=E(n=>n.error);return i.jsxs("span",{className:Be.wrap,title:e??void 0,children:[i.jsx("span",{className:B(Be.dot,Be[t])}),Lr[t]??t]})}const Kr="_toolbar_i9hmh_1",Vr="_brand_i9hmh_10",Gr="_version_i9hmh_16",Jr="_sep_i9hmh_22",Xr="_host_i9hmh_28",Yr="_password_i9hmh_31",Qr="_sidebarToggles_i9hmh_34",Q={toolbar:Kr,brand:Vr,version:Gr,sep:Jr,host:Xr,password:Yr,sidebarToggles:Qr};function Zr(){const t=E(f=>f.status),e=E(f=>f.connect),n=E(f=>f.disconnect),s=v(f=>f.host),o=v(f=>f.setHost),r=v(f=>f.password),a=v(f=>f.setPassword),l=v(f=>f.leftSidebarCollapsed),d=v(f=>f.toggleLeftSidebar),p=v(f=>f.rightSidebarCollapsed),h=v(f=>f.toggleRightSidebar),_=t==="open"||t==="connecting";return i.jsxs("div",{className:Q.toolbar,children:[i.jsx("span",{className:Q.brand,children:"Pi-Studio"}),i.jsxs("span",{className:Q.version,children:["v","0.0.33"]}),i.jsx(Ur,{}),i.jsx("div",{className:Q.sep}),i.jsx(Fe,{className:Q.host,value:s,onChange:f=>o(f.target.value),placeholder:"host:port, ws://…/http://…, or a pasted pairing link",disabled:_}),i.jsx(Fe,{className:Q.password,type:"password",value:r,onChange:f=>a(f.target.value),placeholder:"password",disabled:_}),t==="open"||t==="connecting"||t==="closing"?i.jsx(z,{size:"sm",onClick:()=>n(),children:"Disconnect"}):i.jsx(z,{size:"sm",variant:"default",onClick:()=>void e({url:s,password:r||void 0}),children:"Connect"}),i.jsxs("div",{className:Q.sidebarToggles,children:[i.jsx(z,{size:"sm",variant:"ghost",iconOnly:!0,title:l?"Show sessions sidebar":"Hide sessions sidebar",onClick:()=>d(),children:l?i.jsx(fn,{size:16}):i.jsx(hn,{size:16})}),i.jsx(z,{size:"sm",variant:"ghost",iconOnly:!0,title:p?"Show files/changes sidebar":"Hide files/changes sidebar",onClick:()=>h(),children:p?i.jsx(gn,{size:16}):i.jsx(mn,{size:16})})]})]})}const ze={rows:[],streamingAssistantIndex:null,streamingReasoningIndex:null,toolIndexByCallId:{}};let dt=0;function X(){return dt+=1,`row-${dt}`}function ea(t){switch(t.kind){case"shell":return t.command??"";case"read":case"write":return t.path??"";case"edit":return t.path??"";case"search":return t.query??"";case"fetch":return t.url??"";case"task":return t.description??"";default:return""}}function ta(t,e){return t??`${e.kind}:${ea(e)}`}function na(t){return{...t,streamingAssistantIndex:null,streamingReasoningIndex:null}}function sa(t,e){var r;const n=t.rows.slice();let s=t.streamingAssistantIndex;if(s===null||((r=n[s])==null?void 0:r.kind)!=="assistant"){const a={kind:"assistant",id:X(),text:"",streaming:!0};n.push(a),s=n.length-1}const o=n[s];return!o||o.kind!=="assistant"?t:(n[s]={...o,text:o.text+e},{...t,rows:n,streamingAssistantIndex:s,streamingReasoningIndex:null})}function oa(t,e){var r;const n=t.rows.slice();let s=t.streamingReasoningIndex;if(s===null||((r=n[s])==null?void 0:r.kind)!=="reasoning"){const a={kind:"reasoning",id:X(),text:"",streaming:!0};n.push(a),s=n.length-1}const o=n[s];return!o||o.kind!=="reasoning"?t:(n[s]={...o,text:o.text+e},{...t,rows:n,streamingReasoningIndex:s,streamingAssistantIndex:null})}function ra(t,e){if(t.kind!==e.kind)return e;const n={...t};for(const[s,o]of Object.entries(e))o!==void 0&&o!==""&&(n[s]=o);return n}function aa(t,e){var l;const n=ta(e.callId,e.tool),s=e.status==="completed"||e.status==="error"?e.status:"running",o=t.toolIndexByCallId[n],r=t.rows.slice();if(o!==void 0&&((l=r[o])==null?void 0:l.kind)==="tool"){const d=r[o];return d.kind!=="tool"?t:(r[o]={...d,tool:ra(d.tool,e.tool),status:s},{...t,rows:r,streamingAssistantIndex:null,streamingReasoningIndex:null})}const a={kind:"tool",id:X(),callId:n,tool:e.tool,status:s};return r.push(a),{...t,rows:r,toolIndexByCallId:{...t.toolIndexByCallId,[n]:r.length-1},streamingAssistantIndex:null,streamingReasoningIndex:null}}function Qe(t){const e=t.rows.slice();if(t.streamingAssistantIndex!==null){const n=e[t.streamingAssistantIndex];(n==null?void 0:n.kind)==="assistant"&&(e[t.streamingAssistantIndex]={...n,streaming:!1})}if(t.streamingReasoningIndex!==null){const n=e[t.streamingReasoningIndex];(n==null?void 0:n.kind)==="reasoning"&&(e[t.streamingReasoningIndex]={...n,streaming:!1})}return{...t,rows:e,streamingAssistantIndex:null,streamingReasoningIndex:null}}function ia(t,e){const n=Qe(t),s={kind:"error",id:X(),text:e||"turn failed"};return{...n,rows:[...n.rows,s]}}function ca(t){const e=Qe(t),n={kind:"system",id:X(),text:"(canceled)"};return{...e,rows:[...e.rows,n]}}function la(t,e){const n={kind:"error",id:X(),text:e||"error"};return{...t,rows:[...t.rows,n]}}function da(t,e,n,s){if(s!==void 0){const r=t.rows.findIndex(a=>a.kind==="user"&&a.pending&&a.clientMessageId===s);if(r!==-1){const a=t.rows.slice(),l=a[r];if((l==null?void 0:l.kind)==="user")return a[r]={...l,text:e,images:n,pending:!1},{...t,rows:a}}}const o={kind:"user",id:X(),text:e,images:n,clientMessageId:s};return{...t,rows:[...t.rows,o]}}function ua(t,e){let n=!1;const s=t.rows.map(o=>o.kind!=="user"||!o.queued||e.includes(o.text)?o:(n=!0,{...o,queued:!1}));return n?{...t,rows:s}:t}function Lt(t,e){switch(e.kind){case"turn_started":return na(t);case"user_message":return da(t,e.text??"",e.images,e.messageId);case"assistant_message":return sa(t,e.text??"");case"reasoning":return oa(t,e.text??"");case"tool_call":return aa(t,e);case"turn_completed":return Qe(t);case"turn_failed":return ia(t,e.error);case"turn_canceled":return ca(t);case"error":return la(t,e.message);case"queue_update":return ua(t,e.steering??[]);default:return t}}function pa(t,e,n,s,o){const r={kind:"user",id:X(),text:n,images:s,clientMessageId:e,pending:!0,queued:o};return{...t,rows:[...t.rows,r]}}function fa(t,e){const n=t.rows.findIndex(r=>r.kind==="user"&&r.pending&&r.clientMessageId===e);if(n===-1)return t;const s=t.rows.slice(),o=s[n];return(o==null?void 0:o.kind)!=="user"?t:(s[n]={...o,pending:!1,failed:!0},{...t,rows:s})}let ut=0;function ha(){return ut+=1,`s-${Date.now().toString(36)}-${ut}`}const $=ce()((t,e)=>({sessions:{},order:[],activeSessionId:null,createSession(n){const s=ha(),o={id:s,agentId:null,title:"New chat",status:"idle",cwd:n,timeline:ze,userMessageCount:0};return t(r=>({sessions:{...r.sessions,[s]:o},order:[s,...r.order],activeSessionId:s})),s},hydrate(n){t(s=>s.sessions[n.id]?s:{sessions:{...s.sessions,[n.id]:n},order:[...s.order,n.id]})},bindAgent(n,s){t(o=>{const r=o.sessions[n];return r?{sessions:{...o.sessions,[n]:{...r,agentId:s}}}:o})},setStatus(n,s){t(o=>{const r=o.sessions[n];return r?{sessions:{...o.sessions,[n]:{...r,status:s}}}:o})},setStatusByAgentId(n,s){const o=e().findByAgentId(n);o&&e().setStatus(o.id,s)},setTitle(n,s){t(o=>{const r=o.sessions[n];return r?{sessions:{...o.sessions,[n]:{...r,title:s}}}:o})},setCwd(n,s){t(o=>{const r=o.sessions[n];return r?{sessions:{...o.sessions,[n]:{...r,cwd:s}}}:o})},applyStreamEvent(n,s){t(o=>{const r=o.sessions[n];if(!r)return o;const a=Lt(r.timeline,s);let l=r.title;if(s.kind==="turn_completed"&&l==="New chat"){const d=a.rows.slice().reverse().find(p=>p.kind==="assistant");d&&d.kind==="assistant"&&d.text&&(l=d.text.slice(0,40)+(d.text.length>40?"…":""))}return{sessions:{...o.sessions,[n]:{...r,timeline:a,title:l}}}})},addOptimisticUserMessage(n,s,o,r,a){t(l=>{const d=l.sessions[n];if(!d)return l;const p=pa(d.timeline,s,o,r,a);return{sessions:{...l.sessions,[n]:{...d,timeline:p,userMessageCount:d.userMessageCount+1}}}})},markUserMessageFailed(n,s){t(o=>{const r=o.sessions[n];if(!r)return o;const a=fa(r.timeline,s);return{sessions:{...o.sessions,[n]:{...r,timeline:a}}}})},activate(n){t({activeSessionId:n})},remove(n){t(s=>{const{[n]:o,...r}=s.sessions,a=s.order.filter(d=>d!==n),l=s.activeSessionId===n?a[0]??null:s.activeSessionId;return{sessions:r,order:a,activeSessionId:l}})},findByAgentId(n){return Object.values(e().sessions).find(s=>s.agentId===n)}}));function Me(t,e){return t.filter(n=>n.workspaceCwd===e)}const T=ce()((t,e)=>({tabs:[],activeTabId:null,activeWorkspaceCwd:null,lastActiveTabByWorkspace:{},open(n){const s=e().tabs.find(o=>o.id===n.id);if(s){e().activate(s.id);return}t(o=>({tabs:[...o.tabs,n],activeTabId:n.id,activeWorkspaceCwd:n.workspaceCwd,lastActiveTabByWorkspace:{...o.lastActiveTabByWorkspace,[n.workspaceCwd]:n.id}}))},close(n){t(s=>{const o=s.tabs.find(p=>p.id===n);if(!o)return s;const r=s.tabs.findIndex(p=>p.id===n),a=s.tabs.filter(p=>p.id!==n);let l=s.activeTabId;const d={...s.lastActiveTabByWorkspace};if(l===n){const p=Me(a,o.workspaceCwd),h=Math.min(r,p.length-1),_=p[h];l=(_==null?void 0:_.id)??null}if(d[o.workspaceCwd]===n){const p=Me(a,o.workspaceCwd)[0];p?d[o.workspaceCwd]=p.id:delete d[o.workspaceCwd]}return{tabs:a,activeTabId:l,lastActiveTabByWorkspace:d}})},activate(n){t(s=>{const o=s.tabs.find(r=>r.id===n);return o?{activeTabId:n,activeWorkspaceCwd:o.workspaceCwd,lastActiveTabByWorkspace:{...s.lastActiveTabByWorkspace,[o.workspaceCwd]:n}}:s})},switchWorkspace(n){t(s=>{var d;const o=Me(s.tabs,n),r=s.lastActiveTabByWorkspace[n],l=r&&o.some(p=>p.id===r)?r:((d=o[0])==null?void 0:d.id)??null;return{activeWorkspaceCwd:n,activeTabId:l,lastActiveTabByWorkspace:l?{...s.lastActiveTabByWorkspace,[n]:l}:s.lastActiveTabByWorkspace}})},reorder(n,s){t(o=>{const r=o.tabs.findIndex(p=>p.id===n),a=o.tabs.findIndex(p=>p.id===s);if(r===-1||a===-1||r===a)return o;const l=o.tabs.slice(),[d]=l.splice(r,1);return d?(l.splice(a,0,d),{tabs:l}):o})},updateLabel(n,s){t(o=>({tabs:o.tabs.map(r=>r.id===n?{...r,label:s}:r)}))},updateData(n,s){t(o=>({tabs:o.tabs.map(r=>r.id===n?{...r,data:{...r.data,...s}}:r)}))}})),L={chat:t=>`chat-${t}`,file:t=>`file-${t}`,diff:(t,e)=>`diff-${t}${e?"-staged":""}`,terminal:t=>`term-${t}`};let Ae=0;function Ut(t){Ae+=1,T.getState().open({id:L.terminal(`new-${Ae}`),kind:"terminal",label:`Terminal ${Ae}`,closable:!0,data:{slot:null,cwd:t},workspaceCwd:t})}function Ee(t){const e=$.getState().createSession(t);T.getState().open({id:L.chat(e),kind:"chat",label:"New chat",closable:!0,data:{sessionId:e},workspaceCwd:t})}const ke=ce()(t=>({rootPath:"",expanded:new Set,expandedByRoot:new Map,setRoot:e=>t(n=>{const s=new Map(n.expandedByRoot);n.rootPath&&s.set(n.rootPath,n.expanded);const o=s.get(e),r=new Set(o);return r.add(e),{rootPath:e,expanded:r,expandedByRoot:s}}),toggle:e=>t(n=>{if(e===n.rootPath)return n;const s=new Set(n.expanded);s.has(e)?s.delete(e):s.add(e);const o=new Map(n.expandedByRoot);return o.set(n.rootPath,s),{expanded:s,expandedByRoot:o}})}));let re=null;const We=new Set;function ga(t){return We.add(t),()=>We.delete(t)}async function Ne(t){var e;if(re)return re;try{const n=await t.connection.request("file_explorer_request",{path:"/home"}),o=(((e=n.result)==null?void 0:e.entries)??n.entries??[]).find(r=>r.kind==="directory"||r.type==="directory");re="/home/"+((o==null?void 0:o.name)||"user")}catch{return"/tmp"}for(const n of We)n(re);return re}function ma(){return re}async function _a(t,e){return e==="~"||e.startsWith("~/")?await Ne(t)+e.slice(1):e}function Kt(){const t=E(o=>o.client),e=E(o=>o.status),[n,s]=w.useState(ma());return w.useEffect(()=>ga(s),[]),w.useEffect(()=>{!t||e!=="open"||n||Ne(t)},[t,e,n]),n}const ya="_dot_202py_3",ba={dot:ya};function wa(t){const{status:e,requiresAttention:n,attentionReason:s,showInactive:o}=t;if(!e)return null;if(n)switch(s){case"permission":return"statusWarning";case"error":return"statusDanger";case"finished":default:return"statusSuccess"}switch(e){case"running":case"queued":return"accent";case"waiting":return"statusWarning";case"finished":return"statusSuccess";case"error":return"statusDanger";case"idle":case"archived":return o?"foregroundMuted":null}}const pt=8,Sa={accent:"var(--pi-color-accent)",statusSuccess:"var(--pi-color-statusSuccess)",statusDanger:"var(--pi-color-statusDanger)",statusWarning:"var(--pi-color-statusWarning)",foregroundMuted:"var(--pi-color-foregroundMuted)"};function xa({className:t,...e}){const n=wa(e);return n?i.jsx("span",{className:`${ba.dot}${t?` ${t}`:""}`,style:{width:pt,height:pt,backgroundColor:Sa[n]??"currentColor"},role:"presentation"}):null}const va={initializing:"queued",idle:"idle",running:"running",error:"error",closed:"finished"};function ka(t){return va[t]??"idle"}const Ia="_wrap_sqws5_1",Ca="_header_sqws5_7",Ta="_list_sqws5_23",ja="_item_sqws5_28",Ea="_active_sqws5_37",Na="_title_sqws5_40",Ra="_meta_sqws5_49",qa="_menuBtn_sqws5_57",Ba="_workspaceGroup_sqws5_75",Ma="_workspaceHeader_sqws5_78",Aa="_workspaceChevron_sqws5_91",$a="_workspaceIcon_sqws5_102",Da="_workspaceLabel_sqws5_106",Oa="_workspaceCount_sqws5_112",Fa="_newSessionBtn_sqws5_117",Pa="_workspaceSessions_sqws5_129",M={wrap:Ia,header:Ca,list:Ta,item:ja,active:Ea,title:Na,meta:Ra,menuBtn:qa,workspaceGroup:Ba,workspaceHeader:Ma,workspaceChevron:Aa,workspaceIcon:$a,workspaceLabel:Da,workspaceCount:Oa,newSessionBtn:Fa,workspaceSessions:Pa};function Ha({session:t,active:e,onSelect:n,onOpenMenu:s}){return i.jsxs("div",{className:B(M.item,e&&M.active),onClick:n,onContextMenu:o=>{o.preventDefault(),s(o.clientX,o.clientY)},children:[i.jsxs("div",{className:M.title,children:[i.jsx(xa,{status:ka(t.status),showInactive:!0}),i.jsx("span",{children:t.title})]}),i.jsxs("div",{className:M.meta,children:[t.cwd||"~"," · ",t.agentId?t.agentId.slice(0,8):"new"," ·"," ",t.userMessageCount," msgs"]}),i.jsx("button",{type:"button",className:M.menuBtn,title:"Actions",onClick:o=>{o.stopPropagation();const r=o.currentTarget.getBoundingClientRect();s(r.left,r.bottom)},children:i.jsx(yt,{size:14})})]})}const za="_trigger_16o4s_1",Wa="_content_16o4s_7",La="_item_16o4s_16",Ua="_danger_16o4s_33",Ka="_sep_16o4s_36",U={trigger:za,content:Wa,item:La,danger:Ua,sep:Ka};function Va(){const t=v(S=>S.sessionMenu),e=v(S=>S.closeSessionMenu),n=E(S=>S.client),s=w.useRef(null),[o,r]=w.useState(!1);w.useEffect(()=>{r(t!==null)},[t]);const a=$(S=>t?S.sessions[t.sessionId]:void 0);if(!t)return null;const l=!!(a!=null&&a.agentId)&&(a==null?void 0:a.status)==="running";function d(S){r(S),S||e()}function p(){if(!a)return;const S=window.prompt("Rename:",a.title);if(S!=null&&S.trim()){const y=S.trim();$.getState().setTitle(a.id,y),T.getState().updateLabel(L.chat(a.id),y),a.agentId&&(n==null||n.agent(a.agentId).update({title:y}).catch(()=>{}))}e()}function h(){a!=null&&a.agentId&&(n==null||n.agent(a.agentId).interrupt().catch(()=>{})),e()}function _(S){$.getState().remove(S),T.getState().close(L.chat(S))}async function f(){if(a){if(!window.confirm("Archive this agent? It can be resumed later."))return e();if(e(),!a.agentId){_(a.id);return}if(!n){window.alert("Not connected — cannot archive remotely.");return}try{await n.agent(a.agentId).archive(),_(a.id)}catch(S){window.alert(`Failed to archive: ${S instanceof Error?S.message:String(S)}`)}}}async function x(){if(a){if(!window.confirm("Permanently delete this agent? This cannot be undone."))return e();if(e(),!a.agentId){_(a.id);return}if(!n){window.alert("Not connected — cannot delete remotely.");return}try{await n.agent(a.agentId).delete(),_(a.id)}catch(S){window.alert(`Failed to delete: ${S instanceof Error?S.message:String(S)}`)}}}return i.jsxs(Ke,{open:o,onOpenChange:d,modal:!1,children:[i.jsx(Ve,{asChild:!0,children:i.jsx("button",{ref:s,type:"button",className:U.trigger,style:{left:t.x,top:t.y},"aria-hidden":!0,tabIndex:-1})}),i.jsx(Ge,{children:i.jsxs(Je,{className:U.content,align:"start",sideOffset:2,children:[i.jsx(J,{className:U.item,onSelect:p,children:"Rename"}),i.jsx(J,{className:U.item,disabled:!l,onSelect:h,children:"Stop agent"}),i.jsx(kt,{className:U.sep}),i.jsx(J,{className:`${U.item} ${U.danger}`,onSelect:f,children:"Archive"}),i.jsx(J,{className:`${U.item} ${U.danger}`,onSelect:x,children:"Delete permanently"})]})})]})}function Ga({label:t,cwd:e,sessionCount:n,collapsed:s,onToggleCollapsed:o,onNewSession:r}){return i.jsxs("div",{className:M.workspaceHeader,onClick:o,title:e,children:[i.jsx("button",{type:"button",className:M.workspaceChevron,"aria-label":s?"Expand workspace":"Collapse workspace",onClick:a=>{a.stopPropagation(),o()},children:s?i.jsx(bt,{size:13}):i.jsx(_n,{size:13})}),i.jsx(yn,{size:13,className:B(M.workspaceIcon)}),i.jsx("span",{className:M.workspaceLabel,children:t}),i.jsx("span",{className:M.workspaceCount,children:n}),i.jsx(z,{size:"xs",variant:"ghost",iconOnly:!0,title:"New conversation",className:M.newSessionBtn,onClick:a=>{a.stopPropagation(),r()},children:i.jsx(wt,{size:13})})]})}function te(t,e){return e&&(t==="~"||t.startsWith("~/"))?e+t.slice(1):t}function Vt(t,e,n){const s=new Map;for(const o of t){const r=e[o];if(!r)continue;const a=te(r.cwd||"~",n),l=s.get(a);l?l.push(r):s.set(a,[r])}return Array.from(s,([o,r])=>({cwd:o,sessions:r}))}function Ja(t){return!t||t==="~"?"~":t.split("/").filter(Boolean).pop()||t}function Xa(){const t=$(y=>y.order),e=$(y=>y.sessions),n=$(y=>y.activeSessionId),s=$(y=>y.activate),o=T(y=>y.open),r=E(y=>y.status),a=v(y=>y.openSessionMenu),l=v(y=>y.setCwd),d=v(y=>y.openCwdPicker),p=v(y=>y.collapsedWorkspaces),h=v(y=>y.toggleWorkspaceCollapsed),_=Kt();function f(y){const N=te(y||"~",_);Ee(N)}function x(y){s(y);const N=e[y],O=te((N==null?void 0:N.cwd)||"~",_);N!=null&&N.cwd&&l(N.cwd),o({id:L.chat(y),kind:"chat",label:(N==null?void 0:N.title)??"Chat",closable:!0,data:{sessionId:y},workspaceCwd:O})}const S=Vt(t,e,_);return i.jsxs("div",{className:M.wrap,children:[i.jsxs("div",{className:M.header,children:[i.jsx("h3",{children:"Workspaces"}),i.jsx(z,{size:"xs",variant:"ghost",iconOnly:!0,title:r!=="open"?"Connect to open a workspace":"Open a workspace folder",disabled:r!=="open",onClick:()=>d(),children:i.jsx(bn,{size:14})})]}),i.jsx("div",{className:M.list,children:S.map(y=>{const N=p.has(y.cwd);return i.jsxs("div",{className:M.workspaceGroup,children:[i.jsx(Ga,{label:Ja(y.cwd),cwd:y.cwd,sessionCount:y.sessions.length,collapsed:N,onToggleCollapsed:()=>h(y.cwd),onNewSession:()=>f(y.cwd)}),!N&&i.jsx("div",{className:M.workspaceSessions,children:y.sessions.map(O=>i.jsx(Ha,{session:O,active:O.id===n,onSelect:()=>x(O.id),onOpenMenu:(k,ne)=>a(O.id,k,ne)},O.id))})]},y.cwd)})}),i.jsx(Va,{})]})}const Ya="_strip_8jveh_1",Qa="_tab_8jveh_10",Za="_active_8jveh_26",ei="_icon_8jveh_30",ti="_label_8jveh_35",ni="_close_8jveh_40",si="_newTab_8jveh_50",oi="_content_8jveh_73",ri="_item_8jveh_82",ai="_itemIcon_8jveh_96",P={strip:Ya,tab:Qa,active:Za,icon:ei,label:ti,close:ni,newTab:si,content:oi,item:ri,itemIcon:ai},ii={chat:xt,file:Sn,diff:wn,terminal:St};function ci({tab:t}){const e=T(_=>_.activeTabId),n=T(_=>_.activate),s=T(_=>_.close),o=ii[t.kind],{attributes:r,listeners:a,setNodeRef:l,transform:d,transition:p,isDragging:h}=On({id:t.id});return i.jsxs("div",{ref:l,className:B(P.tab,t.id===e&&P.active),style:{transform:Fn.Transform.toString(d),transition:p,opacity:h?.5:1},onClick:()=>n(t.id),onAuxClick:_=>{_.button===1&&t.closable&&s(t.id)},title:t.label,...r,...a,children:[i.jsx("span",{className:P.icon,children:i.jsx(o,{size:13})}),i.jsx("span",{className:P.label,children:t.label}),t.closable&&i.jsx("span",{className:P.close,onClick:_=>{_.stopPropagation(),s(t.id)},children:i.jsx($e,{size:12})})]})}function li({workspaceCwd:t}){const e=t??"~";return i.jsxs(Ke,{children:[i.jsx(Ve,{asChild:!0,children:i.jsx("button",{type:"button",className:P.newTab,title:"New tab",disabled:!t,children:i.jsx(wt,{size:14})})}),i.jsx(Ge,{children:i.jsxs(Je,{className:P.content,align:"start",sideOffset:4,children:[i.jsxs(J,{className:P.item,onSelect:()=>Ee(e),children:[i.jsx(xt,{size:13,className:P.itemIcon}),"New chat"]}),i.jsxs(J,{className:P.item,onSelect:()=>Ut(e),children:[i.jsx(St,{size:13,className:P.itemIcon}),"New terminal"]})]})})]})}function di(){const t=T(a=>a.tabs),e=T(a=>a.activeWorkspaceCwd),n=T(a=>a.reorder),s=t.filter(a=>a.workspaceCwd===e),o=Rn(qn(Dn,{activationConstraint:{distance:4}}));function r(a){const{active:l,over:d}=a;!d||l.id===d.id||n(String(l.id),String(d.id))}return i.jsxs("div",{className:P.strip,children:[i.jsx(Bn,{sensors:o,collisionDetection:Mn,onDragEnd:r,children:i.jsx(An,{items:s.map(a=>a.id),strategy:$n,children:s.map(a=>i.jsx(ci,{tab:a},a.id))})}),i.jsx(li,{workspaceCwd:e})]})}const ui="_spinner_1tgzp_3",pi={spinner:ui},fi={xs:12,sm:16,md:20,lg:24},hi={xs:1,sm:2,md:2,lg:3};function gi({size:t="md",color:e="currentColor",className:n,"aria-label":s="Loading"}){const o=typeof t=="number"?t:fi[t],r=typeof t=="number"?2:hi[t];return i.jsx("span",{className:`${pi.spinner}${n?` ${n}`:""}`,role:"status","aria-label":s,style:{width:o,height:o,borderWidth:r,color:e}})}const mi=w.lazy(()=>Xe(()=>import("./ChatPanel-C5cHHrg2.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13])).then(t=>({default:t.ChatPanel}))),ft=w.lazy(()=>Xe(()=>import("./FilePanel-DFrjCgQW.js").then(t=>t.F),__vite__mapDeps([14,1,7,6,5,2,9,10,15])).then(t=>({default:t.FilePanel}))),_i=w.lazy(()=>Xe(()=>import("./TerminalPanel-yVOy1dbu.js"),__vite__mapDeps([16,1,17,18,7,6,5,2,3,11,12,19])).then(t=>({default:t.TerminalPanel}))),yi={chat:mi,file:ft,diff:ft,terminal:_i},bi="_area_1vzxd_1",wi="_panel_1vzxd_7",Si="_active_1vzxd_14",xi="_empty_1vzxd_17",fe={area:bi,panel:wi,active:Si,empty:xi};function vi(){const t=T(o=>o.tabs),e=T(o=>o.activeTabId),n=T(o=>o.activeWorkspaceCwd);return t.some(o=>o.workspaceCwd===n)?i.jsx("div",{className:fe.area,children:t.map(o=>{const r=yi[o.kind];return i.jsx("div",{className:B(fe.panel,o.id===e&&fe.active),children:i.jsx(w.Suspense,{fallback:i.jsx(gi,{size:"md"}),children:i.jsx(r,{tab:o})})},o.id)})}):i.jsx("div",{className:fe.area,children:i.jsx("div",{className:fe.empty,children:"No open tabs in this workspace"})})}const Gt={fileRead:t=>["file","read",t],fileDownload:t=>["file","download",t],fileDiff:(t,e,n)=>["file","diff",t,e,n],explorer:t=>["explorer",t],agentList:()=>["agents","list"],agentTimeline:t=>["agents","timeline",t]};function ki(t){const e=t.kind==="directory"||t.type==="directory"?"directory":"file";return{name:t.name??"",kind:e,size:t.size,mtimeMs:t.mtimeMs}}function Ii(t){return t.slice().sort((e,n)=>e.kind!==n.kind?e.kind==="directory"?-1:1:e.name.localeCompare(n.name))}async function Jt(t,e){const s=(await t.connection.request("file_explorer_request",{path:e})).result;if(!s||s.ok===!1)throw new Error(s&&"error"in s?s.error:"explorer request failed");const o="entries"in s?s.entries??[]:[];return{path:s.resolvedPath??e,entries:Ii(o.map(ki))}}function Ci(t,e=!0){const n=E(s=>s.client);return ln({queryKey:Gt.explorer(t),queryFn:()=>{if(!n)throw new Error("not connected");return Jt(n,t)},enabled:!!n&&!!t&&e})}function Ti(t){const e=E(o=>o.client),n=w.useMemo(()=>Array.from(t),[t]),s=dn({queries:n.map(o=>({queryKey:Gt.explorer(o),queryFn:()=>{if(!e)throw new Error("not connected");return Jt(e,o)},enabled:!!e&&!!o}))});return w.useMemo(()=>{const o=new Map;return n.forEach((r,a)=>{const l=s[a];o.set(r,{listing:l==null?void 0:l.data,isLoading:!!(l!=null&&l.isLoading),isError:!!(l!=null&&l.isError),error:l==null?void 0:l.error})}),o},[n,s])}const ht=new WeakMap;function gt(t){let e=ht.get(t);return e||(e=new Er(t),e.start(),ht.set(t,e)),e}function ji(t,e,n){const s=new Blob([Uint8Array.from(t)],{type:n||"application/octet-stream"}),o=URL.createObjectURL(s),r=document.createElement("a");r.href=o,r.download=e,r.rel="noopener",document.body.appendChild(r),r.click(),r.remove(),setTimeout(()=>URL.revokeObjectURL(o),0)}function Xt(){const t=E(o=>o.daemon),e=Ue(),n=w.useCallback(async(o,r)=>{if(!t)throw new Error("not connected");const a=o?`${o}/${r.name}`:r.name,l=new Uint8Array(await r.arrayBuffer());await gt(t).upload(a,l),await e.invalidateQueries({queryKey:["explorer"]})},[t,e]),s=w.useCallback(async o=>{if(!t)throw new Error("not connected");const r=await gt(t).download(o);ji(r.bytes,r.fileName||o.split("/").pop()||"download",r.mimeType)},[t]);return{upload:n,saveToDisk:s}}function Ei(t,e){return t.endsWith("/")?`${t}${e}`:`${t}/${e}`}function Yt(t,e,n,s,o){var a;const r=o.get(e);if(!r||r.isLoading){t.push({kind:"loading",path:e,depth:n});return}if(r.isError){const l=r.error instanceof Error?r.error.message:"failed to load";t.push({kind:"error",path:e,depth:n,message:l});return}for(const l of((a=r.listing)==null?void 0:a.entries)??[])Ni(t,e,l,n,s,o)}function Ni(t,e,n,s,o,r){const a=Ei(e,n.name);if(n.kind!=="directory"){t.push({kind:"file",path:a,name:n.name,depth:s});return}const l=o.has(a);t.push({kind:"directory",path:a,name:n.name,depth:s,expanded:l}),l&&Yt(t,a,s+1,o,r)}function Ri(t,e,n){if(!t)return[];const s=[];return Yt(s,t,0,e,n),s}const qi="_container_yg965_1",Bi="_header_yg965_7",Mi="_uploadButton_yg965_13",Ai="_hiddenInput_yg965_32",$i="_status_yg965_35",Di="_statusError_yg965_36",Oi="_rowAction_yg965_49",Fi="_item_yg965_64",Pi="_dropOverlay_yg965_67",Hi="_list_yg965_82",zi="_chevronSlot_yg965_101",Wi="_chevron_yg965_101",Li="_chevronOpen_yg965_112",Ui="_icon_yg965_115",Ki="_name_yg965_122",Vi="_dirName_yg965_127",Gi="_statusRow_yg965_133",Ji="_statusRowError_yg965_144",Xi="_emptyState_yg965_147",R={container:qi,header:Bi,uploadButton:Mi,hiddenInput:Ai,status:$i,statusError:Di,rowAction:Oi,item:Fi,dropOverlay:Pi,list:Hi,chevronSlot:zi,chevron:Wi,chevronOpen:Li,icon:Ui,name:Ki,dirName:Vi,statusRow:Gi,statusRowError:Ji,emptyState:Xi},Yi=14;function Qi({row:t,onToggle:e,onOpenFile:n,onContextMenu:s}){const o={paddingLeft:8+t.depth*Yi};if(t.kind==="loading")return i.jsx("div",{className:R.statusRow,style:o,children:"Loading…"});if(t.kind==="error")return i.jsx("div",{className:B(R.statusRow,R.statusRowError),style:o,children:t.message??"failed to load"});const r=t.kind==="directory";return i.jsxs("div",{className:R.item,style:o,onClick:()=>r?e(t.path):n(t.path),onContextMenu:a=>{a.preventDefault(),s(t.path,r,a.clientX,a.clientY)},children:[i.jsx("span",{className:R.chevronSlot,children:r&&i.jsx(bt,{size:12,className:B(R.chevron,t.expanded&&R.chevronOpen)})}),i.jsx("span",{className:R.icon,children:r?i.jsx(vt,{size:14}):i.jsx(xn,{size:14})}),i.jsx("span",{className:r?R.dirName:R.name,children:t.name}),i.jsx("button",{type:"button",className:R.rowAction,title:"Actions",onClick:a=>{a.stopPropagation();const l=a.currentTarget.getBoundingClientRect();s(t.path,r,l.left,l.bottom)},children:i.jsx(yt,{size:12})})]})}const Zi="_trigger_g81d7_1",ec="_content_g81d7_7",tc="_item_g81d7_16",nc="_danger_g81d7_29",sc="_sep_g81d7_32",se={trigger:Zi,content:ec,item:tc,danger:nc,sep:sc};function oc(){const t=v(f=>f.fileMenu),e=v(f=>f.closeFileMenu),n=E(f=>f.client),{saveToDisk:s}=Xt(),o=Ue(),r=w.useRef(null),[a,l]=w.useState(!1);if(w.useEffect(()=>{l(t!==null)},[t]),!t)return null;const d=t.path.split("/").pop()||t.path;function p(f){l(f),f||e()}async function h(){if(t){e();try{await s(t.path)}catch(f){window.alert(`Failed to download: ${f instanceof Error?f.message:String(f)}`)}}}async function _(){if(!t)return;const f=t.isDirectory?"folder (and everything inside it)":"file";if(!window.confirm(`Permanently delete this ${f}? "${d}" — this cannot be undone.`))return e();if(e(),!n){window.alert("Not connected — cannot delete remotely.");return}try{const x=await n.connection.request("file_delete_request",{path:t.path});if(!x.ok)throw new Error(x.error??"delete failed");await o.invalidateQueries({queryKey:["explorer"]})}catch(x){window.alert(`Failed to delete: ${x instanceof Error?x.message:String(x)}`)}}return i.jsxs(Ke,{open:a,onOpenChange:p,modal:!1,children:[i.jsx(Ve,{asChild:!0,children:i.jsx("button",{ref:r,type:"button",className:se.trigger,style:{left:t.x,top:t.y},"aria-hidden":!0,tabIndex:-1})}),i.jsx(Ge,{children:i.jsxs(Je,{className:se.content,align:"start",sideOffset:2,children:[!t.isDirectory&&i.jsx(J,{className:se.item,onSelect:h,children:"Download"}),i.jsx(kt,{className:se.sep}),i.jsx(J,{className:`${se.item} ${se.danger}`,onSelect:_,children:"Delete"})]})})]})}const rc=24;function ac(){const t=E(b=>b.client),e=ke(b=>b.rootPath),n=ke(b=>b.expanded),s=ke(b=>b.setRoot),o=ke(b=>b.toggle),r=T(b=>b.activeWorkspaceCwd),a=T(b=>b.open),{upload:l}=Xt(),d=v(b=>b.openFileMenu),[p,h]=w.useState(null),[_,f]=w.useState(!1),[x,S]=w.useState(null),y=w.useRef(null),N=w.useRef(null),O=w.useRef(null);w.useEffect(()=>{if(!t)return;const b=r||"~";O.current!==b&&(O.current=b,_a(t,b).then(q=>s(q)))},[t,r,s]);const k=Ti(n),ne=w.useMemo(()=>Ri(e,n,k),[e,n,k]),Ze=un({count:ne.length,getScrollElement:()=>N.current,estimateSize:()=>rc,overscan:12,getItemKey:b=>{var q;return((q=ne[b])==null?void 0:q.path)??b}});function Zt(b){a({id:L.file(b),kind:"file",label:b.split("/").pop()||b,closable:!0,data:{path:b},workspaceCwd:r||"~"})}async function et(b,q){var be;if(!q.length||!b)return;const Y=(be=k.get(b))==null?void 0:be.listing,Re=new Set((Y==null?void 0:Y.entries.map(W=>W.name))??[]),le=q.filter(W=>Re.has(W.name));if(le.length>0){const W=le.map(nn=>nn.name).join(", ");if(!window.confirm(`Overwrite ${le.length>1?"these files":"this file"}? ${W}`))return}h({text:`Uploading ${q.length} file${q.length>1?"s":""}…`,error:!1});try{for(const W of q)await l(b,W);h({text:`Uploaded ${q.length} file${q.length>1?"s":""}`,error:!1})}catch(W){h({text:`Upload failed: ${W instanceof Error?W.message:"unknown"}`,error:!0})}}function en(b){b.preventDefault(),f(!1);const q=x??e;S(null);const Y=Array.from(b.dataTransfer.files);et(q,Y)}function tn(b){b.dataTransfer.types.includes("Files")&&(b.preventDefault(),f(!0))}return t?i.jsxs("div",{className:R.container,onDragOver:tn,onDragLeave:()=>f(!1),onDrop:en,children:[i.jsxs("div",{className:R.header,children:[i.jsxs("button",{type:"button",className:R.uploadButton,onClick:()=>{var b;return(b=y.current)==null?void 0:b.click()},disabled:!e,title:"Upload files to the workspace root",children:[i.jsx(vn,{size:12}),i.jsx("span",{children:"Upload"})]}),i.jsx("input",{ref:y,type:"file",multiple:!0,className:R.hiddenInput,onChange:b=>{et(e,Array.from(b.target.files??[])),b.target.value=""}})]}),p&&i.jsx("div",{className:p.error?R.statusError:R.status,children:p.text}),i.jsxs("div",{className:R.list,ref:N,children:[ne.length===0&&i.jsx("div",{className:R.emptyState,children:"No files loaded"}),i.jsx("div",{style:{position:"relative",height:Ze.getTotalSize()},children:Ze.getVirtualItems().map(b=>{const q=ne[b.index];return q?i.jsx("div",{"data-index":b.index,style:{position:"absolute",top:0,left:0,width:"100%",height:b.size,transform:`translateY(${b.start}px)`},onDragEnter:()=>{q.kind==="directory"&&S(q.path)},children:i.jsx(Qi,{row:q,onToggle:o,onOpenFile:Zt,onContextMenu:(Y,Re,le,be)=>d(Y,Re,le,be)})},b.key):null})})]}),_&&i.jsx("div",{className:R.dropOverlay,children:"Drop to upload"}),i.jsx(oc,{})]}):i.jsx("div",{className:R.emptyState,children:"Connect to browse files"})}const Le=ce()(t=>({subscribedCwd:null,changes:[],setSubscribedCwd:e=>t({subscribedCwd:e}),applyProjection:e=>{if(!e||!e.available){t({changes:[]});return}const n=[];for(const s of e.staged)n.push({path:s.path,status:s.indexStatus==="A"?"added":s.indexStatus==="D"?"deleted":"modified",staged:!0});for(const s of e.unstaged)n.push({path:s.path,status:s.worktreeStatus==="D"?"deleted":"modified",staged:!1});for(const s of e.untracked)n.push({path:s,status:"added",staged:!1});t({changes:n})}}));function ic(t){return typeof t=="object"&&t!==null&&"type"in t&&t.type==="checkout_status_update"&&"cwd"in t&&typeof t.cwd=="string"&&"projection"in t&&typeof t.projection=="object"&&t.projection!==null}function cc(t){const e=E(r=>r.client),n=Le(r=>r.applyProjection),s=Le(r=>r.setSubscribedCwd),o=w.useRef(e);return o.current=e,w.useEffect(()=>{if(!e||!t)return;let r=!1;e.connection.request("checkout_status_subscribe",{cwd:t}).catch(()=>{}),s(t);const a=e.connection.onSessionMessage(l=>{if(r)return;const d=l;ic(d)&&d.cwd===t&&n(d.projection)});return e.connection.request("checkout_refresh_request",{cwd:t}).catch(()=>{}),()=>{r=!0,a(),e.connection.request("checkout_status_unsubscribe",{cwd:t}).catch(()=>{}),s(null)}},[e,t,n,s]),{refresh(){const r=o.current;!r||!t||r.connection.request("checkout_refresh_request",{cwd:t}).catch(()=>{})}}}const lc="_list_1pgby_1",dc="_summary_1pgby_4",uc="_item_1pgby_11",pc="_badge_1pgby_23",fc="_added_1pgby_30",hc="_modified_1pgby_34",gc="_deleted_1pgby_38",mc="_name_1pgby_42",_c="_emptyState_1pgby_47",Z={list:lc,summary:dc,item:uc,badge:pc,added:fc,modified:hc,deleted:gc,name:mc,emptyState:_c},yc={added:"A",modified:"M",deleted:"D"};function bc(){const e=T(r=>r.activeWorkspaceCwd)||"~";cc(e);const n=Le(r=>r.changes),s=T(r=>r.open);function o(r,a){s({id:L.diff(r,a),kind:"diff",label:r.split("/").pop()||r,closable:!0,data:{path:r,staged:a},workspaceCwd:e})}return n.length===0?i.jsx("div",{className:Z.emptyState,children:"No changes detected"}):i.jsxs("div",{className:Z.list,children:[i.jsxs("div",{className:Z.summary,children:[n.length," changed file",n.length===1?"":"s"]}),n.map((r,a)=>i.jsxs("div",{className:Z.item,onClick:()=>o(r.path,r.staged),children:[i.jsx("span",{className:B(Z.badge,Z[r.status]),children:yc[r.status]}),i.jsx("span",{className:Z.name,children:r.path})]},`${r.path}-${r.staged}-${a}`))]})}const wc="_wrap_r37ok_1",Sc="_tabBar_r37ok_7",xc="_tabBtn_r37ok_13",vc="_active_r37ok_26",kc="_refreshBtn_r37ok_30",Ic="_content_r37ok_34",V={wrap:wc,tabBar:Sc,tabBtn:xc,active:vc,refreshBtn:kc,content:Ic};function Cc(){const t=v(l=>l.rightSidebarTab),e=v(l=>l.setRightSidebarTab),s=T(l=>l.activeWorkspaceCwd)||"~",o=E(l=>l.client),r=Ue();function a(){r.invalidateQueries({queryKey:["explorer"]}),o&&s&&o.connection.request("checkout_refresh_request",{cwd:s}).catch(()=>{})}return i.jsxs("div",{className:V.wrap,children:[i.jsxs("div",{className:V.tabBar,children:[i.jsx("button",{type:"button",className:B(V.tabBtn,t==="files"&&V.active),onClick:()=>e("files"),children:"Files"}),i.jsx("button",{type:"button",className:B(V.tabBtn,t==="changes"&&V.active),onClick:()=>e("changes"),children:"Changes"}),i.jsx(z,{size:"xs",variant:"ghost",iconOnly:!0,title:"Refresh",className:V.refreshBtn,onClick:a,children:i.jsx(kn,{size:13})})]}),i.jsx("div",{className:V.content,children:t==="files"?i.jsx(ac,{}):i.jsx(bc,{})})]})}const Tc="_wrapper_131x2_3",jc="_box_131x2_18",Ec="_checkmark_131x2_36",Nc="_nativeInput_131x2_41",Ie={wrapper:Tc,box:jc,checkmark:Ec,nativeInput:Nc};w.forwardRef(function({label:e,checked:n=!1,disabled:s,className:o,onChange:r,...a},l){return i.jsxs("label",{className:Ie.wrapper,"data-disabled":s||void 0,children:[i.jsx("input",{ref:l,type:"checkbox",className:Ie.nativeInput,checked:n,disabled:s,onChange:r,...a}),i.jsx("span",{className:Ie.box,"data-checked":n,"aria-hidden":!0,children:n&&i.jsx(In,{size:12,className:Ie.checkmark})}),e&&i.jsx("span",{children:e})]})});const Rc="_select_vj45v_3",qc={select:Rc};w.forwardRef(function({options:e,placeholder:n,className:s,...o},r){return i.jsxs("select",{ref:r,className:B(qc.select,s),...o,children:[n&&i.jsx("option",{value:"",disabled:!0,children:n}),e.map(a=>i.jsx("option",{value:a.value,children:a.label},a.value))]})});const Bc="_overlay_1yaef_1",Mc="_contentWrapper_1yaef_7",Ac="_dialog_1yaef_16",$c="_header_1yaef_28",Dc="_title_1yaef_36",Oc="_closeBtn_1yaef_43",Fc="_body_1yaef_57",Pc="_footer_1yaef_63",Hc="_bare_1yaef_72",zc="_bareBody_1yaef_78",Wc="_bareCloseBtn_1yaef_82",Lc="_visuallyHidden_1yaef_101",F={overlay:Bc,contentWrapper:Mc,dialog:Ac,header:$c,title:Dc,closeBtn:Oc,body:Fc,footer:Pc,bare:Hc,bareBody:zc,bareCloseBtn:Wc,visuallyHidden:Lc},Uc=De;function Kc({open:t,onOpenChange:e,title:n,children:s,footer:o,width:r,className:a,bare:l=!1}){return i.jsx(Tn,{open:t,onOpenChange:e,children:i.jsxs(jn,{children:[i.jsx(En,{className:F.overlay}),i.jsx("div",{className:F.contentWrapper,children:i.jsxs(Nn,{className:B(F.dialog,l&&F.bare,a),style:r!==void 0?{width:r}:void 0,children:[l?i.jsx(tt,{className:F.visuallyHidden,children:n}):i.jsxs("div",{className:F.header,children:[i.jsx(tt,{className:F.title,children:n}),i.jsx(De,{asChild:!0,children:i.jsx("button",{type:"button",className:F.closeBtn,"aria-label":"Close",children:i.jsx($e,{size:16})})})]}),i.jsx("div",{className:B(F.body,l&&F.bareBody),children:s}),l&&i.jsx(De,{asChild:!0,children:i.jsx("button",{type:"button",className:F.bareCloseBtn,"aria-label":"Close",children:i.jsx($e,{size:16})})}),o&&i.jsx("div",{className:F.footer,children:o})]})})]})})}const Vc="_handle_1ocv1_1",Gc={handle:Vc};function mt({side:t,onResize:e,className:n}){const s=w.useRef(0),o=w.useCallback(l=>{const d=l.clientX-s.current;s.current=l.clientX,e(t==="left"?d:-d)},[e,t]),r=w.useCallback(l=>{var d,p;window.removeEventListener("pointermove",o),window.removeEventListener("pointerup",r),document.body.style.cursor="",document.body.style.userSelect="",(p=(d=l.target)==null?void 0:d.releasePointerCapture)==null||p.call(d,l.pointerId)},[o]);function a(l){l.preventDefault(),s.current=l.clientX,document.body.style.cursor="col-resize",document.body.style.userSelect="none",window.addEventListener("pointermove",o),window.addEventListener("pointerup",r)}return i.jsx("div",{className:B(Gc.handle,n),onPointerDown:a,role:"separator","aria-orientation":"vertical"})}function Jc(t,e){const{order:n,sessions:s}=$.getState(),r=Vt(n,s,e).find(a=>a.cwd===t);if(r!=null&&r.sessions[0]){const a=r.sessions[0].id;$.getState().activate(a);const l=$.getState().sessions[a];T.getState().open({id:L.chat(a),kind:"chat",label:(l==null?void 0:l.title)??"New chat",closable:!0,data:{sessionId:a},workspaceCwd:t})}else Ee(t);v.getState().setCwd(t)}const Xc="_pathRow_9xphl_1",Yc="_pathInput_9xphl_9",Qc="_list_9xphl_13",Zc="_item_9xphl_20",el="_name_9xphl_32",tl="_emptyState_9xphl_37",G={pathRow:Xc,pathInput:Yc,list:Qc,item:Zc,name:el,emptyState:tl};function nl(){const t=v(k=>k.cwdPickerOpen),e=v(k=>k.closeCwdPicker),n=T(k=>k.activeWorkspaceCwd),s=E(k=>k.client),o=Kt(),[r,a]=w.useState("/"),[l,d]=w.useState("/");w.useEffect(()=>{if(!t)return;const k=te(n||"~",o);a(k),d(k)},[t,s,n]);const{data:p,isLoading:h,isError:_,error:f}=Ci(r,t&&!!s),x=((p==null?void 0:p.entries)??[]).filter(k=>k.kind==="directory");function S(k){a(k),d(k)}function y(){S(r.split("/").slice(0,-1).join("/")||"/")}function N(){S(l.trim())}function O(){Jc(r,o),e()}return i.jsxs(Kc,{open:t,onOpenChange:k=>!k&&e(),title:"Open Workspace",footer:i.jsxs(i.Fragment,{children:[i.jsx(Uc,{asChild:!0,children:i.jsx(z,{size:"sm",variant:"secondary",children:"Cancel"})}),i.jsx(z,{size:"sm",onClick:O,children:"Open this folder"})]}),children:[i.jsxs("div",{className:G.pathRow,children:[i.jsx(z,{size:"xs",variant:"ghost",iconOnly:!0,title:"Up",onClick:y,children:i.jsx(Cn,{size:13})}),i.jsx(Fe,{className:G.pathInput,value:l,onChange:k=>d(k.target.value),onKeyDown:k=>{k.key==="Enter"&&(k.preventDefault(),N())}}),i.jsx(z,{size:"xs",onClick:N,children:"Go"})]}),i.jsx("div",{className:G.list,children:h?i.jsx("div",{className:G.emptyState,children:"Loading..."}):_?i.jsxs("div",{className:G.emptyState,children:["Error: ",f instanceof Error?f.message:"unknown error"]}):x.length===0?i.jsx("div",{className:G.emptyState,children:"No subdirectories"}):x.map(k=>i.jsxs("div",{className:G.item,onClick:()=>S(r==="/"?`/${k.name}`:`${r}/${k.name}`),children:[i.jsx(vt,{size:14}),i.jsx("span",{className:G.name,children:k.name})]},k.name))})]})}const sl="_shell_1m1nv_1",ol="_main_1m1nv_7",rl="_sidebarLeft_1m1nv_13",al="_leftHandle_1m1nv_21",il="_center_1m1nv_24",cl="_sidebarRight_1m1nv_31",ll="_rightHandle_1m1nv_39",ee={shell:sl,main:ol,sidebarLeft:rl,leftHandle:al,center:il,sidebarRight:cl,rightHandle:ll};function dl(){const t=v(a=>a.leftSidebarCollapsed),e=v(a=>a.rightSidebarCollapsed),n=v(a=>a.leftSidebarWidth),s=v(a=>a.rightSidebarWidth),o=v(a=>a.resizeLeftSidebar),r=v(a=>a.resizeRightSidebar);return i.jsxs("div",{className:ee.shell,children:[i.jsx(Zr,{}),i.jsxs("div",{className:ee.main,children:[!t&&i.jsxs("aside",{className:ee.sidebarLeft,style:{width:n},children:[i.jsx(Xa,{}),i.jsx(mt,{side:"left",className:ee.leftHandle,onResize:o})]}),i.jsxs("div",{className:ee.center,children:[i.jsx(di,{}),i.jsx(vi,{})]}),!e&&i.jsxs("aside",{className:ee.sidebarRight,style:{width:s},children:[i.jsx(mt,{side:"right",className:ee.rightHandle,onResize:r}),i.jsx(Cc,{})]})]}),i.jsx(nl,{})]})}function ul(){const t=w.useRef(!1);w.useEffect(()=>{if(t.current)return;if(t.current=!0,window.location.hash.includes("offer=")){const d=window.location.href;v.getState().setHost(d),E.getState().connect({url:d});return}const e=new URLSearchParams(window.location.search),n=e.get("host"),s=e.get("pair"),o=e.get("password"),r=e.get("cwd"),a=e.get("connect")==="1",l=v.getState();if(s?l.setHost(s):n&&l.setHost(n),o&&l.setPassword(o),r&&l.setCwd(r),s)E.getState().connect({url:s});else if(a){const{host:d,password:p}=v.getState();E.getState().connect({url:d,password:p||void 0})}},[])}function pl(t){return typeof t=="object"&&t!==null&&"kind"in t}function fl(t){const e=[];for(const n of t)if(pl(n))if(n.kind==="other")n.event&&e.push(n.event);else for(const s of n.events??[])e.push(s);return e}function hl(){const t=E(s=>s.client),e=E(s=>s.status),n=w.useRef(!1);w.useEffect(()=>{e!=="open"||!t||n.current||(n.current=!0,(async()=>{var d;let s=[];try{s=(await t.connection.request("list_agents_request",{all:!1})).agents??[]}catch{s=[]}s.sort((p,h)=>(h.lastActivity??0)-(p.lastActivity??0));const o=$.getState();for(const p of s){if(o.findByAgentId(p.agentId))continue;let h=ze;try{const _=await t.agent(p.agentId).timeline.fetch({direction:"after",limit:200});h=fl(_.items).reduce(Lt,ze)}catch{}o.hydrate({id:`s-${p.agentId.slice(0,12)}`,agentId:p.agentId,title:p.title||((d=p.cwd)==null?void 0:d.split("/").pop())||"Restored",status:p.status??"idle",cwd:p.cwd||"~",timeline:h,userMessageCount:h.rows.filter(_=>_.kind==="user").length})}const r=await Ne(t).catch(()=>null),{order:a,sessions:l}=$.getState();if(a.length>0){const p=l[a[0]??""];if(p){const h=te(p.cwd||"~",r);$.getState().activate(p.id),v.getState().setCwd(p.cwd),T.getState().open({id:L.chat(p.id),kind:"chat",label:p.title,closable:!0,data:{sessionId:p.id},workspaceCwd:h})}}else{const p=v.getState().cwd||"~",h=te(p,r);Ee(h)}})())},[e,t])}function gl(){const t=E(s=>s.client),e=E(s=>s.status),n=w.useRef(!1);w.useEffect(()=>{e!=="open"||!t||n.current||(n.current=!0,(async()=>{let s=[];try{s=(await t.connection.request("list_terminals_request",{})).terminals??[]}catch{s=[]}if(s.length===0)return;const o=await Ne(t).catch(()=>null),r=T.getState().open;for(const a of s){if(a.closed)continue;const l=te(a.cwd||"~",o);r({id:L.terminal(a.slot),kind:"terminal",label:a.name,closable:!0,data:{slot:a.slot,cwd:l},workspaceCwd:l})}})())},[e,t])}function ml(){w.useEffect(()=>{function t(e){const n=v.getState();if(e.key==="Escape"){n.closeCwdPicker(),n.closeSessionMenu();return}const s=e.ctrlKey||e.metaKey;if(s&&e.key.toLowerCase()==="t"){e.preventDefault(),Ut(T.getState().activeWorkspaceCwd||"~");return}if(s&&e.key.toLowerCase()==="w"){const{activeTabId:o,tabs:r,close:a}=T.getState();if(!o)return;const l=r.find(d=>d.id===o);(l==null?void 0:l.closable)!==!1&&(e.preventDefault(),a(o))}}return document.addEventListener("keydown",t),()=>document.removeEventListener("keydown",t)},[])}function _l(){return ul(),hl(),gl(),ml(),null}function yl(){return i.jsxs(js,{children:[i.jsx(_l,{}),i.jsx(dl,{})]})}const Qt=document.getElementById("root");if(!Qt)throw new Error("Missing #root element");rn.createRoot(Qt).render(i.jsx(w.StrictMode,{children:i.jsx(yl,{})}));export{z as B,Kc as D,gi as S,jl as T,E as a,T as b,gt as c,El as e,Gt as r,ea as t,$ as u};
3
- //# sourceMappingURL=index-B_Wls_vp.js.map