@runfusion/fusion 0.24.0 → 0.25.0

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 (106) hide show
  1. package/dist/bin.js +2254 -1349
  2. package/dist/client/assets/AgentDetailView-ZbHEbYRT.js +18 -0
  3. package/dist/client/assets/{AgentsView-BkB9FiMT.js → AgentsView-B3jYk8Kt.js} +3 -3
  4. package/dist/client/assets/ChatView-DhPkiEGs.js +1 -0
  5. package/dist/client/assets/{DevServerView-BkvtjZBa.js → DevServerView-DyGDEiBP.js} +1 -1
  6. package/dist/client/assets/{DirectoryPicker-BK-KbnhP.js → DirectoryPicker-D5UIeIl6.js} +1 -1
  7. package/dist/client/assets/{DocumentsView-BEg1CQAk.js → DocumentsView-DNHu1T8K.js} +1 -1
  8. package/dist/client/assets/{EvalsView-Berf9bQm.js → EvalsView-CpRobtDi.js} +1 -1
  9. package/dist/client/assets/{ExperimentalAgentOnboardingModal-jcInE50G.js → ExperimentalAgentOnboardingModal-DOY_oZi7.js} +1 -1
  10. package/dist/client/assets/{InsightsView-BX5bSF1J.js → InsightsView-vp0RE8Mg.js} +1 -1
  11. package/dist/client/assets/MemoryView-PSc5lGJt.js +2 -0
  12. package/dist/client/assets/MemoryView-zaXewZzi.css +1 -0
  13. package/dist/client/assets/{NodesView-DLUOBLf6.js → NodesView-DMj6HGeC.js} +1 -1
  14. package/dist/client/assets/{PiExtensionsManager-COlJf0Kx.js → PiExtensionsManager-DL_QcN56.js} +2 -2
  15. package/dist/client/assets/PluginManager-BtYKm8IT.js +1 -0
  16. package/dist/client/assets/{ResearchView-B256Lr8I.js → ResearchView-BhWqfdV0.js} +1 -1
  17. package/dist/client/assets/{SettingsModal-BeA_nQtW.js → SettingsModal-BAgB4_AR.js} +4 -4
  18. package/dist/client/assets/{SettingsModal-yRqM4DV8.js → SettingsModal-CUCyaAyE.js} +1 -1
  19. package/dist/client/assets/{SetupWizardModal-uUZk3TKT.js → SetupWizardModal-BKscasuh.js} +1 -1
  20. package/dist/client/assets/{SkillsView-CP8JX0P_.js → SkillsView-BdELqTy7.js} +1 -1
  21. package/dist/client/assets/{TodoView-DCRIkDZ-.js → TodoView-DFNGBDNV.js} +1 -1
  22. package/dist/client/assets/{folder-open-DHjELt8-.js → folder-open-k1xmUMyr.js} +1 -1
  23. package/dist/client/assets/index-Qq2JOOWx.css +1 -0
  24. package/dist/client/assets/{index-CQyVRLOb.js → index-TFYXEVpn.js} +160 -160
  25. package/dist/client/assets/{star-DYesq1AV.js → star-ne32r3Y4.js} +1 -1
  26. package/dist/client/assets/{upload-DTWF3Db5.js → upload-MS-2Gx53.js} +1 -1
  27. package/dist/client/assets/{users--syrel4l.js → users-C519GSjH.js} +1 -1
  28. package/dist/client/index.html +2 -2
  29. package/dist/client/version.json +1 -1
  30. package/dist/droid-cli/package.json +1 -1
  31. package/dist/extension.js +1370 -629
  32. package/dist/pi-claude-cli/package.json +1 -1
  33. package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +9 -11
  34. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  35. package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +30 -0
  36. package/dist/plugins/fusion-plugin-dependency-graph/package.json +3 -28
  37. package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +899 -895
  38. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  39. package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +68 -71
  40. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  41. package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +47 -50
  42. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  43. package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +155 -109
  44. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  45. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  46. package/dist/plugins/fusion-plugin-reports/src/index.ts +49 -3
  47. package/dist/plugins/fusion-plugin-reports/src/report-schema.ts +38 -0
  48. package/dist/plugins/fusion-plugin-reports/src/store/__tests__/report-schema.test.ts +66 -0
  49. package/dist/plugins/fusion-plugin-reports/src/store/__tests__/report-store.test.ts +177 -0
  50. package/dist/plugins/fusion-plugin-reports/src/store/report-store.ts +341 -0
  51. package/dist/plugins/fusion-plugin-reports/src/store/report-types.ts +77 -0
  52. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  53. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  54. package/package.json +1 -1
  55. package/dist/client/assets/AgentDetailView-gy_5SUj2.js +0 -18
  56. package/dist/client/assets/ChatView-B_-B8fqu.js +0 -1
  57. package/dist/client/assets/MemoryView-CKElJY_3.js +0 -2
  58. package/dist/client/assets/MemoryView-DiajLXby.css +0 -1
  59. package/dist/client/assets/PluginManager-CfW55BF4.js +0 -1
  60. package/dist/client/assets/createLucideIcon-BazL2hk5.js +0 -21
  61. package/dist/client/assets/dashboard-view-BkTMSZYn.css +0 -1
  62. package/dist/client/assets/dashboard-view-CyWN-d02.js +0 -63
  63. package/dist/client/assets/dashboard-view-DdGlfuu-.css +0 -1
  64. package/dist/client/assets/dashboard-view-lR7YYmSC.js +0 -21
  65. package/dist/client/assets/index-CxA2Nn0_.css +0 -1
  66. package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.css +0 -58
  67. package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.tsx +0 -301
  68. package/dist/plugins/fusion-plugin-dependency-graph/src/GraphHighlight.css +0 -27
  69. package/dist/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.css +0 -157
  70. package/dist/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.tsx +0 -126
  71. package/dist/plugins/fusion-plugin-dependency-graph/src/GraphToolbar.css +0 -35
  72. package/dist/plugins/fusion-plugin-dependency-graph/src/GraphToolbar.tsx +0 -36
  73. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraph.highlighting.test.tsx +0 -112
  74. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraph.persistence.test.tsx +0 -115
  75. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraph.test.tsx +0 -128
  76. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.drag.test.tsx +0 -82
  77. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.test.tsx +0 -307
  78. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphToolbar.test.tsx +0 -60
  79. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/edges.test.tsx +0 -75
  80. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/filtering.test.tsx +0 -62
  81. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/filters.test.ts +0 -78
  82. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/graphPositionStorage.test.ts +0 -95
  83. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/host-integration.test.ts +0 -74
  84. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/index.test.ts +0 -58
  85. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/interactions.test.tsx +0 -121
  86. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/layout.test.ts +0 -70
  87. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/persistence.test.tsx +0 -89
  88. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useGraphData.test.ts +0 -86
  89. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useGraphInteraction.test.ts +0 -167
  90. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useGraphPositions.test.ts +0 -66
  91. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useNodeDrag.test.ts +0 -81
  92. package/dist/plugins/fusion-plugin-dependency-graph/src/dashboard-interop.d.ts +0 -35
  93. package/dist/plugins/fusion-plugin-dependency-graph/src/dashboard-view.tsx +0 -19
  94. package/dist/plugins/fusion-plugin-dependency-graph/src/edges.tsx +0 -70
  95. package/dist/plugins/fusion-plugin-dependency-graph/src/filters.ts +0 -8
  96. package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/__tests__/useDependencyChain.test.ts +0 -53
  97. package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/useDependencyChain.ts +0 -60
  98. package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/useGraphPositions.ts +0 -45
  99. package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/useNodeDrag.ts +0 -114
  100. package/dist/plugins/fusion-plugin-dependency-graph/src/index.ts +0 -24
  101. package/dist/plugins/fusion-plugin-dependency-graph/src/layout.ts +0 -91
  102. package/dist/plugins/fusion-plugin-dependency-graph/src/styles/drag.css +0 -15
  103. package/dist/plugins/fusion-plugin-dependency-graph/src/types.ts +0 -21
  104. package/dist/plugins/fusion-plugin-dependency-graph/src/useGraphData.ts +0 -17
  105. package/dist/plugins/fusion-plugin-dependency-graph/src/useGraphInteraction.ts +0 -292
  106. package/dist/plugins/fusion-plugin-dependency-graph/src/utils/graphPositionStorage.ts +0 -65
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/roadmap",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "Roadmap plugin package for Fusion",
6
6
  "private": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/whatsapp-chat",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "WhatsApp Web (Baileys) chat bridge for Fusion agents",
6
6
  "keywords": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runfusion/fusion",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "license": "MIT",
5
5
  "description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
6
6
  "homepage": "https://github.com/Runfusion/Fusion#readme",
