@polderlabs/bizar 5.5.2 → 5.5.4

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 (41) hide show
  1. package/bizar-dash/dist/assets/{EnvVarsSection-DoIzqrlb.js → EnvVarsSection-Bi3Cptpr.js} +3 -3
  2. package/bizar-dash/dist/assets/{EnvVarsSection-DoIzqrlb.js.map → EnvVarsSection-Bi3Cptpr.js.map} +1 -1
  3. package/bizar-dash/dist/assets/{MobileChat-CoUCUsbr.js → MobileChat-H0ASvfzr.js} +1 -1
  4. package/bizar-dash/dist/assets/{MobileChat-CoUCUsbr.js.map → MobileChat-H0ASvfzr.js.map} +1 -1
  5. package/bizar-dash/dist/assets/MobileSettings-ndyqmLdP.js +1 -0
  6. package/bizar-dash/dist/assets/{MobileSettings-BeO04g52.js.map → MobileSettings-ndyqmLdP.js.map} +1 -1
  7. package/bizar-dash/dist/assets/{Toast-D9nv5N6m.js → Toast-BP5x9M-T.js} +1 -1
  8. package/bizar-dash/dist/assets/{Toast-D9nv5N6m.js.map → Toast-BP5x9M-T.js.map} +1 -1
  9. package/bizar-dash/dist/assets/{icons-Btipv2pp.js → icons-Cr5zfF_4.js} +96 -91
  10. package/bizar-dash/dist/assets/icons-Cr5zfF_4.js.map +1 -0
  11. package/bizar-dash/dist/assets/{main-UG4jKK-F.css → main-DAthMQSh.css} +1 -1
  12. package/bizar-dash/dist/assets/{main-DHXPuddY.js → main-dq0UZN8-.js} +10 -10
  13. package/bizar-dash/dist/assets/main-dq0UZN8-.js.map +1 -0
  14. package/bizar-dash/dist/assets/mobile-BIJt6dnI.js +1 -0
  15. package/bizar-dash/dist/assets/{mobile-H5KH9cTL.js.map → mobile-BIJt6dnI.js.map} +1 -1
  16. package/bizar-dash/dist/assets/mobile-layout-DKh7Pn9-.js +2 -0
  17. package/bizar-dash/dist/assets/{mobile-layout-BqHxVb6_.js.map → mobile-layout-DKh7Pn9-.js.map} +1 -1
  18. package/bizar-dash/dist/assets/{useSlashCommands-C24-O1e7.js → useSlashCommands-B8ixT4ub.js} +2 -2
  19. package/bizar-dash/dist/assets/{useSlashCommands-C24-O1e7.js.map → useSlashCommands-B8ixT4ub.js.map} +1 -1
  20. package/bizar-dash/dist/index.html +7 -7
  21. package/bizar-dash/dist/mobile.html +3 -3
  22. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  23. package/bizar-dash/src/server/memory-git.mjs +62 -19
  24. package/bizar-dash/src/server/memory-store.mjs +44 -7
  25. package/bizar-dash/src/web/components/SettingsNav.tsx +29 -9
  26. package/bizar-dash/src/web/styles/settings.css +0 -74
  27. package/bizar-dash/src/web/views/Settings.tsx +1 -1
  28. package/bizar-dash/tests/memory-git.test.mjs +18 -0
  29. package/bizar-dash/tests/settings-layout.test.tsx +1 -1
  30. package/bizar-dash/tests/settings-nav.test.tsx +3 -2
  31. package/cli/doctor.mjs +4 -1
  32. package/cli/doctor.test.mjs +5 -3
  33. package/cli/post-install-smoke.mjs +93 -67
  34. package/cli/post-install-smoke.test.mjs +72 -0
  35. package/cli/provision.mjs +33 -3
  36. package/package.json +1 -1
  37. package/bizar-dash/dist/assets/MobileSettings-BeO04g52.js +0 -1
  38. package/bizar-dash/dist/assets/icons-Btipv2pp.js.map +0 -1
  39. package/bizar-dash/dist/assets/main-DHXPuddY.js.map +0 -1
  40. package/bizar-dash/dist/assets/mobile-H5KH9cTL.js +0 -1
  41. package/bizar-dash/dist/assets/mobile-layout-BqHxVb6_.js +0 -2
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/mobile-layout-BqHxVb6_.js","assets/react-vendor-Dn4wqh4Z.js","assets/icons-Btipv2pp.js","assets/mobile-layout-CJnZNLy3.css"])))=>i.map(i=>d[i]);
2
- import{r as n,j as s}from"./react-vendor-Dn4wqh4Z.js";import{b as Le,d as xe,bj as Ae,aN as Be,bk as Ue,bl as Pe,aB as Fe,R as We,bm as Ge,W as qe,B as He,bn as be,X as Ke,i as Ye,O as Ve}from"./icons-Btipv2pp.js";import{b as Qe,e as Je,a as T,A as le,_ as Xe}from"./mobile-layout-BqHxVb6_.js";import{M as Ze,r as es}from"./markdown-C6mXtQxD.js";function ss({items:i,renderItem:f,itemHeight:h=80,height:l=400,overscan:d=5,className:x}){const[g,S]=n.useState(0),j=n.useRef(null),E=n.useMemo(()=>{const C=Math.max(0,Math.floor(g/h)-d),I=Math.min(i.length,Math.ceil((g+l)/h)+d);return{start:C,end:I}},[g,h,l,d,i.length]),M=i.length*h,R=E.start*h,$=i.slice(E.start,E.end);return s.jsx("div",{ref:j,onScroll:C=>S(C.currentTarget.scrollTop),style:{height:l,overflowY:"auto"},className:x,children:s.jsx("div",{style:{height:M,position:"relative"},children:s.jsx("div",{style:{transform:`translateY(${R}px)`},children:$.map((C,I)=>s.jsx("div",{style:{height:h},children:f(C,E.start+I)},E.start+I))})})})}function ms({activeProject:i,sessionCount:f,sessionsOpen:h,infoOpen:l,onToggleSessions:d,onToggleInfo:x,onOpenOverview:g}){return s.jsxs("header",{className:"chat-topbar",children:[s.jsxs("button",{type:"button",className:"chat-topbar-project",onClick:g,children:[s.jsx(Le,{size:14}),s.jsx("span",{className:"chat-topbar-project-name",children:(i==null?void 0:i.name)??"No project"}),s.jsx(xe,{size:12})]}),s.jsx("div",{className:"chat-topbar-spacer"}),s.jsxs("button",{type:"button",className:`chat-topbar-btn ${h?"active":""}`,onClick:d,"aria-pressed":h,children:["Sessions (",f,")"]}),s.jsx("button",{type:"button",className:`chat-topbar-btn ${l?"active":""}`,onClick:x,"aria-pressed":l,children:"Info"})]})}function ts({count:i=3}){return s.jsx("div",{className:"chat-loading-skeleton","aria-label":"Loading messages",children:Array.from({length:i}).map((f,h)=>s.jsxs("div",{className:"chat-loading-skeleton-bubble",children:[s.jsx("div",{className:"chat-loading-skeleton-meta"}),s.jsx("div",{className:"chat-loading-skeleton-line"}),s.jsx("div",{className:"chat-loading-skeleton-line short"})]},h))})}function ns({projectName:i,onPickSuggestion:f}){const h=[{icon:s.jsx(Ae,{size:16}),title:i?`Explain ${i}`:"Explain this project",preview:"Give me a tour of the codebase, highlight the architecture, and call out any anti-patterns or hotspots.",prompt:i?`Explain the ${i} project. Give me a tour of the codebase, highlight the architecture, and call out any anti-patterns or hotspots.`:"Explain the current project. Give me a tour of the codebase, highlight the architecture, and call out any anti-patterns or hotspots."},{icon:s.jsx(Be,{size:16}),title:"Summarize recent sessions",preview:"Read my last 5 chat sessions and give me a 3-bullet summary of what I worked on and what got stuck.",prompt:"Read my last 5 chat sessions and give me a 3-bullet summary of what I worked on and what got stuck."},{icon:s.jsx(Ue,{size:16}),title:"Suggest a refactor",preview:"Look for the largest, most painful files in this project and propose a concrete refactor for the worst one.",prompt:"Look for the largest, most painful files in this project and propose a concrete refactor for the worst one."},{icon:s.jsx(Pe,{size:16}),title:"Find visual regressions",preview:"Open the dashboard, screenshot the Chat tab, and flag any layout problems or anti-patterns you see.",prompt:"Open the dashboard, screenshot the Chat tab, and flag any layout problems or anti-patterns you see."}];return s.jsx("div",{className:"chat-suggestions",children:h.map((l,d)=>s.jsxs("button",{type:"button",className:"chat-suggestion",onClick:()=>f(l.prompt),children:[s.jsxs("div",{className:"chat-suggestion-title",children:[l.icon,s.jsx("span",{children:l.title})]}),s.jsx("div",{className:"chat-suggestion-preview",children:l.preview})]},d))})}function ye({variant:i,projectName:f,onPickSuggestion:h}){if(i==="no-project")return s.jsxs("div",{className:"chat-welcome",children:[s.jsx("h1",{className:"chat-welcome-h1",children:s.jsx("span",{className:"chat-greeting-hello",children:"No project selected."})}),s.jsx("p",{className:"chat-welcome-subtitle",children:"Pick a project in Overview to scope chat sessions."})]});const l=f||"there";return s.jsxs("div",{className:"chat-welcome",children:[s.jsxs("h1",{className:"chat-welcome-h1",children:[s.jsx("span",{className:"chat-greeting-hello",children:"Hello, "}),s.jsxs("span",{className:"chat-greeting-name",children:[l,"."]})]}),s.jsx("p",{className:"chat-welcome-subtitle",children:"How can I help you today?"}),s.jsx(ns,{projectName:f,onPickSuggestion:h})]})}function as({message:i,pinned:f,onCopy:h,onDelete:l,onTogglePin:d,onRegenerate:x}){const g=(i.role||"assistant").toLowerCase(),S=i.ts?Qe(i.ts):"",j=i.content||i.message||"",E=g==="user";return s.jsxs("article",{className:`chat-message ${E?"chat-message-user":"chat-message-assistant"} ${f?"chat-message-pinned":""}`,children:[s.jsxs("header",{className:"chat-message-meta",children:[s.jsx("span",{className:"chat-message-role",children:g}),i.agent&&s.jsxs("span",{className:"chat-message-agent",children:["@",i.agent]}),S&&s.jsx("time",{className:"chat-message-time",children:S}),f&&s.jsx("span",{className:"chat-message-pin",children:"pinned"}),s.jsxs("div",{className:"chat-message-actions",children:[s.jsx("button",{type:"button",className:"chat-msg-action-btn",onClick:h,title:"Copy","aria-label":"Copy",children:s.jsx(Fe,{size:12})}),!E&&s.jsx("button",{type:"button",className:"chat-msg-action-btn",onClick:x,title:"Regenerate","aria-label":"Regenerate",children:s.jsx(We,{size:12})}),s.jsx("button",{type:"button",className:"chat-msg-action-btn",onClick:d,title:"Pin","aria-label":"Pin",children:s.jsx(Ge,{size:12})}),s.jsx("button",{type:"button",className:"chat-msg-action-btn chat-msg-action-btn-danger",onClick:l,title:"Delete","aria-label":"Delete",children:s.jsx(qe,{size:12})})]})]}),s.jsx("div",{className:"chat-message-content markdown-body",children:s.jsx(Ze,{remarkPlugins:[es],children:j})})]})}function ps({messages:i,loading:f,activeProject:h,sessionId:l,pinned:d,activeSource:x,onPickSuggestion:g,onCopy:S,onDelete:j,onTogglePin:E,onRegenerate:M}){const R=n.useRef(null);n.useEffect(()=>{const C=R.current;if(!C)return;let I=C.parentElement,P=!1;for(;I;){if(I.classList.contains("chat-thread-scroll")){P=!0;break}I=I.parentElement}P||(C.scrollTop=C.scrollHeight)},[i]);const $=x==="opencode"?"opencode":"bizar";return f?s.jsx("div",{className:"chat-thread legacy",ref:R,"data-stream":$,children:s.jsx(ts,{count:3})}):h?i.length===0?s.jsx("div",{className:"chat-thread legacy",ref:R,"data-stream":$,children:s.jsx(ye,{variant:"empty",projectName:h.name,onPickSuggestion:g})}):s.jsx("div",{className:"chat-thread legacy",ref:R,children:s.jsx(ss,{items:i,itemHeight:120,height:800,className:"chat-thread-virtual",renderItem:(C,I)=>s.jsx(as,{message:C,pinned:d.has(I),onCopy:()=>S(C),onDelete:()=>j(I),onTogglePin:()=>E(I),onRegenerate:()=>M(String(C.ts??I))})})}):s.jsx("div",{className:"chat-thread legacy",ref:R,"data-stream":$,children:s.jsx(ye,{variant:"no-project",projectName:"",onPickSuggestion:g})})}function rs({agent:i,setAgent:f,agents:h}){const[l,d]=n.useState(!1),x=n.useRef(null);n.useEffect(()=>{if(!l)return;const j=E=>{x.current&&!x.current.contains(E.target)&&d(!1)};return document.addEventListener("mousedown",j),()=>document.removeEventListener("mousedown",j)},[l]);const g=i||"no agent",S=g.startsWith("@")?g.slice(1):g;return s.jsxs("div",{className:"chat-agent-chip",ref:x,children:[s.jsxs("button",{type:"button",className:"chat-agent-chip-btn",onClick:()=>d(j=>!j),"aria-haspopup":"listbox","aria-expanded":l,children:[s.jsx(He,{size:14}),s.jsx("span",{children:S}),s.jsx(xe,{size:12,className:l?"rotated":""})]}),l&&s.jsxs("div",{className:"chat-agent-chip-menu",role:"listbox",children:[s.jsx("button",{type:"button",role:"option","aria-selected":!i,onClick:()=>{f(""),d(!1)},children:s.jsx("span",{children:"no agent"})}),h.map(j=>s.jsx("button",{type:"button",role:"option","aria-selected":i===j.name,onClick:()=>{f(j.name),d(!1)},children:s.jsxs("span",{children:["@",j.name]})},j.name))]})]})}function os(i,f,h=240){n.useLayoutEffect(()=>{const l=i.current;if(!l)return;l.style.height="auto";const d=Math.min(l.scrollHeight,h);l.style.height=`${d}px`,l.style.overflowY=l.scrollHeight>h?"auto":"hidden"},[i,f,h])}function hs({agent:i,setAgent:f,model:h,setModel:l,text:d,setText:x,sending:g,onSend:S,attachments:j,setAttachments:E,suggestions:M,onPickSuggestion:R,agents:$,onAttach:C}){const I=n.useRef(null),P=n.useRef(null);os(I,d,160);const F=b=>{if(b.key==="Enter"&&(b.metaKey||b.ctrlKey))b.preventDefault(),S();else if(b.key==="Enter"&&!b.shiftKey)b.preventDefault(),S();else if(b.key==="Tab"&&M.length){b.preventDefault();const D=M[0].cmd.split(" ")[0];x(`${D} `)}},W=b=>{const D=b.target.files;if(!D)return;const A=[];for(let G=0;G<D.length;G++)A.push(D[G].name);E(G=>[...G,...A]),b.target.value=""};return s.jsxs("div",{className:"chat-composer",children:[M.length>0&&s.jsx("div",{className:"chat-composer-suggestions",children:M.map(b=>s.jsxs("button",{type:"button",className:"chat-composer-suggestion",onClick:()=>{var A;const D=b.cmd.split(" ")[0];x(`${D} `),(A=I.current)==null||A.focus()},children:[s.jsx("span",{className:"mono",children:b.cmd}),s.jsx("span",{children:b.desc})]},b.cmd))}),j.length>0&&s.jsx("div",{className:"chat-composer-attachments",children:j.map((b,D)=>s.jsxs("span",{className:"chat-composer-attachment-tag",children:[s.jsx(be,{size:10})," ",b,s.jsx("button",{type:"button",className:"chat-composer-attachment-remove",onClick:()=>E(A=>A.filter((G,q)=>q!==D)),"aria-label":`Remove ${b}`,children:s.jsx(Ke,{size:10})})]},D))}),s.jsxs("div",{className:"chat-composer-input",children:[s.jsx(rs,{agent:i,setAgent:f,agents:$}),s.jsx("textarea",{ref:I,className:"chat-composer-textarea",placeholder:g?"Sending…":"Send a message…",rows:1,value:d,onChange:b=>x(b.target.value),onKeyDown:F,disabled:g,"aria-label":"Message"}),s.jsx("input",{ref:P,type:"file",multiple:!0,style:{display:"none"},onChange:W,"aria-label":"Attach files",tabIndex:-1}),s.jsx("button",{type:"button",className:"chat-attach-btn",onClick:C,title:"Attach files","aria-label":"Attach files",children:s.jsx(be,{size:14})}),s.jsx("button",{type:"button",className:"chat-attach-btn",onClick:async()=>{if(!d.trim())return;const b=await Je(d);b!==d&&x(b)},title:"Enhance prompt with AI","aria-label":"Enhance prompt",children:s.jsx(Ye,{size:14})}),s.jsx("button",{type:"button",className:"chat-send-btn",onClick:S,disabled:g||!d.trim(),title:"Send (Enter)","aria-label":"Send message",children:s.jsx(Ve,{size:16})})]})]})}function fs(i,f,h){const[l,d]=n.useState([]),[x,g]=n.useState([]),[S,j]=n.useState(""),[E,M]=n.useState(!0),[R,$]=n.useState({create:!1,send:!1,rename:!1,delete:!1}),[C,I]=n.useState([]),[P,F]=n.useState([]),[W,b]=n.useState(null),[D,A]=n.useState(null),[G,q]=n.useState(null),[je,Z]=n.useState(null),[we,ee]=n.useState(null),[se,ue]=n.useState({}),[de,me]=n.useState(!0),[Se,ce]=n.useState(0),[ke,pe]=n.useState(new Set),[Ce,he]=n.useState(new Set),V=n.useRef(null),v=n.useRef(null),O=n.useRef(null),ne=n.useRef(0),z=n.useRef(null),Q=n.useRef(null),Y=n.useRef(!1),J=n.useCallback(e=>{e&&F(a=>{if(e.id&&a.some(r=>r.id===e.id))return a;const t=a.findIndex(r=>typeof r.id=="string"&&r.id.startsWith("msg_")&&r.role===e.role&&(r.content||"")===(e.content||""));if(t>=0){const r=a.slice();return r[t]={...e,id:e.id??a[t].id},r}return[...a,e]})},[]),X=n.useCallback(e=>{e&&pe(a=>{if(a.has(e))return a;const t=new Set(a);return t.add(e),t})},[]),H=n.useCallback((e,a)=>{ue(t=>{const r=t[e]??{state:"idle",unread:0,pinned:!1};return{...t,[e]:{...r,...a}}})},[]),B=n.useCallback((e,a)=>{H(e,{state:a?"streaming":"idle"})},[H]),Ie=n.useCallback(e=>{v.current=e},[]),K=n.useCallback(async e=>{var a;try{const t=e?`/chat?session=${encodeURIComponent(e)}`:"/chat?limit=200",r=await T.get(t);d(r.messages||[]),g(r.sessions||[])}catch(t){(a=v.current)==null||a.error(`Chat load failed: ${t.message}`)}finally{M(!1)}},[]),ae=n.useCallback(async e=>{var a;M(!0);try{const t=await T.get(`/tasks/${encodeURIComponent(e)}/chat`);d(t.messages||[]),j(t.sessionId||e)}catch(t){(a=v.current)==null||a.error(`Task chat load failed: ${t.message}`)}finally{M(!1)}},[]),ie=n.useCallback(async()=>{try{const e=await T.get("/chat/sessions");g(e.sessions||[])}catch{}},[]),re=n.useCallback(async()=>{try{const a=((await T.get("/opencode-sessions")).sessions||[]).map(t=>({...t,source:"opencode",title:t.title||t.id}));I(a)}catch{}},[]),fe=n.useCallback(e=>{if(O.current){try{O.current.close()}catch{}O.current=null}z.current!==null&&(clearTimeout(z.current),z.current=null);const a=T.getToken(),t=a?`/api/opencode-sessions/${encodeURIComponent(e)}/stream?token=${encodeURIComponent(a)}`:`/api/opencode-sessions/${encodeURIComponent(e)}/stream`;Q.current=e,Y.current=!0,ne.current=0,q(null),Z(null),ee(null);const r=()=>{if(!Y.current||Q.current!==e)return;const o=new EventSource(t);O.current=o;const p=c=>{var w,_,L,U;if(!c||!c.type||c.sessionID&&c.sessionID!==e)return;const m=new Date().toISOString(),y=e;if(c.type==="message.user.created"||c.type==="message.user.updated"){const u=c.data;J({id:(u==null?void 0:u.messageID)??c.messageID,role:"user",content:((w=u==null?void 0:u.data)==null?void 0:w.content)??"",ts:m}),X((u==null?void 0:u.messageID)??c.messageID);return}if(c.type==="message.assistant.created"||c.type==="message.assistant.updated"){const u=c.data;J({id:(u==null?void 0:u.messageID)??c.messageID,role:"assistant",content:((_=u==null?void 0:u.data)==null?void 0:_.content)??"",ts:m}),X((u==null?void 0:u.messageID)??c.messageID),B(y,!0);return}if(c.type==="message.part.updated"){const u=c.data,ge=((L=u==null?void 0:u.part)==null?void 0:L.text)??"";if(!ge)return;J({id:(u==null?void 0:u.id)??(u==null?void 0:u.messageID)??c.messageID,role:"assistant",content:ge,ts:m}),X((u==null?void 0:u.id)??(u==null?void 0:u.messageID)??c.messageID),B(y,!0);return}if(c.type==="session.idle"||c.type==="message.assistant.completed"||c.type==="session.completed"){B(y,!1);return}if(c.type==="session.awaiting"||c.type==="session.awaiting_input"||c.type==="message.assistant.awaiting"){H(y,{state:"awaiting"});return}if(c.type==="session.error"){q(((U=c.data)==null?void 0:U.message)||"opencode session error");return}},k=c=>{if(!c)return null;try{const m=JSON.parse(c);if(typeof m.type=="string"){const y=m.properties,w=m.data??y,_=typeof m.sessionID=="string"?m.sessionID:typeof(y==null?void 0:y.sessionID)=="string"?y.sessionID:typeof(w==null?void 0:w.sessionID)=="string"?w.sessionID:void 0,L=typeof m.messageID=="string"?m.messageID:typeof(y==null?void 0:y.messageID)=="string"?y.messageID:typeof(w==null?void 0:w.messageID)=="string"?w.messageID:void 0;let U=m.type;const u=/\.\d+$/.exec(U);return u&&(U=U.slice(0,u.index)),{type:U,sessionID:_,messageID:L,data:m}}if(m.type==="sync"&&m.syncEvent&&typeof m.syncEvent=="object"){const y=m.syncEvent;let w=y.type||"";const _=/\.\d+$/.exec(w);_&&(w=w.slice(0,_.index));const L=y.data||{};return{type:w,sessionID:typeof L.sessionID=="string"?L.sessionID:void 0,messageID:typeof L.messageID=="string"?L.messageID:void 0,data:y}}return null}catch{return null}},N=["message.user.created","message.user.updated","message.assistant.created","message.assistant.updated","message.part.updated","session.idle","message.assistant.completed","session.completed","session.awaiting","session.awaiting_input","message.assistant.awaiting","session.error"];for(const c of N)o.addEventListener(c,m=>{p(k(m.data))});o.onerror=()=>{if(Q.current!==e)return;if(!Y.current){try{o.close()}catch{}O.current=null;return}try{o.close()}catch{}O.current=null;const c=ne.current+1;ne.current=c;const m=Math.min(3e4,1e3*2**(c-1));z.current!==null&&clearTimeout(z.current),z.current=window.setTimeout(()=>{z.current=null,Y.current&&Q.current===e&&r()},m)},o.onopen=()=>{ne.current=0,q(null),Z(null),ee(null)}};r()},[J,X,B,H]),te=n.useCallback(()=>{if(Y.current=!1,Q.current=null,z.current!==null&&(clearTimeout(z.current),z.current=null),O.current){try{O.current.close()}catch{}O.current=null}F([]),pe(new Set),q(null),Z(null),ee(null),A(null),b("bizar")},[]),oe=n.useCallback(async e=>{var a;if(Y.current=!1,O.current){try{O.current.close()}catch{}O.current=null}z.current!==null&&(clearTimeout(z.current),z.current=null),q(null),Z(null),ee(null),M(!0);try{const t=await T.get(`/opencode-sessions/${encodeURIComponent(e)}/messages`);F(t.messages||[])}catch(t){const r=t.message;let o=null;if(t instanceof le&&t.data&&typeof t.data=="object"){const p=t.data,k=p.error||"unknown",N=k!=="bad_request"&&k!=="too_many_subscribers"&&k!=="unauthorized";o={type:"session_load_failed",code:k,message:p.message||r,cause:p.cause,status:p.status,suggestion:p.suggestion??null,canRetry:N}}else t instanceof le&&(o={type:"session_load_failed",code:"unknown",message:r,suggestion:null,canRetry:!0});q(o?`Opencode session load failed (${o.code}): ${o.message}`:`Opencode session load failed: ${r}`),Z((o==null?void 0:o.suggestion)??null),ee(o),(a=v.current)==null||a.error(o?`Opencode session load failed: ${o.message}`:`Opencode session load failed: ${r}`),F([])}finally{M(!1)}A(e),b("opencode"),B(e,!1),fe(e)},[B,fe]),ve=n.useCallback(e=>{te(),j(e),b("bizar"),K(e),H(e,{unread:0})},[te,K,H]),Ne=n.useCallback(async()=>{var a,t,r,o,p;if(R.create)return{ok:!1};const e=f.defaultAgent||"odin";$(k=>({...k,create:!0}));try{try{const N=await T.post("/opencode-sessions/new",{agent:e});return await re(),await oe(N.id),(a=v.current)==null||a.success(`Session ${N.id} created.`),{ok:!0,source:"opencode",id:N.id}}catch(N){if(!(N instanceof le)||N.status!==503)return(t=v.current)==null||t.error(`Create failed: ${N.message}`),{ok:!1}}if(!i.activeProject)return(r=v.current)==null||r.error("Pick a project in Overview to scope chat sessions."),{ok:!1};const k=await T.post("/chat/sessions",{});return j(k.id),d([]),he(new Set),H(k.id,{state:"idle",unread:0}),await K(k.id),ie().catch(()=>{}),(o=v.current)==null||o.success(`Session ${k.id} created.`),{ok:!0,source:"bizar",id:k.id}}catch(k){return(p=v.current)==null||p.error(`Create failed: ${k.message}`),{ok:!1}}finally{$(k=>({...k,create:!1}))}},[R.create,f.defaultAgent,i.activeProject,re,oe,K,ie,H]),Re=n.useCallback(async(e,a,t,r)=>{var k,N,c;if(R.send)return{ok:!1};const o=e.trim();if(!o)return{ok:!1};if(W==="opencode"&&D){const m=D,y=`msg_${Date.now().toString(36)}${Math.random().toString(36).slice(2,8)}`,w={id:y,role:"user",content:o,agent:a,ts:new Date().toISOString()};J(w),X(y),$(_=>({..._,send:!0}));try{return await T.post(`/opencode-sessions/${encodeURIComponent(m)}/send`,{message:o,agent:a}),B(m,!0),{ok:!0}}catch(_){return F(L=>L.filter(U=>U.id!==y)),(k=v.current)==null||k.error(`Send failed: ${_.message}`),{ok:!1}}finally{$(_=>({..._,send:!1}))}}const p={role:"user",content:o,agent:a,ts:new Date().toISOString()};d(m=>[...m,p]),$(m=>({...m,send:!0})),B(S,!0);try{const m=await T.post("/chat",{message:o,agent:a,model:t,attachments:r||[]});if(m!=null&&m.messages)for(const y of m.messages)y.role==="assistant"&&d(w=>w.some(L=>L.ts===y.ts)?w:[...w,y]);else(N=v.current)==null||N.info("Still processing… the response will appear shortly.");return{ok:!0}}catch(m){return d(y=>y.filter(w=>w!==p)),(c=v.current)==null||c.error(`Send failed: ${m.message}`),{ok:!1}}finally{$(m=>({...m,send:!1})),B(S,!1)}},[W,D,J,X,B,S,R.send]),De=n.useCallback(async e=>{var a,t;if(!S){(a=v.current)==null||a.error("No active session to regenerate.");return}try{await T.post("/chat/regenerate",{sessionId:S,messageId:e}),await K(S)}catch(r){(t=v.current)==null||t.error(`Regenerate failed: ${r.message}`)}},[S,K]),$e=n.useCallback(e=>{W==="opencode"?F(a=>a.filter((t,r)=>r!==e)):d(a=>a.filter((t,r)=>r!==e))},[W]),Ee=n.useCallback(e=>{he(a=>{const t=new Set(a);return t.has(e)?t.delete(e):t.add(e),t})},[]),ze=n.useCallback(e=>{var t,r;const a=e.content||e.message||"";try{(t=navigator.clipboard)==null||t.writeText(a).then(()=>{var o;return(o=v.current)==null?void 0:o.success("Copied.")},()=>{var o;return(o=v.current)==null?void 0:o.error("Copy failed.")})}catch{(r=v.current)==null||r.error("Copy failed.")}},[]),Oe=n.useCallback(()=>{const e=V.current;if(!e)return;const t=e.scrollHeight-e.scrollTop-e.clientHeight<32;me(t),t&&ce(0)},[]),Te=n.useCallback(()=>{const e=V.current;e&&(e.scrollTop=e.scrollHeight,me(!0),ce(0))},[]),Me=n.useCallback(async(e,a)=>{var t,r,o;if(R.rename)return!1;$(p=>({...p,rename:!0}));try{const p=a.trim();return p?(C.some(N=>N.id===e)?(await T.patch(`/opencode-sessions/${encodeURIComponent(e)}`,{title:p}),I(N=>N.map(c=>c.id===e?{...c,title:p}:c))):(await T.post(`/chat/sessions/${encodeURIComponent(e)}/rename`,{title:p}),g(N=>N.map(c=>c.id===e?{...c,title:p}:c))),(r=v.current)==null||r.success("Renamed."),!0):((t=v.current)==null||t.error("Title cannot be empty."),!1)}catch(p){return(o=v.current)==null||o.error(`Rename failed: ${p.message}`),!1}finally{$(p=>({...p,rename:!1}))}},[R.rename,C]),_e=n.useCallback(async e=>{var a,t;if(R.delete)return!1;$(r=>({...r,delete:!0}));try{return C.some(o=>o.id===e)?(await T.del(`/opencode-sessions/${encodeURIComponent(e)}`),I(o=>o.filter(p=>p.id!==e)),D===e&&te()):(await T.del(`/chat/sessions/${encodeURIComponent(e)}`),g(o=>o.filter(p=>p.id!==e)),S===e&&(j(""),d([]))),ue(o=>{const p={...o};return delete p[e],p}),(a=v.current)==null||a.success("Session deleted."),!0}catch(r){return(t=v.current)==null||t.error(`Delete failed: ${r.message}`),!1}finally{$(r=>({...r,delete:!1}))}},[R.delete,C,D,te,S]);return n.useEffect(()=>{V.current&&(de?V.current.scrollTop=V.current.scrollHeight:ce(e=>e+1))},[l,P]),n.useEffect(()=>()=>{if(Y.current=!1,Q.current=null,z.current!==null&&(clearTimeout(z.current),z.current=null),O.current){try{O.current.close()}catch{}O.current=null}},[]),n.useEffect(()=>{h?ae(h):K(),re()},[]),n.useEffect(()=>{const e=a=>{var r;const t=(r=a.detail)==null?void 0:r.taskId;t&&ae(t)};return window.addEventListener("bizar:setChatTask",e),()=>window.removeEventListener("bizar:setChatTask",e)},[ae]),n.useEffect(()=>{let e=!1;return Xe(async()=>{const{Ws:a}=await import("./mobile-layout-BqHxVb6_.js").then(t=>t.w);return{Ws:a}},__vite__mapDeps([0,1,2,3])).then(({Ws:a})=>{if(e)return;new a().on(r=>{if(r.type!=="chat:message")return;const o=r.message;o&&d(p=>p.some(N=>N.ts===o.ts)?p:[...p,o])})}),()=>{e=!0}},[]),{messages:W==="opencode"?P:l,bizarMessages:l,opencodeMessages:P,sessions:x,opencodeSessions:C,sessionId:S,setSessionId:j,loading:E,sending:R.send,pinned:Ce,listRef:V,activeSource:W,activeOpencodeSessionId:D,opencodeError:G,opencodeSuggestion:je,opencodeErrorInfo:we,retryOpencodeSession:()=>{D&&oe(D)},sessionStates:se,busy:R,getSessionDisplay:e=>{var a,t,r,o;return{...e,state:((a=se[e.id])==null?void 0:a.state)??"idle",unread:((t=se[e.id])==null?void 0:t.unread)??0,pinned:((r=se[e.id])==null?void 0:r.pinned)??!1,tree:(o=se[e.id])==null?void 0:o.tree}},stickToBottom:de,newMessageCount:Se,handleScroll:Oe,jumpToLatest:Te,setToast:Ie,loadChat:K,loadTaskChat:ae,refreshSessions:ie,refreshOpencodeSessions:re,loadOpencodeSession:oe,closeOpencodeSession:te,selectBizarSession:ve,onCreateSession:Ne,onSend:Re,onRegenerate:De,deleteMessage:$e,togglePin:Ee,copyMessage:ze,renameSession:Me,deleteSession:_e,seenOpencodeMessages:ke}}const cs=[{cmd:"/visual-plan [on|off|status]",desc:"Toggle or view visual plan mode"},{cmd:"/plan new <slug> [template]",desc:"Create a new plan"},{cmd:"/plan list",desc:"List all plans"},{cmd:"/plan open <slug>",desc:"Open a plan in the viewer"},{cmd:"/plan status <slug> <status>",desc:"Set plan status"},{cmd:"/plan get <slug>",desc:"Fetch plan canvas"},{cmd:"/plan add <slug> --title T --type kind",desc:"Add element to a plan"},{cmd:"/plan update <slug> <id>",desc:"Update a plan element"},{cmd:"/plan delete <slug> <id>",desc:"Delete a plan element"},{cmd:'/plan comment <slug> [id] "text"',desc:"Add a comment"},{cmd:"/plan comments <slug> [id]",desc:"Read plan comments"},{cmd:"/bizar",desc:"Launch Bizar dashboard"},{cmd:"/bizar <args>",desc:"Route via Bizar menu"},{cmd:"/audit",desc:"Run security audit"},{cmd:"/explain <q>",desc:"Read-only code Q&A"},{cmd:"/init",desc:"Initialize .bizar/ in this project"},{cmd:"/learn",desc:"Extract patterns from session"},{cmd:"/pr-review",desc:"PR review"},{cmd:"/help | /commands",desc:"Show all Bizar commands"}];function gs(i){const[f,h]=n.useState(""),l=n.useMemo(()=>[...cs,...(i.mods||[]).flatMap(x=>{var g;return(g=x.entry)!=null&&g.command?[{cmd:`/${x.id}`,desc:x.description||x.name,mod:x.id}]:[]})],[i.mods]),d=n.useMemo(()=>{if(!f.startsWith("/")||f.includes(" "))return[];const x=f.toLowerCase();return l.filter(g=>g.cmd.toLowerCase().startsWith(x)).slice(0,6)},[f,l]);return{allCommands:l,suggestions:d,setQuery:h}}export{hs as C,ss as V,gs as a,ms as b,ps as c,fs as u};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/mobile-layout-DKh7Pn9-.js","assets/react-vendor-Dn4wqh4Z.js","assets/icons-Cr5zfF_4.js","assets/mobile-layout-CJnZNLy3.css"])))=>i.map(i=>d[i]);
2
+ import{r as n,j as s}from"./react-vendor-Dn4wqh4Z.js";import{b as Le,d as xe,bk as Ae,aO as Be,bl as Ue,bm as Pe,aE as Fe,R as We,bn as Ge,$ as qe,B as He,bo as be,X as Ke,i as Ve,V as Ye}from"./icons-Cr5zfF_4.js";import{b as Qe,e as Je,a as T,A as le,_ as Xe}from"./mobile-layout-DKh7Pn9-.js";import{M as Ze,r as es}from"./markdown-C6mXtQxD.js";function ss({items:i,renderItem:f,itemHeight:h=80,height:l=400,overscan:d=5,className:x}){const[g,S]=n.useState(0),j=n.useRef(null),E=n.useMemo(()=>{const C=Math.max(0,Math.floor(g/h)-d),I=Math.min(i.length,Math.ceil((g+l)/h)+d);return{start:C,end:I}},[g,h,l,d,i.length]),M=i.length*h,R=E.start*h,$=i.slice(E.start,E.end);return s.jsx("div",{ref:j,onScroll:C=>S(C.currentTarget.scrollTop),style:{height:l,overflowY:"auto"},className:x,children:s.jsx("div",{style:{height:M,position:"relative"},children:s.jsx("div",{style:{transform:`translateY(${R}px)`},children:$.map((C,I)=>s.jsx("div",{style:{height:h},children:f(C,E.start+I)},E.start+I))})})})}function ms({activeProject:i,sessionCount:f,sessionsOpen:h,infoOpen:l,onToggleSessions:d,onToggleInfo:x,onOpenOverview:g}){return s.jsxs("header",{className:"chat-topbar",children:[s.jsxs("button",{type:"button",className:"chat-topbar-project",onClick:g,children:[s.jsx(Le,{size:14}),s.jsx("span",{className:"chat-topbar-project-name",children:(i==null?void 0:i.name)??"No project"}),s.jsx(xe,{size:12})]}),s.jsx("div",{className:"chat-topbar-spacer"}),s.jsxs("button",{type:"button",className:`chat-topbar-btn ${h?"active":""}`,onClick:d,"aria-pressed":h,children:["Sessions (",f,")"]}),s.jsx("button",{type:"button",className:`chat-topbar-btn ${l?"active":""}`,onClick:x,"aria-pressed":l,children:"Info"})]})}function ts({count:i=3}){return s.jsx("div",{className:"chat-loading-skeleton","aria-label":"Loading messages",children:Array.from({length:i}).map((f,h)=>s.jsxs("div",{className:"chat-loading-skeleton-bubble",children:[s.jsx("div",{className:"chat-loading-skeleton-meta"}),s.jsx("div",{className:"chat-loading-skeleton-line"}),s.jsx("div",{className:"chat-loading-skeleton-line short"})]},h))})}function ns({projectName:i,onPickSuggestion:f}){const h=[{icon:s.jsx(Ae,{size:16}),title:i?`Explain ${i}`:"Explain this project",preview:"Give me a tour of the codebase, highlight the architecture, and call out any anti-patterns or hotspots.",prompt:i?`Explain the ${i} project. Give me a tour of the codebase, highlight the architecture, and call out any anti-patterns or hotspots.`:"Explain the current project. Give me a tour of the codebase, highlight the architecture, and call out any anti-patterns or hotspots."},{icon:s.jsx(Be,{size:16}),title:"Summarize recent sessions",preview:"Read my last 5 chat sessions and give me a 3-bullet summary of what I worked on and what got stuck.",prompt:"Read my last 5 chat sessions and give me a 3-bullet summary of what I worked on and what got stuck."},{icon:s.jsx(Ue,{size:16}),title:"Suggest a refactor",preview:"Look for the largest, most painful files in this project and propose a concrete refactor for the worst one.",prompt:"Look for the largest, most painful files in this project and propose a concrete refactor for the worst one."},{icon:s.jsx(Pe,{size:16}),title:"Find visual regressions",preview:"Open the dashboard, screenshot the Chat tab, and flag any layout problems or anti-patterns you see.",prompt:"Open the dashboard, screenshot the Chat tab, and flag any layout problems or anti-patterns you see."}];return s.jsx("div",{className:"chat-suggestions",children:h.map((l,d)=>s.jsxs("button",{type:"button",className:"chat-suggestion",onClick:()=>f(l.prompt),children:[s.jsxs("div",{className:"chat-suggestion-title",children:[l.icon,s.jsx("span",{children:l.title})]}),s.jsx("div",{className:"chat-suggestion-preview",children:l.preview})]},d))})}function ye({variant:i,projectName:f,onPickSuggestion:h}){if(i==="no-project")return s.jsxs("div",{className:"chat-welcome",children:[s.jsx("h1",{className:"chat-welcome-h1",children:s.jsx("span",{className:"chat-greeting-hello",children:"No project selected."})}),s.jsx("p",{className:"chat-welcome-subtitle",children:"Pick a project in Overview to scope chat sessions."})]});const l=f||"there";return s.jsxs("div",{className:"chat-welcome",children:[s.jsxs("h1",{className:"chat-welcome-h1",children:[s.jsx("span",{className:"chat-greeting-hello",children:"Hello, "}),s.jsxs("span",{className:"chat-greeting-name",children:[l,"."]})]}),s.jsx("p",{className:"chat-welcome-subtitle",children:"How can I help you today?"}),s.jsx(ns,{projectName:f,onPickSuggestion:h})]})}function as({message:i,pinned:f,onCopy:h,onDelete:l,onTogglePin:d,onRegenerate:x}){const g=(i.role||"assistant").toLowerCase(),S=i.ts?Qe(i.ts):"",j=i.content||i.message||"",E=g==="user";return s.jsxs("article",{className:`chat-message ${E?"chat-message-user":"chat-message-assistant"} ${f?"chat-message-pinned":""}`,children:[s.jsxs("header",{className:"chat-message-meta",children:[s.jsx("span",{className:"chat-message-role",children:g}),i.agent&&s.jsxs("span",{className:"chat-message-agent",children:["@",i.agent]}),S&&s.jsx("time",{className:"chat-message-time",children:S}),f&&s.jsx("span",{className:"chat-message-pin",children:"pinned"}),s.jsxs("div",{className:"chat-message-actions",children:[s.jsx("button",{type:"button",className:"chat-msg-action-btn",onClick:h,title:"Copy","aria-label":"Copy",children:s.jsx(Fe,{size:12})}),!E&&s.jsx("button",{type:"button",className:"chat-msg-action-btn",onClick:x,title:"Regenerate","aria-label":"Regenerate",children:s.jsx(We,{size:12})}),s.jsx("button",{type:"button",className:"chat-msg-action-btn",onClick:d,title:"Pin","aria-label":"Pin",children:s.jsx(Ge,{size:12})}),s.jsx("button",{type:"button",className:"chat-msg-action-btn chat-msg-action-btn-danger",onClick:l,title:"Delete","aria-label":"Delete",children:s.jsx(qe,{size:12})})]})]}),s.jsx("div",{className:"chat-message-content markdown-body",children:s.jsx(Ze,{remarkPlugins:[es],children:j})})]})}function ps({messages:i,loading:f,activeProject:h,sessionId:l,pinned:d,activeSource:x,onPickSuggestion:g,onCopy:S,onDelete:j,onTogglePin:E,onRegenerate:M}){const R=n.useRef(null);n.useEffect(()=>{const C=R.current;if(!C)return;let I=C.parentElement,P=!1;for(;I;){if(I.classList.contains("chat-thread-scroll")){P=!0;break}I=I.parentElement}P||(C.scrollTop=C.scrollHeight)},[i]);const $=x==="opencode"?"opencode":"bizar";return f?s.jsx("div",{className:"chat-thread legacy",ref:R,"data-stream":$,children:s.jsx(ts,{count:3})}):h?i.length===0?s.jsx("div",{className:"chat-thread legacy",ref:R,"data-stream":$,children:s.jsx(ye,{variant:"empty",projectName:h.name,onPickSuggestion:g})}):s.jsx("div",{className:"chat-thread legacy",ref:R,children:s.jsx(ss,{items:i,itemHeight:120,height:800,className:"chat-thread-virtual",renderItem:(C,I)=>s.jsx(as,{message:C,pinned:d.has(I),onCopy:()=>S(C),onDelete:()=>j(I),onTogglePin:()=>E(I),onRegenerate:()=>M(String(C.ts??I))})})}):s.jsx("div",{className:"chat-thread legacy",ref:R,"data-stream":$,children:s.jsx(ye,{variant:"no-project",projectName:"",onPickSuggestion:g})})}function rs({agent:i,setAgent:f,agents:h}){const[l,d]=n.useState(!1),x=n.useRef(null);n.useEffect(()=>{if(!l)return;const j=E=>{x.current&&!x.current.contains(E.target)&&d(!1)};return document.addEventListener("mousedown",j),()=>document.removeEventListener("mousedown",j)},[l]);const g=i||"no agent",S=g.startsWith("@")?g.slice(1):g;return s.jsxs("div",{className:"chat-agent-chip",ref:x,children:[s.jsxs("button",{type:"button",className:"chat-agent-chip-btn",onClick:()=>d(j=>!j),"aria-haspopup":"listbox","aria-expanded":l,children:[s.jsx(He,{size:14}),s.jsx("span",{children:S}),s.jsx(xe,{size:12,className:l?"rotated":""})]}),l&&s.jsxs("div",{className:"chat-agent-chip-menu",role:"listbox",children:[s.jsx("button",{type:"button",role:"option","aria-selected":!i,onClick:()=>{f(""),d(!1)},children:s.jsx("span",{children:"no agent"})}),h.map(j=>s.jsx("button",{type:"button",role:"option","aria-selected":i===j.name,onClick:()=>{f(j.name),d(!1)},children:s.jsxs("span",{children:["@",j.name]})},j.name))]})]})}function os(i,f,h=240){n.useLayoutEffect(()=>{const l=i.current;if(!l)return;l.style.height="auto";const d=Math.min(l.scrollHeight,h);l.style.height=`${d}px`,l.style.overflowY=l.scrollHeight>h?"auto":"hidden"},[i,f,h])}function hs({agent:i,setAgent:f,model:h,setModel:l,text:d,setText:x,sending:g,onSend:S,attachments:j,setAttachments:E,suggestions:M,onPickSuggestion:R,agents:$,onAttach:C}){const I=n.useRef(null),P=n.useRef(null);os(I,d,160);const F=b=>{if(b.key==="Enter"&&(b.metaKey||b.ctrlKey))b.preventDefault(),S();else if(b.key==="Enter"&&!b.shiftKey)b.preventDefault(),S();else if(b.key==="Tab"&&M.length){b.preventDefault();const D=M[0].cmd.split(" ")[0];x(`${D} `)}},W=b=>{const D=b.target.files;if(!D)return;const A=[];for(let G=0;G<D.length;G++)A.push(D[G].name);E(G=>[...G,...A]),b.target.value=""};return s.jsxs("div",{className:"chat-composer",children:[M.length>0&&s.jsx("div",{className:"chat-composer-suggestions",children:M.map(b=>s.jsxs("button",{type:"button",className:"chat-composer-suggestion",onClick:()=>{var A;const D=b.cmd.split(" ")[0];x(`${D} `),(A=I.current)==null||A.focus()},children:[s.jsx("span",{className:"mono",children:b.cmd}),s.jsx("span",{children:b.desc})]},b.cmd))}),j.length>0&&s.jsx("div",{className:"chat-composer-attachments",children:j.map((b,D)=>s.jsxs("span",{className:"chat-composer-attachment-tag",children:[s.jsx(be,{size:10})," ",b,s.jsx("button",{type:"button",className:"chat-composer-attachment-remove",onClick:()=>E(A=>A.filter((G,q)=>q!==D)),"aria-label":`Remove ${b}`,children:s.jsx(Ke,{size:10})})]},D))}),s.jsxs("div",{className:"chat-composer-input",children:[s.jsx(rs,{agent:i,setAgent:f,agents:$}),s.jsx("textarea",{ref:I,className:"chat-composer-textarea",placeholder:g?"Sending…":"Send a message…",rows:1,value:d,onChange:b=>x(b.target.value),onKeyDown:F,disabled:g,"aria-label":"Message"}),s.jsx("input",{ref:P,type:"file",multiple:!0,style:{display:"none"},onChange:W,"aria-label":"Attach files",tabIndex:-1}),s.jsx("button",{type:"button",className:"chat-attach-btn",onClick:C,title:"Attach files","aria-label":"Attach files",children:s.jsx(be,{size:14})}),s.jsx("button",{type:"button",className:"chat-attach-btn",onClick:async()=>{if(!d.trim())return;const b=await Je(d);b!==d&&x(b)},title:"Enhance prompt with AI","aria-label":"Enhance prompt",children:s.jsx(Ve,{size:14})}),s.jsx("button",{type:"button",className:"chat-send-btn",onClick:S,disabled:g||!d.trim(),title:"Send (Enter)","aria-label":"Send message",children:s.jsx(Ye,{size:16})})]})]})}function fs(i,f,h){const[l,d]=n.useState([]),[x,g]=n.useState([]),[S,j]=n.useState(""),[E,M]=n.useState(!0),[R,$]=n.useState({create:!1,send:!1,rename:!1,delete:!1}),[C,I]=n.useState([]),[P,F]=n.useState([]),[W,b]=n.useState(null),[D,A]=n.useState(null),[G,q]=n.useState(null),[je,Z]=n.useState(null),[we,ee]=n.useState(null),[se,ue]=n.useState({}),[de,me]=n.useState(!0),[Se,ce]=n.useState(0),[ke,pe]=n.useState(new Set),[Ce,he]=n.useState(new Set),Y=n.useRef(null),v=n.useRef(null),O=n.useRef(null),ne=n.useRef(0),z=n.useRef(null),Q=n.useRef(null),V=n.useRef(!1),J=n.useCallback(e=>{e&&F(a=>{if(e.id&&a.some(r=>r.id===e.id))return a;const t=a.findIndex(r=>typeof r.id=="string"&&r.id.startsWith("msg_")&&r.role===e.role&&(r.content||"")===(e.content||""));if(t>=0){const r=a.slice();return r[t]={...e,id:e.id??a[t].id},r}return[...a,e]})},[]),X=n.useCallback(e=>{e&&pe(a=>{if(a.has(e))return a;const t=new Set(a);return t.add(e),t})},[]),H=n.useCallback((e,a)=>{ue(t=>{const r=t[e]??{state:"idle",unread:0,pinned:!1};return{...t,[e]:{...r,...a}}})},[]),B=n.useCallback((e,a)=>{H(e,{state:a?"streaming":"idle"})},[H]),Ie=n.useCallback(e=>{v.current=e},[]),K=n.useCallback(async e=>{var a;try{const t=e?`/chat?session=${encodeURIComponent(e)}`:"/chat?limit=200",r=await T.get(t);d(r.messages||[]),g(r.sessions||[])}catch(t){(a=v.current)==null||a.error(`Chat load failed: ${t.message}`)}finally{M(!1)}},[]),ae=n.useCallback(async e=>{var a;M(!0);try{const t=await T.get(`/tasks/${encodeURIComponent(e)}/chat`);d(t.messages||[]),j(t.sessionId||e)}catch(t){(a=v.current)==null||a.error(`Task chat load failed: ${t.message}`)}finally{M(!1)}},[]),ie=n.useCallback(async()=>{try{const e=await T.get("/chat/sessions");g(e.sessions||[])}catch{}},[]),re=n.useCallback(async()=>{try{const a=((await T.get("/opencode-sessions")).sessions||[]).map(t=>({...t,source:"opencode",title:t.title||t.id}));I(a)}catch{}},[]),fe=n.useCallback(e=>{if(O.current){try{O.current.close()}catch{}O.current=null}z.current!==null&&(clearTimeout(z.current),z.current=null);const a=T.getToken(),t=a?`/api/opencode-sessions/${encodeURIComponent(e)}/stream?token=${encodeURIComponent(a)}`:`/api/opencode-sessions/${encodeURIComponent(e)}/stream`;Q.current=e,V.current=!0,ne.current=0,q(null),Z(null),ee(null);const r=()=>{if(!V.current||Q.current!==e)return;const o=new EventSource(t);O.current=o;const p=c=>{var w,_,L,U;if(!c||!c.type||c.sessionID&&c.sessionID!==e)return;const m=new Date().toISOString(),y=e;if(c.type==="message.user.created"||c.type==="message.user.updated"){const u=c.data;J({id:(u==null?void 0:u.messageID)??c.messageID,role:"user",content:((w=u==null?void 0:u.data)==null?void 0:w.content)??"",ts:m}),X((u==null?void 0:u.messageID)??c.messageID);return}if(c.type==="message.assistant.created"||c.type==="message.assistant.updated"){const u=c.data;J({id:(u==null?void 0:u.messageID)??c.messageID,role:"assistant",content:((_=u==null?void 0:u.data)==null?void 0:_.content)??"",ts:m}),X((u==null?void 0:u.messageID)??c.messageID),B(y,!0);return}if(c.type==="message.part.updated"){const u=c.data,ge=((L=u==null?void 0:u.part)==null?void 0:L.text)??"";if(!ge)return;J({id:(u==null?void 0:u.id)??(u==null?void 0:u.messageID)??c.messageID,role:"assistant",content:ge,ts:m}),X((u==null?void 0:u.id)??(u==null?void 0:u.messageID)??c.messageID),B(y,!0);return}if(c.type==="session.idle"||c.type==="message.assistant.completed"||c.type==="session.completed"){B(y,!1);return}if(c.type==="session.awaiting"||c.type==="session.awaiting_input"||c.type==="message.assistant.awaiting"){H(y,{state:"awaiting"});return}if(c.type==="session.error"){q(((U=c.data)==null?void 0:U.message)||"opencode session error");return}},k=c=>{if(!c)return null;try{const m=JSON.parse(c);if(typeof m.type=="string"){const y=m.properties,w=m.data??y,_=typeof m.sessionID=="string"?m.sessionID:typeof(y==null?void 0:y.sessionID)=="string"?y.sessionID:typeof(w==null?void 0:w.sessionID)=="string"?w.sessionID:void 0,L=typeof m.messageID=="string"?m.messageID:typeof(y==null?void 0:y.messageID)=="string"?y.messageID:typeof(w==null?void 0:w.messageID)=="string"?w.messageID:void 0;let U=m.type;const u=/\.\d+$/.exec(U);return u&&(U=U.slice(0,u.index)),{type:U,sessionID:_,messageID:L,data:m}}if(m.type==="sync"&&m.syncEvent&&typeof m.syncEvent=="object"){const y=m.syncEvent;let w=y.type||"";const _=/\.\d+$/.exec(w);_&&(w=w.slice(0,_.index));const L=y.data||{};return{type:w,sessionID:typeof L.sessionID=="string"?L.sessionID:void 0,messageID:typeof L.messageID=="string"?L.messageID:void 0,data:y}}return null}catch{return null}},N=["message.user.created","message.user.updated","message.assistant.created","message.assistant.updated","message.part.updated","session.idle","message.assistant.completed","session.completed","session.awaiting","session.awaiting_input","message.assistant.awaiting","session.error"];for(const c of N)o.addEventListener(c,m=>{p(k(m.data))});o.onerror=()=>{if(Q.current!==e)return;if(!V.current){try{o.close()}catch{}O.current=null;return}try{o.close()}catch{}O.current=null;const c=ne.current+1;ne.current=c;const m=Math.min(3e4,1e3*2**(c-1));z.current!==null&&clearTimeout(z.current),z.current=window.setTimeout(()=>{z.current=null,V.current&&Q.current===e&&r()},m)},o.onopen=()=>{ne.current=0,q(null),Z(null),ee(null)}};r()},[J,X,B,H]),te=n.useCallback(()=>{if(V.current=!1,Q.current=null,z.current!==null&&(clearTimeout(z.current),z.current=null),O.current){try{O.current.close()}catch{}O.current=null}F([]),pe(new Set),q(null),Z(null),ee(null),A(null),b("bizar")},[]),oe=n.useCallback(async e=>{var a;if(V.current=!1,O.current){try{O.current.close()}catch{}O.current=null}z.current!==null&&(clearTimeout(z.current),z.current=null),q(null),Z(null),ee(null),M(!0);try{const t=await T.get(`/opencode-sessions/${encodeURIComponent(e)}/messages`);F(t.messages||[])}catch(t){const r=t.message;let o=null;if(t instanceof le&&t.data&&typeof t.data=="object"){const p=t.data,k=p.error||"unknown",N=k!=="bad_request"&&k!=="too_many_subscribers"&&k!=="unauthorized";o={type:"session_load_failed",code:k,message:p.message||r,cause:p.cause,status:p.status,suggestion:p.suggestion??null,canRetry:N}}else t instanceof le&&(o={type:"session_load_failed",code:"unknown",message:r,suggestion:null,canRetry:!0});q(o?`Opencode session load failed (${o.code}): ${o.message}`:`Opencode session load failed: ${r}`),Z((o==null?void 0:o.suggestion)??null),ee(o),(a=v.current)==null||a.error(o?`Opencode session load failed: ${o.message}`:`Opencode session load failed: ${r}`),F([])}finally{M(!1)}A(e),b("opencode"),B(e,!1),fe(e)},[B,fe]),ve=n.useCallback(e=>{te(),j(e),b("bizar"),K(e),H(e,{unread:0})},[te,K,H]),Ne=n.useCallback(async()=>{var a,t,r,o,p;if(R.create)return{ok:!1};const e=f.defaultAgent||"odin";$(k=>({...k,create:!0}));try{try{const N=await T.post("/opencode-sessions/new",{agent:e});return await re(),await oe(N.id),(a=v.current)==null||a.success(`Session ${N.id} created.`),{ok:!0,source:"opencode",id:N.id}}catch(N){if(!(N instanceof le)||N.status!==503)return(t=v.current)==null||t.error(`Create failed: ${N.message}`),{ok:!1}}if(!i.activeProject)return(r=v.current)==null||r.error("Pick a project in Overview to scope chat sessions."),{ok:!1};const k=await T.post("/chat/sessions",{});return j(k.id),d([]),he(new Set),H(k.id,{state:"idle",unread:0}),await K(k.id),ie().catch(()=>{}),(o=v.current)==null||o.success(`Session ${k.id} created.`),{ok:!0,source:"bizar",id:k.id}}catch(k){return(p=v.current)==null||p.error(`Create failed: ${k.message}`),{ok:!1}}finally{$(k=>({...k,create:!1}))}},[R.create,f.defaultAgent,i.activeProject,re,oe,K,ie,H]),Re=n.useCallback(async(e,a,t,r)=>{var k,N,c;if(R.send)return{ok:!1};const o=e.trim();if(!o)return{ok:!1};if(W==="opencode"&&D){const m=D,y=`msg_${Date.now().toString(36)}${Math.random().toString(36).slice(2,8)}`,w={id:y,role:"user",content:o,agent:a,ts:new Date().toISOString()};J(w),X(y),$(_=>({..._,send:!0}));try{return await T.post(`/opencode-sessions/${encodeURIComponent(m)}/send`,{message:o,agent:a}),B(m,!0),{ok:!0}}catch(_){return F(L=>L.filter(U=>U.id!==y)),(k=v.current)==null||k.error(`Send failed: ${_.message}`),{ok:!1}}finally{$(_=>({..._,send:!1}))}}const p={role:"user",content:o,agent:a,ts:new Date().toISOString()};d(m=>[...m,p]),$(m=>({...m,send:!0})),B(S,!0);try{const m=await T.post("/chat",{message:o,agent:a,model:t,attachments:r||[]});if(m!=null&&m.messages)for(const y of m.messages)y.role==="assistant"&&d(w=>w.some(L=>L.ts===y.ts)?w:[...w,y]);else(N=v.current)==null||N.info("Still processing… the response will appear shortly.");return{ok:!0}}catch(m){return d(y=>y.filter(w=>w!==p)),(c=v.current)==null||c.error(`Send failed: ${m.message}`),{ok:!1}}finally{$(m=>({...m,send:!1})),B(S,!1)}},[W,D,J,X,B,S,R.send]),De=n.useCallback(async e=>{var a,t;if(!S){(a=v.current)==null||a.error("No active session to regenerate.");return}try{await T.post("/chat/regenerate",{sessionId:S,messageId:e}),await K(S)}catch(r){(t=v.current)==null||t.error(`Regenerate failed: ${r.message}`)}},[S,K]),$e=n.useCallback(e=>{W==="opencode"?F(a=>a.filter((t,r)=>r!==e)):d(a=>a.filter((t,r)=>r!==e))},[W]),Ee=n.useCallback(e=>{he(a=>{const t=new Set(a);return t.has(e)?t.delete(e):t.add(e),t})},[]),ze=n.useCallback(e=>{var t,r;const a=e.content||e.message||"";try{(t=navigator.clipboard)==null||t.writeText(a).then(()=>{var o;return(o=v.current)==null?void 0:o.success("Copied.")},()=>{var o;return(o=v.current)==null?void 0:o.error("Copy failed.")})}catch{(r=v.current)==null||r.error("Copy failed.")}},[]),Oe=n.useCallback(()=>{const e=Y.current;if(!e)return;const t=e.scrollHeight-e.scrollTop-e.clientHeight<32;me(t),t&&ce(0)},[]),Te=n.useCallback(()=>{const e=Y.current;e&&(e.scrollTop=e.scrollHeight,me(!0),ce(0))},[]),Me=n.useCallback(async(e,a)=>{var t,r,o;if(R.rename)return!1;$(p=>({...p,rename:!0}));try{const p=a.trim();return p?(C.some(N=>N.id===e)?(await T.patch(`/opencode-sessions/${encodeURIComponent(e)}`,{title:p}),I(N=>N.map(c=>c.id===e?{...c,title:p}:c))):(await T.post(`/chat/sessions/${encodeURIComponent(e)}/rename`,{title:p}),g(N=>N.map(c=>c.id===e?{...c,title:p}:c))),(r=v.current)==null||r.success("Renamed."),!0):((t=v.current)==null||t.error("Title cannot be empty."),!1)}catch(p){return(o=v.current)==null||o.error(`Rename failed: ${p.message}`),!1}finally{$(p=>({...p,rename:!1}))}},[R.rename,C]),_e=n.useCallback(async e=>{var a,t;if(R.delete)return!1;$(r=>({...r,delete:!0}));try{return C.some(o=>o.id===e)?(await T.del(`/opencode-sessions/${encodeURIComponent(e)}`),I(o=>o.filter(p=>p.id!==e)),D===e&&te()):(await T.del(`/chat/sessions/${encodeURIComponent(e)}`),g(o=>o.filter(p=>p.id!==e)),S===e&&(j(""),d([]))),ue(o=>{const p={...o};return delete p[e],p}),(a=v.current)==null||a.success("Session deleted."),!0}catch(r){return(t=v.current)==null||t.error(`Delete failed: ${r.message}`),!1}finally{$(r=>({...r,delete:!1}))}},[R.delete,C,D,te,S]);return n.useEffect(()=>{Y.current&&(de?Y.current.scrollTop=Y.current.scrollHeight:ce(e=>e+1))},[l,P]),n.useEffect(()=>()=>{if(V.current=!1,Q.current=null,z.current!==null&&(clearTimeout(z.current),z.current=null),O.current){try{O.current.close()}catch{}O.current=null}},[]),n.useEffect(()=>{h?ae(h):K(),re()},[]),n.useEffect(()=>{const e=a=>{var r;const t=(r=a.detail)==null?void 0:r.taskId;t&&ae(t)};return window.addEventListener("bizar:setChatTask",e),()=>window.removeEventListener("bizar:setChatTask",e)},[ae]),n.useEffect(()=>{let e=!1;return Xe(async()=>{const{Ws:a}=await import("./mobile-layout-DKh7Pn9-.js").then(t=>t.w);return{Ws:a}},__vite__mapDeps([0,1,2,3])).then(({Ws:a})=>{if(e)return;new a().on(r=>{if(r.type!=="chat:message")return;const o=r.message;o&&d(p=>p.some(N=>N.ts===o.ts)?p:[...p,o])})}),()=>{e=!0}},[]),{messages:W==="opencode"?P:l,bizarMessages:l,opencodeMessages:P,sessions:x,opencodeSessions:C,sessionId:S,setSessionId:j,loading:E,sending:R.send,pinned:Ce,listRef:Y,activeSource:W,activeOpencodeSessionId:D,opencodeError:G,opencodeSuggestion:je,opencodeErrorInfo:we,retryOpencodeSession:()=>{D&&oe(D)},sessionStates:se,busy:R,getSessionDisplay:e=>{var a,t,r,o;return{...e,state:((a=se[e.id])==null?void 0:a.state)??"idle",unread:((t=se[e.id])==null?void 0:t.unread)??0,pinned:((r=se[e.id])==null?void 0:r.pinned)??!1,tree:(o=se[e.id])==null?void 0:o.tree}},stickToBottom:de,newMessageCount:Se,handleScroll:Oe,jumpToLatest:Te,setToast:Ie,loadChat:K,loadTaskChat:ae,refreshSessions:ie,refreshOpencodeSessions:re,loadOpencodeSession:oe,closeOpencodeSession:te,selectBizarSession:ve,onCreateSession:Ne,onSend:Re,onRegenerate:De,deleteMessage:$e,togglePin:Ee,copyMessage:ze,renameSession:Me,deleteSession:_e,seenOpencodeMessages:ke}}const cs=[{cmd:"/visual-plan [on|off|status]",desc:"Toggle or view visual plan mode"},{cmd:"/plan new <slug> [template]",desc:"Create a new plan"},{cmd:"/plan list",desc:"List all plans"},{cmd:"/plan open <slug>",desc:"Open a plan in the viewer"},{cmd:"/plan status <slug> <status>",desc:"Set plan status"},{cmd:"/plan get <slug>",desc:"Fetch plan canvas"},{cmd:"/plan add <slug> --title T --type kind",desc:"Add element to a plan"},{cmd:"/plan update <slug> <id>",desc:"Update a plan element"},{cmd:"/plan delete <slug> <id>",desc:"Delete a plan element"},{cmd:'/plan comment <slug> [id] "text"',desc:"Add a comment"},{cmd:"/plan comments <slug> [id]",desc:"Read plan comments"},{cmd:"/bizar",desc:"Launch Bizar dashboard"},{cmd:"/bizar <args>",desc:"Route via Bizar menu"},{cmd:"/audit",desc:"Run security audit"},{cmd:"/explain <q>",desc:"Read-only code Q&A"},{cmd:"/init",desc:"Initialize .bizar/ in this project"},{cmd:"/learn",desc:"Extract patterns from session"},{cmd:"/pr-review",desc:"PR review"},{cmd:"/help | /commands",desc:"Show all Bizar commands"}];function gs(i){const[f,h]=n.useState(""),l=n.useMemo(()=>[...cs,...(i.mods||[]).flatMap(x=>{var g;return(g=x.entry)!=null&&g.command?[{cmd:`/${x.id}`,desc:x.description||x.name,mod:x.id}]:[]})],[i.mods]),d=n.useMemo(()=>{if(!f.startsWith("/")||f.includes(" "))return[];const x=f.toLowerCase();return l.filter(g=>g.cmd.toLowerCase().startsWith(x)).slice(0,6)},[f,l]);return{allCommands:l,suggestions:d,setQuery:h}}export{hs as C,ss as V,gs as a,ms as b,ps as c,fs as u};