@runfusion/fusion 0.13.0 → 0.14.1

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 (72) hide show
  1. package/README.md +13 -0
  2. package/dist/bin.js +1332 -528
  3. package/dist/client/assets/AgentDetailView-B3KAsP2O.js +18 -0
  4. package/dist/client/assets/{AgentsView-Dvf_xUkx.js → AgentsView-DoXb_amw.js} +4 -4
  5. package/dist/client/assets/ChatView-BJ2c7wvd.js +1 -0
  6. package/dist/client/assets/{DevServerView-C2qTJch7.js → DevServerView-DbgM4tlT.js} +1 -1
  7. package/dist/client/assets/{DirectoryPicker-DRfhg9zz.js → DirectoryPicker-DfmtfMiu.js} +1 -1
  8. package/dist/client/assets/{DocumentsView-j8ic1xUw.js → DocumentsView-_-Efkx_W.js} +1 -1
  9. package/dist/client/assets/{InsightsView-CpAz3o0i.js → InsightsView-DUjcfW53.js} +1 -1
  10. package/dist/client/assets/{MemoryView-BcQsi_JK.js → MemoryView-DxMPBb0q.js} +1 -1
  11. package/dist/client/assets/{NodesView-Bo_Yhr4N.js → NodesView-BEBTI15s.js} +1 -1
  12. package/dist/client/assets/PiExtensionsManager-BpMYhHH_.js +11 -0
  13. package/dist/client/assets/PluginManager-CPv7yQd3.js +1 -0
  14. package/dist/client/assets/PluginManager-DA_T0GHn.css +1 -0
  15. package/dist/client/assets/{ResearchView-CLyyqAWE.js → ResearchView-BrFvdyXT.js} +1 -1
  16. package/dist/client/assets/{RoadmapsView-tG7IdOoc.js → RoadmapsView-BDjLrtcj.js} +1 -1
  17. package/dist/client/assets/SettingsModal-Cd-QGB0C.js +31 -0
  18. package/dist/client/assets/{SettingsModal-CXUGeZ0_.js → SettingsModal-CxDxiTRy.js} +1 -1
  19. package/dist/client/assets/SettingsModal-D_AFkDJa.css +1 -0
  20. package/dist/client/assets/{SetupWizardModal-BMJL6eNR.js → SetupWizardModal-DFUA4X3z.js} +1 -1
  21. package/dist/client/assets/{SkillMultiselect-ILMft-Kz.js → SkillMultiselect-BUWe5ujb.js} +1 -1
  22. package/dist/client/assets/{SkillsView-x4_YwBz6.js → SkillsView-RAkqGX3y.js} +1 -1
  23. package/dist/client/assets/TodoView-Ceb0wrg1.js +6 -0
  24. package/dist/client/assets/TodoView-SeO9o7km.css +1 -0
  25. package/dist/client/assets/{folder-open-DDdJt8aE.js → folder-open-DcM-Vd6r.js} +1 -1
  26. package/dist/client/assets/index-C1prPuSl.css +1 -0
  27. package/dist/client/assets/index-DH3aprf6.js +661 -0
  28. package/dist/client/assets/{list-checks-DFxQ9biT.js → list-checks-ByGHVQpZ.js} +1 -1
  29. package/dist/client/assets/{star-BKs1bgJN.js → star-DlEYI8GL.js} +1 -1
  30. package/dist/client/assets/{upload-Bb5Pidne.js → upload-DKshabz-.js} +1 -1
  31. package/dist/client/assets/{users-BImNn91Q.js → users-X6tYPPBV.js} +1 -1
  32. package/dist/client/index.html +2 -2
  33. package/dist/client/sw.js +6 -0
  34. package/dist/client/version.json +1 -1
  35. package/dist/droid-cli/index.ts +127 -0
  36. package/dist/droid-cli/package.json +37 -0
  37. package/dist/droid-cli/src/__tests__/control-handler.test.ts +164 -0
  38. package/dist/droid-cli/src/__tests__/event-bridge.test.ts +1318 -0
  39. package/dist/droid-cli/src/__tests__/mcp-config.test.ts +310 -0
  40. package/dist/droid-cli/src/__tests__/process-manager.test.ts +818 -0
  41. package/dist/droid-cli/src/__tests__/prompt-builder.test.ts +1206 -0
  42. package/dist/droid-cli/src/__tests__/provider.test.ts +1894 -0
  43. package/dist/droid-cli/src/__tests__/setup-test-isolation.test.ts +32 -0
  44. package/dist/droid-cli/src/__tests__/setup-test-isolation.ts +14 -0
  45. package/dist/droid-cli/src/__tests__/stream-parser.test.ts +188 -0
  46. package/dist/droid-cli/src/__tests__/thinking-config.test.ts +141 -0
  47. package/dist/droid-cli/src/__tests__/tool-mapping.test.ts +253 -0
  48. package/dist/droid-cli/src/control-handler.ts +82 -0
  49. package/dist/droid-cli/src/event-bridge.ts +397 -0
  50. package/dist/droid-cli/src/mcp-config.ts +144 -0
  51. package/dist/droid-cli/src/mcp-schema-server.cjs +49 -0
  52. package/dist/droid-cli/src/process-manager.ts +358 -0
  53. package/dist/droid-cli/src/prompt-builder.ts +629 -0
  54. package/dist/droid-cli/src/provider.ts +447 -0
  55. package/dist/droid-cli/src/stream-parser.ts +37 -0
  56. package/dist/droid-cli/src/thinking-config.ts +83 -0
  57. package/dist/droid-cli/src/tool-mapping.ts +147 -0
  58. package/dist/droid-cli/src/types.ts +87 -0
  59. package/dist/extension.js +555 -125
  60. package/dist/pi-claude-cli/package.json +1 -1
  61. package/package.json +2 -1
  62. package/dist/client/assets/AgentDetailView-B7j297GT.js +0 -18
  63. package/dist/client/assets/ChatView-BgUt38ty.js +0 -1
  64. package/dist/client/assets/PiExtensionsManager-DHt2zFg8.js +0 -11
  65. package/dist/client/assets/PluginManager-BQhBHWrB.js +0 -1
  66. package/dist/client/assets/PluginManager-jyNkJZSz.css +0 -1
  67. package/dist/client/assets/SettingsModal-9HS8MnmW.css +0 -1
  68. package/dist/client/assets/SettingsModal-UziTDnLh.js +0 -31
  69. package/dist/client/assets/TodoView-BBYcMbXE.js +0 -6
  70. package/dist/client/assets/TodoView-C1g65hJo.css +0 -1
  71. package/dist/client/assets/index-B15xwijw.css +0 -1
  72. package/dist/client/assets/index-DmSs2FGE.js +0 -661
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion/pi-claude-cli",
3
- "version": "0.13.0",
3
+ "version": "0.14.1",
4
4
  "description": "Fusion vendored fork: pi coding-agent extension that routes LLM calls through the Claude Code CLI. Forked from rchern/pi-claude-cli (MIT). See UPSTREAM.md.",
5
5
  "license": "MIT",
6
6
  "private": true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runfusion/fusion",
3
- "version": "0.13.0",
3
+ "version": "0.14.1",
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",
@@ -34,6 +34,7 @@
34
34
  "dist/**/*.js.map",
35
35
  "dist/client/**",
36
36
  "dist/pi-claude-cli/**",
37
+ "dist/droid-cli/**",
37
38
  "skill/**",
38
39
  "README.md"
39
40
  ],