@@ -1,18 +0,0 @@
1
- import{r as t,j as e}from"./vendor-react-K0fH_qHe.js";import{c as Ns,dy as yt,dz as St,dA as kt,dB as Ct,L as B,R as os,ap as Ds,Z as wt,aq as ms,W as rs,a as qs,b as Gs,dC as Rt,dD as Mt,dE as Ft,v as Ys,cH as At,dF as Tt,z as G,dG as Et,dH as Ks,dI as Zs,dJ as Pt,s as as,bp as Qs,k as Xs,U as hs,V as zs,aQ as Le,X as et,F as Ve,dK as Lt,A as ns,cf as st,dL as tt,dM as $t,cB as Dt,an as zt,bo as Ht,ar as at,B as ys,Y as Ot,a2 as Bt,a4 as It,dN as ps,l as nt,dO as Ut,bz as _t,r as Vt,ao as it,a1 as rt,dP as Jt,C as de,dQ as lt,dR as Hs,bq as Os,dS as Wt,dT as qt,dU as Gt,dV as Je,a9 as We,ab as qe,ac as Ge,a7 as ot,dW as Yt,dX as Kt,i as Zt,h as Qt,j as Bs,$ as Xt,dY as ea,dZ as sa,m as ta,d_ as js,d$ as aa,a3 as na,e0 as ia,O as ra,e1 as la,e2 as oa,e3 as ct,e4 as ca,e5 as da,e6 as ua,e7 as ma,e8 as ha}from"./index-CQyVRLOb.js";import{S as dt}from"./star-DYesq1AV.js";import{f as fs,S as fa,E as ga}from"./ExperimentalAgentOnboardingModal-jcInE50G.js";import"./vendor-xterm-DzcZoU0P.js";/**
2
- * @license lucide-react v1.7.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const xa=[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]],is=Ns("chart-column",xa);/**
7
- * @license lucide-react v1.7.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const ba=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M17 12h-2l-2 5-2-10-2 5H7",key:"15hlnc"}]],va=Ns("square-activity",ba);/**
12
- * @license lucide-react v1.7.0 - ISC
13
- *
14
- * This source code is licensed under the ISC license.
15
- * See the LICENSE file in the root directory of this source tree.
16
- */const pa=[["path",{d:"M16 17h6v-6",key:"t6n2it"}],["path",{d:"m22 17-8.5-8.5-5 5L2 7",key:"x473p"}]],ja=Ns("trending-down",pa);function Is(s){return s<1e3?`${s}ms`:s<6e4?`${(s/1e3).toFixed(1)}s`:s<36e5?`${Math.floor(s/6e4)}m`:`${(s/36e5).toFixed(1)}h`}function Na(s){return`${Math.round(s*100)}%`}function Us(s){const n=Date.now(),i=new Date(s).getTime(),o=n-i;if(o<0){const u=Math.abs(o);return u<6e4?"in a moment":u<36e5?`in ${Math.floor(u/6e4)}m`:u<864e5?`in ${Math.floor(u/36e5)}h`:`in ${Math.floor(u/864e5)}d`}return o<6e4?"just now":o<36e5?`${Math.floor(o/6e4)}m ago`:o<864e5?`${Math.floor(o/36e5)}h ago`:`${Math.floor(o/864e5)}d ago`}function ya(s){switch(s){case"periodic":return"Periodic";case"post-task":return"Post-Task";case"manual":return"Manual";case"user-requested":return"User Requested";default:return s}}function Ue(s){return s instanceof Error&&s.message?s.message:String(s)}function Sa(s){switch(s){case"improving":return"↑ Improving";case"declining":return"↓ Declining";case"stable":return"→ Stable";default:return"Insufficient data"}}function ka(s){switch(s){case"improving":return"trend-improving";case"declining":return"trend-declining";case"stable":return"trend-stable";default:return"trend-insufficient"}}function _s(s,n=5){return e.jsx("span",{className:"rating-stars",children:Array.from({length:n},(i,o)=>e.jsx(dt,{size:14,className:o<s?"star-filled":"star-empty",fill:o<s?"currentColor":"none"},o))})}function Ca({agentId:s,projectId:n,addToast:i}){const[o,u]=t.useState([]),[g,R]=t.useState(null),[d,M]=t.useState(null),[k,F]=t.useState([]),[c,x]=t.useState(!0),[A,z]=t.useState(!0),[N,y]=t.useState(!1),[J,m]=t.useState(!1),[K,ee]=t.useState(null),[C,T]=t.useState(0),[j,E]=t.useState(""),[V,$]=t.useState(""),q=t.useCallback(async()=>{try{const[r,l]=await Promise.all([yt(s,20,n),St(s,void 0,n)]);u(r),R(l)}catch(r){i(`Failed to load reflections: ${Ue(r)}`,"error")}finally{x(!1)}},[s,n,i]),w=t.useCallback(async()=>{try{const[r,l]=await Promise.all([kt(s,n),Ct(s,{limit:50},n)]);M(r),F(l)}catch(r){i(`Failed to load ratings: ${Ue(r)}`,"error")}finally{z(!1)}},[s,n,i]);t.useEffect(()=>{q(),w()},[q,w]);const Q=async()=>{y(!0);try{if(!await Rt(s,n)){i("Not enough history to generate a reflection yet","error");return}i("Reflection generated successfully","success"),x(!0),await q()}catch(r){const l=Ue(r),p=l.toLowerCase();p.includes("agent not found")||p.includes("not found")?i("This agent is no longer available. It may have been deleted.","error"):p.includes("insufficient history")?i("Not enough history to generate a reflection yet","error"):i(`Failed to generate reflection: ${l}`,"error")}finally{y(!1)}},P=async r=>{if(r.preventDefault(),C!==0){m(!0);try{await Mt(s,{score:C,category:j||void 0,comment:V||void 0,raterType:"user"},n),T(0),E(""),$(""),i("Rating added","success"),await w()}catch(l){i(`Failed to add rating: ${Ue(l)}`,"error")}finally{m(!1)}}},O=async r=>{try{await Ft(s,r,n),i("Rating deleted","success"),await w()}catch(l){i(`Failed to delete rating: ${Ue(l)}`,"error")}},f=r=>{ee(l=>l===r?null:r)};if(c&&A)return e.jsx("div",{className:"reflections-tab",children:e.jsxs("div",{className:"reflections-loading-indicator",children:[e.jsx(B,{size:16,className:"animate-spin"}),e.jsx("span",{className:"text-muted",children:"Loading evaluation..."})]})});const b=g&&g.totalTasksCompleted===0&&g.totalTasksFailed===0&&g.recentReflectionCount===0;return e.jsxs("div",{className:"reflections-tab",children:[e.jsxs("div",{className:"reflections-header",children:[e.jsxs("h3",{children:[e.jsx(is,{size:16}),"Performance, Reflections & Ratings"]}),e.jsx("button",{className:"btn btn-secondary",onClick:Q,disabled:N,title:"Generate a manual reflection",children:N?e.jsxs(e.Fragment,{children:[e.jsx(B,{size:14,className:"animate-spin"}),"Reflecting..."]}):e.jsxs(e.Fragment,{children:[e.jsx(os,{size:14}),"Reflect Now"]})})]}),g&&!b&&e.jsxs("div",{className:"reflections-stats-grid",children:[e.jsxs("div",{className:"reflections-stat-card",children:[e.jsxs("div",{className:"stat-value",children:[e.jsx(Ds,{size:16,style:{color:"var(--color-success)"}}),g.totalTasksCompleted]}),e.jsx("div",{className:"stat-label",children:"Tasks Completed"})]}),e.jsxs("div",{className:"reflections-stat-card",children:[e.jsxs("div",{className:"stat-value",children:[e.jsx(ja,{size:16,style:{color:"var(--color-error)"}}),g.totalTasksFailed]}),e.jsx("div",{className:"stat-label",children:"Tasks Failed"})]}),e.jsxs("div",{className:"reflections-stat-card",children:[e.jsxs("div",{className:"stat-value",children:[e.jsx(wt,{size:16,style:{color:"var(--in-progress)"}}),Is(g.avgDurationMs)]}),e.jsx("div",{className:"stat-label",children:"Avg Duration"})]}),e.jsxs("div",{className:"reflections-stat-card",children:[e.jsxs("div",{className:"stat-value",children:[e.jsx(is,{size:16,style:{color:g.successRate>=.8?"var(--color-success)":g.successRate>=.5?"var(--color-warning)":"var(--color-error)"}}),Na(g.successRate)]}),e.jsx("div",{className:"stat-label",children:"Success Rate"})]}),e.jsxs("div",{className:"reflections-stat-card",children:[e.jsxs("div",{className:"stat-value",children:[e.jsx(ms,{size:16,style:{color:"var(--color-info)"}}),g.recentReflectionCount]}),e.jsx("div",{className:"stat-label",children:"Reflections"})]})]}),b&&e.jsxs("div",{className:"reflections-no-data",children:[e.jsx(is,{size:24,opacity:.3}),e.jsx("p",{children:"No performance data yet"})]}),e.jsxs("div",{className:"reflections-ratings-section",children:[e.jsx("h4",{children:"User Ratings"}),A?e.jsxs("div",{className:"reflections-loading-indicator",children:[e.jsx(B,{size:16,className:"animate-spin"}),e.jsx("span",{className:"text-muted",children:"Loading ratings..."})]}):e.jsxs(e.Fragment,{children:[d&&e.jsxs("div",{className:"rating-summary-card",children:[e.jsxs("div",{className:"rating-score-display",children:[e.jsx("span",{className:"rating-average",children:d.averageScore.toFixed(1)}),_s(Math.round(d.averageScore))]}),e.jsxs("div",{className:"rating-stats",children:[e.jsxs("span",{className:"rating-count",children:[d.totalRatings," ratings"]}),e.jsx("span",{className:`rating-trend-badge ${ka(d.trend)}`,children:Sa(d.trend)})]})]}),d&&Object.keys(d.categoryAverages).length>0&&e.jsxs("div",{className:"category-breakdown",children:[e.jsx("h4",{children:"Category Averages"}),Object.entries(d.categoryAverages).map(([r,l])=>e.jsxs("div",{className:"category-item",children:[e.jsx("span",{className:"category-name",children:r}),e.jsx("span",{className:"category-score",children:l.toFixed(1)})]},r))]}),e.jsxs("form",{className:"add-rating-form",onSubmit:P,children:[e.jsx("h4",{children:"Add Rating"}),e.jsx("div",{className:"star-selector",children:[1,2,3,4,5].map(r=>e.jsx("button",{type:"button",className:"star-btn touch-target",onClick:()=>T(r),title:`${r} star${r>1?"s":""}`,children:e.jsx(dt,{size:24,fill:r<=C?"currentColor":"none",className:r<=C?"star-filled":"star-empty"})},r))}),e.jsxs("select",{value:j,onChange:r=>E(r.target.value),className:"select add-rating-category-select",children:[e.jsx("option",{value:"",children:"Select category..."}),e.jsx("option",{value:"quality",children:"Quality"}),e.jsx("option",{value:"speed",children:"Speed"}),e.jsx("option",{value:"communication",children:"Communication"}),e.jsx("option",{value:"reliability",children:"Reliability"}),e.jsx("option",{value:"other",children:"Other"})]}),e.jsx("textarea",{value:V,onChange:r=>$(r.target.value),placeholder:"Optional comment...",className:"input add-rating-comment-input",rows:3}),e.jsx("button",{type:"submit",className:"btn btn-task-create",disabled:C===0||J,children:J?"Submitting...":"Submit Rating"})]}),e.jsxs("div",{className:"rating-history",children:[e.jsx("h4",{children:"Rating History"}),k.length===0?e.jsx("p",{className:"no-ratings",children:"No ratings yet"}):k.map(r=>e.jsxs("div",{className:"rating-history-item",children:[e.jsxs("div",{className:"rating-item-header",children:[_s(r.score),r.category&&e.jsx("span",{className:"rating-category-badge",children:r.category}),e.jsx("span",{className:"rating-time",children:Us(r.createdAt)}),e.jsx("button",{type:"button",className:"rating-delete-btn touch-target",onClick:()=>void O(r.id),title:"Delete rating",children:e.jsx(rs,{size:14})})]}),r.comment&&e.jsx("p",{className:"rating-comment",children:r.comment})]},r.id))]})]})]}),e.jsxs("div",{className:"reflections-list",children:[e.jsx("h4",{children:"Reflection History"}),c?e.jsxs("div",{className:"reflections-loading-indicator",children:[e.jsx(B,{size:16,className:"animate-spin"}),e.jsx("span",{className:"text-muted",children:"Loading reflections..."})]}):o.length===0?e.jsxs("div",{className:"reflection-empty",children:[e.jsx(ms,{size:32,opacity:.3}),e.jsx("p",{children:"No reflections yet"}),e.jsx("p",{className:"text-secondary",children:"Trigger a reflection to get started"})]}):e.jsx("div",{className:"reflection-cards",children:o.map(r=>{const l=K===r.id;return e.jsxs("div",{className:`reflection-card ${l?"reflection-card--expanded":""}`,onClick:()=>f(r.id),role:"button",tabIndex:0,onKeyDown:p=>p.key==="Enter"&&f(r.id),children:[e.jsxs("div",{className:"reflection-card-header",children:[e.jsx("span",{className:`reflection-trigger-badge reflection-trigger-${r.trigger}`,children:ya(r.trigger)}),e.jsx("span",{className:"reflection-timestamp",children:Us(r.timestamp)}),e.jsx("span",{className:"reflection-chevron",children:l?e.jsx(qs,{size:16}):e.jsx(Gs,{size:16})})]}),e.jsx("div",{className:"reflection-summary",children:r.summary}),l&&e.jsxs("div",{className:"reflection-details",children:[r.insights.length>0&&e.jsxs("div",{className:"reflection-insights",children:[e.jsxs("h5",{children:[e.jsx(ms,{size:14})," Insights"]}),e.jsx("ul",{children:r.insights.map((p,se)=>e.jsx("li",{children:p},se))})]}),r.suggestedImprovements.length>0&&e.jsxs("div",{className:"reflection-suggestions",children:[e.jsxs("h5",{children:[e.jsx(Ds,{size:14})," Suggested Improvements"]}),e.jsx("ul",{children:r.suggestedImprovements.map((p,se)=>e.jsx("li",{children:p},se))})]}),r.metrics&&e.jsxs("div",{className:"reflection-metrics",children:[e.jsx("h5",{children:"Metrics"}),e.jsxs("div",{className:"metrics-grid",children:[r.metrics.tasksCompleted!==void 0&&e.jsxs("div",{className:"metric",children:[e.jsx("span",{className:"metric-label",children:"Tasks:"}),e.jsx("span",{className:"metric-value",children:r.metrics.tasksCompleted})]}),r.metrics.tasksFailed!==void 0&&e.jsxs("div",{className:"metric",children:[e.jsx("span",{className:"metric-label",children:"Failed:"}),e.jsx("span",{className:"metric-value",children:r.metrics.tasksFailed})]}),r.metrics.avgDurationMs!==void 0&&e.jsxs("div",{className:"metric",children:[e.jsx("span",{className:"metric-label",children:"Avg Duration:"}),e.jsx("span",{className:"metric-value",children:Is(r.metrics.avgDurationMs)})]}),r.metrics.errorCount!==void 0&&e.jsxs("div",{className:"metric",children:[e.jsx("span",{className:"metric-label",children:"Errors:"}),e.jsx("span",{className:"metric-value",children:r.metrics.errorCount})]})]})]})]})]},r.id)})})]})]})}function ae(...s){return s.filter(Boolean).join(" ")}function $e(s){const n=Date.now(),i=new Date(s).getTime(),o=n-i;if(o<0){const u=Math.abs(o);return u<6e4?"in a moment":u<36e5?`in ${Math.floor(u/6e4)}m`:u<864e5?`in ${Math.floor(u/36e5)}h`:`in ${Math.floor(u/864e5)}d`}return o<6e4?"just now":o<36e5?`${Math.floor(o/6e4)}m ago`:o<864e5?`${Math.floor(o/36e5)}h ago`:`${Math.floor(o/864e5)}d ago`}const wa=[{id:"dashboard",label:"Dashboard",icon:va},{id:"logs",label:"Logs",icon:Ve},{id:"mail",label:"Mail",icon:Lt},{id:"runs",label:"Runs",icon:ns},{id:"tasks",label:"Tasks",icon:st},{id:"employees",label:"Employees",icon:tt},{id:"soul",label:"Soul",icon:$t},{id:"instructions",label:"Instructions",icon:Dt},{id:"memory",label:"Agent Memory",icon:Ve},{id:"reflections",label:"Evaluation",icon:is},{id:"config",label:"Settings",icon:zt}],Ss={idle:{bg:"var(--state-idle-bg)",text:"var(--state-idle-text)",border:"var(--state-idle-border)"},active:{bg:"var(--state-active-bg)",text:"var(--state-active-text)",border:"var(--state-active-border)"},running:{bg:"var(--state-active-bg)",text:"var(--state-active-text)",border:"var(--state-active-border)"},paused:{bg:"var(--state-paused-bg)",text:"var(--state-paused-text)",border:"var(--state-paused-border)"},error:{bg:"var(--state-error-bg)",text:"var(--state-error-text)",border:"var(--state-error-border)"}},ls={completed:{icon:de,color:"var(--color-success)"},failed:{icon:Jt,color:"var(--color-error)"},active:{icon:B,color:"var(--in-progress)"},terminated:{icon:Le,color:"var(--text-muted)"}},Vs={"long-term":"Long-term",daily:"Daily",dreams:"Dreams"},Ra={"long-term":"Curated durable decisions, conventions, constraints, and pitfalls for this specific agent.",daily:"Raw daily observations and open loops recorded by this agent.",dreams:"Synthesized patterns and emerging themes distilled from this agent's daily memory."},Ma=rt(js),Fa=700;function Aa(s,n){return s.some(i=>i.path===n)?n:s.find(i=>i.layer==="long-term")?.path??s[0]?.path??""}function Qa({agentId:s,projectId:n,onClose:i,addToast:o,onChildClick:u,inline:g=!1,showInlineBackButton:R=!1,initialTab:d,initialRunId:M,preferActiveRun:k=!1,onMutationSuccess:F}){const[c,x]=t.useState(null),{confirm:A}=Ys(),[z,N]=t.useState([]),[y,J]=t.useState(!0),[m,K]=t.useState(d??"dashboard"),[ee,C]=t.useState(!1),[T,j]=t.useState(!1),[E,V]=t.useState(null),[$,q]=t.useState(null),[w,Q]=t.useState(!1),[P,O]=t.useState(null),f=t.useRef(null),b=t.useRef(!1);At(f,!g,"fusion:agent-detail-modal-size");const r=t.useRef(i),l=t.useRef(o),p=t.useRef(null),se=t.useRef(!1),L=t.useRef(null),Y=t.useRef(0),ie=t.useRef(s),xe=t.useRef(n);r.current=i,l.current=o,p.current=c;const W=t.useCallback(async()=>{p.current===null&&J(!0);try{const I=await Tt(s,n);x(I)}catch(I){l.current(`Failed to load agent: ${G(I)}`,"error"),r.current()}finally{J(!1)}},[s,n]),H=t.useCallback(async()=>{const v=Y.current,I=s,X=n,ne=()=>Y.current!==v||s!==I||n!==X;try{if(c?.taskId){V(null),L.current=null;const Se=await Et(c.taskId,X,{limit:100});if(ne())return;N(Se.entries);return}const re=await Ks(I,1,X);if(ne())return;const he=re[0]??null;if(V(he),!he){L.current=null,N([]);return}if(L.current===he.id)return;const ye=await Zs(I,he.id,X);if(ne())return;N(ye),L.current=he.id}catch(re){if(ne())return;console.error("Failed to load agent logs:",re)}},[c?.taskId,s,n]),te=t.useCallback(async()=>{Q(!0),O(null);try{const v=await Pt(s,n);q(v)}catch(v){O(G(v)),q(null)}finally{Q(!1)}},[s,n]),De=t.useCallback(v=>{se.current=v},[]),Ne=t.useCallback(async(v=!1)=>{await F?.({agentId:s,deleted:v})},[s,F]),Re=t.useCallback(async()=>{await W(),await Ne(!1)},[W,Ne]);t.useEffect(()=>{W()},[W]),t.useEffect(()=>{const v=setInterval(()=>{W()},3e4);return()=>{clearInterval(v)}},[W]),t.useEffect(()=>{c&&m==="logs"&&H()},[c,m,H]),t.useEffect(()=>{m!=="logs"&&(L.current=null)},[m]),t.useEffect(()=>{c&&m==="mail"&&te()},[c,m,te]),t.useEffect(()=>{if(m!=="logs"||c?.taskId||!E||E.status!=="active")return;const v=Y.current,I=s,X=E.id,ne=n?`?projectId=${encodeURIComponent(n)}`:"",re=as(`/api/agents/${encodeURIComponent(I)}/runs/${encodeURIComponent(X)}/logs/stream${ne}`,{events:{"agent:log":he=>{if(Y.current===v)try{const ye=JSON.parse(he.data);N(Se=>[...Se,ye])}catch{}}},onOpen:()=>{Y.current===v&&C(!0)},onError:()=>{Y.current===v&&C(!1)}});return()=>{re(),Y.current===v&&C(!1)}},[m,c?.taskId,s,n,E]),t.useEffect(()=>{(ie.current!==s||xe.current!==n)&&(ie.current=s,xe.current=n,Y.current++,N([]),C(!1),V(null),q(null),O(null),L.current=null,se.current=!1)},[s,n]),t.useEffect(()=>{const v=n?`?projectId=${encodeURIComponent(n)}`:"",I=Y.current,X=ne=>{if(Y.current===I)try{const re=JSON.parse(ne.data);if(!re||typeof re!="object"||re.agentId!==s)return;W()}catch{}};return as(`/api/events${v}`,{events:{"agent:updated":ne=>{if(Y.current===I)try{const re=JSON.parse(ne.data);if(!re||typeof re!="object"||re.id!==s||se.current)return;W()}catch{}},"approval:requested":X,"approval:updated":X,"approval:decided":X}})},[s,n,W]),t.useEffect(()=>{if(m!=="logs"||!c?.taskId){C(!1);return}const v=Y.current,I=c.taskId,X=n?`?projectId=${encodeURIComponent(n)}`:"",ne=as(`/api/tasks/${encodeURIComponent(I)}/logs/stream${X}`,{events:{"agent:log":re=>{if(Y.current===v)try{const he=JSON.parse(re.data);N(ye=>[...ye,he])}catch{}}},onOpen:()=>{Y.current===v&&C(!0)},onError:()=>{Y.current===v&&C(!1)}});return()=>{ne(),Y.current===v&&C(!1)}},[c?.taskId,m,n]);const oe=async v=>{if(T||!p.current)return;const I=p.current.state;if(I!==v){j(!0),x(X=>X&&{...X,state:v});try{await Bt(s,v,n),o(`Agent state updated to ${v}`,"success"),await Re()}catch(X){x(ne=>ne&&{...ne,state:I}),o(`Failed to update state: ${G(X)}`,"error")}finally{j(!1)}}},Ee=async()=>{if(!(!c||!await A({title:"Delete Agent",message:`Delete agent "${c.name}"? This cannot be undone.`,danger:!0})))try{await It(s,n),o(`Agent "${c.name}" deleted`,"success"),await Ne(!0),i()}catch(I){o(`Failed to delete agent: ${G(I)}`,"error")}},cs=()=>c?Ot(c):{label:"Unknown",icon:e.jsx(ys,{size:14}),color:"var(--text-muted)",stateDerived:!1},Ye=()=>{c&&(navigator.clipboard.writeText(c.id),o("Agent ID copied to clipboard","success"))};if(y)return g?e.jsx("div",{className:"agent-detail-inline-loading",role:"region","aria-label":"Agent detail loading",children:e.jsxs("div",{className:"agent-detail-loading",children:[e.jsx(B,{className:"animate-spin",size:24}),e.jsx("span",{children:"Loading agent..."})]})}):e.jsx("div",{className:"agent-detail-overlay",onMouseDown:v=>{v.target===v.currentTarget&&(b.current=!0)},onMouseUp:v=>{b.current&&v.target===v.currentTarget&&i(),b.current=!1},role:"dialog","aria-modal":"true",children:e.jsx("div",{className:"agent-detail-modal",ref:f,children:e.jsxs("div",{className:"agent-detail-loading",children:[e.jsx(B,{className:"animate-spin",size:24}),e.jsx("span",{children:"Loading agent..."})]})})});if(!c)return null;const ze=Ss[c.state],be=cs(),Me=g?"agent-detail-inline":"agent-detail-modal";return e.jsx("div",{className:g?"agent-detail-inline-shell":"agent-detail-overlay",onClick:v=>!g&&v.target===v.currentTarget&&i(),role:g?"region":"dialog","aria-label":g?"Agent detail":void 0,"aria-modal":g?void 0:"true",children:e.jsxs("div",{className:Me,ref:f,children:[e.jsxs("div",{className:"agent-detail-header",children:[e.jsxs("div",{className:"agent-detail-identity",children:[g&&R?e.jsxs("button",{type:"button",className:"btn agent-detail-inline-back",onClick:i,"aria-label":"Back to agents",children:[e.jsx(Qs,{size:16}),"Agents"]}):null,e.jsx("div",{className:"agent-detail-icon",children:e.jsx(Xs,{agent:c,size:36})}),e.jsxs("div",{className:"agent-detail-info",children:[e.jsx("h2",{children:c.name}),e.jsxs("div",{className:"agent-detail-badges",children:[e.jsx("span",{className:"badge",style:{background:ze.bg,color:ze.text,border:`1px solid ${ze.border}`},children:c.state}),e.jsxs("span",{className:"badge",style:{color:be.color},title:be.reason??be.label,children:[be.icon,!be.stateDerived&&be.label]})]})]})]}),e.jsxs("div",{className:"agent-detail-header-actions",children:[e.jsxs("div",{className:"agent-detail-controls",children:[c.state==="idle"&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn-task-create btn--compact",onClick:()=>void oe("active"),disabled:T,children:[e.jsx(hs,{size:14}),"Start"]}),e.jsxs("button",{className:"btn btn--danger btn--compact",onClick:Ee,children:[e.jsx(rs,{size:14}),"Delete"]})]}),c.state==="active"&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn--compact agent-detail-mobile-icon-control",onClick:()=>void oe("paused"),disabled:T,"aria-label":"Pause",children:[e.jsx(zs,{size:14}),e.jsx("span",{className:"agent-detail-control-label",children:"Pause"})]}),e.jsxs("button",{className:"btn btn--danger btn--compact",onClick:()=>void oe("paused"),disabled:T,children:[e.jsx(Le,{size:14}),"Stop"]})]}),c.state==="paused"&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn-task-create btn--compact agent-detail-mobile-icon-control",onClick:()=>void oe("active"),disabled:T,"aria-label":"Resume",children:[e.jsx(hs,{size:14}),e.jsx("span",{className:"agent-detail-control-label",children:"Resume"})]}),e.jsxs("button",{className:"btn btn--danger btn--compact",onClick:Ee,children:[e.jsx(rs,{size:14}),"Delete"]})]}),c.state==="running"&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn--compact agent-detail-mobile-icon-control",onClick:()=>void oe("paused"),disabled:T,"aria-label":"Pause",children:[e.jsx(zs,{size:14}),e.jsx("span",{className:"agent-detail-control-label",children:"Pause"})]}),e.jsxs("button",{className:"btn btn--danger btn--compact",onClick:()=>void oe("paused"),disabled:T,children:[e.jsx(Le,{size:14}),"Stop"]})]}),c.state==="error"&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn-task-create btn--compact",onClick:()=>void oe("active"),disabled:T,children:[e.jsx(hs,{size:14}),"Retry"]}),e.jsxs("button",{className:"btn btn--danger btn--compact",onClick:()=>void oe("paused"),disabled:T,children:[e.jsx(Le,{size:14}),"Stop"]})]})]}),e.jsxs("div",{className:"agent-detail-utility-actions",children:[e.jsx("button",{className:"btn-icon",onClick:()=>void W(),title:"Refresh","aria-label":"Refresh",children:e.jsx(os,{size:16})}),!g&&e.jsx("button",{className:"btn-icon",onClick:i,"aria-label":"Close",title:"Close",children:e.jsx(et,{size:20})})]})]})]}),e.jsx("div",{className:"agent-detail-tabs",children:wa.map(v=>e.jsxs("button",{className:ae("agent-detail-tab",m===v.id&&"active"),onClick:()=>K(v.id),children:[e.jsx(v.icon,{size:16}),v.label]},v.id))}),e.jsxs("div",{className:"agent-detail-content",children:[m==="dashboard"&&e.jsx(Ta,{agent:c,health:be,onChildClick:u,projectId:n}),m==="logs"&&e.jsx(Ea,{logs:z,isStreaming:ee,hasTask:!!c.taskId||z.length>0||E!==null,fallbackLabel:!c.taskId&&E?`Latest run · ${E.id.slice(0,8)}`:null}),m==="mail"&&e.jsx(La,{agent:c,mailbox:$,isLoading:w,error:P,projectId:n,addToast:o,onRefresh:()=>void te()}),m==="runs"&&e.jsx($a,{addToast:o,agentId:c.id,projectId:n,agentState:c.state,agentName:c.name,initialRunId:M,preferActiveRun:k}),m==="tasks"&&e.jsx(Oa,{agentId:c.id,projectId:n,addToast:o}),m==="employees"&&e.jsx(Wa,{agentId:c.id,projectId:n,onChildClick:u}),m==="soul"&&e.jsx(Ia,{agent:c,projectId:n,addToast:o,onSaved:Re}),m==="instructions"&&e.jsx(_a,{agent:c,projectId:n,addToast:o,onSaved:Re}),m==="memory"&&e.jsx(Ua,{agent:c,projectId:n,addToast:o,onSaved:Re}),m==="reflections"&&e.jsx(Ca,{agentId:c.id,projectId:n,addToast:o}),m==="config"&&e.jsx(Ja,{agent:c,projectId:n,addToast:o,onSaved:Re,onHasChangesChange:De,onDelete:Ee,onAgentDraftApplied:v=>{x(I=>I&&{...I,...v})}},c.id)]}),!g&&e.jsxs("div",{className:"agent-detail-footer",children:[e.jsx("button",{className:"btn-icon",onClick:Ye,title:"Copy Agent ID",children:e.jsx(Ht,{})}),e.jsx("span",{className:"agent-detail-id",onClick:Ye,children:c.id}),c.taskId&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"divider",children:"|"}),e.jsx("span",{className:"text-muted",children:"Working on:"}),e.jsxs("a",{href:`/tasks/${c.taskId}`,className:"link",children:[c.taskId,e.jsx(at,{size:12})]})]})]})]})})}function Ta({agent:s,health:n,onChildClick:i,projectId:o}){const u=Ss[s.state],[g,R]=t.useState([]),[d,M]=t.useState(!0),[k,F]=t.useState(null),[c,x]=t.useState([]),[A,z]=t.useState(null),[N,y]=t.useState(null),[J,m]=t.useState(!1),[K,ee]=t.useState(null),C=typeof s.runtimeConfig?.runtimeHint=="string"?s.runtimeConfig.runtimeHint:"",T=(()=>{const f=s.runtimeConfig??{};if(C){const b=c.find(r=>r.runtimeId===C);return b?b.name:C}if(f.modelProvider&&f.modelId)return`${f.modelProvider}/${f.modelId}`;if(typeof f.model=="string"&&f.model.includes("/")){const b=f.model.indexOf("/");return f.model.slice(b+1)}return null})();t.useEffect(()=>{ps(s.id,o).then(F).catch(()=>F(null))},[s.id,o]),t.useEffect(()=>{nt(o).then(x).catch(()=>x([]))},[o]),t.useEffect(()=>{let f=!1;return M(!0),Ut(s.id,o).then(b=>{if(f)return;const r=b.length>0&&b[0]?.id===s.id?[...b].reverse():b;R(r)}).catch(()=>{f||R([])}).finally(()=>{f||M(!1)}),()=>{f=!0}},[s.id,o]);const j=t.useMemo(()=>{const f=s.completedRuns||[],b=new Date;b.setHours(0,0,0,0);const r=f.filter(p=>new Date(p.startedAt)>=b),l=f.filter(p=>p.status==="completed");return{totalRuns:f.length,todayRuns:r.length,successfulRuns:l.length,successRate:f.length>0?Math.round(l.length/f.length*100):0}},[s]),E=(s.completedRuns||[]).slice(0,5),V=Array.isArray(s.metadata?.skills)?s.metadata.skills:[],$=A?fs(A):null,q=t.useCallback(async f=>{m(!0),ee(null),y(null);try{const b=await _t(f,o);y(b)}catch(b){ee(G(b))}finally{m(!1)}},[o]),w=t.useCallback(f=>{if(A===f){z(null),y(null),ee(null),m(!1);return}z(f),q(f)},[q,A]),Q=s.state==="active"||s.state==="running",P=Vt(s.runtimeConfig?.heartbeatIntervalMs),O=Q&&s.lastHeartbeatAt?new Date(new Date(s.lastHeartbeatAt).getTime()+P).toISOString():null;return e.jsxs("div",{className:"dashboard-tab dashboard-summary-layout",children:[k?.isOverBudget&&e.jsxs("div",{className:"budget-warning-banner",role:"alert",children:[e.jsx("span",{children:"⚠️"}),e.jsxs("span",{children:[e.jsx("strong",{children:"Budget Exhausted:"})," This agent has exceeded its token budget and may operate with limited functionality."]})]}),e.jsxs("section",{className:"dashboard-summary-card dashboard-summary-hero",children:[e.jsxs("div",{className:"dashboard-summary-hero__heading",children:[e.jsx(ys,{}),e.jsx("h3",{children:"Overview"}),e.jsx("strong",{children:s.name}),e.jsx("span",{className:"inline-badge",style:{background:u.bg,color:u.text},children:s.state})]}),e.jsxs("div",{className:"dashboard-summary-hero__meta",children:[e.jsxs("span",{className:"dashboard-summary-hero__health",title:n.reason??n.label,children:[n.icon," ",n.label]}),(s.pendingApprovalCount??0)>0?e.jsxs("span",{className:"badge agent-detail-approval-badge",title:"Pending approvals",children:[e.jsx("span",{className:"status-dot status-dot--pending"}),s.pendingApprovalCount," pending approvals"]}):null,e.jsxs("span",{children:["Role: ",s.role]}),e.jsxs("span",{children:[e.jsx("span",{className:"dashboard-summary-label",children:C?"Runtime":"Model"}),e.jsxs("span",{children:[" ",T??"Auto"]})]}),V.length>0?e.jsxs("span",{className:"dashboard-summary-skills",children:[e.jsx("span",{className:"dashboard-summary-label",children:"Skills"}),e.jsx("span",{className:"dashboard-summary-skill-badges",role:"list","aria-label":"Assigned skills",children:V.map(f=>{const b=A===f;return e.jsx("button",{type:"button",className:ae("badge","badge-skill","dashboard-summary-skill-badge","dashboard-summary-skill-badge-btn",b&&"dashboard-summary-skill-badge--selected"),title:f,onClick:()=>w(f),"aria-expanded":b,"aria-label":`View details for ${fs(f)}`,children:fs(f)},f)})})]}):e.jsx("span",{children:"Skills: —"})]}),A?e.jsxs("div",{className:"dashboard-summary-skill-detail","data-testid":"agent-skill-detail",children:[e.jsxs("div",{className:"dashboard-summary-skill-detail-header",children:[e.jsx("span",{className:"dashboard-summary-skill-detail-title",children:$}),e.jsxs("button",{type:"button",className:"btn btn-sm",onClick:()=>w(A),children:[e.jsx(et,{size:14}),"Close"]})]}),J?e.jsxs("div",{className:"dashboard-summary-skill-detail-loading",role:"status","aria-live":"polite",children:[e.jsx(B,{size:14,className:"animate-spin"}),"Loading skill content..."]}):K?e.jsxs("div",{className:"dashboard-summary-skill-detail-error",role:"alert",children:[e.jsx(it,{size:14}),e.jsx("span",{children:K}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>void q(A),children:"Retry"})]}):N?e.jsx("pre",{className:"dashboard-summary-skill-detail-content",children:N.skillMd||"(No SKILL.md found)"}):e.jsx("div",{className:"dashboard-summary-skill-detail-empty",children:"No skill content available"})]}):null]}),e.jsxs("section",{className:"dashboard-summary-card",children:[e.jsx("h3",{children:"Heartbeat & Health"}),e.jsxs("div",{className:"dashboard-summary-grid",children:[e.jsxs("div",{children:[e.jsx("p",{className:"dashboard-summary-label",children:"Last heartbeat"}),e.jsx("p",{children:s.lastHeartbeatAt?$e(s.lastHeartbeatAt):"Never"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"dashboard-summary-label",children:"Next expected"}),e.jsx("p",{children:O?$e(O):"Not scheduled"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"dashboard-summary-label",children:"Interval"}),e.jsx("p",{children:rt(P)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"dashboard-summary-label",children:"Status"}),e.jsxs("p",{className:"dashboard-summary-health-row",children:[e.jsx("span",{className:ae("status-dot",s.state==="running"&&"status-dot--running")}),n.label,n.reason&&e.jsxs("span",{className:"text-secondary dashboard-summary-health-reason",title:n.reason,children:["(",n.reason,")"]})]})]})]})]}),e.jsxs("section",{className:"dashboard-summary-card",children:[e.jsx("h3",{children:"Current Work"}),s.taskId?e.jsxs("div",{className:"current-task",children:[e.jsx("a",{href:`/tasks/${s.taskId}`,className:"task-badge",children:s.taskId}),e.jsxs("a",{href:`/tasks/${s.taskId}`,className:"btn btn-sm",children:["View Task ",e.jsx(at,{size:14})]})]}):e.jsx("p",{className:"text-muted",children:"No active assignment"})]}),e.jsxs("section",{className:"dashboard-summary-card",children:[e.jsx("h3",{children:"Recent Runs"}),e.jsxs("p",{className:"dashboard-summary-label",children:[j.successfulRuns,"/",j.totalRuns," successful (",j.successRate,"%)"]}),E.length===0?e.jsx("p",{className:"text-muted",children:"No runs yet"}):e.jsx("div",{className:"runs-list",children:E.map(f=>{const b=ls[f.status]||ls.terminated,r=b.icon;return e.jsxs("div",{className:"run-item",children:[e.jsx(r,{size:14,style:{color:b.color}}),e.jsx("span",{children:$e(f.startedAt)}),e.jsxs("span",{className:"text-muted",children:[Math.max(0,Math.round((new Date(f.endedAt||f.startedAt).getTime()-new Date(f.startedAt).getTime())/1e3)),"s"]})]},f.id)})})]}),e.jsxs("section",{className:"dashboard-summary-card",children:[e.jsx("h3",{children:"Throughput"}),e.jsxs("div",{className:"stats-grid",children:[e.jsxs("div",{className:"stat-card",children:[e.jsx("div",{className:"stat-value",children:j.totalRuns}),e.jsx("div",{className:"stat-label",children:"Total Runs"})]}),e.jsxs("div",{className:"stat-card",children:[e.jsx("div",{className:"stat-value",children:j.todayRuns}),e.jsx("div",{className:"stat-label",children:"Runs Today"})]}),e.jsxs("div",{className:"stat-card",children:[e.jsxs("div",{className:"stat-value",children:[j.successRate,"%"]}),e.jsx("div",{className:"stat-label",children:"Success Rate"})]})]})]}),e.jsxs("section",{className:"dashboard-summary-card",children:[e.jsx("h3",{children:"Chain of Command"}),d?e.jsxs("div",{className:"chain-of-command-loading",role:"status","aria-live":"polite",children:[e.jsx(B,{size:14,className:"animate-spin"}),e.jsx("span",{children:"Loading reporting chain..."})]}):g.length<=1?e.jsx("p",{className:"text-muted",children:"No reporting chain"}):e.jsx("div",{className:"chain-of-command-path","aria-label":"Chain of command",children:g.map((f,b)=>{const r=b===g.length-1,l=!r;return e.jsxs("div",{className:"chain-of-command-item",children:[e.jsx("button",{type:"button",className:`chain-of-command-node${r?" chain-of-command-node--current":""}`,onClick:()=>l&&i?.(f.id),disabled:!l||!i,title:r?"Current agent":`View ${f.name}`,children:f.name}),!r&&e.jsx("span",{className:"chain-of-command-separator","aria-hidden":"true",children:"→"})]},f.id)})})]})]})}function Ea({logs:s,isStreaming:n,hasTask:i,fallbackLabel:o}){return i?e.jsxs("div",{className:"logs-tab",children:[e.jsxs("div",{className:"logs-header",children:[e.jsxs("span",{className:"logs-count",children:[s.length," entries"]}),o&&e.jsx("span",{className:"text-muted logs-fallback-label",children:o}),n&&e.jsxs("span",{className:"streaming-indicator",children:[e.jsx("span",{className:"streaming-dot"}),"Live"]})]}),s.length===0?e.jsxs("div",{className:"logs-empty",children:[e.jsx(Ve,{size:48,opacity:.3}),e.jsx("p",{children:"No log entries yet"}),e.jsx("p",{className:"text-muted",children:n?"Waiting for activity...":"Logs will appear here when the agent is active"})]}):e.jsx(lt,{entries:s,loading:!1})]}):e.jsx("div",{className:"logs-tab",children:e.jsxs("div",{className:"logs-empty",children:[e.jsx(Ve,{size:48,opacity:.3}),e.jsx("p",{children:"No activity yet"}),e.jsx("p",{className:"text-muted",children:"Agent logs will appear here from the current task or most recent run"})]})})}function Pa(s){const n=new Date(s),o=new Date().getTime()-n.getTime(),u=Math.floor(o/6e4),g=Math.floor(o/36e5),R=Math.floor(o/864e5);return u<1?"Just now":u<60?`${u}m ago`:g<24?`${g}h ago`:R<7?`${R}d ago`:n.toLocaleDateString(void 0,{month:"short",day:"numeric"})}function ts(s,n){return n==="user"?s==="dashboard"?"You":`User: ${s}`:n==="agent"?`Agent: ${s}`:"System"}function La({agent:s,mailbox:n,isLoading:i,error:o,projectId:u,addToast:g,onRefresh:R}){const[d,M]=t.useState("inbox"),[k,F]=t.useState(null),c=d==="inbox"?n?.inbox??[]:n?.outbox??[],x=k?c.find(y=>y.id===k)??null:null;t.useEffect(()=>{F(null)},[d,s.id]);const A=async y=>{if(F(y.id),!(d!=="inbox"||y.read))try{await ma(y.id,u),R()}catch(J){const m=`Failed to mark message as read: ${G(J)}`;g?g(m,"error"):console.warn(m)}},z=()=>{F(null),R()},N=y=>e.jsxs("button",{type:"button",className:ae("mailbox-item","agent-mail-tab-message",d==="inbox"&&!y.read&&"unread",k===y.id&&"agent-mail-tab-message--selected"),onClick:()=>void A(y),"aria-pressed":k===y.id,children:[e.jsx("div",{className:"mailbox-item-avatar",children:(d==="inbox"?y.fromType:y.toType)==="agent"?e.jsx(ys,{size:16}):e.jsx(aa,{size:16})}),e.jsxs("div",{className:"mailbox-item-content",children:[e.jsxs("div",{className:"mailbox-item-header",children:[d==="inbox"?e.jsx("span",{className:"mailbox-item-from",children:ts(y.fromId,y.fromType)}):e.jsxs("span",{className:"mailbox-item-to",children:["To: ",ts(y.toId,y.toType)]}),e.jsx("span",{className:"mailbox-item-time",children:Pa(y.createdAt)})]}),e.jsxs("div",{className:"mailbox-item-preview",children:[y.content.slice(0,80),y.content.length>80?"…":""]})]}),d==="inbox"&&!y.read?e.jsx("div",{className:"mailbox-item-unread-dot","aria-label":"Unread message"}):null]},y.id);return e.jsxs("div",{className:"agent-mail-tab",children:[e.jsxs("div",{className:"agent-mail-tab-header",children:[e.jsxs("h3",{children:[s.name," Mail"]}),e.jsxs("button",{className:"btn btn-sm",onClick:z,disabled:i,children:[e.jsx(os,{size:14}),"Refresh"]})]}),e.jsxs("div",{className:"mailbox-agent-subtabs","data-testid":"agent-detail-mail-subtabs",children:[e.jsxs("button",{className:ae("btn","btn-sm","btn-secondary","mailbox-agent-subtab",d==="inbox"&&"active"),onClick:()=>M("inbox"),children:[e.jsx(Hs,{size:12}),e.jsx("span",{children:"Inbox"}),(n?.unreadCount??0)>0?e.jsx("span",{className:"mailbox-tab-badge",children:n?.unreadCount}):null]}),e.jsxs("button",{className:ae("btn","btn-sm","btn-secondary","mailbox-agent-subtab",d==="outbox"&&"active"),onClick:()=>M("outbox"),children:[e.jsx(Os,{size:12}),e.jsx("span",{children:"Outbox"})]})]}),i&&!n?e.jsxs("div",{className:"agent-detail-loading agent-detail-loading--inline",role:"status","aria-live":"polite",children:[e.jsx(B,{className:"animate-spin",size:16}),e.jsx("span",{children:"Loading mailbox..."})]}):null,!i&&o?e.jsxs("div",{className:"agent-mail-tab-error",role:"alert",children:[e.jsx(it,{size:16}),e.jsxs("span",{children:["Failed to load mailbox: ",o]})]}):null,!i&&!o?x?e.jsxs("div",{className:"agent-mail-tab-detail","data-testid":"agent-detail-mail-message",children:[e.jsxs("button",{type:"button",className:"btn btn-sm agent-mail-tab-back","data-testid":"agent-detail-mail-back",onClick:()=>F(null),children:[e.jsx(Qs,{size:14}),"Back to ",d==="inbox"?"Inbox":"Outbox"]}),e.jsxs("div",{className:"agent-mail-tab-detail-meta",children:[e.jsxs("div",{className:"agent-mail-tab-detail-row",children:[e.jsx("span",{className:"agent-mail-tab-detail-label",children:"From"}),e.jsx("span",{children:ts(x.fromId,x.fromType)})]}),e.jsxs("div",{className:"agent-mail-tab-detail-row",children:[e.jsx("span",{className:"agent-mail-tab-detail-label",children:"To"}),e.jsx("span",{children:ts(x.toId,x.toType)})]}),e.jsxs("div",{className:"agent-mail-tab-detail-row",children:[e.jsx("span",{className:"agent-mail-tab-detail-label",children:"Type"}),e.jsx("span",{children:x.type})]}),e.jsxs("div",{className:"agent-mail-tab-detail-row",children:[e.jsx("span",{className:"agent-mail-tab-detail-label",children:"Sent"}),e.jsx("span",{children:new Date(x.createdAt).toLocaleString()})]}),x.metadata?.replyTo?.messageId?e.jsxs("div",{className:"agent-mail-tab-reply-context",children:["↪ Replying to message ",x.metadata.replyTo.messageId]}):null]}),e.jsx("div",{className:"agent-mail-tab-detail-body",children:x.content})]}):e.jsx("div",{className:"mailbox-list","data-testid":"agent-detail-mail-list",children:c.length===0?e.jsxs("div",{className:"mailbox-empty","data-testid":"agent-detail-mail-empty",children:[d==="inbox"?e.jsx(Hs,{size:32}):e.jsx(Os,{size:32}),e.jsx("p",{children:d==="inbox"?"No received messages for this agent":"No sent messages for this agent"})]}):c.map(N)}):null]})}function $a({addToast:s,agentId:n,projectId:i,agentState:o,agentName:u,initialRunId:g,preferActiveRun:R}){const[d,M]=t.useState([]),{confirm:k}=Ys(),[F,c]=t.useState(!0),[x,A]=t.useState(null),[z,N]=t.useState([]),[y,J]=t.useState(!1),[m,K]=t.useState(null),[ee,C]=t.useState(!1),T=t.useRef(!1),j=t.useCallback(async()=>{try{const l=await Ks(n,50,i);M(l)}catch(l){s(`Failed to load runs: ${G(l)}`,"error")}finally{c(!1)}},[n,i,s]);t.useEffect(()=>{j()},[j]);const E=d.some(l=>l.status==="active"),V=x?d.find(l=>l.id===x)?.status:void 0;t.useEffect(()=>{if(!E)return;const l=setInterval(()=>{j()},5e3);return()=>clearInterval(l)},[E,j]),t.useEffect(()=>{if(!x||V!=="active")return;const l=i?`?projectId=${encodeURIComponent(i)}`:"";return as(`/api/agents/${encodeURIComponent(n)}/runs/${encodeURIComponent(x)}/logs/stream${l}`,{events:{"agent:log":p=>{try{const se=JSON.parse(p.data);N(L=>[...L,se])}catch{}}}})},[x,V,n,i]);const $=t.useCallback(async l=>{if(x===l){A(null),N([]),K(null);return}A(l),J(!0),C(!0),N([]),K(null);try{const[p,se]=await Promise.all([Zs(n,l,i),Wt(n,l,i)]);N(p),K(se)}catch(p){s(`Failed to load run details: ${G(p)}`,"error"),N([]),K(null)}finally{J(!1),C(!1)}},[x,n,i,s]);t.useEffect(()=>{T.current=!1},[n,g,R]),t.useEffect(()=>{if(d.length===0||F||T.current)return;const l=g?d.find(p=>p.id===g):R?d.find(p=>p.status==="active"):null;T.current=!0,l&&$(l.id)},[g,R,d,F,$]);const q=async()=>{try{await na(n,i,{source:"on_demand",triggerDetail:"Triggered from dashboard"}),s(`Heartbeat run started for ${u??n}`,"success"),c(!0),j()}catch(l){s(`Failed to start heartbeat run: ${G(l)}`,"error")}},w=async()=>{if(await k({title:"Stop Active Run",message:"Stop the active run? The agent's work will be interrupted.",danger:!0}))try{await ia(n,i),s("Run stopped","success"),c(!0),j()}catch(p){s(`Failed to stop run: ${G(p)}`,"error")}},Q=o==="active"||o==="idle";if(F&&d.length===0)return e.jsx("div",{className:"runs-tab",children:e.jsxs("div",{className:"runs-loading-row",children:[e.jsx(B,{size:16,className:"animate-spin"}),e.jsx("span",{className:"text-muted",children:"Loading runs..."})]})});if(d.length===0)return e.jsxs("div",{className:"runs-tab",children:[Q&&e.jsx("div",{className:"runs-toolbar",children:e.jsxs("button",{className:"btn btn--sm btn-task-create",onClick:()=>void q(),"aria-label":`Run now for ${u??n}`,children:[e.jsx(ns,{size:14})," Run Now"]})}),e.jsxs("div",{className:"runs-empty",children:[e.jsx(ns,{size:48,opacity:.3}),e.jsx("p",{children:"No runs yet"}),e.jsx("p",{className:"text-muted",children:"Heartbeat runs will appear here"})]})]});const P=[...d].sort((l,p)=>new Date(p.startedAt).getTime()-new Date(l.startedAt).getTime()),O=P.filter(l=>l.status==="active"),f=P.filter(l=>l.status!=="active"),b=l=>l?e.jsxs("div",{className:"run-usage",children:[e.jsxs("span",{children:["Input: ",l.inputTokens.toLocaleString()]}),e.jsxs("span",{children:["Output: ",l.outputTokens.toLocaleString()]}),l.cachedTokens>0&&e.jsxs("span",{children:["Cached: ",l.cachedTokens.toLocaleString()]})]}):null,r=(l,p,se)=>{const L=ls[l.status]||ls.completed,Y=L.icon,ie=l.endedAt?Da(new Date(l.startedAt),new Date(l.endedAt)):"In progress",xe=x===l.id;return e.jsxs("div",{children:[e.jsxs("div",{className:ae("run-card",se&&"run-card--active",xe&&"run-card--selected","run-card--clickable"),onClick:()=>void $(l.id),role:"button",tabIndex:0,"aria-expanded":xe,"aria-label":`${se?"Active":""} run ${l.id.slice(0,8)}, ${l.status}`,onKeyDown:W=>{(W.key==="Enter"||W.key===" ")&&(W.preventDefault(),$(l.id))},children:[e.jsxs("div",{className:"run-header",children:[e.jsxs("div",{className:"run-header-group",children:[xe?e.jsx(qs,{size:14}):e.jsx(Gs,{size:14}),se?e.jsxs("span",{className:"run-live-indicator",children:[e.jsx("span",{className:"live-dot"}),"Live Run"]}):e.jsxs("span",{className:"run-id",children:["#",p+1," ",l.id.slice(0,8)]})]}),e.jsxs("div",{className:"run-header-group",children:[l.invocationSource&&e.jsx("span",{className:"badge run-badge--compact",children:l.invocationSource}),se&&e.jsxs("button",{className:"btn btn--sm btn--danger",onClick:W=>{W.preventDefault(),W.stopPropagation(),w()},"aria-label":"Stop active run",children:[e.jsx(Le,{size:12})," Stop"]}),e.jsxs("span",{className:ae("run-status",l.status),children:[e.jsx(Y,{size:14,style:{color:L.color}}),l.status]}),l.heartbeatProcedureSource==="custom"&&e.jsx("span",{className:"badge run-badge--compact",children:"Heartbeat: custom"})]})]}),e.jsxs("div",{className:"run-details",children:[e.jsxs("span",{children:["Started ",$e(l.startedAt)]}),e.jsx("span",{children:"•"}),e.jsx("span",{children:ie}),l.triggerDetail&&e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"•"}),e.jsx("span",{className:"text-muted",children:l.triggerDetail})]})]})]}),xe&&e.jsxs("div",{className:"run-logs-container",children:[ee?e.jsxs("div",{className:"run-details-loading-state",children:[e.jsx(B,{size:14,className:"animate-spin"}),e.jsx("span",{className:"text-muted",children:"Loading details..."})]}):m&&e.jsxs("div",{className:"run-output-sections",children:[e.jsx("div",{className:"run-output-section",children:e.jsxs("details",{children:[e.jsx("summary",{className:"run-output-label run-output-summary",children:"System Prompt"}),m.systemPrompt?e.jsx("pre",{className:"run-output-panel",children:m.systemPrompt}):e.jsx("div",{className:"text-muted run-output-empty",children:"System prompt not captured for this run"})]})}),e.jsx("div",{className:"run-output-section",children:e.jsxs("details",{children:[e.jsx("summary",{className:"run-output-label run-output-summary",children:"Execution Prompt"}),m.executionPrompt?e.jsx("pre",{className:"run-output-panel",children:m.executionPrompt}):e.jsx("div",{className:"text-muted run-output-empty",children:"Execution prompt not captured for this run"})]})}),m.usageJson&&e.jsxs("div",{className:"run-output-section",children:[e.jsx("div",{className:"run-output-label",children:"Token Usage"}),b(m.usageJson)]}),m.stdoutExcerpt&&e.jsxs("div",{className:"run-output-section",children:[e.jsx("div",{className:"run-output-label",children:"Output"}),e.jsx("pre",{className:"run-output-panel",children:m.stdoutExcerpt.length>2e3?`${m.stdoutExcerpt.slice(0,2e3)}
17
-
18
- ... (truncated, ${m.stdoutExcerpt.length} chars total)`:m.stdoutExcerpt})]}),m.stderrExcerpt&&e.jsxs("div",{className:"run-output-section",children:[e.jsx("div",{className:"run-output-label run-output-label--error",children:"Errors"}),e.jsx(ra,{errorText:m.stderrExcerpt,summaryPrefix:"Run error",issueContext:{surface:"AgentDetailView runs",agentId:n,agentName:u,agentState:o,runId:m.id,taskId:void 0,timestamp:m.startedAt}})]}),m.resultJson&&e.jsxs("div",{className:"run-output-section",children:[e.jsx("div",{className:"run-output-label",children:"Result"}),e.jsx("pre",{className:"run-output-panel",children:JSON.stringify(m.resultJson,null,2)})]}),m.contextSnapshot&&Object.keys(m.contextSnapshot).length>0&&e.jsxs("div",{className:"run-output-section",children:[e.jsx("div",{className:"run-output-label",children:"Context"}),e.jsx("div",{className:"run-context-grid",children:Object.entries(m.contextSnapshot).map(([W,H])=>e.jsxs("span",{className:"run-context-item",children:[e.jsxs("span",{className:"text-muted",children:[W,":"]})," ",e.jsx("span",{children:String(H)})]},W))})]}),!m.stdoutExcerpt&&!m.stderrExcerpt&&!m.resultJson&&e.jsx("div",{className:"text-muted run-output-empty",children:"No output captured"})]}),e.jsxs("div",{className:"run-agent-logs-section",children:[e.jsx("div",{className:"run-output-label",children:"Agent Logs"}),y?e.jsxs("div",{className:"run-details-loading-state",children:[e.jsx(B,{size:14,className:"animate-spin"}),e.jsx("span",{className:"text-muted",children:"Loading logs..."})]}):z.length===0?e.jsx("div",{className:"text-muted run-output-empty",children:"No logs available for this run"}):e.jsx(lt,{entries:z,loading:!1})]})]})]},l.id)};return e.jsxs("div",{className:"runs-tab",children:[Q&&e.jsxs("div",{className:"runs-toolbar runs-toolbar--between",children:[e.jsxs("span",{className:"runs-toolbar-meta",children:[d.length," run",d.length!==1?"s":"",E&&e.jsxs("span",{className:"run-live-indicator run-live-indicator--with-margin",children:[e.jsx("span",{className:"live-dot"}),"Live"]})]}),e.jsxs("div",{className:"run-header-group",children:[E&&e.jsxs("button",{className:"btn btn--sm btn--danger",onClick:()=>void w(),"aria-label":`Stop active run for ${u??n}`,children:[e.jsx(Le,{size:14})," Stop Run"]}),e.jsxs("button",{className:"btn btn--sm btn-task-create",onClick:()=>void q(),"aria-label":`Run now for ${u??n}`,children:[e.jsx(ns,{size:14})," Run Now"]})]})]}),O.map((l,p)=>r(l,p,!0)),f.map((l,p)=>r(l,O.length+p,!1))]})}function Da(s,n){const i=Math.floor((n.getTime()-s.getTime())/1e3);return i<60?`${i}s`:i<3600?`${Math.floor(i/60)}m ${i%60}s`:`${Math.floor(i/3600)}h ${Math.floor(i%3600/60)}m`}const za={triage:"Triage",todo:"Todo","in-progress":"In Progress","in-review":"In Review",done:"Done",archived:"Archived"};function Ha(s){const n=s.title?.trim()||s.description?.trim()||s.id;return n.length>80?`${n.slice(0,77)}...`:n}function Oa({agentId:s,projectId:n,addToast:i}){const[o,u]=t.useState([]),[g,R]=t.useState(!0);return t.useEffect(()=>{let d=!1;return R(!0),qt(s,n).then(M=>{d||u(M)}).catch(M=>{d||(u([]),i(`Failed to load assigned tasks: ${G(M)}`,"error"))}).finally(()=>{d||R(!1)}),()=>{d=!0}},[s,n,i]),g?e.jsxs("div",{className:"agent-tasks-empty",children:[e.jsx(B,{size:16,className:"animate-spin"}),e.jsx("p",{children:"Loading assigned tasks..."})]}):o.length===0?e.jsxs("div",{className:"agent-tasks-empty",children:[e.jsx(st,{size:18}),e.jsx("p",{children:"No tasks assigned to this agent"})]}):e.jsx("div",{className:"agent-tasks-list",children:o.map(d=>e.jsxs("a",{className:"agent-task-item",href:`/tasks/${d.id}`,children:[e.jsxs("div",{className:"agent-task-row",children:[e.jsx("span",{className:"agent-task-id",children:d.id}),e.jsx("span",{className:`agent-task-column column-${d.column}`,children:za[d.column]})]}),e.jsx("div",{className:"agent-task-title",title:d.title||d.description||d.id,children:Ha(d)}),e.jsxs("div",{className:"agent-task-status",children:[d.status??"idle"," · Updated ",$e(d.updatedAt)]})]},d.id))})}const _e=[{key:"maxRetries",label:"Max Retries",type:"number",placeholder:"3",hint:"Maximum number of automatic retries on task failure (0–10, default 3)",min:0,max:10},{key:"timeoutMs",label:"Task Timeout (ms)",type:"number",placeholder:"600000",hint:"Maximum time in ms before a task is considered timed out (minimum 60000ms, default 600000ms)",min:6e4,max:864e5},{key:"logLevel",label:"Log Level",type:"select",hint:"Verbosity of agent log output",options:[{value:"debug",label:"Debug"},{value:"info",label:"Info"},{value:"warn",label:"Warning"},{value:"error",label:"Error"}]}];function Ba(s){const n={};for(const i of _e){const o=s[i.key]?.trim();if(o){if(i.type==="number"){const u=Number(o);if(Number.isNaN(u)||!Number.isFinite(u)){n[i.key]=`"${i.label}" must be a valid number`;continue}i.min!==void 0&&u<i.min&&(n[i.key]=`"${i.label}" must be at least ${i.min.toLocaleString()}`),i.max!==void 0&&u>i.max&&(n[i.key]=`"${i.label}" must be at most ${i.max.toLocaleString()}`)}if(i.type==="select"){const u=i.options?.map(g=>g.value)??[];u.length>0&&!u.includes(o)&&(n[i.key]=`"${i.label}" must be one of: ${u.join(", ")}`)}}}return n}function Ia({agent:s,projectId:n,addToast:i,onSaved:o}){const[u,g]=t.useState(s.soul??""),[R,d]=t.useState(!1),[M,k]=t.useState(!1),[F,c]=t.useState(!1),x=t.useRef(null);t.useEffect(()=>{g(s.soul??""),k(!1),c(!1)},[s.id,s.soul]),t.useEffect(()=>()=>{x.current&&clearTimeout(x.current)},[]);const A=u!==(s.soul??""),z=async()=>{if(u.length>1e4){i("Soul must be at most 10,000 characters","error");return}d(!0);try{await la(s.id,u,n),i("Soul saved","success"),k(!0),x.current&&clearTimeout(x.current),x.current=setTimeout(()=>k(!1),3e3),await o()}catch(N){i(`Failed to save soul: ${G(N)}`,"error")}finally{d(!1)}};return e.jsx("div",{className:"config-tab",children:e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Soul"}),e.jsx("p",{className:"config-description",children:"Define this agent's personality and identity."}),e.jsx("div",{className:"config-fields",children:e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"agent-soul",children:"Agent Soul"}),e.jsx("div",{className:"agent-content-toolbar",children:e.jsxs("div",{className:"agent-content-mode-toggle",children:[e.jsxs("button",{className:`btn btn-sm ${F?"":"btn-primary"}`,onClick:()=>c(!1),disabled:!F,"aria-label":"Edit mode",children:[e.jsx(Je,{size:14}),"Edit"]}),e.jsxs("button",{className:`btn btn-sm ${F?"btn-primary":""}`,onClick:()=>c(!0),disabled:F,"aria-label":"Preview mode",children:[e.jsx(We,{size:14}),"Preview"]})]})}),F?u.trim()?e.jsx("div",{className:"agent-content-preview markdown-body",children:e.jsx(qe,{remarkPlugins:[Ge],children:u})}):e.jsx("div",{className:"agent-content-preview agent-content-placeholder",children:"No soul defined yet. Switch to Edit mode to define the agent's personality."}):e.jsx("textarea",{id:"agent-soul",className:"input config-textarea-mono",rows:12,placeholder:"Describe this agent's personality, tone, and behavioral traits...",value:u,onChange:N=>{g(N.target.value),k(!1)}}),!F&&e.jsx("span",{className:"config-hint",children:"Defines the agent's character and identity. Max 10,000 characters."})]})}),!F&&e.jsxs("div",{className:"config-actions",children:[e.jsx("button",{className:"btn btn-task-create",disabled:!A||R,onClick:()=>void z(),children:R?e.jsxs(e.Fragment,{children:[e.jsx(B,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(de,{size:16}),"Save Soul"]})}),!A&&M&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(de,{size:14}),"Soul saved"]})]})]})})}function Ua({agent:s,projectId:n,addToast:i,onSaved:o}){const[u,g]=t.useState(s.memory??""),[R,d]=t.useState(!1),[M,k]=t.useState(!1),[F,c]=t.useState(!1),[x,A]=t.useState(!1),[z,N]=t.useState([]),[y,J]=t.useState(!1),[m,K]=t.useState(""),[ee,C]=t.useState(""),[T,j]=t.useState(!1),[E,V]=t.useState(!1),[$,q]=t.useState(!1),[w,Q]=t.useState(!1),[P,O]=t.useState(""),f=t.useRef(null),b=t.useRef(null),r=s.state==="running",l=u!==(s.memory??""),p=t.useMemo(()=>z.find(H=>H.path===m),[z,m]),se=p?Ra[p.layer]:"Select a memory file to view or edit.",L=t.useCallback(async H=>{V(!0);try{const te=await Yt(s.id,H,n);K(te.path),C(te.content),j(!1),Q(!1)}catch(te){i(`Failed to load agent memory file: ${G(te)}`,"error")}finally{V(!1)}},[s.id,n,i]),Y=t.useCallback(async(H="")=>{J(!0);try{const{files:te}=await Kt(s.id,n);if(N(te),te.length===0){K(""),C(""),j(!1);return}const De=Aa(te,H);await L(De)}catch(te){i(`Failed to load memory files: ${G(te)}`,"error"),N([]),K(""),C(""),j(!1)}finally{J(!1)}},[s.id,n,i,L]);t.useEffect(()=>{g(s.memory??""),k(!1),c(!1),A(!1),O(""),Q(!1),Y()},[s.id,s.memory,Y]),t.useEffect(()=>()=>{f.current&&clearTimeout(f.current),b.current&&clearTimeout(b.current)},[]);const ie=async()=>{if(u.length>5e4){i("Memory must be at most 50,000 characters","error");return}d(!0);try{await ca(s.id,u,n),i("Memory saved","success"),k(!0),f.current&&clearTimeout(f.current),f.current=setTimeout(()=>k(!1),3e3),await o()}catch(H){i(`Failed to save memory: ${G(H)}`,"error")}finally{d(!1)}},xe=async H=>{if(!(!H||H===m)){if(T){O("Save the current file before switching to another file.");return}O(""),await L(H)}},W=async()=>{if(m){q(!0);try{await da(s.id,m,ee,n),j(!1),Q(!0),b.current&&clearTimeout(b.current),b.current=setTimeout(()=>Q(!1),3e3),O(""),await Y(m),i("Agent memory file saved","success"),await o()}catch(H){i(`Failed to save agent memory file: ${G(H)}`,"error")}finally{q(!1)}}};return e.jsx("div",{className:"config-tab",children:e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Agent Memory"}),e.jsx("p",{className:"config-description",children:"Store context that belongs to this agent only. Workspace memory, daily notes, dreams, and qmd search live in project settings under Project Memory."}),r&&e.jsx("p",{className:"config-hint config-hint--block-spacing",children:"Read-only while this agent is running."}),e.jsxs("div",{className:"config-fields",children:[e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"agent-memory",children:"Inline Memory"}),e.jsx("span",{className:"config-hint config-hint--block",children:"Short-form memory stored directly on the agent record and injected into prompts."}),e.jsx("div",{className:"agent-content-toolbar",children:e.jsxs("div",{className:"agent-content-mode-toggle",children:[!r&&e.jsxs("button",{className:`btn btn-sm ${F?"":"btn-primary"}`,onClick:()=>c(!1),disabled:!F,"aria-label":"Edit mode",children:[e.jsx(Je,{size:14}),"Edit"]}),e.jsxs("button",{className:`btn btn-sm ${F?"btn-primary":""}`,onClick:()=>c(!0),disabled:F,"aria-label":"Preview mode",children:[e.jsx(We,{size:14}),"Preview"]})]})}),F?u.trim()?e.jsx("div",{className:"agent-content-preview markdown-body",children:e.jsx(qe,{remarkPlugins:[Ge],children:u})}):e.jsx("div",{className:"agent-content-preview agent-content-placeholder",children:"No agent memory defined yet. Switch to Edit mode to add memory content."}):e.jsx("textarea",{id:"agent-memory","aria-label":"Agent Memory",className:"input config-textarea-mono",rows:10,placeholder:"Durable preferences, operating habits, and context this agent should carry across tasks...",value:u,readOnly:r,onChange:H=>{g(H.target.value),k(!1)}}),!F&&e.jsx("span",{className:"config-hint",children:"This is the inline memory field on the agent JSON record. Max 50,000 characters."})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"agent-memory-file-select",children:"Memory Files"}),e.jsxs("span",{className:"config-hint config-hint--block",children:["Full OpenClaw memory files at ",e.jsxs("code",{children:["agent/",s.name||s.id,"/memory/"]})," (MEMORY.md, DREAMS.md, and daily notes)."]}),e.jsx("select",{id:"agent-memory-file-select",className:"select",value:m,disabled:y||E||$||z.length===0,onChange:H=>{xe(H.target.value)},children:z.length===0?e.jsx("option",{value:"",children:"No memory files found"}):z.map(H=>e.jsxs("option",{value:H.path,children:[Vs[H.layer]," • ",H.label]},H.path))}),y&&e.jsxs("span",{className:"config-hint config-hint--inline-loader",children:[e.jsx(B,{size:14,className:"animate-spin"}),"Loading memory files…"]}),p&&e.jsxs("div",{className:"config-hint config-hint--top-spacing",children:[e.jsx("strong",{children:Vs[p.layer]})," · ",se,e.jsx("br",{}),p.size.toLocaleString()," bytes · Updated ",$e(p.updatedAt)]}),e.jsx("div",{className:"agent-content-toolbar config-textarea-top-spacing",children:e.jsxs("div",{className:"agent-content-mode-toggle",children:[!r&&e.jsxs("button",{className:`btn btn-sm ${x?"":"btn-primary"}`,onClick:()=>A(!1),disabled:!x,"aria-label":"Memory file edit mode",children:[e.jsx(Je,{size:14}),"Edit"]}),e.jsxs("button",{className:`btn btn-sm ${x?"btn-primary":""}`,onClick:()=>A(!0),disabled:x,"aria-label":"Memory file preview mode",children:[e.jsx(We,{size:14}),"Preview"]})]})}),x?ee.trim()?e.jsx("div",{className:"agent-content-preview markdown-body",children:e.jsx(qe,{remarkPlugins:[Ge],children:ee})}):e.jsx("div",{className:"agent-content-preview agent-content-placeholder",children:"No memory file content yet. Switch to Edit mode to add content."}):e.jsx("textarea",{className:"input config-textarea-mono",rows:14,placeholder:"Select a memory file to view and edit its content...",value:ee,readOnly:r||!m||E,onChange:H=>{C(H.target.value),j(!0),Q(!1),O("")}}),E&&e.jsxs("span",{className:"config-hint config-hint--inline-loader",children:[e.jsx(B,{size:14,className:"animate-spin"}),"Loading file content…"]}),P&&e.jsx("span",{className:"config-hint config-hint--top-spacing config-hint--block",children:P})]})]}),e.jsxs("div",{className:"config-actions",children:[!F&&e.jsx("button",{className:"btn btn-task-create",disabled:!l||R||r,onClick:()=>void ie(),children:R?e.jsxs(e.Fragment,{children:[e.jsx(B,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(de,{size:16}),"Save Memory"]})}),!x&&e.jsx("button",{className:"btn",disabled:!T||$||!m||r,onClick:()=>void W(),children:$?e.jsxs(e.Fragment,{children:[e.jsx(B,{size:16,className:"animate-spin"}),"Saving file…"]}):e.jsxs(e.Fragment,{children:[e.jsx(de,{size:16}),"Save Memory File"]})}),!l&&M&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(de,{size:14}),"Memory saved"]}),!T&&w&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(de,{size:14}),"Memory file saved"]})]})]})})}function _a({agent:s,projectId:n,addToast:i,onSaved:o}){const[u,g]=t.useState(s.instructionsText??""),[R,d]=t.useState(s.instructionsPath??""),[M,k]=t.useState(!1),[F,c]=t.useState(""),[x,A]=t.useState(!1),[z,N]=t.useState(!1),[y,J]=t.useState(!1),[m,K]=t.useState(!1),[ee,C]=t.useState(!1),[T,j]=t.useState(!1),E=t.useRef(null),V=t.useRef(null);t.useEffect(()=>{const P=R.trim();if(!P){c(""),N(!1);return}A(!0),ot("project",P).then(O=>{c(O.content),N(!1)}).catch(O=>{const f=G(O);f.includes("ENOENT")||f.includes("Not found")||f.includes("not found")?(c(""),N(!1)):(i(`Failed to load instructions file: ${f}`,"error"),c(""))}).finally(()=>{A(!1)})},[R,i]),t.useEffect(()=>{g(s.instructionsText??""),d(s.instructionsPath??""),C(!1),j(!1),k(!1)},[s.id,s.instructionsText,s.instructionsPath]),t.useEffect(()=>()=>{E.current&&clearTimeout(E.current),V.current&&clearTimeout(V.current)},[]);const $=(()=>{const P=u??"",O=s.instructionsText??"",f=R?.trim()??"",b=s.instructionsPath?.trim()??"";return P!==O||f!==b})(),q=async()=>{J(!0);try{await oa(s.id,{instructionsText:u||void 0,instructionsPath:R.trim()||void 0},n),i("Instructions saved","success"),C(!0),E.current&&clearTimeout(E.current),E.current=setTimeout(()=>C(!1),3e3),await o()}catch(P){i(`Failed to save instructions: ${G(P)}`,"error")}finally{J(!1)}},w=async()=>{const P=R.trim();if(!P){i("No instructions file path set","error");return}K(!0);try{await ct("project",P,F),i("Instructions file saved","success"),N(!1),j(!0),V.current&&clearTimeout(V.current),V.current=setTimeout(()=>j(!1),3e3),await o()}catch(O){i(`Failed to save instructions file: ${G(O)}`,"error")}finally{K(!1)}},Q=!!R.trim();return e.jsxs("div",{className:"config-tab",children:[e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Custom Instructions"}),e.jsx("p",{className:"config-description",children:"Append custom instructions to this agent's system prompt at execution time. Use this to customize behavior, coding style, or project conventions without modifying built-in prompts."}),e.jsxs("div",{className:"config-fields",children:[e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"instructions-text",children:"Inline Instructions"}),e.jsx("div",{className:"agent-content-toolbar",children:e.jsxs("div",{className:"agent-content-mode-toggle",children:[e.jsxs("button",{className:`btn btn-sm ${M?"":"btn-primary"}`,onClick:()=>k(!1),disabled:!M,"aria-label":"Edit mode","data-testid":"instructions-edit-toggle",children:[e.jsx(Je,{size:14}),"Edit"]}),e.jsxs("button",{className:`btn btn-sm ${M?"btn-primary":""}`,onClick:()=>k(!0),disabled:M,"aria-label":"Preview mode","data-testid":"instructions-preview-toggle",children:[e.jsx(We,{size:14}),"Preview"]})]})}),M?u.trim()?e.jsx("div",{className:"agent-content-preview markdown-body",children:e.jsx(qe,{remarkPlugins:[Ge],children:u})}):e.jsx("div",{className:"agent-content-preview agent-content-placeholder",children:"No inline instructions defined yet. Switch to Edit mode to add instructions."}):e.jsx("textarea",{id:"instructions-text",className:"input",rows:10,placeholder:"Enter custom instructions to append to this agent's system prompt...",value:u,onChange:P=>{g(P.target.value),C(!1)}}),!M&&e.jsx("span",{className:"config-hint",children:"Markdown formatting supported. Max 50,000 characters."})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"instructions-path",children:"Instructions File Path"}),e.jsx("input",{id:"instructions-path",type:"text",className:"input",placeholder:"e.g., .fusion/agents/my-agent-instructions.md",value:R,onChange:P=>{d(P.target.value),C(!1)}}),e.jsx("span",{className:"config-hint",children:"Path to a .md file (relative to project root). Contents are read and appended at execution time."})]})]}),!M&&e.jsxs("div",{className:"config-actions",children:[e.jsx("button",{className:"btn btn-task-create",disabled:!$||y,onClick:()=>void q(),children:y?e.jsxs(e.Fragment,{children:[e.jsx(B,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(de,{size:16}),"Save Instructions"]})}),!$&&ee&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(de,{size:14}),"Instructions saved"]})]})]}),Q&&e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Instructions File Editor"}),e.jsx("p",{className:"config-description",children:"Edit the instructions file directly. Changes are saved separately from the path configuration."}),e.jsx("div",{className:"config-fields",children:e.jsxs("div",{className:"config-field",children:[e.jsxs("div",{className:"config-inline-header",children:[e.jsx("label",{htmlFor:"instructions-file-content",children:"File Content"}),x&&e.jsxs("span",{className:"config-hint config-hint--inline-tight",children:[e.jsx(B,{size:12,className:"animate-spin"}),"Loading..."]}),z&&!x&&e.jsx("span",{className:"config-hint config-hint--warning",children:"Unsaved changes"})]}),e.jsx("textarea",{id:"instructions-file-content",className:"input config-textarea-mono",rows:20,placeholder:"File content will appear here when loaded...",value:F,readOnly:x,onChange:P=>{c(P.target.value),N(!0),j(!1)}}),e.jsx("span",{className:"config-hint",children:"Edit the markdown file content directly. Save separately using the button below."})]})}),e.jsxs("div",{className:"config-actions",children:[e.jsx("button",{className:"btn btn-task-create",disabled:!z||m,onClick:()=>void w(),children:m?e.jsxs(e.Fragment,{children:[e.jsx(B,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(de,{size:16}),"Save File"]})}),!z&&T&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(de,{size:14}),"File saved"]})]})]})]})}function Js(s){const n=s??{},i={};return n.heartbeatIntervalMs!==void 0&&n.heartbeatIntervalMs!==null&&(i.heartbeatIntervalMs=String(Number(n.heartbeatIntervalMs)/1e3)),n.heartbeatTimeoutMs!==void 0&&n.heartbeatTimeoutMs!==null&&(i.heartbeatTimeoutMs=String(Number(n.heartbeatTimeoutMs)/1e3)),n.maxConcurrentRuns!==void 0&&n.maxConcurrentRuns!==null&&(i.maxConcurrentRuns=String(n.maxConcurrentRuns)),(n.messageResponseMode==="immediate"||n.messageResponseMode==="on-heartbeat")&&(i.messageResponseMode=n.messageResponseMode),i}function gs(s){return s?.enabled!==!1}function xs(s){return s?.autoClaimRelevantTasks!==!1}function bs(s){return s?.runMissedHeartbeatOnStartup===!0}function vs(s){return s?.allowParallelExecution!==!1}function Ws(s){const n=(s??{}).budgetConfig,i={};return n&&(n.tokenBudget!==void 0&&n.tokenBudget!==null&&(i.tokenBudget=String(n.tokenBudget)),n.usageThreshold!==void 0&&n.usageThreshold!==null&&(i.usageThreshold=String(Number(n.usageThreshold)*100)),n.budgetPeriod!==void 0&&n.budgetPeriod!==null&&(i.budgetPeriod=String(n.budgetPeriod)),n.resetDay!==void 0&&n.resetDay!==null&&(i.resetDay=String(n.resetDay))),i}function Va({agent:s,projectId:n,addToast:i,onSaved:o}){const[u,g]=t.useState(!1),[R,d]=t.useState(!1),[M,k]=t.useState(!1),[F,c]=t.useState(!1),[x,A]=t.useState(!1),[z,N]=t.useState(""),[y,J]=t.useState(!1),[m,K]=t.useState(null),[ee,C]=t.useState(!1),T=t.useRef(null),j=s.heartbeatProcedurePath?.trim(),E=`.fusion/agents/${s.name.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||s.id.toLowerCase().replace(/[^a-z0-9]+/g,"-")||"agent"}-${s.id.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"agent"}/HEARTBEAT.md`,V=`.fusion/agents/${s.id}/HEARTBEAT.md`,$=s.id.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"agent",q=!!(j&&(j===E||j===V||new RegExp(`^\\.fusion/agents/[^/]+-${$}/HEARTBEAT\\.md$`).test(j))),w=!!j,Q=t.useCallback(async b=>{k(!0),K(null);try{const r=await ot("project",b,n);N(r.content),J(!1)}catch(r){const l=G(r);K(l),i(`Failed to load heartbeat procedure file: ${l}`,"error")}finally{k(!1)}},[i,n]);t.useEffect(()=>{d(!1),A(!1),N(""),J(!1),K(null),k(!1),c(!1),C(!1)},[s.id,j]),t.useEffect(()=>()=>{T.current&&clearTimeout(T.current)},[]);const P=async()=>{j&&(d(!0),await Q(j))},O=async()=>{if(j){c(!0);try{await ct("project",j,z,n),J(!1),C(!0),i("Heartbeat procedure file saved","success"),T.current&&clearTimeout(T.current),T.current=setTimeout(()=>C(!1),3e3),await o()}catch(b){i(`Failed to save heartbeat procedure file: ${G(b)}`,"error")}finally{c(!1)}}},f=async()=>{g(!0);try{const b=await ha(s.id,n);i(b.procedureFileSeeded?`Heartbeat procedure file ready at ${b.heartbeatProcedurePath}`:`Heartbeat procedure path set to ${b.heartbeatProcedurePath}`,"success"),await o()}catch(b){i(`Failed to upgrade heartbeat procedure: ${G(b)}`,"error")}finally{g(!1)}};return e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Heartbeat Procedure"}),e.jsxs("p",{className:"config-description",children:["The per-tick procedure this agent runs every wake. Defaults to a per-agent markdown file (for example ",e.jsx("code",{children:".fusion/agents/ceo-agent2736/HEARTBEAT.md"}),") that you can edit. Legacy id-only default paths remain valid. Resets on every tick — no need to restart the agent after editing."]}),e.jsxs("div",{className:"config-fields",children:[e.jsxs("div",{className:"config-field",children:[e.jsxs("span",{className:"config-hint",children:["Current path: ",e.jsx("code",{children:j||"(none — using built-in default)"})]}),w&&e.jsx("div",{className:"heartbeat-procedure-actions",children:e.jsx("button",{className:"btn btn-sm",onClick:()=>void P(),disabled:M,children:M?e.jsxs(e.Fragment,{children:[e.jsx(B,{size:16,className:"animate-spin"}),"Loading file…"]}):e.jsxs(e.Fragment,{children:[e.jsx(Ve,{size:16}),"View Heartbeat Markdown"]})})})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("button",{className:"btn",disabled:u||q,onClick:()=>void f(),"aria-label":"Upgrade agent to default heartbeat procedure file",children:u?e.jsxs(e.Fragment,{children:[e.jsx(B,{size:16,className:"animate-spin"}),"Upgrading…"]}):q?e.jsxs(e.Fragment,{children:[e.jsx(de,{size:16}),"Already on default"]}):"Upgrade to Default Heartbeat Procedure"}),e.jsxs("span",{className:"config-hint",children:["Sets ",e.jsx("code",{children:"heartbeatProcedurePath"})," to"," ",e.jsx("code",{children:E})," ","and seeds the file from the built-in template if it doesn't exist. Each agent gets its own per-agent file, so edits stay scoped to this agent. Operator edits to the file are preserved."]})]})]}),R&&w&&j&&e.jsxs("div",{className:"config-fields heartbeat-procedure-viewer",children:[e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"heartbeat-procedure-file-content",children:"Heartbeat Procedure File"}),e.jsxs("div",{className:"agent-content-toolbar",children:[e.jsxs("div",{className:"agent-content-mode-toggle",children:[e.jsxs("button",{className:`btn btn-sm ${x?"":"btn-primary"}`,onClick:()=>A(!1),disabled:!x,"aria-label":"Heartbeat file edit mode",children:[e.jsx(Je,{size:14}),"Edit"]}),e.jsxs("button",{className:`btn btn-sm ${x?"btn-primary":""}`,onClick:()=>A(!0),disabled:x,"aria-label":"Heartbeat file preview mode",children:[e.jsx(We,{size:14}),"Preview"]})]}),M&&e.jsxs("span",{className:"config-hint heartbeat-procedure-status",children:[e.jsx(B,{size:12,className:"animate-spin"}),"Loading..."]}),y&&!M&&e.jsx("span",{className:"config-hint heartbeat-procedure-status heartbeat-procedure-status--warning",children:"Unsaved changes"})]}),x?z.trim()?e.jsx("div",{className:"agent-content-preview markdown-body",children:e.jsx(qe,{remarkPlugins:[Ge],children:z})}):e.jsx("div",{className:"agent-content-preview agent-content-placeholder",children:"No heartbeat procedure markdown content yet."}):e.jsx("textarea",{id:"heartbeat-procedure-file-content",className:"input",rows:16,value:z,readOnly:M,placeholder:"Heartbeat procedure markdown file content will appear here...",onChange:b=>{N(b.target.value),J(!0),C(!1)}}),m&&e.jsxs("span",{className:"config-error",children:["Failed to load file: ",m]}),e.jsxs("span",{className:"config-hint",children:["This editor writes directly to ",e.jsx("code",{children:j}),"."]})]}),!x&&e.jsxs("div",{className:"config-actions",children:[e.jsx("button",{className:"btn btn-task-create",disabled:!y||F||M,onClick:()=>void O(),children:F?e.jsxs(e.Fragment,{children:[e.jsx(B,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(de,{size:16}),"Save Heartbeat File"]})}),!y&&ee&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(de,{size:14}),"File saved"]})]})]})]})}function Ja({agent:s,projectId:n,addToast:i,onSaved:o,onHasChangesChange:u,onDelete:g,onAgentDraftApplied:R}){const[d,M]=t.useState(s.name),[k,F]=t.useState(s.role),[c,x]=t.useState(s.title??""),[A,z]=t.useState(s.icon??""),[N,y]=t.useState(s.reportsTo??""),[J,m]=t.useState([]),[K,ee]=t.useState(!1),[C,T]=t.useState(!1),[j,E]=t.useState(!1),V=t.useRef(null),[$,q]=t.useState(()=>{const a={};for(const h of _e){const S=s.metadata[h.key];S!=null&&(a[h.key]=String(S))}return a}),[w,Q]=t.useState(()=>Js(s.runtimeConfig)),[P,O]=t.useState(()=>gs(s.runtimeConfig)),[f,b]=t.useState(()=>xs(s.runtimeConfig)),[r,l]=t.useState(()=>bs(s.runtimeConfig)),[p,se]=t.useState(()=>vs(s.runtimeConfig)),[L,Y]=t.useState(()=>Ws(s.runtimeConfig)),[ie,xe]=t.useState(s.bundleConfig?.mode??""),[W,H]=t.useState(s.bundleConfig?.entryFile??"AGENTS.md"),[te,De]=t.useState(s.bundleConfig?.externalPath??""),[Ne,Re]=t.useState(s.bundleConfig?.files??[]),[oe,Ee]=t.useState(Array.isArray(s.metadata?.skills)?s.metadata.skills:[]),[cs,Ye]=t.useState([]),[ze,be]=t.useState(!1),[Me,v]=t.useState([]),[I,X]=t.useState([]),[ne,re]=t.useState([]),[he,ye]=t.useState(!1),Se=(()=>{const a=s.runtimeConfig??{};return a.modelProvider&&a.modelId?`${a.modelProvider}/${a.modelId}`:typeof a.model=="string"&&a.model.includes("/")?a.model:""})(),Fe=typeof s.runtimeConfig?.runtimeHint=="string"?s.runtimeConfig.runtimeHint:"",[fe,He]=t.useState(Fe?"runtime":"model"),[ve,Ke]=t.useState(Se),[Ae,Oe]=t.useState(Fe),Ze=N.trim(),ks=t.useMemo(()=>J.filter(a=>a.id!==s.id),[J,s.id]),ut=!!Ze&&!ks.some(a=>a.id===Ze),mt=t.useMemo(()=>({name:d,role:k,title:c||void 0,instructionsText:s.instructionsText,soul:s.soul,memory:s.memory,reportsTo:N||void 0,skills:oe,model:ve||void 0,runtimeHint:fe==="runtime"&&Ae||void 0,thinkingLevel:$.thinkingLevel??void 0,maxTurns:$.maxTurns?Number($.maxTurns):void 0,heartbeatIntervalMs:w.heartbeatIntervalMs?Number(w.heartbeatIntervalMs)*1e3:void 0,heartbeatTimeoutMs:w.heartbeatTimeoutMs?Number(w.heartbeatTimeoutMs)*1e3:void 0,maxConcurrentRuns:w.maxConcurrentRuns?Number(w.maxConcurrentRuns):void 0,messageResponseMode:w.messageResponseMode}),[s.instructionsText,s.memory,s.soul,$.maxTurns,$.thinkingLevel,w.heartbeatIntervalMs,w.heartbeatTimeoutMs,w.maxConcurrentRuns,w.messageResponseMode,ve,d,N,k,fe,Ae,oe,c]),ht=t.useCallback(a=>{M(a.name),F(a.role),x(a.title??""),z(a.icon??""),y(a.reportsTo??""),a.skills&&Ee(a.skills),a.thinkingLevel&&q(S=>({...S,thinkingLevel:a.thinkingLevel})),a.maxTurns!==void 0&&q(S=>({...S,maxTurns:String(a.maxTurns)})),a.runtimeHint!==void 0?(He("runtime"),Oe(a.runtimeHint??""),a.runtimeHint&&Ke("")):a.model!==void 0&&(He("model"),Ke(a.model??""),Oe(""));const h=Object.fromEntries(Object.entries({name:a.name,role:a.role,title:a.title,icon:a.icon,reportsTo:a.reportsTo,instructionsText:a.instructionsText,soul:a.soul,memory:a.memory}).filter(([,S])=>S!==void 0));R?.(h),E(!1),i("Interview draft applied. Review and save when ready.","success")},[i,R]);t.useEffect(()=>{let a=!1;return ee(!0),Zt(void 0,n).then(h=>{a||m(h)}).catch(()=>{a||m([])}).finally(()=>{a||ee(!1)}),()=>{a=!0}},[n]),t.useEffect(()=>{be(!0),Qt().then(a=>{Ye(a.models),v(a.favoriteProviders),X(a.favoriteModels)}).catch(()=>{}).finally(()=>be(!1))},[]);const ft=t.useCallback(async a=>{const h=Me,_=h.includes(a)?h.filter(ce=>ce!==a):[a,...h];v(_);try{await Bs({favoriteProviders:_,favoriteModels:I})}catch{v(h)}},[Me,I]),gt=t.useCallback(async a=>{const h=I,_=h.includes(a)?h.filter(ce=>ce!==a):[a,...h];X(_);try{await Bs({favoriteProviders:Me,favoriteModels:_})}catch{X(h)}},[Me,I]);t.useEffect(()=>{ye(!0),nt(n).then(re).catch(()=>re([])).finally(()=>ye(!1))},[n]);const[ke,ds]=t.useState(null),[Cs,ws]=t.useState(!1);t.useEffect(()=>{ps(s.id,n).then(ds).catch(()=>ds(null))},[s.id,n]);const xt=async()=>{ws(!0);try{await ua(s.id,n),i("Budget usage reset successfully","success");const a=await ps(s.id,n);ds(a)}catch(a){i(`Failed to reset budget: ${G(a)}`,"error")}finally{ws(!1)}},[Ce,Rs]=t.useState(!1),[U,Te]=t.useState({}),[bt,Pe]=t.useState(!1),[us,Qe]=t.useState(null),Ms=s.state==="idle"||s.state==="paused",Be=t.useRef(null),Fs=t.useRef(null),As=t.useRef(null),Xe=t.useRef(0);t.useEffect(()=>()=>{Be.current&&clearTimeout(Be.current)},[]);const ge=(()=>{if(d!==s.name||k!==s.role||c!==(s.title??"")||A!==(s.icon??"")||N!==(s.reportsTo??"")||ie!==(s.bundleConfig?.mode??"")||W!==(s.bundleConfig?.entryFile??"AGENTS.md")||te!==(s.bundleConfig?.externalPath??"")||JSON.stringify(Ne)!==JSON.stringify(s.bundleConfig?.files??[]))return!0;for(const Z of _e){const me=$[Z.key]?.trim()??"",D=s.metadata[Z.key]!==void 0&&s.metadata[Z.key]!==null?String(s.metadata[Z.key]):"";if(me!==D)return!0}const a=s.runtimeConfig??{};if(P!==gs(s.runtimeConfig)||f!==xs(s.runtimeConfig)||r!==bs(s.runtimeConfig)||p!==vs(s.runtimeConfig))return!0;for(const Z of["heartbeatIntervalMs","heartbeatTimeoutMs","maxConcurrentRuns","messageResponseMode"]){const me=w[Z]?.trim()??"";let D=a[Z]!==void 0&&a[Z]!==null?String(a[Z]):"";if((Z==="heartbeatIntervalMs"||Z==="heartbeatTimeoutMs")&&D&&(D=String(Number(D)/1e3)),me!==D)return!0}const h=a.budgetConfig;for(const Z of["tokenBudget","budgetPeriod","resetDay"]){const me=L[Z]?.trim()??"",D=h?.[Z]!==void 0&&h?.[Z]!==null?String(h[Z]):"";if(me!==D)return!0}const S=L.usageThreshold?.trim()??"",_=h?.usageThreshold!==void 0&&h?.usageThreshold!==null?String(Number(h.usageThreshold)*100):"";if(S!==_)return!0;const ce=Array.isArray(s.metadata?.skills)?s.metadata.skills:[];return JSON.stringify(oe)!==JSON.stringify(ce)||fe!==(Fe?"runtime":"model")||ve!==Se||Ae!==Fe})(),Ts=t.useRef(null);t.useEffect(()=>{u&&Ts.current!==ge&&(Ts.current=ge,u(ge))},[ge,u]),t.useEffect(()=>()=>{u?.(!1)},[u]),t.useEffect(()=>{const a={id:s.id,updatedAt:s.updatedAt},h=Fs.current;(!h||h.id!==a.id||h.updatedAt!==a.updatedAt)&&(ge||(Fs.current=a,Q(Js(s.runtimeConfig)),O(gs(s.runtimeConfig)),b(xs(s.runtimeConfig)),l(bs(s.runtimeConfig)),se(vs(s.runtimeConfig)),Y(Ws(s.runtimeConfig)),Ke(Se),Oe(Fe),He(Fe?"runtime":"model")))},[s,ge,Se,Fe]);const Es=(a,h)=>{q(S=>({...S,[a]:h})),Pe(!1),U[a]&&Te(S=>{const _={...S};return delete _[a],_})},es=(a,h)=>{Q(S=>({...S,[a]:h})),Pe(!1),U[a]&&Te(S=>{const _={...S};return delete _[a],_})},vt=a=>{O(a),Pe(!1)},ss=(a,h)=>{Y(S=>({...S,[a]:h})),Pe(!1),U[a]&&Te(S=>{const _={...S};return delete _[a],_})},pe=t.useMemo(()=>{const a=Ba($);for(const[D,we]of Object.entries({heartbeatIntervalMs:{label:"Heartbeat Interval",min:1},heartbeatTimeoutMs:{label:"Heartbeat Timeout",min:5},maxConcurrentRuns:{label:"Max Concurrent Runs",min:1}})){const le=w[D]?.trim();if(!le)continue;const je=Number(le);Number.isNaN(je)||!Number.isFinite(je)?a[D]=`"${we.label}" must be a valid number`:je<we.min&&(a[D]=`"${we.label}" must be at least ${we.min.toLocaleString()}`)}const h=w.messageResponseMode?.trim();h&&!["immediate","on-heartbeat"].includes(h)&&(a.messageResponseMode='"Message Response Mode" must be either immediate or on-heartbeat');const S=L.tokenBudget?.trim();if(S){const D=Number(S);Number.isNaN(D)||!Number.isFinite(D)?a.tokenBudget='"Token Budget" must be a valid number':D<=0&&(a.tokenBudget='"Token Budget" must be greater than 0')}const _=L.usageThreshold?.trim();if(_){const D=Number(_);Number.isNaN(D)||!Number.isFinite(D)?a.usageThreshold='"Usage Threshold" must be a valid number':(D<1||D>100)&&(a.usageThreshold='"Usage Threshold" must be between 1 and 100')}const ce=L.budgetPeriod?.trim();ce&&!["daily","weekly","monthly","lifetime"].includes(ce)&&(a.budgetPeriod='"Budget Period" must be one of: daily, weekly, monthly, lifetime');const Z=L.resetDay?.trim(),me=ce||"lifetime";if(Z){const D=Number(Z);Number.isNaN(D)||!Number.isFinite(D)?a.resetDay='"Reset Day" must be a valid number':me==="weekly"?(D<0||D>6||!Number.isInteger(D))&&(a.resetDay='"Reset Day" must be between 0 (Sunday) and 6 (Saturday) for weekly period'):me==="monthly"&&(D<1||D>31||!Number.isInteger(D))&&(a.resetDay='"Reset Day" must be between 1 and 31 for monthly period')}return a},[$,w,L]),Ps=t.useCallback(()=>{if(Object.keys(pe).length>0)return null;const a={...s.metadata};for(const le of _e){const je=$[le.key]?.trim();je?le.type==="number"?a[le.key]=Number(je):a[le.key]=je:delete a[le.key]}oe.length>0?a.skills=oe:delete a.skills;const h={...s.runtimeConfig};h.enabled=P,h.autoClaimRelevantTasks=f,h.runMissedHeartbeatOnStartup=r,h.allowParallelExecution=p;for(const le of["heartbeatIntervalMs","heartbeatTimeoutMs","maxConcurrentRuns"]){const je=w[le]?.trim();if(!je)delete h[le];else{const $s=Number(je);h[le]=le==="maxConcurrentRuns"?$s:$s*1e3}}const S=w.messageResponseMode?.trim();if(S?h.messageResponseMode=S:delete h.messageResponseMode,fe==="runtime")Ae.trim()?h.runtimeHint=Ae.trim():delete h.runtimeHint,delete h.modelProvider,delete h.modelId,delete h.model;else if(delete h.runtimeHint,ve.trim()){const le=ve.indexOf("/");le!==-1&&(h.modelProvider=ve.slice(0,le),h.modelId=ve.slice(le+1),h.model=ve.trim())}else delete h.modelProvider,delete h.modelId,delete h.model;const _={},ce=L.tokenBudget?.trim(),Z=L.usageThreshold?.trim(),me=L.budgetPeriod?.trim(),D=L.resetDay?.trim();ce&&(_.tokenBudget=Number(ce)),Z&&(_.usageThreshold=Number(Z)/100),me&&(_.budgetPeriod=me),D&&(_.resetDay=Number(D)),Object.keys(_).length>0?h.budgetConfig=_:delete h.budgetConfig;let we;return ie&&(we={mode:ie,entryFile:W||"AGENTS.md",files:Ne.length>0?Ne:["AGENTS.md"]},ie==="external"&&te.trim()&&(we.externalPath=te.trim())),{name:d.trim()||void 0,role:k,title:c.trim()||void 0,icon:A.trim()||void 0,reportsTo:N.trim()||void 0,metadata:a,runtimeConfig:h,bundleConfig:we}},[s.metadata,s.runtimeConfig,p,f,L,W,te,Ne,ie,$,P,w,A,ve,d,N,k,r,fe,Ae,oe,c,pe]),Ie=t.useCallback(async(a,h)=>{const S=Ps();if(!S)return Te(pe),a&&i("Please fix validation errors before saving","error"),h==="auto"&&Qe("Fix validation errors to save changes"),!1;const _=JSON.stringify(S);if(_===As.current)return!1;const ce=++Xe.current;Te({}),Qe(null),Rs(!0);try{return await Xt(s.id,S,n),ce!==Xe.current?!1:(As.current=_,h==="manual"&&i("Settings saved","success"),Qe(null),Pe(!0),Be.current&&clearTimeout(Be.current),Be.current=setTimeout(()=>Pe(!1),3e3),await o(),!0)}catch(Z){if(ce===Xe.current){const me=G(Z);Qe(me),i(`Failed to save settings: ${me}`,"error")}return!1}finally{ce===Xe.current&&Rs(!1)}},[i,s.id,Ps,o,n,pe]),pt=async()=>{await Ie(!0,"manual")},ue=t.useCallback(()=>{if(!(!ge||Ce)){if(Object.keys(pe).length>0){Te(pe);return}Ie(!1,"auto")}},[ge,Ce,Ie,pe]);t.useEffect(()=>{if(!ge||Ce)return;if(Object.keys(pe).length>0){Te(pe);return}const a=setTimeout(()=>{Ie(!1,"auto")},Fa);return()=>clearTimeout(a)},[ge,Ce,Ie,pe]);const jt=t.useCallback(async a=>{T(!0);try{await ea(s.id,a,n),await o(),i("Avatar uploaded","success")}catch(h){i(G(h),"error")}finally{T(!1),V.current&&(V.current.value="")}},[i,s.id,o,n]),Nt=t.useCallback(async()=>{T(!0);try{await sa(s.id,n),await o(),i("Avatar removed","success")}catch(a){i(G(a),"error")}finally{T(!1)}},[i,s.id,o,n]),Ls=Ce?"Saving changes…":us?`Save failed: ${us}`:!ge&&bt?"All changes saved":null;return e.jsxs("div",{className:"config-tab",children:[e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Agent Configuration"}),e.jsx("p",{className:"config-description",children:"Configure agent settings and behavior."}),e.jsx("div",{className:"config-actions-row",children:e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>E(!0),children:"AI Interview"})}),e.jsxs("div",{className:"config-fields",children:[e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"agent-name",children:"Name"}),e.jsx("input",{id:"agent-name",type:"text",className:"input",value:d,onChange:a=>M(a.target.value),onBlur:()=>{ue()}})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"agent-role",children:"Role"}),e.jsxs("select",{id:"agent-role",className:"select",value:k,onChange:a=>{F(a.target.value),ue()},children:[e.jsx("option",{value:"triage",children:"Triage"}),e.jsx("option",{value:"executor",children:"Executor"}),e.jsx("option",{value:"reviewer",children:"Reviewer"}),e.jsx("option",{value:"merger",children:"Merger"}),e.jsx("option",{value:"scheduler",children:"Scheduler"}),e.jsx("option",{value:"custom",children:"Custom"})]})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"agent-title",children:"Title"}),e.jsx("input",{id:"agent-title",type:"text",className:"input",placeholder:"e.g. Senior Code Reviewer",value:c,onChange:a=>x(a.target.value),onBlur:()=>{ue()}})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{children:"Avatar"}),e.jsxs("div",{className:"agent-avatar-editor",children:[e.jsx(Xs,{agent:s,size:64,className:"agent-avatar-editor-preview"}),e.jsxs("div",{className:"agent-avatar-editor-actions",children:[e.jsx("input",{ref:V,id:"agent-avatar-upload",type:"file",accept:"image/png,image/jpeg,image/gif,image/webp",className:"visually-hidden",disabled:C,onChange:a=>{const h=a.target.files?.[0];h&&jt(h)}}),e.jsx("button",{type:"button",className:"btn btn-sm",disabled:C,onClick:()=>V.current?.click(),children:"Upload Avatar"}),s.imageUrl?e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>void Nt(),disabled:C,children:"Remove Avatar"}):null]})]})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"agent-icon",children:"Icon"}),e.jsx("input",{id:"agent-icon",type:"text",className:"input",placeholder:"e.g. 🤖",value:A,onChange:a=>z(a.target.value),onBlur:()=>{ue()}})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"agent-reports-to",children:"Reports To"}),e.jsxs("select",{id:"agent-reports-to",className:"select",value:N,onChange:a=>{y(a.target.value),ue()},disabled:K,children:[e.jsx("option",{value:"",children:"No manager"}),ut&&e.jsxs("option",{value:Ze,children:["Unknown manager (",Ze,")"]}),ks.map(a=>e.jsxs("option",{value:a.id,children:[a.name," (",a.id,")"]},a.id))]})]})]})]}),e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Skills"}),e.jsx("p",{className:"config-description",children:"Assign skills to this agent for specialized behavior."}),e.jsx("div",{className:"config-fields",children:e.jsx("div",{className:"config-field",children:e.jsx(fa,{id:"agent-skills",label:"Skills",value:oe,onChange:a=>{Ee(a),ue()},projectId:n})})})]}),e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Model"}),e.jsx("p",{className:"config-description",children:"Choose either a built-in model or a plugin runtime for this agent. These options are mutually exclusive."}),e.jsxs("div",{className:"config-fields",children:[e.jsxs("div",{className:"config-field",children:[e.jsx("label",{children:"Runtime Source"}),e.jsxs("div",{className:"config-runtime-tabs",role:"tablist","aria-label":"Runtime source",children:[e.jsx("button",{type:"button",className:`config-runtime-tab${fe==="model"?" active":""}`,role:"tab","aria-selected":fe==="model",tabIndex:fe==="model"?0:-1,onClick:()=>{He("model"),Oe(""),ue()},children:"Built-in Model"}),e.jsx("button",{type:"button",className:`config-runtime-tab${fe==="runtime"?" active":""}`,role:"tab","aria-selected":fe==="runtime",tabIndex:fe==="runtime"?0:-1,onClick:()=>{He("runtime"),ue()},children:"Plugin Runtime"})]})]}),fe==="model"?e.jsx("div",{className:"config-field",children:e.jsx(ta,{models:cs,value:ve,onChange:a=>{Ke(a),ue()},placeholder:"Use global default",label:"Agent Model",disabled:ze,favoriteProviders:Me,onToggleFavorite:ft,favoriteModels:I,onToggleModelFavorite:gt})}):e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"agent-runtime-hint",children:"Runtime"}),he?e.jsx("span",{className:"config-hint",children:"Loading runtimes…"}):e.jsxs("select",{id:"agent-runtime-hint",className:"select",value:Ae,onChange:a=>{Oe(a.target.value),ue()},children:[e.jsx("option",{value:"",children:ne.length>0?"Select a plugin runtime…":"No plugin runtimes available"}),ne.map(a=>e.jsx("option",{value:a.runtimeId,children:a.description?`${a.name} — ${a.description}`:a.name},`${a.pluginId}:${a.runtimeId}`))]})]})]})]}),e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Heartbeat Settings"}),e.jsx("p",{className:"config-description",children:"Configure how this agent's heartbeat is monitored. Leave a field empty to use system defaults."}),e.jsxs("div",{className:"config-fields",children:[e.jsxs("div",{className:"config-field",children:[e.jsxs("label",{className:"checkbox-label",htmlFor:"hb-enabled",children:[e.jsx("input",{id:"hb-enabled",type:"checkbox",checked:P,onChange:a=>{vt(a.target.checked),ue()}}),"Heartbeat Enabled"]}),e.jsx("span",{className:"config-hint",children:"When enabled, this agent receives scheduled heartbeat runs based on its interval."})]}),e.jsxs("div",{className:"config-field",children:[e.jsxs("label",{className:"checkbox-label",htmlFor:"hb-autoClaimRelevantTasks",children:[e.jsx("input",{id:"hb-autoClaimRelevantTasks",type:"checkbox",checked:f,onChange:a=>{b(a.target.checked),ue()}}),"Auto-Claim Relevant Tasks"]}),e.jsx("span",{className:"config-hint",children:"When enabled (default), no-task heartbeats scan open unowned work and auto-claim tasks aligned with this agent's role and soul."})]}),e.jsxs("div",{className:"config-field",children:[e.jsxs("label",{className:"checkbox-label",htmlFor:"hb-runMissedHeartbeatOnStartup",children:[e.jsx("input",{id:"hb-runMissedHeartbeatOnStartup",type:"checkbox",checked:r,onChange:a=>{l(a.target.checked),ue()}}),"Run Missed Heartbeat On Startup"]}),e.jsx("span",{className:"config-hint",children:"When enabled, if the server was down across this agent's scheduled heartbeat tick, fire a single catch-up heartbeat at startup. Default: off."})]}),e.jsxs("div",{className:"config-field",children:[e.jsxs("label",{className:"checkbox-label",htmlFor:"hb-allowParallelExecution",children:[e.jsx("input",{id:"hb-allowParallelExecution",type:"checkbox",checked:p,onChange:a=>{se(a.target.checked),ue()}}),"Allow Parallel Execution"]}),e.jsx("span",{className:"config-hint",children:"When disabled, the heartbeat and task execution paths serialize for this agent (heartbeat will not start while the agent's task is executing, and vice versa). Permanent agents only."})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"hb-heartbeatIntervalMs",children:"Heartbeat Interval (s)"}),e.jsx("input",{id:"hb-heartbeatIntervalMs",type:"text",inputMode:"numeric",className:ae("input",!!U.heartbeatIntervalMs&&"input--error"),placeholder:String(js/1e3),value:w.heartbeatIntervalMs??"",onChange:a=>es("heartbeatIntervalMs",a.target.value)}),U.heartbeatIntervalMs?e.jsx("span",{className:"config-error",children:U.heartbeatIntervalMs}):e.jsxs("span",{className:"config-hint",children:["How often heartbeats are checked. Leave empty for system default (",js/1e3,"s / ",Ma,")."]})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"hb-heartbeatTimeoutMs",children:"Heartbeat Timeout (s)"}),e.jsx("input",{id:"hb-heartbeatTimeoutMs",type:"text",inputMode:"numeric",className:ae("input",!!U.heartbeatTimeoutMs&&"input--error"),placeholder:"60",value:w.heartbeatTimeoutMs??"",onChange:a=>es("heartbeatTimeoutMs",a.target.value)}),U.heartbeatTimeoutMs?e.jsx("span",{className:"config-error",children:U.heartbeatTimeoutMs}):e.jsx("span",{className:"config-hint",children:"Time without heartbeat before agent is considered unresponsive. Leave empty for system default (60s)"})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"hb-maxConcurrentRuns",children:"Max Concurrent Runs"}),e.jsx("input",{id:"hb-maxConcurrentRuns",type:"text",inputMode:"numeric",className:ae("input",!!U.maxConcurrentRuns&&"input--error"),placeholder:"1",value:w.maxConcurrentRuns??"",onChange:a=>es("maxConcurrentRuns",a.target.value)}),U.maxConcurrentRuns?e.jsx("span",{className:"config-error",children:U.maxConcurrentRuns}):e.jsx("span",{className:"config-hint",children:"Maximum simultaneous heartbeat runs for this agent. Leave empty for system default (1)."})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"hb-messageResponseMode",children:"Message Response Mode"}),e.jsxs("select",{id:"hb-messageResponseMode",className:ae("select",!!U.messageResponseMode&&"input--error"),value:w.messageResponseMode??"",onChange:a=>es("messageResponseMode",a.target.value),children:[e.jsx("option",{value:"",children:"System Default (On Heartbeat)"}),e.jsx("option",{value:"on-heartbeat",children:"On Heartbeat"}),e.jsx("option",{value:"immediate",children:"Immediate"})]}),U.messageResponseMode?e.jsx("span",{className:"config-error",children:U.messageResponseMode}):e.jsx("span",{className:"config-hint",children:"How this agent responds to incoming messages. 'Immediate' wakes the agent as soon as a message arrives. 'On Heartbeat' defers processing to the next scheduled heartbeat."})]})]})]}),e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Budget Settings"}),e.jsx("p",{className:"config-description",children:"Configure token budget limits for this agent. Leave all fields empty to disable budget tracking."}),e.jsxs("div",{className:"config-fields",children:[e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"budget-tokenBudget",children:"Token Budget"}),e.jsx("input",{id:"budget-tokenBudget",type:"text",inputMode:"numeric",className:ae("input",!!U.tokenBudget&&"input--error"),placeholder:"No limit",value:L.tokenBudget??"",onChange:a=>ss("tokenBudget",a.target.value)}),U.tokenBudget?e.jsx("span",{className:"config-error",children:U.tokenBudget}):e.jsx("span",{className:"config-hint",children:"Total token cap (input + output) for this agent. Leave empty for no limit."})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"budget-usageThreshold",children:"Usage Threshold (%)"}),e.jsx("input",{id:"budget-usageThreshold",type:"text",inputMode:"numeric",className:ae("input",!!U.usageThreshold&&"input--error"),placeholder:"80",value:L.usageThreshold??"",onChange:a=>ss("usageThreshold",a.target.value)}),U.usageThreshold?e.jsx("span",{className:"config-error",children:U.usageThreshold}):e.jsx("span",{className:"config-hint",children:"Warning threshold as a percentage. Agent warns when usage reaches this level. Default: 80%."})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"budget-budgetPeriod",children:"Budget Period"}),e.jsxs("select",{id:"budget-budgetPeriod",className:ae("select",!!U.budgetPeriod&&"input--error"),value:L.budgetPeriod??"",onChange:a=>ss("budgetPeriod",a.target.value),children:[e.jsx("option",{value:"",children:"No reset (lifetime)"}),e.jsx("option",{value:"daily",children:"Daily"}),e.jsx("option",{value:"weekly",children:"Weekly"}),e.jsx("option",{value:"monthly",children:"Monthly"})]}),U.budgetPeriod?e.jsx("span",{className:"config-error",children:U.budgetPeriod}):e.jsx("span",{className:"config-hint",children:"How often the budget counter resets. Leave empty for lifetime budget."})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"budget-resetDay",children:"Reset Day"}),e.jsx("input",{id:"budget-resetDay",type:"text",inputMode:"numeric",className:ae("input",!!U.resetDay&&"input--error"),placeholder:"Auto",value:L.resetDay??"",onChange:a=>ss("resetDay",a.target.value)}),U.resetDay?e.jsx("span",{className:"config-error",children:U.resetDay}):e.jsx("span",{className:"config-hint",children:L.budgetPeriod==="weekly"?"Day of week (0=Sunday to 6=Saturday) for reset.":L.budgetPeriod==="monthly"?"Day of month (1-31) for reset.":"Day for reset (weekly: 0-6, monthly: 1-31). Leave empty for automatic."})]}),ke?.budgetLimit!=null&&e.jsxs("div",{className:"config-field",children:[e.jsx("label",{children:"Current Usage"}),e.jsxs("div",{className:"budget-progress-container",children:[e.jsx("div",{className:"budget-progress-bar",children:e.jsx("div",{className:ae("budget-progress-bar__fill",(ke.usagePercent??0)>=100?"budget-progress-bar__fill--red":(ke.usagePercent??0)>=80?"budget-progress-bar__fill--amber":"budget-progress-bar__fill--green"),style:{width:`${Math.min(ke.usagePercent??0,100)}%`}})}),e.jsxs("span",{className:"budget-progress-label",children:[(ke.currentUsage??0).toLocaleString()," / ",(ke.budgetLimit??0).toLocaleString()," tokens (",Math.round(ke.usagePercent??0),"% used)"]})]})]}),ke?.budgetLimit!=null&&e.jsx("div",{className:"config-field",children:e.jsx("button",{className:"btn btn-reset-budget",onClick:()=>void xt(),disabled:Cs,children:Cs?e.jsxs(e.Fragment,{children:[e.jsx(B,{size:14,className:"animate-spin"}),"Resetting…"]}):e.jsxs(e.Fragment,{children:[e.jsx(os,{size:14}),"Reset Budget Usage"]})})})]})]}),e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Instruction Bundle"}),e.jsx("p",{className:"config-description",children:"Configure the agent's instruction bundle. Leave empty to use inline instructions only."}),e.jsxs("div",{className:"config-fields",children:[e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"bundle-mode",children:"Bundle Mode"}),e.jsxs("select",{id:"bundle-mode",className:"select",value:ie,onChange:a=>xe(a.target.value),children:[e.jsx("option",{value:"",children:"None (use inline instructions)"}),e.jsx("option",{value:"managed",children:"Managed (system-managed directory)"}),e.jsx("option",{value:"external",children:"External (user-specified path)"})]}),e.jsxs("span",{className:"config-hint",children:[ie==="managed"&&"Files will be stored in a system-managed directory within .fusion/agents/",ie==="external"&&"Specify an external directory path for the instruction files",!ie&&"Select a mode to enable instruction bundling"]})]}),ie&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"bundle-entry-file",children:"Entry File"}),e.jsx("input",{id:"bundle-entry-file",type:"text",className:"input",placeholder:"AGENTS.md",value:W,onChange:a=>H(a.target.value)}),e.jsx("span",{className:"config-hint",children:"Primary instructions file name (default: AGENTS.md)"})]}),ie==="external"&&e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"bundle-external-path",children:"External Path"}),e.jsx("input",{id:"bundle-external-path",type:"text",className:"input",placeholder:"e.g. .fusion/agents/my-agent",value:te,onChange:a=>De(a.target.value)}),e.jsx("span",{className:"config-hint",children:"Absolute or relative path to the external directory"})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"bundle-files",children:"Files (comma-separated)"}),e.jsx("input",{id:"bundle-files",type:"text",className:"input",placeholder:"AGENTS.md, PROMPTS.md",value:Ne.join(", "),onChange:a=>Re(a.target.value.split(",").map(h=>h.trim()).filter(Boolean))}),e.jsx("span",{className:"config-hint",children:"List of file names in the bundle directory"})]})]})]})]}),e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Advanced Settings"}),e.jsx("p",{className:"config-description",children:"Advanced configuration options for this agent. Leave a field empty to use system defaults."}),e.jsx("div",{className:"config-fields",children:_e.map(a=>{const h=!!U[a.key];return e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:`adv-${a.key}`,children:a.label}),a.type==="select"?e.jsxs("select",{id:`adv-${a.key}`,className:ae("select",h&&"input--error"),value:$[a.key]??"",onChange:S=>Es(a.key,S.target.value),children:[e.jsx("option",{value:"",children:"System Default"}),a.options?.map(S=>e.jsx("option",{value:S.value,children:S.label},S.value))]}):e.jsx("input",{id:`adv-${a.key}`,type:"text",inputMode:a.type==="number"?"numeric":void 0,className:ae("input",h&&"input--error"),placeholder:a.placeholder,value:$[a.key]??"",onChange:S=>Es(a.key,S.target.value)}),h&&e.jsx("span",{className:"config-error",children:U[a.key]}),!h&&a.hint&&e.jsx("span",{className:"config-hint",children:a.hint})]},a.key)})}),e.jsxs("div",{className:"config-actions",children:[e.jsx("button",{className:"btn btn-task-create",disabled:!ge||Ce,onClick:()=>void pt(),children:Ce?e.jsxs(e.Fragment,{children:[e.jsx(B,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(de,{size:16}),"Save Settings"]})}),Ls&&e.jsxs("span",{className:ae("config-saved-indicator",us&&"config-saved-indicator--error"),children:[Ce?e.jsx(B,{size:14,className:"animate-spin"}):e.jsx(de,{size:14}),Ls]})]})]}),e.jsx(Va,{agent:s,projectId:n,addToast:i,onSaved:o}),e.jsxs("div",{className:"config-section config-section--danger",children:[e.jsx("h3",{children:"Danger Zone"}),e.jsx("p",{className:"config-description",children:"Permanently delete this agent from the project."}),e.jsx("div",{className:"config-fields",children:e.jsxs("div",{className:"config-field",children:[e.jsxs("button",{className:"btn btn--danger",disabled:!Ms||!g,onClick:()=>void g?.(),children:[e.jsx(rs,{size:16}),"Delete Agent"]}),e.jsx("span",{className:"config-danger-note",children:Ms?"Deletion is permanent and cannot be undone.":`Agent deletion is only available when state is idle or paused (current state: ${s.state}).`})]})})]}),e.jsx(ga,{isOpen:j,onClose:()=>E(!1),onUseDraft:ht,projectId:n,existingAgents:J,mode:"edit",existingAgentConfig:mt})]})}function Wa({agentId:s,projectId:n,onChildClick:i}){const[o,u]=t.useState([]),[g,R]=t.useState(!0);return t.useEffect(()=>{R(!0),Gt(s,n).then(u).finally(()=>R(!1))},[s,n]),g?e.jsxs("div",{className:"detail-section",children:[e.jsx("div",{className:"detail-section-header",children:e.jsx("h3",{children:"Employees"})}),e.jsxs("div",{className:"detail-section-body detail-section-body--loading",children:[e.jsx(B,{size:16,className:"spin"}),e.jsx("span",{className:"text-muted",children:"Loading employees..."})]})]}):e.jsxs("div",{className:"detail-section",children:[e.jsxs("div",{className:"detail-section-header",children:[e.jsx("h3",{children:"Employees"}),e.jsxs("span",{className:"text-muted",children:["(",o.length,")"]})]}),e.jsx("div",{className:"detail-section-body",children:o.length===0?e.jsxs("div",{className:"agent-empty agent-empty--padded",children:[e.jsx(tt,{size:32,opacity:.3}),e.jsx("p",{children:"No employees"}),e.jsx("p",{className:"text-muted",children:"This agent has no employees"})]}):e.jsx("div",{className:"agent-tree__children",children:o.map(d=>{const M=Ss[d.state];return e.jsxs("div",{className:"agent-tree__node agent-is-child",onClick:()=>i?.(d.id),role:"button",tabIndex:0,onKeyDown:k=>{(k.key==="Enter"||k.key===" ")&&(k.key===" "&&k.preventDefault(),i?.(d.id))},style:{cursor:i?"pointer":"default"},children:[e.jsx("span",{className:"agent-tree__icon",children:d.icon??"🤖"}),e.jsx("span",{className:"agent-tree__name",children:d.name}),e.jsx("span",{className:"agent-tree__badge",style:{background:M?.bg??"var(--state-idle-bg)",color:M?.text??"var(--state-idle-text)",border:`1px solid ${M?.border??"var(--state-idle-border)"}`},children:d.state})]},d.id)})})})]})}export{Qa as AgentDetailView,$e as relativeTime};
@@ -1 +0,0 @@
1
- import{r as s,a as ys,j as t}from"./vendor-react-K0fH_qHe.js";import{i as nt,b1 as It,t as Jt,b2 as ks,b3 as zt,b4 as Cs,w as Ct,b5 as $e,b6 as Ns,b7 as js,b8 as Ms,b9 as Rs,ba as As,bb as Es,s as Yt,bc as Ts,bd as Ps,be as Ds,bf as $s,bg as Ls,bh as Fs,bi as Is,k as Xt,bj as zs,p as _s,bk as Us,bl as Os,u as Hs,bm as Bs,ab as Qt,ac as Zt,bn as Ws,bo as Gs,S as Vs,W as _t,P as et,I as Ye,am as Ks,bp as Ut,bq as Ot,B as st,a8 as qs,a9 as Js,a as Ys,br as Xs,bs as Qs,bt as Zs,aQ as en,bu as tn,bv as Ht,bw as sn,h as nn,j as Bt,m as an}from"./index-CQyVRLOb.js";import"./vendor-xterm-DzcZoU0P.js";const St="kb-chat-active-session";function Wt(n){const r=typeof n=="string"?n.trim():"",o=r.indexOf("/");return!r||o<=0||o>=r.length-1?{}:{modelProvider:r.slice(0,o),modelId:r.slice(o+1)}}function rn(n){const r=n?.toolCalls;if(!Array.isArray(r))return;const o=r.map(d=>{if(!d||typeof d!="object")return null;const c=d,S=typeof c.toolName=="string"?c.toolName:"";if(!S)return null;const R=c.args;return{toolName:S,...R&&typeof R=="object"?{args:R}:{},isError:!!c.isError,result:c.result,status:"completed"}}).filter(d=>d!==null);return o.length>0?o:void 0}function on(n){const r=n?.fallback;if(!r||typeof r!="object")return;const o=r,d=typeof o.primaryModel=="string"?o.primaryModel:"",c=typeof o.fallbackModel=="string"?o.fallbackModel:"",S=o.triggerPoint;if(!(!d||!c||S!=="session-creation"&&S!=="prompt-time"))return{primaryModel:d,fallbackModel:c,triggerPoint:S}}function yt(n){return{id:n.id,sessionId:n.sessionId,role:n.role,content:n.content,thinkingOutput:n.thinkingOutput,toolCalls:rn(n.metadata),fallbackInfo:on(n.metadata),attachments:n.attachments,createdAt:n.createdAt}}function cn(n,r){const[o,d]=s.useState([]),[c,S]=s.useState(null),[R,A]=s.useState(!0),[D,y]=s.useState([]),[Y,p]=s.useState(!1),[K,C]=s.useState(!1),[Q,b]=s.useState(""),[E,m]=s.useState(""),[j,M]=s.useState([]),[T,I]=s.useState(""),[B,z]=s.useState(""),[G,v]=s.useState(!0),[h,u]=s.useState(new Map),i=s.useRef(null),f=s.useRef(!1),x=s.useRef(""),P=s.useRef(null),ye=s.useRef(o),W=s.useRef(c),ae=s.useRef(K);ye.current=o,W.current=c,ae.current=K,s.useEffect(()=>{x.current=T},[T]);const Fe=s.useRef(new Set),me=s.useRef(0),q=s.useRef(n);q.current!==n&&(q.current=n,me.current++),s.useEffect(()=>{const g=me.current;nt(void 0,n).then(k=>{if(me.current!==g)return;const w=new Map;for(const N of k)w.set(N.id,N);u(w)}).catch(()=>{})},[n]);const oe=s.useCallback(async()=>{A(!0);try{const k=[...(await It(n)).sessions].sort((w,N)=>new Date(N.updatedAt).getTime()-new Date(w.updatedAt).getTime());d(k)}catch{}finally{A(!1)}},[n]);s.useEffect(()=>{oe()},[oe]);const Ge=s.useRef(()=>{}),he=s.useRef(!1);s.useEffect(()=>{he.current=!1},[n]),s.useEffect(()=>{if(R||he.current||W.current)return;const g=Jt(St,n);if(!g){he.current=!0;return}const k=o.find(w=>w.id===g);if(k){he.current=!0,Ge.current(g,k);return}he.current=!0},[R,o,n]);const re=s.useCallback(async(g,k)=>{p(!0);try{const w=await ks(g,{limit:50,...k},n),N=w.messages.map(yt);k?.offset&&k.offset>0?y(ee=>[...N,...ee]):y(N),v(w.messages.length>=50)}catch{}finally{p(!1)}},[n]),je=s.useCallback(()=>{P.current?.(),P.current=null,x.current="",I(""),b(""),m(""),M([]),C(!1)},[]),fe=s.useCallback(g=>{if(i.current||!g)return!0;f.current=!1,C(!0);const{handlers:k}=zt({sessionId:g,tempUserMessageId:"",setStreamingText:b,setStreamingThinking:m,setStreamingToolCalls:M,cancelStreamingFlushesRef:P,addToast:r,onFallbackSession:(N,ee)=>{const F=Wt(N.fallbackModel);d(J=>J.map(Z=>Z.id===ee?{...Z,...F}:Z)),S(J=>J&&J.id===ee?{...J,...F}:J)},onDone:()=>{b(""),m(""),M([]),C(!1),ae.current=!1,i.current=null,re(g)},onError:N=>{b(""),m(""),M([]),C(!1),ae.current=!1,i.current=null;const ee=typeof N=="string"&&N.trim()?N:"Failed to get response";r?.(ee,"error"),re(g)}}),w=Cs(g,k,n);return i.current=w,!0},[r,re,n]),ce=s.useCallback((g,k)=>{const w=W.current?.id??null;if(g&&w===g&&!k)return;i.current&&(i.current.close(),i.current=null);const N=k??o.find(ee=>ee.id===g);S(N||null),je(),v(!0),g?re(g):y([]),N?.isGenerating&&(b(""),fe(N.id)),g?Ct(St,g,n):$e(St,n)},[fe,o,re,n,je]);Ge.current=ce;const ve=s.useCallback(async g=>{const k=await Ns(g,n);i.current&&(i.current.close(),i.current=null);const w={id:k.session.id,title:k.session.title,agentId:k.session.agentId,status:k.session.status,modelProvider:k.session.modelProvider,modelId:k.session.modelId,createdAt:k.session.createdAt,updatedAt:k.session.updatedAt};return d(N=>N.some(ee=>ee.id===w.id)?N:[w,...N]),je(),ce(w.id,w),y([]),w},[n,je,ce]),Ie=s.useCallback(async g=>{await js(g,{status:"archived"},n),d(k=>k.filter(w=>w.id!==g)),c?.id===g&&(S(null),y([]))},[c,n]),Me=s.useCallback(async g=>{c?.id===g&&i.current&&(i.current.close(),i.current=null),await Ms(g,n),d(k=>k.filter(w=>w.id!==g)),c?.id===g&&(S(null),y([]))},[c,n]),Re=s.useCallback(async()=>{!c||!G||await re(c.id,{offset:D.length})},[c,G,re,D.length]),ke=s.useCallback(()=>{c&&(f.current=!0,P.current?.(),P.current=null,i.current?.close(),i.current=null,Rs(c.id,n).catch(()=>{}),C(!1),b(""),m(""),M([]))},[c,n]),Ae=s.useCallback(()=>{x.current="",I("")},[]),ue=s.useRef(()=>{}),ie=As(),ge=s.useCallback((g,k)=>{if(!c)return;if(ae.current){x.current=g,I(g),r?.("Still waiting for previous response — message queued","warning");return}f.current=!1,i.current&&(i.current.close(),i.current=null);const w=`temp-${Date.now()}`,N={id:w,sessionId:c.id,role:"user",content:g,createdAt:new Date().toISOString()};y(F=>[...F,N]),b(""),m(""),M([]),C(!0);const{handlers:ee}=zt({sessionId:c.id,tempUserMessageId:w,setStreamingText:b,setStreamingThinking:m,setStreamingToolCalls:M,cancelStreamingFlushesRef:P,addToast:r,onFallbackSession:(F,J)=>{const Z=Wt(F.fallbackModel);d(te=>te.map(U=>U.id===J?{...U,...Z}:U)),S(te=>te&&te.id===J?{...te,...Z}:te)},onDone:({messageId:F,message:J,accumulated:Z})=>{const te=J?yt(J):{id:F||`msg-${Date.now()}`,sessionId:c.id,role:"assistant",content:Z.text,thinkingOutput:Z.thinking,toolCalls:Z.toolCalls.length>0?Z.toolCalls:void 0,fallbackInfo:Z.fallbackInfo,createdAt:new Date().toISOString()};Fe.current.add(te.id),y(O=>[...O,te]),b(""),m(""),M([]),C(!1),ae.current=!1,i.current=null,setTimeout(()=>{Fe.current.delete(te.id)},1e3),oe();const U=x.current.trim();U&&(x.current="",I(""),ue.current(U))},onError:(F,J)=>{y(U=>U.filter(O=>O.id!==J)),b(""),m(""),M([]),C(!1),ae.current=!1,i.current=null,console.error("[useChat] Stream error:",F);const Z=typeof F=="string"&&F.trim()?F:"Failed to get response";if(typeof F=="string"&&Ts(F)&&(ie.isHiddenNow()||ie.wasRecentlyHidden(5e3))?(console.info("[useChat] Suppressed tab-suspension stream error:",F),c?.id&&re(c.id)):r?.(Z,"error"),!f.current){const U=x.current.trim();U&&(x.current="",I(""),ue.current(U))}}});i.current=Es(c.id,g,ee,k,n)},[c,n,oe,r,re,ie]);ue.current=ge;const ze=B?o.filter(g=>g.title?.toLowerCase().includes(B.toLowerCase())||g.agentId.toLowerCase().includes(B.toLowerCase())):o;return s.useEffect(()=>{if(!W.current?.isGenerating||(i.current||fe(W.current.id),!ae.current||i.current||!W.current))return;const g=setInterval(async()=>{if(!ae.current||i.current||!W.current){clearInterval(g);return}try{(await It(n)).sessions.find(N=>N.id===W.current?.id)?.isGenerating||(clearInterval(g),await re(W.current.id),b(""),m(""),M([]),C(!1))}catch{}},3e3);return()=>clearInterval(g)},[fe,re,n,c]),s.useEffect(()=>{const g=me.current,k=n?`?projectId=${encodeURIComponent(n)}`:"",w=()=>me.current!==g,N=U=>{if(w())return;const O=JSON.parse(U.data);d($=>$.some(X=>X.id===O.id)?$:[O,...$])},ee=U=>{if(w())return;const O=JSON.parse(U.data);d($=>[...$.map(ne=>ne.id===O.id?O:ne)]),W.current?.id===O.id&&(S(O),O.isGenerating&&!i.current&&(b(""),fe(O.id)))},F=U=>{if(w())return;const{id:O}=JSON.parse(U.data);d($=>$.filter(X=>X.id!==O)),W.current?.id===O&&(S(null),y([]))},J=U=>{if(w())return;const O=JSON.parse(U.data),$=yt(O);if(!Fe.current.has($.id)){if(W.current?.id===$.sessionId&&ae.current&&!i.current&&$.role==="assistant"){y(X=>X.some(ne=>ne.id===$.id)?X:[...X,$]),b(""),m(""),M([]),C(!1);return}W.current?.id===$.sessionId&&!ae.current&&y(X=>{if(X.some(ne=>ne.id===$.id))return X;if($.role==="user"){const ne=X.findIndex(xe=>xe.role==="user"&&xe.id.startsWith("temp-")&&xe.content.trim()===$.content.trim());if(ne>=0){const xe=[...X];return xe[ne]=$,xe}}return[...X,$]})}},Z=U=>{if(w())return;const{id:O}=JSON.parse(U.data);y($=>$.filter(X=>X.id!==O))};return Yt(`/api/events${k}`,{events:{"chat:session:created":N,"chat:session:updated":ee,"chat:session:deleted":F,"chat:message:added":J,"chat:message:deleted":Z}})},[fe,n]),s.useEffect(()=>()=>{i.current&&(i.current.close(),i.current=null)},[]),{sessions:o,activeSession:c,sessionsLoading:R,messages:D,messagesLoading:Y,isStreaming:K,streamingText:Q,streamingThinking:E,streamingToolCalls:j,pendingMessage:T,selectSession:ce,createSession:ve,archiveSession:Ie,deleteSession:Me,sendMessage:ge,stopStreaming:ke,clearPendingMessage:Ae,loadMoreMessages:Re,hasMoreMessages:G,searchQuery:B,setSearchQuery:z,filteredSessions:ze,refreshSessions:oe,agentsMap:h}}const we="fusion:chat-active-room";function Nt(n){return[...n].sort((r,o)=>new Date(o.updatedAt).getTime()-new Date(r.updatedAt).getTime())}function Xe(n,r){const o=n.findIndex(c=>c.id===r.id);if(o===-1)return Nt([r,...n]);const d=[...n];return d[o]=r,Nt(d)}function Se(n){try{return JSON.parse(n.data)}catch{return null}}function ln(n,r){const[o,d]=s.useState([]),[c,S]=s.useState(!0),[R,A]=s.useState(null),[D,y]=s.useState(null),[Y,p]=s.useState([]),[K,C]=s.useState([]),[Q,b]=s.useState(!1),E=s.useRef(o),m=s.useRef(D),j=s.useRef(0),M=s.useRef(n);E.current=o,m.current=D,M.current!==n&&(M.current=n,j.current+=1);const T=s.useCallback(async(h,u=!0)=>{if(!h){p([]),C([]),b(!1);return}u&&C([]),b(!0);try{const[i,f]=await Promise.all([Ps(h.id,n),Ds(h.id,{limit:100},n)]);p(i.members),C(f.messages)}catch{p([]),C([])}finally{b(!1)}},[n]),I=s.useCallback(async()=>{S(!0);try{const h=await $s({},n),u=Nt(h.rooms);d(u),A(null);const i=Jt(we,n);if(i){const f=u.find(x=>x.id===i)??null;f?(y(f),T(f,!0)):$e(we,n)}}catch(h){const u=h instanceof Error?h.message:"Failed to load chat rooms";A(u),r?.(u,"error")}finally{S(!1)}},[r,T,n]),B=s.useCallback(h=>{if(!h){y(null),$e(we,n),T(null,!0);return}const u=E.current.find(i=>i.id===h)??null;y(u),u&&(Ct(we,u.id,n),T(u,!0))},[T,n]),z=s.useCallback(async h=>{const i=(await Ls({name:h.name,memberAgentIds:h.memberAgentIds},n)).room;return d(f=>Xe(f,i)),y(i),Ct(we,i.id,n),await T(i,!0),i},[T,n]),G=s.useCallback(async h=>{await Fs(h,n),d(u=>u.filter(i=>i.id!==h)),m.current?.id===h&&(y(null),p([]),C([]),$e(we,n))},[n]),v=s.useCallback(async(h,u)=>{const i=m.current?.id;if(!i)throw new Error("Select a room before sending a message");await Is(i,{content:h,...u?.attachments?{attachments:u.attachments}:{}},n)},[n]);return s.useEffect(()=>{I()},[I]),s.useEffect(()=>{const h=j.current,u=n?`/api/events?projectId=${encodeURIComponent(n)}`:"/api/events";return Yt(u,{onReconnect:()=>{I()},events:{"chat:room:created":i=>{if(j.current!==h)return;const f=Se(i);f&&d(x=>Xe(x,f))},"chat:room:updated":i=>{if(j.current!==h)return;const f=Se(i);f&&(d(x=>Xe(x,f)),m.current?.id===f.id&&y(f))},"chat:room:deleted":i=>{if(j.current!==h)return;const f=Se(i);f?.id&&(d(x=>x.filter(P=>P.id!==f.id)),m.current?.id===f.id&&(y(null),p([]),C([]),$e(we,n)))},"chat:room:member:added":i=>{if(j.current!==h)return;const f=Se(i);!f||m.current?.id!==f.roomId||p(x=>x.some(P=>P.agentId===f.agentId)?x:[...x,f])},"chat:room:member:removed":i=>{if(j.current!==h)return;const f=Se(i);!f||m.current?.id!==f.roomId||p(x=>x.filter(P=>P.agentId!==f.agentId))},"chat:room:message:added":i=>{if(j.current!==h)return;const f=Se(i);f&&(d(x=>{const P=x.find(ye=>ye.id===f.roomId);return P?Xe(x,{...P,updatedAt:f.createdAt}):x}),m.current?.id===f.roomId&&C(x=>x.some(P=>P.id===f.id)?x:[...x,f]))},"chat:room:message:updated":i=>{if(j.current!==h)return;const f=Se(i);!f||m.current?.id!==f.roomId||C(x=>x.map(P=>P.id===f.id?f:P))},"chat:room:message:deleted":i=>{if(j.current!==h)return;const f=Se(i);f?.id&&C(x=>x.filter(P=>P.id!==f.id))}}})},[n,I]),s.useEffect(()=>{D&&(o.some(h=>h.id===D.id)||(y(null),p([]),C([]),$e(we,n)))},[D,n,o]),{rooms:o,roomsLoading:c,roomsError:R,activeRoom:D,activeRoomMembers:Y,messages:K,messagesLoading:Q,selectRoom:B,createRoom:z,deleteRoom:G,sendRoomMessage:v,refreshRooms:I}}function dn(n,r=[]){const o=n.trim().replace(/^#/,"");if(!o)return{ok:!1,error:"Room name is required."};if(/[A-Z]/.test(o))return{ok:!1,error:"Use lowercase letters only."};const d=o.toLowerCase();return d.length>80?{ok:!1,error:"Room names can be at most 80 characters."}:/^[a-z0-9_-]+$/.test(d)?/^[-_]|[-_]$/.test(d)?{ok:!1,error:"Room names cannot start or end with a hyphen or underscore."}:r.some(c=>c.toLowerCase()===d)?{ok:!1,error:"A room with this name already exists."}:{ok:!0,name:d}:{ok:!1,error:"Use lowercase letters, numbers, hyphens, or underscores only."}}function un({isOpen:n,onClose:r,onCreate:o,projectId:d,existingRoomNames:c=[]}){const[S,R]=s.useState(""),[A,D]=s.useState([]),[y,Y]=s.useState(""),[p,K]=s.useState([]),[C,Q]=s.useState(!1),[b,E]=s.useState(null),[m,j]=s.useState(!1),M=s.useRef(null),T=s.useRef(null);s.useEffect(()=>{n&&(T.current=document.activeElement instanceof HTMLElement?document.activeElement:null,Q(!0),E(null),nt(void 0,d).then(u=>D(u)).catch(()=>{D([]),E("Failed to load agents.")}).finally(()=>Q(!1)))},[n,d]),s.useEffect(()=>{if(!n){R(""),Y(""),K([]),E(null),j(!1);return}const u=window.requestAnimationFrame(()=>M.current?.focus());return()=>window.cancelAnimationFrame(u)},[n]),s.useEffect(()=>{if(!n)return;const u=i=>{i.key==="Escape"&&r()};return document.addEventListener("keydown",u),()=>document.removeEventListener("keydown",u)},[n,r]),s.useEffect(()=>{n||T.current?.focus()},[n]);const I=s.useMemo(()=>dn(S,c),[S,c]),B=s.useMemo(()=>{const u=y.trim().toLowerCase();return u?A.filter(i=>i.name.toLowerCase().includes(u)):A},[A,y]),z=s.useMemo(()=>A.filter(u=>p.includes(u.id)),[A,p]),G=I.ok&&p.length>0&&!m&&!C;if(!n)return null;const v=u=>{m||K(i=>i.includes(u)?i.filter(f=>f!==u):[...i,u])},h=async()=>{if(!I.ok){E(I.error);return}if(p.length===0){E("Select at least one member.");return}E(null),j(!0);try{await o({name:I.name,displayName:`#${I.name}`,memberAgentIds:p}),r()}catch(u){E(u instanceof Error?u.message:"Failed to create room.")}finally{j(!1)}};return ys.createPortal(t.jsx("div",{className:"modal-overlay open",onClick:u=>u.target===u.currentTarget&&r(),children:t.jsxs("div",{className:"modal modal-lg create-room-modal",role:"dialog","aria-modal":"true","aria-label":"Create room",onClick:u=>u.stopPropagation(),children:[t.jsxs("div",{className:"modal-header",children:[t.jsx("h3",{children:"Create room"}),t.jsx("button",{type:"button",className:"modal-close","aria-label":"Close",onClick:r,children:"×"})]}),t.jsxs("div",{className:"form-group create-room-modal-name-group",children:[t.jsx("label",{htmlFor:"create-room-name",children:"Room name"}),t.jsxs("div",{className:"create-room-modal-name-field",children:[t.jsx("span",{"aria-hidden":"true",className:"create-room-modal-name-hash",children:"#"}),t.jsx("input",{ref:M,id:"create-room-name",className:"input",value:S,disabled:m,onChange:u=>{const i=u.target.value.replace(/^#/,"").replace(/\s+/g,"-").toLowerCase();R(i)}})]}),!I.ok&&t.jsx("div",{className:"form-error",children:I.error})]}),t.jsxs("div",{className:"form-group",children:[t.jsx("label",{htmlFor:"create-room-member-search",children:"Members"}),t.jsx("input",{id:"create-room-member-search",className:"input",placeholder:"Search agents",value:y,disabled:m,onChange:u=>Y(u.target.value)})]}),z.length>0&&t.jsx("div",{className:"create-room-modal-selected","data-testid":"create-room-selected-chips",children:z.map(u=>t.jsxs("button",{type:"button",className:"btn btn-sm create-room-modal-chip",onClick:()=>v(u.id),disabled:m,children:[u.name," ×"]},u.id))}),t.jsx("div",{className:"create-room-modal-member-list","data-testid":"create-room-member-list",children:C?t.jsx("div",{className:"create-room-modal-empty",children:"Loading agents..."}):B.length===0?t.jsx("div",{className:"create-room-modal-empty",children:A.length===0?"No agents in this project yet.":"No agents match your search."}):B.map(u=>{const i=p.includes(u.id);return t.jsxs("button",{type:"button",className:`create-room-modal-member-row${i?" create-room-modal-member-row--selected":""}`,onClick:()=>v(u.id),disabled:m,children:[t.jsx(Xt,{agent:u,size:20}),t.jsx("span",{children:u.name}),t.jsx("span",{className:"create-room-modal-member-role",children:u.role})]},u.id)})}),b&&t.jsx("div",{className:"form-group",children:t.jsx("div",{className:"form-error",children:b})}),t.jsxs("div",{className:"modal-actions",children:[t.jsx("button",{type:"button",className:"btn",onClick:r,disabled:m,children:"Cancel"}),t.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>void h(),disabled:!G,children:m?"Creating...":"Create room"})]})]})}),document.body)}function es(n){const r=new Date(n),d=new Date().getTime()-r.getTime(),c=Math.floor(d/1e3),S=Math.floor(c/60),R=Math.floor(S/60),A=Math.floor(R/24);return c<60?"just now":S<60?`${S}m ago`:R<24?`${R}h ago`:A<7?`${A}d ago`:r.toLocaleDateString()}function Gt(n,r){if(!n||!r)return null;const o=r.toLowerCase();if(o.includes("claude")){let c=r.replace(/^claude[- ]/i,"Claude ").replace(/sonnet[- ](\d+)[- ](\d+)/i,"Sonnet $1.$2").replace(/sonnet[- ](\d+)/i,"Sonnet $1").replace(/haiku[- ](\d+)/i,"Haiku $1").replace(/opus[- ](\d+)/i,"Opus $1").replace(/sonnet/i,"Sonnet").replace(/haiku/i,"Haiku").replace(/opus/i,"Opus").replace(/-/g," ").trim();return c=c.replace(/\s+/g," "),c.length>30?c.slice(0,30)+"…":c}if(o.includes("gpt")||o.includes("openai")){const c=r.replace(/^gpt-4-turbo$/i,"GPT-4 Turbo").replace(/^gpt-4o-mini$/i,"GPT-4o Mini").replace(/^gpt-4o$/i,"GPT-4o").replace(/^gpt-4$/i,"GPT-4").replace(/^gpt-o1-preview$/i,"GPT-o1 Preview").replace(/^gpt-o1-mini$/i,"GPT-o1 Mini").replace(/^gpt-o1$/i,"GPT-o1").replace(/^gpt/i,"GPT").trim();return c.length>30?c.slice(0,30)+"…":c}if(o.includes("gemini")){const c=r.replace(/^gemini[- ]/i,"Gemini ").replace(/pro[- ](\d+)[- ](\d+)/i,"Pro $1.$2").replace(/pro[- ](\d+)/i,"Pro $1").replace(/-/g," ").replace(/\s+/g," ").trim();return c.length>30?c.slice(0,30)+"…":c}const d=r.replace(/-/g," ").replace(/^\w/,c=>c.toUpperCase()).replace(/\s+/g," ").trim();return d.length>30?d.slice(0,30)+"…":d}function tt(n,r){return n.length<=r?n:`${n.slice(0,r)}…`}function mn(n){if(!n)return null;const r=Object.entries(n);return r.length===0?null:r.map(([o,d])=>{const c=typeof d=="string"?d:(()=>{try{return JSON.stringify(d)}catch{return String(d)}})();return`${o}=${tt(c,50)}`}).join(", ")}function hn(n){if(n===void 0)return null;if(typeof n=="string")return tt(n,200);try{return tt(JSON.stringify(n),200)}catch{return tt(String(n),200)}}function ts(n){if(!n||n.length===0)return null;const r=(p,K)=>{const C=p.status==="running",Q=p.status==="completed"&&p.isError,b=mn(p.args),E=hn(p.result),m=C?b:E?`result: ${E}`:b?`args: ${b}`:null,j=C?"running":Q?"error":"completed";return t.jsxs("details",{className:`chat-tool-call${C?" chat-tool-call--running":""}${Q?" chat-tool-call--error":""}`,open:C,children:[t.jsxs("summary",{children:[t.jsx("span",{className:"chat-tool-call-status-dot","aria-hidden":"true"}),t.jsx("span",{className:"chat-tool-call-name",title:p.toolName,children:p.toolName}),m&&t.jsx("span",{className:"chat-tool-call-preview",title:m,children:m}),t.jsx("span",{className:"chat-tool-call-status-text",children:j})]}),t.jsxs("div",{className:"chat-tool-call-content",children:[b&&t.jsxs("div",{className:"chat-tool-call-row",children:[t.jsx("span",{className:"chat-tool-call-label",children:"args"}),t.jsx("span",{className:"chat-tool-call-value",children:b})]}),E&&t.jsxs("div",{className:`chat-tool-call-row${Q?" chat-tool-call-row--error":""}`,children:[t.jsx("span",{className:"chat-tool-call-label",children:"result"}),t.jsx("span",{className:"chat-tool-call-value",children:E})]})]})]},`${p.toolName}-${K}`)},o="chat-tool-calls";if(n.length===1)return t.jsxs("div",{className:o,"data-testid":"chat-tool-calls",children:[t.jsxs("div",{className:"chat-tool-calls-header",children:[t.jsx(Ht,{size:12,"aria-hidden":"true"}),t.jsx("span",{children:"Tool calls"})]}),r(n[0],0)]});const d=n.filter(p=>p.status==="running").length,c=n.filter(p=>p.status==="completed"&&p.isError).length,S=d>0,R=Array.from(new Set(n.map(p=>p.toolName))),A=R.slice(0,5),D=Math.max(0,R.length-A.length),y=D>0?`${A.join(", ")}, +${D} more`:A.join(", "),Y=S?`(${d} running)`:c>0?`(${c} ${c===1?"error":"errors"})`:null;return t.jsx("div",{className:o,"data-testid":"chat-tool-calls",children:t.jsxs("details",{className:"chat-tool-calls-group","data-testid":"chat-tool-calls-group",open:S,children:[t.jsxs("summary",{className:"chat-tool-calls-group-summary",children:[t.jsx(Ht,{size:12,"aria-hidden":"true"}),t.jsxs("span",{className:"chat-tool-calls-count",children:[n.length," tool calls"]}),t.jsx("span",{className:"chat-tool-calls-names",title:y,children:y}),Y&&t.jsx("span",{className:"chat-tool-calls-group-status",children:Y})]}),n.map((p,K)=>r(p,K))]})})}const ss={pre:({children:n,...r})=>t.jsx("pre",{...r,className:"chat-markdown-pre",children:n}),table:({children:n,...r})=>t.jsx("table",{...r,className:"chat-markdown-table",children:n})},Le="__fn_agent__",fn=280,Qe=180,Ze=500,Vt="fusion:chat-sidebar-width",Kt="fusion:chat-scope",gn=["image/png","image/jpeg","image/gif","image/webp","text/plain","application/json","text/yaml","text/markdown","text/csv","application/xml","text/x-log"];function qt(n){const r=/(^|[\s])\/([^\s]*)$/.exec(n);if(!r)return null;const o=r[1]??"",d=r[2]??"",c=r.index+o.length;return{filter:d,start:c,end:n.length}}function pn(n,r){const o=n.slice(0,r),d=/(^|[\s\n])@([\w-]*)$/.exec(o);if(!d)return null;const c=d[2]??"",S=o.length-c.length-1;return{filter:c,start:S,end:r}}function bn({projectId:n,onClose:r,onCreate:o}){const[d,c]=s.useState("agent"),[S,R]=s.useState([]),[A,D]=s.useState(!0),[y,Y]=s.useState(""),[p,K]=s.useState([]),[C,Q]=s.useState(!0),[b,E]=s.useState(""),[m,j]=s.useState([]),[M,T]=s.useState([]);s.useEffect(()=>{let v=!1;return D(!0),nt(void 0,n).then(h=>{v||R(h)}).catch(()=>{v||R([])}).finally(()=>{v||D(!1)}),()=>{v=!0}},[n]),s.useEffect(()=>{Q(!0),nn().then(v=>{K(v.models),j(v.favoriteProviders),T(v.favoriteModels)}).catch(()=>{K([]),j([]),T([])}).finally(()=>{Q(!1)})},[]);const I=s.useCallback(async v=>{const h=m,i=h.includes(v)?h.filter(f=>f!==v):[v,...h];j(i);try{await Bt({favoriteProviders:i,favoriteModels:M})}catch{j(h)}},[m,M]),B=s.useCallback(async v=>{const h=M,i=h.includes(v)?h.filter(f=>f!==v):[v,...h];T(i);try{await Bt({favoriteProviders:m,favoriteModels:i})}catch{T(h)}},[M,m]),z=v=>{if(v.preventDefault(),d==="agent"){if(!y)return;o({agentId:y});return}if(!b)return;const h=b.indexOf("/");if(h<=0)return;const u=b.slice(0,h),i=b.slice(h+1);o({agentId:Le,modelProvider:u,modelId:i})},G=d==="agent"?!y:!b;return t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:r,role:"dialog","aria-modal":"true",children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:v=>v.stopPropagation(),children:[t.jsx("h3",{children:"New Chat"}),t.jsxs("div",{className:"chat-new-dialog-mode-toggle","data-testid":"chat-new-dialog-mode-toggle",children:[t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${d==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{c("agent"),E("")},children:"Agent"}),t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${d==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{c("model"),Y("")},children:"Model"})]}),t.jsxs("form",{onSubmit:z,children:[d==="agent"&&t.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",A?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):S.length===0?t.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):t.jsx("div",{className:"chat-new-dialog-agent-list",children:S.map(v=>t.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${y===v.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>Y(v.id),"data-testid":`agent-option-${v.id}`,children:[t.jsx(st,{size:16}),t.jsx("span",{className:"chat-new-dialog-agent-name",children:v.name}),t.jsx("span",{className:"chat-new-dialog-agent-role",children:v.role})]},v.id))})]}),d==="model"&&t.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:C?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading models..."}):t.jsx(an,{models:p,value:b,onChange:E,label:"Model",placeholder:"Select a model",favoriteProviders:m,onToggleFavorite:I,favoriteModels:M,onToggleModelFavorite:B})}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{type:"button",className:"btn btn-sm",onClick:r,children:"Cancel"}),t.jsx("button",{type:"submit",className:"btn btn-sm btn-primary",disabled:G,children:"Create"})]})]})]})})}const kt=s.memo(function({message:r,forcePlain:o,agentName:d,hideAssistantIdentity:c,showAssistantModelTag:S,activeModelTag:R,activeModelProvider:A,activeSessionId:D,mentionAgentsByName:y,copyAction:Y}){const p=r.role==="assistant",K=s.useMemo(()=>{if(p)return null;const b=r.content,E=/@([\w-]+)/g,m=[];let j=0,M=E.exec(b);for(;M;){const[T,I=""]=M,B=M.index;B>j&&m.push(b.slice(j,B));const z=I.replace(/_/g," ").toLowerCase(),G=y.get(z);G?m.push(t.jsxs("span",{className:"chat-mention-chip",children:["@",G.name.replace(/\s+/g,"_")]},`${G.id}-${B}`)):m.push(T),j=B+T.length,M=E.exec(b)}return j<b.length&&m.push(b.slice(j)),m.length===0?b:m},[p,r.content,y]),C=s.useMemo(()=>{const b=r.attachments;if(!b||b.length===0||!D)return null;const E=`/api/chat/sessions/${encodeURIComponent(D)}/attachments/`;return t.jsx("div",{className:"chat-message-attachments",children:b.map(m=>{const j=m.mimeType.startsWith("image/"),M=m.id||m.filename,T=`${E}${encodeURIComponent(m.filename)}`;return j?t.jsx("a",{className:"chat-message-attachment-link","data-testid":"chat-message-attachment",href:T,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{className:"chat-message-attachment",src:T,alt:m.originalName})},M):t.jsxs("a",{className:"chat-message-attachment-file","data-testid":"chat-message-attachment",href:T,target:"_blank",rel:"noopener noreferrer",children:[t.jsx(tn,{size:14}),t.jsx("span",{children:m.originalName})]},M)})})},[r.attachments,D]),Q=s.useMemo(()=>p?o?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:r.content}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(Qt,{remarkPlugins:[Zt],components:ss,children:r.content})}):null,[p,o,r.content]);return t.jsxs("div",{className:`chat-message chat-message--${r.role}`,"data-testid":`chat-message-${r.id}`,children:[p&&!c&&t.jsxs("div",{className:"chat-message-avatar",children:[A?t.jsx(et,{provider:A,size:"sm"}):t.jsx(st,{size:14}),t.jsx("span",{children:d}),S&&R&&t.jsx("span",{className:"chat-model-tag",children:R})]}),p?Q:t.jsx("div",{className:"chat-message-content",children:K}),Y,ts(r.toolCalls),r.thinkingOutput&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:r.thinkingOutput})]}),C,t.jsx("div",{className:"chat-message-time",children:es(r.createdAt)})]})});function yn({projectId:n,addToast:r}){const{activeSession:o,sessionsLoading:d,messages:c,messagesLoading:S,isStreaming:R,streamingText:A,streamingThinking:D,streamingToolCalls:y,selectSession:Y,createSession:p,archiveSession:K,deleteSession:C,sendMessage:Q,stopStreaming:b,pendingMessage:E,clearPendingMessage:m,searchQuery:j,setSearchQuery:M,filteredSessions:T}=cn(n,r),[I,B]=s.useState(!1),[z,G]=s.useState(""),[v,h]=s.useState(null),[u,i]=s.useState(null),[f,x]=s.useState(!0),[P,ye]=s.useState(fn),[W,ae]=s.useState("direct"),[Fe,me]=s.useState(!1),q=ln(n,r),[oe,Ge]=s.useState(new Map),[he,re]=s.useState([]),[je,fe]=s.useState(!0),[ce,ve]=s.useState(!1),[Ie,Me]=s.useState(""),[Re,ke]=s.useState(0),[Ae,ue]=s.useState(""),[ie,ge]=s.useState(!1),[ze,g]=s.useState(0),[k,w]=s.useState(-1),[N,ee]=s.useState(!1),[F,J]=s.useState([]),[Z,te]=s.useState(!1),[U,O]=s.useState(!1),[$,X]=s.useState({}),[,ne]=s.useState(!1),[xe,ns]=s.useState({top:0,left:0}),_=zs({projectId:n}),at=s.useCallback(e=>{if(!e||!_.mentionActive)return;const a=e.getBoundingClientRect();ns({top:a.top-260,left:a.left+8})},[_.mentionActive]),jt=s.useRef(null),rt=s.useRef(!1),ot=s.useRef(null),pe=s.useRef(null),Ee=s.useRef(null),se=s.useRef(null),Mt=s.useRef(null),Rt=s.useRef([]),_e=s.useRef(0),Ue=s.useRef(new Map),V=_s()==="mobile";s.useEffect(()=>{try{const e=localStorage.getItem(Vt);if(!e)return;const a=Number.parseInt(e,10);if(Number.isNaN(a))return;const l=Math.max(Qe,Math.min(Ze,a));ye(l)}catch{}},[]),s.useEffect(()=>{try{const e=localStorage.getItem(Kt);(e==="direct"||e==="rooms")&&ae(e)}catch{}},[]),s.useEffect(()=>{try{localStorage.setItem(Kt,W)}catch{}},[W]);const{keyboardOverlap:Ve,viewportHeight:At,viewportOffsetTop:Et,keyboardOpen:Oe}=Us({enabled:V&&!!o}),Tt=Ve>0||Et>0,as=Oe&&Tt?{"--keyboard-overlap":`${Ve}px`,"--vv-offset-top":`${Et}px`,...At!==null?{"--vv-height":`${At}px`}:{}}:{},le=s.useMemo(()=>{const e=Ie.trim().toLowerCase();return(e?he.filter(l=>l.name.toLowerCase().includes(e)):he).slice(0,10)},[he,Ie]),He=s.useMemo(()=>Array.from(oe.values()),[oe]),Ce=s.useMemo(()=>He.filter(e=>Os(e.name,Ae)),[He,Ae]),it=s.useMemo(()=>{const e=new Map;for(const a of He)e.set(a.name.toLowerCase(),a);return e},[He]);s.useEffect(()=>{ke(0)},[le]),s.useEffect(()=>{g(0)},[Ae,ie]),s.useEffect(()=>()=>{pe.current!==null&&window.clearTimeout(pe.current)},[]);const Pt=s.useCallback(()=>{const e=Ee.current;if(!e)return;const l=e.scrollTop+e.clientHeight>=e.scrollHeight-50;O(!l),rt.current=!l},[]),Ke=s.useCallback(e=>{if(!e.isConnected)return;let a=0,l=0,L=-1;const H=6,de=()=>{if(e.isConnected){if(e.scrollTop=e.scrollHeight,e.scrollHeight===L?l+=1:(l=0,L=e.scrollHeight),a+=1,a>=H||l>=2){O(!1),rt.current=!1;return}window.requestAnimationFrame(de)}};de()},[]),Be=s.useCallback(()=>{const e=Ee.current;e&&Ke(e)},[Ke]);s.useLayoutEffect(()=>{const e=o?.id??null;if(!e){ot.current=null;return}const a={sessionId:e,loaded:!S,hasMessages:c.length>0},l=ot.current,L=l?.sessionId!==e,H=l?.sessionId===e&&!l.loaded&&a.loaded,de=l?.sessionId===e&&!l.hasMessages&&a.hasMessages;if(!(l===null||L||H||de))return;const be=Ee.current;be&&(Ke(be),ot.current=a)},[o?.id,c.length,S,Ke]),s.useEffect(()=>{rt.current||Be()},[c,A,D,R,Be]),s.useEffect(()=>{Ve<=0||!Ee.current||Be()},[Ve,Be]),Hs(V&&Oe),s.useEffect(()=>{const e=()=>h(null);if(v)return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[v]),s.useEffect(()=>{if(!V||!Oe)return;const e=a=>{a.target?.closest(".chat-messages")||a.preventDefault()};return document.addEventListener("touchmove",e,{passive:!1}),()=>{document.removeEventListener("touchmove",e)}},[V,Oe]),s.useEffect(()=>{if(!V||!o)return;const e=()=>{const a=se.current;a&&document.activeElement===a&&(a.blur(),window.setTimeout(()=>{a.focus({preventScroll:!0})},0))};return document.addEventListener("visibilitychange",e),window.addEventListener("pageshow",e),()=>{document.removeEventListener("visibilitychange",e),window.removeEventListener("pageshow",e)}},[V,o]),s.useEffect(()=>{let e=!1;const a=n;return nt(void 0,n).then(l=>{if(e||a!==n)return;const L=new Map;for(const H of l)L.set(H.id,H);Ge(L)}).catch(()=>{}),()=>{e=!0}},[n]),s.useEffect(()=>{let e=!1;return fe(!0),Bs(n).then(a=>{e||re(a)}).catch(()=>{e||re([])}).finally(()=>{e||fe(!1)}),()=>{e=!0}},[n]),s.useEffect(()=>{Rt.current=F},[F]),s.useEffect(()=>()=>{for(const e of Rt.current)e.previewUrl&&URL.revokeObjectURL(e.previewUrl);for(const e of Ue.current.values())window.clearTimeout(e);Ue.current.clear()},[]);const qe=s.useCallback(e=>{if(!e||e.length===0)return;const a=[];for(const l of Array.from(e)){if(!gn.includes(l.type))continue;const L=l.type.startsWith("image/");a.push({file:l,previewUrl:L?URL.createObjectURL(l):""})}a.length>0&&J(l=>[...l,...a])},[]),rs=s.useCallback(e=>{J(a=>{const l=a[e];return l?.previewUrl&&URL.revokeObjectURL(l.previewUrl),a.filter((L,H)=>H!==e)})},[]),os=s.useCallback(e=>{const a=e.clipboardData?.files;if(!a||a.length===0)return;const l=Array.from(a).filter(L=>L.type.startsWith("image/"));l.length!==0&&qe(l)},[qe]),is=s.useCallback(async e=>{try{await p(e),B(!1),V&&x(!1)}catch{r("Failed to create chat session","error")}},[p,r,V]),ct=s.useCallback(()=>{G(""),ve(!1),Me(""),ge(!1),ue(""),w(-1),J(e=>{for(const a of e)a.previewUrl&&URL.revokeObjectURL(a.previewUrl);return[]})},[]),lt=s.useCallback(()=>{const e=z.trim(),a=F.map(l=>l.file);if(!(!e&&a.length===0||!o)){if(e==="/clear"){ct(),b(),m(),p({agentId:o.agentId,modelProvider:o.modelProvider??void 0,modelId:o.modelId??void 0}).catch(()=>{r("Failed to clear conversation","error")});return}ct(),Q(e,a)}},[z,F,o,ct,b,m,p,r,Q]),dt=s.useCallback(e=>{G(a=>{const l=qt(a);if(!l)return a;const L=`/skill:${e.name} `,H=a.slice(0,l.start)+L+a.slice(l.end);return window.requestAnimationFrame(()=>{se.current&&(se.current.style.height="auto",se.current.style.height=`${Math.min(se.current.scrollHeight,120)}px`,se.current.focus())}),H}),ve(!1),Me(""),ke(0)},[]),ut=s.useCallback(e=>{const a=se.current;if(!a||k<0)return;const l=a.selectionStart??_e.current,L=a.selectionEnd??l,H=Math.max(l,L),de=Math.min(k,H),be=`${`@${e.name.replace(/\s+/g,"_")}`} `,wt=z.slice(0,de)+be+z.slice(H),De=de+be.length;G(wt),ge(!1),ue(""),g(0),w(-1),window.requestAnimationFrame(()=>{se.current&&(se.current.style.height="auto",se.current.style.height=`${Math.min(se.current.scrollHeight,120)}px`,se.current.focus(),se.current.setSelectionRange(De,De))})},[k,z]),Dt=s.useCallback(e=>{if(_e.current=e.currentTarget.selectionStart??_e.current,_.mentionActive&&_.files.length>0){if(_.handleKeyDown(e,z),e.key==="Enter"||e.key==="Tab"){const a=_.files[_.selectedIndex];if(a){const l=_.selectFile(a,z);G(l),_.dismissMention(),ne(!1)}}return}if(ie&&e.key==="ArrowDown"){e.preventDefault(),Ce.length>0&&g(a=>(a+1)%Ce.length);return}if(ie&&e.key==="ArrowUp"){e.preventDefault(),Ce.length>0&&g(a=>a===0?Ce.length-1:a-1);return}if(ie&&e.key==="Enter"){e.preventDefault();const a=Ce[ze]??Ce[0];a&&ut(a);return}if(ie&&e.key==="Escape"){e.preventDefault(),ge(!1),ue(""),w(-1);return}if(ce&&e.key==="ArrowDown"){e.preventDefault(),le.length>0&&ke(a=>(a+1)%le.length);return}if(ce&&e.key==="ArrowUp"){e.preventDefault(),le.length>0&&ke(a=>a===0?le.length-1:a-1);return}if(ce&&(e.key==="Enter"||e.key==="Tab")&&le.length>0){e.preventDefault();const a=le[Re]??le[0];a&&dt(a);return}if(ce&&e.key==="Escape"){e.preventDefault(),ve(!1);return}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),lt())},[ie,Ce,ze,ut,ce,le,Re,dt,lt,_,z]),Je=s.useCallback((e,a)=>{const l=pn(e,a);if(l){ge(!0),ue(l.filter),w(l.start);return}ge(!1),ue(""),w(-1)},[]),$t=s.useCallback(e=>{const a=e.target,l=a.value,L=a.selectionStart??l.length;_e.current=L,G(l);const H=qt(l);H?(ve(!0),Me(H.filter)):(ve(!1),Me("")),Je(l,L),_.detectMention(l,L),ne(_.mentionActive),_.mentionActive&&at(a),a.style.height="auto",a.style.height=`${Math.min(a.scrollHeight,120)}px`},[Je]),mt=s.useCallback(e=>{const a=e.currentTarget,l=a.selectionStart??a.value.length;_e.current=l,Je(a.value,l),_.detectMention(a.value,l),ne(_.mentionActive),_.mentionActive&&at(a)},[Je,_,at]),cs=s.useCallback(e=>{e.key!=="Escape"&&mt(e)},[mt]),ls=s.useCallback(()=>{pe.current!==null&&window.clearTimeout(pe.current),pe.current=window.setTimeout(()=>{ve(!1),ge(!1),ue(""),w(-1),ne(!1),_.dismissMention(),pe.current=null},120)},[_]),ds=s.useCallback(()=>{pe.current!==null&&(window.clearTimeout(pe.current),pe.current=null),typeof window<"u"&&window.innerWidth<=768&&window.setTimeout(()=>{(window.scrollY!==0||window.scrollX!==0)&&window.scrollTo(0,0)},0)},[]),us=s.useCallback(async e=>{h(null);try{await K(e),r("Conversation archived","success")}catch{r("Failed to archive conversation","error")}},[K,r]),ms=s.useCallback(async e=>{i(null),h(null);try{await C(e),r("Conversation deleted","success")}catch{r("Failed to delete conversation","error")}},[C,r]),We=s.useCallback(e=>{try{localStorage.setItem(Vt,String(e))}catch{}},[]),hs=s.useCallback(e=>{if(V)return;e.preventDefault(),e.stopPropagation();const a=e.currentTarget;typeof a.setPointerCapture=="function"&&a.setPointerCapture(e.pointerId);const l=e.clientX,L=P;let H=L;document.body.style.userSelect="none";const de=be=>{const wt=be.clientX-l,De=Math.max(Qe,Math.min(Ze,L+wt));H=De,ye(De),We(De)},Pe=be=>{typeof a.releasePointerCapture=="function"&&a.releasePointerCapture(be.pointerId),document.body.style.userSelect="",document.removeEventListener("pointermove",de),document.removeEventListener("pointerup",Pe),We(H)};document.addEventListener("pointermove",de),document.addEventListener("pointerup",Pe)},[V,We,P]),fs=s.useCallback(e=>{if(V||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;e.preventDefault();const a=e.shiftKey?50:10,l=e.key==="ArrowLeft"?-a:a,L=Math.max(Qe,Math.min(Ze,P+l));ye(L),We(L)},[V,We,P]),gs=s.useCallback(e=>{Y(e),V&&x(!1)},[Y,V]),ps=s.useCallback(()=>{Y(""),x(!0)},[Y]),bs=()=>t.jsxs("div",{className:"chat-empty-state",children:[t.jsx(sn,{size:48,strokeWidth:1.5}),t.jsx("h2",{children:"Start a new conversation"}),t.jsxs("button",{className:"btn btn-primary",onClick:()=>B(!0),children:[t.jsx(Ye,{size:16}),"New Chat"]})]}),Ne=Gt(o?.modelProvider,o?.modelId),Te=o?.modelProvider??null,ht=!!(o||R||c.length>0),Lt=o?.agentId===Le?Ne??"Fusion":o?.title||oe.get(o?.agentId??"")?.name||o?.agentId||"Chat",vs=!!(Ne&&Ne!==Lt),ft=oe.get(o?.agentId??"")?.name||(o?.agentId===Le?Ne??"Fusion":o?.agentId?.slice(0,30)??"Fusion"),gt=!1,pt=o?.agentId===Le,xs=E.length>50?`${E.slice(0,50)}…`:E,ws=s.useCallback(()=>{ee(e=>!e)},[]),bt=s.useCallback((e,a)=>{const l=Ue.current.get(e);l&&window.clearTimeout(l),X(H=>({...H,[e]:a}));const L=window.setTimeout(()=>{X(H=>{const{[e]:de,...Pe}=H;return Pe}),Ue.current.delete(e)},2e3);Ue.current.set(e,L)},[]),Ft=s.useCallback(async(e,a)=>{try{if(!navigator.clipboard?.writeText)throw new Error("Clipboard API unavailable");await navigator.clipboard.writeText(a),bt(e,"success")}catch{bt(e,"error")}},[bt]),Ss=s.useCallback((e,a=!1)=>a?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:e}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(Qt,{remarkPlugins:[Zt],components:ss,children:e})}),[]),vt=o?.agentId===Le,xt=s.useCallback((e,a,l)=>t.jsx("button",{type:"button",className:`btn-icon chat-message-copy-action${$[e]==="success"?" chat-message-copy-action--success":""}${$[e]==="error"?" chat-message-copy-action--error":""}`,"data-testid":l??`chat-copy-response-${e}`,"aria-label":$[e]==="success"?"Response copied":$[e]==="error"?"Copy failed":"Copy response",onClick:()=>{Ft(e,a)},children:$[e]==="success"?t.jsx(Ws,{size:14}):t.jsx(Gs,{size:14})}),[$,Ft]);return t.jsxs("div",{className:"chat-view",children:[t.jsxs("div",{className:`chat-sidebar${f?"":" chat-sidebar--hidden"}`,style:V?void 0:{width:`${P}px`},children:[t.jsxs("div",{className:"chat-sidebar-scope-toggle",role:"tablist","data-testid":"chat-sidebar-scope-toggle",children:[t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${W==="direct"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":W==="direct","data-testid":"chat-sidebar-scope-direct",onClick:()=>ae("direct"),children:"Direct"}),t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${W==="rooms"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":W==="rooms","data-testid":"chat-sidebar-scope-rooms",onClick:()=>ae("rooms"),children:"Rooms"})]}),W==="direct"?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"chat-sidebar-search-container",children:t.jsxs("div",{className:"chat-sidebar-search-wrapper",children:[t.jsx(Vs,{size:14,className:"chat-sidebar-search-icon"}),t.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:j,onChange:e=>M(e.target.value),"data-testid":"chat-search-input"})]})}),t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:d?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"Loading..."}):T.length===0?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"No conversations yet"}):T.map(e=>t.jsxs("div",{className:`chat-session-item${o?.id===e.id?" chat-session-item--active":""}`,onClick:()=>gs(e.id),onContextMenu:a=>{a.preventDefault(),h({sessionId:e.id,x:a.clientX,y:a.clientY})},"data-testid":`chat-session-${e.id}`,children:[t.jsx("button",{className:"chat-session-delete-btn",onClick:a=>{a.stopPropagation(),i(e.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:t.jsx(_t,{size:14})}),t.jsx("div",{className:"chat-session-title",children:e.title||"Untitled"}),t.jsx("div",{className:"chat-session-preview",children:e.lastMessagePreview||"No messages"}),t.jsxs("div",{className:"chat-session-meta",children:[t.jsxs("span",{className:"chat-session-meta-model",children:[e.modelProvider&&t.jsx(et,{provider:e.modelProvider,size:"sm"}),t.jsx("span",{children:oe.get(e.agentId)?.name||(e.agentId===Le?Gt(e.modelProvider,e.modelId)??"Fusion":e.agentId.slice(0,30))})]}),t.jsx("span",{children:e.updatedAt?es(e.updatedAt):""})]})]},e.id))})]}):t.jsxs("div",{className:"chat-sidebar-rooms","data-testid":"chat-sidebar-rooms",children:[t.jsx("div",{className:"chat-sidebar-rooms-header",children:t.jsxs("button",{type:"button",className:"btn btn-sm btn-primary","data-testid":"chat-create-room-btn",onClick:()=>me(!0),children:[t.jsx(Ye,{size:14}),"Create room"]})}),q.rooms.length===0?t.jsx("div",{className:"chat-sidebar-rooms-empty","data-testid":"chat-sidebar-rooms-empty",children:"No rooms yet."}):t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:q.rooms.map(e=>{const a=q.activeRoom?.id===e.id,l=a?q.activeRoomMembers.length:"—";return t.jsxs("button",{type:"button",className:`chat-room-item${a?" chat-room-item--active":""}`,"data-testid":`chat-room-item-${e.slug}`,onClick:()=>{q.selectRoom(e.id),V&&x(!1)},children:[t.jsxs("span",{className:"chat-room-item-name",children:["#",e.name]}),t.jsxs("span",{className:"chat-room-item-meta",children:[l," ",l===1?"member":"members"]})]},e.id)})})]}),t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>B(!0),"data-testid":"chat-new-btn",children:[t.jsx(Ye,{size:14}),"New Chat"]})})]}),!V&&f&&t.jsx("div",{className:"chat-sidebar-resize-handle",role:"separator","aria-orientation":"vertical","aria-valuemin":Qe,"aria-valuemax":Ze,"aria-valuenow":P,"aria-label":"Resize chat sidebar",tabIndex:0,onPointerDown:hs,onKeyDown:fs}),v&&t.jsxs("div",{className:"chat-session-context-menu",style:{top:v.y,left:v.x},onClick:e=>e.stopPropagation(),children:[t.jsxs("button",{onClick:()=>us(v.sessionId),"data-testid":"chat-context-archive",children:[t.jsx(Ks,{size:14}),"Archive"]}),t.jsxs("button",{onClick:()=>{h(null),i(v.sessionId)},"data-testid":"chat-context-delete",children:[t.jsx(_t,{size:14}),"Delete"]})]}),u&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>i(null),children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:e=>e.stopPropagation(),children:[t.jsx("h3",{children:"Delete Conversation?"}),t.jsx("p",{className:"chat-view-delete-dialog-copy",children:"This action cannot be undone. All messages in this conversation will be permanently deleted."}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{className:"btn btn-sm",onClick:()=>i(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void ms(u),children:"Delete"})]})]})}),W==="rooms"?t.jsxs("div",{className:"chat-thread",children:[q.activeRoom?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"chat-room-thread-header",children:[V&&t.jsx("button",{className:"btn-icon",onClick:()=>{q.selectRoom(null),x(!0)},"data-testid":"chat-back-btn",children:t.jsx(Ut,{size:16})}),t.jsxs("div",{className:"chat-thread-header-title",children:["#",q.activeRoom.name]}),t.jsx("div",{className:"chat-room-thread-members",children:q.activeRoomMembers.map(e=>t.jsx(Xt,{agent:oe.get(e.agentId)??null},e.agentId))})]}),t.jsxs("div",{className:"chat-messages",ref:Ee,onScroll:Pt,children:[q.messagesLoading?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):q.messages.length===0?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):q.messages.map(e=>{const a=e.senderAgentId?oe.get(e.senderAgentId)?.name??e.senderAgentId.slice(0,30):"You",l={id:e.id,sessionId:e.roomId,role:e.role,content:e.content,thinkingOutput:e.thinkingOutput??void 0,toolCalls:void 0,fallbackInfo:void 0,attachments:e.attachments,createdAt:e.createdAt};return t.jsx(kt,{message:l,forcePlain:N,agentName:a,hideAssistantIdentity:!1,showAssistantModelTag:!1,activeModelTag:null,activeModelProvider:null,activeSessionId:q.activeRoom?.id??null,mentionAgentsByName:it},e.id)}),t.jsx("div",{ref:jt})]})]}):t.jsx("div",{className:"chat-room-empty-pane","data-testid":"chat-rooms-empty-pane",children:"Select a room or create one"}),q.activeRoom&&t.jsx("div",{className:"chat-input-area",children:t.jsxs("div",{className:"chat-input-row",children:[t.jsx("div",{className:"chat-input-wrapper",children:t.jsx("textarea",{ref:se,className:"chat-input-textarea",placeholder:"Type a message...",value:z,onChange:$t,onKeyDown:Dt,rows:1,"data-testid":"chat-input"})}),t.jsx("button",{type:"button",className:"chat-input-send",onClick:()=>{const e=z.trim();e&&q.sendRoomMessage(e).then(()=>{G("")})},disabled:!z.trim(),"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(Ot,{size:16})})]})})]}):t.jsxs("div",{className:`chat-thread${Oe&&Tt?" chat-thread--keyboard-active":""}`,style:as,children:[(ht||!V)&&t.jsxs("div",{className:"chat-thread-header",children:[V&&ht&&t.jsx("button",{className:"btn-icon",onClick:ps,"data-testid":"chat-back-btn",children:t.jsx(Ut,{size:16})}),t.jsxs("div",{className:"chat-thread-header-identity","data-testid":"chat-thread-header-identity",children:[Te?t.jsx(et,{provider:Te,size:"md"}):t.jsx(st,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:Lt}),vs&&t.jsx("span",{className:"chat-model-tag",children:Ne})]}),ht&&t.jsx("button",{type:"button",className:`chat-thread-header-render-toggle${N?" chat-thread-header-render-toggle--plain":""}`,"data-testid":"chat-thread-render-toggle","aria-label":N?"Show all messages as rendered Markdown":"Show all messages as plain text",onClick:ws,children:N?t.jsx(qs,{size:14}):t.jsx(Js,{size:14})}),!V&&t.jsxs("button",{className:"btn btn-sm btn-primary chat-thread-header-new-chat",onClick:()=>B(!0),"data-testid":"chat-thread-new-chat-btn",children:[t.jsx(Ye,{size:14}),"New Chat"]})]}),t.jsxs("div",{className:"chat-messages",ref:Ee,onScroll:Pt,children:[R?t.jsxs(t.Fragment,{children:[c.map(e=>t.jsx(kt,{message:e,forcePlain:N,agentName:ft,hideAssistantIdentity:pt,showAssistantModelTag:gt,activeModelTag:Ne,activeModelProvider:Te,activeSessionId:o?.id??null,mentionAgentsByName:it,copyAction:vt&&e.role==="assistant"?xt(e.id,e.content):void 0},e.id)),t.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[!pt&&t.jsxs("div",{className:"chat-message-avatar",children:[Te?t.jsx(et,{provider:Te,size:"sm"}):t.jsx(st,{size:14}),t.jsx("span",{children:ft}),gt]}),A?Ss(A,N):t.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:D?"Thinking…":"Connecting…"}),vt&&A&&xt("__streaming__",A,"chat-copy-response-streaming"),ts(y),D&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:D})]}),t.jsxs("div",{className:"chat-typing-indicator",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]})]})]}):S?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):c.length===0&&!o?bs():c.length===0&&o?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):t.jsx(t.Fragment,{children:c.map(e=>t.jsx(kt,{message:e,forcePlain:N,agentName:ft,hideAssistantIdentity:pt,showAssistantModelTag:gt,activeModelTag:Ne,activeModelProvider:Te,activeSessionId:o?.id??null,mentionAgentsByName:it,copyAction:vt&&e.role==="assistant"?xt(e.id,e.content):void 0},e.id))}),t.jsx("div",{ref:jt})]}),U&&t.jsxs("button",{type:"button",className:"btn btn-sm chat-jump-to-latest","data-testid":"chat-jump-to-latest",onClick:Be,children:[t.jsx(Ys,{size:14}),"Latest"]}),o&&t.jsxs("div",{className:"chat-input-area",children:[t.jsx("input",{ref:Mt,type:"file",accept:"image/*,.txt,.json,.yaml,.yml,.log,.csv,.xml,.md",multiple:!0,style:{display:"none"},onChange:e=>{qe(e.target.files),e.target.value=""}}),ce&&t.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:je?t.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):le.length===0?t.jsx("div",{className:"chat-skill-menu-empty",children:Ie?"No skills found":"No skills available"}):le.map((e,a)=>t.jsxs("button",{type:"button",role:"option","aria-selected":a===Re,className:`chat-skill-menu-item${a===Re?" chat-skill-menu-item--highlighted":""}`,onMouseDown:l=>l.preventDefault(),onMouseEnter:()=>ke(a),onClick:()=>dt(e),children:[t.jsx("span",{className:"chat-skill-menu-item-name",children:e.name}),t.jsx("span",{className:"chat-skill-menu-item-description",title:e.relativePath,children:e.relativePath})]},e.id))}),F.length>0&&t.jsx("div",{className:"chat-attachment-previews","data-testid":"chat-attachment-previews",children:F.map((e,a)=>t.jsxs("div",{className:"chat-attachment-preview","data-testid":`chat-attachment-preview-${a}`,children:[e.previewUrl?t.jsx("img",{src:e.previewUrl,alt:e.file.name}):t.jsx("span",{className:"chat-attachment-preview-name",children:e.file.name}),t.jsx("button",{type:"button",className:"chat-attachment-remove",onClick:()=>rs(a),"data-testid":`chat-attachment-remove-${a}`,"aria-label":`Remove ${e.file.name}`,children:"×"})]},e.previewUrl||`${e.file.name}-${a}`))}),t.jsxs("div",{className:"chat-input-row",children:[t.jsx("button",{type:"button",className:"btn-icon chat-attach-btn","data-testid":"chat-attach-btn","aria-label":"Attach files",onClick:()=>Mt.current?.click(),children:t.jsx(Xs,{size:16})}),t.jsxs("div",{className:`chat-input-wrapper${Z?" chat-input-wrapper--dragover":""}`,onDragOver:e=>{e.preventDefault(),te(!0)},onDragLeave:()=>te(!1),onDrop:e=>{e.preventDefault(),te(!1),qe(e.dataTransfer.files)},children:[t.jsx("textarea",{ref:se,className:"chat-input-textarea",placeholder:"Type a message...",value:z,onChange:$t,onKeyDown:Dt,onKeyUp:cs,onClick:mt,onBlur:ls,onFocus:ds,onPaste:os,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(Qs,{agents:He,filter:Ae,highlightedIndex:ze,visible:ie,onSelect:ut,position:"below"}),t.jsx(Zs,{visible:_.mentionActive&&!ie,position:xe,files:_.files,selectedIndex:_.selectedIndex,onSelect:e=>{const a=_.selectFile(e,z);G(a),_.dismissMention(),ne(!1),se.current?.focus()},loading:_.loading}),E&&t.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[t.jsx("span",{children:`Queued: ${xs}`}),t.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:m,children:"×"})]})]}),R?t.jsx("button",{className:"chat-input-stop",onClick:b,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:t.jsx(en,{size:14})}):t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{e.pointerType&&e.pointerType!=="mouse"&&e.preventDefault()},onMouseDown:e=>{e.preventDefault()},onClick:()=>{lt()},disabled:!z.trim()&&F.length===0,"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(Ot,{size:16})})]})]})]}),t.jsx(un,{isOpen:Fe,onClose:()=>me(!1),projectId:n,existingRoomNames:q.rooms.map(e=>e.name),onCreate:async e=>{await q.createRoom({name:e.name,memberAgentIds:e.memberAgentIds}),me(!1)}}),I&&t.jsx(bn,{projectId:n,onClose:()=>B(!1),onCreate:is})]})}export{yn as ChatView};
@@ -1,2 +0,0 @@
1
- import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{u as Le}from"./SettingsModal-yRqM4DV8.js";import{bA as Ee,bB as Me,bC as Ie,y as Re,bD as qe,bE as _e,bF as Pe,bG as ke,bH as we,bI as We,bJ as Oe,bK as Te,bL as Ae,bM as $e,x as Ue,bN as He,L as w,bO as Fe}from"./index-CQyVRLOb.js";import"./vendor-xterm-DzcZoU0P.js";const O=".fusion/memory/MEMORY.md",Qe=5e4,Ye="0 3 * * *",Be="0 4 * * *";function he(i){return{memoryEnabled:i.memoryEnabled!==!1,memoryAutoSummarizeEnabled:i.memoryAutoSummarizeEnabled??!1,memoryAutoSummarizeThresholdChars:i.memoryAutoSummarizeThresholdChars??Qe,memoryAutoSummarizeSchedule:i.memoryAutoSummarizeSchedule??Ye,memoryDreamsEnabled:i.memoryDreamsEnabled??!1,memoryDreamsSchedule:i.memoryDreamsSchedule??Be}}function De(i,t){return i.some(m=>m.path===t)?t:i.find(m=>m.path===O)?.path??i[0]?.path??O}function Ge(i={}){const{projectId:t}=i,[m,u]=a.useState(""),[C,A]=a.useState(!0),[E,M]=a.useState(!1),[b,x]=a.useState(!1),[r,p]=a.useState(null),[T,J]=a.useState(!0),[X,L]=a.useState(!1),[S,P]=a.useState(()=>he({})),[F,ee]=a.useState(!0),[ue,$]=a.useState(!1),[o,v]=a.useState([]),[se,I]=a.useState(!0),[c,k]=a.useState(O),[W,y]=a.useState(""),[d,te]=a.useState(!1),[U,f]=a.useState(!1),[ae,H]=a.useState(!1),[ne,Q]=a.useState(!1),[Y,re]=a.useState(!1),[D,z]=a.useState(null),[ye,R]=a.useState(!0),[ge,B]=a.useState(!1),[ie,G]=a.useState(!1),[le,V]=a.useState(null),{status:me,loading:K,refresh:j}=Le({projectId:t}),be=a.useCallback(n=>{y(n),f(!0)},[]),N=a.useCallback(async n=>{te(!0);try{const{content:l}=await Ee(n,t);k(n),y(l),f(!1)}finally{te(!1)}},[t]),q=a.useCallback(async()=>{I(!0);try{const{files:n}=await Me(t);if(v(n),n.length===0){k(O),y(""),f(!1);return}const l=De(n,c);l!==c&&await N(l)}finally{I(!1)}},[t,c,N]);a.useEffect(()=>{let n=!1;async function l(){try{const s=await $e(t);n||(u(s.content),A(!1))}catch{n||(u(""),A(!1))}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){try{const s=await we(t);n||(p(s.content),L(s.exists),J(!1))}catch{n||(p(null),L(!1),J(!1))}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){ee(!0);try{const s=await Ue(t);n||P(he(s))}catch{n||P(he({}))}finally{n||ee(!1)}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){I(!0);try{const{files:s}=await Me(t);if(n)return;if(v(s),s.length===0){k(O),y(""),f(!1);return}const h=De(s,c),{content:g}=await Ee(h,t);if(n)return;k(h),y(g),f(!1)}catch{n||(v([]),k(O),y(""),f(!1))}finally{n||I(!1)}}return l(),()=>{n=!0}},[t,c]),a.useEffect(()=>{let n=!1;async function l(){try{const s=await ke(t);n||(z(s),R(!1))}catch{n||(z(null),R(!1))}}return l(),()=>{n=!0}},[t]),a.useEffect(()=>{let n=!1;async function l(){try{const s=await He(t);n||V(s)}catch{n||V(null)}}return l(),()=>{n=!0}},[t]);const ce=a.useCallback(n=>{u(n),M(!0)},[]),oe=a.useCallback(async()=>{if(E){x(!0);try{await Ie(m,t),M(!1)}finally{x(!1)}}},[m,E,t]),xe=a.useCallback(async n=>{$(!0);try{const l=await Re(n,t);P(he(l))}finally{$(!1)}},[t]),pe=a.useCallback(async n=>{await N(n)},[N]),fe=a.useCallback(async()=>{if(U){H(!0);try{await qe(c,W,t),f(!1),await q()}finally{H(!1)}}},[W,U,c,t,q]),je=a.useCallback(async()=>{G(!0);try{const n=await _e(t);return await j(),n}finally{G(!1)}},[t,j]),Se=a.useCallback(async n=>Pe(n,t),[t]),Z=a.useCallback(async()=>{try{const n=await ke(t);z(n)}catch{z(null)}},[t]),_=a.useCallback(async()=>{try{const n=await we(t);p(n.content),L(n.exists)}catch{p(null),L(!1)}},[t]),de=a.useCallback(async n=>{await We(n,t),await _()},[t,_]),ve=a.useCallback(async()=>{Q(!0);try{const n=await Oe(t);return await Promise.all([_(),Z()]),{success:n.success,summary:n.summary}}finally{Q(!1)}},[t,_,Z]),Ne=a.useCallback(async()=>{re(!0);try{return await Te(t)}finally{re(!1)}},[t]),Ce=a.useCallback(async n=>{B(!0);try{const l=n?await Ae(n,t):await Ae(t);if(n){const s=l.path??n;k(s),y(l.content),f(!1),await q();return}u(l.content),M(!0)}finally{B(!1)}},[t,q]);return{workingMemory:m,workingMemoryLoading:C,workingMemoryDirty:E,setWorkingMemory:ce,saveWorkingMemory:oe,savingWorkingMemory:b,insightsContent:r,insightsLoading:T,insightsExists:X,refreshInsights:_,saveInsights:de,memorySettings:S,settingsLoading:F,savingMemorySettings:ue,saveMemorySettings:xe,memoryFiles:o,memoryFilesLoading:se,selectedFilePath:c,selectedFileContent:W,selectedFileLoading:d,selectedFileDirty:U,setSelectedFileContent:be,selectFile:pe,saveSelectedFile:fe,savingSelectedFile:ae,reloadMemoryFiles:q,backendStatus:me,backendLoading:K,extractInsights:ve,extracting:ne,triggerDreamNow:Ne,dreamRunning:Y,auditReport:D,auditLoading:ye,refreshAudit:Z,compactMemory:Ce,compacting:ge,installQmdAction:je,installingQmd:ie,testRetrieval:Se,stats:le}}const Ve={Patterns:"pattern",Principles:"principle",Conventions:"convention",Pitfalls:"pitfall",Context:"context"},Ke={"long-term":"Long-term",daily:"Daily",dreams:"Dreams"},Ze={"long-term":"Curated durable decisions, conventions, constraints, and pitfalls promoted from dreams.",daily:"Raw daily observations, open loops, and running context for dream processing.",dreams:"Synthesized patterns and open loops promoted from daily memory."},Je=72;function Xe(i,t){if(i.length<=t)return i;const m=Math.max(1,t-1),u=Math.ceil(m/2),C=Math.floor(m/2);return`${i.slice(0,u)}…${i.slice(i.length-C)}`}function es(i){const t=`${i.label} — ${i.path}`;return Xe(t,Je)}function ss(i){if(!i)return[];const t=[],m=i.split(/(?=^## )/m);for(const u of m){const C=u.trim();if(!C)continue;const A=C.match(/^##\s+(.+?)(\n|$)/);if(A){const E=A[1].trim(),M=Ve[E]??E.toLowerCase(),b=C.slice(A[0].length).trim(),x=b.split(`
2
- `).map(r=>r.replace(/^-\s+/,"").trim()).filter(r=>r.length>0&&(r.startsWith("- ")||r.startsWith("* ")));(x.length>0||b.length>0)&&t.push({name:E,key:M,items:x.length>0?x:b.length>0?[b]:[],expanded:!0})}}return t}function ts(i){if(!i)return null;const t=i.match(/##\s+Last\s+Updated:\s*(\d{4}-\d{2}-\d{2})/i);return t?t[1]:null}function as(i){return i.reduce((t,m)=>t+m.items.length,0)}function ns(i){switch(i){case"file":return"File (.fusion/memory/, agent/<agent-name>/memory/)";case"readonly":return"Read-Only";case"qmd":return"QMD (Quantized Memory Distillation)";default:return i}}function rs(i){switch(i){case"healthy":return"Healthy";case"warning":return"Warning";case"issues":return"Issues Found"}}function os({projectId:i,addToast:t}){const[m,u]=a.useState("working"),[C,A]=a.useState(new Set),[E,M]=a.useState(!1),[b,x]=a.useState(null),[r,p]=a.useState({memoryEnabled:!0,memoryAutoSummarizeEnabled:!1,memoryAutoSummarizeThresholdChars:5e4,memoryAutoSummarizeSchedule:"0 3 * * *",memoryDreamsEnabled:!1,memoryDreamsSchedule:"0 4 * * *"}),[T,J]=a.useState(""),[X,L]=a.useState(!1),[S,P]=a.useState(null),{insightsContent:F,insightsLoading:ee,insightsExists:ue,saveInsights:$,memorySettings:o,settingsLoading:v,saveMemorySettings:se,savingMemorySettings:I,backendStatus:c,backendLoading:k,extractInsights:W,extracting:y,auditReport:d,auditLoading:te,refreshAudit:U,compactMemory:f,compacting:ae,installQmdAction:H,installingQmd:ne,testRetrieval:Q,memoryFiles:Y,memoryFilesLoading:re,selectedFilePath:D,selectedFileContent:z,selectedFileLoading:ye,selectedFileDirty:R,setSelectedFileContent:ge,selectFile:B,saveSelectedFile:ie,savingSelectedFile:G,reloadMemoryFiles:le,triggerDreamNow:V,dreamRunning:me}=Ge({projectId:i});a.useEffect(()=>{p(o)},[o]);const K=a.useMemo(()=>r.memoryEnabled!==o.memoryEnabled||r.memoryAutoSummarizeEnabled!==o.memoryAutoSummarizeEnabled||r.memoryAutoSummarizeThresholdChars!==o.memoryAutoSummarizeThresholdChars||r.memoryAutoSummarizeSchedule!==o.memoryAutoSummarizeSchedule||r.memoryDreamsEnabled!==o.memoryDreamsEnabled||r.memoryDreamsSchedule!==o.memoryDreamsSchedule,[r,o]),j=a.useMemo(()=>Y.find(s=>s.path===D),[Y,D]),be=j?Ze[j.layer]:"Edits the selected memory file.",N=a.useMemo(()=>ss(F),[F]),q=a.useMemo(()=>as(N),[N]),ce=a.useMemo(()=>ts(F),[F]),oe=a.useCallback(s=>{A(h=>{const g=new Set(h);return g.has(s)?g.delete(s):g.add(s),g})},[]),xe=a.useCallback(async s=>{try{await B(s)}catch{t("Failed to load memory file","error")}},[B,t]),pe=a.useCallback(async()=>{try{await ie(),t("Memory saved","success")}catch{t("Failed to save memory","error")}},[ie,t]),fe=a.useCallback(async()=>{if(!K)return;const s={};r.memoryEnabled!==o.memoryEnabled&&(s.memoryEnabled=r.memoryEnabled),r.memoryAutoSummarizeEnabled!==o.memoryAutoSummarizeEnabled&&(s.memoryAutoSummarizeEnabled=r.memoryAutoSummarizeEnabled),r.memoryAutoSummarizeThresholdChars!==o.memoryAutoSummarizeThresholdChars&&(s.memoryAutoSummarizeThresholdChars=r.memoryAutoSummarizeThresholdChars),r.memoryAutoSummarizeSchedule!==o.memoryAutoSummarizeSchedule&&(s.memoryAutoSummarizeSchedule=r.memoryAutoSummarizeSchedule),r.memoryDreamsEnabled!==o.memoryDreamsEnabled&&(s.memoryDreamsEnabled=r.memoryDreamsEnabled),r.memoryDreamsSchedule!==o.memoryDreamsSchedule&&(s.memoryDreamsSchedule=r.memoryDreamsSchedule);try{await se(s),t("Memory settings saved","success")}catch{t("Failed to save memory settings","error")}},[K,r,o,se,t]),je=a.useCallback(async()=>{try{const s=await H();t(s.qmdAvailable?"qmd installed successfully":"qmd install finished, but qmd is still unavailable",s.qmdAvailable?"success":"info")}catch{t("Failed to install qmd","error")}},[H,t]),Se=a.useCallback(async()=>{L(!0),P(null);try{const s=await Q(T);P(s),t(s.qmdAvailable?"Memory retrieval test complete":"qmd is not installed; local fallback was used",s.qmdAvailable?"success":"info")}catch{t("Failed to test memory retrieval","error")}finally{L(!1)}},[T,Q,t]),Z=a.useCallback(async()=>{try{await V(),t("Dream processing completed","success"),await le()}catch(s){t(s instanceof Error?s.message:"Failed to run dream processing","error")}},[V,le,t]),_=a.useCallback(async()=>{try{await f(D),t("Memory file compacted","success")}catch{t("Failed to compact memory","error")}},[f,D,t]),de=a.useCallback(async()=>{try{const s=await W();t(s.summary,"success")}catch(s){t(s instanceof Error?s.message:"Failed to extract insights","error")}},[W,t]),ve=a.useCallback(async()=>{if(b!==null)try{await $(b),M(!1),x(null),t("Insights saved","success")}catch{t("Failed to save insights","error")}},[b,$,t]),Ne=a.useCallback(()=>{x(F??""),M(!0)},[F]),Ce=a.useCallback(()=>{M(!1),x(null)},[]),n=!k&&c!==null,l=c?.capabilities?.writable??!1;return e.jsxs("div",{className:"memory-view",children:[e.jsx("div",{className:"memory-view-header",children:e.jsxs("div",{children:[e.jsx("h2",{children:"Memory"}),e.jsx("p",{className:"memory-view-description",children:"Working memory, long-term insights, and engine status"})]})}),e.jsxs("div",{className:"memory-view-tabs",role:"tablist",children:[e.jsx("button",{type:"button",role:"tab","aria-selected":m==="working",className:`memory-view-tab${m==="working"?" memory-view-tab--active":""}`,onClick:()=>u("working"),"data-testid":"memory-tab-working",children:"Working Memory"}),e.jsx("button",{type:"button",role:"tab","aria-selected":m==="insights",className:`memory-view-tab${m==="insights"?" memory-view-tab--active":""}`,onClick:()=>u("insights"),"data-testid":"memory-tab-insights",children:"Insights"}),e.jsx("button",{type:"button",role:"tab","aria-selected":m==="engines",className:`memory-view-tab${m==="engines"?" memory-view-tab--active":""}`,onClick:()=>u("engines"),"data-testid":"memory-tab-engines",children:"Engines"})]}),e.jsxs("div",{className:"memory-view-content",children:[m==="working"&&e.jsxs("div",{className:"memory-working-tab",children:[n&&!l&&e.jsx("div",{className:"memory-readonly-banner",children:"This memory backend is read-only. Changes cannot be saved."}),re||ye?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading memory file…"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-editor-section",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryViewFilePath",children:"Memory File"}),e.jsx("select",{id:"memoryViewFilePath",className:"select",value:D,onChange:s=>{xe(s.target.value)},disabled:R,children:Y.map(s=>e.jsx("option",{value:s.path,title:`${s.label} — ${s.path}`,children:es(s)},s.path))}),e.jsx("small",{children:R?"Save or discard the current edits before switching files.":"Choose any project memory file to view or edit."})]}),j&&e.jsxs("div",{className:"memory-file-summary",children:[e.jsx("span",{children:Ke[j.layer]}),e.jsx("strong",{children:j.path}),e.jsxs("small",{children:[j.size.toLocaleString()," bytes · updated ",new Date(j.updatedAt).toLocaleString()]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:j?.label||"Memory Editor"}),e.jsx("small",{children:be}),e.jsx("div",{className:"memory-editor-container",children:e.jsx(Fe,{content:z,onChange:ge,readOnly:!l,filePath:D})})]})]}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsxs("span",{className:"memory-char-count",children:[z.length," characters"]}),e.jsx("div",{className:"memory-flex-spacer"}),l&&z.length>0&&e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:_,disabled:ae||R,children:ae?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Compacting…"]}):"Compact Selected File"}),R&&l&&e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:pe,disabled:G,children:G?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Saving…"]}):"Save"})]}),e.jsxs("div",{className:"memory-config-section",children:[e.jsxs("div",{className:"memory-settings-group",children:[e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryDreamsEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryDreamsEnabled",type:"checkbox",checked:r.memoryDreamsEnabled,onChange:s=>{p(h=>({...h,memoryDreamsEnabled:s.target.checked}))},disabled:!r.memoryEnabled||v}),"Process dreams from daily memory"]}),e.jsx("small",{children:"Turns daily notes into DREAMS.md and promotes reusable lessons into MEMORY.md."})]}),r.memoryEnabled&&r.memoryDreamsEnabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryDreamsSchedule",children:"Dream Schedule"}),e.jsx("input",{id:"memoryDreamsSchedule",type:"text",className:"input",value:r.memoryDreamsSchedule,onChange:s=>{p(h=>({...h,memoryDreamsSchedule:s.target.value}))},placeholder:"0 4 * * *",disabled:v}),e.jsx("small",{children:"Cron expression for dream processing."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:Z,disabled:me||!r.memoryDreamsEnabled,children:me?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Dreaming…"]}):"Dream Now"}),e.jsx("small",{children:"Manually trigger dream processing now."})]})]})]}),e.jsxs("div",{className:"memory-settings-group",children:[e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryAutoSummarizeEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryAutoSummarizeEnabled",type:"checkbox",checked:r.memoryAutoSummarizeEnabled,onChange:s=>{p(h=>({...h,memoryAutoSummarizeEnabled:s.target.checked}))},disabled:!r.memoryEnabled||v}),"Auto-Summarize Memory"]}),e.jsx("small",{children:"Automatically compact memory when it exceeds the threshold on a schedule"})]}),r.memoryEnabled&&r.memoryAutoSummarizeEnabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeThresholdChars",children:"Compaction Threshold (chars)"}),e.jsx("input",{id:"memoryAutoSummarizeThresholdChars",type:"number",className:"input",value:r.memoryAutoSummarizeThresholdChars,onChange:s=>{p(h=>({...h,memoryAutoSummarizeThresholdChars:parseInt(s.target.value,10)||5e4}))},min:1e3,disabled:v}),e.jsx("small",{children:"Memory will be compacted when it exceeds this character count"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeSchedule",children:"Schedule (cron)"}),e.jsx("input",{id:"memoryAutoSummarizeSchedule",type:"text",className:"input",value:r.memoryAutoSummarizeSchedule,onChange:s=>{p(h=>({...h,memoryAutoSummarizeSchedule:s.target.value}))},placeholder:"0 3 * * *",disabled:v}),e.jsx("small",{children:"Cron expression for auto-summarize schedule (default: daily at 3 AM)"})]})]})]}),!r.memoryEnabled&&e.jsx("div",{className:"settings-empty-state memory-status-message",children:"Memory is currently disabled. Enable memory tools in Settings to edit these automations."}),K&&e.jsx("div",{className:"memory-action-bar",children:e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:fe,disabled:I||v,children:I?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Saving…"]}):"Save Settings"})})]})]})]}),m==="insights"&&e.jsx("div",{className:"memory-insights-tab",children:ee?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading insights…"})]}):E?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"memory-editor-container",children:e.jsx(Fe,{content:b??"",onChange:x,readOnly:!1,filePath:".fusion/memory/INSIGHTS.md"})}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Ce,children:"Cancel"}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:ve,children:"Save Insights"})]})]}):!ue||N.length===0?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx("p",{children:"No insights extracted yet."}),e.jsx("p",{children:'Insights are automatically extracted from working memory. Click "Extract Now" to trigger extraction manually.'}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm memory-empty-extract-button",onClick:de,disabled:y,children:y?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Extracting…"]}):"Extract Now"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-stats-row",children:[e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value",children:q}),e.jsx("div",{className:"memory-stat-label",children:"Total Insights"})]}),e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value",children:N.length}),e.jsx("div",{className:"memory-stat-label",children:"Categories"})]}),ce&&e.jsxs("div",{className:"memory-stat-card",children:[e.jsx("div",{className:"memory-stat-value memory-stat-value--updated",children:ce}),e.jsx("div",{className:"memory-stat-label",children:"Last Updated"})]})]}),e.jsxs("div",{className:"memory-action-bar",children:[e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:de,disabled:y,children:y?e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14,className:"animate-spin"}),"Extracting…"]}):"Extract Now"}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Ne,children:"Edit Raw"})]}),e.jsx("div",{className:"memory-categories-list",children:N.map(s=>{const h=!C.has(s.key);return e.jsxs("div",{className:"memory-category-section",children:[e.jsxs("div",{className:"memory-category-header",onClick:()=>oe(s.key),role:"button",tabIndex:0,onKeyDown:g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),oe(s.key))},children:[e.jsx("h4",{children:s.name}),e.jsx("span",{className:"memory-category-count",children:s.items.length})]}),h&&e.jsx("div",{className:"memory-category-items",children:s.items.map((g,ze)=>e.jsx("div",{className:"memory-insight-item",children:g.replace(/^-\s+/,"").replace(/^\*\s+/,"")},ze))})]},s.key)})})]})}),m==="engines"&&e.jsx("div",{className:"memory-engines-tab",children:k||te?e.jsxs("div",{className:"memory-empty-state",children:[e.jsx(w,{size:20,className:"animate-spin"}),e.jsx("span",{children:"Loading engine status…"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"memory-engine-card memory-qmd-card",children:[e.jsx("h3",{children:"QMD Integration"}),c?.qmdAvailable===!0?e.jsxs("div",{className:"memory-engine-status",children:[e.jsx("span",{className:"memory-health-badge memory-health-badge--healthy",children:"Installed"}),e.jsx("span",{className:"memory-char-count",children:"qmd is available on PATH."})]}):c?.qmdAvailable===!1?e.jsxs("div",{className:"settings-empty-state memory-status-message",children:[e.jsxs("span",{children:["qmd is not installed. Search will use local files. Install indexed retrieval: ",e.jsx("code",{children:c.qmdInstallCommand||"bun install -g @tobilu/qmd"})]}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:je,disabled:ne,children:ne?"Installing…":"Install qmd"})]}):e.jsxs("div",{className:"memory-engine-status",children:[e.jsx("span",{className:"memory-health-badge",children:"Checking"}),e.jsx("span",{className:"memory-char-count",children:"Checking qmd availability…"})]}),e.jsxs("div",{className:"memory-capability-row",children:[c?.capabilities?.readable&&e.jsx("span",{className:"memory-capability-badge",children:"Readable"}),c?.capabilities?.writable&&e.jsx("span",{className:"memory-capability-badge",children:"Writable"}),c?.capabilities?.supportsAtomicWrite&&e.jsx("span",{className:"memory-capability-badge",children:"Atomic Writes"}),c?.capabilities?.persistent&&e.jsx("span",{className:"memory-capability-badge",children:"Persistent"})]})]}),e.jsxs("div",{className:"memory-engine-card memory-retrieval-card",children:[e.jsx("h3",{children:"Test Memory Search"}),e.jsxs("div",{className:"memory-retrieval-input-row",children:[e.jsx("input",{type:"text",className:"input",value:T,onChange:s=>J(s.target.value),placeholder:"Search memory with qmd"}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Se,disabled:X,children:X?"Testing…":"Test Retrieval"})]}),e.jsx("small",{className:"settings-muted",children:"Runs the same qmd-backed memory_search path agents use."}),S&&e.jsxs("div",{className:"memory-test-result",children:[e.jsxs("strong",{children:[S.results.length," result",S.results.length===1?"":"s"," ",'for "',S.query,'"']}),e.jsxs("small",{children:["qmd ",S.qmdAvailable?"available":"missing"," · ",S.usedFallback?"local fallback used":"qmd path used"]}),S.results.length>0?e.jsx("ul",{children:S.results.map((s,h)=>e.jsxs("li",{children:[e.jsxs("span",{children:[s.path,":",s.lineStart]}),e.jsx("p",{children:s.snippet})]},`${s.path}-${s.lineStart}-${h}`))}):e.jsx("small",{children:"No matching memory found."})]})]}),e.jsxs("div",{className:"memory-engine-card",children:[e.jsx("h3",{children:"Current Backend"}),e.jsx("div",{className:"memory-engine-status",children:e.jsx("span",{className:"memory-emphasis-text",children:ns(c?.currentBackend??"unknown")})}),e.jsxs("div",{className:"memory-capability-row",children:[c?.capabilities?.readable&&e.jsx("span",{className:"memory-capability-badge",children:"Readable"}),c?.capabilities?.writable&&e.jsx("span",{className:"memory-capability-badge",children:"Writable"}),c?.capabilities?.supportsAtomicWrite&&e.jsx("span",{className:"memory-capability-badge",children:"Atomic Writes"}),c?.capabilities?.persistent&&e.jsx("span",{className:"memory-capability-badge",children:"Persistent"})]})]}),d&&e.jsxs("div",{className:"memory-engine-card",children:[e.jsxs("div",{className:"memory-health-header",children:[e.jsx("h3",{children:"Health Status"}),e.jsx("span",{className:`memory-health-badge memory-health-badge--${d.health}`,children:rs(d.health)})]}),e.jsxs("div",{className:"memory-health-grid",children:[e.jsxs("div",{children:[e.jsx("div",{className:"memory-health-label",children:"Working Memory"}),e.jsxs("div",{className:"memory-emphasis-text",children:[d.workingMemory.size," chars"]}),e.jsxs("div",{className:"memory-health-detail",children:[d.workingMemory.sectionCount," sections"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"memory-health-label",children:"Insights Memory"}),e.jsxs("div",{className:"memory-emphasis-text",children:[d.insightsMemory.size," chars"]}),e.jsxs("div",{className:"memory-health-detail",children:[d.insightsMemory.insightCount," insights"]})]})]}),e.jsxs("div",{className:"memory-health-section",children:[e.jsx("div",{className:"memory-health-label",children:"Last Extraction"}),e.jsx("div",{className:"memory-emphasis-text",children:d.extraction.success?e.jsx("span",{className:"memory-status-text memory-status-text--success",children:"Success"}):e.jsx("span",{className:"memory-status-text memory-status-text--error",children:"Failed"})}),e.jsx("div",{className:"memory-health-detail",children:d.extraction.summary||`${d.extraction.insightCount} insights extracted`})]}),e.jsxs("div",{className:"memory-health-section",children:[e.jsx("div",{className:"memory-health-label",children:"Pruning"}),e.jsx("div",{className:"memory-emphasis-text",children:d.pruning.applied?e.jsx("span",{className:"memory-status-text memory-status-text--warning",children:"Applied"}):e.jsx("span",{className:"memory-status-text memory-status-text--muted",children:"Not needed"})}),d.pruning.applied&&e.jsx("div",{className:"memory-health-detail",children:d.pruning.reason})]})]}),d&&d.checks.length>0&&e.jsxs("div",{className:"memory-engine-card",children:[e.jsx("h3",{children:"Audit Checks"}),e.jsx("div",{children:d.checks.map(s=>e.jsxs("div",{className:"memory-audit-check",children:[e.jsx("span",{className:s.passed?"memory-audit-check-passed":"memory-audit-check-failed",children:s.passed?"✓":"✗"}),e.jsxs("div",{className:"memory-audit-check-content",children:[e.jsx("div",{className:"memory-emphasis-text",children:s.name}),e.jsx("div",{className:"memory-health-detail",children:s.details})]})]},s.id))})]}),e.jsx("div",{className:"memory-action-bar",children:e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:()=>U(),children:"Run Audit"})}),e.jsxs("div",{className:"memory-settings-note",children:[e.jsx("span",{children:"Note: Change backend type in"}),e.jsx("button",{type:"button",className:"memory-settings-note-button",onClick:()=>{t("Open Settings → Memory to change backend type","info")},children:"Settings → Memory"})]})]})})]})]})}export{os as MemoryView};
@@ -1 +0,0 @@
1
- .memory-view{display:flex;flex-direction:column;height:100%;padding:var(--space-lg);overflow:hidden}.memory-view-header{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start;margin-bottom:var(--space-lg)}.memory-view-header h2{font-size:18px;color:var(--text);margin:0}.memory-view-description{color:var(--text-muted);font-size:13px;margin:var(--space-xs) 0 0 0}.memory-view-tabs{display:flex;flex-direction:row;gap:var(--space-xs);border-bottom:1px solid var(--border);margin-bottom:var(--space-lg)}.memory-view-tab{padding:var(--space-sm) var(--space-md);border-radius:var(--radius-sm) var(--radius-sm) 0 0;color:var(--text-muted);background:transparent;border:none;cursor:pointer;font-size:13px;transition:background var(--transition-fast),color var(--transition-fast)}.memory-view-tab:hover{background:var(--card-hover);color:var(--text)}.memory-view-tab:focus-visible{outline:none;box-shadow:var(--focus-ring)}.memory-view-tab--active{color:var(--text);border-bottom:2px solid var(--todo);font-weight:500}.memory-view-content{flex:1;overflow-y:auto}.memory-editor-container{border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden;display:flex;flex-direction:column;height:calc(100vh - var(--header-height) - 180px)}.memory-category-section{margin-bottom:var(--space-lg)}.memory-category-header{display:flex;flex-direction:row;justify-content:space-between;align-items:center;cursor:pointer;padding:var(--space-sm) 0;border-bottom:1px solid var(--border);transition:opacity var(--transition-fast)}.memory-category-header:hover{opacity:.8}.memory-category-header h4{font-size:14px;font-weight:500;margin:0;color:var(--text)}.memory-category-count{font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted);background:color-mix(in srgb,var(--text-muted) 15%,transparent);padding:2px 8px;border-radius:var(--radius-pill)}.memory-category-items{padding-top:var(--space-sm)}.memory-insight-item{padding:var(--space-xs) var(--space-sm);margin-bottom:var(--space-xs);border-left:3px solid var(--border);font-size:13px;color:var(--text);line-height:1.5}.memory-engine-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--space-xl);margin-bottom:var(--space-lg)}.memory-engine-card h3{font-size:14px;font-weight:500;margin:0 0 var(--space-md) 0;color:var(--text)}.memory-engine-status{display:flex;flex-direction:row;align-items:center;gap:var(--space-sm)}.memory-health-badge{display:inline-block;padding:2px 10px;border-radius:var(--radius-pill);font-size:12px}.memory-health-badge--healthy{background:color-mix(in srgb,var(--color-success) 15%,transparent);color:var(--color-success)}.memory-health-badge--warning{background:color-mix(in srgb,var(--color-warning) 15%,transparent);color:var(--color-warning)}.memory-health-badge--issues{background:color-mix(in srgb,var(--color-error) 15%,transparent);color:var(--color-error)}.memory-action-bar{display:flex;flex-direction:row;gap:var(--space-sm);margin-top:var(--space-md);align-items:center}.memory-empty-extract-button{margin-top:var(--space-md)}.memory-stat-value--updated{font-size:var(--space-lg)}.memory-capability-row{display:flex;gap:var(--space-xs);margin-top:var(--space-sm);flex-wrap:wrap}.memory-emphasis-text{font-weight:500}.memory-health-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--space-md)}.memory-health-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-md)}.memory-health-label{font-size:var(--space-md);color:var(--text-muted);text-transform:uppercase;margin-bottom:var(--space-xs)}.memory-health-detail{font-size:var(--space-md);color:var(--text-muted)}.memory-health-section{margin-top:var(--space-md);padding-top:var(--space-md);border-top:1px solid var(--border)}.memory-status-text--success{color:var(--color-success)}.memory-status-text--error{color:var(--color-error)}.memory-status-text--warning{color:var(--color-warning)}.memory-status-text--muted{color:var(--text-muted)}.memory-audit-check-content{flex:1}.memory-settings-note{margin-top:var(--space-lg);font-size:var(--space-md);color:var(--text-muted);display:flex;align-items:center;gap:var(--space-xs);flex-wrap:wrap}.memory-settings-note-button{background:none;border:none;color:inherit;cursor:pointer;font:inherit;padding:0;text-decoration:underline}.memory-settings-note-button:focus-visible{outline:none;border-radius:var(--radius-sm);box-shadow:var(--focus-ring-strong)}.memory-empty-state{color:var(--text-muted);padding:var(--space-2xl);text-align:center;display:flex;flex-direction:column;align-items:center;gap:var(--space-sm)}.memory-stats-row{display:flex;flex-direction:row;gap:var(--space-lg);margin-bottom:var(--space-lg)}.memory-stat-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-md) var(--space-lg);flex:1}.memory-stat-value{font-size:24px;font-weight:600;color:var(--text);margin-bottom:var(--space-xs)}.memory-stat-label{font-size:12px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px}.memory-audit-check{display:flex;flex-direction:row;padding:var(--space-sm) 0;border-bottom:1px solid var(--border);gap:var(--space-sm)}.memory-audit-check:last-child{border-bottom:none}.memory-audit-check-passed{color:var(--color-success);font-weight:600}.memory-audit-check-failed{color:var(--color-error);font-weight:600}.memory-capability-badge{font-size:11px;padding:2px 8px;border-radius:var(--radius-pill);background:color-mix(in srgb,var(--todo) 15%,transparent);color:var(--text-muted)}.memory-readonly-banner{background:color-mix(in srgb,var(--color-warning) 10%,transparent);border:1px solid color-mix(in srgb,var(--color-warning) 30%,transparent);border-radius:var(--radius-md);padding:var(--space-md);color:var(--color-warning);font-size:13px;margin-bottom:var(--space-md)}.memory-char-count{font-size:12px;color:var(--text-muted)}.memory-categories-list{margin-top:var(--space-lg)}.memory-config-section{margin-top:var(--space-lg);padding-top:var(--space-lg);border-top:1px solid var(--border);display:flex;flex-direction:column;gap:var(--space-md)}.memory-settings-group{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface);padding:var(--space-sm) 0}.memory-flex-spacer{flex:1}.memory-qmd-card{border-style:solid}.memory-retrieval-card{display:flex;flex-direction:column;gap:var(--space-sm)}.memory-retrieval-input-row{display:flex;align-items:center;gap:var(--space-sm)}.memory-retrieval-input-row .input{flex:1}.memory-retrieval-card .memory-test-result{margin-top:var(--space-sm)}@media(max-width:768px){.memory-view{padding:var(--space-md)}.memory-view-header{flex-direction:column;gap:var(--space-sm)}.memory-editor-container{height:calc(100vh - var(--header-height) - var(--mobile-nav-height) - 200px)}.memory-stats-row{flex-wrap:wrap}.memory-stat-card{min-width:calc(50% - var(--space-sm))}.memory-view-tab{min-height:36px;padding:var(--space-sm)}.memory-engine-card{padding:var(--space-md)}.memory-retrieval-input-row{flex-direction:column;align-items:stretch}.memory-settings-group{padding:var(--space-xs) 0}.memory-health-grid{grid-template-columns:1fr}.memory-config-section{margin-top:var(--space-md);padding-top:var(--space-md)}}