@cosmicstack/mercury-agent 1.1.9 → 1.1.11

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 (114) hide show
  1. package/README.md +101 -1
  2. package/README.zh-CN.md +265 -140
  3. package/dist/index.js +4442 -1838
  4. package/dist/index.js.map +1 -1
  5. package/dist/web/ui/assets/{Chat-DCFkzIwn.js → Chat-DXSn2dY8.js} +2 -2
  6. package/dist/web/ui/assets/{Chat-DCFkzIwn.js.map → Chat-DXSn2dY8.js.map} +1 -1
  7. package/dist/web/ui/assets/{Dashboard-B81ollv8.js → Dashboard-1rlAqQ-Y.js} +2 -2
  8. package/dist/web/ui/assets/{Dashboard-B81ollv8.js.map → Dashboard-1rlAqQ-Y.js.map} +1 -1
  9. package/dist/web/ui/assets/{Goals-D0cR8yIP.js → Goals-CgSUAXLH.js} +2 -2
  10. package/dist/web/ui/assets/{Goals-D0cR8yIP.js.map → Goals-CgSUAXLH.js.map} +1 -1
  11. package/dist/web/ui/assets/{Graph-C3eHp3_J.js → Graph-DnlOWkay.js} +2 -2
  12. package/dist/web/ui/assets/{Graph-C3eHp3_J.js.map → Graph-DnlOWkay.js.map} +1 -1
  13. package/dist/web/ui/assets/{Kanban-DrkTRyni.js → Kanban-DRlNiNRF.js} +2 -2
  14. package/dist/web/ui/assets/{Kanban-DrkTRyni.js.map → Kanban-DRlNiNRF.js.map} +1 -1
  15. package/dist/web/ui/assets/{Login-GRQ-LjgN.js → Login-BP5524pC.js} +2 -2
  16. package/dist/web/ui/assets/{Login-GRQ-LjgN.js.map → Login-BP5524pC.js.map} +1 -1
  17. package/dist/web/ui/assets/{MarkdownRenderer-Dvh1jwyj.js → MarkdownRenderer-B9KGVD0X.js} +2 -2
  18. package/dist/web/ui/assets/{MarkdownRenderer-Dvh1jwyj.js.map → MarkdownRenderer-B9KGVD0X.js.map} +1 -1
  19. package/dist/web/ui/assets/{Memory-dAZsKmWz.js → Memory-BOQEY0H8.js} +2 -2
  20. package/dist/web/ui/assets/{Memory-dAZsKmWz.js.map → Memory-BOQEY0H8.js.map} +1 -1
  21. package/dist/web/ui/assets/{Permissions-DCiyUUfI.js → Permissions-jbFH-toa.js} +2 -2
  22. package/dist/web/ui/assets/{Permissions-DCiyUUfI.js.map → Permissions-jbFH-toa.js.map} +1 -1
  23. package/dist/web/ui/assets/{PersonDetail-iZgApJog.js → PersonDetail-Ca8B9io8.js} +2 -2
  24. package/dist/web/ui/assets/{PersonDetail-iZgApJog.js.map → PersonDetail-Ca8B9io8.js.map} +1 -1
  25. package/dist/web/ui/assets/{Persons-Bs_HhYjC.js → Persons-epdmUeBM.js} +2 -2
  26. package/dist/web/ui/assets/{Persons-Bs_HhYjC.js.map → Persons-epdmUeBM.js.map} +1 -1
  27. package/dist/web/ui/assets/{Providers-CL6wMWni.js → Providers-Bm8sZNZo.js} +2 -2
  28. package/dist/web/ui/assets/{Providers-CL6wMWni.js.map → Providers-Bm8sZNZo.js.map} +1 -1
  29. package/dist/web/ui/assets/{Schedules-BQwE1hP5.js → Schedules-BZKhm9R7.js} +2 -2
  30. package/dist/web/ui/assets/{Schedules-BQwE1hP5.js.map → Schedules-BZKhm9R7.js.map} +1 -1
  31. package/dist/web/ui/assets/{Settings-26SF-okR.js → Settings-Hii-5oku.js} +2 -2
  32. package/dist/web/ui/assets/{Settings-26SF-okR.js.map → Settings-Hii-5oku.js.map} +1 -1
  33. package/dist/web/ui/assets/Skills-BHJp2CgD.js +17 -0
  34. package/dist/web/ui/assets/Skills-BHJp2CgD.js.map +1 -0
  35. package/dist/web/ui/assets/{Tasks-DbwRozzx.js → Tasks-D36pqkro.js} +2 -2
  36. package/dist/web/ui/assets/{Tasks-DbwRozzx.js.map → Tasks-D36pqkro.js.map} +1 -1
  37. package/dist/web/ui/assets/{Usage-i_q6Ri4s.js → Usage-CmjaYrsT.js} +2 -2
  38. package/dist/web/ui/assets/{Usage-i_q6Ri4s.js.map → Usage-CmjaYrsT.js.map} +1 -1
  39. package/dist/web/ui/assets/{Workspace-ZR5syf-9.js → Workspace-BYLf-wTJ.js} +2 -2
  40. package/dist/web/ui/assets/{Workspace-ZR5syf-9.js.map → Workspace-BYLf-wTJ.js.map} +1 -1
  41. package/dist/web/ui/assets/{activity-CIP1IzSg.js → activity-MOTqH8zM.js} +2 -2
  42. package/dist/web/ui/assets/{activity-CIP1IzSg.js.map → activity-MOTqH8zM.js.map} +1 -1
  43. package/dist/web/ui/assets/{alert-dialog-CW-j2nG4.js → alert-dialog-MbYSbZx5.js} +2 -2
  44. package/dist/web/ui/assets/{alert-dialog-CW-j2nG4.js.map → alert-dialog-MbYSbZx5.js.map} +1 -1
  45. package/dist/web/ui/assets/{arrow-left-D2YO-iMS.js → arrow-left-CtqQsBC6.js} +2 -2
  46. package/dist/web/ui/assets/{arrow-left-D2YO-iMS.js.map → arrow-left-CtqQsBC6.js.map} +1 -1
  47. package/dist/web/ui/assets/{avatar-BLsf3GhK.js → avatar-BIYaY7pR.js} +2 -2
  48. package/dist/web/ui/assets/{avatar-BLsf3GhK.js.map → avatar-BIYaY7pR.js.map} +1 -1
  49. package/dist/web/ui/assets/{badge-DfDJNUtd.js → badge-CUJiWF1y.js} +2 -2
  50. package/dist/web/ui/assets/{badge-DfDJNUtd.js.map → badge-CUJiWF1y.js.map} +1 -1
  51. package/dist/web/ui/assets/{button-TaFPR-zy.js → button-CNasMlFE.js} +2 -2
  52. package/dist/web/ui/assets/{button-TaFPR-zy.js.map → button-CNasMlFE.js.map} +1 -1
  53. package/dist/web/ui/assets/{card-DAYo4Zl5.js → card-BdsEOP7t.js} +2 -2
  54. package/dist/web/ui/assets/{card-DAYo4Zl5.js.map → card-BdsEOP7t.js.map} +1 -1
  55. package/dist/web/ui/assets/{chevron-down-CQi0yuay.js → chevron-down-CB9J_vvZ.js} +2 -2
  56. package/dist/web/ui/assets/{chevron-down-CQi0yuay.js.map → chevron-down-CB9J_vvZ.js.map} +1 -1
  57. package/dist/web/ui/assets/{circle-check-DweDcOkA.js → circle-check-DvGSe1uZ.js} +2 -2
  58. package/dist/web/ui/assets/{circle-check-DweDcOkA.js.map → circle-check-DvGSe1uZ.js.map} +1 -1
  59. package/dist/web/ui/assets/{circle-x-BmL20etA.js → circle-x-CyaGJ_BM.js} +2 -2
  60. package/dist/web/ui/assets/{circle-x-BmL20etA.js.map → circle-x-CyaGJ_BM.js.map} +1 -1
  61. package/dist/web/ui/assets/{dialog-DovgkMhT.js → dialog-Bd1rELXb.js} +2 -2
  62. package/dist/web/ui/assets/{dialog-DovgkMhT.js.map → dialog-Bd1rELXb.js.map} +1 -1
  63. package/dist/web/ui/assets/{download-_QBatDio.js → download-C8RvlFqO.js} +2 -2
  64. package/dist/web/ui/assets/{download-_QBatDio.js.map → download-C8RvlFqO.js.map} +1 -1
  65. package/dist/web/ui/assets/{eye-Wpgtfmgw.js → eye-BJ0NucMz.js} +2 -2
  66. package/dist/web/ui/assets/{eye-Wpgtfmgw.js.map → eye-BJ0NucMz.js.map} +1 -1
  67. package/dist/web/ui/assets/{file-text-2EGFNyc1.js → file-text-BWWBuD_N.js} +2 -2
  68. package/dist/web/ui/assets/{file-text-2EGFNyc1.js.map → file-text-BWWBuD_N.js.map} +1 -1
  69. package/dist/web/ui/assets/{folder-open-C-OiZn9P.js → folder-open-BwjemFy7.js} +2 -2
  70. package/dist/web/ui/assets/{folder-open-C-OiZn9P.js.map → folder-open-BwjemFy7.js.map} +1 -1
  71. package/dist/web/ui/assets/{git-branch-BT9gCKgG.js → git-branch-D9JVASpC.js} +2 -2
  72. package/dist/web/ui/assets/{git-branch-BT9gCKgG.js.map → git-branch-D9JVASpC.js.map} +1 -1
  73. package/dist/web/ui/assets/{index-BhxU0YlT.js → index-C3YiF4qv.js} +6 -6
  74. package/dist/web/ui/assets/index-C3YiF4qv.js.map +1 -0
  75. package/dist/web/ui/assets/{index-CUT6Fr2C.js → index-CaqLZNof.js} +2 -2
  76. package/dist/web/ui/assets/{index-CUT6Fr2C.js.map → index-CaqLZNof.js.map} +1 -1
  77. package/dist/web/ui/assets/index-CuhiuVab.css +1 -0
  78. package/dist/web/ui/assets/{input-L1uz5xAQ.js → input-CH3dmo9r.js} +2 -2
  79. package/dist/web/ui/assets/{input-L1uz5xAQ.js.map → input-CH3dmo9r.js.map} +1 -1
  80. package/dist/web/ui/assets/{loader-circle-BTFgt3hG.js → loader-circle-DbYKk0_Q.js} +2 -2
  81. package/dist/web/ui/assets/{loader-circle-BTFgt3hG.js.map → loader-circle-DbYKk0_Q.js.map} +1 -1
  82. package/dist/web/ui/assets/{pencil-uxK07iYy.js → pencil-gNDEMhav.js} +2 -2
  83. package/dist/web/ui/assets/{pencil-uxK07iYy.js.map → pencil-gNDEMhav.js.map} +1 -1
  84. package/dist/web/ui/assets/{plus-DcWFYr4m.js → plus-7rbHkByr.js} +2 -2
  85. package/dist/web/ui/assets/{plus-DcWFYr4m.js.map → plus-7rbHkByr.js.map} +1 -1
  86. package/dist/web/ui/assets/{power-DVIqVIMj.js → power-BS7gCDWs.js} +2 -2
  87. package/dist/web/ui/assets/{power-DVIqVIMj.js.map → power-BS7gCDWs.js.map} +1 -1
  88. package/dist/web/ui/assets/{progress-DMwOdxli.js → progress-ZzhsBV2v.js} +2 -2
  89. package/dist/web/ui/assets/{progress-DMwOdxli.js.map → progress-ZzhsBV2v.js.map} +1 -1
  90. package/dist/web/ui/assets/{search-D1OOxb1X.js → search-BZsbhO0B.js} +2 -2
  91. package/dist/web/ui/assets/{search-D1OOxb1X.js.map → search-BZsbhO0B.js.map} +1 -1
  92. package/dist/web/ui/assets/{select-Dnx_bUgy.js → select-vRSgBrHz.js} +2 -2
  93. package/dist/web/ui/assets/{select-Dnx_bUgy.js.map → select-vRSgBrHz.js.map} +1 -1
  94. package/dist/web/ui/assets/{send-D4uxqmyH.js → send-BkyTIUtJ.js} +2 -2
  95. package/dist/web/ui/assets/{send-D4uxqmyH.js.map → send-BkyTIUtJ.js.map} +1 -1
  96. package/dist/web/ui/assets/{sparkles-DLSJA4xU.js → sparkles-DcP24GEL.js} +2 -2
  97. package/dist/web/ui/assets/{sparkles-DLSJA4xU.js.map → sparkles-DcP24GEL.js.map} +1 -1
  98. package/dist/web/ui/assets/{switch-CvDDbCUA.js → switch-LRN9wWy2.js} +2 -2
  99. package/dist/web/ui/assets/{switch-CvDDbCUA.js.map → switch-LRN9wWy2.js.map} +1 -1
  100. package/dist/web/ui/assets/{terminal-DI3J3W_z.js → terminal-CWG62zdD.js} +2 -2
  101. package/dist/web/ui/assets/{terminal-DI3J3W_z.js.map → terminal-CWG62zdD.js.map} +1 -1
  102. package/dist/web/ui/assets/{textarea-CXLsr8tf.js → textarea-CXh3tmJ1.js} +2 -2
  103. package/dist/web/ui/assets/{textarea-CXLsr8tf.js.map → textarea-CXh3tmJ1.js.map} +1 -1
  104. package/dist/web/ui/assets/{zap-C-0oH5gt.js → zap-BEfqVtvZ.js} +2 -2
  105. package/dist/web/ui/assets/{zap-C-0oH5gt.js.map → zap-BEfqVtvZ.js.map} +1 -1
  106. package/dist/web/ui/index.html +2 -2
  107. package/package.json +9 -4
  108. package/dist/web/ui/assets/Skills-DANyYK_d.js +0 -7
  109. package/dist/web/ui/assets/Skills-DANyYK_d.js.map +0 -1
  110. package/dist/web/ui/assets/index-BhxU0YlT.js.map +0 -1
  111. package/dist/web/ui/assets/index-DOw1nKre.css +0 -1
  112. package/dist/web/ui/sw.js.map +0 -1
  113. package/dist/web/ui/workbox-0bb07689.js +0 -3
  114. package/dist/web/ui/workbox-0bb07689.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import{j as e,m as A,A as $}from"./vendor-motion-Dwx3-JO5.js";import{r as d,j as pe,e as fe}from"./vendor-react-C7pctHW3.js";import{e as E,S as V,M as X,c as j,a as k,X as Z,g as J,u as Y,h as ge,i as be}from"./index-BhxU0YlT.js";import{B as C}from"./button-TaFPR-zy.js";import{P as ye}from"./progress-DMwOdxli.js";import{A as je,F as ve,o as we,u as y,M as Q,C as Ne,a as ke,b as Se}from"./MarkdownRenderer-Dvh1jwyj.js";import{A as Ce,a as Te,b as De,c as Me,d as Ae,e as Pe,f as Le,g as Be,T as ze}from"./alert-dialog-CW-j2nG4.js";import{P as $e}from"./plus-DcWFYr4m.js";import{L as M}from"./loader-circle-BTFgt3hG.js";import{h as Ee}from"./vendor-syntax-xZUI6Op9.js";import{B as Ie}from"./badge-DfDJNUtd.js";import{f as Oe,g as Re,h as Fe,i as ee}from"./vendor-radix-3UdfCgs_.js";import{C as Ue,a as R}from"./chevron-down-CQi0yuay.js";import{C as We,a as _e,b as qe}from"./collapsible-BU_K9n8f.js";import{C as He}from"./circle-x-BmL20etA.js";import{C as Ge}from"./circle-check-DweDcOkA.js";import{F as Ke}from"./folder-open-C-OiZn9P.js";import{Z as Ve}from"./zap-C-0oH5gt.js";import{S as Xe}from"./send-D4uxqmyH.js";import"./index-CUT6Fr2C.js";import"./vendor-markdown-DwTbvico.js";/**
1
+ import{j as e,m as A,A as $}from"./vendor-motion-Dwx3-JO5.js";import{r as d,j as pe,e as fe}from"./vendor-react-C7pctHW3.js";import{e as E,S as V,M as X,c as j,a as k,X as Z,g as J,u as Y,h as ge,i as be}from"./index-C3YiF4qv.js";import{B as C}from"./button-CNasMlFE.js";import{P as ye}from"./progress-ZzhsBV2v.js";import{A as je,F as ve,o as we,u as y,M as Q,C as Ne,a as ke,b as Se}from"./MarkdownRenderer-B9KGVD0X.js";import{A as Ce,a as Te,b as De,c as Me,d as Ae,e as Pe,f as Le,g as Be,T as ze}from"./alert-dialog-MbYSbZx5.js";import{P as $e}from"./plus-7rbHkByr.js";import{L as M}from"./loader-circle-DbYKk0_Q.js";import{h as Ee}from"./vendor-syntax-xZUI6Op9.js";import{B as Ie}from"./badge-CUJiWF1y.js";import{f as Oe,g as Re,h as Fe,i as ee}from"./vendor-radix-3UdfCgs_.js";import{C as Ue,a as R}from"./chevron-down-CB9J_vvZ.js";import{C as We,a as _e,b as qe}from"./collapsible-BU_K9n8f.js";import{C as He}from"./circle-x-CyaGJ_BM.js";import{C as Ge}from"./circle-check-DvGSe1uZ.js";import{F as Ke}from"./folder-open-BwjemFy7.js";import{Z as Ve}from"./zap-BEfqVtvZ.js";import{S as Xe}from"./send-BkyTIUtJ.js";import"./index-CaqLZNof.js";import"./vendor-markdown-DwTbvico.js";/**
2
2
  * @license lucide-react v0.511.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -25,4 +25,4 @@ import{j as e,m as A,A as $}from"./vendor-motion-Dwx3-JO5.js";import{r as d,j as
25
25
  ---
26
26
 
27
27
  `),he=new Blob([xe],{type:"text/plain"}),H=URL.createObjectURL(he),O=document.createElement("a");O.href=H,O.download=`${v.title||"conversation"}-${s.slice(0,8)}.txt`,O.click(),URL.revokeObjectURL(H)}const de=p||h,me=N>0,ue=N>0?D/N*100:0;return e.jsxs("div",{className:"flex h-full w-full overflow-hidden",children:[e.jsx("div",{className:j("hidden h-full shrink-0 border-r border-border bg-background transition-[width] duration-200 ease-in-out md:block overflow-hidden",L?"w-[240px]":"w-0 border-r-0"),children:e.jsx("div",{className:"h-full w-[240px]",children:e.jsx(G,{threads:c,activeThreadId:f,onSelect:_,onDelete:U,onNew:W,onExport:q})})}),e.jsx($,{children:L&&e.jsxs(e.Fragment,{children:[e.jsx(A.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:"fixed inset-0 z-40 bg-black/50 backdrop-blur-sm md:hidden",onClick:()=>B(!1)}),e.jsx(A.div,{initial:{x:-260},animate:{x:0},exit:{x:-260},transition:{duration:.2,ease:"easeInOut"},className:"fixed inset-y-0 left-0 z-50 w-[260px] bg-background shadow-xl md:hidden",children:e.jsx(G,{threads:c,activeThreadId:f,onSelect:s=>{_(s),B(!1)},onDelete:U,onNew:()=>{W(),B(!1)},onExport:q})})]})}),e.jsxs("div",{className:"flex min-w-0 flex-1 flex-col",children:[e.jsxs("header",{className:"flex h-12 items-center gap-2 border-b border-border bg-background/80 backdrop-blur-xl px-3",children:[e.jsx(C,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>B(!L),children:L?e.jsx(Qe,{className:"h-4 w-4"}):e.jsx(tt,{className:"h-4 w-4"})}),e.jsx("span",{className:"hidden text-sm font-bold mercury-gradient-text sm:inline",children:"Mercury"}),e.jsx("div",{className:"mx-1 h-4 w-px bg-border"}),e.jsx(dt,{currentProvider:S,currentModel:w}),e.jsx("div",{className:"flex-1"}),e.jsx(ut,{}),e.jsx("div",{className:j("h-2 w-2 rounded-full",r?"bg-emerald-500":"bg-destructive"),title:r?"Connected":"Disconnected"}),e.jsx(C,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>F(!I),children:e.jsx(Ke,{className:"h-4 w-4"})}),e.jsx(C,{variant:"ghost",size:"icon",className:"h-8 w-8 hidden md:inline-flex",onClick:()=>window.location.href="/settings",children:e.jsx(be,{className:"h-4 w-4"})})]}),e.jsxs("div",{className:"relative flex-1 min-h-0",children:[e.jsx("div",{ref:ne,onScroll:ie,className:"h-full overflow-y-auto",children:e.jsx("div",{className:"mx-auto max-w-3xl space-y-4 px-4 py-6",children:a&&o.length===0?e.jsx("div",{className:"flex flex-col items-center justify-center py-24",children:e.jsx(M,{className:"h-6 w-6 animate-spin text-primary"})}):o.length===0&&!p&&!h?e.jsxs("div",{className:"flex flex-col items-center justify-center gap-3 py-24 text-center",children:[e.jsx("div",{className:"rounded-2xl bg-primary/10 p-4",children:e.jsx(X,{className:"h-8 w-8 text-primary"})}),e.jsx("h3",{className:"text-lg font-semibold text-foreground",children:"Start a conversation"}),e.jsx("p",{className:"max-w-sm text-sm text-muted-foreground",children:"Send a message to begin. Mercury is ready to assist you."})]}):e.jsxs(e.Fragment,{children:[o.map(s=>{if(s.role==="system")try{const v=JSON.parse(s.content);if(v.id&&(v.tool||v.description))return e.jsx(yt,{data:v},s.id)}catch{}return e.jsx(ht,{message:s},s.id)}),p&&m&&e.jsx(pt,{text:m}),h&&!p&&e.jsx(bt,{})]})})}),e.jsx($,{children:!oe&&e.jsx(A.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},exit:{opacity:0,y:10},className:"absolute bottom-4 right-4",children:e.jsx(C,{variant:"outline",size:"icon",className:"h-9 w-9 rounded-full shadow-lg border-border bg-background/90 backdrop-blur-sm",onClick:le,children:e.jsx(Se,{className:"h-4 w-4"})})})})]}),me&&e.jsx("div",{className:"px-4 py-1.5",children:e.jsxs("div",{className:"mx-auto max-w-3xl",children:[e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground mb-1",children:[e.jsx(M,{className:"h-3 w-3 animate-spin text-primary"}),e.jsxs("span",{children:["Step ",D," of ",N,x&&e.jsxs("span",{className:"ml-1 text-foreground font-medium",children:["— ",x]})]})]}),e.jsx(ye,{value:ue,className:"h-1"})]})}),e.jsx(vt,{onSend:ce,disabled:de})]}),e.jsx($,{mode:"wait",children:I&&e.jsx(A.div,{initial:{width:0,opacity:0},animate:{width:320,opacity:1},exit:{width:0,opacity:0},transition:{duration:.2,ease:"easeInOut"},className:"hidden h-full shrink-0 overflow-hidden md:block",children:e.jsx("div",{className:"h-full w-[320px]",children:e.jsx(lt,{open:I,onClose:()=>F(!1)})})})})]})}export{_t as ChatPage};
28
- //# sourceMappingURL=Chat-DCFkzIwn.js.map
28
+ //# sourceMappingURL=Chat-DXSn2dY8.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Chat-DCFkzIwn.js","sources":["../../node_modules/lucide-react/dist/esm/icons/file.js","../../node_modules/lucide-react/dist/esm/icons/panel-left-close.js","../../node_modules/lucide-react/dist/esm/icons/panel-left-open.js","../../node_modules/lucide-react/dist/esm/icons/wrench.js","../../src/components/chat/ThreadList.tsx","../../src/components/chat/WorkspacePanel.tsx","../../src/components/ui/popover.tsx","../../src/components/chat/ModelSwitcher.tsx","../../src/components/chat/CodeModeToggle.tsx","../../src/components/chat/ToolCallCard.tsx","../../src/components/chat/MessageBubble.tsx","../../src/components/chat/StreamingMessage.tsx","../../src/pages/Chat.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }]\n];\nconst File = createLucideIcon(\"file\", __iconNode);\n\nexport { __iconNode, File as default };\n//# sourceMappingURL=file.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"m16 15-3-3 3-3\", key: \"14y99z\" }]\n];\nconst PanelLeftClose = createLucideIcon(\"panel-left-close\", __iconNode);\n\nexport { __iconNode, PanelLeftClose as default };\n//# sourceMappingURL=panel-left-close.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"m14 9 3 3-3 3\", key: \"8010ee\" }]\n];\nconst PanelLeftOpen = createLucideIcon(\"panel-left-open\", __iconNode);\n\nexport { __iconNode, PanelLeftOpen as default };\n//# sourceMappingURL=panel-left-open.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\",\n key: \"cbrjhi\"\n }\n ]\n];\nconst Wrench = createLucideIcon(\"wrench\", __iconNode);\n\nexport { __iconNode, Wrench as default };\n//# sourceMappingURL=wrench.js.map\n","import { useState } from \"react\";\nimport { Plus, Trash2, Download, MessageSquare } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"@/components/ui/alert-dialog\";\nimport type { ChatThread } from \"@/lib/api\";\n\ninterface ThreadListProps {\n threads: ChatThread[];\n activeThreadId: string | null;\n onSelect: (id: string) => void;\n onDelete: (id: string) => void;\n onNew: () => void;\n onExport: (id: string) => void;\n}\n\nexport function ThreadList({\n threads,\n activeThreadId,\n onSelect,\n onDelete,\n onNew,\n onExport,\n}: ThreadListProps) {\n const [deleteTarget, setDeleteTarget] = useState<string | null>(null);\n\n function formatDate(iso: string): string {\n const d = new Date(iso);\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) {\n return d.toLocaleTimeString(undefined, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n }\n if (diffDays === 1) return \"Yesterday\";\n if (diffDays < 7) return `${diffDays} days ago`;\n return d.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n });\n }\n\n return (\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold text-foreground\">Conversations</h2>\n <Button size=\"sm\" onClick={onNew} className=\"h-7 gap-1 px-2 text-xs\">\n <Plus className=\"h-3.5 w-3.5\" />\n New Chat\n </Button>\n </div>\n\n {/* Thread list */}\n <ScrollArea className=\"flex-1\">\n {threads.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center gap-2 px-4 py-12 text-center\">\n <MessageSquare className=\"h-8 w-8 text-muted-foreground/40\" />\n <p className=\"text-sm text-muted-foreground\">\n No conversations yet\n </p>\n </div>\n ) : (\n <div className=\"p-2\">\n {threads.map((thread) => {\n const isActive = thread.id === activeThreadId;\n return (\n <ThreadItem\n key={thread.id}\n thread={thread}\n isActive={isActive}\n formatDate={formatDate}\n onSelect={() => onSelect(thread.id)}\n onDelete={() => setDeleteTarget(thread.id)}\n onExport={() => onExport(thread.id)}\n />\n );\n })}\n </div>\n )}\n </ScrollArea>\n\n {/* Delete confirmation */}\n <AlertDialog\n open={deleteTarget !== null}\n onOpenChange={(open) => {\n if (!open) setDeleteTarget(null);\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete conversation?</AlertDialogTitle>\n <AlertDialogDescription>\n This will permanently remove this conversation and all its\n messages. This action cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n onClick={() => {\n if (deleteTarget) {\n onDelete(deleteTarget);\n setDeleteTarget(null);\n }\n }}\n >\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n\nfunction ThreadItem({\n thread,\n isActive,\n formatDate,\n onSelect,\n onDelete,\n onExport,\n}: {\n thread: ChatThread;\n isActive: boolean;\n formatDate: (iso: string) => string;\n onSelect: () => void;\n onDelete: () => void;\n onExport: () => void;\n}) {\n return (\n <div\n onClick={onSelect}\n className={cn(\n \"group flex w-full cursor-pointer items-center rounded-lg pl-2 pr-1 py-2 text-left transition-all duration-150\",\n isActive\n ? \"border-l-2 border-l-primary bg-primary/10 text-foreground\"\n : \"border-l-2 border-l-transparent hover:bg-muted/60 text-foreground/80\"\n )}\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-medium leading-snug text-left\">\n {thread.title || \"New conversation\"}\n </div>\n <div className=\"text-xs text-muted-foreground text-left\">\n {formatDate(thread.createdAt)}\n </div>\n </div>\n\n {/* Delete button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n className={cn(\n \"shrink-0 rounded-md p-1 text-red-500 hover:bg-red-500/10 hover:text-red-600 transition-opacity\",\n isActive ? \"opacity-100\" : \"opacity-0 group-hover:opacity-100\"\n )}\n title=\"Delete\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n );\n}\n","import { useState, useCallback } from \"react\";\nimport {\n X,\n Folder,\n File,\n ChevronRight,\n ArrowUp,\n Loader2,\n} from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport api from \"@/lib/api\";\nimport type { WorkspaceTree, WorkspaceFile } from \"@/lib/api\";\nimport { Prism as SyntaxHighlighter } from \"react-syntax-highlighter\";\nimport { oneDark } from \"react-syntax-highlighter/dist/esm/styles/prism\";\n\ninterface WorkspacePanelProps {\n open: boolean;\n onClose: () => void;\n}\n\nconst EXT_LANG_MAP: Record<string, string> = {\n ts: \"typescript\",\n tsx: \"tsx\",\n js: \"javascript\",\n jsx: \"jsx\",\n py: \"python\",\n go: \"go\",\n rs: \"rust\",\n json: \"json\",\n yaml: \"yaml\",\n yml: \"yaml\",\n md: \"markdown\",\n css: \"css\",\n html: \"html\",\n sh: \"bash\",\n bash: \"bash\",\n sql: \"sql\",\n toml: \"toml\",\n xml: \"xml\",\n dockerfile: \"docker\",\n};\n\nfunction getLanguage(ext: string): string {\n return EXT_LANG_MAP[ext.toLowerCase().replace(/^\\./, \"\")] || \"text\";\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport function WorkspacePanel({ open, onClose }: WorkspacePanelProps) {\n const [tree, setTree] = useState<WorkspaceTree | null>(null);\n const [file, setFile] = useState<WorkspaceFile | null>(null);\n const [loading, setLoading] = useState(false);\n const [fileLoading, setFileLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const loadTree = useCallback(async (path?: string) => {\n setLoading(true);\n setError(null);\n setFile(null);\n try {\n const data = await api.workspace.tree(path);\n setTree(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load workspace\");\n } finally {\n setLoading(false);\n }\n }, []);\n\n const loadFile = useCallback(async (path: string) => {\n setFileLoading(true);\n try {\n const data = await api.workspace.file(path);\n setFile(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load file\");\n } finally {\n setFileLoading(false);\n }\n }, []);\n\n // Load tree on first open\n const [initialized, setInitialized] = useState(false);\n if (open && !initialized) {\n setInitialized(true);\n loadTree();\n }\n if (!open && initialized) {\n setInitialized(false);\n }\n\n if (!open) return null;\n\n // Build breadcrumb segments\n const breadcrumbs: { label: string; path: string }[] = [];\n if (tree) {\n const relative = tree.currentPath.replace(tree.root, \"\").replace(/^\\//, \"\");\n if (relative) {\n const parts = relative.split(\"/\");\n let accumulated = \"\";\n for (const part of parts) {\n accumulated = accumulated ? `${accumulated}/${part}` : part;\n breadcrumbs.push({ label: part, path: accumulated });\n }\n }\n }\n\n function navigateUp() {\n if (!tree) return;\n const rel = tree.currentPath.replace(tree.root, \"\").replace(/^\\//, \"\");\n const parts = rel.split(\"/\").filter(Boolean);\n if (parts.length <= 1) {\n loadTree();\n } else {\n parts.pop();\n loadTree(parts.join(\"/\"));\n }\n }\n\n return (\n <div className=\"flex h-full w-full flex-col border-l border-border bg-background\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border px-4 py-3\">\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"text-sm font-semibold text-foreground\">Workspace</h2>\n {tree && (\n <p className=\"truncate text-xs text-muted-foreground\">\n {tree.root}\n </p>\n )}\n </div>\n <Button variant=\"ghost\" size=\"icon\" onClick={onClose} className=\"h-7 w-7 shrink-0\">\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n\n {/* Breadcrumbs */}\n {tree && breadcrumbs.length > 0 && (\n <div className=\"flex items-center gap-1 border-b border-border px-4 py-2 text-xs\">\n <button\n onClick={() => loadTree()}\n className=\"text-primary hover:underline\"\n >\n root\n </button>\n {breadcrumbs.map((bc) => (\n <span key={bc.path} className=\"flex items-center gap-1\">\n <ChevronRight className=\"h-3 w-3 text-muted-foreground\" />\n <button\n onClick={() => loadTree(bc.path)}\n className=\"text-primary hover:underline\"\n >\n {bc.label}\n </button>\n </span>\n ))}\n </div>\n )}\n\n <ScrollArea className=\"flex-1\">\n {loading ? (\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-5 w-5 animate-spin text-primary\" />\n </div>\n ) : error ? (\n <div className=\"px-4 py-8 text-center text-sm text-destructive\">\n {error}\n </div>\n ) : (\n <div className=\"flex flex-col\">\n {/* File tree */}\n {tree && (\n <div className=\"border-b border-border\">\n {/* Up button */}\n {breadcrumbs.length > 0 && (\n <button\n onClick={navigateUp}\n className=\"flex w-full items-center gap-2 px-4 py-2 text-sm text-muted-foreground hover:bg-muted/50 transition-colors\"\n >\n <ArrowUp className=\"h-4 w-4\" />\n <span>..</span>\n </button>\n )}\n\n {tree.items.map((item) => (\n <button\n key={item.name}\n onClick={() => {\n if (item.type === \"directory\") {\n const rel = tree.currentPath\n .replace(tree.root, \"\")\n .replace(/^\\//, \"\");\n const newPath = rel\n ? `${rel}/${item.name}`\n : item.name;\n loadTree(newPath);\n } else {\n const rel = tree.currentPath\n .replace(tree.root, \"\")\n .replace(/^\\//, \"\");\n const filePath = rel\n ? `${rel}/${item.name}`\n : item.name;\n loadFile(filePath);\n }\n }}\n className={cn(\n \"flex w-full items-center gap-2 px-4 py-2 text-sm transition-colors hover:bg-muted/50\",\n item.type === \"directory\"\n ? \"text-foreground\"\n : \"text-foreground/80\"\n )}\n >\n {item.type === \"directory\" ? (\n <Folder className=\"h-4 w-4 shrink-0 text-primary/70\" />\n ) : (\n <File className=\"h-4 w-4 shrink-0 text-muted-foreground\" />\n )}\n <span className=\"truncate\">{item.name}</span>\n {item.size !== undefined && item.type === \"file\" && (\n <span className=\"ml-auto shrink-0 text-xs text-muted-foreground\">\n {formatSize(item.size)}\n </span>\n )}\n </button>\n ))}\n\n {tree.items.length === 0 && (\n <p className=\"px-4 py-6 text-center text-sm text-muted-foreground\">\n Empty directory\n </p>\n )}\n </div>\n )}\n\n {/* File preview */}\n {fileLoading && (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"h-5 w-5 animate-spin text-primary\" />\n </div>\n )}\n\n {file && !fileLoading && (\n <div className=\"flex flex-col\">\n <div className=\"flex items-center justify-between border-b border-border px-4 py-2\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-foreground\">\n {file.name}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {formatSize(file.size)}\n {file.truncated && \" (truncated)\"}\n </p>\n </div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setFile(null)}\n className=\"h-6 text-xs\"\n >\n Close\n </Button>\n </div>\n <div className=\"overflow-auto text-xs\">\n <SyntaxHighlighter\n language={getLanguage(file.ext)}\n style={oneDark}\n customStyle={{\n margin: 0,\n borderRadius: 0,\n fontSize: \"0.75rem\",\n lineHeight: \"1.5\",\n }}\n showLineNumbers\n wrapLongLines\n >\n {file.content}\n </SyntaxHighlighter>\n </div>\n </div>\n )}\n </div>\n )}\n </ScrollArea>\n </div>\n );\n}\n","import * as React from \"react\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { cn } from \"@/lib/utils\";\n\nconst Popover = PopoverPrimitive.Root;\nconst PopoverTrigger = PopoverPrimitive.Trigger;\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\nconst PopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };\n","import { useState, useCallback } from \"react\";\nimport { ChevronDown, Loader2, Check } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { Badge } from \"@/components/ui/badge\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport api from \"@/lib/api\";\nimport type { ModelsResponse } from \"@/lib/api\";\nimport { useChatStore } from \"@/stores/chat\";\n\ninterface ModelSwitcherProps {\n currentProvider: string;\n currentModel: string;\n}\n\nexport function ModelSwitcher({\n currentProvider,\n currentModel,\n}: ModelSwitcherProps) {\n const [open, setOpen] = useState(false);\n const [models, setModels] = useState<ModelsResponse | null>(null);\n const [loading, setLoading] = useState(false);\n const [switching, setSwitching] = useState<string | null>(null);\n\n const setProvider = useChatStore((s) => s.setProvider);\n const setModel = useChatStore((s) => s.setModel);\n\n const loadModels = useCallback(async () => {\n if (models) return;\n setLoading(true);\n try {\n const data = await api.chat.models.list();\n setModels(data);\n } catch {\n // silently fail\n } finally {\n setLoading(false);\n }\n }, [models]);\n\n async function handleSwitch(providerName: string) {\n setSwitching(providerName);\n try {\n await api.chat.models.switch(providerName);\n // Refresh model list to get new current\n const data = await api.chat.models.list();\n setModels(data);\n\n // Find the provider to get the model name\n const p = data.providers.find((pr) => pr.name === providerName);\n if (p) {\n setProvider(p.name);\n setModel(p.model);\n }\n setOpen(false);\n } catch {\n // silently fail\n } finally {\n setSwitching(null);\n }\n }\n\n const displayName =\n currentModel.length > 24\n ? currentModel.slice(0, 22) + \"...\"\n : currentModel || currentProvider || \"Model\";\n\n return (\n <Popover\n open={open}\n onOpenChange={(o) => {\n setOpen(o);\n if (o) loadModels();\n }}\n >\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 gap-1 px-2 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n <span className=\"max-w-[140px] truncate\">{displayName}</span>\n <ChevronDown className=\"h-3 w-3\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-72 p-2\">\n <p className=\"px-2 pb-2 text-xs font-semibold text-muted-foreground uppercase tracking-wider\">\n Providers\n </p>\n\n {loading ? (\n <div className=\"flex items-center justify-center py-4\">\n <Loader2 className=\"h-4 w-4 animate-spin text-primary\" />\n </div>\n ) : models ? (\n <div className=\"flex flex-col gap-0.5\">\n {models.providers.map((p) => {\n const isActive = p.name === currentProvider;\n const isSwitching = switching === p.name;\n return (\n <button\n key={p.name}\n disabled={!p.available || isSwitching}\n onClick={() => {\n if (!isActive && p.available) handleSwitch(p.name);\n }}\n className={cn(\n \"flex items-center gap-2 rounded-md px-2 py-2 text-left text-sm transition-colors\",\n p.available\n ? \"hover:bg-muted/60\"\n : \"cursor-not-allowed opacity-40\",\n isActive && \"bg-primary/10\"\n )}\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"font-medium text-foreground\">\n {p.name}\n </span>\n {isActive && (\n <Check className=\"h-3.5 w-3.5 text-primary\" />\n )}\n </div>\n <p className=\"truncate text-xs text-muted-foreground\">\n {p.model}\n </p>\n </div>\n {isSwitching ? (\n <Loader2 className=\"h-3.5 w-3.5 shrink-0 animate-spin text-primary\" />\n ) : (\n <Badge\n variant={p.available ? \"success\" : \"secondary\"}\n className=\"shrink-0 text-[10px] px-1.5 py-0\"\n >\n {p.available ? \"Ready\" : \"Unavailable\"}\n </Badge>\n )}\n </button>\n );\n })}\n </div>\n ) : (\n <p className=\"px-2 py-4 text-center text-sm text-muted-foreground\">\n No providers found\n </p>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport api from \"@/lib/api\";\nimport type { CodeStatus } from \"@/lib/api\";\n\ntype CodeState = \"off\" | \"plan\" | \"execute\";\n\nconst STATES: { value: CodeState; label: string }[] = [\n { value: \"off\", label: \"Off\" },\n { value: \"plan\", label: \"Plan\" },\n { value: \"execute\", label: \"Exec\" },\n];\n\nexport function CodeModeToggle() {\n const [status, setStatus] = useState<CodeStatus | null>(null);\n const [switching, setSwitching] = useState(false);\n\n const loadStatus = useCallback(async () => {\n try {\n const data = await api.code.status();\n setStatus(data);\n } catch {\n // not available\n }\n }, []);\n\n useEffect(() => {\n loadStatus();\n }, [loadStatus]);\n\n async function handleSet(state: CodeState) {\n if (!status || switching || state === status.state) return;\n setSwitching(true);\n try {\n const result = await api.code.set(state);\n setStatus((prev) =>\n prev\n ? {\n ...prev,\n state: result.state as CodeState,\n active: result.active,\n }\n : prev\n );\n } catch {\n // silently fail\n } finally {\n setSwitching(false);\n }\n }\n\n if (!status?.available) return null;\n\n return (\n <div className=\"flex items-center rounded-lg border border-border bg-muted/40 p-0.5\">\n {STATES.map((s) => {\n const isActive = status.state === s.value;\n return (\n <button\n key={s.value}\n disabled={switching}\n onClick={() => handleSet(s.value)}\n className={cn(\n \"rounded-md px-2.5 py-1 text-xs font-medium transition-all duration-150\",\n isActive\n ? s.value === \"plan\"\n ? \"bg-amber-500/15 text-amber-600 dark:text-amber-400 shadow-sm\"\n : s.value === \"execute\"\n ? \"bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 shadow-sm\"\n : \"bg-background text-muted-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\"\n )}\n >\n {s.label}\n </button>\n );\n })}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Wrench, Loader2, CheckCircle2, XCircle, ChevronRight } from \"lucide-react\";\nimport {\n Collapsible,\n CollapsibleTrigger,\n CollapsibleContent,\n} from \"@/components/ui/collapsible\";\nimport { cn } from \"@/lib/utils\";\n\ninterface ToolCallCardProps {\n tool: string;\n status: \"running\" | \"done\" | \"error\";\n result?: string;\n}\n\nconst statusConfig = {\n running: {\n icon: Loader2,\n label: \"Running...\",\n color: \"text-mercury-500\",\n border: \"border-l-mercury-500\",\n iconClass: \"animate-spin\",\n },\n done: {\n icon: CheckCircle2,\n label: \"Complete\",\n color: \"text-emerald-500\",\n border: \"border-l-emerald-500\",\n iconClass: \"\",\n },\n error: {\n icon: XCircle,\n label: \"Failed\",\n color: \"text-red-500\",\n border: \"border-l-red-500\",\n iconClass: \"\",\n },\n} as const;\n\nexport function ToolCallCard({ tool, status, result }: ToolCallCardProps) {\n const [open, setOpen] = useState(false);\n const config = statusConfig[status];\n const StatusIcon = config.icon;\n\n return (\n <Collapsible open={open} onOpenChange={setOpen}>\n <div\n className={cn(\n \"my-1.5 overflow-hidden rounded-md border border-border/60 border-l-2 bg-muted/30\",\n config.border\n )}\n >\n <CollapsibleTrigger className=\"flex w-full items-center gap-2 px-3 py-2 text-xs transition-colors hover:bg-muted/50\">\n <ChevronRight\n className={cn(\n \"h-3 w-3 text-muted-foreground transition-transform\",\n open && \"rotate-90\"\n )}\n />\n <Wrench className=\"h-3 w-3 text-muted-foreground\" />\n <span className=\"font-medium\">{tool}</span>\n <div className=\"ml-auto flex items-center gap-1.5\">\n <StatusIcon\n className={cn(\"h-3.5 w-3.5\", config.color, config.iconClass)}\n />\n <span className={cn(\"text-[0.6875rem]\", config.color)}>\n {config.label}\n </span>\n </div>\n </CollapsibleTrigger>\n\n <CollapsibleContent>\n {result && (\n <div className=\"max-h-40 overflow-auto border-t border-border/40 bg-background/50 px-3 py-2\">\n <pre className=\"whitespace-pre-wrap font-mono text-[0.75rem] leading-relaxed text-muted-foreground\">\n {result}\n </pre>\n </div>\n )}\n </CollapsibleContent>\n </div>\n </Collapsible>\n );\n}\n","import { useState, useCallback } from \"react\";\nimport { motion } from \"framer-motion\";\nimport { Copy, Check } from \"lucide-react\";\nimport type { ChatMessage } from \"@/lib/api\";\nimport { cn, formatDate } from \"@/lib/utils\";\nimport { useThemeStore } from \"@/stores/theme\";\nimport { MarkdownRenderer } from \"./MarkdownRenderer\";\nimport { ToolCallCard } from \"./ToolCallCard\";\n\ninterface MessageBubbleProps {\n message: ChatMessage;\n isLast?: boolean;\n}\n\nexport function MessageBubble({ message, isLast }: MessageBubbleProps) {\n const [copied, setCopied] = useState(false);\n const isUser = message.role === \"user\";\n const resolved = useThemeStore((s) => s.resolved);\n\n const handleCopy = useCallback(() => {\n navigator.clipboard.writeText(message.content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }, [message.content]);\n\n return (\n <motion.div\n initial={{ opacity: 0, y: 6 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.25, ease: \"easeOut\" }}\n className={cn(\n \"group flex gap-3\",\n isUser ? \"flex-row-reverse\" : \"flex-row\"\n )}\n >\n {/* Avatar */}\n <div\n className={cn(\n \"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full text-xs font-semibold\",\n isUser\n ? \"bg-primary text-primary-foreground\"\n : \"bg-card\"\n )}\n >\n {isUser ? (\n \"U\"\n ) : (\n <img\n src={resolved === \"dark\" ? \"/logo-dark.png\" : \"/logo-light.png\"}\n alt=\"Mercury\"\n className=\"h-full w-full object-contain\"\n />\n )}\n </div>\n\n {/* Content column */}\n <div\n className={cn(\n \"relative max-w-[80%] space-y-1\",\n isUser ? \"items-end\" : \"items-start\"\n )}\n >\n {/* Tool steps */}\n {message.steps?.map((step, i) => (\n <ToolCallCard\n key={`${message.id}-step-${i}`}\n tool={step.tool}\n status={step.status}\n result={step.result}\n />\n ))}\n\n {/* Bubble */}\n <div\n className={cn(\n \"relative rounded-2xl px-4 py-2.5\",\n isUser\n ? \"rounded-br-sm bg-mercury-500 text-white\"\n : \"rounded-bl-sm border border-border/60 bg-card text-card-foreground\"\n )}\n >\n {isUser ? (\n <p className=\"whitespace-pre-wrap text-sm leading-relaxed\">\n {message.content}\n </p>\n ) : (\n <MarkdownRenderer content={message.content} />\n )}\n\n {/* Hover actions */}\n <div\n className={cn(\n \"absolute -top-3 flex items-center gap-1 rounded-md border border-border bg-popover px-1 py-0.5 opacity-0 shadow-sm transition-opacity group-hover:opacity-100\",\n isUser ? \"right-0\" : \"left-0\"\n )}\n >\n <button\n onClick={handleCopy}\n className=\"rounded p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n {copied ? (\n <Check className=\"h-3 w-3 text-emerald-500\" />\n ) : (\n <Copy className=\"h-3 w-3\" />\n )}\n </button>\n </div>\n </div>\n\n {/* Timestamp */}\n <p\n className={cn(\n \"px-1 text-[0.6875rem] text-muted-foreground\",\n isUser ? \"text-right\" : \"text-left\"\n )}\n >\n {formatDate(message.timestamp)}\n </p>\n </div>\n </motion.div>\n );\n}\n","import { MarkdownRenderer } from \"./MarkdownRenderer\";\nimport { ToolCallCard } from \"./ToolCallCard\";\nimport { useThemeStore } from \"@/stores/theme\";\n\ninterface StreamingMessageProps {\n text: string;\n steps?: { tool: string; status: string }[];\n}\n\nexport function StreamingMessage({ text, steps }: StreamingMessageProps) {\n const isThinking = !text;\n const resolved = useThemeStore((s) => s.resolved);\n\n return (\n <div className=\"flex gap-3\">\n {/* Avatar */}\n <div className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full bg-card\">\n <img\n src={resolved === \"dark\" ? \"/logo-dark.png\" : \"/logo-light.png\"}\n alt=\"Mercury\"\n className=\"h-full w-full object-contain\"\n />\n </div>\n\n {/* Content */}\n <div className=\"max-w-[80%] space-y-1\">\n {/* Tool steps */}\n {steps?.map((step, i) => (\n <ToolCallCard\n key={`stream-step-${i}`}\n tool={step.tool}\n status={step.status as \"running\" | \"done\" | \"error\"}\n />\n ))}\n\n {/* Bubble */}\n <div className=\"rounded-2xl rounded-bl-sm border border-border/60 bg-card px-4 py-2.5 text-card-foreground\">\n {isThinking ? (\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground\">\n <span>Thinking</span>\n <span className=\"inline-flex w-5\">\n <span className=\"animate-pulse\">...</span>\n </span>\n </div>\n ) : (\n <div className=\"inline\">\n <MarkdownRenderer content={text} />\n <span className=\"ml-0.5 inline-block h-4 w-[3px] translate-y-[2px] rounded-sm bg-mercury-500 animate-cursor-blink\" />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useEffect, useRef, useCallback } from \"react\";\nimport { useParams, useNavigate } from \"react-router-dom\";\nimport {\n PanelLeftClose,\n PanelLeftOpen,\n FolderOpen,\n Settings,\n ArrowDown,\n Send,\n Loader2,\n MessageSquare,\n Check,\n X,\n Zap,\n} from \"lucide-react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport { Progress } from \"@/components/ui/progress\";\nimport { useChatStore } from \"@/stores/chat\";\nimport { useSSE } from \"@/hooks/useSSE\";\nimport api from \"@/lib/api\";\nimport type { ChatMessage, ChatThread } from \"@/lib/api\";\n\nimport { ThreadList } from \"@/components/chat/ThreadList\";\nimport { WorkspacePanel } from \"@/components/chat/WorkspacePanel\";\nimport { ModelSwitcher } from \"@/components/chat/ModelSwitcher\";\nimport { CodeModeToggle } from \"@/components/chat/CodeModeToggle\";\nimport { MessageBubble as MessageBubbleComponent } from \"@/components/chat/MessageBubble\";\nimport { StreamingMessage } from \"@/components/chat/StreamingMessage\";\n\n// ─── Hooks ───────────────────────────────────────────────────\n\nfunction useThreads() {\n const setThreads = useChatStore((s) => s.setThreads);\n const threads = useChatStore((s) => s.threads);\n const threadVersion = useChatStore((s) => s.threadVersion);\n const [loading, setLoading] = useState(true);\n\n const load = useCallback(async () => {\n try {\n const data = await api.chat.threads.list();\n setThreads(data.threads);\n } catch {\n // ignore\n } finally {\n setLoading(false);\n }\n }, [setThreads]);\n\n useEffect(() => {\n load();\n }, [load, threadVersion]);\n\n return { threads, loading, reload: load };\n}\n\nfunction useAutoScroll(deps: unknown[]) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [atBottom, setAtBottom] = useState(true);\n const userScrolledUp = useRef(false);\n\n const scrollToBottom = useCallback(() => {\n const el = containerRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n userScrolledUp.current = false;\n setAtBottom(true);\n }\n }, []);\n\n useEffect(() => {\n if (!userScrolledUp.current) {\n scrollToBottom();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n const handleScroll = useCallback(() => {\n const el = containerRef.current;\n if (!el) return;\n const threshold = 80;\n const isAtBottom =\n el.scrollHeight - el.scrollTop - el.clientHeight < threshold;\n setAtBottom(isAtBottom);\n if (!isAtBottom) {\n userScrolledUp.current = true;\n } else {\n userScrolledUp.current = false;\n }\n }, []);\n\n return { containerRef, atBottom, scrollToBottom, handleScroll };\n}\n\n// ─── Sub-components ──────────────────────────────────────────\n\nfunction WaitingIndicator() {\n return (\n <div className=\"flex w-full justify-start\">\n <div className=\"flex items-center gap-2 rounded-2xl bg-muted px-4 py-3 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin text-primary\" />\n Thinking...\n </div>\n </div>\n );\n}\n\nfunction PermissionPrompt({\n data,\n}: {\n data: { id: string; tool?: string; description?: string };\n}) {\n const [resolving, setResolving] = useState(false);\n\n async function handle(action: string) {\n setResolving(true);\n try {\n await api.chat.permission(data.id, action);\n } catch {\n // ignore\n } finally {\n setResolving(false);\n }\n }\n\n return (\n <div className=\"flex w-full justify-start\">\n <div className=\"max-w-[85%] rounded-2xl border border-amber-500/30 bg-amber-500/5 px-4 py-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium text-amber-600 dark:text-amber-400\">\n <Zap className=\"h-4 w-4\" />\n Permission Required\n </div>\n {data.tool && (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n Tool: <span className=\"font-medium text-foreground\">{data.tool}</span>\n </p>\n )}\n {data.description && (\n <p className=\"mt-1 text-sm text-foreground\">{data.description}</p>\n )}\n <div className=\"mt-3 flex items-center gap-2\">\n <Button\n size=\"sm\"\n className=\"h-7 gap-1 text-xs\"\n disabled={resolving}\n onClick={() => handle(\"allow\")}\n >\n {resolving ? (\n <Loader2 className=\"h-3 w-3 animate-spin\" />\n ) : (\n <Check className=\"h-3 w-3\" />\n )}\n Allow\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-7 gap-1 text-xs\"\n disabled={resolving}\n onClick={() => handle(\"deny\")}\n >\n <X className=\"h-3 w-3\" />\n Deny\n </Button>\n </div>\n </div>\n </div>\n );\n}\n\n// ─── Slash Commands ──────────────────────────────────────────\n\ninterface SlashCommand {\n command: string;\n description: string;\n category: string;\n}\n\nconst SLASH_COMMANDS: SlashCommand[] = [\n { command: \"/help\", description: \"Show all available commands\", category: \"General\" },\n { command: \"/progress\", description: \"Show current task progress\", category: \"General\" },\n { command: \"/halt\", description: \"Stop all sub-agents\", category: \"General\" },\n { command: \"/stop\", description: \"Stop all agents and clear tasks\", category: \"General\" },\n { command: \"/agents\", description: \"List active sub-agents and status\", category: \"Agents\" },\n { command: \"/agents kill\", description: \"Kill a specific sub-agent\", category: \"Agents\" },\n { command: \"/bg\", description: \"Run a shell command in background\", category: \"Background\" },\n { command: \"/bg:\", description: \"Delegate an LLM task to background\", category: \"Background\" },\n { command: \"/bg list\", description: \"Show all background tasks\", category: \"Background\" },\n { command: \"/bg current\", description: \"Move active task to background\", category: \"Background\" },\n { command: \"/bg stop\", description: \"Stop a background task\", category: \"Background\" },\n { command: \"/bg killall\", description: \"Stop all background tasks\", category: \"Background\" },\n { command: \"/bg clear\", description: \"Prune completed background tasks\", category: \"Background\" },\n { command: \"/models\", description: \"List available models\", category: \"Models\" },\n { command: \"/models use\", description: \"Switch to a different model\", category: \"Models\" },\n { command: \"/code\", description: \"Toggle programming mode\", category: \"Code\" },\n { command: \"/code plan\", description: \"Set plan-only mode\", category: \"Code\" },\n { command: \"/code execute\", description: \"Set execute mode\", category: \"Code\" },\n { command: \"/code off\", description: \"Disable programming mode\", category: \"Code\" },\n { command: \"/spotify\", description: \"Spotify status and controls\", category: \"Spotify\" },\n { command: \"/spotify play\", description: \"Play or search for music\", category: \"Spotify\" },\n { command: \"/spotify pause\", description: \"Pause playback\", category: \"Spotify\" },\n { command: \"/spotify next\", description: \"Skip to next track\", category: \"Spotify\" },\n { command: \"/spotify prev\", description: \"Previous track\", category: \"Spotify\" },\n { command: \"/spotify queue\", description: \"Show play queue\", category: \"Spotify\" },\n { command: \"/budget\", description: \"Show token budget status\", category: \"Budget\" },\n { command: \"/budget override\", description: \"Override budget for next request\", category: \"Budget\" },\n { command: \"/budget reset\", description: \"Reset daily usage counter\", category: \"Budget\" },\n { command: \"/budget set\", description: \"Set new daily budget limit\", category: \"Budget\" },\n { command: \"/memory\", description: \"Manage second-brain memory\", category: \"Memory\" },\n { command: \"/permissions\", description: \"Toggle permission mode\", category: \"General\" },\n { command: \"/ws\", description: \"Workspace file operations\", category: \"Workspace\" },\n { command: \"/exit\", description: \"Shutdown Mercury\", category: \"General\" },\n];\n\nfunction SlashCommandMenu({\n filter,\n selectedIndex,\n onSelect,\n}: {\n filter: string;\n selectedIndex: number;\n onSelect: (cmd: string) => void;\n}) {\n const filtered = SLASH_COMMANDS.filter((c) =>\n c.command.startsWith(filter.toLowerCase())\n );\n\n if (filtered.length === 0) return null;\n\n return (\n <motion.div\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 8 }}\n transition={{ duration: 0.15 }}\n className=\"absolute bottom-full left-0 right-0 mb-2 max-h-64 overflow-y-auto rounded-xl border border-border bg-popover shadow-xl\"\n >\n <div className=\"p-1\">\n {filtered.map((cmd, i) => (\n <button\n key={cmd.command}\n onMouseDown={(e) => {\n e.preventDefault();\n onSelect(cmd.command);\n }}\n className={cn(\n \"flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors\",\n i === selectedIndex\n ? \"bg-primary/10 text-primary\"\n : \"text-foreground hover:bg-muted\"\n )}\n >\n <span className=\"font-mono font-medium text-xs shrink-0\">\n {cmd.command}\n </span>\n <span className=\"text-muted-foreground text-xs truncate\">\n {cmd.description}\n </span>\n <span className=\"ml-auto text-[10px] text-muted-foreground/60 shrink-0\">\n {cmd.category}\n </span>\n </button>\n ))}\n </div>\n </motion.div>\n );\n}\n\nfunction ChatInput({\n onSend,\n disabled,\n}: {\n onSend: (text: string) => void;\n disabled: boolean;\n}) {\n const [text, setText] = useState(\"\");\n const [showSlash, setShowSlash] = useState(false);\n const [slashIndex, setSlashIndex] = useState(0);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n // Compute filtered commands for index bounds\n const slashFilter = showSlash ? text.split(\"\\n\")[0] : \"\";\n const filteredCommands = SLASH_COMMANDS.filter((c) =>\n c.command.startsWith(slashFilter.toLowerCase())\n );\n\n function handleSubmit() {\n const trimmed = text.trim();\n if (!trimmed || disabled) return;\n setShowSlash(false);\n onSend(trimmed);\n setText(\"\");\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n }\n }\n\n function selectSlashCommand(cmd: string) {\n // If the command typically takes arguments, add a trailing space\n const needsArg = [\"/bg\", \"/bg:\", \"/bg stop\", \"/models use\", \"/agents kill\", \"/spotify play\", \"/budget set\"].includes(cmd);\n setText(needsArg ? cmd + \" \" : cmd);\n setShowSlash(false);\n setSlashIndex(0);\n textareaRef.current?.focus();\n }\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (showSlash && filteredCommands.length > 0) {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setSlashIndex((prev) => Math.min(prev + 1, filteredCommands.length - 1));\n return;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setSlashIndex((prev) => Math.max(prev - 1, 0));\n return;\n }\n if (e.key === \"Tab\" || (e.key === \"Enter\" && !e.shiftKey)) {\n e.preventDefault();\n selectSlashCommand(filteredCommands[slashIndex].command);\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n setShowSlash(false);\n return;\n }\n }\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n }\n\n function handleChange(value: string) {\n setText(value);\n\n // Show slash menu when text starts with / and is a single line of just the command\n const firstLine = value.split(\"\\n\")[0];\n if (firstLine.startsWith(\"/\") && !firstLine.includes(\" \")) {\n setShowSlash(true);\n setSlashIndex(0);\n } else if (firstLine.startsWith(\"/\") && firstLine.split(\" \").length <= 2) {\n // Allow filtering for two-word commands like \"/bg list\"\n setShowSlash(true);\n setSlashIndex(0);\n } else {\n setShowSlash(false);\n }\n }\n\n function handleInput() {\n const el = textareaRef.current;\n if (el) {\n el.style.height = \"auto\";\n el.style.height = Math.min(el.scrollHeight, 200) + \"px\";\n }\n }\n\n return (\n <div className=\"border-t border-border bg-background/80 backdrop-blur-xl px-4 py-3\">\n <div className=\"mx-auto flex max-w-3xl items-end gap-2\">\n <div className=\"relative flex-1\">\n <AnimatePresence>\n {showSlash && filteredCommands.length > 0 && (\n <SlashCommandMenu\n filter={slashFilter}\n selectedIndex={slashIndex}\n onSelect={selectSlashCommand}\n />\n )}\n </AnimatePresence>\n <textarea\n ref={textareaRef}\n value={text}\n onChange={(e) => {\n handleChange(e.target.value);\n handleInput();\n }}\n onKeyDown={handleKeyDown}\n onBlur={() => {\n // Delay to allow click on menu item\n setTimeout(() => setShowSlash(false), 200);\n }}\n placeholder=\"Send a message... (type / for commands)\"\n rows={1}\n className={cn(\n \"w-full resize-none rounded-xl border border-border bg-muted/40 px-4 py-3 pr-12 text-sm text-foreground placeholder:text-muted-foreground\",\n \"focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary/40\",\n \"transition-all duration-150\"\n )}\n style={{ maxHeight: 200 }}\n />\n </div>\n <Button\n size=\"icon\"\n disabled={disabled || !text.trim()}\n onClick={handleSubmit}\n className=\"h-10 w-10 shrink-0 rounded-xl\"\n >\n <Send className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n\n// ─── Main Page ───────────────────────────────────────────────\n\nexport function ChatPage() {\n const { threadId: urlThreadId } = useParams<{ threadId?: string }>();\n const navigate = useNavigate();\n const { connected } = useSSE();\n const { threads, loading: threadsLoading, reload: reloadThreads } = useThreads();\n\n // Store state\n const messages = useChatStore((s) => s.messages);\n const streamingText = useChatStore((s) => s.streamingText);\n const isStreaming = useChatStore((s) => s.isStreaming);\n const waiting = useChatStore((s) => s.waiting);\n const activeThreadId = useChatStore((s) => s.activeThreadId);\n const provider = useChatStore((s) => s.provider);\n const model = useChatStore((s) => s.model);\n const totalSteps = useChatStore((s) => s.totalSteps);\n const completedSteps = useChatStore((s) => s.completedSteps);\n const currentStepTool = useChatStore((s) => s.currentStepTool);\n const setActiveThread = useChatStore((s) => s.setActiveThread);\n const addMessage = useChatStore((s) => s.addMessage);\n const clearMessages = useChatStore((s) => s.clearMessages);\n const setWaiting = useChatStore((s) => s.setWaiting);\n const clearStreaming = useChatStore((s) => s.clearStreaming);\n const resetSteps = useChatStore((s) => s.resetSteps);\n const bumpThreadVersion = useChatStore((s) => s.bumpThreadVersion);\n\n // Sync URL param → active thread\n useEffect(() => {\n if (urlThreadId && urlThreadId !== activeThreadId) {\n setActiveThread(urlThreadId);\n }\n }, [urlThreadId]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Panel state\n const [sidebarOpen, setSidebarOpen] = useState(true);\n const [workspaceOpen, setWorkspaceOpen] = useState(false);\n\n // Auto-scroll\n const { containerRef, atBottom, scrollToBottom, handleScroll } =\n useAutoScroll([messages, streamingText, waiting]);\n\n // Load thread messages when switching\n useEffect(() => {\n if (!activeThreadId) {\n clearMessages();\n return;\n }\n (async () => {\n try {\n const thread = await api.chat.threads.get(activeThreadId);\n clearMessages();\n if (thread.messages && thread.messages.length > 0) {\n thread.messages.forEach((m) => addMessage(m));\n }\n } catch {\n // Thread doesn't exist yet (new thread) — just clear\n clearMessages();\n }\n })();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeThreadId]);\n\n async function handleSend(content: string) {\n // Ensure we have a thread ID — create one if needed\n let threadId = activeThreadId;\n if (!threadId) {\n threadId = `web:${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n setActiveThread(threadId);\n }\n\n // Optimistic user message\n addMessage({\n id: crypto.randomUUID(),\n role: \"user\",\n content,\n timestamp: new Date().toISOString(),\n });\n\n // Immediately show waiting state\n setWaiting(true);\n\n // Persist user message to backend thread\n api.chat.threads.addMessage(threadId, \"user\", content)\n .then(() => bumpThreadVersion())\n .catch(() => {});\n\n try {\n await api.chat.send(content, threadId);\n // Reload threads in background to pick up new thread\n reloadThreads();\n } catch {\n setWaiting(false);\n clearStreaming();\n resetSteps();\n addMessage({\n id: crypto.randomUUID(),\n role: \"system\",\n content: \"Failed to send message. Please try again.\",\n timestamp: new Date().toISOString(),\n });\n }\n }\n\n async function handleDeleteThread(id: string) {\n try {\n await api.chat.threads.delete(id);\n if (activeThreadId === id) {\n setActiveThread(null);\n clearMessages();\n }\n reloadThreads();\n } catch {\n // ignore\n }\n }\n\n function handleNewThread() {\n const newId = `web:${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n setActiveThread(newId);\n clearMessages();\n reloadThreads();\n navigate(`/chat/${newId}`);\n }\n\n function handleSelectThread(id: string) {\n setActiveThread(id);\n navigate(`/chat/${id}`);\n }\n\n function handleExportThread(id: string) {\n const thread = threads.find((t) => t.id === id);\n if (!thread) return;\n const content = thread.messages\n .map((m) => `[${m.role}] ${m.content}`)\n .join(\"\\n\\n---\\n\\n\");\n const blob = new Blob([content], { type: \"text/plain\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `${thread.title || \"conversation\"}-${id.slice(0, 8)}.txt`;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n const isBusy = isStreaming || waiting;\n const hasSteps = totalSteps > 0;\n const stepProgress =\n totalSteps > 0 ? (completedSteps / totalSteps) * 100 : 0;\n\n return (\n <div className=\"flex h-full w-full overflow-hidden\">\n {/* ── Thread Sidebar (desktop) ── */}\n <div\n className={cn(\n \"hidden h-full shrink-0 border-r border-border bg-background transition-[width] duration-200 ease-in-out md:block overflow-hidden\",\n sidebarOpen ? \"w-[240px]\" : \"w-0 border-r-0\"\n )}\n >\n <div className=\"h-full w-[240px]\">\n <ThreadList\n threads={threads}\n activeThreadId={activeThreadId}\n onSelect={handleSelectThread}\n onDelete={handleDeleteThread}\n onNew={handleNewThread}\n onExport={handleExportThread}\n />\n </div>\n </div>\n\n {/* ── Mobile sidebar overlay ── */}\n <AnimatePresence>\n {sidebarOpen && (\n <>\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"fixed inset-0 z-40 bg-black/50 backdrop-blur-sm md:hidden\"\n onClick={() => setSidebarOpen(false)}\n />\n <motion.div\n initial={{ x: -260 }}\n animate={{ x: 0 }}\n exit={{ x: -260 }}\n transition={{ duration: 0.2, ease: \"easeInOut\" }}\n className=\"fixed inset-y-0 left-0 z-50 w-[260px] bg-background shadow-xl md:hidden\"\n >\n <ThreadList\n threads={threads}\n activeThreadId={activeThreadId}\n onSelect={(id) => {\n handleSelectThread(id);\n setSidebarOpen(false);\n }}\n onDelete={handleDeleteThread}\n onNew={() => {\n handleNewThread();\n setSidebarOpen(false);\n }}\n onExport={handleExportThread}\n />\n </motion.div>\n </>\n )}\n </AnimatePresence>\n\n {/* ── Main Chat Area ── */}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {/* Header */}\n <header className=\"flex h-12 items-center gap-2 border-b border-border bg-background/80 backdrop-blur-xl px-3\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setSidebarOpen(!sidebarOpen)}\n >\n {sidebarOpen ? (\n <PanelLeftClose className=\"h-4 w-4\" />\n ) : (\n <PanelLeftOpen className=\"h-4 w-4\" />\n )}\n </Button>\n\n {/* Logo */}\n <span className=\"hidden text-sm font-bold mercury-gradient-text sm:inline\">\n Mercury\n </span>\n\n <div className=\"mx-1 h-4 w-px bg-border\" />\n\n <ModelSwitcher currentProvider={provider} currentModel={model} />\n\n <div className=\"flex-1\" />\n\n <CodeModeToggle />\n\n {/* Connection indicator */}\n <div\n className={cn(\n \"h-2 w-2 rounded-full\",\n connected ? \"bg-emerald-500\" : \"bg-destructive\"\n )}\n title={connected ? \"Connected\" : \"Disconnected\"}\n />\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setWorkspaceOpen(!workspaceOpen)}\n >\n <FolderOpen className=\"h-4 w-4\" />\n </Button>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 hidden md:inline-flex\"\n onClick={() => (window.location.href = \"/settings\")}\n >\n <Settings className=\"h-4 w-4\" />\n </Button>\n </header>\n\n {/* Messages */}\n <div className=\"relative flex-1 min-h-0\">\n <div\n ref={containerRef}\n onScroll={handleScroll}\n className=\"h-full overflow-y-auto\"\n >\n <div className=\"mx-auto max-w-3xl space-y-4 px-4 py-6\">\n {threadsLoading && messages.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-24\">\n <Loader2 className=\"h-6 w-6 animate-spin text-primary\" />\n </div>\n ) : messages.length === 0 && !isStreaming && !waiting ? (\n <div className=\"flex flex-col items-center justify-center gap-3 py-24 text-center\">\n <div className=\"rounded-2xl bg-primary/10 p-4\">\n <MessageSquare className=\"h-8 w-8 text-primary\" />\n </div>\n <h3 className=\"text-lg font-semibold text-foreground\">\n Start a conversation\n </h3>\n <p className=\"max-w-sm text-sm text-muted-foreground\">\n Send a message to begin. Mercury is ready to assist you.\n </p>\n </div>\n ) : (\n <>\n {messages.map((msg) => {\n // Permission prompt detection for system messages\n if (msg.role === \"system\") {\n try {\n const parsed = JSON.parse(msg.content);\n if (parsed.id && (parsed.tool || parsed.description)) {\n return <PermissionPrompt key={msg.id} data={parsed} />;\n }\n } catch {\n // not a permission prompt, render as regular message\n }\n }\n return <MessageBubbleComponent key={msg.id} message={msg} />;\n })}\n {isStreaming && streamingText && (\n <StreamingMessage text={streamingText} />\n )}\n {waiting && !isStreaming && <WaitingIndicator />}\n </>\n )}\n </div>\n </div>\n\n {/* Scroll-to-bottom */}\n <AnimatePresence>\n {!atBottom && (\n <motion.div\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 10 }}\n className=\"absolute bottom-4 right-4\"\n >\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"h-9 w-9 rounded-full shadow-lg border-border bg-background/90 backdrop-blur-sm\"\n onClick={scrollToBottom}\n >\n <ArrowDown className=\"h-4 w-4\" />\n </Button>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n\n {/* Step progress */}\n {hasSteps && (\n <div className=\"px-4 py-1.5\">\n <div className=\"mx-auto max-w-3xl\">\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground mb-1\">\n <Loader2 className=\"h-3 w-3 animate-spin text-primary\" />\n <span>\n Step {completedSteps} of {totalSteps}\n {currentStepTool && (\n <span className=\"ml-1 text-foreground font-medium\">\n — {currentStepTool}\n </span>\n )}\n </span>\n </div>\n <Progress value={stepProgress} className=\"h-1\" />\n </div>\n </div>\n )}\n\n {/* Chat input */}\n <ChatInput onSend={handleSend} disabled={isBusy} />\n </div>\n\n {/* ── Workspace Panel ── */}\n <AnimatePresence mode=\"wait\">\n {workspaceOpen && (\n <motion.div\n initial={{ width: 0, opacity: 0 }}\n animate={{ width: 320, opacity: 1 }}\n exit={{ width: 0, opacity: 0 }}\n transition={{ duration: 0.2, ease: \"easeInOut\" }}\n className=\"hidden h-full shrink-0 overflow-hidden md:block\"\n >\n <div className=\"h-full w-[320px]\">\n <WorkspacePanel\n open={workspaceOpen}\n onClose={() => setWorkspaceOpen(false)}\n />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n"],"names":["__iconNode","File","createLucideIcon","PanelLeftClose","PanelLeftOpen","Wrench","ThreadList","threads","activeThreadId","onSelect","onDelete","onNew","onExport","deleteTarget","setDeleteTarget","useState","formatDate","iso","d","diffMs","diffDays","jsxs","jsx","Button","Plus","ScrollArea","MessageSquare","thread","isActive","ThreadItem","AlertDialog","open","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","cn","e","Trash2","EXT_LANG_MAP","getLanguage","ext","formatSize","bytes","WorkspacePanel","onClose","tree","setTree","file","setFile","loading","setLoading","fileLoading","setFileLoading","error","setError","loadTree","useCallback","path","data","api","err","loadFile","initialized","setInitialized","breadcrumbs","relative","parts","accumulated","part","navigateUp","X","bc","ChevronRight","Loader2","ArrowUp","item","rel","newPath","filePath","Folder","SyntaxHighlighter","oneDark","Popover","PopoverPrimitive.Root","PopoverTrigger","PopoverPrimitive.Trigger","PopoverContent","React.forwardRef","className","align","sideOffset","props","ref","PopoverPrimitive.Portal","PopoverPrimitive.Content","ModelSwitcher","currentProvider","currentModel","setOpen","models","setModels","switching","setSwitching","setProvider","useChatStore","s","setModel","loadModels","handleSwitch","providerName","p","pr","displayName","o","ChevronDown","isSwitching","Check","Badge","STATES","CodeModeToggle","status","setStatus","loadStatus","useEffect","handleSet","state","result","prev","statusConfig","CheckCircle2","XCircle","ToolCallCard","tool","config","StatusIcon","Collapsible","CollapsibleTrigger","CollapsibleContent","MessageBubble","message","isLast","copied","setCopied","isUser","resolved","useThemeStore","handleCopy","motion","_a","step","i","MarkdownRenderer","Copy","StreamingMessage","text","steps","isThinking","useThreads","setThreads","threadVersion","load","useAutoScroll","deps","containerRef","useRef","atBottom","setAtBottom","userScrolledUp","scrollToBottom","el","handleScroll","isAtBottom","WaitingIndicator","PermissionPrompt","resolving","setResolving","handle","action","Zap","SLASH_COMMANDS","SlashCommandMenu","filter","selectedIndex","filtered","c","cmd","ChatInput","onSend","disabled","setText","showSlash","setShowSlash","slashIndex","setSlashIndex","textareaRef","slashFilter","filteredCommands","handleSubmit","trimmed","selectSlashCommand","needsArg","handleKeyDown","handleChange","value","firstLine","handleInput","AnimatePresence","Send","ChatPage","urlThreadId","useParams","navigate","useNavigate","connected","useSSE","threadsLoading","reloadThreads","messages","streamingText","isStreaming","waiting","provider","model","totalSteps","completedSteps","currentStepTool","setActiveThread","addMessage","clearMessages","setWaiting","clearStreaming","resetSteps","bumpThreadVersion","sidebarOpen","setSidebarOpen","workspaceOpen","setWorkspaceOpen","m","handleSend","content","threadId","handleDeleteThread","id","handleNewThread","newId","handleSelectThread","handleExportThread","t","blob","url","a","isBusy","hasSteps","stepProgress","Fragment","FolderOpen","Settings","msg","parsed","MessageBubbleComponent","ArrowDown","Progress"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
1
+ {"version":3,"file":"Chat-DXSn2dY8.js","sources":["../../node_modules/lucide-react/dist/esm/icons/file.js","../../node_modules/lucide-react/dist/esm/icons/panel-left-close.js","../../node_modules/lucide-react/dist/esm/icons/panel-left-open.js","../../node_modules/lucide-react/dist/esm/icons/wrench.js","../../src/components/chat/ThreadList.tsx","../../src/components/chat/WorkspacePanel.tsx","../../src/components/ui/popover.tsx","../../src/components/chat/ModelSwitcher.tsx","../../src/components/chat/CodeModeToggle.tsx","../../src/components/chat/ToolCallCard.tsx","../../src/components/chat/MessageBubble.tsx","../../src/components/chat/StreamingMessage.tsx","../../src/pages/Chat.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }]\n];\nconst File = createLucideIcon(\"file\", __iconNode);\n\nexport { __iconNode, File as default };\n//# sourceMappingURL=file.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"m16 15-3-3 3-3\", key: \"14y99z\" }]\n];\nconst PanelLeftClose = createLucideIcon(\"panel-left-close\", __iconNode);\n\nexport { __iconNode, PanelLeftClose as default };\n//# sourceMappingURL=panel-left-close.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"m14 9 3 3-3 3\", key: \"8010ee\" }]\n];\nconst PanelLeftOpen = createLucideIcon(\"panel-left-open\", __iconNode);\n\nexport { __iconNode, PanelLeftOpen as default };\n//# sourceMappingURL=panel-left-open.js.map\n","/**\n * @license lucide-react v0.511.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\",\n key: \"cbrjhi\"\n }\n ]\n];\nconst Wrench = createLucideIcon(\"wrench\", __iconNode);\n\nexport { __iconNode, Wrench as default };\n//# sourceMappingURL=wrench.js.map\n","import { useState } from \"react\";\nimport { Plus, Trash2, Download, MessageSquare } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"@/components/ui/alert-dialog\";\nimport type { ChatThread } from \"@/lib/api\";\n\ninterface ThreadListProps {\n threads: ChatThread[];\n activeThreadId: string | null;\n onSelect: (id: string) => void;\n onDelete: (id: string) => void;\n onNew: () => void;\n onExport: (id: string) => void;\n}\n\nexport function ThreadList({\n threads,\n activeThreadId,\n onSelect,\n onDelete,\n onNew,\n onExport,\n}: ThreadListProps) {\n const [deleteTarget, setDeleteTarget] = useState<string | null>(null);\n\n function formatDate(iso: string): string {\n const d = new Date(iso);\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) {\n return d.toLocaleTimeString(undefined, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n }\n if (diffDays === 1) return \"Yesterday\";\n if (diffDays < 7) return `${diffDays} days ago`;\n return d.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n });\n }\n\n return (\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold text-foreground\">Conversations</h2>\n <Button size=\"sm\" onClick={onNew} className=\"h-7 gap-1 px-2 text-xs\">\n <Plus className=\"h-3.5 w-3.5\" />\n New Chat\n </Button>\n </div>\n\n {/* Thread list */}\n <ScrollArea className=\"flex-1\">\n {threads.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center gap-2 px-4 py-12 text-center\">\n <MessageSquare className=\"h-8 w-8 text-muted-foreground/40\" />\n <p className=\"text-sm text-muted-foreground\">\n No conversations yet\n </p>\n </div>\n ) : (\n <div className=\"p-2\">\n {threads.map((thread) => {\n const isActive = thread.id === activeThreadId;\n return (\n <ThreadItem\n key={thread.id}\n thread={thread}\n isActive={isActive}\n formatDate={formatDate}\n onSelect={() => onSelect(thread.id)}\n onDelete={() => setDeleteTarget(thread.id)}\n onExport={() => onExport(thread.id)}\n />\n );\n })}\n </div>\n )}\n </ScrollArea>\n\n {/* Delete confirmation */}\n <AlertDialog\n open={deleteTarget !== null}\n onOpenChange={(open) => {\n if (!open) setDeleteTarget(null);\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete conversation?</AlertDialogTitle>\n <AlertDialogDescription>\n This will permanently remove this conversation and all its\n messages. This action cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n onClick={() => {\n if (deleteTarget) {\n onDelete(deleteTarget);\n setDeleteTarget(null);\n }\n }}\n >\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n\nfunction ThreadItem({\n thread,\n isActive,\n formatDate,\n onSelect,\n onDelete,\n onExport,\n}: {\n thread: ChatThread;\n isActive: boolean;\n formatDate: (iso: string) => string;\n onSelect: () => void;\n onDelete: () => void;\n onExport: () => void;\n}) {\n return (\n <div\n onClick={onSelect}\n className={cn(\n \"group flex w-full cursor-pointer items-center rounded-lg pl-2 pr-1 py-2 text-left transition-all duration-150\",\n isActive\n ? \"border-l-2 border-l-primary bg-primary/10 text-foreground\"\n : \"border-l-2 border-l-transparent hover:bg-muted/60 text-foreground/80\"\n )}\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-medium leading-snug text-left\">\n {thread.title || \"New conversation\"}\n </div>\n <div className=\"text-xs text-muted-foreground text-left\">\n {formatDate(thread.createdAt)}\n </div>\n </div>\n\n {/* Delete button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n className={cn(\n \"shrink-0 rounded-md p-1 text-red-500 hover:bg-red-500/10 hover:text-red-600 transition-opacity\",\n isActive ? \"opacity-100\" : \"opacity-0 group-hover:opacity-100\"\n )}\n title=\"Delete\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n );\n}\n","import { useState, useCallback } from \"react\";\nimport {\n X,\n Folder,\n File,\n ChevronRight,\n ArrowUp,\n Loader2,\n} from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport api from \"@/lib/api\";\nimport type { WorkspaceTree, WorkspaceFile } from \"@/lib/api\";\nimport { Prism as SyntaxHighlighter } from \"react-syntax-highlighter\";\nimport { oneDark } from \"react-syntax-highlighter/dist/esm/styles/prism\";\n\ninterface WorkspacePanelProps {\n open: boolean;\n onClose: () => void;\n}\n\nconst EXT_LANG_MAP: Record<string, string> = {\n ts: \"typescript\",\n tsx: \"tsx\",\n js: \"javascript\",\n jsx: \"jsx\",\n py: \"python\",\n go: \"go\",\n rs: \"rust\",\n json: \"json\",\n yaml: \"yaml\",\n yml: \"yaml\",\n md: \"markdown\",\n css: \"css\",\n html: \"html\",\n sh: \"bash\",\n bash: \"bash\",\n sql: \"sql\",\n toml: \"toml\",\n xml: \"xml\",\n dockerfile: \"docker\",\n};\n\nfunction getLanguage(ext: string): string {\n return EXT_LANG_MAP[ext.toLowerCase().replace(/^\\./, \"\")] || \"text\";\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport function WorkspacePanel({ open, onClose }: WorkspacePanelProps) {\n const [tree, setTree] = useState<WorkspaceTree | null>(null);\n const [file, setFile] = useState<WorkspaceFile | null>(null);\n const [loading, setLoading] = useState(false);\n const [fileLoading, setFileLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const loadTree = useCallback(async (path?: string) => {\n setLoading(true);\n setError(null);\n setFile(null);\n try {\n const data = await api.workspace.tree(path);\n setTree(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load workspace\");\n } finally {\n setLoading(false);\n }\n }, []);\n\n const loadFile = useCallback(async (path: string) => {\n setFileLoading(true);\n try {\n const data = await api.workspace.file(path);\n setFile(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load file\");\n } finally {\n setFileLoading(false);\n }\n }, []);\n\n // Load tree on first open\n const [initialized, setInitialized] = useState(false);\n if (open && !initialized) {\n setInitialized(true);\n loadTree();\n }\n if (!open && initialized) {\n setInitialized(false);\n }\n\n if (!open) return null;\n\n // Build breadcrumb segments\n const breadcrumbs: { label: string; path: string }[] = [];\n if (tree) {\n const relative = tree.currentPath.replace(tree.root, \"\").replace(/^\\//, \"\");\n if (relative) {\n const parts = relative.split(\"/\");\n let accumulated = \"\";\n for (const part of parts) {\n accumulated = accumulated ? `${accumulated}/${part}` : part;\n breadcrumbs.push({ label: part, path: accumulated });\n }\n }\n }\n\n function navigateUp() {\n if (!tree) return;\n const rel = tree.currentPath.replace(tree.root, \"\").replace(/^\\//, \"\");\n const parts = rel.split(\"/\").filter(Boolean);\n if (parts.length <= 1) {\n loadTree();\n } else {\n parts.pop();\n loadTree(parts.join(\"/\"));\n }\n }\n\n return (\n <div className=\"flex h-full w-full flex-col border-l border-border bg-background\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border px-4 py-3\">\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"text-sm font-semibold text-foreground\">Workspace</h2>\n {tree && (\n <p className=\"truncate text-xs text-muted-foreground\">\n {tree.root}\n </p>\n )}\n </div>\n <Button variant=\"ghost\" size=\"icon\" onClick={onClose} className=\"h-7 w-7 shrink-0\">\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n\n {/* Breadcrumbs */}\n {tree && breadcrumbs.length > 0 && (\n <div className=\"flex items-center gap-1 border-b border-border px-4 py-2 text-xs\">\n <button\n onClick={() => loadTree()}\n className=\"text-primary hover:underline\"\n >\n root\n </button>\n {breadcrumbs.map((bc) => (\n <span key={bc.path} className=\"flex items-center gap-1\">\n <ChevronRight className=\"h-3 w-3 text-muted-foreground\" />\n <button\n onClick={() => loadTree(bc.path)}\n className=\"text-primary hover:underline\"\n >\n {bc.label}\n </button>\n </span>\n ))}\n </div>\n )}\n\n <ScrollArea className=\"flex-1\">\n {loading ? (\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-5 w-5 animate-spin text-primary\" />\n </div>\n ) : error ? (\n <div className=\"px-4 py-8 text-center text-sm text-destructive\">\n {error}\n </div>\n ) : (\n <div className=\"flex flex-col\">\n {/* File tree */}\n {tree && (\n <div className=\"border-b border-border\">\n {/* Up button */}\n {breadcrumbs.length > 0 && (\n <button\n onClick={navigateUp}\n className=\"flex w-full items-center gap-2 px-4 py-2 text-sm text-muted-foreground hover:bg-muted/50 transition-colors\"\n >\n <ArrowUp className=\"h-4 w-4\" />\n <span>..</span>\n </button>\n )}\n\n {tree.items.map((item) => (\n <button\n key={item.name}\n onClick={() => {\n if (item.type === \"directory\") {\n const rel = tree.currentPath\n .replace(tree.root, \"\")\n .replace(/^\\//, \"\");\n const newPath = rel\n ? `${rel}/${item.name}`\n : item.name;\n loadTree(newPath);\n } else {\n const rel = tree.currentPath\n .replace(tree.root, \"\")\n .replace(/^\\//, \"\");\n const filePath = rel\n ? `${rel}/${item.name}`\n : item.name;\n loadFile(filePath);\n }\n }}\n className={cn(\n \"flex w-full items-center gap-2 px-4 py-2 text-sm transition-colors hover:bg-muted/50\",\n item.type === \"directory\"\n ? \"text-foreground\"\n : \"text-foreground/80\"\n )}\n >\n {item.type === \"directory\" ? (\n <Folder className=\"h-4 w-4 shrink-0 text-primary/70\" />\n ) : (\n <File className=\"h-4 w-4 shrink-0 text-muted-foreground\" />\n )}\n <span className=\"truncate\">{item.name}</span>\n {item.size !== undefined && item.type === \"file\" && (\n <span className=\"ml-auto shrink-0 text-xs text-muted-foreground\">\n {formatSize(item.size)}\n </span>\n )}\n </button>\n ))}\n\n {tree.items.length === 0 && (\n <p className=\"px-4 py-6 text-center text-sm text-muted-foreground\">\n Empty directory\n </p>\n )}\n </div>\n )}\n\n {/* File preview */}\n {fileLoading && (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"h-5 w-5 animate-spin text-primary\" />\n </div>\n )}\n\n {file && !fileLoading && (\n <div className=\"flex flex-col\">\n <div className=\"flex items-center justify-between border-b border-border px-4 py-2\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-foreground\">\n {file.name}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {formatSize(file.size)}\n {file.truncated && \" (truncated)\"}\n </p>\n </div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setFile(null)}\n className=\"h-6 text-xs\"\n >\n Close\n </Button>\n </div>\n <div className=\"overflow-auto text-xs\">\n <SyntaxHighlighter\n language={getLanguage(file.ext)}\n style={oneDark}\n customStyle={{\n margin: 0,\n borderRadius: 0,\n fontSize: \"0.75rem\",\n lineHeight: \"1.5\",\n }}\n showLineNumbers\n wrapLongLines\n >\n {file.content}\n </SyntaxHighlighter>\n </div>\n </div>\n )}\n </div>\n )}\n </ScrollArea>\n </div>\n );\n}\n","import * as React from \"react\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { cn } from \"@/lib/utils\";\n\nconst Popover = PopoverPrimitive.Root;\nconst PopoverTrigger = PopoverPrimitive.Trigger;\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\nconst PopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };\n","import { useState, useCallback } from \"react\";\nimport { ChevronDown, Loader2, Check } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { Badge } from \"@/components/ui/badge\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport api from \"@/lib/api\";\nimport type { ModelsResponse } from \"@/lib/api\";\nimport { useChatStore } from \"@/stores/chat\";\n\ninterface ModelSwitcherProps {\n currentProvider: string;\n currentModel: string;\n}\n\nexport function ModelSwitcher({\n currentProvider,\n currentModel,\n}: ModelSwitcherProps) {\n const [open, setOpen] = useState(false);\n const [models, setModels] = useState<ModelsResponse | null>(null);\n const [loading, setLoading] = useState(false);\n const [switching, setSwitching] = useState<string | null>(null);\n\n const setProvider = useChatStore((s) => s.setProvider);\n const setModel = useChatStore((s) => s.setModel);\n\n const loadModels = useCallback(async () => {\n if (models) return;\n setLoading(true);\n try {\n const data = await api.chat.models.list();\n setModels(data);\n } catch {\n // silently fail\n } finally {\n setLoading(false);\n }\n }, [models]);\n\n async function handleSwitch(providerName: string) {\n setSwitching(providerName);\n try {\n await api.chat.models.switch(providerName);\n // Refresh model list to get new current\n const data = await api.chat.models.list();\n setModels(data);\n\n // Find the provider to get the model name\n const p = data.providers.find((pr) => pr.name === providerName);\n if (p) {\n setProvider(p.name);\n setModel(p.model);\n }\n setOpen(false);\n } catch {\n // silently fail\n } finally {\n setSwitching(null);\n }\n }\n\n const displayName =\n currentModel.length > 24\n ? currentModel.slice(0, 22) + \"...\"\n : currentModel || currentProvider || \"Model\";\n\n return (\n <Popover\n open={open}\n onOpenChange={(o) => {\n setOpen(o);\n if (o) loadModels();\n }}\n >\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 gap-1 px-2 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n <span className=\"max-w-[140px] truncate\">{displayName}</span>\n <ChevronDown className=\"h-3 w-3\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-72 p-2\">\n <p className=\"px-2 pb-2 text-xs font-semibold text-muted-foreground uppercase tracking-wider\">\n Providers\n </p>\n\n {loading ? (\n <div className=\"flex items-center justify-center py-4\">\n <Loader2 className=\"h-4 w-4 animate-spin text-primary\" />\n </div>\n ) : models ? (\n <div className=\"flex flex-col gap-0.5\">\n {models.providers.map((p) => {\n const isActive = p.name === currentProvider;\n const isSwitching = switching === p.name;\n return (\n <button\n key={p.name}\n disabled={!p.available || isSwitching}\n onClick={() => {\n if (!isActive && p.available) handleSwitch(p.name);\n }}\n className={cn(\n \"flex items-center gap-2 rounded-md px-2 py-2 text-left text-sm transition-colors\",\n p.available\n ? \"hover:bg-muted/60\"\n : \"cursor-not-allowed opacity-40\",\n isActive && \"bg-primary/10\"\n )}\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"font-medium text-foreground\">\n {p.name}\n </span>\n {isActive && (\n <Check className=\"h-3.5 w-3.5 text-primary\" />\n )}\n </div>\n <p className=\"truncate text-xs text-muted-foreground\">\n {p.model}\n </p>\n </div>\n {isSwitching ? (\n <Loader2 className=\"h-3.5 w-3.5 shrink-0 animate-spin text-primary\" />\n ) : (\n <Badge\n variant={p.available ? \"success\" : \"secondary\"}\n className=\"shrink-0 text-[10px] px-1.5 py-0\"\n >\n {p.available ? \"Ready\" : \"Unavailable\"}\n </Badge>\n )}\n </button>\n );\n })}\n </div>\n ) : (\n <p className=\"px-2 py-4 text-center text-sm text-muted-foreground\">\n No providers found\n </p>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport api from \"@/lib/api\";\nimport type { CodeStatus } from \"@/lib/api\";\n\ntype CodeState = \"off\" | \"plan\" | \"execute\";\n\nconst STATES: { value: CodeState; label: string }[] = [\n { value: \"off\", label: \"Off\" },\n { value: \"plan\", label: \"Plan\" },\n { value: \"execute\", label: \"Exec\" },\n];\n\nexport function CodeModeToggle() {\n const [status, setStatus] = useState<CodeStatus | null>(null);\n const [switching, setSwitching] = useState(false);\n\n const loadStatus = useCallback(async () => {\n try {\n const data = await api.code.status();\n setStatus(data);\n } catch {\n // not available\n }\n }, []);\n\n useEffect(() => {\n loadStatus();\n }, [loadStatus]);\n\n async function handleSet(state: CodeState) {\n if (!status || switching || state === status.state) return;\n setSwitching(true);\n try {\n const result = await api.code.set(state);\n setStatus((prev) =>\n prev\n ? {\n ...prev,\n state: result.state as CodeState,\n active: result.active,\n }\n : prev\n );\n } catch {\n // silently fail\n } finally {\n setSwitching(false);\n }\n }\n\n if (!status?.available) return null;\n\n return (\n <div className=\"flex items-center rounded-lg border border-border bg-muted/40 p-0.5\">\n {STATES.map((s) => {\n const isActive = status.state === s.value;\n return (\n <button\n key={s.value}\n disabled={switching}\n onClick={() => handleSet(s.value)}\n className={cn(\n \"rounded-md px-2.5 py-1 text-xs font-medium transition-all duration-150\",\n isActive\n ? s.value === \"plan\"\n ? \"bg-amber-500/15 text-amber-600 dark:text-amber-400 shadow-sm\"\n : s.value === \"execute\"\n ? \"bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 shadow-sm\"\n : \"bg-background text-muted-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\"\n )}\n >\n {s.label}\n </button>\n );\n })}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Wrench, Loader2, CheckCircle2, XCircle, ChevronRight } from \"lucide-react\";\nimport {\n Collapsible,\n CollapsibleTrigger,\n CollapsibleContent,\n} from \"@/components/ui/collapsible\";\nimport { cn } from \"@/lib/utils\";\n\ninterface ToolCallCardProps {\n tool: string;\n status: \"running\" | \"done\" | \"error\";\n result?: string;\n}\n\nconst statusConfig = {\n running: {\n icon: Loader2,\n label: \"Running...\",\n color: \"text-mercury-500\",\n border: \"border-l-mercury-500\",\n iconClass: \"animate-spin\",\n },\n done: {\n icon: CheckCircle2,\n label: \"Complete\",\n color: \"text-emerald-500\",\n border: \"border-l-emerald-500\",\n iconClass: \"\",\n },\n error: {\n icon: XCircle,\n label: \"Failed\",\n color: \"text-red-500\",\n border: \"border-l-red-500\",\n iconClass: \"\",\n },\n} as const;\n\nexport function ToolCallCard({ tool, status, result }: ToolCallCardProps) {\n const [open, setOpen] = useState(false);\n const config = statusConfig[status];\n const StatusIcon = config.icon;\n\n return (\n <Collapsible open={open} onOpenChange={setOpen}>\n <div\n className={cn(\n \"my-1.5 overflow-hidden rounded-md border border-border/60 border-l-2 bg-muted/30\",\n config.border\n )}\n >\n <CollapsibleTrigger className=\"flex w-full items-center gap-2 px-3 py-2 text-xs transition-colors hover:bg-muted/50\">\n <ChevronRight\n className={cn(\n \"h-3 w-3 text-muted-foreground transition-transform\",\n open && \"rotate-90\"\n )}\n />\n <Wrench className=\"h-3 w-3 text-muted-foreground\" />\n <span className=\"font-medium\">{tool}</span>\n <div className=\"ml-auto flex items-center gap-1.5\">\n <StatusIcon\n className={cn(\"h-3.5 w-3.5\", config.color, config.iconClass)}\n />\n <span className={cn(\"text-[0.6875rem]\", config.color)}>\n {config.label}\n </span>\n </div>\n </CollapsibleTrigger>\n\n <CollapsibleContent>\n {result && (\n <div className=\"max-h-40 overflow-auto border-t border-border/40 bg-background/50 px-3 py-2\">\n <pre className=\"whitespace-pre-wrap font-mono text-[0.75rem] leading-relaxed text-muted-foreground\">\n {result}\n </pre>\n </div>\n )}\n </CollapsibleContent>\n </div>\n </Collapsible>\n );\n}\n","import { useState, useCallback } from \"react\";\nimport { motion } from \"framer-motion\";\nimport { Copy, Check } from \"lucide-react\";\nimport type { ChatMessage } from \"@/lib/api\";\nimport { cn, formatDate } from \"@/lib/utils\";\nimport { useThemeStore } from \"@/stores/theme\";\nimport { MarkdownRenderer } from \"./MarkdownRenderer\";\nimport { ToolCallCard } from \"./ToolCallCard\";\n\ninterface MessageBubbleProps {\n message: ChatMessage;\n isLast?: boolean;\n}\n\nexport function MessageBubble({ message, isLast }: MessageBubbleProps) {\n const [copied, setCopied] = useState(false);\n const isUser = message.role === \"user\";\n const resolved = useThemeStore((s) => s.resolved);\n\n const handleCopy = useCallback(() => {\n navigator.clipboard.writeText(message.content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }, [message.content]);\n\n return (\n <motion.div\n initial={{ opacity: 0, y: 6 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.25, ease: \"easeOut\" }}\n className={cn(\n \"group flex gap-3\",\n isUser ? \"flex-row-reverse\" : \"flex-row\"\n )}\n >\n {/* Avatar */}\n <div\n className={cn(\n \"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full text-xs font-semibold\",\n isUser\n ? \"bg-primary text-primary-foreground\"\n : \"bg-card\"\n )}\n >\n {isUser ? (\n \"U\"\n ) : (\n <img\n src={resolved === \"dark\" ? \"/logo-dark.png\" : \"/logo-light.png\"}\n alt=\"Mercury\"\n className=\"h-full w-full object-contain\"\n />\n )}\n </div>\n\n {/* Content column */}\n <div\n className={cn(\n \"relative max-w-[80%] space-y-1\",\n isUser ? \"items-end\" : \"items-start\"\n )}\n >\n {/* Tool steps */}\n {message.steps?.map((step, i) => (\n <ToolCallCard\n key={`${message.id}-step-${i}`}\n tool={step.tool}\n status={step.status}\n result={step.result}\n />\n ))}\n\n {/* Bubble */}\n <div\n className={cn(\n \"relative rounded-2xl px-4 py-2.5\",\n isUser\n ? \"rounded-br-sm bg-mercury-500 text-white\"\n : \"rounded-bl-sm border border-border/60 bg-card text-card-foreground\"\n )}\n >\n {isUser ? (\n <p className=\"whitespace-pre-wrap text-sm leading-relaxed\">\n {message.content}\n </p>\n ) : (\n <MarkdownRenderer content={message.content} />\n )}\n\n {/* Hover actions */}\n <div\n className={cn(\n \"absolute -top-3 flex items-center gap-1 rounded-md border border-border bg-popover px-1 py-0.5 opacity-0 shadow-sm transition-opacity group-hover:opacity-100\",\n isUser ? \"right-0\" : \"left-0\"\n )}\n >\n <button\n onClick={handleCopy}\n className=\"rounded p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n {copied ? (\n <Check className=\"h-3 w-3 text-emerald-500\" />\n ) : (\n <Copy className=\"h-3 w-3\" />\n )}\n </button>\n </div>\n </div>\n\n {/* Timestamp */}\n <p\n className={cn(\n \"px-1 text-[0.6875rem] text-muted-foreground\",\n isUser ? \"text-right\" : \"text-left\"\n )}\n >\n {formatDate(message.timestamp)}\n </p>\n </div>\n </motion.div>\n );\n}\n","import { MarkdownRenderer } from \"./MarkdownRenderer\";\nimport { ToolCallCard } from \"./ToolCallCard\";\nimport { useThemeStore } from \"@/stores/theme\";\n\ninterface StreamingMessageProps {\n text: string;\n steps?: { tool: string; status: string }[];\n}\n\nexport function StreamingMessage({ text, steps }: StreamingMessageProps) {\n const isThinking = !text;\n const resolved = useThemeStore((s) => s.resolved);\n\n return (\n <div className=\"flex gap-3\">\n {/* Avatar */}\n <div className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full bg-card\">\n <img\n src={resolved === \"dark\" ? \"/logo-dark.png\" : \"/logo-light.png\"}\n alt=\"Mercury\"\n className=\"h-full w-full object-contain\"\n />\n </div>\n\n {/* Content */}\n <div className=\"max-w-[80%] space-y-1\">\n {/* Tool steps */}\n {steps?.map((step, i) => (\n <ToolCallCard\n key={`stream-step-${i}`}\n tool={step.tool}\n status={step.status as \"running\" | \"done\" | \"error\"}\n />\n ))}\n\n {/* Bubble */}\n <div className=\"rounded-2xl rounded-bl-sm border border-border/60 bg-card px-4 py-2.5 text-card-foreground\">\n {isThinking ? (\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground\">\n <span>Thinking</span>\n <span className=\"inline-flex w-5\">\n <span className=\"animate-pulse\">...</span>\n </span>\n </div>\n ) : (\n <div className=\"inline\">\n <MarkdownRenderer content={text} />\n <span className=\"ml-0.5 inline-block h-4 w-[3px] translate-y-[2px] rounded-sm bg-mercury-500 animate-cursor-blink\" />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useEffect, useRef, useCallback } from \"react\";\nimport { useParams, useNavigate } from \"react-router-dom\";\nimport {\n PanelLeftClose,\n PanelLeftOpen,\n FolderOpen,\n Settings,\n ArrowDown,\n Send,\n Loader2,\n MessageSquare,\n Check,\n X,\n Zap,\n} from \"lucide-react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport { Progress } from \"@/components/ui/progress\";\nimport { useChatStore } from \"@/stores/chat\";\nimport { useSSE } from \"@/hooks/useSSE\";\nimport api from \"@/lib/api\";\nimport type { ChatMessage, ChatThread } from \"@/lib/api\";\n\nimport { ThreadList } from \"@/components/chat/ThreadList\";\nimport { WorkspacePanel } from \"@/components/chat/WorkspacePanel\";\nimport { ModelSwitcher } from \"@/components/chat/ModelSwitcher\";\nimport { CodeModeToggle } from \"@/components/chat/CodeModeToggle\";\nimport { MessageBubble as MessageBubbleComponent } from \"@/components/chat/MessageBubble\";\nimport { StreamingMessage } from \"@/components/chat/StreamingMessage\";\n\n// ─── Hooks ───────────────────────────────────────────────────\n\nfunction useThreads() {\n const setThreads = useChatStore((s) => s.setThreads);\n const threads = useChatStore((s) => s.threads);\n const threadVersion = useChatStore((s) => s.threadVersion);\n const [loading, setLoading] = useState(true);\n\n const load = useCallback(async () => {\n try {\n const data = await api.chat.threads.list();\n setThreads(data.threads);\n } catch {\n // ignore\n } finally {\n setLoading(false);\n }\n }, [setThreads]);\n\n useEffect(() => {\n load();\n }, [load, threadVersion]);\n\n return { threads, loading, reload: load };\n}\n\nfunction useAutoScroll(deps: unknown[]) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [atBottom, setAtBottom] = useState(true);\n const userScrolledUp = useRef(false);\n\n const scrollToBottom = useCallback(() => {\n const el = containerRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n userScrolledUp.current = false;\n setAtBottom(true);\n }\n }, []);\n\n useEffect(() => {\n if (!userScrolledUp.current) {\n scrollToBottom();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n const handleScroll = useCallback(() => {\n const el = containerRef.current;\n if (!el) return;\n const threshold = 80;\n const isAtBottom =\n el.scrollHeight - el.scrollTop - el.clientHeight < threshold;\n setAtBottom(isAtBottom);\n if (!isAtBottom) {\n userScrolledUp.current = true;\n } else {\n userScrolledUp.current = false;\n }\n }, []);\n\n return { containerRef, atBottom, scrollToBottom, handleScroll };\n}\n\n// ─── Sub-components ──────────────────────────────────────────\n\nfunction WaitingIndicator() {\n return (\n <div className=\"flex w-full justify-start\">\n <div className=\"flex items-center gap-2 rounded-2xl bg-muted px-4 py-3 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin text-primary\" />\n Thinking...\n </div>\n </div>\n );\n}\n\nfunction PermissionPrompt({\n data,\n}: {\n data: { id: string; tool?: string; description?: string };\n}) {\n const [resolving, setResolving] = useState(false);\n\n async function handle(action: string) {\n setResolving(true);\n try {\n await api.chat.permission(data.id, action);\n } catch {\n // ignore\n } finally {\n setResolving(false);\n }\n }\n\n return (\n <div className=\"flex w-full justify-start\">\n <div className=\"max-w-[85%] rounded-2xl border border-amber-500/30 bg-amber-500/5 px-4 py-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium text-amber-600 dark:text-amber-400\">\n <Zap className=\"h-4 w-4\" />\n Permission Required\n </div>\n {data.tool && (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n Tool: <span className=\"font-medium text-foreground\">{data.tool}</span>\n </p>\n )}\n {data.description && (\n <p className=\"mt-1 text-sm text-foreground\">{data.description}</p>\n )}\n <div className=\"mt-3 flex items-center gap-2\">\n <Button\n size=\"sm\"\n className=\"h-7 gap-1 text-xs\"\n disabled={resolving}\n onClick={() => handle(\"allow\")}\n >\n {resolving ? (\n <Loader2 className=\"h-3 w-3 animate-spin\" />\n ) : (\n <Check className=\"h-3 w-3\" />\n )}\n Allow\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-7 gap-1 text-xs\"\n disabled={resolving}\n onClick={() => handle(\"deny\")}\n >\n <X className=\"h-3 w-3\" />\n Deny\n </Button>\n </div>\n </div>\n </div>\n );\n}\n\n// ─── Slash Commands ──────────────────────────────────────────\n\ninterface SlashCommand {\n command: string;\n description: string;\n category: string;\n}\n\nconst SLASH_COMMANDS: SlashCommand[] = [\n { command: \"/help\", description: \"Show all available commands\", category: \"General\" },\n { command: \"/progress\", description: \"Show current task progress\", category: \"General\" },\n { command: \"/halt\", description: \"Stop all sub-agents\", category: \"General\" },\n { command: \"/stop\", description: \"Stop all agents and clear tasks\", category: \"General\" },\n { command: \"/agents\", description: \"List active sub-agents and status\", category: \"Agents\" },\n { command: \"/agents kill\", description: \"Kill a specific sub-agent\", category: \"Agents\" },\n { command: \"/bg\", description: \"Run a shell command in background\", category: \"Background\" },\n { command: \"/bg:\", description: \"Delegate an LLM task to background\", category: \"Background\" },\n { command: \"/bg list\", description: \"Show all background tasks\", category: \"Background\" },\n { command: \"/bg current\", description: \"Move active task to background\", category: \"Background\" },\n { command: \"/bg stop\", description: \"Stop a background task\", category: \"Background\" },\n { command: \"/bg killall\", description: \"Stop all background tasks\", category: \"Background\" },\n { command: \"/bg clear\", description: \"Prune completed background tasks\", category: \"Background\" },\n { command: \"/models\", description: \"List available models\", category: \"Models\" },\n { command: \"/models use\", description: \"Switch to a different model\", category: \"Models\" },\n { command: \"/code\", description: \"Toggle programming mode\", category: \"Code\" },\n { command: \"/code plan\", description: \"Set plan-only mode\", category: \"Code\" },\n { command: \"/code execute\", description: \"Set execute mode\", category: \"Code\" },\n { command: \"/code off\", description: \"Disable programming mode\", category: \"Code\" },\n { command: \"/spotify\", description: \"Spotify status and controls\", category: \"Spotify\" },\n { command: \"/spotify play\", description: \"Play or search for music\", category: \"Spotify\" },\n { command: \"/spotify pause\", description: \"Pause playback\", category: \"Spotify\" },\n { command: \"/spotify next\", description: \"Skip to next track\", category: \"Spotify\" },\n { command: \"/spotify prev\", description: \"Previous track\", category: \"Spotify\" },\n { command: \"/spotify queue\", description: \"Show play queue\", category: \"Spotify\" },\n { command: \"/budget\", description: \"Show token budget status\", category: \"Budget\" },\n { command: \"/budget override\", description: \"Override budget for next request\", category: \"Budget\" },\n { command: \"/budget reset\", description: \"Reset daily usage counter\", category: \"Budget\" },\n { command: \"/budget set\", description: \"Set new daily budget limit\", category: \"Budget\" },\n { command: \"/memory\", description: \"Manage second-brain memory\", category: \"Memory\" },\n { command: \"/permissions\", description: \"Toggle permission mode\", category: \"General\" },\n { command: \"/ws\", description: \"Workspace file operations\", category: \"Workspace\" },\n { command: \"/exit\", description: \"Shutdown Mercury\", category: \"General\" },\n];\n\nfunction SlashCommandMenu({\n filter,\n selectedIndex,\n onSelect,\n}: {\n filter: string;\n selectedIndex: number;\n onSelect: (cmd: string) => void;\n}) {\n const filtered = SLASH_COMMANDS.filter((c) =>\n c.command.startsWith(filter.toLowerCase())\n );\n\n if (filtered.length === 0) return null;\n\n return (\n <motion.div\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 8 }}\n transition={{ duration: 0.15 }}\n className=\"absolute bottom-full left-0 right-0 mb-2 max-h-64 overflow-y-auto rounded-xl border border-border bg-popover shadow-xl\"\n >\n <div className=\"p-1\">\n {filtered.map((cmd, i) => (\n <button\n key={cmd.command}\n onMouseDown={(e) => {\n e.preventDefault();\n onSelect(cmd.command);\n }}\n className={cn(\n \"flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors\",\n i === selectedIndex\n ? \"bg-primary/10 text-primary\"\n : \"text-foreground hover:bg-muted\"\n )}\n >\n <span className=\"font-mono font-medium text-xs shrink-0\">\n {cmd.command}\n </span>\n <span className=\"text-muted-foreground text-xs truncate\">\n {cmd.description}\n </span>\n <span className=\"ml-auto text-[10px] text-muted-foreground/60 shrink-0\">\n {cmd.category}\n </span>\n </button>\n ))}\n </div>\n </motion.div>\n );\n}\n\nfunction ChatInput({\n onSend,\n disabled,\n}: {\n onSend: (text: string) => void;\n disabled: boolean;\n}) {\n const [text, setText] = useState(\"\");\n const [showSlash, setShowSlash] = useState(false);\n const [slashIndex, setSlashIndex] = useState(0);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n // Compute filtered commands for index bounds\n const slashFilter = showSlash ? text.split(\"\\n\")[0] : \"\";\n const filteredCommands = SLASH_COMMANDS.filter((c) =>\n c.command.startsWith(slashFilter.toLowerCase())\n );\n\n function handleSubmit() {\n const trimmed = text.trim();\n if (!trimmed || disabled) return;\n setShowSlash(false);\n onSend(trimmed);\n setText(\"\");\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n }\n }\n\n function selectSlashCommand(cmd: string) {\n // If the command typically takes arguments, add a trailing space\n const needsArg = [\"/bg\", \"/bg:\", \"/bg stop\", \"/models use\", \"/agents kill\", \"/spotify play\", \"/budget set\"].includes(cmd);\n setText(needsArg ? cmd + \" \" : cmd);\n setShowSlash(false);\n setSlashIndex(0);\n textareaRef.current?.focus();\n }\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (showSlash && filteredCommands.length > 0) {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setSlashIndex((prev) => Math.min(prev + 1, filteredCommands.length - 1));\n return;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setSlashIndex((prev) => Math.max(prev - 1, 0));\n return;\n }\n if (e.key === \"Tab\" || (e.key === \"Enter\" && !e.shiftKey)) {\n e.preventDefault();\n selectSlashCommand(filteredCommands[slashIndex].command);\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n setShowSlash(false);\n return;\n }\n }\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n }\n\n function handleChange(value: string) {\n setText(value);\n\n // Show slash menu when text starts with / and is a single line of just the command\n const firstLine = value.split(\"\\n\")[0];\n if (firstLine.startsWith(\"/\") && !firstLine.includes(\" \")) {\n setShowSlash(true);\n setSlashIndex(0);\n } else if (firstLine.startsWith(\"/\") && firstLine.split(\" \").length <= 2) {\n // Allow filtering for two-word commands like \"/bg list\"\n setShowSlash(true);\n setSlashIndex(0);\n } else {\n setShowSlash(false);\n }\n }\n\n function handleInput() {\n const el = textareaRef.current;\n if (el) {\n el.style.height = \"auto\";\n el.style.height = Math.min(el.scrollHeight, 200) + \"px\";\n }\n }\n\n return (\n <div className=\"border-t border-border bg-background/80 backdrop-blur-xl px-4 py-3\">\n <div className=\"mx-auto flex max-w-3xl items-end gap-2\">\n <div className=\"relative flex-1\">\n <AnimatePresence>\n {showSlash && filteredCommands.length > 0 && (\n <SlashCommandMenu\n filter={slashFilter}\n selectedIndex={slashIndex}\n onSelect={selectSlashCommand}\n />\n )}\n </AnimatePresence>\n <textarea\n ref={textareaRef}\n value={text}\n onChange={(e) => {\n handleChange(e.target.value);\n handleInput();\n }}\n onKeyDown={handleKeyDown}\n onBlur={() => {\n // Delay to allow click on menu item\n setTimeout(() => setShowSlash(false), 200);\n }}\n placeholder=\"Send a message... (type / for commands)\"\n rows={1}\n className={cn(\n \"w-full resize-none rounded-xl border border-border bg-muted/40 px-4 py-3 pr-12 text-sm text-foreground placeholder:text-muted-foreground\",\n \"focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary/40\",\n \"transition-all duration-150\"\n )}\n style={{ maxHeight: 200 }}\n />\n </div>\n <Button\n size=\"icon\"\n disabled={disabled || !text.trim()}\n onClick={handleSubmit}\n className=\"h-10 w-10 shrink-0 rounded-xl\"\n >\n <Send className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n\n// ─── Main Page ───────────────────────────────────────────────\n\nexport function ChatPage() {\n const { threadId: urlThreadId } = useParams<{ threadId?: string }>();\n const navigate = useNavigate();\n const { connected } = useSSE();\n const { threads, loading: threadsLoading, reload: reloadThreads } = useThreads();\n\n // Store state\n const messages = useChatStore((s) => s.messages);\n const streamingText = useChatStore((s) => s.streamingText);\n const isStreaming = useChatStore((s) => s.isStreaming);\n const waiting = useChatStore((s) => s.waiting);\n const activeThreadId = useChatStore((s) => s.activeThreadId);\n const provider = useChatStore((s) => s.provider);\n const model = useChatStore((s) => s.model);\n const totalSteps = useChatStore((s) => s.totalSteps);\n const completedSteps = useChatStore((s) => s.completedSteps);\n const currentStepTool = useChatStore((s) => s.currentStepTool);\n const setActiveThread = useChatStore((s) => s.setActiveThread);\n const addMessage = useChatStore((s) => s.addMessage);\n const clearMessages = useChatStore((s) => s.clearMessages);\n const setWaiting = useChatStore((s) => s.setWaiting);\n const clearStreaming = useChatStore((s) => s.clearStreaming);\n const resetSteps = useChatStore((s) => s.resetSteps);\n const bumpThreadVersion = useChatStore((s) => s.bumpThreadVersion);\n\n // Sync URL param → active thread\n useEffect(() => {\n if (urlThreadId && urlThreadId !== activeThreadId) {\n setActiveThread(urlThreadId);\n }\n }, [urlThreadId]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Panel state\n const [sidebarOpen, setSidebarOpen] = useState(true);\n const [workspaceOpen, setWorkspaceOpen] = useState(false);\n\n // Auto-scroll\n const { containerRef, atBottom, scrollToBottom, handleScroll } =\n useAutoScroll([messages, streamingText, waiting]);\n\n // Load thread messages when switching\n useEffect(() => {\n if (!activeThreadId) {\n clearMessages();\n return;\n }\n (async () => {\n try {\n const thread = await api.chat.threads.get(activeThreadId);\n clearMessages();\n if (thread.messages && thread.messages.length > 0) {\n thread.messages.forEach((m) => addMessage(m));\n }\n } catch {\n // Thread doesn't exist yet (new thread) — just clear\n clearMessages();\n }\n })();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeThreadId]);\n\n async function handleSend(content: string) {\n // Ensure we have a thread ID — create one if needed\n let threadId = activeThreadId;\n if (!threadId) {\n threadId = `web:${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n setActiveThread(threadId);\n }\n\n // Optimistic user message\n addMessage({\n id: crypto.randomUUID(),\n role: \"user\",\n content,\n timestamp: new Date().toISOString(),\n });\n\n // Immediately show waiting state\n setWaiting(true);\n\n // Persist user message to backend thread\n api.chat.threads.addMessage(threadId, \"user\", content)\n .then(() => bumpThreadVersion())\n .catch(() => {});\n\n try {\n await api.chat.send(content, threadId);\n // Reload threads in background to pick up new thread\n reloadThreads();\n } catch {\n setWaiting(false);\n clearStreaming();\n resetSteps();\n addMessage({\n id: crypto.randomUUID(),\n role: \"system\",\n content: \"Failed to send message. Please try again.\",\n timestamp: new Date().toISOString(),\n });\n }\n }\n\n async function handleDeleteThread(id: string) {\n try {\n await api.chat.threads.delete(id);\n if (activeThreadId === id) {\n setActiveThread(null);\n clearMessages();\n }\n reloadThreads();\n } catch {\n // ignore\n }\n }\n\n function handleNewThread() {\n const newId = `web:${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n setActiveThread(newId);\n clearMessages();\n reloadThreads();\n navigate(`/chat/${newId}`);\n }\n\n function handleSelectThread(id: string) {\n setActiveThread(id);\n navigate(`/chat/${id}`);\n }\n\n function handleExportThread(id: string) {\n const thread = threads.find((t) => t.id === id);\n if (!thread) return;\n const content = thread.messages\n .map((m) => `[${m.role}] ${m.content}`)\n .join(\"\\n\\n---\\n\\n\");\n const blob = new Blob([content], { type: \"text/plain\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `${thread.title || \"conversation\"}-${id.slice(0, 8)}.txt`;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n const isBusy = isStreaming || waiting;\n const hasSteps = totalSteps > 0;\n const stepProgress =\n totalSteps > 0 ? (completedSteps / totalSteps) * 100 : 0;\n\n return (\n <div className=\"flex h-full w-full overflow-hidden\">\n {/* ── Thread Sidebar (desktop) ── */}\n <div\n className={cn(\n \"hidden h-full shrink-0 border-r border-border bg-background transition-[width] duration-200 ease-in-out md:block overflow-hidden\",\n sidebarOpen ? \"w-[240px]\" : \"w-0 border-r-0\"\n )}\n >\n <div className=\"h-full w-[240px]\">\n <ThreadList\n threads={threads}\n activeThreadId={activeThreadId}\n onSelect={handleSelectThread}\n onDelete={handleDeleteThread}\n onNew={handleNewThread}\n onExport={handleExportThread}\n />\n </div>\n </div>\n\n {/* ── Mobile sidebar overlay ── */}\n <AnimatePresence>\n {sidebarOpen && (\n <>\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"fixed inset-0 z-40 bg-black/50 backdrop-blur-sm md:hidden\"\n onClick={() => setSidebarOpen(false)}\n />\n <motion.div\n initial={{ x: -260 }}\n animate={{ x: 0 }}\n exit={{ x: -260 }}\n transition={{ duration: 0.2, ease: \"easeInOut\" }}\n className=\"fixed inset-y-0 left-0 z-50 w-[260px] bg-background shadow-xl md:hidden\"\n >\n <ThreadList\n threads={threads}\n activeThreadId={activeThreadId}\n onSelect={(id) => {\n handleSelectThread(id);\n setSidebarOpen(false);\n }}\n onDelete={handleDeleteThread}\n onNew={() => {\n handleNewThread();\n setSidebarOpen(false);\n }}\n onExport={handleExportThread}\n />\n </motion.div>\n </>\n )}\n </AnimatePresence>\n\n {/* ── Main Chat Area ── */}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {/* Header */}\n <header className=\"flex h-12 items-center gap-2 border-b border-border bg-background/80 backdrop-blur-xl px-3\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setSidebarOpen(!sidebarOpen)}\n >\n {sidebarOpen ? (\n <PanelLeftClose className=\"h-4 w-4\" />\n ) : (\n <PanelLeftOpen className=\"h-4 w-4\" />\n )}\n </Button>\n\n {/* Logo */}\n <span className=\"hidden text-sm font-bold mercury-gradient-text sm:inline\">\n Mercury\n </span>\n\n <div className=\"mx-1 h-4 w-px bg-border\" />\n\n <ModelSwitcher currentProvider={provider} currentModel={model} />\n\n <div className=\"flex-1\" />\n\n <CodeModeToggle />\n\n {/* Connection indicator */}\n <div\n className={cn(\n \"h-2 w-2 rounded-full\",\n connected ? \"bg-emerald-500\" : \"bg-destructive\"\n )}\n title={connected ? \"Connected\" : \"Disconnected\"}\n />\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setWorkspaceOpen(!workspaceOpen)}\n >\n <FolderOpen className=\"h-4 w-4\" />\n </Button>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 hidden md:inline-flex\"\n onClick={() => (window.location.href = \"/settings\")}\n >\n <Settings className=\"h-4 w-4\" />\n </Button>\n </header>\n\n {/* Messages */}\n <div className=\"relative flex-1 min-h-0\">\n <div\n ref={containerRef}\n onScroll={handleScroll}\n className=\"h-full overflow-y-auto\"\n >\n <div className=\"mx-auto max-w-3xl space-y-4 px-4 py-6\">\n {threadsLoading && messages.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-24\">\n <Loader2 className=\"h-6 w-6 animate-spin text-primary\" />\n </div>\n ) : messages.length === 0 && !isStreaming && !waiting ? (\n <div className=\"flex flex-col items-center justify-center gap-3 py-24 text-center\">\n <div className=\"rounded-2xl bg-primary/10 p-4\">\n <MessageSquare className=\"h-8 w-8 text-primary\" />\n </div>\n <h3 className=\"text-lg font-semibold text-foreground\">\n Start a conversation\n </h3>\n <p className=\"max-w-sm text-sm text-muted-foreground\">\n Send a message to begin. Mercury is ready to assist you.\n </p>\n </div>\n ) : (\n <>\n {messages.map((msg) => {\n // Permission prompt detection for system messages\n if (msg.role === \"system\") {\n try {\n const parsed = JSON.parse(msg.content);\n if (parsed.id && (parsed.tool || parsed.description)) {\n return <PermissionPrompt key={msg.id} data={parsed} />;\n }\n } catch {\n // not a permission prompt, render as regular message\n }\n }\n return <MessageBubbleComponent key={msg.id} message={msg} />;\n })}\n {isStreaming && streamingText && (\n <StreamingMessage text={streamingText} />\n )}\n {waiting && !isStreaming && <WaitingIndicator />}\n </>\n )}\n </div>\n </div>\n\n {/* Scroll-to-bottom */}\n <AnimatePresence>\n {!atBottom && (\n <motion.div\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 10 }}\n className=\"absolute bottom-4 right-4\"\n >\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"h-9 w-9 rounded-full shadow-lg border-border bg-background/90 backdrop-blur-sm\"\n onClick={scrollToBottom}\n >\n <ArrowDown className=\"h-4 w-4\" />\n </Button>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n\n {/* Step progress */}\n {hasSteps && (\n <div className=\"px-4 py-1.5\">\n <div className=\"mx-auto max-w-3xl\">\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground mb-1\">\n <Loader2 className=\"h-3 w-3 animate-spin text-primary\" />\n <span>\n Step {completedSteps} of {totalSteps}\n {currentStepTool && (\n <span className=\"ml-1 text-foreground font-medium\">\n — {currentStepTool}\n </span>\n )}\n </span>\n </div>\n <Progress value={stepProgress} className=\"h-1\" />\n </div>\n </div>\n )}\n\n {/* Chat input */}\n <ChatInput onSend={handleSend} disabled={isBusy} />\n </div>\n\n {/* ── Workspace Panel ── */}\n <AnimatePresence mode=\"wait\">\n {workspaceOpen && (\n <motion.div\n initial={{ width: 0, opacity: 0 }}\n animate={{ width: 320, opacity: 1 }}\n exit={{ width: 0, opacity: 0 }}\n transition={{ duration: 0.2, ease: \"easeInOut\" }}\n className=\"hidden h-full shrink-0 overflow-hidden md:block\"\n >\n <div className=\"h-full w-[320px]\">\n <WorkspacePanel\n open={workspaceOpen}\n onClose={() => setWorkspaceOpen(false)}\n />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n"],"names":["__iconNode","File","createLucideIcon","PanelLeftClose","PanelLeftOpen","Wrench","ThreadList","threads","activeThreadId","onSelect","onDelete","onNew","onExport","deleteTarget","setDeleteTarget","useState","formatDate","iso","d","diffMs","diffDays","jsxs","jsx","Button","Plus","ScrollArea","MessageSquare","thread","isActive","ThreadItem","AlertDialog","open","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","cn","e","Trash2","EXT_LANG_MAP","getLanguage","ext","formatSize","bytes","WorkspacePanel","onClose","tree","setTree","file","setFile","loading","setLoading","fileLoading","setFileLoading","error","setError","loadTree","useCallback","path","data","api","err","loadFile","initialized","setInitialized","breadcrumbs","relative","parts","accumulated","part","navigateUp","X","bc","ChevronRight","Loader2","ArrowUp","item","rel","newPath","filePath","Folder","SyntaxHighlighter","oneDark","Popover","PopoverPrimitive.Root","PopoverTrigger","PopoverPrimitive.Trigger","PopoverContent","React.forwardRef","className","align","sideOffset","props","ref","PopoverPrimitive.Portal","PopoverPrimitive.Content","ModelSwitcher","currentProvider","currentModel","setOpen","models","setModels","switching","setSwitching","setProvider","useChatStore","s","setModel","loadModels","handleSwitch","providerName","p","pr","displayName","o","ChevronDown","isSwitching","Check","Badge","STATES","CodeModeToggle","status","setStatus","loadStatus","useEffect","handleSet","state","result","prev","statusConfig","CheckCircle2","XCircle","ToolCallCard","tool","config","StatusIcon","Collapsible","CollapsibleTrigger","CollapsibleContent","MessageBubble","message","isLast","copied","setCopied","isUser","resolved","useThemeStore","handleCopy","motion","_a","step","i","MarkdownRenderer","Copy","StreamingMessage","text","steps","isThinking","useThreads","setThreads","threadVersion","load","useAutoScroll","deps","containerRef","useRef","atBottom","setAtBottom","userScrolledUp","scrollToBottom","el","handleScroll","isAtBottom","WaitingIndicator","PermissionPrompt","resolving","setResolving","handle","action","Zap","SLASH_COMMANDS","SlashCommandMenu","filter","selectedIndex","filtered","c","cmd","ChatInput","onSend","disabled","setText","showSlash","setShowSlash","slashIndex","setSlashIndex","textareaRef","slashFilter","filteredCommands","handleSubmit","trimmed","selectSlashCommand","needsArg","handleKeyDown","handleChange","value","firstLine","handleInput","AnimatePresence","Send","ChatPage","urlThreadId","useParams","navigate","useNavigate","connected","useSSE","threadsLoading","reloadThreads","messages","streamingText","isStreaming","waiting","provider","model","totalSteps","completedSteps","currentStepTool","setActiveThread","addMessage","clearMessages","setWaiting","clearStreaming","resetSteps","bumpThreadVersion","sidebarOpen","setSidebarOpen","workspaceOpen","setWorkspaceOpen","m","handleSend","content","threadId","handleDeleteThread","id","handleNewThread","newId","handleSelectThread","handleExportThread","t","blob","url","a","isBusy","hasSteps","stepProgress","Fragment","FolderOpen","Settings","msg","parsed","MessageBubbleComponent","ArrowDown","Progress"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
@@ -1,2 +1,2 @@
1
- import{j as e,m as c}from"./vendor-motion-Dwx3-JO5.js";import{r as x}from"./vendor-react-C7pctHW3.js";import{C as u,a as p,b as j,c as f}from"./card-DAYo4Zl5.js";import{P as w}from"./progress-DMwOdxli.js";import{B as h}from"./badge-DfDJNUtd.js";import{a as k,c as N,C as B,f as P,b,B as y,d as S}from"./index-BhxU0YlT.js";import{Z as T}from"./zap-C-0oH5gt.js";import{A as E}from"./activity-CIP1IzSg.js";import{C as U}from"./circle-check-DweDcOkA.js";import{C as A}from"./circle-x-BmL20etA.js";import"./vendor-radix-3UdfCgs_.js";import"./index-CUT6Fr2C.js";import"./vendor-syntax-xZUI6Op9.js";const g={hidden:{opacity:0,y:12},visible:s=>({opacity:1,y:0,transition:{delay:s*.07,duration:.35,ease:"easeOut"}})};function i({className:s}){return e.jsx("div",{className:N("animate-pulse rounded-lg bg-muted",s)})}function n({icon:s,label:d,children:r,index:m,glow:o}){return e.jsx(c.div,{custom:m,variants:g,initial:"hidden",animate:"visible",children:e.jsxs(u,{className:N(o&&"mercury-glow-sm"),children:[e.jsxs(p,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(j,{className:"text-sm font-medium text-muted-foreground",children:d}),e.jsx(s,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsx(f,{children:r})]})})}function I(){const[s,d]=x.useState(null),[r,m]=x.useState("");if(x.useEffect(()=>{k.status.get().then(d).catch(a=>m(a.message))},[]),r)return e.jsx("div",{className:"flex h-full items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-destructive",children:r})});if(!s)return e.jsxs("div",{className:"space-y-6 p-6 lg:p-8",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(i,{className:"h-8 w-40"}),e.jsx(i,{className:"h-4 w-56"})]}),e.jsx("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:Array.from({length:4}).map((a,t)=>e.jsx(i,{className:"h-[120px]"},t))}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(i,{className:"h-[200px]"}),e.jsx(i,{className:"h-[200px]"})]})]});const o=s.tokens.dailyBudget?Math.min(Math.round(s.tokens.dailyUsed/s.tokens.dailyBudget*100),100):0,l=Object.entries(s.providers),C=l.filter(([,a])=>a.enabled).length,v=Object.entries(s.memory.byType);return e.jsxs("div",{className:"space-y-6 p-6 lg:p-8",children:[e.jsxs(c.div,{initial:{opacity:0,y:-8},animate:{opacity:1,y:0},transition:{duration:.3},children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Status"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Agent is"," ",e.jsx("span",{className:N("font-medium",s.running?"text-emerald-500":"text-muted-foreground"),children:s.state})]})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(n,{icon:B,label:"Uptime",index:0,glow:!0,children:e.jsx("p",{className:"text-2xl font-bold tabular-nums",children:P(s.uptime)})}),e.jsxs(n,{icon:T,label:"Tokens Used",index:1,children:[e.jsxs("p",{className:"text-2xl font-bold tabular-nums",children:[b(s.tokens.dailyUsed),e.jsxs("span",{className:"ml-1 text-sm font-normal text-muted-foreground",children:["/ ",b(s.tokens.dailyBudget)]})]}),e.jsx(w,{value:o,className:"mt-3"})]}),e.jsx(n,{icon:y,label:"Total Memories",index:2,children:e.jsx("p",{className:"text-2xl font-bold tabular-nums",children:s.memory.total.toLocaleString()})}),e.jsx(n,{icon:S,label:"Active Providers",index:3,children:e.jsxs("p",{className:"text-2xl font-bold tabular-nums",children:[C,e.jsxs("span",{className:"ml-1 text-sm font-normal text-muted-foreground",children:["/ ",l.length]})]})})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(c.div,{custom:4,variants:g,initial:"hidden",animate:"visible",children:e.jsxs(u,{children:[e.jsx(p,{children:e.jsxs(j,{className:"flex items-center gap-2 text-base",children:[e.jsx(y,{className:"h-4 w-4"}),"Memory by Type"]})}),e.jsx(f,{children:v.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No memories stored yet."}):e.jsx("div",{className:"flex flex-col gap-3",children:v.map(([a,t])=>e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(h,{variant:"secondary",className:"capitalize",children:a}),e.jsx("span",{className:"text-sm font-medium tabular-nums",children:t.toLocaleString()})]},a))})})]})}),e.jsx(c.div,{custom:5,variants:g,initial:"hidden",animate:"visible",children:e.jsxs(u,{children:[e.jsx(p,{children:e.jsxs(j,{className:"flex items-center gap-2 text-base",children:[e.jsx(E,{className:"h-4 w-4"}),"Providers"]})}),e.jsx(f,{children:l.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No providers configured."}):e.jsx("div",{className:"flex flex-col gap-3",children:l.map(([a,t])=>e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-sm font-medium",children:a}),t.enabled?e.jsxs(h,{variant:"success",className:"gap-1",children:[e.jsx(U,{className:"h-3 w-3"}),"Enabled"]}):e.jsxs(h,{variant:"outline",className:"gap-1 text-muted-foreground",children:[e.jsx(A,{className:"h-3 w-3"}),"Disabled"]})]},a))})})]})})]})]})}export{I as DashboardPage};
2
- //# sourceMappingURL=Dashboard-B81ollv8.js.map
1
+ import{j as e,m as c}from"./vendor-motion-Dwx3-JO5.js";import{r as x}from"./vendor-react-C7pctHW3.js";import{C as u,a as p,b as j,c as f}from"./card-BdsEOP7t.js";import{P as w}from"./progress-ZzhsBV2v.js";import{B as h}from"./badge-CUJiWF1y.js";import{a as k,c as N,C as B,f as P,b,B as y,d as S}from"./index-C3YiF4qv.js";import{Z as T}from"./zap-BEfqVtvZ.js";import{A as E}from"./activity-MOTqH8zM.js";import{C as U}from"./circle-check-DvGSe1uZ.js";import{C as A}from"./circle-x-CyaGJ_BM.js";import"./vendor-radix-3UdfCgs_.js";import"./index-CaqLZNof.js";import"./vendor-syntax-xZUI6Op9.js";const g={hidden:{opacity:0,y:12},visible:s=>({opacity:1,y:0,transition:{delay:s*.07,duration:.35,ease:"easeOut"}})};function i({className:s}){return e.jsx("div",{className:N("animate-pulse rounded-lg bg-muted",s)})}function n({icon:s,label:d,children:r,index:m,glow:o}){return e.jsx(c.div,{custom:m,variants:g,initial:"hidden",animate:"visible",children:e.jsxs(u,{className:N(o&&"mercury-glow-sm"),children:[e.jsxs(p,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(j,{className:"text-sm font-medium text-muted-foreground",children:d}),e.jsx(s,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsx(f,{children:r})]})})}function I(){const[s,d]=x.useState(null),[r,m]=x.useState("");if(x.useEffect(()=>{k.status.get().then(d).catch(a=>m(a.message))},[]),r)return e.jsx("div",{className:"flex h-full items-center justify-center p-8",children:e.jsx("p",{className:"text-sm text-destructive",children:r})});if(!s)return e.jsxs("div",{className:"space-y-6 p-6 lg:p-8",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(i,{className:"h-8 w-40"}),e.jsx(i,{className:"h-4 w-56"})]}),e.jsx("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:Array.from({length:4}).map((a,t)=>e.jsx(i,{className:"h-[120px]"},t))}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(i,{className:"h-[200px]"}),e.jsx(i,{className:"h-[200px]"})]})]});const o=s.tokens.dailyBudget?Math.min(Math.round(s.tokens.dailyUsed/s.tokens.dailyBudget*100),100):0,l=Object.entries(s.providers),C=l.filter(([,a])=>a.enabled).length,v=Object.entries(s.memory.byType);return e.jsxs("div",{className:"space-y-6 p-6 lg:p-8",children:[e.jsxs(c.div,{initial:{opacity:0,y:-8},animate:{opacity:1,y:0},transition:{duration:.3},children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Status"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Agent is"," ",e.jsx("span",{className:N("font-medium",s.running?"text-emerald-500":"text-muted-foreground"),children:s.state})]})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(n,{icon:B,label:"Uptime",index:0,glow:!0,children:e.jsx("p",{className:"text-2xl font-bold tabular-nums",children:P(s.uptime)})}),e.jsxs(n,{icon:T,label:"Tokens Used",index:1,children:[e.jsxs("p",{className:"text-2xl font-bold tabular-nums",children:[b(s.tokens.dailyUsed),e.jsxs("span",{className:"ml-1 text-sm font-normal text-muted-foreground",children:["/ ",b(s.tokens.dailyBudget)]})]}),e.jsx(w,{value:o,className:"mt-3"})]}),e.jsx(n,{icon:y,label:"Total Memories",index:2,children:e.jsx("p",{className:"text-2xl font-bold tabular-nums",children:s.memory.total.toLocaleString()})}),e.jsx(n,{icon:S,label:"Active Providers",index:3,children:e.jsxs("p",{className:"text-2xl font-bold tabular-nums",children:[C,e.jsxs("span",{className:"ml-1 text-sm font-normal text-muted-foreground",children:["/ ",l.length]})]})})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(c.div,{custom:4,variants:g,initial:"hidden",animate:"visible",children:e.jsxs(u,{children:[e.jsx(p,{children:e.jsxs(j,{className:"flex items-center gap-2 text-base",children:[e.jsx(y,{className:"h-4 w-4"}),"Memory by Type"]})}),e.jsx(f,{children:v.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No memories stored yet."}):e.jsx("div",{className:"flex flex-col gap-3",children:v.map(([a,t])=>e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(h,{variant:"secondary",className:"capitalize",children:a}),e.jsx("span",{className:"text-sm font-medium tabular-nums",children:t.toLocaleString()})]},a))})})]})}),e.jsx(c.div,{custom:5,variants:g,initial:"hidden",animate:"visible",children:e.jsxs(u,{children:[e.jsx(p,{children:e.jsxs(j,{className:"flex items-center gap-2 text-base",children:[e.jsx(E,{className:"h-4 w-4"}),"Providers"]})}),e.jsx(f,{children:l.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No providers configured."}):e.jsx("div",{className:"flex flex-col gap-3",children:l.map(([a,t])=>e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-sm font-medium",children:a}),t.enabled?e.jsxs(h,{variant:"success",className:"gap-1",children:[e.jsx(U,{className:"h-3 w-3"}),"Enabled"]}):e.jsxs(h,{variant:"outline",className:"gap-1 text-muted-foreground",children:[e.jsx(A,{className:"h-3 w-3"}),"Disabled"]})]},a))})})]})})]})]})}export{I as DashboardPage};
2
+ //# sourceMappingURL=Dashboard-1rlAqQ-Y.js.map