@@ -1,18 +0,0 @@
1
- import{r as t,j as e}from"./vendor-react-K0fH_qHe.js";import{c as Ge,de as zs,df as Bs,dg as Hs,dh as Is,L as _,R as We,al as ms,Z as Os,am as _e,V as Te,W as Ss,N as ks,di as _s,dj as Vs,dk as Us,w as Cs,cu as Js,dl as Gs,z as q,dm as Ws,s as hs,B as gs,Q as Fe,U as fs,a$ as ve,X as qs,F as be,A as Me,I as qe,dn as Ys,cp as Ks,aF as Zs,bn as Qs,an as ws,Y as Xs,a1 as et,a3 as st,dp as Ue,j as Rs,dq as tt,r as at,dr as nt,ds as it,dt as rt,du as lt,dv as ct,dw as De,a9 as Ee,ab as Le,ac as Pe,C as Z,a7 as Fs,dx as ot,dy as dt,i as ut,h as mt,k as ht,dz as Je,a2 as gt,dA as ft,dB as xt,dC as pt,dD as vt,dE as bt,dF as Ms,dG as jt,dH as Nt,a0 as yt,dI as St,_ as kt,dJ as Ct}from"./index-DmSs2FGE.js";import{S as As}from"./star-BKs1bgJN.js";import{S as wt}from"./SkillMultiselect-ILMft-Kz.js";import{L as Ts}from"./list-checks-DFxQ9biT.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 Rt=[["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"}]],Ae=Ge("chart-column",Rt);/**
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 Ft=[["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"}]],Mt=Ge("square-activity",Ft);/**
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 At=[["path",{d:"M16 17h6v-6",key:"t6n2it"}],["path",{d:"m22 17-8.5-8.5-5 5L2 7",key:"x473p"}]],Tt=Ge("trending-down",At);function xs(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 Dt(s){return`${Math.round(s*100)}%`}function ps(s){const a=Date.now(),i=new Date(s).getTime(),o=a-i;if(o<0){const d=Math.abs(o);return d<6e4?"in a moment":d<36e5?`in ${Math.floor(d/6e4)}m`:d<864e5?`in ${Math.floor(d/36e5)}h`:`in ${Math.floor(d/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 Et(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 xe(s){return s instanceof Error&&s.message?s.message:String(s)}function Lt(s){switch(s){case"improving":return"↑ Improving";case"declining":return"↓ Declining";case"stable":return"→ Stable";default:return"Insufficient data"}}function Pt(s){switch(s){case"improving":return"trend-improving";case"declining":return"trend-declining";case"stable":return"trend-stable";default:return"trend-insufficient"}}function vs(s,a=5){return e.jsx("span",{className:"rating-stars",children:Array.from({length:a},(i,o)=>e.jsx(As,{size:14,className:o<s?"star-filled":"star-empty",fill:o<s?"currentColor":"none"},o))})}function $t({agentId:s,projectId:a,addToast:i}){const[o,d]=t.useState([]),[r,b]=t.useState(null),[m,j]=t.useState(null),[x,y]=t.useState([]),[A,f]=t.useState(!0),[B,L]=t.useState(!0),[T,l]=t.useState(!1),[p,w]=t.useState(!1),[H,D]=t.useState(null),[R,k]=t.useState(0),[U,G]=t.useState(""),[I,F]=t.useState(""),W=t.useCallback(async()=>{try{const[c,E]=await Promise.all([zs(s,20,a),Bs(s,void 0,a)]);d(c),b(E)}catch(c){i(`Failed to load reflections: ${xe(c)}`,"error")}finally{f(!1)}},[s,a,i]),h=t.useCallback(async()=>{try{const[c,E]=await Promise.all([Hs(s,a),Is(s,{limit:50},a)]);j(c),y(E)}catch(c){i(`Failed to load ratings: ${xe(c)}`,"error")}finally{L(!1)}},[s,a,i]);t.useEffect(()=>{W(),h()},[W,h]);const J=async()=>{l(!0);try{if(!await _s(s,a)){i("Not enough history to generate a reflection yet","error");return}i("Reflection generated successfully","success"),f(!0),await W()}catch(c){const E=xe(c),V=E.toLowerCase();V.includes("agent not found")||V.includes("not found")?i("This agent is no longer available. It may have been deleted.","error"):V.includes("insufficient history")?i("Not enough history to generate a reflection yet","error"):i(`Failed to generate reflection: ${E}`,"error")}finally{l(!1)}},S=async c=>{if(c.preventDefault(),R!==0){w(!0);try{await Vs(s,{score:R,category:U||void 0,comment:I||void 0,raterType:"user"},a),k(0),G(""),F(""),i("Rating added","success"),await h()}catch(E){i(`Failed to add rating: ${xe(E)}`,"error")}finally{w(!1)}}},u=async c=>{try{await Us(s,c,a),i("Rating deleted","success"),await h()}catch(E){i(`Failed to delete rating: ${xe(E)}`,"error")}},C=c=>{D(E=>E===c?null:c)};if(A&&B)return e.jsx("div",{className:"reflections-tab",children:e.jsxs("div",{className:"reflections-loading-indicator",children:[e.jsx(_,{size:16,className:"animate-spin"}),e.jsx("span",{className:"text-muted",children:"Loading evaluation..."})]})});const Q=r&&r.totalTasksCompleted===0&&r.totalTasksFailed===0&&r.recentReflectionCount===0;return e.jsxs("div",{className:"reflections-tab",children:[e.jsxs("div",{className:"reflections-header",children:[e.jsxs("h3",{children:[e.jsx(Ae,{size:16}),"Performance, Reflections & Ratings"]}),e.jsx("button",{className:"btn btn-secondary",onClick:J,disabled:T,title:"Generate a manual reflection",children:T?e.jsxs(e.Fragment,{children:[e.jsx(_,{size:14,className:"animate-spin"}),"Reflecting..."]}):e.jsxs(e.Fragment,{children:[e.jsx(We,{size:14}),"Reflect Now"]})})]}),r&&!Q&&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(ms,{size:16,style:{color:"var(--color-success)"}}),r.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(Tt,{size:16,style:{color:"var(--color-error)"}}),r.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(Os,{size:16,style:{color:"var(--in-progress)"}}),xs(r.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(Ae,{size:16,style:{color:r.successRate>=.8?"var(--color-success)":r.successRate>=.5?"var(--color-warning)":"var(--color-error)"}}),Dt(r.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(_e,{size:16,style:{color:"var(--color-info)"}}),r.recentReflectionCount]}),e.jsx("div",{className:"stat-label",children:"Reflections"})]})]}),Q&&e.jsxs("div",{className:"reflections-no-data",children:[e.jsx(Ae,{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"}),B?e.jsxs("div",{className:"reflections-loading-indicator",children:[e.jsx(_,{size:16,className:"animate-spin"}),e.jsx("span",{className:"text-muted",children:"Loading ratings..."})]}):e.jsxs(e.Fragment,{children:[m&&e.jsxs("div",{className:"rating-summary-card",children:[e.jsxs("div",{className:"rating-score-display",children:[e.jsx("span",{className:"rating-average",children:m.averageScore.toFixed(1)}),vs(Math.round(m.averageScore))]}),e.jsxs("div",{className:"rating-stats",children:[e.jsxs("span",{className:"rating-count",children:[m.totalRatings," ratings"]}),e.jsx("span",{className:`rating-trend-badge ${Pt(m.trend)}`,children:Lt(m.trend)})]})]}),m&&Object.keys(m.categoryAverages).length>0&&e.jsxs("div",{className:"category-breakdown",children:[e.jsx("h4",{children:"Category Averages"}),Object.entries(m.categoryAverages).map(([c,E])=>e.jsxs("div",{className:"category-item",children:[e.jsx("span",{className:"category-name",children:c}),e.jsx("span",{className:"category-score",children:E.toFixed(1)})]},c))]}),e.jsxs("form",{className:"add-rating-form",onSubmit:S,children:[e.jsx("h4",{children:"Add Rating"}),e.jsx("div",{className:"star-selector",children:[1,2,3,4,5].map(c=>e.jsx("button",{type:"button",className:"star-btn touch-target",onClick:()=>k(c),title:`${c} star${c>1?"s":""}`,children:e.jsx(As,{size:24,fill:c<=R?"currentColor":"none",className:c<=R?"star-filled":"star-empty"})},c))}),e.jsxs("select",{value:U,onChange:c=>G(c.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:I,onChange:c=>F(c.target.value),placeholder:"Optional comment...",className:"input add-rating-comment-input",rows:3}),e.jsx("button",{type:"submit",className:"btn btn-task-create",disabled:R===0||p,children:p?"Submitting...":"Submit Rating"})]}),e.jsxs("div",{className:"rating-history",children:[e.jsx("h4",{children:"Rating History"}),x.length===0?e.jsx("p",{className:"no-ratings",children:"No ratings yet"}):x.map(c=>e.jsxs("div",{className:"rating-history-item",children:[e.jsxs("div",{className:"rating-item-header",children:[vs(c.score),c.category&&e.jsx("span",{className:"rating-category-badge",children:c.category}),e.jsx("span",{className:"rating-time",children:ps(c.createdAt)}),e.jsx("button",{type:"button",className:"rating-delete-btn touch-target",onClick:()=>void u(c.id),title:"Delete rating",children:e.jsx(Te,{size:14})})]}),c.comment&&e.jsx("p",{className:"rating-comment",children:c.comment})]},c.id))]})]})]}),e.jsxs("div",{className:"reflections-list",children:[e.jsx("h4",{children:"Reflection History"}),A?e.jsxs("div",{className:"reflections-loading-indicator",children:[e.jsx(_,{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(_e,{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(c=>{const E=H===c.id;return e.jsxs("div",{className:`reflection-card ${E?"reflection-card--expanded":""}`,onClick:()=>C(c.id),role:"button",tabIndex:0,onKeyDown:V=>V.key==="Enter"&&C(c.id),children:[e.jsxs("div",{className:"reflection-card-header",children:[e.jsx("span",{className:`reflection-trigger-badge reflection-trigger-${c.trigger}`,children:Et(c.trigger)}),e.jsx("span",{className:"reflection-timestamp",children:ps(c.timestamp)}),e.jsx("span",{className:"reflection-chevron",children:E?e.jsx(Ss,{size:16}):e.jsx(ks,{size:16})})]}),e.jsx("div",{className:"reflection-summary",children:c.summary}),E&&e.jsxs("div",{className:"reflection-details",children:[c.insights.length>0&&e.jsxs("div",{className:"reflection-insights",children:[e.jsxs("h5",{children:[e.jsx(_e,{size:14})," Insights"]}),e.jsx("ul",{children:c.insights.map((V,g)=>e.jsx("li",{children:V},g))})]}),c.suggestedImprovements.length>0&&e.jsxs("div",{className:"reflection-suggestions",children:[e.jsxs("h5",{children:[e.jsx(ms,{size:14})," Suggested Improvements"]}),e.jsx("ul",{children:c.suggestedImprovements.map((V,g)=>e.jsx("li",{children:V},g))})]}),c.metrics&&e.jsxs("div",{className:"reflection-metrics",children:[e.jsx("h5",{children:"Metrics"}),e.jsxs("div",{className:"metrics-grid",children:[c.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:c.metrics.tasksCompleted})]}),c.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:c.metrics.tasksFailed})]}),c.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:xs(c.metrics.avgDurationMs)})]}),c.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:c.metrics.errorCount})]})]})]})]})]},c.id)})})]})]})}function ee(...s){return s.filter(Boolean).join(" ")}function je(s){const a=Date.now(),i=new Date(s).getTime(),o=a-i;if(o<0){const d=Math.abs(o);return d<6e4?"in a moment":d<36e5?`in ${Math.floor(d/6e4)}m`:d<864e5?`in ${Math.floor(d/36e5)}h`:`in ${Math.floor(d/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 zt=[{id:"dashboard",label:"Dashboard",icon:Mt},{id:"logs",label:"Logs",icon:be},{id:"runs",label:"Runs",icon:Me},{id:"tasks",label:"Tasks",icon:Ts},{id:"employees",label:"Employees",icon:qe},{id:"soul",label:"Soul",icon:Ys},{id:"instructions",label:"Instructions",icon:Ks},{id:"memory",label:"Agent Memory",icon:be},{id:"reflections",label:"Evaluation",icon:Ae},{id:"config",label:"Settings",icon:Zs}],Ye={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)"},terminated:{bg:"var(--state-error-bg)",text:"var(--state-error-text)",border:"var(--state-error-border)"}},bs={completed:{icon:Z,color:"var(--color-success, #3fb950)"},failed:{icon:xt,color:"var(--color-error, #f85149)"},active:{icon:_,color:"var(--in-progress, #bc8cff)"},terminated:{icon:ve,color:"var(--text-muted, #8b949e)"}},js={"long-term":"Long-term",daily:"Daily",dreams:"Dreams"},Bt={"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."},Ht=yt(Je);function It(s,a){return s.some(i=>i.path===a)?a:s.find(i=>i.layer==="long-term")?.path??s[0]?.path??""}function ca({agentId:s,projectId:a,onClose:i,addToast:o,onChildClick:d}){const[r,b]=t.useState(null),{confirm:m}=Cs(),[j,x]=t.useState([]),[y,A]=t.useState(!0),[f,B]=t.useState("dashboard"),[L,T]=t.useState(!1),[l,p]=t.useState(!1),w=t.useRef(null),H=t.useRef(null),D=t.useRef(!1);Js(H,!0,"fusion:agent-detail-modal-size");const R=t.useRef(i),k=t.useRef(o),U=t.useRef(null),G=t.useRef(!1),I=t.useRef(0),F=t.useRef(s),W=t.useRef(a);R.current=i,k.current=o,U.current=r;const h=t.useCallback(async()=>{U.current===null&&A(!0);try{const P=await Gs(s,a);b(P)}catch(P){k.current(`Failed to load agent: ${q(P)}`,"error"),R.current()}finally{A(!1)}},[s,a]),J=t.useCallback(async()=>{const g=I.current,P=s,v=a;if(r?.taskId)try{const O=await Ws(r.taskId,v,{limit:100});if(I.current!==g||s!==P||a!==v)return;x(O.entries)}catch(O){if(I.current!==g||s!==P||a!==v)return;console.error("Failed to load task logs:",O)}},[r?.taskId,s,a]),S=t.useCallback(g=>{G.current=g},[]);t.useEffect(()=>{h()},[h]),t.useEffect(()=>{const g=setInterval(()=>{h()},3e4);return()=>{clearInterval(g)}},[h]),t.useEffect(()=>{r?.taskId&&J()},[r?.taskId,J]),t.useEffect(()=>{(F.current!==s||W.current!==a)&&(F.current=s,W.current=a,I.current++,x([]),T(!1),G.current=!1)},[s,a]),t.useEffect(()=>{const g=a?`?projectId=${encodeURIComponent(a)}`:"",P=I.current;return hs(`/api/events${g}`,{events:{"agent:updated":v=>{if(I.current===P)try{const O=JSON.parse(v.data);if(!O||typeof O!="object"||O.id!==s||G.current)return;h()}catch{}}}})},[s,a,h]),t.useEffect(()=>{if(f!=="logs"||!r?.taskId){T(!1);return}const g=I.current,P=r.taskId,v=a?`?projectId=${encodeURIComponent(a)}`:"",O=hs(`/api/tasks/${encodeURIComponent(P)}/logs/stream${v}`,{events:{"agent:log":le=>{if(I.current===g)try{const Ne=JSON.parse(le.data);x($e=>[Ne,...$e]);const de=w.current;de&&de.scrollTop<50&&(de.scrollTop=0)}catch{}}},onOpen:()=>{I.current===g&&T(!0)},onError:()=>{I.current===g&&T(!1)}});return()=>{O(),I.current===g&&T(!1)}},[r?.taskId,f,a]);const u=async g=>{if(l||!U.current)return;const P=U.current.state;if(P!==g){p(!0),b(v=>v&&{...v,state:g});try{await et(s,g,a),o(`Agent state updated to ${g}`,"success"),h()}catch(v){b(O=>O&&{...O,state:P}),o(`Failed to update state: ${q(v)}`,"error")}finally{p(!1)}}},C=async()=>{if(!(!r||!await m({title:"Delete Agent",message:`Delete agent "${r.name}"? This cannot be undone.`,danger:!0})))try{await st(s,a),o(`Agent "${r.name}" deleted`,"success"),i()}catch(P){o(`Failed to delete agent: ${q(P)}`,"error")}},Q=()=>r?Xs(r):{label:"Unknown",icon:e.jsx(gs,{size:14}),color:"var(--text-muted, #8b949e)",stateDerived:!1},c=()=>{r&&(navigator.clipboard.writeText(r.id),o("Agent ID copied to clipboard","success"))};if(y)return e.jsx("div",{className:"agent-detail-overlay",onMouseDown:g=>{g.target===g.currentTarget&&(D.current=!0)},onMouseUp:g=>{D.current&&g.target===g.currentTarget&&i(),D.current=!1},role:"dialog","aria-modal":"true",children:e.jsx("div",{className:"agent-detail-modal",ref:H,children:e.jsxs("div",{className:"agent-detail-loading",children:[e.jsx(_,{className:"animate-spin",size:24}),e.jsx("span",{children:"Loading agent..."})]})})});if(!r)return null;const E=Ye[r.state],V=Q();return e.jsx("div",{className:"agent-detail-overlay",onClick:g=>g.target===g.currentTarget&&i(),role:"dialog","aria-modal":"true",children:e.jsxs("div",{className:"agent-detail-modal",children:[e.jsxs("div",{className:"agent-detail-header",children:[e.jsxs("div",{className:"agent-detail-identity",children:[e.jsx("div",{className:"agent-detail-icon",children:e.jsx(gs,{size:20})}),e.jsxs("div",{className:"agent-detail-info",children:[e.jsx("h2",{children:r.name}),e.jsxs("div",{className:"agent-detail-badges",children:[e.jsx("span",{className:"badge",style:{background:E.bg,color:E.text,border:`1px solid ${E.border}`},children:r.state}),e.jsxs("span",{className:"badge",style:{color:V.color},title:V.label,children:[V.icon,!V.stateDerived&&V.label]})]})]})]}),e.jsxs("div",{className:"agent-detail-controls",children:[r.state==="idle"&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn-task-create btn--compact",onClick:()=>void u("active"),disabled:l,children:[e.jsx(Fe,{size:14}),"Start"]}),e.jsxs("button",{className:"btn btn--danger btn--compact",onClick:C,children:[e.jsx(Te,{size:14}),"Delete"]})]}),r.state==="active"&&e.jsxs("button",{className:"btn btn--compact",onClick:()=>void u("paused"),disabled:l,children:[e.jsx(fs,{size:14}),"Pause"]}),r.state==="paused"&&e.jsxs("button",{className:"btn btn-task-create btn--compact",onClick:()=>void u("active"),disabled:l,children:[e.jsx(Fe,{size:14}),"Resume"]}),r.state==="running"&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn--compact",onClick:()=>void u("paused"),disabled:l,children:[e.jsx(fs,{size:14}),"Pause"]}),e.jsxs("button",{className:"btn btn--danger btn--compact",onClick:()=>void u("terminated"),disabled:l,children:[e.jsx(ve,{size:14}),"Stop"]})]}),r.state==="error"&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn-task-create btn--compact",onClick:()=>void u("active"),disabled:l,children:[e.jsx(Fe,{size:14}),"Retry"]}),e.jsxs("button",{className:"btn btn--danger btn--compact",onClick:()=>void u("terminated"),disabled:l,children:[e.jsx(ve,{size:14}),"Stop"]})]}),r.state==="terminated"&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn-task-create btn--compact",onClick:()=>void u("active"),disabled:l,children:[e.jsx(Fe,{size:14}),"Start"]}),e.jsxs("button",{className:"btn btn--danger btn--compact",onClick:C,children:[e.jsx(Te,{size:14}),"Delete"]})]})]}),e.jsxs("div",{className:"agent-detail-utility-actions",children:[e.jsx("button",{className:"btn-icon",onClick:()=>void h(),title:"Refresh",children:e.jsx(We,{size:16})}),e.jsx("button",{className:"btn-icon",onClick:i,"aria-label":"Close",title:"Close",children:e.jsx(qs,{size:20})})]})]}),e.jsx("div",{className:"agent-detail-tabs",children:zt.map(g=>e.jsxs("button",{className:ee("agent-detail-tab",f===g.id&&"active"),onClick:()=>B(g.id),children:[e.jsx(g.icon,{size:16}),g.label]},g.id))}),e.jsxs("div",{className:"agent-detail-content",children:[f==="dashboard"&&e.jsx(Ot,{agent:r,health:V,onChildClick:d,projectId:a}),f==="logs"&&e.jsx(_t,{logs:j,isStreaming:L,containerRef:w,hasTask:!!r.taskId}),f==="runs"&&e.jsx(Ut,{addToast:o,agentId:r.id,projectId:a,agentState:r.state,agentName:r.name}),f==="tasks"&&e.jsx(qt,{agentId:r.id,projectId:a,addToast:o}),f==="employees"&&e.jsx(sa,{agentId:r.id,projectId:a,onChildClick:d}),f==="soul"&&e.jsx(Kt,{agent:r,projectId:a,addToast:o,onSaved:h}),f==="instructions"&&e.jsx(Qt,{agent:r,projectId:a,addToast:o,onSaved:h}),f==="memory"&&e.jsx(Zt,{agent:r,projectId:a,addToast:o,onSaved:h}),f==="reflections"&&e.jsx($t,{agentId:r.id,projectId:a,addToast:o}),f==="config"&&e.jsx(ea,{agent:r,projectId:a,addToast:o,onSaved:h,onHasChangesChange:S,onDelete:C})]}),e.jsxs("div",{className:"agent-detail-footer",children:[e.jsx("button",{className:"btn-icon",onClick:c,title:"Copy Agent ID",children:e.jsx(Qs,{size:14})}),e.jsx("span",{className:"agent-detail-id",onClick:c,children:r.id}),r.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/${r.taskId}`,className:"link",children:[r.taskId,e.jsx(ws,{size:12})]})]})]})]})})}function Ot({agent:s,health:a,onChildClick:i,projectId:o}){const d=Ye[s.state],[r,b]=t.useState([]),[m,j]=t.useState(!0),[x,y]=t.useState(null),[A,f]=t.useState([]),B=typeof s.runtimeConfig?.runtimeHint=="string"?s.runtimeConfig.runtimeHint:"",L=(()=>{const l=s.runtimeConfig??{};if(B){const p=A.find(w=>w.runtimeId===B);return p?p.name:B}if(l.modelProvider&&l.modelId)return`${l.modelProvider}/${l.modelId}`;if(typeof l.model=="string"&&l.model.includes("/")){const p=l.model.indexOf("/");return l.model.slice(p+1)}return null})();t.useEffect(()=>{Ue(s.id,o).then(y).catch(()=>y(null))},[s.id,o]),t.useEffect(()=>{Rs(o).then(f).catch(()=>f([]))},[o]),t.useEffect(()=>{let l=!1;return j(!0),tt(s.id,o).then(p=>{if(l)return;const w=p.length>0&&p[0]?.id===s.id?[...p].reverse():p;b(w)}).catch(()=>{l||b([])}).finally(()=>{l||j(!1)}),()=>{l=!0}},[s.id,o]);const T=t.useMemo(()=>{const l=s.completedRuns||[],p=new Date;p.setHours(0,0,0,0);const w=l.filter(D=>new Date(D.startedAt)>=p),H=l.filter(D=>D.status==="completed");return{totalRuns:l.length,todayRuns:w.length,successfulRuns:H.length,successRate:l.length>0?Math.round(H.length/l.length*100):0}},[s]);return e.jsxs("div",{className:"dashboard-tab",children:[x?.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 be operating with limited functionality."]})]}),e.jsxs("div",{className:"dashboard-section",children:[e.jsx("h3",{children:"Agent Information"}),e.jsxs("div",{className:"info-grid",children:[e.jsxs("div",{className:"info-item",children:[e.jsx("span",{className:"info-label",children:"Name"}),e.jsx("span",{className:"info-value",children:s.name})]}),e.jsxs("div",{className:"info-item",children:[e.jsx("span",{className:"info-label",children:"Role"}),e.jsx("span",{className:"info-value",children:s.role})]}),e.jsxs("div",{className:"info-item",children:[e.jsx("span",{className:"info-label",children:"Skills"}),e.jsx("span",{className:"info-value",children:Array.isArray(s.metadata?.skills)&&s.metadata.skills.length>0?e.jsx("div",{className:"skill-badge-row",children:s.metadata.skills.map(l=>e.jsx("span",{className:"skill-badge",children:l},l))}):"—"})]}),e.jsxs("div",{className:"info-item",children:[e.jsx("span",{className:"info-label",children:"State"}),e.jsx("span",{className:"info-value",children:e.jsx("span",{className:"inline-badge",style:{background:d.bg,color:d.text},children:s.state})})]}),e.jsxs("div",{className:"info-item",children:[e.jsx("span",{className:"info-label",children:"Health"}),e.jsx("span",{className:"info-value",style:{color:a.color},title:a.label,children:a.stateDerived?a.icon:a.label})]}),L&&e.jsxs("div",{className:"info-item",children:[e.jsx("span",{className:"info-label",children:B?"Runtime":"Model"}),e.jsx("span",{className:"info-value",children:L})]}),x?.budgetLimit!=null&&e.jsxs("div",{className:"info-item",children:[e.jsx("span",{className:"info-label",children:"Budget"}),e.jsx("span",{className:"info-value",children:e.jsx("span",{className:"budget-badge",style:{background:x.isOverBudget?"var(--state-error-bg, rgba(248,81,73,0.15))":x.isOverThreshold?"var(--state-paused-bg, rgba(227,181,65,0.15))":"var(--state-active-bg, rgba(63,185,80,0.15))",color:x.isOverBudget?"var(--state-error-text, #f85149)":x.isOverThreshold?"var(--state-paused-text, #e3b541)":"var(--state-active-text, #3fb950)",border:`1px solid ${x.isOverBudget?"var(--state-error-border, #f85149)":x.isOverThreshold?"var(--state-paused-border, #e3b541)":"var(--state-active-border, #3fb950)"}`},children:x.isOverBudget?"⚠ Budget Exhausted":`${Math.round(x.usagePercent??0)}% used`})})]}),e.jsxs("div",{className:"info-item",children:[e.jsx("span",{className:"info-label",children:"Created"}),e.jsx("span",{className:"info-value",children:new Date(s.createdAt).toLocaleDateString()})]}),e.jsxs("div",{className:"info-item",children:[e.jsx("span",{className:"info-label",children:"Last Heartbeat"}),e.jsx("span",{className:"info-value",children:s.lastHeartbeatAt?je(s.lastHeartbeatAt):"Never"})]}),(()=>{if(!(s.state==="active"||s.state==="running")||!s.lastHeartbeatAt)return null;const p=at(s.runtimeConfig?.heartbeatIntervalMs),w=new Date(new Date(s.lastHeartbeatAt).getTime()+p);return e.jsxs("div",{className:"info-item",children:[e.jsx("span",{className:"info-label",children:"Next Heartbeat"}),e.jsx("span",{className:"info-value",title:w.toLocaleString(),children:je(w.toISOString())})]})})()]})]}),e.jsxs("div",{className:"dashboard-section",children:[e.jsxs("h3",{children:[e.jsx(qe,{size:16,style:{marginRight:"6px",verticalAlign:"-2px"}}),"Chain of Command"]}),m?e.jsxs("div",{className:"chain-of-command-loading",role:"status","aria-live":"polite",children:[e.jsx(_,{size:14,className:"animate-spin"}),e.jsx("span",{children:"Loading reporting chain..."})]}):r.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:r.map((l,p)=>{const w=p===r.length-1,H=!w;return e.jsxs("div",{className:"chain-of-command-item",children:[e.jsx("button",{type:"button",className:`chain-of-command-node${w?" chain-of-command-node--current":""}`,onClick:()=>H&&i?.(l.id),disabled:!H||!i,title:w?"Current agent":`View ${l.name}`,children:l.name}),!w&&e.jsx("span",{className:"chain-of-command-separator","aria-hidden":"true",children:"→"})]},l.id)})})]}),e.jsxs("div",{className:"dashboard-section",children:[e.jsx("h3",{children:"Statistics"}),e.jsxs("div",{className:"stats-grid",children:[e.jsxs("div",{className:"stat-card",children:[e.jsx("div",{className:"stat-value",children:T.totalRuns}),e.jsx("div",{className:"stat-label",children:"Total Runs"})]}),e.jsxs("div",{className:"stat-card",children:[e.jsx("div",{className:"stat-value",children:T.todayRuns}),e.jsx("div",{className:"stat-label",children:"Runs Today"})]}),e.jsxs("div",{className:"stat-card",children:[e.jsxs("div",{className:"stat-value",children:[T.successRate,"%"]}),e.jsx("div",{className:"stat-label",children:"Success Rate"})]})]})]}),s.taskId&&e.jsxs("div",{className:"dashboard-section",children:[e.jsx("h3",{children:"Current Task"}),e.jsxs("div",{className:"current-task",children:[e.jsx("span",{className:"task-badge",children:s.taskId}),e.jsxs("a",{href:`/tasks/${s.taskId}`,className:"btn btn--sm",children:["View Task ",e.jsx(ws,{size:14})]})]})]}),s.metadata&&Object.keys(s.metadata).length>0&&e.jsxs("div",{className:"dashboard-section",children:[e.jsx("h3",{children:"Metadata"}),e.jsx("pre",{className:"metadata-json",children:JSON.stringify(s.metadata,null,2)})]})]})}function _t({logs:s,isStreaming:a,containerRef:i,hasTask:o}){return o?e.jsxs("div",{className:"logs-tab",children:[e.jsxs("div",{className:"logs-header",children:[e.jsxs("span",{className:"logs-count",children:[s.length," entries"]}),a&&e.jsxs("span",{className:"streaming-indicator",children:[e.jsx("span",{className:"streaming-dot"}),"Live"]})]}),e.jsx("div",{ref:i,className:"logs-container",children:s.length===0?e.jsxs("div",{className:"logs-empty",children:[e.jsx(be,{size:48,opacity:.3}),e.jsx("p",{children:"No log entries yet"}),e.jsx("p",{className:"text-muted",children:a?"Waiting for activity...":"Logs will appear here when the agent is active"})]}):s.map((d,r)=>{const b=r>0?s[r-1]:void 0,m=!b||b.agent!==d.agent;return e.jsx(Vt,{entry:d,showTimestamp:m},`${d.timestamp}-${r}`)})})]}):e.jsx("div",{className:"logs-tab",children:e.jsxs("div",{className:"logs-empty",children:[e.jsx(be,{size:48,opacity:.3}),e.jsx("p",{children:"No task assigned"}),e.jsx("p",{className:"text-muted",children:"Agent logs are available when the agent is assigned to a task"})]})})}function Vt({entry:s,showTimestamp:a}){const o=(()=>{switch(s.type){case"tool":return{color:"var(--accent)",borderLeft:"3px solid var(--accent)",background:"var(--log-tool-bg)"};case"tool_result":return{color:"var(--color-success)",borderLeft:"3px solid var(--color-success)",background:"var(--log-success-bg)"};case"tool_error":return{color:"var(--color-error)",borderLeft:"3px solid var(--color-error)",background:"var(--log-error-bg)"};case"thinking":return{color:"var(--text-muted)",fontStyle:"italic",opacity:.7};default:return{color:"var(--text-primary)"}}})(),d=new Date(s.timestamp).toLocaleTimeString();return e.jsxs("div",{className:"log-entry",style:o,children:[a&&e.jsxs("span",{className:"log-timestamp",children:["[",d,"]"]}),s.agent&&e.jsxs("span",{className:"log-agent",children:["[",s.agent,"]"]}),s.type==="tool"&&e.jsx("span",{className:"log-icon",children:"⚡"}),s.type==="tool_result"&&e.jsx("span",{className:"log-icon",children:"✓"}),s.type==="tool_error"&&e.jsx("span",{className:"log-icon",children:"✗"}),e.jsxs("span",{className:"log-text",children:[s.text,s.detail&&e.jsxs("span",{className:"log-detail",children:[" — ",s.detail]})]})]})}function Ut({addToast:s,agentId:a,projectId:i,agentState:o,agentName:d}){const[r,b]=t.useState([]),{confirm:m}=Cs(),[j,x]=t.useState(!0),[y,A]=t.useState(null),[f,B]=t.useState([]),[L,T]=t.useState(!1),[l,p]=t.useState(null),[w,H]=t.useState(!1),D=t.useCallback(async()=>{try{const u=await nt(a,50,i);b(u)}catch(u){s(`Failed to load runs: ${q(u)}`,"error")}finally{x(!1)}},[a,i,s]);t.useEffect(()=>{D()},[D]);const R=r.some(u=>u.status==="active");t.useEffect(()=>{if(!R)return;const u=setInterval(()=>{D()},5e3);return()=>clearInterval(u)},[R,D]);const k=t.useCallback(async u=>{if(y===u){A(null),B([]),p(null);return}A(u),T(!0),H(!0),B([]),p(null);try{const[C,Q]=await Promise.all([it(a,u,i),rt(a,u,i)]);B(C),p(Q)}catch(C){s(`Failed to load run details: ${q(C)}`,"error"),B([]),p(null)}finally{T(!1),H(!1)}},[y,a,i,s]),U=async()=>{try{await gt(a,i,{source:"on_demand",triggerDetail:"Triggered from dashboard"}),s(`Heartbeat run started for ${d??a}`,"success"),x(!0),D()}catch(u){s(`Failed to start heartbeat run: ${q(u)}`,"error")}},G=async()=>{if(await m({title:"Stop Active Run",message:"Stop the active run? The agent's work will be interrupted.",danger:!0}))try{await ft(a,i),s("Run stopped","success"),x(!0),D()}catch(C){s(`Failed to stop run: ${q(C)}`,"error")}},I=o==="active"||o==="idle";if(j&&r.length===0)return e.jsx("div",{className:"runs-tab",children:e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px",padding:"24px",justifyContent:"center"},children:[e.jsx(_,{size:16,className:"animate-spin"}),e.jsx("span",{className:"text-muted",children:"Loading runs..."})]})});if(r.length===0)return e.jsxs("div",{className:"runs-tab",children:[I&&e.jsx("div",{style:{padding:"12px 16px",borderBottom:"1px solid var(--border-color)"},children:e.jsxs("button",{className:"btn btn--sm btn-task-create",onClick:()=>void U(),"aria-label":`Run now for ${d??a}`,children:[e.jsx(Me,{size:14})," Run Now"]})}),e.jsxs("div",{className:"runs-empty",children:[e.jsx(Me,{size:48,opacity:.3}),e.jsx("p",{children:"No runs yet"}),e.jsx("p",{className:"text-muted",children:"Heartbeat runs will appear here"})]})]});const F=[...r].sort((u,C)=>new Date(C.startedAt).getTime()-new Date(u.startedAt).getTime()),W=F.filter(u=>u.status==="active"),h=F.filter(u=>u.status!=="active"),J=u=>u?e.jsxs("div",{style:{fontSize:"12px",color:"var(--text-secondary)",display:"flex",gap:"12px",flexWrap:"wrap"},children:[e.jsxs("span",{children:["Input: ",u.inputTokens.toLocaleString()]}),e.jsxs("span",{children:["Output: ",u.outputTokens.toLocaleString()]}),u.cachedTokens>0&&e.jsxs("span",{children:["Cached: ",u.cachedTokens.toLocaleString()]})]}):null,S=(u,C,Q)=>{const c=bs[u.status]||bs.completed,E=c.icon,V=u.endedAt?Jt(new Date(u.startedAt),new Date(u.endedAt)):"In progress",g=y===u.id;return e.jsxs("div",{children:[e.jsxs("div",{className:ee("run-card",Q&&"run-card--active",g&&"run-card--selected"),onClick:()=>void k(u.id),style:{cursor:"pointer"},role:"button",tabIndex:0,"aria-expanded":g,"aria-label":`${Q?"Active":""} run ${u.id.slice(0,8)}, ${u.status}`,onKeyDown:P=>{(P.key==="Enter"||P.key===" ")&&(P.preventDefault(),k(u.id))},children:[e.jsxs("div",{className:"run-header",children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[g?e.jsx(Ss,{size:14}):e.jsx(ks,{size:14}),Q?e.jsxs("span",{className:"run-live-indicator",children:[e.jsx("span",{className:"live-dot"}),"Live Run"]}):e.jsxs("span",{className:"run-id",children:["#",C+1," ",u.id.slice(0,8)]})]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[u.invocationSource&&e.jsx("span",{className:"badge",style:{fontSize:"10px",padding:"1px 6px"},children:u.invocationSource}),Q&&e.jsxs("button",{className:"btn btn--sm btn--danger",onClick:P=>{P.preventDefault(),P.stopPropagation(),G()},"aria-label":"Stop active run",children:[e.jsx(ve,{size:12})," Stop"]}),e.jsxs("span",{className:ee("run-status",u.status),children:[e.jsx(E,{size:14,className:c.color,style:u.status==="active"?{color:c.color}:void 0}),u.status]}),u.heartbeatProcedureSource==="custom"&&e.jsx("span",{className:"badge",style:{fontSize:"10px",padding:"1px 6px"},children:"Heartbeat: custom"})]})]}),e.jsxs("div",{className:"run-details",children:[e.jsxs("span",{children:["Started ",je(u.startedAt)]}),e.jsx("span",{children:"•"}),e.jsx("span",{children:V}),u.triggerDetail&&e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"•"}),e.jsx("span",{className:"text-muted",children:u.triggerDetail})]})]})]}),g&&e.jsxs("div",{className:"run-logs-container",children:[w?e.jsxs("div",{className:"run-details-loading-state",children:[e.jsx(_,{size:14,className:"animate-spin"}),e.jsx("span",{className:"text-muted",children:"Loading details..."})]}):l&&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",style:{cursor:"pointer",userSelect:"none"},children:"System Prompt"}),l.systemPrompt?e.jsx("pre",{className:"run-output-panel",children:l.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",style:{cursor:"pointer",userSelect:"none"},children:"Execution Prompt"}),l.executionPrompt?e.jsx("pre",{className:"run-output-panel",children:l.executionPrompt}):e.jsx("div",{className:"text-muted run-output-empty",children:"Execution prompt not captured for this run"})]})}),l.usageJson&&e.jsxs("div",{className:"run-output-section",children:[e.jsx("div",{className:"run-output-label",children:"Token Usage"}),J(l.usageJson)]}),l.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:l.stdoutExcerpt.length>2e3?`${l.stdoutExcerpt.slice(0,2e3)}
17
-
18
- ... (truncated, ${l.stdoutExcerpt.length} chars total)`:l.stdoutExcerpt})]}),l.stderrExcerpt&&e.jsxs("div",{className:"run-output-section",children:[e.jsx("div",{className:"run-output-label run-output-label--error",children:"Errors"}),e.jsx("pre",{className:"run-output-panel run-output-panel--error",children:l.stderrExcerpt})]}),l.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(l.resultJson,null,2)})]}),l.contextSnapshot&&Object.keys(l.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(l.contextSnapshot).map(([P,v])=>e.jsxs("span",{className:"run-context-item",children:[e.jsxs("span",{className:"text-muted",children:[P,":"]})," ",e.jsx("span",{children:String(v)})]},P))})]}),!l.stdoutExcerpt&&!l.stderrExcerpt&&!l.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"}),L?e.jsxs("div",{className:"run-details-loading-state",children:[e.jsx(_,{size:14,className:"animate-spin"}),e.jsx("span",{className:"text-muted",children:"Loading logs..."})]}):f.length===0?e.jsx("div",{className:"text-muted run-output-empty",children:"No logs available for this run"}):e.jsx(pt,{entries:f,loading:!1})]})]})]},u.id)};return e.jsxs("div",{className:"runs-tab",children:[I&&e.jsxs("div",{style:{padding:"12px 16px",borderBottom:"1px solid var(--border-color)",display:"flex",justifyContent:"space-between",alignItems:"center"},children:[e.jsxs("span",{style:{fontSize:"12px",color:"var(--text-secondary)"},children:[r.length," run",r.length!==1?"s":"",R&&e.jsxs("span",{className:"run-live-indicator",style:{marginLeft:"8px"},children:[e.jsx("span",{className:"live-dot"}),"Live"]})]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[R&&e.jsxs("button",{className:"btn btn--sm btn--danger",onClick:()=>void G(),"aria-label":`Stop active run for ${d??a}`,children:[e.jsx(ve,{size:14})," Stop Run"]}),e.jsxs("button",{className:"btn btn--sm btn-task-create",onClick:()=>void U(),"aria-label":`Run now for ${d??a}`,children:[e.jsx(Me,{size:14})," Run Now"]})]})]}),W.map((u,C)=>S(u,C,!0)),h.map((u,C)=>S(u,W.length+C,!1))]})}function Jt(s,a){const i=Math.floor((a.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 Gt={triage:"Triage",todo:"Todo","in-progress":"In Progress","in-review":"In Review",done:"Done",archived:"Archived"};function Wt(s){const a=s.title?.trim()||s.description?.trim()||s.id;return a.length>80?`${a.slice(0,77)}...`:a}function qt({agentId:s,projectId:a,addToast:i}){const[o,d]=t.useState([]),[r,b]=t.useState(!0);return t.useEffect(()=>{let m=!1;return b(!0),lt(s,a).then(j=>{m||d(j)}).catch(j=>{m||(d([]),i(`Failed to load assigned tasks: ${q(j)}`,"error"))}).finally(()=>{m||b(!1)}),()=>{m=!0}},[s,a,i]),r?e.jsxs("div",{className:"agent-tasks-empty",children:[e.jsx(_,{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(Ts,{size:18}),e.jsx("p",{children:"No tasks assigned to this agent"})]}):e.jsx("div",{className:"agent-tasks-list",children:o.map(m=>e.jsxs("a",{className:"agent-task-item",href:`/tasks/${m.id}`,children:[e.jsxs("div",{className:"agent-task-row",children:[e.jsx("span",{className:"agent-task-id",children:m.id}),e.jsx("span",{className:`agent-task-column column-${m.column}`,children:Gt[m.column]})]}),e.jsx("div",{className:"agent-task-title",title:m.title||m.description||m.id,children:Wt(m)}),e.jsxs("div",{className:"agent-task-status",children:[m.status??"idle"," · Updated ",je(m.updatedAt)]})]},m.id))})}const pe=[{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 Yt(s){const a={};for(const i of pe){const o=s[i.key]?.trim();if(o){if(i.type==="number"){const d=Number(o);if(Number.isNaN(d)||!Number.isFinite(d)){a[i.key]=`"${i.label}" must be a valid number`;continue}i.min!==void 0&&d<i.min&&(a[i.key]=`"${i.label}" must be at least ${i.min.toLocaleString()}`),i.max!==void 0&&d>i.max&&(a[i.key]=`"${i.label}" must be at most ${i.max.toLocaleString()}`)}if(i.type==="select"){const d=i.options?.map(r=>r.value)??[];d.length>0&&!d.includes(o)&&(a[i.key]=`"${i.label}" must be one of: ${d.join(", ")}`)}}}return a}function Kt({agent:s,projectId:a,addToast:i,onSaved:o}){const[d,r]=t.useState(s.soul??""),[b,m]=t.useState(!1),[j,x]=t.useState(!1),[y,A]=t.useState(!1);t.useEffect(()=>{r(s.soul??""),x(!1),A(!1)},[s.id,s.soul]);const f=d!==(s.soul??""),B=async()=>{if(d.length>1e4){i("Soul must be at most 10,000 characters","error");return}m(!0);try{await vt(s.id,d,a),i("Soul saved","success"),x(!0),setTimeout(()=>x(!1),3e3),await o()}catch(L){i(`Failed to save soul: ${q(L)}`,"error")}finally{m(!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 ${y?"":"btn-primary"}`,onClick:()=>A(!1),disabled:!y,"aria-label":"Edit mode",children:[e.jsx(De,{size:14}),"Edit"]}),e.jsxs("button",{className:`btn btn-sm ${y?"btn-primary":""}`,onClick:()=>A(!0),disabled:y,"aria-label":"Preview mode",children:[e.jsx(Ee,{size:14}),"Preview"]})]})}),y?d.trim()?e.jsx("div",{className:"agent-content-preview markdown-body",children:e.jsx(Le,{remarkPlugins:[Pe],children:d})}):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",rows:12,placeholder:"Describe this agent's personality, tone, and behavioral traits...",value:d,onChange:L=>{r(L.target.value),x(!1)},style:{fontFamily:"monospace",fontSize:"0.875rem",resize:"vertical"}}),!y&&e.jsx("span",{className:"config-hint",children:"Defines the agent's character and identity. Max 10,000 characters."})]})}),!y&&e.jsxs("div",{className:"config-actions",children:[e.jsx("button",{className:"btn btn-task-create",disabled:!f||b,onClick:()=>void B(),children:b?e.jsxs(e.Fragment,{children:[e.jsx(_,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(Z,{size:16}),"Save Soul"]})}),!f&&j&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(Z,{size:14}),"Soul saved"]})]})]})})}function Zt({agent:s,projectId:a,addToast:i,onSaved:o}){const[d,r]=t.useState(s.memory??""),[b,m]=t.useState(!1),[j,x]=t.useState(!1),[y,A]=t.useState(!1),[f,B]=t.useState([]),[L,T]=t.useState(!1),[l,p]=t.useState(""),[w,H]=t.useState(""),[D,R]=t.useState(!1),[k,U]=t.useState(!1),[G,I]=t.useState(!1),[F,W]=t.useState(!1),[h,J]=t.useState(""),S=s.state==="running",u=d!==(s.memory??""),C=t.useMemo(()=>f.find(v=>v.path===l),[f,l]),Q=C?Bt[C.layer]:"Select a memory file to view or edit.",c=t.useCallback(async v=>{U(!0);try{const O=await ot(s.id,v,a);p(O.path),H(O.content),R(!1),W(!1)}catch(O){i(`Failed to load agent memory file: ${q(O)}`,"error")}finally{U(!1)}},[s.id,a,i]),E=t.useCallback(async(v="")=>{T(!0);try{const{files:O}=await dt(s.id,a);if(B(O),O.length===0){p(""),H(""),R(!1);return}const le=It(O,v);await c(le)}catch(O){i(`Failed to load memory files: ${q(O)}`,"error"),B([]),p(""),H(""),R(!1)}finally{T(!1)}},[s.id,a,i,c]);t.useEffect(()=>{r(s.memory??""),x(!1),A(!1),J(""),W(!1),E()},[s.id,s.memory,E]);const V=async()=>{if(d.length>5e4){i("Memory must be at most 50,000 characters","error");return}m(!0);try{await jt(s.id,d,a),i("Memory saved","success"),x(!0),setTimeout(()=>x(!1),3e3),await o()}catch(v){i(`Failed to save memory: ${q(v)}`,"error")}finally{m(!1)}},g=async v=>{if(!(!v||v===l)){if(D){J("Save the current file before switching to another file.");return}J(""),await c(v)}},P=async()=>{if(l){I(!0);try{await Nt(s.id,l,w,a),R(!1),W(!0),setTimeout(()=>W(!1),3e3),J(""),await E(l),i("Agent memory file saved","success")}catch(v){i(`Failed to save agent memory file: ${q(v)}`,"error")}finally{I(!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."}),S&&e.jsx("p",{className:"config-hint",style:{marginBottom:12},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",style:{display:"block",marginBottom:8},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:[!S&&e.jsxs("button",{className:`btn btn-sm ${y?"":"btn-primary"}`,onClick:()=>A(!1),disabled:!y,"aria-label":"Edit mode",children:[e.jsx(De,{size:14}),"Edit"]}),e.jsxs("button",{className:`btn btn-sm ${y?"btn-primary":""}`,onClick:()=>A(!0),disabled:y,"aria-label":"Preview mode",children:[e.jsx(Ee,{size:14}),"Preview"]})]})}),y?d.trim()?e.jsx("div",{className:"agent-content-preview markdown-body",children:e.jsx(Le,{remarkPlugins:[Pe],children:d})}):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",rows:10,placeholder:"Durable preferences, operating habits, and context this agent should carry across tasks...",value:d,readOnly:S,onChange:v=>{r(v.target.value),x(!1)},style:{fontFamily:"monospace",fontSize:"0.875rem",resize:"vertical"}}),!y&&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",style:{display:"block",marginBottom:8},children:["Full OpenClaw memory files at ",e.jsxs("code",{children:[".fusion/agent-memory/",s.id,"/"]})," (MEMORY.md, DREAMS.md, and daily notes)."]}),e.jsx("select",{id:"agent-memory-file-select",className:"select",value:l,disabled:L||k||G||f.length===0,onChange:v=>{g(v.target.value)},children:f.length===0?e.jsx("option",{value:"",children:"No memory files found"}):f.map(v=>e.jsxs("option",{value:v.path,children:[js[v.layer]," • ",v.label]},v.path))}),L&&e.jsxs("span",{className:"config-hint",style:{display:"inline-flex",gap:6,marginTop:8},children:[e.jsx(_,{size:14,className:"animate-spin"}),"Loading memory files…"]}),C&&e.jsxs("div",{className:"config-hint",style:{marginTop:8},children:[e.jsx("strong",{children:js[C.layer]})," · ",Q,e.jsx("br",{}),C.size.toLocaleString()," bytes · Updated ",je(C.updatedAt)]}),e.jsx("textarea",{className:"input",rows:14,placeholder:"Select a memory file to view and edit its content...",value:w,readOnly:S||!l||k,onChange:v=>{H(v.target.value),R(!0),W(!1),J("")},style:{fontFamily:"monospace",fontSize:"0.875rem",resize:"vertical",marginTop:8}}),k&&e.jsxs("span",{className:"config-hint",style:{display:"inline-flex",gap:6,marginTop:8},children:[e.jsx(_,{size:14,className:"animate-spin"}),"Loading file content…"]}),h&&e.jsx("span",{className:"config-hint",style:{display:"block",marginTop:8},children:h})]})]}),e.jsxs("div",{className:"config-actions",children:[!y&&e.jsx("button",{className:"btn btn-task-create",disabled:!u||b||S,onClick:()=>void V(),children:b?e.jsxs(e.Fragment,{children:[e.jsx(_,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(Z,{size:16}),"Save Memory"]})}),e.jsx("button",{className:"btn",disabled:!D||G||!l||S,onClick:()=>void P(),children:G?e.jsxs(e.Fragment,{children:[e.jsx(_,{size:16,className:"animate-spin"}),"Saving file…"]}):e.jsxs(e.Fragment,{children:[e.jsx(Z,{size:16}),"Save Memory File"]})}),!u&&j&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(Z,{size:14}),"Memory saved"]}),!D&&F&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(Z,{size:14}),"Memory file saved"]})]})]})})}function Qt({agent:s,projectId:a,addToast:i,onSaved:o}){const[d,r]=t.useState(s.instructionsText??""),[b,m]=t.useState(s.instructionsPath??""),[j,x]=t.useState(!1),[y,A]=t.useState(""),[f,B]=t.useState(!1),[L,T]=t.useState(!1),[l,p]=t.useState(!1),[w,H]=t.useState(!1),[D,R]=t.useState(!1),[k,U]=t.useState(!1);t.useEffect(()=>{const h=b.trim();if(!h){A(""),T(!1);return}B(!0),Fs("project",h).then(J=>{A(J.content),T(!1)}).catch(J=>{const S=q(J);S.includes("ENOENT")||S.includes("Not found")||S.includes("not found")?(A(""),T(!1)):(i(`Failed to load instructions file: ${S}`,"error"),A(""))}).finally(()=>{B(!1)})},[b,i]),t.useEffect(()=>{r(s.instructionsText??""),m(s.instructionsPath??""),R(!1),U(!1),x(!1)},[s.id,s.instructionsText,s.instructionsPath]);const G=(()=>{const h=d??"",J=s.instructionsText??"",S=b?.trim()??"",u=s.instructionsPath?.trim()??"";return h!==J||S!==u})(),I=async()=>{p(!0);try{await bt(s.id,{instructionsText:d||void 0,instructionsPath:b.trim()||void 0},a),i("Instructions saved","success"),R(!0),setTimeout(()=>R(!1),3e3),await o()}catch(h){i(`Failed to save instructions: ${q(h)}`,"error")}finally{p(!1)}},F=async()=>{const h=b.trim();if(!h){i("No instructions file path set","error");return}H(!0);try{await Ms("project",h,y),i("Instructions file saved","success"),T(!1),U(!0),setTimeout(()=>U(!1),3e3)}catch(J){i(`Failed to save instructions file: ${q(J)}`,"error")}finally{H(!1)}},W=!!b.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 ${j?"":"btn-primary"}`,onClick:()=>x(!1),disabled:!j,"aria-label":"Edit mode","data-testid":"instructions-edit-toggle",children:[e.jsx(De,{size:14}),"Edit"]}),e.jsxs("button",{className:`btn btn-sm ${j?"btn-primary":""}`,onClick:()=>x(!0),disabled:j,"aria-label":"Preview mode","data-testid":"instructions-preview-toggle",children:[e.jsx(Ee,{size:14}),"Preview"]})]})}),j?d.trim()?e.jsx("div",{className:"agent-content-preview markdown-body",children:e.jsx(Le,{remarkPlugins:[Pe],children:d})}):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:d,onChange:h=>{r(h.target.value),R(!1)},style:{fontFamily:"monospace",fontSize:"0.875rem",resize:"vertical"}}),!j&&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:b,onChange:h=>{m(h.target.value),R(!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."})]})]}),!j&&e.jsxs("div",{className:"config-actions",children:[e.jsx("button",{className:"btn btn-task-create",disabled:!G||l,onClick:()=>void I(),children:l?e.jsxs(e.Fragment,{children:[e.jsx(_,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(Z,{size:16}),"Save Instructions"]})}),!G&&D&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(Z,{size:14}),"Instructions saved"]})]})]}),W&&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",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"8px"},children:[e.jsx("label",{htmlFor:"instructions-file-content",children:"File Content"}),f&&e.jsxs("span",{className:"config-hint",style:{display:"flex",alignItems:"center",gap:"4px"},children:[e.jsx(_,{size:12,className:"animate-spin"}),"Loading..."]}),L&&!f&&e.jsx("span",{className:"config-hint",style:{color:"var(--color-warning, #e3b541)"},children:"Unsaved changes"})]}),e.jsx("textarea",{id:"instructions-file-content",className:"input",rows:20,placeholder:"File content will appear here when loaded...",value:y,readOnly:f,onChange:h=>{A(h.target.value),T(!0),U(!1)},style:{fontFamily:"monospace",fontSize:"0.875rem",resize:"vertical"}}),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:!L||w,onClick:()=>void F(),children:w?e.jsxs(e.Fragment,{children:[e.jsx(_,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(Z,{size:16}),"Save File"]})}),!L&&k&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(Z,{size:14}),"File saved"]})]})]})]})}function Ns(s){const a=s??{},i={};return a.heartbeatIntervalMs!==void 0&&a.heartbeatIntervalMs!==null&&(i.heartbeatIntervalMs=String(Number(a.heartbeatIntervalMs)/1e3)),a.heartbeatTimeoutMs!==void 0&&a.heartbeatTimeoutMs!==null&&(i.heartbeatTimeoutMs=String(Number(a.heartbeatTimeoutMs)/1e3)),a.maxConcurrentRuns!==void 0&&a.maxConcurrentRuns!==null&&(i.maxConcurrentRuns=String(a.maxConcurrentRuns)),(a.messageResponseMode==="immediate"||a.messageResponseMode==="on-heartbeat")&&(i.messageResponseMode=a.messageResponseMode),i}function Ve(s){return s?.enabled!==!1}function ys(s){const a=(s??{}).budgetConfig,i={};return a&&(a.tokenBudget!==void 0&&a.tokenBudget!==null&&(i.tokenBudget=String(a.tokenBudget)),a.usageThreshold!==void 0&&a.usageThreshold!==null&&(i.usageThreshold=String(Number(a.usageThreshold)*100)),a.budgetPeriod!==void 0&&a.budgetPeriod!==null&&(i.budgetPeriod=String(a.budgetPeriod)),a.resetDay!==void 0&&a.resetDay!==null&&(i.resetDay=String(a.resetDay))),i}function Xt({agent:s,projectId:a,addToast:i,onSaved:o}){const[d,r]=t.useState(!1),[b,m]=t.useState(!1),[j,x]=t.useState(!1),[y,A]=t.useState(!1),[f,B]=t.useState(!1),[L,T]=t.useState(""),[l,p]=t.useState(!1),[w,H]=t.useState(null),[D,R]=t.useState(!1),k=s.heartbeatProcedurePath?.trim(),U=`.fusion/agents/${s.id}/HEARTBEAT.md`,G=k===U,I=!!k,F=t.useCallback(async S=>{x(!0),H(null);try{const u=await Fs("project",S,a);T(u.content),p(!1)}catch(u){const C=q(u);H(C),i(`Failed to load heartbeat procedure file: ${C}`,"error")}finally{x(!1)}},[i,a]);t.useEffect(()=>{m(!1),B(!1),T(""),p(!1),H(null),x(!1),A(!1),R(!1)},[s.id,k]);const W=async()=>{k&&(m(!0),await F(k))},h=async()=>{if(k){A(!0);try{await Ms("project",k,L,a),p(!1),R(!0),i("Heartbeat procedure file saved","success"),setTimeout(()=>R(!1),3e3)}catch(S){i(`Failed to save heartbeat procedure file: ${q(S)}`,"error")}finally{A(!1)}}},J=async()=>{r(!0);try{const S=await Ct(s.id,a);i(S.procedureFileSeeded?`Heartbeat procedure file ready at ${S.heartbeatProcedurePath}`:`Heartbeat procedure path set to ${S.heartbeatProcedurePath}`,"success"),await o()}catch(S){i(`Failed to upgrade heartbeat procedure: ${q(S)}`,"error")}finally{r(!1)}};return e.jsxs("div",{className:"config-section",children:[e.jsx("h3",{children:"Heartbeat Procedure"}),e.jsx("p",{className:"config-description",children:"The per-tick procedure this agent runs every wake. Defaults to a project-level markdown file you can edit. 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:k||"(none — using built-in default)"})]}),I&&e.jsx("div",{className:"heartbeat-procedure-actions",children:e.jsx("button",{className:"btn btn-sm",onClick:()=>void W(),disabled:j,children:j?e.jsxs(e.Fragment,{children:[e.jsx(_,{size:16,className:"animate-spin"}),"Loading file…"]}):e.jsxs(e.Fragment,{children:[e.jsx(be,{size:16}),"View Heartbeat Markdown"]})})})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("button",{className:"btn",disabled:d||G,onClick:()=>void J(),"aria-label":"Upgrade agent to default heartbeat procedure file",children:d?e.jsxs(e.Fragment,{children:[e.jsx(_,{size:16,className:"animate-spin"}),"Upgrading…"]}):G?e.jsxs(e.Fragment,{children:[e.jsx(Z,{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:U})," ","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."]})]})]}),b&&I&&k&&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 ${f?"":"btn-primary"}`,onClick:()=>B(!1),disabled:!f,"aria-label":"Heartbeat file edit mode",children:[e.jsx(De,{size:14}),"Edit"]}),e.jsxs("button",{className:`btn btn-sm ${f?"btn-primary":""}`,onClick:()=>B(!0),disabled:f,"aria-label":"Heartbeat file preview mode",children:[e.jsx(Ee,{size:14}),"Preview"]})]}),j&&e.jsxs("span",{className:"config-hint heartbeat-procedure-status",children:[e.jsx(_,{size:12,className:"animate-spin"}),"Loading..."]}),l&&!j&&e.jsx("span",{className:"config-hint heartbeat-procedure-status heartbeat-procedure-status--warning",children:"Unsaved changes"})]}),f?L.trim()?e.jsx("div",{className:"agent-content-preview markdown-body",children:e.jsx(Le,{remarkPlugins:[Pe],children:L})}):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:L,readOnly:j,placeholder:"Heartbeat procedure markdown file content will appear here...",onChange:S=>{T(S.target.value),p(!0),R(!1)}}),w&&e.jsxs("span",{className:"config-error",children:["Failed to load file: ",w]}),e.jsxs("span",{className:"config-hint",children:["This editor writes directly to ",e.jsx("code",{children:k}),"."]})]}),!f&&e.jsxs("div",{className:"config-actions",children:[e.jsx("button",{className:"btn btn-task-create",disabled:!l||y||j,onClick:()=>void h(),children:y?e.jsxs(e.Fragment,{children:[e.jsx(_,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(Z,{size:16}),"Save Heartbeat File"]})}),!l&&D&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(Z,{size:14}),"File saved"]})]})]})]})}function ea({agent:s,projectId:a,addToast:i,onSaved:o,onHasChangesChange:d,onDelete:r}){const[b,m]=t.useState(s.name),[j,x]=t.useState(s.role),[y,A]=t.useState(s.title??""),[f,B]=t.useState(s.icon??""),[L,T]=t.useState(s.reportsTo??""),[l,p]=t.useState([]),[w,H]=t.useState(!1),[D,R]=t.useState(()=>{const n={};for(const M of pe){const z=s.metadata[M.key];z!=null&&(n[M.key]=String(z))}return n}),[k,U]=t.useState(()=>Ns(s.runtimeConfig)),[G,I]=t.useState(()=>Ve(s.runtimeConfig)),[F,W]=t.useState(()=>ys(s.runtimeConfig)),[h,J]=t.useState(s.bundleConfig?.mode??""),[S,u]=t.useState(s.bundleConfig?.entryFile??"AGENTS.md"),[C,Q]=t.useState(s.bundleConfig?.externalPath??""),[c,E]=t.useState(s.bundleConfig?.files??[]),[V,g]=t.useState(Array.isArray(s.metadata?.skills)?s.metadata.skills:[]),[P,v]=t.useState([]),[O,le]=t.useState(!1),[Ne,de]=t.useState([]),[$e,Ke]=t.useState(!1),ye=(()=>{const n=s.runtimeConfig??{};return n.modelProvider&&n.modelId?`${n.modelProvider}/${n.modelId}`:typeof n.model=="string"&&n.model.includes("/")?n.model:""})(),ce=typeof s.runtimeConfig?.runtimeHint=="string"?s.runtimeConfig.runtimeHint:"",[ae,ze]=t.useState(ce?"runtime":"model"),[oe,Ze]=t.useState(ye),[Se,Be]=t.useState(ce),ke=L.trim(),Qe=t.useMemo(()=>l.filter(n=>n.id!==s.id),[l,s.id]),Ds=!!ke&&!Qe.some(n=>n.id===ke);t.useEffect(()=>{let n=!1;return H(!0),ut(void 0,a).then(M=>{n||p(M)}).catch(()=>{n||p([])}).finally(()=>{n||H(!1)}),()=>{n=!0}},[a]),t.useEffect(()=>{le(!0),mt().then(n=>v(n.models)).catch(()=>{}).finally(()=>le(!1))},[]),t.useEffect(()=>{Ke(!0),Rs(a).then(de).catch(()=>de([])).finally(()=>Ke(!1))},[a]);const[ne,He]=t.useState(null),[Xe,es]=t.useState(!1);t.useEffect(()=>{Ue(s.id,a).then(He).catch(()=>He(null))},[s.id,a]);const Es=async()=>{es(!0);try{await St(s.id,a),i("Budget usage reset successfully","success");const n=await Ue(s.id,a);He(n)}catch(n){i(`Failed to reset budget: ${q(n)}`,"error")}finally{es(!1)}},[ss,ts]=t.useState(!1),[$,Ce]=t.useState({}),[Ls,ue]=t.useState(!1),as=s.state==="idle"||s.state==="terminated",he=t.useRef(null),ns=t.useRef(null);t.useEffect(()=>()=>{he.current&&clearTimeout(he.current)},[]);const ie=(()=>{if(b!==s.name||j!==s.role||y!==(s.title??"")||f!==(s.icon??"")||L!==(s.reportsTo??"")||h!==(s.bundleConfig?.mode??"")||S!==(s.bundleConfig?.entryFile??"AGENTS.md")||C!==(s.bundleConfig?.externalPath??"")||JSON.stringify(c)!==JSON.stringify(s.bundleConfig?.files??[]))return!0;for(const K of pe){const re=D[K.key]?.trim()??"",X=s.metadata[K.key]!==void 0&&s.metadata[K.key]!==null?String(s.metadata[K.key]):"";if(re!==X)return!0}const n=s.runtimeConfig??{};if(G!==Ve(s.runtimeConfig))return!0;for(const K of["heartbeatIntervalMs","heartbeatTimeoutMs","maxConcurrentRuns","messageResponseMode"]){const re=k[K]?.trim()??"";let X=n[K]!==void 0&&n[K]!==null?String(n[K]):"";if((K==="heartbeatIntervalMs"||K==="heartbeatTimeoutMs")&&X&&(X=String(Number(X)/1e3)),re!==X)return!0}const M=n.budgetConfig;for(const K of["tokenBudget","budgetPeriod","resetDay"]){const re=F[K]?.trim()??"",X=M?.[K]!==void 0&&M?.[K]!==null?String(M[K]):"";if(re!==X)return!0}const z=F.usageThreshold?.trim()??"",se=M?.usageThreshold!==void 0&&M?.usageThreshold!==null?String(Number(M.usageThreshold)*100):"";if(z!==se)return!0;const ge=Array.isArray(s.metadata?.skills)?s.metadata.skills:[];return JSON.stringify(V)!==JSON.stringify(ge)||ae!==(ce?"runtime":"model")||oe!==ye||Se!==ce})(),is=t.useRef(null);t.useEffect(()=>{d&&is.current!==ie&&(is.current=ie,d(ie))},[ie,d]),t.useEffect(()=>()=>{d?.(!1)},[d]),t.useEffect(()=>{const n={id:s.id,updatedAt:s.updatedAt},M=ns.current;(!M||M.id!==n.id||M.updatedAt!==n.updatedAt)&&(ie||(ns.current=n,U(Ns(s.runtimeConfig)),I(Ve(s.runtimeConfig)),W(ys(s.runtimeConfig)),Ze(ye),Be(ce),ze(ce?"runtime":"model")))},[s,ie,ye,ce]);const rs=(n,M)=>{R(z=>({...z,[n]:M})),ue(!1),$[n]&&Ce(z=>{const se={...z};return delete se[n],se})},we=(n,M)=>{U(z=>({...z,[n]:M})),ue(!1),$[n]&&Ce(z=>{const se={...z};return delete se[n],se})},Ps=n=>{I(n),ue(!1)},Re=(n,M)=>{W(z=>({...z,[n]:M})),ue(!1),$[n]&&Ce(z=>{const se={...z};return delete se[n],se})},$s=async()=>{const n=Yt(D);for(const[N,te]of Object.entries({heartbeatIntervalMs:{label:"Heartbeat Interval",min:1},heartbeatTimeoutMs:{label:"Heartbeat Timeout",min:5},maxConcurrentRuns:{label:"Max Concurrent Runs",min:1}})){const fe=k[N]?.trim();if(!fe)continue;const Oe=Number(fe);Number.isNaN(Oe)||!Number.isFinite(Oe)?n[N]=`"${te.label}" must be a valid number`:Oe<te.min&&(n[N]=`"${te.label}" must be at least ${te.min.toLocaleString()}`)}const M=k.messageResponseMode?.trim();M&&!["immediate","on-heartbeat"].includes(M)&&(n.messageResponseMode='"Message Response Mode" must be either immediate or on-heartbeat');const z=F.tokenBudget?.trim();if(z){const N=Number(z);Number.isNaN(N)||!Number.isFinite(N)?n.tokenBudget='"Token Budget" must be a valid number':N<=0&&(n.tokenBudget='"Token Budget" must be greater than 0')}const se=F.usageThreshold?.trim();if(se){const N=Number(se);Number.isNaN(N)||!Number.isFinite(N)?n.usageThreshold='"Usage Threshold" must be a valid number':(N<1||N>100)&&(n.usageThreshold='"Usage Threshold" must be between 1 and 100')}const ge=F.budgetPeriod?.trim();ge&&!["daily","weekly","monthly","lifetime"].includes(ge)&&(n.budgetPeriod='"Budget Period" must be one of: daily, weekly, monthly, lifetime');const K=F.resetDay?.trim(),re=ge||"lifetime";if(K){const N=Number(K);Number.isNaN(N)||!Number.isFinite(N)?n.resetDay='"Reset Day" must be a valid number':re==="weekly"?(N<0||N>6||!Number.isInteger(N))&&(n.resetDay='"Reset Day" must be between 0 (Sunday) and 6 (Saturday) for weekly period'):re==="monthly"&&(N<1||N>31||!Number.isInteger(N))&&(n.resetDay='"Reset Day" must be between 1 and 31 for monthly period')}if(Object.keys(n).length>0){Ce(n),i("Please fix validation errors before saving","error");return}const X={...s.metadata};for(const N of pe){const te=D[N.key]?.trim();te?N.type==="number"?X[N.key]=Number(te):X[N.key]=te:delete X[N.key]}V.length>0?X.skills=V:delete X.skills;const Y={...s.runtimeConfig};Y.enabled=G;for(const N of["heartbeatIntervalMs","heartbeatTimeoutMs","maxConcurrentRuns"]){const te=k[N]?.trim();if(!te)delete Y[N];else{const fe=Number(te);Y[N]=N==="maxConcurrentRuns"?fe:fe*1e3}}const ls=k.messageResponseMode?.trim();if(ls?Y.messageResponseMode=ls:delete Y.messageResponseMode,ae==="runtime")Se.trim()?Y.runtimeHint=Se.trim():delete Y.runtimeHint,delete Y.modelProvider,delete Y.modelId,delete Y.model;else if(delete Y.runtimeHint,oe.trim()){const N=oe.indexOf("/");N!==-1&&(Y.modelProvider=oe.slice(0,N),Y.modelId=oe.slice(N+1),Y.model=oe.trim())}else delete Y.modelProvider,delete Y.modelId,delete Y.model;const me={},cs=F.tokenBudget?.trim(),os=F.usageThreshold?.trim(),ds=F.budgetPeriod?.trim(),us=F.resetDay?.trim();cs&&(me.tokenBudget=Number(cs)),os&&(me.usageThreshold=Number(os)/100),ds&&(me.budgetPeriod=ds),us&&(me.resetDay=Number(us)),Object.keys(me).length>0?Y.budgetConfig=me:delete Y.budgetConfig;let Ie;h&&(Ie={mode:h,entryFile:S||"AGENTS.md",files:c.length>0?c:["AGENTS.md"]},h==="external"&&C.trim()&&(Ie.externalPath=C.trim())),ts(!0);try{await kt(s.id,{name:b.trim()||void 0,role:j,title:y.trim()||void 0,icon:f.trim()||void 0,reportsTo:L.trim()||void 0,metadata:X,runtimeConfig:Y,bundleConfig:Ie},a),i("Settings saved","success"),ue(!0),he.current&&clearTimeout(he.current),he.current=setTimeout(()=>ue(!1),3e3),await o()}catch(N){i(`Failed to save settings: ${q(N)}`,"error")}finally{ts(!1)}};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.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:b,onChange:n=>m(n.target.value)})]}),e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"agent-role",children:"Role"}),e.jsxs("select",{id:"agent-role",className:"select",value:j,onChange:n=>x(n.target.value),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:y,onChange:n=>A(n.target.value)})]}),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:f,onChange:n=>B(n.target.value)})]}),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:L,onChange:n=>T(n.target.value),disabled:w,children:[e.jsx("option",{value:"",children:"No manager"}),Ds&&e.jsxs("option",{value:ke,children:["Unknown manager (",ke,")"]}),Qe.map(n=>e.jsxs("option",{value:n.id,children:[n.name," (",n.id,")"]},n.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(wt,{id:"agent-skills",label:"Skills",value:V,onChange:g,projectId:a})})})]}),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${ae==="model"?" active":""}`,role:"tab","aria-selected":ae==="model",tabIndex:ae==="model"?0:-1,onClick:()=>{ze("model"),Be("")},children:"Built-in Model"}),e.jsx("button",{type:"button",className:`config-runtime-tab${ae==="runtime"?" active":""}`,role:"tab","aria-selected":ae==="runtime",tabIndex:ae==="runtime"?0:-1,onClick:()=>ze("runtime"),children:"Plugin Runtime"})]})]}),ae==="model"?e.jsx("div",{className:"config-field",children:e.jsx(ht,{models:P,value:oe,onChange:Ze,placeholder:"Use global default",label:"Agent Model",disabled:O})}):e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:"agent-runtime-hint",children:"Runtime"}),$e?e.jsx("span",{className:"config-hint",children:"Loading runtimes…"}):e.jsxs("select",{id:"agent-runtime-hint",className:"select",value:Se,onChange:n=>Be(n.target.value),children:[e.jsx("option",{value:"",children:Ne.length>0?"Select a plugin runtime…":"No plugin runtimes available"}),Ne.map(n=>e.jsx("option",{value:n.runtimeId,children:n.description?`${n.name} — ${n.description}`:n.name},`${n.pluginId}:${n.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:G,onChange:n=>Ps(n.target.checked)}),"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.jsx("label",{htmlFor:"hb-heartbeatIntervalMs",children:"Heartbeat Interval (s)"}),e.jsx("input",{id:"hb-heartbeatIntervalMs",type:"text",inputMode:"numeric",className:ee("input",!!$.heartbeatIntervalMs&&"input--error"),placeholder:String(Je/1e3),value:k.heartbeatIntervalMs??"",onChange:n=>we("heartbeatIntervalMs",n.target.value)}),$.heartbeatIntervalMs?e.jsx("span",{className:"config-error",children:$.heartbeatIntervalMs}):e.jsxs("span",{className:"config-hint",children:["How often heartbeats are checked. Leave empty for system default (",Je/1e3,"s / ",Ht,")."]})]}),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:ee("input",!!$.heartbeatTimeoutMs&&"input--error"),placeholder:"60",value:k.heartbeatTimeoutMs??"",onChange:n=>we("heartbeatTimeoutMs",n.target.value)}),$.heartbeatTimeoutMs?e.jsx("span",{className:"config-error",children:$.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:ee("input",!!$.maxConcurrentRuns&&"input--error"),placeholder:"1",value:k.maxConcurrentRuns??"",onChange:n=>we("maxConcurrentRuns",n.target.value)}),$.maxConcurrentRuns?e.jsx("span",{className:"config-error",children:$.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:ee("select",!!$.messageResponseMode&&"input--error"),value:k.messageResponseMode??"",onChange:n=>we("messageResponseMode",n.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"})]}),$.messageResponseMode?e.jsx("span",{className:"config-error",children:$.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:ee("input",!!$.tokenBudget&&"input--error"),placeholder:"No limit",value:F.tokenBudget??"",onChange:n=>Re("tokenBudget",n.target.value)}),$.tokenBudget?e.jsx("span",{className:"config-error",children:$.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:ee("input",!!$.usageThreshold&&"input--error"),placeholder:"80",value:F.usageThreshold??"",onChange:n=>Re("usageThreshold",n.target.value)}),$.usageThreshold?e.jsx("span",{className:"config-error",children:$.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:ee("select",!!$.budgetPeriod&&"input--error"),value:F.budgetPeriod??"",onChange:n=>Re("budgetPeriod",n.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"})]}),$.budgetPeriod?e.jsx("span",{className:"config-error",children:$.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:ee("input",!!$.resetDay&&"input--error"),placeholder:"Auto",value:F.resetDay??"",onChange:n=>Re("resetDay",n.target.value)}),$.resetDay?e.jsx("span",{className:"config-error",children:$.resetDay}):e.jsx("span",{className:"config-hint",children:F.budgetPeriod==="weekly"?"Day of week (0=Sunday to 6=Saturday) for reset.":F.budgetPeriod==="monthly"?"Day of month (1-31) for reset.":"Day for reset (weekly: 0-6, monthly: 1-31). Leave empty for automatic."})]}),ne?.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:ee("budget-progress-bar__fill",(ne.usagePercent??0)>=100?"budget-progress-bar__fill--red":(ne.usagePercent??0)>=80?"budget-progress-bar__fill--amber":"budget-progress-bar__fill--green"),style:{width:`${Math.min(ne.usagePercent??0,100)}%`}})}),e.jsxs("span",{className:"budget-progress-label",children:[(ne.currentUsage??0).toLocaleString()," / ",(ne.budgetLimit??0).toLocaleString()," tokens (",Math.round(ne.usagePercent??0),"% used)"]})]})]}),ne?.budgetLimit!=null&&e.jsx("div",{className:"config-field",children:e.jsx("button",{className:"btn btn-reset-budget",onClick:()=>void Es(),disabled:Xe,children:Xe?e.jsxs(e.Fragment,{children:[e.jsx(_,{size:14,className:"animate-spin"}),"Resetting…"]}):e.jsxs(e.Fragment,{children:[e.jsx(We,{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:h,onChange:n=>J(n.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:[h==="managed"&&"Files will be stored in a system-managed directory within .fusion/agents/",h==="external"&&"Specify an external directory path for the instruction files",!h&&"Select a mode to enable instruction bundling"]})]}),h&&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:S,onChange:n=>u(n.target.value)}),e.jsx("span",{className:"config-hint",children:"Primary instructions file name (default: AGENTS.md)"})]}),h==="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:C,onChange:n=>Q(n.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:c.join(", "),onChange:n=>E(n.target.value.split(",").map(M=>M.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:pe.map(n=>{const M=!!$[n.key];return e.jsxs("div",{className:"config-field",children:[e.jsx("label",{htmlFor:`adv-${n.key}`,children:n.label}),n.type==="select"?e.jsxs("select",{id:`adv-${n.key}`,className:ee("select",M&&"input--error"),value:D[n.key]??"",onChange:z=>rs(n.key,z.target.value),children:[e.jsx("option",{value:"",children:"System Default"}),n.options?.map(z=>e.jsx("option",{value:z.value,children:z.label},z.value))]}):e.jsx("input",{id:`adv-${n.key}`,type:"text",inputMode:n.type==="number"?"numeric":void 0,className:ee("input",M&&"input--error"),placeholder:n.placeholder,value:D[n.key]??"",onChange:z=>rs(n.key,z.target.value)}),M&&e.jsx("span",{className:"config-error",children:$[n.key]}),!M&&n.hint&&e.jsx("span",{className:"config-hint",children:n.hint})]},n.key)})}),e.jsxs("div",{className:"config-actions",children:[e.jsx("button",{className:"btn btn-task-create",disabled:!ie||ss,onClick:()=>void $s(),children:ss?e.jsxs(e.Fragment,{children:[e.jsx(_,{size:16,className:"animate-spin"}),"Saving…"]}):e.jsxs(e.Fragment,{children:[e.jsx(Z,{size:16}),"Save Settings"]})}),!ie&&Ls&&e.jsxs("span",{className:"config-saved-indicator",children:[e.jsx(Z,{size:14}),"Settings saved"]})]})]}),e.jsx(Xt,{agent:s,projectId:a,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:!as||!r,onClick:()=>void r?.(),children:[e.jsx(Te,{size:16}),"Delete Agent"]}),e.jsx("span",{className:"config-danger-note",children:as?"Deletion is permanent and cannot be undone.":`Agent deletion is only available when state is idle or terminated (current state: ${s.state}).`})]})})]})]})}function sa({agentId:s,projectId:a,onChildClick:i}){const[o,d]=t.useState([]),[r,b]=t.useState(!0);return t.useEffect(()=>{b(!0),ct(s,a).then(d).finally(()=>b(!1))},[s,a]),r?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",style:{display:"flex",alignItems:"center",gap:8,padding:16},children:[e.jsx(_,{size:16,className:"spin"}),e.jsx("span",{className:"text-secondary",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-secondary",children:["(",o.length,")"]})]}),e.jsx("div",{className:"detail-section-body",children:o.length===0?e.jsxs("div",{className:"agent-empty",style:{padding:24},children:[e.jsx(qe,{size:32,opacity:.3}),e.jsx("p",{children:"No employees"}),e.jsx("p",{className:"text-secondary",children:"This agent has no employees"})]}):e.jsx("div",{className:"agent-tree__children",children:o.map(m=>{const j=Ye[m.state];return e.jsxs("div",{className:"agent-tree__node agent-is-child",onClick:()=>i?.(m.id),role:"button",tabIndex:0,onKeyDown:x=>x.key==="Enter"&&i?.(m.id),style:{cursor:i?"pointer":"default"},children:[e.jsx("span",{className:"agent-tree__icon",children:m.icon??"🤖"}),e.jsx("span",{className:"agent-tree__name",children:m.name}),e.jsx("span",{className:"agent-tree__badge",style:{background:j?.bg??"var(--state-idle-bg)",color:j?.text??"var(--state-idle-text)",border:`1px solid ${j?.border??"var(--state-idle-border)"}`},children:m.state})]},m.id)})})})]})}export{ca as AgentDetailView};
@@ -1 +0,0 @@
1
- import{r as s,j as t}from"./vendor-react-K0fH_qHe.js";import{i as ze,aL as Dt,g as Et,aM as Pt,a as Ft,aN as Lt,aO as _t,aP as Ot,aQ as It,aR as Ut,aS as zt,s as Ht,aT as Vt,aU as Bt,aV as qt,aW as Gt,ab as it,ac as rt,S as Wt,V as Xe,J as Ze,ao as Kt,aX as Jt,B as Ee,a8 as lt,a9 as ot,aY as Yt,aZ as Qt,a_ as Xt,a$ as Zt,b0 as es,b1 as ts,b2 as ss,b3 as et,h as ns,u as tt,k as as}from"./index-DmSs2FGE.js";import"./vendor-xterm-DzcZoU0P.js";const Ue="kb-chat-active-session";function is(a){const i=a?.toolCalls;if(!Array.isArray(i))return;const l=i.map(o=>{if(!o||typeof o!="object")return null;const c=o,y=typeof c.toolName=="string"?c.toolName:"";if(!y)return null;const N=c.args;return{toolName:y,...N&&typeof N=="object"?{args:N}:{},isError:!!c.isError,result:c.result,status:"completed"}}).filter(o=>o!==null);return l.length>0?l:void 0}function st(a){return{id:a.id,sessionId:a.sessionId,role:a.role,content:a.content,thinkingOutput:a.thinkingOutput,toolCalls:is(a.metadata),attachments:a.attachments,createdAt:a.createdAt}}function rs(a){const[i,l]=s.useState([]),[o,c]=s.useState(null),[y,N]=s.useState(!0),[$,b]=s.useState([]),[D,z]=s.useState(!1),[p,F]=s.useState(!1),[C,M]=s.useState(""),[g,x]=s.useState(""),[T,k]=s.useState([]),[H,L]=s.useState(""),[ee,K]=s.useState(""),[_,X]=s.useState(!0),[h,j]=s.useState(new Map),v=s.useRef(null),O=s.useRef(!1),V=s.useRef(""),de=s.useRef(null),ue=s.useRef(i),pe=s.useRef(o),xe=s.useRef(p);ue.current=i,pe.current=o,xe.current=p,s.useEffect(()=>{V.current=H},[H]);const ve=s.useRef(new Set),he=s.useRef(0),ye=s.useRef(a);ye.current!==a&&(ye.current=a,he.current++),s.useEffect(()=>{const u=he.current;ze(void 0,a).then(f=>{if(he.current!==u)return;const m=new Map;for(const R of f)m.set(R.id,R);j(m)}).catch(()=>{})},[a]);const J=s.useCallback(async()=>{N(!0);try{const f=[...(await Dt(a)).sessions].sort((m,R)=>new Date(R.updatedAt).getTime()-new Date(m.updatedAt).getTime());l(f)}catch{}finally{N(!1)}},[a]);s.useEffect(()=>{J()},[J]);const se=s.useRef(()=>{});s.useEffect(()=>{if(y)return;const u=Et(Ue,a);u&&i.find(m=>m.id===u)&&se.current(u)},[y,i,a]);const le=s.useCallback(async(u,f)=>{z(!0);try{const m=await Pt(u,{limit:50,...f},a),R=m.messages.map(st);f?.offset&&f.offset>0?b(I=>[...R,...I]):b(R),X(m.messages.length>=50)}catch{}finally{z(!1)}},[a]),ne=s.useCallback((u,f)=>{v.current&&(v.current.close(),v.current=null);const m=f??i.find(R=>R.id===u);c(m||null),M(""),x(""),k([]),F(!1),X(!0),u?le(u):b([]),u?Ft(Ue,u,a):Lt(Ue,a)},[i,le,a]);se.current=ne;const we=s.useCallback(async u=>{const f=await _t(u,a);v.current&&(v.current.close(),v.current=null);const m={id:f.session.id,title:f.session.title,agentId:f.session.agentId,status:f.session.status,modelProvider:f.session.modelProvider,modelId:f.session.modelId,createdAt:f.session.createdAt,updatedAt:f.session.updatedAt};return l(R=>R.some(I=>I.id===m.id)?R:[m,...R]),ne(m.id,m),b([]),m},[a,ne]),me=s.useCallback(async u=>{await Ot(u,{status:"archived"},a),l(f=>f.filter(m=>m.id!==u)),o?.id===u&&(c(null),b([]))},[o,a]),Se=s.useCallback(async u=>{o?.id===u&&v.current&&(v.current.close(),v.current=null),await It(u,a),l(f=>f.filter(m=>m.id!==u)),o?.id===u&&(c(null),b([]))},[o,a]),oe=s.useCallback(async()=>{!o||!_||await le(o.id,{offset:$.length})},[o,_,le,$.length]),te=s.useCallback(()=>{o&&(O.current=!0,de.current?.(),de.current=null,v.current?.close(),v.current=null,Ut(o.id,a).catch(()=>{}),F(!1),M(""),x(""),k([]))},[o,a]),ce=s.useCallback(()=>{V.current="",L("")},[]),fe=s.useCallback((u,f)=>{if(!o)return;if(p){V.current=u,L(u);return}O.current=!1,v.current&&(v.current.close(),v.current=null);const m=`temp-${Date.now()}`,R={id:m,sessionId:o.id,role:"user",content:u,createdAt:new Date().toISOString()};b(w=>[...w,R]),M(""),x(""),k([]),F(!0);let I="",ae="",B=[],Y=null,q=null;const G=()=>{Y=null,M(I)},E=()=>{q=null,x(ae)},d=()=>{Y!==null&&(cancelAnimationFrame(Y),Y=null),q!==null&&(cancelAnimationFrame(q),q=null)};de.current=d;const U={onThinking:w=>{ae+=w,q===null&&(q=requestAnimationFrame(E))},onText:w=>{I+=w,Y===null&&(Y=requestAnimationFrame(G))},onToolStart:w=>{B=[...B,{toolName:w.toolName,args:w.args,isError:!1,status:"running"}],k(B)},onToolEnd:w=>{const S=[...B];for(let W=S.length-1;W>=0;W--){const A=S[W];if(A?.toolName===w.toolName&&A.status==="running"){S[W]={...A,status:"completed",isError:w.isError,result:w.result},B=S,k(S);return}}B=[...S,{toolName:w.toolName,isError:w.isError,result:w.result,status:"completed"}],k(B)},onDone:w=>{d();const S={id:w.messageId||`msg-${Date.now()}`,sessionId:o.id,role:"assistant",content:I,thinkingOutput:ae,toolCalls:B.length>0?B:void 0,createdAt:new Date().toISOString()};ve.current.add(S.id),b(A=>[...A,S]),M(""),x(""),k([]),F(!1),v.current=null,setTimeout(()=>{ve.current.delete(S.id)},1e3),J();const W=V.current.trim();W&&(V.current="",L(""),fe(W))},onError:w=>{if(d(),b(S=>S.filter(W=>W.id!==m)),M(""),x(""),k([]),F(!1),v.current=null,console.error("[useChat] Stream error:",w),!O.current){const S=V.current.trim();S&&(V.current="",L(""),fe(S))}}};v.current=zt(o.id,u,U,f,a)},[o,p,a,J]),be=ee?i.filter(u=>u.title?.toLowerCase().includes(ee.toLowerCase())||u.agentId.toLowerCase().includes(ee.toLowerCase())):i;return s.useEffect(()=>{const u=he.current,f=a?`?projectId=${encodeURIComponent(a)}`:"",m=()=>he.current!==u,R=G=>{if(m())return;const E=JSON.parse(G.data);l(d=>d.some(U=>U.id===E.id)?d:[E,...d])},I=G=>{if(m())return;const E=JSON.parse(G.data);l(d=>[...d.map(w=>w.id===E.id?E:w)]),pe.current?.id===E.id&&c(E)},ae=G=>{if(m())return;const{id:E}=JSON.parse(G.data);l(d=>d.filter(U=>U.id!==E)),pe.current?.id===E&&(c(null),b([]))},B=G=>{if(m())return;const E=JSON.parse(G.data),d=st(E);ve.current.has(d.id)||pe.current?.id===d.sessionId&&!xe.current&&b(U=>U.some(w=>w.id===d.id)?U:[...U,d])},Y=G=>{if(m())return;const{id:E}=JSON.parse(G.data);b(d=>d.filter(U=>U.id!==E))};return Ht(`/api/events${f}`,{events:{"chat:session:created":R,"chat:session:updated":I,"chat:session:deleted":ae,"chat:message:added":B,"chat:message:deleted":Y}})},[a]),s.useEffect(()=>()=>{v.current&&(v.current.close(),v.current=null)},[]),{sessions:i,activeSession:o,sessionsLoading:y,messages:$,messagesLoading:D,isStreaming:p,streamingText:C,streamingThinking:g,streamingToolCalls:T,pendingMessage:H,selectSession:ne,createSession:we,archiveSession:me,deleteSession:Se,sendMessage:fe,stopStreaming:te,clearPendingMessage:ce,loadMoreMessages:oe,hasMoreMessages:_,searchQuery:ee,setSearchQuery:K,filteredSessions:be,refreshSessions:J,agentsMap:h}}function ct(a){const i=new Date(a),o=new Date().getTime()-i.getTime(),c=Math.floor(o/1e3),y=Math.floor(c/60),N=Math.floor(y/60),$=Math.floor(N/24);return c<60?"just now":y<60?`${y}m ago`:N<24?`${N}h ago`:$<7?`${$}d ago`:i.toLocaleDateString()}function nt(a,i){if(!a||!i)return null;const l=i.toLowerCase();if(l.includes("claude")){let c=i.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(l.includes("gpt")||l.includes("openai")){const c=i.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(l.includes("gemini")){const c=i.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 o=i.replace(/-/g," ").replace(/^\w/,c=>c.toUpperCase()).replace(/\s+/g," ").trim();return o.length>30?o.slice(0,30)+"…":o}function Re(a,i){return a.length<=i?a:`${a.slice(0,i)}…`}function ls(a){if(!a)return null;const i=Object.entries(a);return i.length===0?null:i.map(([l,o])=>{const c=typeof o=="string"?o:(()=>{try{return JSON.stringify(o)}catch{return String(o)}})();return`${l}=${Re(c,50)}`}).join(", ")}function os(a){if(a===void 0)return null;if(typeof a=="string")return Re(a,200);try{return Re(JSON.stringify(a),200)}catch{return Re(String(a),200)}}function dt(a){if(!a||a.length===0)return null;const i=(p,F)=>{const C=p.status==="running",M=p.status==="completed"&&p.isError,g=ls(p.args),x=os(p.result),T=C?g:x?`result: ${x}`:g?`args: ${g}`:null,k=C?"running":M?"error":"completed";return t.jsxs("details",{className:`chat-tool-call${C?" chat-tool-call--running":""}${M?" 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",children:p.toolName}),T&&t.jsx("span",{className:"chat-tool-call-preview",title:T,children:T}),t.jsx("span",{className:"chat-tool-call-status-text",children:k})]}),t.jsxs("div",{className:"chat-tool-call-content",children:[g&&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:g})]}),x&&t.jsxs("div",{className:`chat-tool-call-row${M?" 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:x})]})]})]},`${p.toolName}-${F}`)},l="chat-tool-calls";if(a.length===1)return t.jsxs("div",{className:l,"data-testid":"chat-tool-calls",children:[t.jsxs("div",{className:"chat-tool-calls-header",children:[t.jsx(et,{size:12,"aria-hidden":"true"}),t.jsx("span",{children:"Tool calls"})]}),i(a[0],0)]});const o=a.filter(p=>p.status==="running").length,c=a.filter(p=>p.status==="completed"&&p.isError).length,y=o>0,N=Array.from(new Set(a.map(p=>p.toolName))),$=N.slice(0,5),b=Math.max(0,N.length-$.length),D=b>0?`${$.join(", ")}, +${b} more`:$.join(", "),z=y?`(${o} running)`:c>0?`(${c} ${c===1?"error":"errors"})`:null;return t.jsx("div",{className:l,"data-testid":"chat-tool-calls",children:t.jsxs("details",{className:"chat-tool-calls-group","data-testid":"chat-tool-calls-group",open:y,children:[t.jsxs("summary",{className:"chat-tool-calls-group-summary",children:[t.jsx(et,{size:12,"aria-hidden":"true"}),t.jsxs("span",{children:[a.length," tool calls"]}),t.jsx("span",{className:"chat-tool-calls-names",title:D,children:D}),z&&t.jsx("span",{className:"chat-tool-calls-group-status",children:z})]}),a.map((p,F)=>i(p,F))]})})}const ut={pre:({children:a,...i})=>t.jsx("pre",{...i,className:"chat-markdown-pre",children:a}),table:({children:a,...i})=>t.jsx("table",{...i,className:"chat-markdown-table",children:a})},De="__fn_agent__",cs=["image/png","image/jpeg","image/gif","image/webp","text/plain","application/json","text/yaml","text/markdown","text/csv","application/xml","text/x-log"];function at(a){const i=/(^|[\s])\/([^\s]*)$/.exec(a);if(!i)return null;const l=i[1]??"",o=i[2]??"",c=i.index+l.length;return{filter:o,start:c,end:a.length}}function ds(a,i){const l=a.slice(0,i),o=/(^|[\s\n])@([\w-]*)$/.exec(l);if(!o)return null;const c=o[2]??"",y=l.length-c.length-1;return{filter:c,start:y,end:i}}function us({projectId:a,onClose:i,onCreate:l}){const[o,c]=s.useState("agent"),[y,N]=s.useState([]),[$,b]=s.useState(!0),[D,z]=s.useState(""),[p,F]=s.useState([]),[C,M]=s.useState(!0),[g,x]=s.useState(""),[T,k]=s.useState([]),[H,L]=s.useState([]);s.useEffect(()=>{let h=!1;return b(!0),ze(void 0,a).then(j=>{h||N(j)}).catch(()=>{h||N([])}).finally(()=>{h||b(!1)}),()=>{h=!0}},[a]),s.useEffect(()=>{M(!0),ns().then(h=>{F(h.models),k(h.favoriteProviders),L(h.favoriteModels)}).catch(()=>{F([]),k([]),L([])}).finally(()=>{M(!1)})},[]);const ee=s.useCallback(async h=>{const j=T,O=j.includes(h)?j.filter(V=>V!==h):[h,...j];k(O);try{await tt({favoriteProviders:O,favoriteModels:H})}catch{k(j)}},[T,H]),K=s.useCallback(async h=>{const j=H,O=j.includes(h)?j.filter(V=>V!==h):[h,...j];L(O);try{await tt({favoriteProviders:T,favoriteModels:O})}catch{L(j)}},[H,T]),_=h=>{if(h.preventDefault(),o==="agent"){if(!D)return;l({agentId:D});return}if(!g)return;const j=g.indexOf("/");if(j<=0)return;const v=g.slice(0,j),O=g.slice(j+1);l({agentId:De,modelProvider:v,modelId:O})},X=o==="agent"?!D:!g;return t.jsx("div",{className:"chat-new-dialog-backdrop",onClick:i,role:"dialog","aria-modal":"true",children:t.jsxs("div",{className:"chat-new-dialog",onClick:h=>h.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${o==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{c("agent"),x("")},children:"Agent"}),t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${o==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{c("model"),z("")},children:"Model"})]}),t.jsxs("form",{onSubmit:_,children:[o==="agent"&&t.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",$?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):y.length===0?t.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):t.jsx("div",{className:"chat-new-dialog-agent-list",children:y.map(h=>t.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${D===h.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>z(h.id),"data-testid":`agent-option-${h.id}`,children:[t.jsx(Ee,{size:16}),t.jsx("span",{className:"chat-new-dialog-agent-name",children:h.name}),t.jsx("span",{className:"chat-new-dialog-agent-role",children:h.role})]},h.id))})]}),o==="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(as,{models:p,value:g,onChange:x,label:"Model",placeholder:"Select a model",favoriteProviders:T,onToggleFavorite:ee,favoriteModels:H,onToggleModelFavorite:K})}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{type:"button",className:"btn btn-sm",onClick:i,children:"Cancel"}),t.jsx("button",{type:"submit",className:"btn btn-sm btn-primary",disabled:X,children:"Create"})]})]})]})})}const hs=s.memo(function({message:i,forcePlain:l,agentName:o,showAssistantModelTag:c,activeModelTag:y,activeSessionId:N,mentionAgentsByName:$,onToggleRender:b}){const D=i.role==="assistant",z=s.useMemo(()=>{if(D)return null;const C=i.content,M=/@([\w-]+)/g,g=[];let x=0,T=M.exec(C);for(;T;){const[k,H=""]=T,L=T.index;L>x&&g.push(C.slice(x,L));const ee=H.replace(/_/g," ").toLowerCase(),K=$.get(ee);K?g.push(t.jsxs("span",{className:"chat-mention-chip",children:["@",K.name.replace(/\s+/g,"_")]},`${K.id}-${L}`)):g.push(k),x=L+k.length,T=M.exec(C)}return x<C.length&&g.push(C.slice(x)),g.length===0?C:g},[D,i.content,$]),p=s.useMemo(()=>{const C=i.attachments;if(!C||C.length===0||!N)return null;const M=`/api/chat/sessions/${encodeURIComponent(N)}/attachments/`;return t.jsx("div",{className:"chat-message-attachments",children:C.map(g=>{const x=g.mimeType.startsWith("image/"),T=g.id||g.filename,k=`${M}${encodeURIComponent(g.filename)}`;return x?t.jsx("a",{className:"chat-message-attachment-link","data-testid":"chat-message-attachment",href:k,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{className:"chat-message-attachment",src:k,alt:g.originalName})},T):t.jsxs("a",{className:"chat-message-attachment-file","data-testid":"chat-message-attachment",href:k,target:"_blank",rel:"noopener noreferrer",children:[t.jsx(ss,{size:14}),t.jsx("span",{children:g.originalName})]},T)})})},[i.attachments,N]),F=s.useMemo(()=>D?l?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:i.content}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(it,{remarkPlugins:[rt],components:ut,children:i.content})}):null,[D,l,i.content]);return t.jsxs("div",{className:`chat-message chat-message--${i.role}`,"data-testid":`chat-message-${i.id}`,children:[D&&t.jsxs("div",{className:"chat-message-avatar",children:[t.jsx(Ee,{size:14}),t.jsx("span",{children:o}),c&&y&&t.jsx("span",{className:"chat-model-tag",children:y}),t.jsx("button",{type:"button",className:`chat-message-render-toggle${l?" chat-message-render-toggle--plain":""}`,"data-testid":"chat-message-render-toggle","aria-label":l?"Show rendered markdown":"Show plain text",onClick:()=>b(i.id),children:l?t.jsx(lt,{size:14}):t.jsx(ot,{size:14})})]}),D?F:t.jsx("div",{className:"chat-message-content",children:z}),dt(i.toolCalls),i.thinkingOutput&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:i.thinkingOutput})]}),p,t.jsx("div",{className:"chat-message-time",children:ct(i.createdAt)})]})});function vs({projectId:a,addToast:i}){const{activeSession:l,sessionsLoading:o,messages:c,messagesLoading:y,isStreaming:N,streamingText:$,streamingThinking:b,streamingToolCalls:D,selectSession:z,createSession:p,archiveSession:F,deleteSession:C,sendMessage:M,stopStreaming:g,pendingMessage:x,clearPendingMessage:T,searchQuery:k,setSearchQuery:H,filteredSessions:L}=rs(a),[ee,K]=s.useState(!1),[_,X]=s.useState(""),[h,j]=s.useState(null),[v,O]=s.useState(null),[V,de]=s.useState(!0),[ue,pe]=s.useState(new Map),[xe,ve]=s.useState([]),[he,ye]=s.useState(!0),[J,se]=s.useState(!1),[le,ne]=s.useState(""),[we,me]=s.useState(0),[Se,oe]=s.useState(""),[te,ce]=s.useState(!1),[fe,be]=s.useState(0),[u,f]=s.useState(-1),[m,R]=s.useState(()=>new Set),[I,ae]=s.useState([]),[B,Y]=s.useState(!1),[,q]=s.useState(!1),[G,E]=s.useState({top:0,left:0}),d=Vt({projectId:a}),U=s.useCallback(e=>{if(!e||!d.mentionActive)return;const n=e.getBoundingClientRect();E({top:n.top-260,left:n.left+8})},[d.mentionActive]),w=s.useRef(null),S=s.useRef(null),W=s.useRef(null),A=s.useRef(null),Ce=s.useRef(!1),Me=s.useRef(!1),He=s.useRef(null),Ve=s.useRef([]),Ne=s.useRef(0),ie=Bt()==="mobile",{keyboardOverlap:Pe,viewportHeight:Be,viewportOffsetTop:ht,keyboardOpen:Fe}=qt({enabled:ie&&!!l}),mt=Fe?{"--keyboard-overlap":`${Pe}px`,"--vv-offset-top":`${ht}px`,...Be!==null?{"--vv-height":`${Be}px`}:{}}:{},Z=s.useMemo(()=>{const e=le.trim().toLowerCase();return(e?xe.filter(r=>r.name.toLowerCase().includes(e)):xe).slice(0,10)},[xe,le]),ke=s.useMemo(()=>Array.from(ue.values()),[ue]),ge=s.useMemo(()=>{const e=Se.trim().toLowerCase();return e?ke.filter(n=>n.name.toLowerCase().includes(e)):ke},[ke,Se]),ft=s.useMemo(()=>{const e=new Map;for(const n of ke)e.set(n.name.toLowerCase(),n);return e},[ke]);s.useEffect(()=>{me(0)},[Z]),s.useEffect(()=>{be(0)},[Se,te]),s.useEffect(()=>()=>{S.current!==null&&window.clearTimeout(S.current)},[]),s.useEffect(()=>{const e=W.current;e&&(e.scrollTop=e.scrollHeight)},[c,$]),s.useEffect(()=>{if(Pe<=0)return;const e=W.current;e&&(e.scrollTop=e.scrollHeight)},[Pe]),s.useEffect(()=>{if(!ie||!Fe)return;const e=document.documentElement,n=document.body,r={htmlOverflow:e.style.overflow,bodyOverflow:n.style.overflow};return e.style.overflow="hidden",n.style.overflow="hidden",()=>{e.style.overflow=r.htmlOverflow,n.style.overflow=r.bodyOverflow}},[ie,Fe]),s.useEffect(()=>{const e=()=>j(null);if(h)return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[h]),s.useEffect(()=>{let e=!1;const n=a;return ze(void 0,a).then(r=>{if(e||n!==a)return;const P=new Map;for(const Q of r)P.set(Q.id,Q);pe(P)}).catch(()=>{}),()=>{e=!0}},[a]),s.useEffect(()=>{let e=!1;return ye(!0),Gt(a).then(n=>{e||ve(n)}).catch(()=>{e||ve([])}).finally(()=>{e||ye(!1)}),()=>{e=!0}},[a]),s.useEffect(()=>{Ve.current=I},[I]),s.useEffect(()=>()=>{for(const e of Ve.current)e.previewUrl&&URL.revokeObjectURL(e.previewUrl)},[]);const Te=s.useCallback(e=>{if(!e||e.length===0)return;const n=[];for(const r of Array.from(e)){if(!cs.includes(r.type))continue;const P=r.type.startsWith("image/");n.push({file:r,previewUrl:P?URL.createObjectURL(r):""})}n.length>0&&ae(r=>[...r,...n])},[]),gt=s.useCallback(e=>{ae(n=>{const r=n[e];return r?.previewUrl&&URL.revokeObjectURL(r.previewUrl),n.filter((P,Q)=>Q!==e)})},[]),pt=s.useCallback(e=>{const n=e.clipboardData?.files;if(!n||n.length===0)return;const r=Array.from(n).filter(P=>P.type.startsWith("image/"));r.length!==0&&Te(r)},[Te]),xt=s.useCallback(async e=>{try{await p(e),K(!1),ie&&de(!1)}catch{i("Failed to create chat session","error")}},[p,i,ie]),je=s.useCallback(()=>{const e=_.trim(),n=I.map(r=>r.file);!e&&n.length===0||!l||(X(""),se(!1),ne(""),ce(!1),oe(""),f(-1),M(e,n),ae(r=>{for(const P of r)P.previewUrl&&URL.revokeObjectURL(P.previewUrl);return[]}))},[_,I,l,M]),Ae=s.useCallback(()=>{if(typeof window>"u"||window.innerWidth>768)return;const e=A.current;if(!e||e.disabled)return;const n=window.scrollX,r=window.scrollY;e.focus({preventScroll:!0}),window.requestAnimationFrame(()=>{(window.scrollX!==n||window.scrollY!==r)&&window.scrollTo(n,r)})},[]),qe=s.useCallback(()=>{typeof window>"u"||window.innerWidth>768||(Ce.current=!0)},[]),Le=s.useCallback(e=>{X(n=>{const r=at(n);if(!r)return n;const P=`/skill:${e.name} `,Q=n.slice(0,r.start)+P+n.slice(r.end);return window.requestAnimationFrame(()=>{A.current&&(A.current.style.height="auto",A.current.style.height=`${Math.min(A.current.scrollHeight,120)}px`,A.current.focus())}),Q}),se(!1),ne(""),me(0)},[]),_e=s.useCallback(e=>{const n=A.current;if(!n||u<0)return;const r=n.selectionStart??Ne.current,P=n.selectionEnd??r,Q=Math.max(r,P),Je=Math.min(u,Q),Ye=`${`@${e.name.replace(/\s+/g,"_")}`} `,Rt=_.slice(0,Je)+Ye+_.slice(Q),Qe=Je+Ye.length;X(Rt),ce(!1),oe(""),be(0),f(-1),window.requestAnimationFrame(()=>{A.current&&(A.current.style.height="auto",A.current.style.height=`${Math.min(A.current.scrollHeight,120)}px`,A.current.focus(),A.current.setSelectionRange(Qe,Qe))})},[u,_]),vt=s.useCallback(e=>{if(Ne.current=e.currentTarget.selectionStart??Ne.current,d.mentionActive&&d.files.length>0){if(d.handleKeyDown(e,_),e.key==="Enter"||e.key==="Tab"){const n=d.files[d.selectedIndex];if(n){const r=d.selectFile(n,_);X(r),d.dismissMention(),q(!1)}}return}if(te&&e.key==="ArrowDown"){e.preventDefault(),ge.length>0&&be(n=>(n+1)%ge.length);return}if(te&&e.key==="ArrowUp"){e.preventDefault(),ge.length>0&&be(n=>n===0?ge.length-1:n-1);return}if(te&&e.key==="Enter"){e.preventDefault();const n=ge[fe]??ge[0];n&&_e(n);return}if(te&&e.key==="Escape"){e.preventDefault(),ce(!1),oe(""),f(-1);return}if(J&&e.key==="ArrowDown"){e.preventDefault(),Z.length>0&&me(n=>(n+1)%Z.length);return}if(J&&e.key==="ArrowUp"){e.preventDefault(),Z.length>0&&me(n=>n===0?Z.length-1:n-1);return}if(J&&(e.key==="Enter"||e.key==="Tab")&&Z.length>0){e.preventDefault();const n=Z[we]??Z[0];n&&Le(n);return}if(J&&e.key==="Escape"){e.preventDefault(),se(!1);return}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),je())},[te,ge,fe,_e,J,Z,we,Le,je,d,_]),$e=s.useCallback((e,n)=>{const r=ds(e,n);if(r){ce(!0),oe(r.filter),f(r.start);return}ce(!1),oe(""),f(-1)},[]),wt=s.useCallback(e=>{const n=e.target,r=n.value,P=n.selectionStart??r.length;Ne.current=P,X(r);const Q=at(r);Q?(se(!0),ne(Q.filter)):(se(!1),ne("")),$e(r,P),d.detectMention(r,P),q(d.mentionActive),d.mentionActive&&U(n),n.style.height="auto",n.style.height=`${Math.min(n.scrollHeight,120)}px`},[$e]),Oe=s.useCallback(e=>{const n=e.currentTarget,r=n.selectionStart??n.value.length;Ne.current=r,$e(n.value,r),d.detectMention(n.value,r),q(d.mentionActive),d.mentionActive&&U(n)},[$e,d,U]),St=s.useCallback(e=>{e.key!=="Escape"&&Oe(e)},[Oe]),bt=s.useCallback(()=>{if(Ce.current){window.requestAnimationFrame(()=>{Ae()});return}S.current!==null&&window.clearTimeout(S.current),S.current=window.setTimeout(()=>{se(!1),ce(!1),oe(""),f(-1),q(!1),d.dismissMention(),S.current=null},120)},[d,Ae]),kt=s.useCallback(()=>{S.current!==null&&(window.clearTimeout(S.current),S.current=null)},[]),yt=s.useCallback(async e=>{j(null);try{await F(e),i("Conversation archived","success")}catch{i("Failed to archive conversation","error")}},[F,i]),Nt=s.useCallback(async e=>{O(null),j(null);try{await C(e),i("Conversation deleted","success")}catch{i("Failed to delete conversation","error")}},[C,i]),jt=s.useCallback(e=>{z(e),ie&&de(!1)},[z,ie]),Ct=s.useCallback(()=>{z(""),de(!0)},[z]),Mt=()=>t.jsxs("div",{className:"chat-empty-state",children:[t.jsx(ts,{size:48,strokeWidth:1.5}),t.jsx("h2",{children:"Start a new conversation"}),t.jsxs("button",{className:"btn btn-primary",onClick:()=>K(!0),children:[t.jsx(Ze,{size:16}),"New Chat"]})]}),re=nt(l?.modelProvider,l?.modelId),Ge=l?.agentId===De?re??"Fusion":l?.title||ue.get(l?.agentId??"")?.name||l?.agentId||"Chat",Tt=!!(re&&re!==Ge),Ie=ue.get(l?.agentId??"")?.name||(l?.agentId===De?re??"Fusion":l?.agentId?.slice(0,30)??"Fusion"),We=!!(re&&re!==Ie),At=x.length>50?`${x.slice(0,50)}…`:x,Ke=s.useCallback(e=>{R(n=>{const r=new Set(n);return r.has(e)?r.delete(e):r.add(e),r})},[]),$t=s.useCallback((e,n=!1)=>n?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(it,{remarkPlugins:[rt],components:ut,children:e})}),[]);return t.jsxs("div",{className:"chat-view",children:[t.jsxs("div",{className:`chat-sidebar${V?"":" chat-sidebar--hidden"}`,children:[t.jsx("div",{className:"chat-sidebar-search",children:t.jsxs("div",{className:"chat-sidebar-search-wrapper",children:[t.jsx(Wt,{size:14,className:"chat-sidebar-search-icon"}),t.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:k,onChange:e=>H(e.target.value),"data-testid":"chat-search-input"})]})}),t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:o?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"Loading..."}):L.length===0?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"No conversations yet"}):L.map(e=>t.jsxs("div",{className:`chat-session-item${l?.id===e.id?" chat-session-item--active":""}`,onClick:()=>jt(e.id),onContextMenu:n=>{n.preventDefault(),j({sessionId:e.id,x:n.clientX,y:n.clientY})},"data-testid":`chat-session-${e.id}`,children:[t.jsx("button",{className:"chat-session-delete-btn",onClick:n=>{n.stopPropagation(),O(e.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:t.jsx(Xe,{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.jsx("span",{children:ue.get(e.agentId)?.name||(e.agentId===De?nt(e.modelProvider,e.modelId)??"Fusion":e.agentId.slice(0,30))}),t.jsx("span",{children:e.updatedAt?ct(e.updatedAt):""})]})]},e.id))}),t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>K(!0),"data-testid":"chat-new-btn",children:[t.jsx(Ze,{size:14}),"New Chat"]})})]}),h&&t.jsxs("div",{className:"chat-session-context-menu",style:{top:h.y,left:h.x},onClick:e=>e.stopPropagation(),children:[t.jsxs("button",{onClick:()=>yt(h.sessionId),"data-testid":"chat-context-archive",children:[t.jsx(Kt,{size:14}),"Archive"]}),t.jsxs("button",{onClick:()=>{j(null),O(h.sessionId)},"data-testid":"chat-context-delete",children:[t.jsx(Xe,{size:14}),"Delete"]})]}),v&&t.jsx("div",{className:"chat-new-dialog-backdrop",onClick:()=>O(null),children:t.jsxs("div",{className:"chat-new-dialog",onClick:e=>e.stopPropagation(),children:[t.jsx("h3",{children:"Delete Conversation?"}),t.jsx("p",{style:{fontSize:"14px",color:"var(--text-secondary)",marginBottom:"16px"},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:()=>O(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void Nt(v),children:"Delete"})]})]})}),t.jsxs("div",{className:"chat-thread",style:mt,children:[(l||!ie)&&t.jsxs("div",{className:"chat-thread-header",children:[ie&&l&&t.jsx("button",{className:"btn-icon",onClick:Ct,"data-testid":"chat-back-btn",children:t.jsx(Jt,{size:16})}),t.jsx(Ee,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:Ge}),Tt&&t.jsx("span",{className:"chat-model-tag",children:re})]}),t.jsxs("div",{className:"chat-messages",ref:W,children:[y?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):c.length===0&&!l?Mt():c.length===0&&l?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):t.jsxs(t.Fragment,{children:[c.map(e=>t.jsx(hs,{message:e,forcePlain:m.has(e.id),agentName:Ie,showAssistantModelTag:We,activeModelTag:re,activeSessionId:l?.id??null,mentionAgentsByName:ft,onToggleRender:Ke},e.id)),N&&t.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[t.jsxs("div",{className:"chat-message-avatar",children:[t.jsx(Ee,{size:14}),t.jsx("span",{children:Ie}),We&&t.jsx("span",{className:"chat-model-tag",children:re}),t.jsx("button",{type:"button",className:`chat-message-render-toggle${m.has("__streaming__")?" chat-message-render-toggle--plain":""}`,"data-testid":"chat-message-render-toggle","aria-label":m.has("__streaming__")?"Show rendered markdown":"Show plain text",onClick:()=>Ke("__streaming__"),children:m.has("__streaming__")?t.jsx(lt,{size:14}):t.jsx(ot,{size:14})})]}),$?$t($,m.has("__streaming__")):t.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:b?"Thinking…":"Connecting…"}),dt(D),b&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:b})]}),t.jsxs("div",{className:"chat-typing-indicator",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]})]})]}),t.jsx("div",{ref:w})]}),l&&t.jsxs("div",{className:"chat-input-area",children:[t.jsx("input",{ref:He,type:"file",accept:"image/*,.txt,.json,.yaml,.yml,.log,.csv,.xml,.md",multiple:!0,style:{display:"none"},onChange:e=>{Te(e.target.files),e.target.value=""}}),J&&t.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:he?t.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):Z.length===0?t.jsx("div",{className:"chat-skill-menu-empty",children:le?"No skills found":"No skills available"}):Z.map((e,n)=>t.jsxs("button",{type:"button",role:"option","aria-selected":n===we,className:`chat-skill-menu-item${n===we?" chat-skill-menu-item--highlighted":""}`,onMouseDown:r=>r.preventDefault(),onMouseEnter:()=>me(n),onClick:()=>Le(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))}),I.length>0&&t.jsx("div",{className:"chat-attachment-previews","data-testid":"chat-attachment-previews",children:I.map((e,n)=>t.jsxs("div",{className:"chat-attachment-preview","data-testid":`chat-attachment-preview-${n}`,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:()=>gt(n),"data-testid":`chat-attachment-remove-${n}`,"aria-label":`Remove ${e.file.name}`,children:"×"})]},e.previewUrl||`${e.file.name}-${n}`))}),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:()=>He.current?.click(),children:t.jsx(Yt,{size:16})}),t.jsxs("div",{className:`chat-input-wrapper${B?" chat-input-wrapper--dragover":""}`,onDragOver:e=>{e.preventDefault(),Y(!0)},onDragLeave:()=>Y(!1),onDrop:e=>{e.preventDefault(),Y(!1),Te(e.dataTransfer.files)},children:[t.jsx("textarea",{ref:A,className:"chat-input-textarea",placeholder:"Type a message...",value:_,onChange:wt,onKeyDown:vt,onKeyUp:St,onClick:Oe,onBlur:bt,onFocus:kt,onPaste:pt,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(Qt,{agents:ke,filter:Se,highlightedIndex:fe,visible:te,onSelect:_e,position:"below"}),t.jsx(Xt,{visible:d.mentionActive&&!te,position:G,files:d.files,selectedIndex:d.selectedIndex,onSelect:e=>{const n=d.selectFile(e,_);X(n),d.dismissMention(),q(!1),A.current?.focus()},loading:d.loading}),x&&t.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[t.jsx("span",{children:`Queued: ${At}`}),t.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:T,children:"×"})]})]}),N?t.jsx("button",{className:"chat-input-stop",onClick:g,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:t.jsx(Zt,{size:14})}):t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{typeof window>"u"||window.innerWidth>768||(e.preventDefault(),e.pointerType&&e.pointerType!=="mouse"&&(Me.current=!0,qe(),Ae(),je(),window.setTimeout(()=>{Ce.current=!1},1500)))},onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||(e.preventDefault(),Me.current=!0,qe(),Ae(),je(),window.setTimeout(()=>{Ce.current=!1},1500))},onMouseDown:e=>{typeof window>"u"||window.innerWidth>768||e.preventDefault()},onClick:()=>{if(Me.current){Me.current=!1;return}je()},disabled:!_.trim()&&I.length===0,"data-testid":"chat-send-btn",children:t.jsx(es,{size:16})})]})]})]}),ee&&t.jsx(us,{projectId:a,onClose:()=>K(!1),onCreate:xt})]})}export{vs as ChatView};
@@ -1,11 +0,0 @@
1
- import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{c as A,dU as Y,dV as Z,dW as H,R as $,dM as y,J as Q,W as T,N as ee,V as se,cp as L,F as D,dX as ae,dY as te,dZ as M,X as ie}from"./index-DmSs2FGE.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 ne=[["path",{d:"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z",key:"e79jfc"}],["circle",{cx:"13.5",cy:"6.5",r:".5",fill:"currentColor",key:"1okk4w"}],["circle",{cx:"17.5",cy:"10.5",r:".5",fill:"currentColor",key:"f64h9f"}],["circle",{cx:"6.5",cy:"12.5",r:".5",fill:"currentColor",key:"qy21gx"}],["circle",{cx:"8.5",cy:"7.5",r:".5",fill:"currentColor",key:"fotxhn"}]],W=A("palette",ne);/**
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 le=[["path",{d:"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z",key:"w46dr5"}]],_=A("puzzle",le);function ce(t){return t.replace(/-/g,"-")}function re(t){return{"fusion-global":"Fusion Global","pi-global":"Pi Global","fusion-project":"Fusion Project","pi-project":"Pi Project",package:"Package"}[t]??t}function oe(t){return t.startsWith("npm:")?"npm":t.startsWith("git:")?"git":"local"}function de(t){return t.replace(/^(npm:|git:)/,"")}function he({addToast:t,projectId:x}){const[c,G]=l.useState(null),[f,P]=l.useState(!0),[N,S]=l.useState(!1),[E,w]=l.useState(!1),[h,F]=l.useState(""),[I,O]=l.useState(new Set),[m,U]=l.useState([]),[b,z]=l.useState(!0),[V,C]=l.useState(!1),r=l.useCallback(async()=>{try{P(!0);const s=await Y();G(s)}catch(s){t(`Failed to load Pi settings: ${s instanceof Error?s.message:String(s)}`,"error")}finally{P(!1)}},[t]),p=l.useCallback(async()=>{try{z(!0);const s=await Z(x);U(s.extensions)}catch(s){t(`Failed to load extensions: ${s instanceof Error?s.message:String(s)}`,"error")}finally{z(!1)}},[t,x]),X=l.useCallback(async s=>{try{C(!0);const i=s.enabled?[...m.filter(a=>a.enabled&&a.id!==s.id).map(a=>a.id),s.id]:m.filter(a=>a.enabled&&a.id!==s.id).map(a=>a.id);await H(i,x),await p(),t(s.enabled?"Extension disabled":"Extension enabled","success")}catch(i){t(`Failed to update extension: ${i instanceof Error?i.message:String(i)}`,"error")}finally{C(!1)}},[m,x,p,t]);l.useEffect(()=>{r()},[r]),l.useEffect(()=>{p()},[p]);const q=s=>{O(i=>{const a=new Set(i);return a.has(s)?a.delete(s):a.add(s),a})},R=async()=>{if(!h.trim()){t("Please enter a package source","error");return}try{S(!0),await ae(h.trim()),t("Package installed successfully","success"),F(""),await r()}catch(s){t(`Failed to install package: ${s instanceof Error?s.message:String(s)}`,"error")}finally{S(!1)}},B=async()=>{try{w(!0),await te(x),await Promise.all([r(),p()]),t("Fusion skill reinstalled successfully","success")}catch(s){t(`Failed to reinstall Fusion skill: ${s instanceof Error?s.message:String(s)}`,"error")}finally{w(!1)}},J=async s=>{if(!c)return;const i=c.packages.filter(a=>(typeof a=="string"?a:a.source)!==s);try{await M({packages:i}),t("Package removed","success"),await r()}catch(a){t(`Failed to remove package: ${a instanceof Error?a.message:String(a)}`,"error")}},K=async(s,i)=>{if(!c)return;const a=c[s].filter(n=>n!==i);try{await M({[s]:a}),t(`${s.slice(0,-1)} removed`,"success"),await r()}catch(n){t(`Failed to update settings: ${n instanceof Error?n.message:String(n)}`,"error")}},u=(s,i,a)=>!c||c[a].length===0?null:e.jsxs("div",{className:"pi-ext-section",children:[e.jsxs("div",{className:"pi-ext-section-header",children:[e.jsx(i,{size:14}),e.jsx("span",{children:s}),e.jsx("span",{className:"pi-ext-count",children:c[a].length})]}),e.jsx("div",{className:"pi-ext-resource-list",children:c[a].map((n,g)=>e.jsxs("span",{className:"pi-ext-resource-tag",children:[e.jsx("span",{className:"pi-ext-resource-path",children:n}),e.jsx("button",{className:"btn-icon touch-target pi-ext-resource-remove",onClick:()=>K(a,n),title:`Remove ${n}`,"aria-label":`Remove ${n}`,children:e.jsx(ie,{size:12})})]},g))})]});return e.jsxs("div",{className:"pi-ext-manager",children:[e.jsxs("div",{className:"pi-ext-manager-header",children:[e.jsx("h4",{className:"pi-ext-manager-title",children:"Pi Extensions"}),e.jsx("div",{className:"pi-ext-manager-actions",children:e.jsx("button",{className:"btn-icon",onClick:r,title:"Refresh",disabled:f,children:e.jsx($,{size:16,className:f?"spin":""})})})]}),f?e.jsx("div",{className:"loading-state",children:"Loading Pi settings…"}):c?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"pi-ext-add-form",children:[e.jsxs("div",{className:"pi-ext-add-form-row",children:[e.jsx("input",{type:"text",className:"input",placeholder:"npm:pi-extension-name or git:https://github.com/...",value:h,onChange:s=>F(s.target.value),onKeyDown:s=>{s.key==="Enter"&&(s.preventDefault(),R())},disabled:N}),e.jsxs("button",{className:"btn btn-primary",onClick:R,disabled:N||!h.trim(),children:[e.jsx(Q,{size:14}),N?"Installing…":"Add"]})]}),e.jsx("div",{className:"pi-ext-add-form-row",children:e.jsx("button",{className:"btn",onClick:B,disabled:E,children:E?"Reinstalling Fusion…":"Reinstall Fusion skill"})})]}),c.packages.length>0?e.jsx("div",{className:"pi-ext-package-list",children:c.packages.map((s,i)=>{const a=typeof s=="string"?s:s.source,n=oe(a),g=de(a),j=typeof s=="object"&&s!==null,v=j&&(s.extensions?.length??0)>0||(s.skills?.length??0)>0||(s.prompts?.length??0)>0||(s.themes?.length??0)>0,k=I.has(i);return e.jsxs("div",{className:"pi-ext-package-card",children:[e.jsxs("div",{className:"pi-ext-package-header",children:[j&&v?e.jsx("button",{className:"pi-ext-expand-btn",onClick:()=>q(i),"aria-expanded":k,children:k?e.jsx(T,{size:14}):e.jsx(ee,{size:14})}):e.jsx("span",{className:"pi-ext-expand-placeholder"}),e.jsx("span",{className:`pi-ext-source-badge pi-ext-source-badge--${n}`,children:n}),e.jsx("span",{className:"pi-ext-package-source",children:g}),e.jsxs("div",{className:"pi-ext-package-actions",children:[j&&v&&e.jsxs("span",{className:"pi-ext-filter-hint",children:[s.extensions?.length??0," ext,"," ",s.skills?.length??0," skill,"," ",s.prompts?.length??0," prompt,"," ",s.themes?.length??0," theme"]}),e.jsx("button",{className:"btn-icon touch-target pi-ext-remove-btn",onClick:()=>J(a),title:"Remove package","aria-label":`Remove package ${g}`,children:e.jsx(se,{size:14})})]})]}),j&&v&&k&&e.jsxs("div",{className:"pi-ext-filter-list",children:[s.extensions?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(_,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Extensions:"}),s.extensions.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.skills?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(L,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Skills:"}),s.skills.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.prompts?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(D,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Prompts:"}),s.prompts.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.themes?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(W,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Themes:"}),s.themes.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null]})]},i)})}):e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"No packages configured."}),e.jsx("p",{className:"text-muted",children:"Add a package source above to get started."})]}),e.jsxs("div",{className:"pi-ext-top-level",children:[u("Extensions",_,"extensions"),u("Skills",L,"skills"),u("Prompts",D,"prompts"),u("Themes",W,"themes")]})]}):e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"Failed to load Pi settings."})]}),e.jsxs("div",{className:"pi-ext-discovered-section",children:[e.jsxs("div",{className:"pi-ext-discovered-header",children:[e.jsx("h4",{children:"Discovered Extensions"}),e.jsx("button",{className:"btn-icon",onClick:p,disabled:b,title:"Refresh extensions",children:e.jsx($,{size:14,className:b?"spin":""})})]}),e.jsx("p",{className:"pi-ext-description",children:"Installed extensions resolved from packages and configured paths."}),b?e.jsx("div",{className:"loading-state",children:"Loading extensions…"}):m.length===0?e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"No extensions discovered."})]}):e.jsx("div",{className:"pi-ext-list",children:m.map(s=>e.jsxs("div",{className:"pi-ext-item",children:[e.jsxs("div",{className:"pi-ext-item-content",children:[e.jsxs("div",{className:"pi-ext-info",children:[e.jsx("span",{className:"pi-ext-name",children:s.name}),e.jsx("span",{className:`pi-ext-source-badge pi-ext-source-badge--${ce(s.source)}`,children:re(s.source)})]}),e.jsx("span",{className:"pi-ext-path",children:s.path})]}),e.jsx("div",{className:"pi-ext-actions",children:e.jsxs("label",{className:"toggle-switch",children:[e.jsx("input",{type:"checkbox",checked:s.enabled,onChange:()=>void X(s),disabled:V,"aria-label":`Toggle ${s.name}`}),e.jsx("span",{className:"toggle-slider"})]})})]},s.id))})]})]})}export{he as PiExtensionsManager};
@@ -1 +0,0 @@
1
- import{r as u,j as s}from"./vendor-react-K0fH_qHe.js";import{w as ee,dK as se,s as ne,X as k,an as te,J as O,dL as A,V,R as ie,dM as ae,aF as le,cf as re,dN as ce,dO as de,dP as ue,dQ as oe,dR as _,cc as ge}from"./index-DmSs2FGE.js";import{D as me}from"./DirectoryPicker-DRfhg9zz.js";import"./vendor-xterm-DzcZoU0P.js";import"./folder-open-DDdJt8aE.js";const M=[{id:"fusion-plugin-hermes-runtime",name:"Hermes Runtime",path:"./plugins/fusion-plugin-hermes-runtime",experimental:!0},{id:"fusion-plugin-paperclip-runtime",name:"Paperclip Runtime",path:"./plugins/fusion-plugin-paperclip-runtime"},{id:"fusion-plugin-openclaw-runtime",name:"OpenClaw Runtime",path:"./plugins/fusion-plugin-openclaw-runtime",experimental:!0}],j={started:"var(--color-success)",loaded:"var(--color-warning)",error:"var(--color-error)",stopped:"var(--color-muted)",installed:"var(--color-info)"};function fe({addToast:l,projectId:c}){const[N,x]=u.useState([]),[S,w]=u.useState(!0),[H,f]=u.useState(!1),[b,v]=u.useState(""),[C,P]=u.useState(!1),[h,I]=u.useState(null),[i,y]=u.useState(null),[a,p]=u.useState({}),[J,R]=u.useState(!1),[$,E]=u.useState(null),{confirm:K}=ee(),o=u.useCallback(async()=>{try{w(!0);const e=await se(c);x(e)}catch(e){l(`Failed to load plugins: ${e instanceof Error?e.message:String(e)}`,"error")}finally{w(!1)}},[c,l]);u.useEffect(()=>{o()},[o]);const G=u.useRef([]);G.current=N,u.useEffect(()=>{const e=c?`?projectId=${encodeURIComponent(c)}`:"",n=g=>{try{const t=JSON.parse(g.data);if(c&&t.projectId&&t.projectId!==c)return;switch(t.transition){case"installing":case"enabled":case"disabled":case"settings-updated":x(d=>{const m=d.findIndex(r=>r.id===t.pluginId);if(m>=0){const r=[...d];return r[m]={...r[m],enabled:t.enabled,state:t.state,settings:t.settings,error:t.error},r}else return o(),d});break;case"uninstalled":x(d=>d.filter(m=>m.id!==t.pluginId));break;case"error":x(d=>{const m=d.findIndex(r=>r.id===t.pluginId);if(m>=0){const r=[...d];return r[m]={...r[m],state:t.state,error:t.error},r}return d});break}}catch{}};return ne(`/api/events${e}`,{events:{"plugin:lifecycle":n},onReconnect:()=>{o()}})},[c,o]);const z=async()=>{if(!b.trim()){l("Please enter a plugin path","error");return}try{P(!0),await _({path:b},c),l("Plugin installed successfully","success"),f(!1),v(""),await o()}catch(e){l(`Failed to install plugin: ${e instanceof Error?e.message:String(e)}`,"error")}finally{P(!1)}},Q=async e=>{try{E(e.id),await _({path:e.path},c),l(`${e.name} installed successfully`,"success"),await o()}catch(n){l(`Failed to install ${e.name}: ${n instanceof Error?n.message:String(n)}`,"error")}finally{E(null)}},F=async e=>{try{await ue(e.id,c),l(`${e.name} enabled`,"success"),await o()}catch(n){l(`Failed to enable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},L=async e=>{try{await de(e.id,c),l(`${e.name} disabled`,"success"),await o()}catch(n){l(`Failed to disable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},B=async e=>{try{I(e.id),await ce(e.id,c),l(`${e.name} reloaded`,"success"),await o()}catch(n){l(`Failed to reload plugin: ${n instanceof Error?n.message:String(n)}`,"error")}finally{I(null)}},U=async e=>{if(await K({title:"Uninstall Plugin",message:`Are you sure you want to uninstall "${e.name}"?`,danger:!0}))try{await oe(e.id,c),l(`${e.name} uninstalled`,"success"),await o(),y(null)}catch(g){l(`Failed to uninstall plugin: ${g instanceof Error?g.message:String(g)}`,"error")}},X=async e=>{y(e);try{R(!0);const n=await ge(e.id,c);p(n)}catch{p({})}finally{R(!1)}},W=async()=>{if(i)try{await re(i.id,a,c),l("Settings saved","success")}catch(e){l(`Failed to save settings: ${e instanceof Error?e.message:String(e)}`,"error")}};if(i)return s.jsxs("div",{className:"plugin-manager-detail","data-testid":"plugin-manager-detail",children:[s.jsxs("div",{className:"plugin-manager-detail-header",children:[s.jsx("button",{className:"btn-icon",onClick:()=>y(null),"aria-label":"Back to plugin list",children:s.jsx(k,{size:16})}),s.jsxs("div",{className:"plugin-detail-title",children:[s.jsx("h4",{className:"plugin-detail-name",children:i.name}),s.jsx("span",{className:"plugin-state-badge",style:{color:j[i.state]||j.installed},children:i.state})]})]}),s.jsxs("div",{className:"plugin-detail-content",children:[s.jsxs("div",{className:"plugin-detail-card",children:[i.description&&s.jsx("p",{className:"plugin-description",children:i.description}),i.author&&s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Author:"}),i.author]}),i.homepage&&s.jsxs("p",{className:"plugin-detail-meta-row plugin-homepage",children:[s.jsx("span",{className:"text-muted",children:"Homepage:"}),s.jsxs("a",{href:i.homepage,target:"_blank",rel:"noopener noreferrer",children:[i.homepage,s.jsx(te,{size:12})]})]}),s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Version:"}),i.version]})]}),s.jsxs("div",{className:"plugin-detail-card",children:[s.jsx("h5",{className:"plugin-detail-section-heading",children:"Settings"}),J?s.jsx("p",{className:"text-muted",children:"Loading..."}):i.settingsSchema&&Object.keys(i.settingsSchema).length>0?s.jsxs("div",{className:"plugin-settings-form",children:[Object.entries(i.settingsSchema).map(([e,n])=>{const g=`setting-${e}-help`;return s.jsxs("div",{className:"form-group",children:[s.jsxs("label",{htmlFor:`setting-${e}`,children:[n.label||e,n.required&&" *"]}),n.type==="string"&&!n.multiline&&s.jsx("input",{type:"text",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?g:void 0}),n.type==="string"&&n.multiline&&s.jsx("textarea",{id:`setting-${e}`,rows:4,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?g:void 0}),n.type==="password"&&s.jsx("input",{type:"password",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?g:void 0}),n.type==="number"&&s.jsx("input",{type:"number",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:Number(t.target.value)}),"aria-describedby":n.description&&!n.required?g:void 0}),n.type==="boolean"&&s.jsxs("label",{className:"checkbox-label",children:[s.jsx("input",{type:"checkbox",checked:a[e]??!1,onChange:t=>p({...a,[e]:t.target.checked})}),n.description]}),n.type==="enum"&&s.jsxs("select",{id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),"aria-describedby":n.description&&!n.required?g:void 0,children:[s.jsx("option",{value:"",children:"Select..."}),n.enumValues?.map(t=>s.jsx("option",{value:t,children:t},t))]}),n.type==="array"&&s.jsxs("div",{className:"plugin-settings-array",children:[a[e]?.map((t,d)=>s.jsxs("div",{className:"plugin-settings-array-item",children:[s.jsx("input",{type:n.itemType==="number"?"number":"text",value:t??"",onChange:m=>{const r=m.target.value,D=[...a[e]||[]];D[d]=n.itemType==="number"?Number(r):r,p({...a,[e]:D})}}),s.jsx("button",{className:"btn-icon",onClick:()=>{const r=[...a[e]||[]];r.splice(d,1),p({...a,[e]:r})},"aria-label":"Remove item",children:s.jsx(k,{size:14})})]},d)),s.jsxs("button",{className:"btn btn-secondary",onClick:()=>{const t=a[e]||[],d=n.itemType==="number"?0:"";p({...a,[e]:[...t,d]})},children:[s.jsx(O,{size:14})," Add Item"]})]}),n.description&&!n.required&&!n.multiline&&s.jsx("span",{id:g,className:"form-help",children:n.description})]},e)}),s.jsx("button",{className:"btn btn-primary",onClick:W,children:"Save Settings"})]}):s.jsx("p",{className:"text-muted",children:"No configurable settings."})]}),s.jsxs("div",{className:"plugin-detail-actions",children:[i.state==="started"&&s.jsxs("button",{className:"btn btn-secondary",onClick:()=>B(i),disabled:h===i.id,children:[s.jsx(A,{size:14,className:h===i.id?"spin":""}),h===i.id?"Reloading...":"Reload"]}),i.enabled?s.jsx("button",{className:"btn btn-secondary",onClick:()=>L(i),children:"Disable"}):s.jsx("button",{className:"btn btn-primary",onClick:()=>F(i),children:"Enable"}),s.jsxs("button",{className:"btn btn-danger",onClick:()=>U(i),children:[s.jsx(V,{size:14})," Uninstall"]})]})]})]});const Y=new Set(N.map(e=>e.id)),Z=new Set(M.map(e=>e.id)),q=N.filter(e=>!Z.has(e.id)),T=()=>s.jsxs("section",{className:"plugin-bundled-runtime-section","aria-label":"Bundled Runtime Plugins",children:[s.jsxs("div",{className:"plugin-bundled-runtime-header",children:[s.jsx("h4",{className:"plugin-bundled-runtime-heading",children:"Bundled Runtime Plugins"}),s.jsx("p",{className:"plugin-bundled-runtime-description",children:"Install Fusion's bundled runtimes directly from this screen."})]}),s.jsx("div",{className:"plugin-bundled-runtime-list","aria-label":"Bundled runtime plugin recommendations",children:M.map(e=>{const n=Y.has(e.id);return s.jsxs("div",{className:"plugin-bundled-runtime-item",children:[s.jsxs("div",{className:"plugin-bundled-runtime-meta",children:[s.jsx("span",{className:"plugin-bundled-runtime-name",children:e.name}),e.experimental&&s.jsx("span",{className:"plugin-bundled-runtime-badge",children:"Experimental"}),s.jsx("span",{className:`plugin-bundled-runtime-status ${n?"plugin-bundled-runtime-status--installed":"plugin-bundled-runtime-status--available"}`,children:n?"Installed":"Not installed"})]}),s.jsx("button",{className:`btn ${n?"btn-secondary":"btn-primary"} btn-sm`,onClick:()=>Q(e),disabled:n||$===e.id,children:n?"Installed":$===e.id?"Installing...":`Install ${e.name}`})]},e.id)})})]});return s.jsxs("div",{className:"plugin-manager","data-testid":"plugin-manager",children:[s.jsxs("div",{className:"plugin-manager-header",children:[s.jsx("span",{className:"plugin-manager-header-title",children:"Installed Plugins"}),s.jsxs("div",{className:"plugin-manager-actions",children:[s.jsxs("button",{className:"btn btn-sm btn-ghost",onClick:o,title:"Refresh","aria-label":"Refresh plugin list",children:[s.jsx(ie,{size:14,className:S?"spin":""}),"Refresh"]}),s.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>f(!0),children:[s.jsx(O,{size:14})," Install"]})]})]}),H&&s.jsxs("div",{className:"plugin-install-form",children:[s.jsxs("p",{className:"plugin-install-hint",children:["Browse to a plugin package root (contains ",s.jsx("code",{children:"manifest.json"}),") or a built ",s.jsx("code",{children:"dist"})," directory."]}),s.jsx(me,{value:b,onChange:v,placeholder:"Absolute path to plugin directory or dist folder",onInputKeyDown:e=>{e.key==="Enter"&&(e.preventDefault(),z())}}),s.jsxs("div",{className:"plugin-install-actions",children:[s.jsx("button",{className:"btn btn-primary",onClick:z,disabled:C||!b.trim(),children:C?"Installing...":"Install Plugin"}),s.jsx("button",{className:"btn btn-secondary",onClick:()=>{f(!1),v("")},children:"Cancel"})]})]}),S?s.jsx("div",{className:"settings-empty-state",children:"Loading plugins..."}):s.jsxs(s.Fragment,{children:[q.length===0?s.jsxs("div",{className:"settings-empty-state",children:[s.jsx(ae,{size:32,className:"text-muted"}),s.jsx("p",{children:"No plugins installed."}),s.jsx("p",{className:"text-muted",children:"Install a plugin to get started, or use a bundled runtime below."})]}):s.jsx("div",{className:"plugin-list",children:q.map(e=>s.jsxs("div",{className:"plugin-item",children:[s.jsxs("div",{className:"plugin-info",children:[s.jsx("span",{className:"plugin-name",children:e.name}),s.jsxs("span",{className:"plugin-version text-muted",children:["v",e.version]}),s.jsx("span",{className:"plugin-state-badge",style:{color:j[e.state]||j.installed},children:e.state})]}),s.jsxs("div",{className:"plugin-actions",children:[e.state==="started"&&s.jsx("button",{className:"btn-icon",onClick:()=>B(e),disabled:h===e.id,title:"Reload",children:s.jsx(A,{size:14,className:h===e.id?"spin":""})}),s.jsxs("label",{className:"toggle-switch",children:[s.jsx("input",{type:"checkbox",checked:e.enabled,onChange:()=>e.enabled?L(e):F(e)}),s.jsx("span",{className:"toggle-slider"})]}),s.jsx("button",{className:"btn-icon",onClick:()=>X(e),title:"Settings",children:s.jsx(le,{size:14})}),s.jsx("button",{className:"btn-icon",onClick:()=>U(e),title:"Uninstall",children:s.jsx(V,{size:14})})]})]},e.id))}),T()]})]})}export{fe as PluginManager,j as STATE_COLORS};
@@ -1 +0,0 @@
1
- .plugin-manager,.plugin-manager-detail{display:flex;flex-direction:column;gap:var(--space-lg);padding-inline:var(--space-xl);padding-block:var(--space-md)}.plugin-manager-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:var(--space-sm);border-bottom:var(--btn-border-width) solid var(--border);gap:var(--space-sm)}.plugin-manager-header-title{font-size:13px;font-weight:600;color:var(--text);flex:1}.plugin-manager-actions{display:flex;gap:var(--space-sm);align-items:center}.plugin-install-form{display:flex;flex-direction:column;gap:var(--space-sm);padding:var(--space-lg);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:var(--surface)}.plugin-install-hint{margin:0;font-size:.85rem;color:var(--text-secondary, var(--text-muted));line-height:1.45}.plugin-install-hint code{padding:var(--btn-border-width) var(--space-xs);border-radius:var(--radius-sm);background:color-mix(in srgb,var(--text-muted) 12%,transparent);font-size:.85em}.plugin-install-actions{display:flex;gap:var(--space-sm);justify-content:flex-end}.plugin-list{display:flex;flex-direction:column;gap:var(--space-sm)}.plugin-item{display:flex;align-items:center;justify-content:space-between;padding:var(--space-md) var(--space-lg);background:var(--surface);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);transition:border-color var(--transition-fast)}.plugin-item:hover{border-color:var(--text-dim)}.plugin-info{display:flex;align-items:center;gap:var(--space-sm);min-width:0}.plugin-name{font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.plugin-version{font-size:.85rem}.plugin-state-badge{display:inline-flex;align-items:center;padding:var(--space-xs) var(--space-sm);border-radius:var(--radius-pill);font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;background:color-mix(in srgb,currentColor 12%,transparent)}.plugin-actions{display:flex;align-items:center;gap:var(--space-xs);flex-shrink:0}.plugin-manager-detail-header,.plugin-detail-title{display:flex;align-items:center;gap:var(--space-md);flex-wrap:wrap}.plugin-detail-name{margin:0}.plugin-detail-content{display:flex;flex-direction:column;gap:var(--space-lg)}.plugin-detail-card{background:var(--surface);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);padding:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-md)}.plugin-description{font-size:.95rem;color:var(--text-secondary, var(--text-muted));line-height:1.5}.plugin-detail-meta-row{display:flex;align-items:center;gap:var(--space-xs);font-size:.9rem;color:var(--text-muted)}.plugin-homepage a{display:inline-flex;align-items:center;gap:var(--space-xs);color:var(--color-info);font-size:.85rem}.plugin-detail-section-heading{margin:0;padding:0;border:0;font-size:.95rem}.plugin-settings-form{display:flex;flex-direction:column;gap:var(--space-lg);margin-top:var(--space-xs)}.plugin-settings-form .form-group{padding:0;margin:0}.plugin-settings-array{display:flex;flex-direction:column;gap:var(--space-sm)}.plugin-settings-array-item{display:flex;align-items:center;gap:var(--space-sm)}.plugin-settings-array-item input{flex:1}.plugin-detail-actions{display:flex;gap:var(--space-sm);padding-top:var(--space-md);border-top:var(--btn-border-width) solid var(--border);justify-content:flex-end}.plugin-manager .empty-state,.plugin-manager .loading-state,.plugin-manager .settings-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-sm);padding:var(--space-2xl);text-align:center;color:var(--text-muted)}.plugin-bundled-runtime-list{width:100%;display:flex;flex-direction:column;gap:var(--space-sm);margin-top:var(--space-sm)}.plugin-bundled-runtime-item{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm);padding:var(--space-sm) var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:var(--surface)}.plugin-bundled-runtime-meta{display:flex;align-items:center;gap:var(--space-sm);min-width:0}.plugin-bundled-runtime-name{color:var(--text);font-size:.9rem;font-weight:500}.plugin-bundled-runtime-badge{display:inline-flex;align-items:center;padding:var(--btn-border-width) var(--space-xs);border-radius:var(--radius-pill);background:var(--status-in-review-bg);color:var(--in-review);font-size:.75rem;font-weight:600;text-transform:uppercase}.plugin-bundled-runtime-section{display:flex;flex-direction:column;gap:var(--space-sm)}.plugin-bundled-runtime-header{display:flex;flex-direction:column;gap:var(--space-xs)}.plugin-bundled-runtime-heading{margin:0;font-size:.95rem}.plugin-bundled-runtime-description{margin:0;font-size:.85rem;color:var(--text-muted)}.plugin-bundled-runtime-status{display:inline-flex;align-items:center;padding:var(--btn-border-width) var(--space-xs);border-radius:var(--radius-pill);font-size:.75rem;font-weight:600;text-transform:uppercase}.plugin-bundled-runtime-status--installed{background:var(--status-done-bg);color:var(--done)}.plugin-bundled-runtime-status--available{background:var(--status-todo-bg);color:var(--todo)}@media(max-width:768px){.plugin-manager-detail-header{gap:var(--space-sm)}.plugin-detail-title{gap:var(--space-xs)}.plugin-detail-card{padding:var(--space-md);gap:var(--space-sm)}.plugin-list{gap:var(--space-xs)}.plugin-item{padding:var(--space-md);flex-direction:column;align-items:stretch;gap:var(--space-sm)}.plugin-info{width:100%;flex-wrap:wrap;row-gap:var(--space-xs)}.plugin-name{flex:1 1 100%;white-space:normal}.plugin-actions{width:100%;justify-content:flex-end;flex-wrap:wrap;gap:var(--space-sm)}.plugin-actions .btn-icon,.plugin-actions .toggle-switch{min-width:36px;min-height:36px}.plugin-actions .toggle-switch{display:inline-flex;align-items:center;justify-content:center}.plugin-detail-actions{flex-wrap:wrap;justify-content:flex-start}.plugin-detail-actions button{flex:1 1 auto;min-height:36px}.plugin-bundled-runtime-item{flex-direction:column;align-items:stretch}.plugin-bundled-runtime-item .btn{min-height:36px}}
@@ -1 +0,0 @@
1
- .prompt-manager{display:flex;flex-direction:column;gap:var(--space-md);padding:0 20px;margin-top:var(--space-md)}.prompt-manager-tabs{display:flex;gap:var(--space-xs);border-bottom:1px solid var(--border);padding-bottom:var(--space-sm)}.prompt-manager-tab{display:inline-flex;align-items:center;gap:var(--space-xs);padding:var(--space-sm) var(--space-md);background:none;border:1px solid transparent;border-radius:var(--radius-md);color:var(--text-muted);font-size:13px;cursor:pointer;transition:all var(--transition-fast)}.prompt-manager-tab:hover{color:var(--text);background:var(--surface)}.prompt-manager-tab.active{color:var(--text);background:var(--surface);border-color:var(--border)}.prompt-manager-content{min-height:200px}.prompt-manager-templates-tab,.prompt-manager-assignments-tab,.prompt-manager-overrides-tab{display:flex;flex-direction:column;gap:var(--space-lg)}.prompt-template-section{display:flex;flex-direction:column;gap:var(--space-md)}.prompt-template-section-title{font-size:14px;font-weight:600;color:var(--text);margin:0}.prompt-template-section-desc{font-size:12px;color:var(--text-muted);margin:0}.prompt-template-list{display:flex;flex-direction:column;gap:var(--space-md)}.prompt-template-card{padding:var(--space-md);background:var(--card);border:1px solid var(--border);border-radius:var(--radius-md);transition:border-color var(--transition-fast)}.prompt-template-card:hover{border-color:var(--text-dim)}.prompt-template-card-header{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-md);margin-bottom:var(--space-sm)}.prompt-template-card-info{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-sm)}.prompt-template-card-name{font-weight:600;color:var(--text);font-size:14px}.prompt-template-badge-built-in,.prompt-template-badge-custom,.prompt-template-badge-override{display:inline-flex;align-items:center;padding:2px 6px;font-size:10px;font-weight:500;border-radius:var(--radius-sm);text-transform:uppercase;letter-spacing:.02em}.prompt-template-badge-built-in{background:var(--surface);color:var(--text-muted);border:1px solid var(--border)}.prompt-template-badge-custom{background:color-mix(in srgb,var(--ws-info) 15%,transparent);color:var(--ws-info)}.prompt-template-badge-override{background:color-mix(in srgb,var(--ws-warning) 15%,transparent);color:var(--ws-warning)}.prompt-template-badge-role{display:inline-flex;align-items:center;padding:2px 6px;font-size:10px;font-weight:500;border-radius:var(--radius-sm)}.prompt-template-card-actions{display:flex;gap:var(--space-xs)}.prompt-template-card-actions .btn-icon{padding:var(--space-xs)}.prompt-template-card-description{font-size:12px;color:var(--text-muted);margin:0 0 var(--space-sm) 0;line-height:1.4}.prompt-template-card-preview{background:var(--surface);border-radius:var(--radius-sm);padding:var(--space-sm);overflow:hidden}.prompt-template-card-preview code{font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted);font-family:var(--font-mono);white-space:pre-wrap;word-break:break-word;display:block;max-height:120px;overflow-y:auto}.prompt-template-empty{padding:var(--space-lg);text-align:center;color:var(--text-muted);font-size:13px;background:var(--surface);border:1px dashed var(--border);border-radius:var(--radius-md)}.prompt-template-add-btn{align-self:flex-start;margin-top:var(--space-sm)}.prompt-template-editor{padding:var(--space-lg);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);margin-bottom:var(--space-lg)}.prompt-template-editor-title{font-size:14px;font-weight:600;color:var(--text);margin:0 0 var(--space-md) 0}.prompt-template-editor-fields{display:flex;flex-direction:column;gap:var(--space-md)}.prompt-template-field{display:flex;flex-direction:column;gap:var(--space-xs)}.prompt-template-field label{font-size:12px;font-weight:500;color:var(--text-muted)}.prompt-template-field input,.prompt-template-field select,.prompt-template-prompt-textarea{padding:var(--space-sm) var(--space-md);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-md);color:var(--text);font-size:13px;transition:border-color var(--transition-fast)}.prompt-template-field input:focus,.prompt-template-field select:focus,.prompt-template-prompt-textarea:focus{outline:none;border-color:var(--todo)}.prompt-template-prompt-textarea{font-family:var(--font-mono);font-size:12px;line-height:1.5;resize:vertical;min-height:120px}.prompt-template-error{padding:var(--space-sm);background:color-mix(in srgb,var(--color-error) 10%,transparent);border:1px solid var(--color-error);border-radius:var(--radius-sm);color:var(--color-error);font-size:12px}.prompt-template-editor-actions{display:flex;gap:var(--space-sm);justify-content:flex-end;margin-top:var(--space-sm)}.prompt-template-delete-confirm{padding:var(--space-md);background:color-mix(in srgb,var(--color-error) 10%,transparent);border:1px solid var(--color-error);border-radius:var(--radius-md);display:flex;flex-direction:column;gap:var(--space-sm)}.prompt-template-delete-confirm p{margin:0;font-size:13px;color:var(--text)}.prompt-template-delete-actions{display:flex;gap:var(--space-sm)}.prompt-assignments-desc{font-size:12px;color:var(--text-muted);margin:0}.prompt-role-assignment-list{display:flex;flex-direction:column;gap:var(--space-md)}.prompt-role-assignment-row{display:flex;align-items:center;justify-content:space-between;gap:var(--space-lg);padding:var(--space-md);background:var(--card);border:1px solid var(--border);border-radius:var(--radius-md)}.prompt-role-assignment-label{display:flex;align-items:center;gap:var(--space-md)}.prompt-role-badge{display:inline-flex;align-items:center;padding:var(--space-xs) var(--space-sm);font-size:12px;font-weight:600;border-radius:var(--radius-sm)}.prompt-role-assignment-status{font-size:12px;color:var(--text-muted)}.prompt-role-select{min-width:200px;padding:var(--space-sm) var(--space-md);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-md);color:var(--text);font-size:13px;cursor:pointer}.prompt-role-select:focus{outline:none;border-color:var(--todo)}.prompt-assignments-note{margin-top:var(--space-md);padding:var(--space-md);background:var(--surface);border-radius:var(--radius-md);font-size:12px;color:var(--text-muted);line-height:1.5}.prompt-assignments-note strong{color:var(--text)}.prompt-overrides-desc{font-size:12px;color:var(--text-muted);margin:0}.prompt-overrides-list{display:flex;flex-direction:column;gap:var(--space-md)}.prompt-override-item{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden}.prompt-override-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-md);cursor:pointer;transition:background var(--transition-fast)}.prompt-override-header:hover{background:var(--card-hover)}.prompt-override-info{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-sm)}.prompt-override-name{font-weight:600;color:var(--text);font-size:13px}.prompt-override-key{font-size:11px;font-family:var(--font-mono);color:var(--text-muted);padding:2px 4px;background:var(--surface);border-radius:var(--radius-sm)}.prompt-override-badge{display:inline-flex;align-items:center;padding:2px 6px;font-size:10px;font-weight:500;background:color-mix(in srgb,var(--ws-warning) 15%,transparent);color:var(--ws-warning);border-radius:var(--radius-sm)}.prompt-override-expand-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;background:none;border:none;color:var(--text-muted);cursor:pointer;border-radius:var(--radius-sm);transition:color var(--transition-fast),background var(--transition-fast)}.prompt-override-expand-btn:hover{color:var(--text);background:var(--surface)}.prompt-override-description{font-size:12px;color:var(--text-muted);margin:0;padding:0 var(--space-md) var(--space-md);line-height:1.4}.prompt-override-editor{padding:var(--space-md);border-top:1px solid var(--border);background:var(--surface);display:flex;flex-direction:column;gap:var(--space-sm)}.prompt-override-textarea{padding:var(--space-sm) var(--space-md);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-md);color:var(--text);font-size:12px;font-family:var(--font-mono);line-height:1.5;resize:vertical;min-height:80px;transition:border-color var(--transition-fast)}.prompt-override-textarea:focus{outline:none;border-color:var(--todo)}.prompt-override-footer{display:flex;align-items:center;gap:var(--space-md)}.prompt-override-hint{font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted)}.prompt-override-header-actions{display:flex;align-items:center;gap:var(--space-xs)}.prompt-override-fullscreen-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;background:none;border:none;color:var(--text-muted);cursor:pointer;border-radius:var(--radius-sm);transition:color var(--transition-fast),background var(--transition-fast)}.prompt-override-fullscreen-btn:hover{color:var(--text);background:var(--surface)}.prompt-override-fullscreen{position:fixed;inset:0;z-index:10000;background:var(--surface);padding:max(var(--space-lg),env(safe-area-inset-top,0px)) max(var(--space-lg),env(safe-area-inset-right,0px)) max(var(--space-lg),env(safe-area-inset-bottom,0px)) max(var(--space-lg),env(safe-area-inset-left,0px));display:flex;flex-direction:column}.prompt-override-fullscreen-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--space-md);flex-shrink:0}.prompt-override-fullscreen-title{font-size:13px;font-weight:600;color:var(--text);display:flex;align-items:center;gap:var(--space-sm)}.prompt-override-fullscreen-close{display:flex;align-items:center;justify-content:center;gap:var(--space-xs);padding:var(--space-xs) var(--space-sm);background:none;border:1px solid var(--border);border-radius:var(--radius-md);color:var(--text-muted);cursor:pointer;font-size:12px;transition:all var(--transition-fast)}.prompt-override-fullscreen-close:hover{color:var(--text);border-color:var(--text-muted)}.prompt-override-fullscreen-close:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.prompt-override-fullscreen textarea{flex:1;min-height:unset;resize:none;border-radius:var(--radius-md);font-size:14px;line-height:1.6}.prompt-template-fullscreen-pre{flex:1;font-family:var(--font-mono);font-size:13px;line-height:1.6;color:var(--text);white-space:pre-wrap;word-break:break-word;overflow-y:auto;padding:var(--space-md);background:var(--bg);border-radius:var(--radius-md);border:1px solid var(--border);margin:0}.prompt-override-fullscreen .prompt-override-footer{flex-shrink:0;padding-top:var(--space-sm)}.prompt-template-prompt-label-row{display:flex;align-items:center;gap:var(--space-sm);margin-bottom:var(--space-xs)}.prompt-template-prompt-label-row label{display:block}.prompt-template-fullscreen-btn{vertical-align:middle}.prompt-template-prompt-label-row .prompt-template-fullscreen-btn{margin-left:var(--space-xs)}@media(max-width:768px){.prompt-manager{padding:0 14px}.prompt-manager-tabs{flex-wrap:wrap}.prompt-manager-tab{flex:1;justify-content:center;min-width:calc(50% - var(--space-xs))}.prompt-role-assignment-row{flex-direction:column;align-items:stretch;gap:var(--space-sm)}.prompt-role-select{width:100%}.prompt-template-editor-actions{flex-direction:column}.prompt-template-editor-actions .btn{width:100%}.prompt-override-fullscreen{padding:var(--space-md)}.prompt-override-fullscreen textarea{font-size:16px}}.new-task-modal .form-group small{display:block;margin-top:var(--space-sm);font-size:12px;color:var(--text-muted);line-height:1.4}.new-task-modal textarea{min-height:80px;transition:height .1s ease-out}.selected-deps{display:flex;flex-wrap:wrap;gap:6px;margin-top:var(--space-sm);padding:2px 0}.dep-chip{display:inline-flex;align-items:center;gap:var(--space-xs);padding:3px 8px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);font-size:12px;color:var(--text);font-family:var(--font-mono);max-width:100%}.dep-chip-remove{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:12px;line-height:1;padding:0;margin-left:2px;border-radius:50%;transition:background .1s,color .1s}.dep-chip-remove:hover{color:var(--color-error);background:color-mix(in srgb,var(--color-error) 10%,transparent)}.model-select-row{display:flex;align-items:center;gap:var(--space-md);margin-bottom:var(--space-md)}.model-select-row:last-child{margin-bottom:0}.model-select-label{width:70px;flex-shrink:0;font-size:13px;color:var(--text-muted);text-align:right}@media(max-width:768px){.model-select-row{flex-direction:column;align-items:stretch;gap:var(--space-xs)}.model-select-label{width:auto;text-align:left}}.onboarding-disclosure{display:flex;flex-direction:column;margin-top:var(--space-sm)}.onboarding-disclosure-trigger{display:flex;align-items:center;gap:var(--space-xs);background:none;border:none;color:var(--text-muted);font-size:var(--font-size-sm, 12px);cursor:pointer;padding:var(--space-xs) 0;transition:color var(--transition-fast);font-family:inherit}.onboarding-disclosure-trigger:hover{color:var(--text)}.onboarding-disclosure-trigger:focus-visible{outline:var(--focus-ring-strong);border-radius:var(--radius-sm)}.onboarding-disclosure-chevron{width:14px;height:14px;transition:transform var(--transition-fast);flex-shrink:0}.onboarding-disclosure-trigger[aria-expanded=true] .onboarding-disclosure-chevron{transform:rotate(90deg)}.onboarding-disclosure-content{padding:var(--space-sm) 0 var(--space-sm) calc(var(--space-sm) + var(--space-lg) - var(--space-xs));color:var(--text-muted);font-size:var(--font-size-sm, 12px);line-height:1.5;animation:onboarding-disclosure-enter var(--transition-fast) ease-out}@keyframes onboarding-disclosure-enter{0%{opacity:0;transform:translateY(calc(var(--space-xs) * -1))}to{opacity:1;transform:translateY(0)}}@media(max-width:768px){.onboarding-disclosure-trigger{min-height:calc(var(--space-lg) + var(--space-lg) + var(--space-xs));padding:var(--space-sm) 0}}@keyframes custom-provider-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.custom-providers-section .onboarding-disclosure-content{margin-top:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-sm)}.custom-provider-list{display:flex;flex-direction:column;gap:var(--space-sm)}.custom-provider-item{display:flex;align-items:center;justify-content:space-between;padding:var(--space-sm) var(--space-md);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.custom-provider-item:hover{border-color:var(--text-dim)}.custom-provider-item-info{display:flex;flex-direction:column;gap:var(--space-xs);min-width:0}.custom-provider-item-name{font-weight:600;color:var(--text)}.custom-provider-item-meta{color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.custom-provider-item-actions{display:flex;gap:var(--space-xs);flex-shrink:0}.custom-provider-badge{display:inline-flex;align-items:center;padding:var(--space-xs);border-radius:var(--radius-pill);background:color-mix(in srgb,var(--color-info) 15%,transparent);color:var(--color-info)}.custom-provider-empty{color:var(--text-muted);padding:var(--space-sm) 0}.custom-provider-add-btn{margin-top:var(--space-sm)}.custom-provider-form{padding:var(--space-md);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);margin-top:var(--space-sm)}.custom-provider-form-row{margin-bottom:var(--space-sm)}.custom-provider-form-actions{display:flex;gap:var(--space-sm);margin-top:var(--space-md)}.custom-provider-form-error{display:flex;align-items:center;gap:var(--space-xs);color:var(--color-error);margin-top:var(--space-xs);background:color-mix(in srgb,var(--color-error) 10%,transparent);padding:var(--space-xs) var(--space-sm);border-radius:var(--radius-sm)}.custom-provider-item-edit-form{margin-top:var(--space-xs)}.spin{animation:custom-provider-spin calc(var(--transition-slow) * 4) linear infinite}@media(max-width:768px){.custom-provider-item{flex-direction:column;align-items:flex-start;gap:var(--space-xs)}.custom-provider-item-meta{max-width:100%}.custom-provider-form{padding:var(--space-sm)}.custom-provider-item-actions{align-self:flex-end;margin-top:var(--space-xs)}}