@runfusion/fusion 0.51.0 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/dist/bin.js +9038 -4527
  2. package/dist/client/.vite/manifest.json +329 -329
  3. package/dist/client/assets/{AgentDetailView-CjwOlcMI.js → AgentDetailView-C-PM8cwG.js} +1 -1
  4. package/dist/client/assets/{AgentPermissionPolicyEditor-CD8znNHS.js → AgentPermissionPolicyEditor-DrVW4VPc.js} +1 -1
  5. package/dist/client/assets/{AgentsView-CTjNaKu-.js → AgentsView-DJJO0laF.js} +6 -11
  6. package/dist/client/assets/ChatView-C7uTm5hO.js +16 -0
  7. package/dist/client/assets/ChatView-D_2wBIIx.css +1 -0
  8. package/dist/client/assets/CommandCenter-CKvo0MuO.js +71 -0
  9. package/dist/client/assets/{DevServerView-BE_o7v9j.js → DevServerView-BHLG4Mxg.js} +1 -1
  10. package/dist/client/assets/{DirectoryPicker-BpcPo65A.js → DirectoryPicker-CRY-rpnj.js} +1 -1
  11. package/dist/client/assets/{DocumentsView-Cpma23hu.js → DocumentsView-DhC4dnXD.js} +1 -1
  12. package/dist/client/assets/{EvalsView-DYSobhb7.js → EvalsView-DsnLOVZB.js} +1 -1
  13. package/dist/client/assets/{ExperimentalAgentOnboardingModal-D_iQqD-n.js → ExperimentalAgentOnboardingModal-B4iFX60E.js} +1 -1
  14. package/dist/client/assets/GoalsView-D5bzq6W9.js +2 -0
  15. package/dist/client/assets/{InsightsView-DZyMvYQ8.js → InsightsView-Drpu72M4.js} +1 -1
  16. package/dist/client/assets/{MemoryView-B9Z6cRma.js → MemoryView-auLBP3UW.js} +1 -1
  17. package/dist/client/assets/{PiExtensionsManager-BQt3JU60.js → PiExtensionsManager-RlbkXf_t.js} +1 -1
  18. package/dist/client/assets/{PluginManager-DEsUstVo.js → PluginManager-BJMUacpG.js} +1 -1
  19. package/dist/client/assets/{PullRequestView-B7k8ogy4.js → PullRequestView-344B9WF-.js} +1 -1
  20. package/dist/client/assets/{ResearchView-BseF58_R.js → ResearchView-BNqt-f53.js} +1 -1
  21. package/dist/client/assets/{SecretsView-bkNS5VBC.js → SecretsView-Be8Tm8It.js} +1 -1
  22. package/dist/client/assets/SessionTerminal-CumHUelZ.js +2 -0
  23. package/dist/client/assets/SettingsModal-AJfer-ve.js +21 -0
  24. package/dist/client/assets/{SettingsModal-DAH7LuLw.js → SettingsModal-B28DuhaN.js} +1 -1
  25. package/dist/client/assets/SettingsModal-CaE4JYxi.css +1 -0
  26. package/dist/client/assets/{SetupWizardModal-Bm6bG31V.js → SetupWizardModal-y2j9aZoi.js} +2 -2
  27. package/dist/client/assets/ShadcnColorPicker-Cc72uPKJ.js +11 -0
  28. package/dist/client/assets/ShadcnColorPicker-CyeAnJUU.css +1 -0
  29. package/dist/client/assets/{SkillsView-D_UEJY_f.js → SkillsView-HQp7UTdA.js} +1 -1
  30. package/dist/client/assets/{TodoView-CMCoPep1.js → TodoView-DF7_qWGH.js} +1 -1
  31. package/dist/client/assets/WorkflowNodeEditor-BjpqTIYE.js +8 -0
  32. package/dist/client/assets/WorkflowNodeEditor-Df-_206_.css +1 -0
  33. package/dist/client/assets/{agentSkills-BiipFw1z.js → agentSkills-Cy_HrYHd.js} +1 -1
  34. package/dist/client/assets/{app-A1yCJR4Q.js → app-CGubyqAW.js} +3 -3
  35. package/dist/client/assets/{app-T5iMjZpX.js → app-CrQpHbIs.js} +1 -1
  36. package/dist/client/assets/{app-Bfiafek7.js → app-DboK-0Ty.js} +3 -3
  37. package/dist/client/assets/{app-Bh-Xj32t.js → app-DjnYET2y.js} +1 -1
  38. package/dist/client/assets/{app-zR_n4GL2.js → app-MacS555z.js} +1 -1
  39. package/dist/client/assets/{app-DxJHfzxz.js → app-nvVayIeU.js} +3 -3
  40. package/dist/client/assets/{architectureDiagram-3BPJPVTR-glwWkaDt.js → architectureDiagram-3BPJPVTR-4ur4sxlr.js} +1 -1
  41. package/dist/client/assets/{blockDiagram-GPEHLZMM-C8DhxwG4.js → blockDiagram-GPEHLZMM-BgZeqq_q.js} +1 -1
  42. package/dist/client/assets/{c4Diagram-AAUBKEIU-CQXf6PzI.js → c4Diagram-AAUBKEIU-BQtdOIrm.js} +1 -1
  43. package/dist/client/assets/channel-Dn5XowfJ.js +1 -0
  44. package/dist/client/assets/{chunk-2J33WTMH-kak65s83.js → chunk-2J33WTMH-C1k1PBy1.js} +1 -1
  45. package/dist/client/assets/{chunk-4BX2VUAB-B_yEpoxU.js → chunk-4BX2VUAB-hNujwvSn.js} +1 -1
  46. package/dist/client/assets/{chunk-55IACEB6-C9lQVeH5.js → chunk-55IACEB6-CnXV9LyI.js} +1 -1
  47. package/dist/client/assets/{chunk-727SXJPM-D4SVzqNs.js → chunk-727SXJPM-B-ocMdYN.js} +1 -1
  48. package/dist/client/assets/{chunk-AQP2D5EJ-DBHuj4BH.js → chunk-AQP2D5EJ-CWNRUL6C.js} +1 -1
  49. package/dist/client/assets/{chunk-FMBD7UC4-BJ3ghjau.js → chunk-FMBD7UC4-DerrCiYe.js} +1 -1
  50. package/dist/client/assets/{chunk-ND2GUHAM-CE4tkh6e.js → chunk-ND2GUHAM-BfcSPlX-.js} +1 -1
  51. package/dist/client/assets/{chunk-QZHKN3VN-DmVw_cEu.js → chunk-QZHKN3VN-BaWScAds.js} +1 -1
  52. package/dist/client/assets/classDiagram-4FO5ZUOK-zSOW-KNk.js +1 -0
  53. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-zSOW-KNk.js +1 -0
  54. package/dist/client/assets/{cose-bilkent-S5V4N54A-DI_-BOYE.js → cose-bilkent-S5V4N54A-n0Oeinz2.js} +1 -1
  55. package/dist/client/assets/{dagre-BM42HDAG-ywUbHZxt.js → dagre-BM42HDAG-CUtehSt2.js} +1 -1
  56. package/dist/client/assets/{dashboard-view-r4NTTh_X.js → dashboard-view-BW3GHqgb.js} +218 -218
  57. package/dist/client/assets/{dashboard-view-DJvdban3.js → dashboard-view-DWKCxtr5.js} +1 -1
  58. package/dist/client/assets/{diagram-2AECGRRQ-CAGucHCe.js → diagram-2AECGRRQ-Bz4aOzhR.js} +1 -1
  59. package/dist/client/assets/{diagram-5GNKFQAL-D_1uzVtW.js → diagram-5GNKFQAL-UoxIMwPf.js} +1 -1
  60. package/dist/client/assets/{diagram-KO2AKTUF-D7zY4Nlm.js → diagram-KO2AKTUF-BYR7hloS.js} +1 -1
  61. package/dist/client/assets/{diagram-LMA3HP47-C1T9eOzA.js → diagram-LMA3HP47-BR9MaP8U.js} +1 -1
  62. package/dist/client/assets/{diagram-OG6HWLK6-sWxhPvzU.js → diagram-OG6HWLK6-BOfldYHv.js} +1 -1
  63. package/dist/client/assets/{erDiagram-TEJ5UH35-DfHtnaNg.js → erDiagram-TEJ5UH35-B8x9mfOs.js} +1 -1
  64. package/dist/client/assets/{flowDiagram-I6XJVG4X-Brbb_Jlh.js → flowDiagram-I6XJVG4X-DBnTroCV.js} +1 -1
  65. package/dist/client/assets/{folder-open-BLwukrE0.js → folder-open-CFze34Eq.js} +1 -1
  66. package/dist/client/assets/{ganttDiagram-6RSMTGT7-CLvZ7891.js → ganttDiagram-6RSMTGT7-BfzFy7iz.js} +1 -1
  67. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-DD56Jsa3.js → gitGraphDiagram-PVQCEYII-CNTFu6IY.js} +1 -1
  68. package/dist/client/assets/index-QnHUwSjw.css +1 -0
  69. package/dist/client/assets/index-Y-vyXPPN.js +1331 -0
  70. package/dist/client/assets/{infoDiagram-5YYISTIA-uXai801q.js → infoDiagram-5YYISTIA-DJiBRaAl.js} +1 -1
  71. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-C_bWlUP_.js → ishikawaDiagram-YF4QCWOH-CIY9t4cc.js} +1 -1
  72. package/dist/client/assets/{journeyDiagram-JHISSGLW-B2kB9niE.js → journeyDiagram-JHISSGLW-HLMZmcjY.js} +1 -1
  73. package/dist/client/assets/{kanban-definition-UN3LZRKU-BJwlpR9z.js → kanban-definition-UN3LZRKU-x9nKoxCI.js} +1 -1
  74. package/dist/client/assets/{linear-dXivciGL.js → linear-CwI45w2t.js} +1 -1
  75. package/dist/client/assets/{mermaid.core-0hUjZF5S.js → mermaid.core-pHkdB6fb.js} +4 -4
  76. package/dist/client/assets/{mindmap-definition-RKZ34NQL-DsTgTpX-.js → mindmap-definition-RKZ34NQL-Bs_4Tofu.js} +1 -1
  77. package/dist/client/assets/{pieDiagram-4H26LBE5-BUQsNWHN.js → pieDiagram-4H26LBE5-BGHz9JGZ.js} +1 -1
  78. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-DOYWgfAz.js → quadrantDiagram-W4KKPZXB-xHSR7cAR.js} +1 -1
  79. package/dist/client/assets/{requirementDiagram-4Y6WPE33-DUnPKaMd.js → requirementDiagram-4Y6WPE33-D7YMNM44.js} +1 -1
  80. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-Btl4NRo-.js → sankeyDiagram-5OEKKPKP-OAXuab3Y.js} +1 -1
  81. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-b0hyJ_Wr.js → sequenceDiagram-3UESZ5HK-BZCjKFVL.js} +1 -1
  82. package/dist/client/assets/{shield-alert-yWvC7t2v.js → shield-alert-BBK8Risa.js} +1 -1
  83. package/dist/client/assets/{stateDiagram-AJRCARHV-orREjkd9.js → stateDiagram-AJRCARHV-COnJQqA4.js} +1 -1
  84. package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-DYJRRNh-.js → stateDiagram-v2-BHNVJYJU-Diml4Nhm.js} +1 -1
  85. package/dist/client/assets/{time-DoDTxsna.js → time-Ckmi30gH.js} +1 -1
  86. package/dist/client/assets/{timeline-definition-PNZ67QCA-DZga7lqO.js → timeline-definition-PNZ67QCA-DHIKvV9L.js} +1 -1
  87. package/dist/client/assets/{upload-BsYRkl_8.js → upload-CqUJUdZW.js} +1 -1
  88. package/dist/client/assets/{users-dyoJEvrM.js → users-CAE-FEzI.js} +1 -1
  89. package/dist/client/assets/{vendor-reactflow-Bg-Qjzh8.js → vendor-reactflow-CnI7NMXG.js} +1 -1
  90. package/dist/client/assets/{vennDiagram-CIIHVFJN-C2P26V71.js → vennDiagram-CIIHVFJN-o9AxLDoL.js} +1 -1
  91. package/dist/client/assets/{wardley-L42UT6IY-ckctH9bL.js → wardley-L42UT6IY-B7MIazje.js} +1 -1
  92. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-9It3QAYs.js → wardleyDiagram-YWT4CUSO-B6qUJx0N.js} +1 -1
  93. package/dist/client/assets/{xychartDiagram-2RQKCTM6-Dj3sSBqg.js → xychartDiagram-2RQKCTM6-13mSXuCA.js} +1 -1
  94. package/dist/client/index.html +8 -8
  95. package/dist/client/theme-data.css +140 -0
  96. package/dist/client/version.json +1 -1
  97. package/dist/droid-cli/package.json +1 -1
  98. package/dist/extension.js +7126 -3447
  99. package/dist/pi-claude-cli/index.ts +13 -0
  100. package/dist/pi-claude-cli/package.json +1 -1
  101. package/dist/pi-claude-cli/src/__tests__/process-manager.test.ts +2 -2
  102. package/dist/pi-claude-cli/src/__tests__/provider.test.ts +27 -4
  103. package/dist/plugin-sdk/index.d.ts +32 -1
  104. package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
  105. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  106. package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
  107. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  108. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  109. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  110. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  111. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  112. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  113. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  114. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  115. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  116. package/package.json +1 -1
  117. package/skill/fusion/SKILL.md +1 -0
  118. package/skill/fusion/references/engine-tools.md +3 -3
  119. package/skill/fusion/references/extension-tools.md +81 -4
  120. package/skill/fusion/references/fusion-capabilities.md +8 -0
  121. package/dist/client/assets/ChatView-DCWypaw3.js +0 -19
  122. package/dist/client/assets/ChatView-DwIIrJxb.css +0 -1
  123. package/dist/client/assets/CommandCenter-C4v0FMxx.js +0 -71
  124. package/dist/client/assets/GoalsView-B6Wfxk59.js +0 -2
  125. package/dist/client/assets/SessionTerminal-BSllyqgF.js +0 -2
  126. package/dist/client/assets/SettingsModal-Dso0K76J.js +0 -21
  127. package/dist/client/assets/SettingsModal-tUDR6nJ9.css +0 -1
  128. package/dist/client/assets/ShadcnColorPicker-CLiOvo7W.js +0 -11
  129. package/dist/client/assets/ShadcnColorPicker-CzZo9UOD.css +0 -1
  130. package/dist/client/assets/WorkflowNodeEditor-BeQcn0Wa.js +0 -8
  131. package/dist/client/assets/WorkflowNodeEditor-WYIxHTxY.css +0 -1
  132. package/dist/client/assets/channel-BY6zFSV1.js +0 -1
  133. package/dist/client/assets/classDiagram-4FO5ZUOK-CeX_WCiC.js +0 -1
  134. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CeX_WCiC.js +0 -1
  135. package/dist/client/assets/index-DAv17W73.js +0 -1317
  136. package/dist/client/assets/index-DhBnj8YN.css +0 -1
@@ -1,21 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/PluginManager-DEsUstVo.js","assets/vendor-react-SZ_qB27O.js","assets/index-DAv17W73.js","assets/vendor-i18n-GF3RlKbq.js","assets/vendor-reactflow-Bg-Qjzh8.js","assets/vendor-reactflow-C5ap-Sga.css","assets/vendor-xterm-BNq00GSj.js","assets/vendor-xterm-LZoznX6r.css","assets/vendor-codemirror-jBKmHyH0.js","assets/index-DhBnj8YN.css","assets/DirectoryPicker-BpcPo65A.js","assets/folder-open-BLwukrE0.js","assets/DirectoryPicker-0rspvcMz.css","assets/PluginManager-DSiHizRD.css","assets/PiExtensionsManager-BQt3JU60.js","assets/AgentPermissionPolicyEditor-CD8znNHS.js","assets/AgentPermissionPolicyEditor-CGxjOr6G.css","assets/PiExtensionsManager-kgTOHPE9.css"])))=>i.map(i=>d[i]);
2
- import{r as o,j as e}from"./vendor-react-SZ_qB27O.js";import{c as zi,fl as Ze,fm as Vi,fn as Yi,c2 as Qi,fo as Us,fp as Ji,fq as mt,fr as Dt,bM as pt,fs as Xi,ft as Zi,fu as el,fv as tl,fw as Ua,dy as gt,h as sl,b8 as al,fx as nl,fy as Ns,fz as rl,fA as Ss,fB as il,fC as ll,fD as Rn,fE as Hs,P as Ot,R as Ks,cl as ol,I as Bt,J as Gt,fc as cl,a6 as Ha,X as dl,al as ze,bP as Ke,fF as ul,fG as ml,fH as pl,fI as hl,fJ as gl,fK as bl,L as qe,q as fl,aK as Ka,fL as vl,fM as xl,fN as yl,fO as jl,fP as qs,dw as bt,fQ as In,a8 as En,fR as kl,fS as wl,aw as Qs,fT as Cl,fU as Nl,aq as et,fV as Sl,fW as Pl,fX as Al,fY as Ml,fZ as Tl,f_ as Rl,f$ as qa,g0 as za,g1 as Il,di as Rt,dh as Ps,ad as El,o as Fl,ey as Dl,g2 as Ll,g3 as Ol,el as Bl,bF as Va,em as Gl,g4 as _l,g5 as Wl,g6 as $l,bd as Ul,b6 as Hl,_ as Fn,ai as Kl,ae as Dn,dz as ql,b$ as zl,W as Vl,ce as Yl,g7 as Ql,g8 as As,u as Jl,aR as Ya,cN as Xl,g9 as Qa,ga as Ja,bp as pe,gb as Zl,gc as eo,gd as to,ge as so,c1 as Xa,gf as Za,bL as ao,gg as en,gh as no,gi as Ms,gj as ro,gk as io,gl as tn,gm as lo,aT as sn,aS as oo,gn as co,go as uo,gp as mo,gq as po,gr as ho,gs as go,gt as bo,gu as fo,gv as vo,gw as xo,gx as yo,dk as jo,aV as ko,gy as wo,aW as Co,b2 as No,aY as So,b1 as Po,aX as Ao,gz as Mo,a2 as To,ca as Ro,ac as an,f3 as Io,gA as Ts,fi as Eo,gB as Fo,gC as Do}from"./index-DAv17W73.js";import{T as Lo,S as Oo,M as Bo,C as nn,a as Go}from"./ShadcnColorPicker-CLiOvo7W.js";import{u as Z,T as zs}from"./vendor-i18n-GF3RlKbq.js";import{U as _o}from"./upload-BsYRkl_8.js";import{SecretsView as Wo}from"./SecretsView-bkNS5VBC.js";import{B as $o,A as Uo}from"./AgentPermissionPolicyEditor-CD8znNHS.js";import{U as Ho}from"./users-dyoJEvrM.js";import{u as Ko}from"./SettingsModal-DAH7LuLw.js";import"./vendor-reactflow-Bg-Qjzh8.js";import"./vendor-xterm-BNq00GSj.js";import"./vendor-codemirror-jBKmHyH0.js";/**
3
- * @license lucide-react v1.7.0 - ISC
4
- *
5
- * This source code is licensed under the ISC license.
6
- * See the LICENSE file in the root directory of this source tree.
7
- */const qo=[["path",{d:"M14 17H5",key:"gfn3mx"}],["path",{d:"M19 7h-9",key:"6i9tg"}],["circle",{cx:"17",cy:"17",r:"3",key:"18b49y"}],["circle",{cx:"7",cy:"7",r:"3",key:"dfmy0x"}]],zo=zi("settings-2",qo);function Ne(a,t,s){return{path:a,code:t,message:s}}function Vo(a,t){return a===void 0?{value:void 0,errors:[]}:!Array.isArray(a)||!a.every(s=>typeof s=="string"&&s.trim().length>0)?{errors:[Ne(t,"invalid-args","Expected an array of non-empty strings")]}:{value:a.map(s=>s.trim()),errors:[]}}function rn(a,t){if(a===void 0)return{value:void 0,errors:[]};if(!a||typeof a!="object"||Array.isArray(a))return{errors:[Ne(t,"invalid-sensitive-map","Expected an object whose values are secret references")]};const s={},c=[];for(const[r,m]of Object.entries(a)){if(!r.trim()){c.push(Ne(`${t}.${r}`,"invalid-sensitive-map","Sensitive field names must be non-empty"));continue}if(typeof m=="string"){c.push(Ne(`${t}.${r}`,"plaintext-secret","Sensitive MCP values must be Fusion secret references, never plaintext strings"));continue}if(!Ze(m)){c.push(Ne(`${t}.${r}`,"invalid-sensitive-map","Sensitive MCP values must be { secretRef, scope } objects"));continue}s[r.trim()]={secretRef:m.secretRef.trim(),scope:m.scope}}return c.length>0?{errors:c}:{value:s,errors:[]}}function Js(a,t="server"){if(!a||typeof a!="object"||Array.isArray(a))return{errors:[Ne(t,"invalid-shape","MCP server definition must be an object")]};const s=a,c=[];(typeof s.name!="string"||s.name.trim().length===0)&&c.push(Ne(`${t}.name`,"invalid-name","MCP server name is required"));const r=typeof s.enabled=="boolean"?s.enabled:void 0;if(s.transport==="stdio"){(typeof s.command!="string"||s.command.trim().length===0)&&c.push(Ne(`${t}.command`,"missing-command","stdio MCP servers require a command"));const m=Vo(s.args,`${t}.args`),i=rn(s.env,`${t}.env`);return c.push(...m.errors,...i.errors),c.length>0?{errors:c}:{value:{name:s.name.trim(),...r!==void 0?{enabled:r}:{},transport:"stdio",command:s.command.trim(),...m.value?{args:m.value}:{},...i.value?{env:i.value}:{}},errors:[]}}if(s.transport==="sse"||s.transport==="streamable-http"){(typeof s.url!="string"||s.url.trim().length===0)&&c.push(Ne(`${t}.url`,"missing-url",`${s.transport} MCP servers require a url`));const m=rn(s.headers,`${t}.headers`);return c.push(...m.errors),c.length>0?{errors:c}:{value:{name:s.name.trim(),...r!==void 0?{enabled:r}:{},transport:s.transport,url:s.url.trim(),...m.value?{headers:m.value}:{}},errors:[]}}return c.push(Ne(`${t}.transport`,"invalid-transport","MCP transport must be stdio, sse, or streamable-http")),{errors:c}}function _t(a){return Js(a).value}function Yo(a,t="servers"){if(!Array.isArray(a))return{errors:[Ne(t,"invalid-shape","MCP servers must be an array")]};const s=[],c=[],r=new Set;return a.forEach((m,i)=>{const n=Js(m,`${t}.${i}`);if(s.push(...n.errors),!!n.value){if(r.has(n.value.name)){s.push(Ne(`${t}.${i}.name`,"duplicate-name",`Duplicate MCP server name: ${n.value.name}`));return}r.add(n.value.name),c.push(n.value)}}),s.length>0?{errors:s}:{value:c,errors:[]}}function Ln(a){return{enabled:a?.enabled===!0,servers:Array.isArray(a?.servers)?a.servers:[]}}function ln(a){return Ln(a).servers?.map(_t).filter(t=>!!t)??[]}function Qo(a,t){try{const s=Ln(a?.mcpServers),c=t?.mcpServers;if(!(typeof c?.enabled=="boolean"?c.enabled:s.enabled))return[];const m=new Map;for(const i of ln(a?.mcpServers))i.enabled!==!1&&m.set(i.name,i);for(const i of ln(c)){if(i.enabled===!1){m.delete(i.name);continue}m.set(i.name,i)}return[...m.values()].filter(i=>i.enabled!==!1)}catch{return[]}}function Jo(a){if(typeof a!="string")return{data:a};try{return{data:JSON.parse(a)}}catch(t){return{error:t instanceof Error?t.message:String(t)}}}function Xo(a,t,s){const c=r=>r.trim().replace(/[^A-Za-z0-9_.-]+/gu,"_").replace(/^_+|_+$/gu,"");return["mcp",c(a),c(t),c(s)].filter(Boolean).join(".")}function on(a){const{value:t,serverName:s,field:c,scope:r,secretsToCreate:m,errors:i}=a;if(t===void 0)return;if(!t||typeof t!="object"||Array.isArray(t)){i.push(`${s}.${c} must be an object`);return}const n={};for(const[p,A]of Object.entries(t)){if(Ze(A)){n[p]={secretRef:A.secretRef.trim(),scope:A.scope};continue}if(typeof A=="string"){const j=Xo(s,c,p);n[p]={secretRef:j,scope:r},m.push({serverName:s,field:c,key:p,scope:r,suggestedKey:j,plaintextValue:A});continue}i.push(`${s}.${c}.${p} must be a string or MCP secret reference`)}return Object.keys(n).length>0?n:void 0}function Zo(a,t={}){const s=Jo(a);if(s.error)return{definitions:[],secretsToCreate:[],errors:[s.error]};const c=[],r=[],m=t.scope??"project",i=s.data;if(!i||typeof i!="object"||Array.isArray(i))return{definitions:[],secretsToCreate:r,errors:["MCP import data must be an object"]};const n=i.mcpServers;if(!n||typeof n!="object"||Array.isArray(n))return{definitions:[],secretsToCreate:r,errors:["MCP import data must contain an mcpServers object"]};const p=[],A=new Set;for(const[j,u]of Object.entries(n)){if(!u||typeof u!="object"||Array.isArray(u)){c.push(`${j} must be an object`);continue}const d=u,C=typeof d.enabled=="boolean"?d.enabled:void 0,b={name:typeof d.name=="string"&&d.name.trim()?d.name.trim():j,...C!==void 0?{enabled:C}:{}},h=typeof d.transport=="string"?d.transport:typeof d.command=="string"?"stdio":void 0;let f;if(h==="stdio"?f=_t({...b,transport:"stdio",command:d.command,args:d.args,env:on({value:d.env,serverName:b.name,field:"env",scope:m,secretsToCreate:r,errors:c})}):h==="sse"||h==="streamable-http"?f=_t({...b,transport:h,url:d.url,headers:on({value:d.headers,serverName:b.name,field:"headers",scope:m,secretsToCreate:r,errors:c})}):c.push(`${j}.transport must be stdio, sse, or streamable-http`),!f){c.push(`${j} is not a valid MCP server definition`);continue}if(A.has(f.name)){c.push(`Duplicate MCP server name: ${f.name}`);continue}A.add(f.name),p.push(f)}return{definitions:p,secretsToCreate:r,errors:c}}function cn(a){if(!a)return;const t={};for(const[s,c]of Object.entries(a))Ze(c)&&(t[s]={secretRef:c.secretRef,scope:c.scope});return Object.keys(t).length>0?t:void 0}function ec(a){const t={};for(const s of a){const c=_t(s);if(c){if(c.transport==="stdio"){t[c.name]={transport:"stdio",...c.enabled!==void 0?{enabled:c.enabled}:{},command:c.command,...c.args?{args:c.args}:{},...c.env?{env:cn(c.env)}:{}};continue}t[c.name]={transport:c.transport,...c.enabled!==void 0?{enabled:c.enabled}:{},url:c.url,...c.headers?{headers:cn(c.headers)}:{}}}}return{mcpServers:t}}const tc=["defaultProviderOverride","defaultModelIdOverride","titleSummarizerProvider","titleSummarizerModelId","titleSummarizerFallbackProvider","titleSummarizerFallbackModelId"],sc=new Set(tc),ac={appearance:new Set(["themeMode","colorTheme","dashboardFontScalePct","shadcnCustomColors"]),notifications:new Set(["ntfyEnabled","ntfyTopic","ntfyBaseUrl","ntfyAccessToken","ntfyEvents","ntfyDashboardHost","failureNotificationDelayMs","failureNotificationMode","webhookEnabled","webhookUrl","webhookFormat","webhookEvents","notificationProviders"]),experimental:new Set(["experimentalFeatures"]),"global-general":new Set(["githubTrackingDefaultRepo","language","persistAgentToolOutput","persistAgentThinkingLogPermanent","persistAgentThinkingLogEphemeral","fnBinaryCheckEnabled","updateCheckEnabled","updateCheckFrequency","autoReloadOnVersionChange"]),"global-mcp":new Set(["mcpServers"]),"global-models":new Set(["defaultProvider","defaultModelId","fallbackProvider","fallbackModelId","defaultThinkingLevel","modelRouterEnabled","modelRouterCheapProvider","modelRouterCheapModelId","opencodeGoModelSync","openrouterAppAttribution","openrouterModelFilters","openrouterModelSync","openrouterProviderPreferences","executionGlobalProvider","executionGlobalModelId","planningGlobalProvider","planningGlobalModelId","validatorGlobalProvider","validatorGlobalModelId","titleSummarizerGlobalProvider","titleSummarizerGlobalModelId"]),"project-models":new Set(["defaultProvider","defaultModelId","fallbackProvider","fallbackModelId","defaultThinkingLevel","modelRouterEnabled","modelRouterCheapProvider","modelRouterCheapModelId","opencodeGoModelSync","openrouterAppAttribution","openrouterModelFilters","openrouterModelSync","openrouterProviderPreferences","executionGlobalProvider","executionGlobalModelId","planningGlobalProvider","planningGlobalModelId","validatorGlobalProvider","validatorGlobalModelId","titleSummarizerGlobalProvider","titleSummarizerGlobalModelId"]),"node-sync":new Set(["settingsSyncEnabled","settingsSyncAuth","settingsSyncInterval","settingsSyncConflictResolution"]),"research-global":new Set(["researchGlobalDefaults","researchGlobalEnabled","researchGlobalMaxConcurrentRuns","researchGlobalDefaultTimeout","researchGlobalMaxSourcesPerRun","researchGlobalMaxSynthesisRounds","researchGlobalWebSearchProvider","researchGlobalSearxngUrl","researchGlobalBraveApiKey","researchGlobalGoogleSearchApiKey","researchGlobalGoogleSearchCx","researchGlobalTavilyApiKey","researchGlobalGitHubEnabled","researchGlobalLocalDocsEnabled","researchGlobalMaxSearchResults","researchGlobalFetchTimeoutMs","researchGlobalUserAgent"]),remote:new Set(["remoteAccess"])};function nc(a,t){const s=ac[t];return!s||s.has(a)}function Vs(a,t){return!!a&&Object.prototype.hasOwnProperty.call(a,t)}function It(a){return typeof a=="object"&&a!==null&&!Array.isArray(a)}function ht(a,t){if(Object.is(a,t))return!0;if(Array.isArray(a)||Array.isArray(t))return!Array.isArray(a)||!Array.isArray(t)||a.length!==t.length?!1:a.every((s,c)=>ht(s,t[c]));if(It(a)||It(t)){if(!It(a)||!It(t))return!1;const s=Object.keys(a),c=Object.keys(t);return s.length!==c.length?!1:s.every(r=>Vs(t,r)&&ht(a[r],t[r]))}return!1}function rc({payload:a,initialValues:t,initialScopedValues:s,activeSection:c}){const r={};for(const[i,n]of Object.entries(a))if(!(i==="githubTrackingDefaultRepo"&&c!=="global-general")&&!(i==="mcpServers"&&c!=="global-mcp")&&i!=="persistAgentThinkingLog"&&i!=="customProviders"&&Vi(i)){if(!nc(i,c))continue;if(n===void 0&&i==="ntfyAccessToken"&&c==="notifications"){r[i]=null;continue}const p=Vs(s?.global,i),A=Vs(t,i),j=p?s?.global?.[i]:t?.[i],u=p||A;if(ht(n,j))continue;n===void 0&&u&&j!==void 0?r[i]=null:n!==void 0&&(r[i]=n)}const m={};for(const[i,n]of Object.entries(a)){if(i==="githubTokenConfigured"||i==="prAuthAvailable"||i==="customProviders"||i==="githubTrackingDefaultRepo"&&c==="global-general"||i==="mcpServers"&&c==="global-mcp"||!Yi(i))continue;const p=s?.project?.[i];sc.has(i)?ht(n,p)||(n==null&&p!==void 0&&p!==null?m[i]=null:n!==void 0&&(m[i]=n)):ht(n,p)||(n===void 0&&p!==void 0&&p!==null?m[i]=null:n!==void 0&&(m[i]=n))}return{globalPatch:r,projectPatch:m}}const ic=[{value:90,label:"Small"},{value:100,label:"Default"},{value:110,label:"Large"},{value:120,label:"Largest"}];function lc({themeMode:a,colorTheme:t,dashboardFontScalePct:s=100,shadcnCustomColors:c={},resolvedThemeMode:r=a==="light"?"light":"dark",onThemeModeChange:m,onColorThemeChange:i,onDashboardFontScaleChange:n=()=>{},onShadcnCustomColorsChange:p=()=>{}}){const{t:A}=Z("app"),j=o.useCallback(()=>{m("dark"),i("ocean"),n(100),p({})},[m,i,n,p]);return e.jsxs("div",{className:"theme-selector",children:[e.jsx("div",{className:"theme-mode-toggle",role:"radiogroup","aria-label":A("theme.modeLabel","Theme mode"),children:Lo.map(({value:u,label:d,icon:C})=>e.jsxs("button",{className:`theme-mode-btn${a===u?" active":""}`,onClick:()=>m(u),"aria-pressed":a===u,"aria-label":A(`theme.${u}Mode`,`${d} mode`),title:A(`theme.${u}Mode`,`${d} mode`),children:[e.jsx(C,{size:16}),e.jsx("span",{children:A(`theme.${u}`,d)})]},u))}),e.jsxs("div",{className:"theme-current-preview",children:[e.jsx("div",{className:"theme-preview-icon",children:a==="light"?e.jsx(Oo,{size:20}):a==="dark"?e.jsx(Bo,{size:20}):e.jsx(Qi,{size:20})}),e.jsxs("div",{className:"theme-preview-info",children:[e.jsx("div",{className:"theme-preview-label",children:A("theme.currentTheme","Current theme")}),e.jsxs("div",{className:"theme-preview-value",children:[a==="system"?"System":`${a.charAt(0).toUpperCase()+a.slice(1)}`," / ",nn.find(u=>u.value===t)?.label]})]})]}),e.jsx("div",{className:"theme-section-title",children:A("theme.fontSize","Font Size")}),e.jsx("div",{className:"theme-font-size-toggle",role:"radiogroup","aria-label":A("theme.fontSizeLabel","Dashboard font size"),children:ic.map(({value:u,label:d})=>e.jsx("button",{className:`theme-font-size-btn${s===u?" active":""}`,onClick:()=>n(u),"aria-pressed":s===u,children:e.jsx("span",{children:A(`theme.fontSize.${d}`,d)})},u))}),e.jsx("div",{className:"theme-section-title",children:A("theme.colorTheme","Color Theme")}),e.jsx("div",{className:"theme-grid",role:"radiogroup","aria-label":A("theme.colorThemeLabel","Color theme"),children:nn.map(({value:u,label:d,className:C})=>e.jsxs("button",{className:`theme-option${t===u?" active":""}`,onClick:()=>i(u),"aria-pressed":t===u,"aria-label":A(`theme.colorTheme.${u}`,`${d} theme`),title:A(`theme.colorTheme.${u}`,d),children:[e.jsxs("div",{className:`theme-option-swatch ${C}`,"aria-hidden":"true",children:[e.jsx("span",{className:"theme-option-swatch-sample theme-option-swatch-sample-1"}),e.jsx("span",{className:"theme-option-swatch-sample theme-option-swatch-sample-2"}),e.jsx("span",{className:"theme-option-swatch-sample theme-option-swatch-sample-3"}),e.jsx("span",{className:"theme-option-swatch-sample theme-option-swatch-sample-4"})]}),e.jsx("span",{className:"theme-option-label",children:A(`theme.colorTheme.${u}`,d)})]},u))}),t==="shadcn-custom"?e.jsx(Go,{value:c,onChange:p,resolvedThemeMode:r}):null,e.jsx("button",{className:"theme-reset-btn",onClick:j,"aria-label":A("theme.resetLabel","Reset to default theme"),children:e.jsx("span",{children:A("theme.resetButton","Reset to defaults")})})]})}const Wt=typeof window<"u";function dn(){if(Wt)try{const a=localStorage.getItem(Dt);return mt(a)?a:void 0}catch{return}}function un(){if(!Wt)return Us;for(const a of navigator.languages??[navigator.language]){const t=Zi(a);if(t)return t}return Us}function oc(){const{i18n:a}=Z(),t=a.resolvedLanguage??a.language,s=mt(t)?t:Us,[c,r]=o.useState(s),[m,i]=o.useState(()=>dn()!==void 0),n=o.useRef(!1);o.useEffect(()=>{const j=u=>{mt(u)&&r(u)};return a.on("languageChanged",j),()=>{a.off("languageChanged",j)}},[a]),o.useEffect(()=>{if(!Wt)return;const j=u=>{if(u.key===Dt){if(mt(u.newValue))i(!0),u.newValue!==a.resolvedLanguage&&a.changeLanguage(u.newValue);else if(u.newValue===null){i(!1);const d=un();d!==a.resolvedLanguage&&a.changeLanguage(d)}}};return window.addEventListener("storage",j),()=>{window.removeEventListener("storage",j)}},[a]),o.useEffect(()=>{if(!Wt)return;let j=!1;return Ji().then(u=>{if(j||n.current)return;const d=mt(u.language)?u.language:void 0;d&&!dn()&&d!==a.resolvedLanguage&&a.changeLanguage(d)}).catch(u=>{console.warn("[useLanguage] Failed to hydrate language from global settings",u)}),()=>{j=!0}},[a]);const p=o.useCallback(j=>{n.current=!0,r(j),i(!0),a.changeLanguage(j);try{localStorage.setItem(Dt,j)}catch{}pt({language:j}).catch(u=>{console.warn("[useLanguage] Failed to persist language to global settings",u)})},[a]),A=o.useCallback(()=>{n.current=!0,i(!1);try{localStorage.removeItem(Dt)}catch{}pt({language:null}).catch(j=>{console.warn("[useLanguage] Failed to clear language in global settings",j)}),a.changeLanguage(un())},[a]);return{language:c,supportedLocales:Xi,setLanguage:p,clearLanguage:A,hasExplicitChoice:m}}const cc={en:"English","zh-CN":"简体中文","zh-TW":"繁體中文",fr:"Français",es:"Español",ko:"한국어"};function dc(){const{t:a}=Z("app"),{language:t,supportedLocales:s,setLanguage:c,clearLanguage:r,hasExplicitChoice:m}=oc(),i=a("settings.appearance.language","Language");return e.jsxs("div",{className:"language-selector",children:[e.jsx("div",{className:"language-selector-title",children:i}),e.jsxs("div",{className:"language-options",role:"group","aria-label":i,children:[e.jsx("button",{type:"button",className:`language-option${m?"":" active"}`,onClick:r,"aria-pressed":!m,title:a("settings.appearance.languageAutoHint","Follow the browser language"),children:a("settings.appearance.languageAuto","Auto")}),s.map(n=>e.jsx("button",{type:"button",className:`language-option${m&&t===n?" active":""}`,onClick:()=>c(n),"aria-pressed":m&&t===n,lang:n,children:cc[n]},n))]})]})}function uc({scopeBanner:a,form:t,setForm:s,themeMode:c,colorTheme:r,dashboardFontScalePct:m,shadcnCustomColors:i={},resolvedThemeMode:n,onThemeModeChange:p,onColorThemeChange:A,onDashboardFontScaleChange:j,onShadcnCustomColorsChange:u,sessionBannersHidden:d,setSessionBannersHidden:C}){const{t:b}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:b("settings.appearance.title","Appearance")}),e.jsx(lc,{themeMode:c,colorTheme:r,dashboardFontScalePct:m,onThemeModeChange:h=>{s(f=>({...f,themeMode:h})),p?.(h)},onColorThemeChange:h=>{s(f=>({...f,colorTheme:h})),A?.(h)},onDashboardFontScaleChange:h=>{s(f=>({...f,dashboardFontScalePct:h})),j?.(h)},shadcnCustomColors:i,resolvedThemeMode:n,onShadcnCustomColorsChange:h=>{s(f=>({...f,shadcnCustomColors:h})),u?.(h)}}),e.jsx(dc,{}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:t.openTasksInRightSidebar===!0,onChange:h=>s(f=>({...f,openTasksInRightSidebar:h.target.checked}))}),e.jsx("span",{children:b("settings.appearance.openTasksInRightSidebar","Open tasks in the right sidebar")})]}),e.jsx("small",{className:"form-text text-muted",children:b("settings.appearance.openTasksInRightSidebarHelp","When enabled, board task cards open detail in the right sidebar when it is available; mobile and hidden-sidebar states keep the full task panel.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:d,onChange:h=>C(h.target.checked)}),e.jsx("span",{children:b("settings.appearance.hideAISessionNotificationBanners","Hide AI session notification banners")})]}),e.jsx("small",{className:"form-text text-muted",children:b("settings.appearance.suppressTheLdquoNeedsYourInputRdquoBanner"," Suppress the &ldquo;needs your input&rdquo; banner that appears when AI sessions are awaiting input or have failed. ")})]})]})}function mc({scopeBanner:a,form:t,setForm:s,knownFeatures:c,legacyAliases:r,getCanonicalKey:m,isFeatureEnabled:i,hiddenFeatureKeys:n}){const{t:p}=Z("app"),A=t.experimentalFeatures??{},u=Array.from(new Set([...Object.keys(c),...Object.keys(A).map(m)])).filter(d=>!n?.has(d)).sort((d,C)=>d.localeCompare(C)).map(d=>[d,i(A,d)]);return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:p("settings.experimental.experimentalFeatures","Experimental Features")}),e.jsx("div",{className:"form-group",children:e.jsx("small",{children:p("settings.experimental.experimentalFeaturesAreEarlyCapabilitiesThatAreNot"," Experimental features are early capabilities that are not yet fully stable. Enable them to test new functionality, but be aware they may change or be removed. ")})}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:p("settings.experimental.featureFlags","Feature Flags")}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"var(--space-sm)"},children:u.map(([d,C])=>e.jsxs("label",{htmlFor:`experimental-${d}`,className:"checkbox-label",children:[e.jsx("input",{id:`experimental-${d}`,type:"checkbox",checked:C,onChange:b=>{s(h=>{const f={...h.experimentalFeatures??{},[d]:b.target.checked};for(const[S,w]of Object.entries(r))w===d&&delete f[S];return{...h,experimentalFeatures:f}})}}),e.jsx("span",{children:c[d]??d})]},d))})]})]})}function pc({scopeBanner:a,form:t,setForm:s}){const{t:c}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:c("settings.nodeSync.nodeSync","Node Sync")}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"settingsSyncEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"settingsSyncEnabled",type:"checkbox",checked:t.settingsSyncEnabled||!1,onChange:r=>s(m=>({...m,settingsSyncEnabled:r.target.checked}))}),c("settings.nodeSync.enableAutomaticSettingsSync"," Enable automatic settings sync ")]}),e.jsx("small",{children:c("settings.nodeSync.automaticallySynchronizeSettingsBetweenThisNodeAndConnected","Automatically synchronize settings between this node and connected remote nodes")})]}),t.settingsSyncEnabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"settingsSyncAuth",className:"checkbox-label",children:[e.jsx("input",{id:"settingsSyncAuth",type:"checkbox",checked:t.settingsSyncAuth||!1,onChange:r=>s(m=>({...m,settingsSyncAuth:r.target.checked}))}),c("settings.nodeSync.syncModelAuthCredentials"," Sync model auth credentials ")]}),e.jsx("small",{children:c("settings.nodeSync.includeAPIKeysAndOAuthTokensInSync","Include API keys and OAuth tokens in sync operations")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"settingsSyncInterval",children:c("settings.nodeSync.syncInterval","Sync interval")}),e.jsxs("select",{id:"settingsSyncInterval",className:"select",value:t.settingsSyncInterval||9e5,onChange:r=>s(m=>({...m,settingsSyncInterval:parseInt(r.target.value,10)})),children:[e.jsx("option",{value:3e5,children:c("settings.nodeSync.every5Minutes","Every 5 minutes")}),e.jsx("option",{value:9e5,children:c("settings.nodeSync.every15Minutes","Every 15 minutes")}),e.jsx("option",{value:18e5,children:c("settings.nodeSync.every30Minutes","Every 30 minutes")}),e.jsx("option",{value:36e5,children:c("settings.nodeSync.every1Hour","Every 1 hour")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"settingsSyncConflictResolution",children:c("settings.nodeSync.conflictResolution","Conflict resolution")}),e.jsxs("select",{id:"settingsSyncConflictResolution",className:"select",value:t.settingsSyncConflictResolution||"last-write-wins",onChange:r=>s(m=>({...m,settingsSyncConflictResolution:r.target.value})),children:[e.jsx("option",{value:"last-write-wins",children:c("settings.nodeSync.lastWriteWins","Last write wins")}),e.jsx("option",{value:"always-ask",children:c("settings.nodeSync.alwaysAsk","Always ask")}),e.jsx("option",{value:"keep-local",children:c("settings.nodeSync.keepLocal","Keep local")}),e.jsx("option",{value:"keep-remote",children:c("settings.nodeSync.keepRemote","Keep remote")})]})]})]}),e.jsx("p",{className:"settings-sync-workflow-note text-muted",role:"note",children:c("settings.nodeSync.workflowSettingsNotSynced","Workflow settings are not synced across nodes yet.")})]})}const Rs=["in-review","merged","failed","awaiting-approval","awaiting-user-review","planning-awaiting-input","cli-agent-awaiting-input","gridlock","fallback-used","memory-dreams-processed","message:agent-to-user","message:agent-to-agent","message:room","oauth-token-expired"],mn=[{event:"in-review",label:"Task completed (in-review)",description:"When a task moves to In Review (ready for review)"},{event:"merged",label:"Task merged",description:"When a task is successfully merged to main"},{event:"failed",label:"Task failed",description:"When a task fails during execution (high priority)"},{event:"awaiting-approval",label:"Plan needs approval",description:"When a task specification needs manual approval before execution"},{event:"awaiting-user-review",label:"User review needed",description:"When an agent hands off a task for human review (high priority)"},{event:"planning-awaiting-input",label:"Planning needs input",description:"When planning mode is waiting for your response to continue"},{event:"cli-agent-awaiting-input",label:"CLI agent needs input",description:"When a CLI agent is blocked on a tool permission or terminal input prompt"},{event:"gridlock",label:"Pipeline gridlocked",description:"When all schedulable todo tasks are blocked and work cannot advance"},{event:"fallback-used",label:"Fallback model used (recovered)",description:"When Fusion recovers from a retryable model failure by switching to a fallback model"},{event:"task-created",label:"Agent created a task",description:"When an agent files a new task on the board"},{event:"memory-dreams-processed",label:"DREAMS.md entry added",description:"When manual dream processing writes a new entry to project or agent DREAMS.md"},{event:"message:agent-to-user",label:"Agent → user message",description:"An agent sent you a direct message"},{event:"message:agent-to-agent",label:"Agent → agent message",description:"Agents are talking to each other (including replies)"},{event:"message:room",label:"Agent message in room",description:"An agent posted a reply in a chat room you're watching"},{event:"oauth-token-expired",label:"OAuth token expired",description:"Notify when a provider OAuth token (Codex, Claude, etc.) expires."}];function hc({scopeBanner:a,form:t,setForm:s,testNotificationLoading:c,testNotificationResult:r,onTestProviderNotification:m}){const{t:i}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:i("settings.notifications.notifications","Notifications")}),e.jsxs("div",{className:"notification-provider-card",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"failureNotificationMode",children:i("settings.notifications.failureNotificationMode","Failure notification mode")}),e.jsxs("select",{id:"failureNotificationMode",value:t.failureNotificationMode??"sticky-only",onChange:n=>{const p=n.target.value;s(A=>({...A,failureNotificationMode:p}))},children:[e.jsx("option",{value:"sticky-only",children:i("settings.notifications.stickyFailuresOnlyDefault","Sticky failures only (default)")}),e.jsx("option",{value:"terminal-only",children:i("settings.notifications.terminalFailuresOnlySuppressAutoRetried","Terminal failures only (suppress auto-retried)")}),e.jsx("option",{value:"all",children:i("settings.notifications.allFailuresLegacy","All failures (legacy)")})]}),e.jsx("small",{children:i("settings.notifications.stickyOnlySuppressesRecoveredFailuresTerminalOnlyWaits","Sticky-only suppresses recovered failures; terminal-only waits for paused/in-review failed tasks; all restores legacy alerts.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"failureNotificationDelayMs",children:i("settings.notifications.failureNotificationDelayMs","Failure notification delay (ms)")}),e.jsx("input",{id:"failureNotificationDelayMs",type:"number",min:0,step:1e3,disabled:(t.failureNotificationMode??"sticky-only")==="all",value:t.failureNotificationDelayMs??3e4,onChange:n=>{const p=Number(n.target.value);s(A=>({...A,failureNotificationDelayMs:Number.isFinite(p)&&p>=0?p:0}))}}),e.jsx("small",{children:i("settings.notifications.howLongAFailureMustPersistBeforeA"," How long a failure must persist before a push notification is sent. 0 = notify immediately. ")})]})]}),e.jsxs("div",{className:"notification-provider-card",children:[e.jsxs("div",{className:"notification-provider-header",children:[e.jsx("strong",{children:i("settings.notifications.ntfy","ntfy")}),e.jsxs("label",{htmlFor:"ntfyEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"ntfyEnabled",type:"checkbox",checked:t.ntfyEnabled||!1,onChange:n=>s(p=>({...p,ntfyEnabled:n.target.checked}))}),i("settings.notifications.enable"," Enable ")]})]}),t.ntfyEnabled&&e.jsxs("div",{className:"notification-provider-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"ntfyTopic",children:i("settings.notifications.ntfyTopic","ntfy Topic")}),e.jsx("input",{id:"ntfyTopic",type:"text",placeholder:i("settings.notifications.myTopicName","my-topic-name"),value:t.ntfyTopic||"",onChange:n=>{const p=n.target.value;s(A=>({...A,ntfyTopic:p||void 0}))}}),e.jsxs("small",{children:[i("settings.notifications.yourNtfyShTopicName164Alphanumeric"," Your ntfy.sh topic name (1–64 alphanumeric/hyphen/underscore characters).")," ",e.jsx("a",{href:"https://ntfy.sh",target:"_blank",rel:"noopener noreferrer",className:"settings-inline-link",children:i("settings.notifications.learnMoreAboutNtfySh"," Learn more about ntfy.sh ")})]}),t.ntfyTopic&&!/^[a-zA-Z0-9_-]{1,64}$/.test(t.ntfyTopic)&&e.jsx("small",{className:"field-error",children:i("settings.notifications.topicMustBe164AlphanumericHyphenOr"," Topic must be 1–64 alphanumeric, hyphen, or underscore characters ")}),e.jsxs("details",{className:"ntfy-advanced-disclosure",children:[e.jsx("summary",{children:i("settings.notifications.advanced","Advanced")}),e.jsxs("div",{className:"ntfy-advanced-content",children:[e.jsx("label",{htmlFor:"ntfyBaseUrl",children:i("settings.notifications.customNtfyServerURLOptional","Custom ntfy server URL (optional)")}),e.jsx("input",{id:"ntfyBaseUrl",type:"url",placeholder:i("settings.notifications.httpsNtfySh","https://ntfy.sh"),value:t.ntfyBaseUrl||"",onChange:n=>{const p=n.target.value;s(A=>({...A,ntfyBaseUrl:p||void 0}))}}),e.jsx("small",{children:i("settings.notifications.leaveBlankToKeepTheDefaultServerHttps"," Leave blank to keep the default server: https://ntfy.sh. Custom servers must use http:// or https://. ")}),e.jsx("label",{htmlFor:"ntfyAccessToken",children:i("settings.notifications.accessTokenOptional","Access token (optional)")}),e.jsx("input",{id:"ntfyAccessToken",type:"password",autoComplete:"off",placeholder:i("settings.notifications.tk","tk_..."),value:t.ntfyAccessToken||"",onChange:n=>{const p=n.target.value;s(A=>({...A,ntfyAccessToken:p||void 0}))}}),e.jsx("small",{children:i("settings.notifications.leaveBlankToPublishWithoutAuthenticationWhenSet"," Leave blank to publish without authentication. When set, Fusion sends an Authorization Bearer header with ntfy requests. ")})]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:i("settings.notifications.notifyOnEvents","Notify on events")}),e.jsx("div",{className:"ntfy-events-list",children:mn.map(({event:n,label:p,description:A})=>{const j=t.ntfyEvents?.includes(n)??!0;return e.jsxs("div",{children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:j,onChange:u=>{const d=t.ntfyEvents??[...Rs],C=u.target.checked?d.includes(n)?d:[...d,n]:d.filter(b=>b!==n);s(b=>({...b,ntfyEvents:C.length>0?C:void 0}))}}),p]}),e.jsx("small",{children:A})]},`ntfy-${n}`)})})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"ntfyDashboardHost",children:i("settings.notifications.dashboardHostname","Dashboard Hostname")}),e.jsx("input",{id:"ntfyDashboardHost",type:"text",placeholder:i("settings.notifications.httpLocalhost3000","http://localhost:3000"),value:t.ntfyDashboardHost||"",onChange:n=>{const p=n.target.value;s(A=>({...A,ntfyDashboardHost:p||void 0}))}}),e.jsx("small",{children:i("settings.notifications.baseURLForDeepLinksInNotificationsWhen"," Base URL for deep links in notifications. When set, clicking a notification opens the dashboard directly to the task. ")}),t.ntfyDashboardHost&&!/^https?:\/\/.+/.test(t.ntfyDashboardHost)&&e.jsx("small",{className:"field-error",children:i("settings.notifications.mustBeAValidURLStartingWithHttp"," Must be a valid URL starting with http:// or https:// ")})]}),e.jsxs("div",{className:"notification-provider-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>m("ntfy"),disabled:c.ntfy||c["ntfy-message"]||c["ntfy-room"]||!t.ntfyEnabled||!t.ntfyTopic||!/^[a-zA-Z0-9_-]{1,64}$/.test(t.ntfyTopic),children:c.ntfy?i("settings.notifications.sending","Sending…"):i("settings.notifications.testNotification","Test notification")}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>m("ntfy-message"),disabled:c.ntfy||c["ntfy-message"]||c["ntfy-room"]||!t.ntfyEnabled||!t.ntfyTopic||!/^[a-zA-Z0-9_-]{1,64}$/.test(t.ntfyTopic),children:c["ntfy-message"]?i("settings.notifications.sending","Sending…"):i("settings.notifications.testMessageInbox","Test message inbox")}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>m("ntfy-room"),disabled:c.ntfy||c["ntfy-message"]||c["ntfy-room"]||!t.ntfyEnabled||!t.ntfyTopic||!/^[a-zA-Z0-9_-]{1,64}$/.test(t.ntfyTopic),children:c["ntfy-room"]?i("settings.notifications.sending","Sending…"):i("settings.notifications.testRoomReply","Test room reply")})]}),(r.ntfy||r["ntfy-message"]||r["ntfy-room"])&&e.jsxs("div",{className:"notification-test-feedback","aria-live":"polite",children:[r.ntfy&&e.jsxs("small",{className:`notification-test-feedback-item notification-test-feedback-item--${r.ntfy.status}`,children:[i("settings.notifications.general"," General: "),r.ntfy.message]}),r["ntfy-message"]&&e.jsxs("small",{className:`notification-test-feedback-item notification-test-feedback-item--${r["ntfy-message"].status}`,children:[i("settings.notifications.messageInbox"," Message inbox: "),r["ntfy-message"].message]}),r["ntfy-room"]&&e.jsxs("small",{className:`notification-test-feedback-item notification-test-feedback-item--${r["ntfy-room"].status}`,children:[i("settings.notifications.roomReply"," Room reply: "),r["ntfy-room"].message]})]})]})]}),e.jsxs("div",{className:"notification-provider-card",children:[e.jsxs("div",{className:"notification-provider-header",children:[e.jsx("strong",{children:i("settings.notifications.webhook","Webhook")}),e.jsxs("label",{htmlFor:"webhookEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"webhookEnabled",type:"checkbox",checked:t.webhookEnabled||!1,onChange:n=>s(p=>({...p,webhookEnabled:n.target.checked}))}),i("settings.notifications.webhookNotifications"," Webhook notifications ")]})]}),t.webhookEnabled&&e.jsxs("div",{className:"notification-provider-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"webhookUrl",children:i("settings.notifications.webhookURL","Webhook URL")}),e.jsx("input",{id:"webhookUrl",type:"text",placeholder:i("settings.notifications.httpsHooksExampleCom","https://hooks.example.com/..."),value:t.webhookUrl||"",onChange:n=>{const p=n.target.value;s(A=>({...A,webhookUrl:p||void 0}))}})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"webhookFormat",children:i("settings.notifications.format","Format")}),e.jsxs("select",{id:"webhookFormat",value:t.webhookFormat||"generic",onChange:n=>{const p=n.target.value;s(A=>({...A,webhookFormat:p}))},children:[e.jsx("option",{value:"slack",children:i("settings.notifications.slack","Slack")}),e.jsx("option",{value:"discord",children:i("settings.notifications.discord","Discord")}),e.jsx("option",{value:"generic",children:i("settings.notifications.generic","Generic")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:i("settings.notifications.notifyOnEvents","Notify on events")}),e.jsx("div",{className:"ntfy-events-list",children:mn.map(({event:n,label:p,description:A})=>{const u=(t.webhookEvents??[...Rs]).includes(n);return e.jsxs("div",{children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:u,onChange:d=>{const C=t.webhookEvents??[...Rs],b=d.target.checked?C.includes(n)?C:[...C,n]:C.filter(h=>h!==n);s(h=>({...h,webhookEvents:b.length>0?b:void 0}))}}),p]}),e.jsx("small",{children:A})]},`webhook-${n}`)})})]}),e.jsx("div",{className:"notification-provider-actions",children:e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>m("webhook"),disabled:c.webhook||!t.webhookUrl,children:c.webhook?i("settings.notifications.sending","Sending…"):i("settings.notifications.testNotification","Test notification")})}),r.webhook&&e.jsx("div",{className:"notification-test-feedback","aria-live":"polite",children:e.jsx("small",{className:`notification-test-feedback-item notification-test-feedback-item--${r.webhook.status}`,children:r.webhook.message})})]})]})]})}const Et="__custom__";function gc(a){const t=new Map;for(const s of a){const c=s.value.trim();!c||t.has(c)||t.set(c,{...s,value:c,label:s.label?.trim()||c})}return[...t.values()].sort((s,c)=>s.value.localeCompare(c.value))}function On({id:a,value:t,onChange:s,options:c,loading:r=!1,error:m,placeholder:i="owner/repo",ariaLabel:n}){const{t:p}=Z("app"),A=o.useRef(null),j=o.useId(),[u,d]=o.useState(!1),C=o.useMemo(()=>gc(c),[c]),b=C.find(w=>w.value===t),h=b?b.value:Et;o.useEffect(()=>{d(h===Et)},[h]);const f=w=>{if(w===Et){d(!0),requestAnimationFrame(()=>{A.current?.focus()});return}d(!1),s(w)},S=m||(r?p("trackingRepoSelect.loadingHint","Loading detected GitHub remotes…"):null);return e.jsxs("div",{className:"tracking-repo-select",children:[e.jsxs("select",{id:a,className:"select",value:h,onChange:w=>f(w.target.value),"aria-label":n,"aria-describedby":S?j:void 0,children:[C.map(w=>e.jsx("option",{value:w.value,children:w.source?`${w.label} — ${w.source}`:w.label},w.value)),e.jsx("option",{value:Et,children:p("trackingRepoSelect.customOption","Custom…")})]}),u?e.jsx("input",{ref:A,className:"input tracking-repo-select__custom-input",type:"text",value:t,placeholder:i,onChange:w=>s(w.target.value),"aria-describedby":S?j:void 0}):null,S?e.jsx("small",{id:j,className:m?"tracking-repo-select__hint tracking-repo-select__hint--error":"tracking-repo-select__hint",children:S}):null]})}function bc({defer:a=!1}){const{t}=Z("app"),[s,c]=o.useState(null),[r,m]=o.useState(!1),[i,n]=o.useState(!1),[p,A]=o.useState(null),[j,u]=o.useState(null),[d,C]=o.useState(null),b=I=>{switch(I){case"installed":return{text:t("cliBinary.stateInstalled","Installed"),tone:"ok"};case"missing":return{text:t("cliBinary.stateMissing","Not installed"),tone:"err"};case"version-mismatch":return{text:t("cliBinary.stateVersionMismatch","Version mismatch"),tone:"warn"};case"skipped":return{text:t("cliBinary.stateCheckDisabled","Check disabled"),tone:"warn"}}},h=o.useCallback(async()=>{m(!0),u(null);try{const I=await el();c(I)}catch(I){u(I instanceof Error?I.message:String(I))}finally{m(!1)}},[]);o.useEffect(()=>{a||h()},[a,h]);const f=o.useCallback(async()=>{n(!0),A(null),u(null);try{const I=await tl();c({binary:I.binary,expectedVersion:I.expectedVersion,state:I.state,install:I.install}),A(I.installResult)}catch(I){u(I instanceof Error?I.message:String(I))}finally{n(!1)}},[]),S=o.useCallback(async(I,x)=>{try{await navigator.clipboard.writeText(x),C(I),setTimeout(()=>C(v=>v===I?null:v),1500)}catch{}},[]),w=s?b(s.state):null;return e.jsxs("div",{className:"cli-binary-panel",children:[e.jsxs("div",{className:"cli-binary-header",children:[e.jsx("h4",{className:"settings-section-heading",children:t("cliBinary.heading","CLI Binary")}),w&&e.jsx("span",{className:`cli-binary-pill cli-binary-pill--${w.tone}`,children:w.text})]}),e.jsx("small",{className:"cli-binary-help",children:t("cliBinary.help","Installing the global CLI lets you run fn and fusion from any terminal. Automations and scripts work without it via npx, but a global install is faster and more convenient.")}),r&&!s&&e.jsx("p",{className:"cli-binary-status-line",children:t("cliBinary.checking","Checking…")}),s&&e.jsxs("div",{className:"cli-binary-detail",children:[s.binary.installed?e.jsxs("ul",{className:"cli-binary-info-list",children:[e.jsxs("li",{children:[e.jsx("span",{children:t("cliBinary.binaryLabel","Binary:")}),e.jsx("code",{children:s.binary.binary})]}),s.binary.path&&e.jsxs("li",{children:[e.jsx("span",{children:t("cliBinary.pathLabel","Path:")}),e.jsx("code",{children:s.binary.path})]}),e.jsxs("li",{children:[e.jsx("span",{children:t("cliBinary.versionLabel","Version:")}),e.jsx("code",{children:s.binary.version??"unknown"}),e.jsx("span",{className:"cli-binary-expected",children:t("cliBinary.expectedVersion","(expected {{version}})",{version:s.expectedVersion})})]})]}):e.jsx("p",{className:"cli-binary-status-line",children:t("cliBinary.notOnPath","Neither fn nor fusion was found on PATH.")}),e.jsxs("div",{className:"cli-binary-actions",children:[e.jsx("button",{type:"button",className:"cli-binary-install-btn",onClick:f,disabled:i,children:i?t("cliBinary.installing","Installing…"):s.binary.installed?t("cliBinary.reinstall","Reinstall"):t("cliBinary.installWithNpm","Install with npm")}),e.jsx("button",{type:"button",className:"cli-binary-refresh-btn",onClick:()=>void h(),disabled:r||i,children:t("cliBinary.refresh","Refresh")})]}),e.jsxs("div",{className:"cli-binary-commands",children:[e.jsx("label",{children:t("cliBinary.orCopyLabel","Or copy and run yourself:")}),[{label:"npm",command:s.install.npm},{label:"curl",command:s.install.curl}].map(({label:I,command:x})=>e.jsxs("div",{className:"cli-binary-command-row",children:[e.jsx("code",{children:x}),e.jsx("button",{type:"button",onClick:()=>void S(I,x),className:"cli-binary-copy-btn",children:d===I?t("cliBinary.copied","Copied"):t("cliBinary.copy","Copy")})]},I))]})]}),p&&e.jsxs("details",{className:"cli-binary-install-log",open:!p.success,children:[e.jsx("summary",{children:p.success?t("cliBinary.succeededDuration","Install succeeded in {{duration}}s",{duration:(p.durationMs/1e3).toFixed(1)}):t("cliBinary.failedExit","Install failed (exit {{code}})",{code:p.exitCode??"n/a"})}),p.permissionsHint&&e.jsx("p",{className:"cli-binary-permissions-hint",children:p.permissionsHint}),p.stdout&&e.jsx("pre",{className:"cli-binary-install-output",children:p.stdout}),p.stderr&&e.jsx("pre",{className:"cli-binary-install-output cli-binary-install-output--err",children:p.stderr})]}),j&&e.jsx("p",{className:"field-error",children:j})]})}function fc({scopeBanner:a,form:t,setForm:s,globalTrackingRepoOptions:c,globalTrackingRepoLoading:r,globalTrackingRepoError:m}){const{t:i}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:i("settings.globalGeneral.general","General")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"globalGithubTrackingDefaultRepo",children:i("settings.globalGeneral.globalDefaultTrackingRepo","Global default tracking repo")}),e.jsx(On,{id:"globalGithubTrackingDefaultRepo",ariaLabel:"Global default tracking repo",value:t.githubTrackingDefaultRepo??"",options:c,loading:r,error:m??void 0,placeholder:i("settings.globalGeneral.ownerRepo","owner/repo"),onChange:n=>s(p=>({...p,githubTrackingDefaultRepo:n||void 0}))}),e.jsx("small",{children:i("settings.globalGeneral.projectsInheritThisValueWhenTheyDoNot","Projects inherit this value when they do not set a project default tracking repo.")})]}),e.jsx(bc,{}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"persistAgentToolOutput",className:"checkbox-label",children:[e.jsx("input",{id:"persistAgentToolOutput",type:"checkbox",checked:t.persistAgentToolOutput===!0,onChange:n=>s(p=>({...p,persistAgentToolOutput:n.target.checked}))}),i("settings.globalGeneral.saveToolOutputInAgentLogs"," Save tool output in agent logs ")]}),e.jsx("small",{children:i("settings.globalGeneral.whenDisabledToolRowsAreStillLoggedBut"," When disabled, tool rows are still logged but detailed tool payloads are omitted. Very large tool payloads may still be clipped even when this stays enabled. ")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("h5",{className:"settings-section-heading",children:i("settings.globalGeneral.saveAIThinkingLogs","Save AI thinking logs")}),e.jsxs("label",{htmlFor:"persistAgentThinkingLogPermanent",className:"checkbox-label",children:[e.jsx("input",{id:"persistAgentThinkingLogPermanent",type:"checkbox",checked:Ua(t,{ephemeral:!1}),onChange:n=>s(p=>({...p,persistAgentThinkingLogPermanent:n.target.checked}))}),i("settings.globalGeneral.saveAIThinkingForPermanentAgents"," Save AI thinking for permanent agents ")]}),e.jsxs("label",{htmlFor:"persistAgentThinkingLogEphemeral",className:"checkbox-label",children:[e.jsx("input",{id:"persistAgentThinkingLogEphemeral",type:"checkbox",checked:Ua(t,{ephemeral:!0}),onChange:n=>s(p=>({...p,persistAgentThinkingLogEphemeral:n.target.checked}))}),i("settings.globalGeneral.saveAIThinkingForEphemeralTaskWorkerAgents"," Save AI thinking for ephemeral / task-worker agents ")]}),e.jsxs("small",{children:[i("settings.globalGeneral.leaveBothThinkingTogglesOffToKeepThe"," Leave both thinking toggles off to keep the original default behavior. This only controls persisted "),e.jsx("code",{children:"thinking"}),i("settings.globalGeneral.rowsAndDoesNotAffectAssistantTextOr"," rows and does not affect assistant text or tool rows. ")]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"fnBinaryCheckEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"fnBinaryCheckEnabled",type:"checkbox",checked:t.fnBinaryCheckEnabled!==!1,onChange:n=>s(p=>({...p,fnBinaryCheckEnabled:n.target.checked}))}),i("settings.globalGeneral.checkForThe"," Check for the "),e.jsx("code",{children:"fn"}),i("settings.globalGeneral.cLIBinaryOnPATH"," CLI binary on PATH ")]}),e.jsxs("small",{children:[i("settings.globalGeneral.whenEnabledTheDashboardProbesForAGlobally"," When enabled, the dashboard probes for a globally-installed")," ",e.jsx("code",{children:"fn"})," / ",e.jsx("code",{children:"fusion"}),i("settings.globalGeneral.cLIBySpawning"," CLI by spawning")," ",e.jsx("code",{children:"<bin> --version"}),i("settings.globalGeneral.disableThisIfYourLocalDevProcessIs",". Disable this if your local dev process is the source of truth and you don't want any outdated globally-installed binary executed during the probe. ")]})]}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:i("settings.globalGeneral.updates","Updates")}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"updateCheckEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"updateCheckEnabled",type:"checkbox",checked:t.updateCheckEnabled!==!1,onChange:n=>s(p=>({...p,updateCheckEnabled:n.target.checked}))}),i("settings.globalGeneral.checkForUpdatesAutomatically"," Check for updates automatically ")]}),e.jsxs("small",{children:[i("settings.globalGeneral.whenEnabledFusionChecksNpmForNewVersions"," When enabled, Fusion checks npm for new versions of")," ",e.jsx("code",{children:"@runfusion/fusion"}),i("settings.globalGeneral.andShowsUpdateNoticesInTheCLIAnd"," and shows update notices in the CLI and dashboard. Cadence is governed by the frequency below. ")]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"updateCheckFrequency",children:i("settings.globalGeneral.frequency","Frequency")}),e.jsxs("select",{id:"updateCheckFrequency",value:t.updateCheckFrequency??"daily",onChange:n=>s(p=>({...p,updateCheckFrequency:n.target.value})),disabled:t.updateCheckEnabled===!1,children:[e.jsx("option",{value:"manual",children:i("settings.globalGeneral.manualOnlyNeverAutoCheck","Manual only — never auto-check")}),e.jsx("option",{value:"on-startup",children:i("settings.globalGeneral.onStartupOncePerServerLaunch","On startup — once per server launch")}),e.jsx("option",{value:"daily",children:i("settings.globalGeneral.dailyRecommended","Daily (recommended)")}),e.jsx("option",{value:"weekly",children:i("settings.globalGeneral.weekly","Weekly")})]}),e.jsx("small",{children:i("settings.globalGeneral.controlsHowOftenTheDashboardReFetchesThe"," Controls how often the dashboard re-fetches the npm registry. Use the version + refresh control in the header to trigger an immediate check at any time. ")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"autoReloadOnVersionChange",className:"checkbox-label",children:[e.jsx("input",{id:"autoReloadOnVersionChange",type:"checkbox",checked:t.autoReloadOnVersionChange!==!1,onChange:n=>s(p=>({...p,autoReloadOnVersionChange:n.target.checked}))}),i("settings.globalGeneral.autoReloadDashboardOnVersionChange"," Auto-reload dashboard on version change ")]}),e.jsx("small",{children:i("settings.globalGeneral.whenEnabledDefaultTheDashboardAutomaticallyReloadsWhen"," When enabled (default), the dashboard automatically reloads when it detects a new build version — either from server rebuilds or service worker updates. Disable this to stay on the current version until you manually refresh. ")})]})]})}function vc({scopeBanner:a,form:t,setForm:s,authProviders:c,onNavigateToSection:r}){const{t:m}=Z("app"),i=t.researchGlobalWebSearchProvider??t.researchGlobalDefaults?.searchProvider??"builtin",n=i==="searxng"||i==="brave"||i==="google"||i==="tavily",p=i==="brave"||i==="tavily"?i:null,A=p?c.some(u=>u.id===p&&!u.authenticated):!1,j=u=>{s(d=>({...d,researchGlobalWebSearchProvider:u,researchGlobalDefaults:{...d.researchGlobalDefaults??{},searchProvider:u}}))};return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:m("settings.researchGlobal.researchDefaults","Research Defaults")}),e.jsxs("div",{className:"form-group settings-research-provider-group",children:[e.jsxs("label",{htmlFor:"research-global-provider-builtin",className:"checkbox-label",children:[e.jsx("input",{id:"research-global-provider-builtin",type:"radio",name:"research-global-search-provider",checked:!n,onChange:()=>j("builtin")}),m("settings.researchGlobal.builtInUsesAgentWebTools"," Built-in (uses agent web tools) ")]}),e.jsx("small",{children:m("settings.researchGlobal.searchesAndFetchesUseTheAgentsNativeWebSearch"," Searches and fetches use the agent's native WebSearch/WebFetch tools. No API key required. ")}),e.jsxs("details",{className:"settings-option-details settings-research-provider-advanced-details",children:[e.jsx("summary",{children:m("settings.researchGlobal.advancedExternalSearchProviders","Advanced — external search providers")}),e.jsxs("div",{className:"settings-research-provider-advanced-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-global-search-provider-advanced",children:m("settings.researchGlobal.searchProvider","Search Provider")}),e.jsxs("select",{id:"research-global-search-provider-advanced",className:"input",value:n?i:"searxng",onChange:u=>j(u.target.value),children:[e.jsx("option",{value:"searxng",children:m("settings.researchGlobal.searXNG","SearXNG")}),e.jsx("option",{value:"brave",children:m("settings.researchGlobal.brave","Brave")}),e.jsx("option",{value:"google",children:m("settings.researchGlobal.googleCustomSearch","Google Custom Search")}),e.jsx("option",{value:"tavily",children:m("settings.researchGlobal.tavily","Tavily")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-global-searxng-url",children:m("settings.researchGlobal.searXNGURL","SearXNG URL")}),e.jsx("input",{id:"research-global-searxng-url",className:"input",value:t.researchGlobalSearxngUrl??"",onChange:u=>s(d=>({...d,researchGlobalSearxngUrl:u.target.value||void 0})),placeholder:m("settings.researchGlobal.httpsSearxExampleCom","https://searx.example.com")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-global-google-cx",children:m("settings.researchGlobal.googleSearchCX","Google Search CX")}),e.jsx("input",{id:"research-global-google-cx",className:"input",value:t.researchGlobalGoogleSearchCx??"",onChange:u=>s(d=>({...d,researchGlobalGoogleSearchCx:u.target.value||void 0})),placeholder:m("settings.researchGlobal.customSearchEngineId","custom-search-engine-id")})]}),e.jsxs("div",{className:"settings-empty-state settings-research-empty-state",role:"note",children:[m("settings.researchGlobal.configureBraveTavilyAndGoogleAPIKeysIn"," Configure Brave, Tavily, and Google API keys in Authentication. "),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>r("authentication"),children:m("settings.researchGlobal.openAuthenticationSettings"," Open Authentication Settings ")})]})]})]})]}),e.jsx("div",{className:"form-group",children:e.jsxs("div",{className:"settings-research-limits-grid",children:[e.jsxs("div",{className:"settings-research-limit-field",children:[e.jsx("label",{htmlFor:"research-global-max-concurrent",children:m("settings.researchGlobal.defaultMaxConcurrentRuns","Default Max Concurrent Runs")}),e.jsx("input",{id:"research-global-max-concurrent",className:"input",type:"number",min:1,value:t.researchGlobalMaxConcurrentRuns??3,onChange:u=>s(d=>({...d,researchGlobalMaxConcurrentRuns:u.target.value===""?void 0:Number(u.target.value)}))})]}),e.jsxs("div",{className:"settings-research-limit-field",children:[e.jsx("label",{htmlFor:"research-global-max-sources",children:m("settings.researchGlobal.defaultMaxSourcesPerRun","Default Max Sources Per Run")}),e.jsx("input",{id:"research-global-max-sources",className:"input",type:"number",min:1,value:t.researchGlobalMaxSourcesPerRun??20,onChange:u=>s(d=>({...d,researchGlobalMaxSourcesPerRun:u.target.value===""?void 0:Number(u.target.value),researchGlobalDefaults:{...d.researchGlobalDefaults??{},maxSourcesPerRun:u.target.value===""?void 0:Number(u.target.value)}}))})]}),e.jsxs("div",{className:"settings-research-limit-field",children:[e.jsx("label",{htmlFor:"research-global-default-timeout",children:m("settings.researchGlobal.defaultMaxDurationMs","Default Max Duration (ms)")}),e.jsx("input",{id:"research-global-default-timeout",className:"input",type:"number",min:1e3,value:t.researchGlobalDefaultTimeout??3e5,onChange:u=>s(d=>({...d,researchGlobalDefaultTimeout:u.target.value===""?void 0:Number(u.target.value)}))})]}),e.jsxs("div",{className:"settings-research-limit-field",children:[e.jsx("label",{htmlFor:"research-global-fetch-timeout",children:m("settings.researchGlobal.requestTimeoutMs","Request Timeout (ms)")}),e.jsx("input",{id:"research-global-fetch-timeout",className:"input",type:"number",min:1e3,value:t.researchGlobalFetchTimeoutMs??3e4,onChange:u=>s(d=>({...d,researchGlobalFetchTimeoutMs:u.target.value===""?void 0:Number(u.target.value)}))})]}),e.jsxs("div",{className:"settings-research-limit-field",children:[e.jsx("label",{htmlFor:"research-global-max-synthesis-rounds",children:m("settings.researchGlobal.maxSynthesisRounds","Max Synthesis Rounds")}),e.jsx("input",{id:"research-global-max-synthesis-rounds",className:"input",type:"number",min:1,value:t.researchGlobalMaxSynthesisRounds??2,onChange:u=>s(d=>({...d,researchGlobalMaxSynthesisRounds:u.target.value===""?void 0:Number(u.target.value)}))})]})]})}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:m("settings.researchGlobal.enabledSources","Enabled Sources")}),e.jsxs("label",{htmlFor:"research-global-source-webSearch",className:"checkbox-label settings-research-source-locked",children:[e.jsx("input",{id:"research-global-source-webSearch",type:"checkbox",checked:!0,disabled:!0,readOnly:!0}),m("settings.researchGlobal.webSearch"," Web Search "),e.jsx("span",{className:"settings-muted",children:m("settings.researchGlobal.alwaysOn","Always on")})]}),e.jsxs("div",{className:"settings-research-source-grid",children:[e.jsxs("label",{htmlFor:"research-global-source-github",className:"checkbox-label",children:[e.jsx("input",{id:"research-global-source-github",type:"checkbox",checked:t.researchGlobalGitHubEnabled??!1,onChange:u=>s(d=>({...d,researchGlobalGitHubEnabled:u.target.checked}))}),m("settings.researchGlobal.gitHub"," GitHub ")]}),e.jsxs("label",{htmlFor:"research-global-source-local-docs",className:"checkbox-label",children:[e.jsx("input",{id:"research-global-source-local-docs",type:"checkbox",checked:t.researchGlobalLocalDocsEnabled??!0,onChange:u=>s(d=>({...d,researchGlobalLocalDocsEnabled:u.target.checked}))}),m("settings.researchGlobal.localDocs"," Local Docs ")]})]})]}),A&&e.jsxs("div",{className:"settings-empty-state",role:"alert",children:[m("settings.researchGlobal.missingCredentialsForTheSelectedResearchProvider"," Missing credentials for the selected research provider. "),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>r("authentication"),children:m("settings.researchGlobal.openAuthentication"," Open Authentication ")})]})]})}function xc({scopeBanner:a,form:t,setForm:s,remote:c}){const{t:r}=Z("app"),{projectId:m,addToast:i,remoteStatus:n,externalTunnel:p,tunnelShareLink:A,remoteBusyAction:j,cloudflaredInstalling:u,cloudflaredInstallError:d,cloudflaredManualInstallCommand:C,cloudflaredMacFallbackCommand:b,handleInstallCloudflared:h,runRemoteAction:f,remoteShortLivedToken:S,setRemoteShortLivedToken:w,remoteAuthLinkTokenType:I,setRemoteAuthLinkTokenType:x,remoteUrlPreview:v,setRemoteUrlPreview:B,remoteQrSvg:k,setRemoteQrSvg:Y}=c,W=t,J=W.remoteActiveProvider??null,V=n?.state??"stopped",ne=V==="running"?"running":V==="starting"?"starting":V==="failed"||V==="error"?"error":"stopped",ae=$=>{const _=t;return{remoteActiveProvider:$,remoteTailscaleEnabled:$==="tailscale",remoteTailscaleHostname:String(_.remoteTailscaleHostname??""),remoteTailscaleTargetPort:Number(_.remoteTailscaleTargetPort??4040),remoteTailscaleAcceptRoutes:!!_.remoteTailscaleAcceptRoutes,remoteCloudflareEnabled:$==="cloudflare",remoteCloudflareQuickTunnel:!!(_.remoteCloudflareQuickTunnel??!0),remoteCloudflareTunnelName:String(_.remoteCloudflareTunnelName??""),remoteCloudflareTunnelToken:_.remoteCloudflareTunnelToken||null,remoteCloudflareIngressUrl:String(_.remoteCloudflareIngressUrl??""),remoteShortLivedEnabled:!!_.remoteShortLivedEnabled,remoteShortLivedTtlMs:Number(_.remoteShortLivedTtlMs??9e5),remoteRememberLastRunning:!!_.remoteRememberLastRunning}};return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:r("settings.remote.remoteAccess","Remote Access")}),e.jsxs("div",{className:`remote-status-bar remote-status-bar--${ne}`,children:[e.jsx("span",{className:`remote-status-dot remote-status-dot--${ne}`}),e.jsx("strong",{children:V}),n?.provider&&e.jsxs("span",{children:[" · ",n.provider]}),n?.url&&e.jsx("code",{className:"remote-status-url",children:n.url}),n?.lastError&&e.jsx("span",{className:"field-error",children:n.lastError})]}),V==="stopped"&&p&&e.jsxs("div",{className:"remote-external-tunnel-panel",role:"status",children:[e.jsxs("div",{className:"remote-external-tunnel-header",children:[e.jsx(gt,{"aria-hidden":"true"}),e.jsxs("strong",{children:[r("settings.remote.external","External "),p.provider,r("settings.remote.tunnelDetected"," tunnel detected")]})]}),p.url&&e.jsx("code",{className:"settings-url-output",children:p.url}),A?.qrSvg&&e.jsxs("div",{className:"remote-external-tunnel-qr",children:[e.jsx("small",{children:r("settings.remote.scanToOpen","Scan to open:")}),e.jsx("img",{src:`data:image/svg+xml;utf8,${encodeURIComponent(A.qrSvg)}`,alt:r("settings.remote.externalTunnelQRCode","External tunnel QR code"),className:"settings-qr-preview-image"})]})]}),V==="running"&&(n?.url||A)&&(()=>{let $=null,_=n?.url??null;if(A?.url)try{const T=new URL(A.url);$=T.searchParams.get("rt"),_||(_=`${T.origin}/`)}catch{}return e.jsxs("div",{className:"remote-share-block",children:[_&&e.jsxs("div",{className:"remote-share-row",children:[e.jsx("small",{children:r("settings.remote.tailnetURL","Tailnet URL:")}),e.jsx("code",{className:"settings-url-output",children:_})]}),$&&e.jsxs("div",{className:"remote-share-row",children:[e.jsx("small",{children:r("settings.remote.remoteAccessCode","Remote access code:")}),e.jsx("code",{className:"settings-url-output",children:$})]}),A?.qrSvg&&e.jsxs("div",{className:"remote-share-row",children:[e.jsx("small",{children:r("settings.remote.scanToConnect","Scan to connect:")}),e.jsx("img",{src:`data:image/svg+xml;utf8,${encodeURIComponent(A.qrSvg)}`,alt:r("settings.remote.remoteAccessQRCode","Remote access QR code"),className:"settings-qr-preview-image"})]})]})})(),e.jsxs("div",{className:"form-group",children:[e.jsxs("div",{className:"remote-provider-selector",role:"radiogroup","aria-label":r("settings.remote.remoteProvider","Remote provider"),children:[e.jsxs("label",{className:"remote-provider-option",children:[e.jsx("input",{type:"radio",name:"remoteProvider",value:"tailscale",checked:J==="tailscale",onChange:()=>s($=>({...$,remoteActiveProvider:"tailscale"}))}),e.jsx("span",{children:e.jsxs("span",{className:"remote-provider-option-content",children:[e.jsx("span",{"data-testid":"remote-provider-icon-tailscale","aria-hidden":"true",children:e.jsx(gt,{size:16})}),e.jsx("span",{children:r("settings.remote.tailscale","Tailscale")})]})})]}),e.jsxs("label",{className:"remote-provider-option",children:[e.jsx("input",{type:"radio",name:"remoteProvider",value:"cloudflare",checked:J==="cloudflare",onChange:()=>s($=>({...$,remoteActiveProvider:"cloudflare"}))}),e.jsx("span",{children:e.jsxs("span",{className:"remote-provider-option-content",children:[e.jsx("span",{"data-testid":"remote-provider-icon-cloudflare","aria-hidden":"true",className:"remote-provider-option-icon",children:e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","data-testid":"remote-cloudflare-option-icon",children:e.jsx("path",{d:"M7 16.5h10.8a2.9 2.9 0 0 0 .3-5.8 4.9 4.9 0 0 0-9.3-1.6A3.6 3.6 0 0 0 7 16.5m-1.9 0h3.2a2.5 2.5 0 0 0 .2-5 3.4 3.4 0 0 0-3.4 3.4c0 .6 0 1 .2 1.6",fill:"var(--provider-cloudflare)"})})}),e.jsx("span",{children:r("settings.remote.cloudflare","Cloudflare")})]})})]})]}),!J&&e.jsx("small",{children:r("settings.remote.selectAProviderAboveToConfigureRemoteAccess","Select a provider above to configure remote access.")})]}),J==="cloudflare"&&n?.cloudflaredAvailable===!0&&e.jsxs("div",{className:"remote-cli-detection remote-cli-detection--available",role:"status",children:[e.jsx(sl,{"aria-hidden":"true"}),e.jsx("span",{children:r("settings.remote.cloudflaredIsInstalled","cloudflared is installed")})]}),J==="cloudflare"&&n?.cloudflaredAvailable===!1&&e.jsxs("div",{className:"remote-cli-detection remote-cli-detection--missing",role:"status",children:[e.jsx(al,{"aria-hidden":"true"}),e.jsxs("div",{className:"remote-cli-detection-content",children:[e.jsx("span",{children:r("settings.remote.cloudflaredIsNotInstalled","cloudflared is not installed")}),e.jsx("button",{type:"button",className:"btn btn-sm",disabled:u||j!==null,onClick:()=>void h(),children:u?r("settings.remote.installing","Installing…"):r("settings.remote.installCloudflared","Install cloudflared")}),d&&e.jsx("small",{className:"remote-cli-install-error",children:d}),e.jsxs("small",{className:"remote-cli-manual",children:[r("settings.remote.manualInstall","Manual install: "),e.jsx("code",{children:C()})]}),b()?e.jsxs("small",{className:"remote-cli-manual",children:[r("settings.remote.ifHomebrewIsUnavailable","If Homebrew is unavailable: "),e.jsx("code",{children:b()})]}):null]})]}),J&&e.jsx("div",{className:"form-group remote-provider-settings",children:J==="tailscale"?e.jsxs(e.Fragment,{children:[e.jsxs("small",{children:[r("settings.remote.tailscaleFunnelWillExposeThisDashboardOnYour","Tailscale Funnel will expose this dashboard on your tailnet's public "),"https://<machine>.<tailnet>.ts.net/",r("settings.remote.uRLNoHostnameOrPortConfigurationNeeded"," URL — no hostname or port configuration needed.")]}),e.jsxs("label",{htmlFor:"remoteTailscaleAcceptRoutes",className:"checkbox-label",children:[e.jsx("input",{id:"remoteTailscaleAcceptRoutes",type:"checkbox",checked:!!W.remoteTailscaleAcceptRoutes,onChange:$=>s(_=>({..._,remoteTailscaleAcceptRoutes:$.target.checked}))}),r("settings.remote.acceptRoutes"," Accept routes ")]})]}):e.jsxs(e.Fragment,{children:[e.jsx("small",{children:W.remoteCloudflareQuickTunnel??!0?r("settings.remote.usingQuickTunnel","Using Quick Tunnel — automatically creates a random trycloudflare.com URL, no account needed."):r("settings.remote.namedTunnelModeEnabled","Named Tunnel mode enabled — configure tunnel name, token, and ingress URL below.")}),e.jsxs("details",{className:"remote-cf-advanced-details",open:!(W.remoteCloudflareQuickTunnel??!0),onToggle:$=>{const _=$.currentTarget.open;s(T=>{const D=!!(T.remoteCloudflareQuickTunnel??!0),re=!_;return D===re?T:{...T,remoteCloudflareQuickTunnel:re}})},children:[e.jsx("summary",{children:r("settings.remote.advancedNamedTunnel","Advanced (Named Tunnel)")}),W.remoteCloudflareQuickTunnel??!0?null:e.jsxs("div",{className:"remote-cf-advanced-fields",children:[e.jsx("label",{htmlFor:"remoteCloudflareTunnelName",children:r("settings.remote.tunnelName","Tunnel name")}),e.jsx("input",{id:"remoteCloudflareTunnelName",type:"text",placeholder:r("settings.remote.tunnelName","Tunnel name"),value:String(W.remoteCloudflareTunnelName??""),onChange:$=>s(_=>({..._,remoteCloudflareTunnelName:$.target.value}))}),e.jsx("label",{htmlFor:"remoteCloudflareTunnelToken",children:r("settings.remote.tunnelToken","Tunnel token")}),e.jsx("input",{id:"remoteCloudflareTunnelToken",type:"password",placeholder:r("settings.remote.tunnelToken","Tunnel token"),value:String(W.remoteCloudflareTunnelToken??""),onChange:$=>s(_=>({..._,remoteCloudflareTunnelToken:$.target.value}))}),e.jsx("label",{htmlFor:"remoteCloudflareIngressUrl",children:r("settings.remote.ingressURL","Ingress URL")}),e.jsx("input",{id:"remoteCloudflareIngressUrl",type:"text",placeholder:r("settings.remote.httpsYourDomainExample","https://your-domain.example"),value:String(W.remoteCloudflareIngressUrl??""),onChange:$=>s(_=>({..._,remoteCloudflareIngressUrl:$.target.value}))})]})]})]})}),e.jsx("div",{className:"form-group remote-tunnel-actions",children:V==="running"||V==="starting"?e.jsx("button",{type:"button",className:"btn btn-danger",disabled:j!==null,onClick:()=>void f("stop",async()=>{await nl(m),i(r("settings.remote.tunnelStopped","Remote tunnel stopped"),"success")}),children:j==="stop"?r("settings.remote.stopping","Stopping…"):r("settings.remote.stopTunnel","Stop Tunnel")}):e.jsxs(e.Fragment,{children:[p?e.jsxs("div",{className:"remote-external-tunnel-actions",children:[e.jsx("button",{type:"button",className:"btn",disabled:!J||j!==null,onClick:()=>void f("start fresh",async()=>{J&&(await Ns(ae(J),m),await rl(m),await Ss(m),i(r("settings.remote.tunnelRestarted","Remote tunnel restarted"),"success"))}),children:j==="start fresh"?r("settings.remote.restarting","Restarting…"):r("settings.remote.startFresh","Start Fresh")}),e.jsx("button",{type:"button",className:"btn btn-primary",disabled:!J||j!==null,onClick:()=>void f("use existing",async()=>{J&&(await Ns(ae(J),m),await Ss(m),i(r("settings.remote.tunnelStarted","Remote tunnel started"),"success"))}),children:j==="use existing"?r("settings.remote.starting","Starting…"):r("settings.remote.useExisting","Use Existing")})]}):e.jsx("button",{type:"button",className:"btn btn-primary",disabled:!J||j!==null,onClick:()=>void f("start",async()=>{J&&(await Ns(ae(J),m),await Ss(m),i(r("settings.remote.tunnelStarted","Remote tunnel started"),"success"))}),children:j==="start"?r("settings.remote.starting","Starting…"):r("settings.remote.startTunnel","Start Tunnel")}),J==="cloudflare"&&n?.cloudflaredAvailable===!1?e.jsx("small",{className:"field-error",children:r("settings.remote.cloudflaredMustBeInstalledToStartTheTunnel","cloudflared must be installed to start the tunnel")}):null]})}),e.jsxs("details",{className:"remote-advanced-details",children:[e.jsx("summary",{children:r("settings.remote.advancedSettings","Advanced Settings")}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"remoteShortLivedEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"remoteShortLivedEnabled",type:"checkbox",checked:!!W.remoteShortLivedEnabled,onChange:$=>s(_=>({..._,remoteShortLivedEnabled:$.target.checked}))}),r("settings.remote.enableShortLivedTokens"," Enable short-lived tokens ")]}),e.jsx("label",{htmlFor:"remoteShortLivedTtlMs",children:r("settings.remote.shortLivedTTLMs","Short-lived TTL (ms)")}),e.jsx("input",{id:"remoteShortLivedTtlMs",type:"number",min:6e4,max:864e5,value:Number(W.remoteShortLivedTtlMs??9e5),onChange:$=>s(_=>({..._,remoteShortLivedTtlMs:Number($.target.value||9e5)}))}),S&&e.jsxs("small",{children:[r("settings.remote.lastShortLivedTokenExpiresAt","Last short-lived token expires at "),new Date(S.expiresAt).toLocaleString()," (",S.ttlMs,r("settings.remote.ms","ms)")]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"remoteRememberLastRunning",className:"checkbox-label",children:[e.jsx("input",{id:"remoteRememberLastRunning",type:"checkbox",checked:!!W.remoteRememberLastRunning,onChange:$=>s(_=>({..._,remoteRememberLastRunning:$.target.checked}))}),r("settings.remote.rememberLastRunningState"," Remember last running state ")]}),e.jsx("small",{children:r("settings.remote.automaticallyRestoreTunnelOnStartupIfItWas","Automatically restore tunnel on startup if it was running when last stopped.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:r("settings.remote.authLinks","Auth Links")}),e.jsxs("div",{className:"settings-button-row",children:[e.jsx("button",{type:"button",className:"btn btn-sm",disabled:j!==null,onClick:()=>void f("regenerate persistent token",async()=>{await il(m),i(r("settings.remote.persistentTokenRegenerated","Persistent token regenerated"),"success")}),children:r("settings.remote.regeneratePersistentToken","Regenerate persistent token")}),e.jsx("button",{type:"button",className:"btn btn-sm",disabled:j!==null,onClick:()=>void f("generate short-lived token",async()=>{const $=Number(W.remoteShortLivedTtlMs??9e5),_=await ll($,m);w(_),i(r("settings.remote.shortLivedTokenGenerated","Short-lived token generated"),"success")}),children:r("settings.remote.generateShortLivedToken","Generate short-lived token")}),e.jsx("button",{type:"button",className:"btn btn-sm",disabled:j!==null,onClick:()=>void f("fetch remote url",async()=>{const $=Number(W.remoteShortLivedTtlMs??9e5),_=await Rn({projectId:m,tokenType:I,ttlMs:I==="short-lived"?$:void 0});B(_),Y(null)}),children:r("settings.remote.showURL","Show URL")}),e.jsx("button",{type:"button",className:"btn btn-sm",disabled:j!==null,onClick:()=>void f("generate QR",async()=>{const $=Number(W.remoteShortLivedTtlMs??9e5),_=await Hs("image/svg",{projectId:m,tokenType:I,ttlMs:I==="short-lived"?$:void 0});B({url:_.url,expiresAt:_.expiresAt,tokenType:_.tokenType}),Y(_.data??null)}),children:r("settings.remote.generateQR","Generate QR")})]}),e.jsx("label",{htmlFor:"remoteAuthLinkTokenType",children:r("settings.remote.authLinkTokenType","Auth link token type")}),e.jsxs("select",{id:"remoteAuthLinkTokenType",value:I,onChange:$=>x($.target.value),children:[e.jsx("option",{value:"persistent",children:r("settings.remote.persistentToken","Persistent token")}),e.jsx("option",{value:"short-lived",children:r("settings.remote.shortLivedToken","Short-lived token")})]}),e.jsxs("small",{children:[r("settings.remote.uRLAndQRGenerationUseTheSelectedToken"," URL and QR generation use the selected token type. "),I==="short-lived"?` TTL: ${Number(W.remoteShortLivedTtlMs??9e5)}ms.`:""]}),v?.url&&e.jsxs(e.Fragment,{children:[e.jsxs("small",{children:[r("settings.remote.authenticatedURL","Authenticated URL:"),e.jsx("code",{className:"settings-url-output",children:v.url})]}),e.jsxs("small",{children:[r("settings.remote.tokenType"," Token type: "),e.jsx("strong",{children:v.tokenType}),v.expiresAt?r("settings.remote.expiresAt"," · Expires at {{expiresAt}}",{expiresAt:new Date(v.expiresAt).toLocaleString()}):r("settings.remote.noExpiry"," · No expiry")]})]}),k&&e.jsxs("div",{className:"settings-qr-preview","aria-live":"polite",children:[e.jsx("p",{className:"settings-qr-preview-label",children:r("settings.remote.scanThisQRCodeOnYourPhone","Scan this QR code on your phone")}),e.jsx("div",{className:"settings-qr-preview-image-wrap",children:e.jsx("img",{src:`data:image/svg+xml;utf8,${encodeURIComponent(k)}`,alt:r("settings.remote.remoteAccessQRCode","Remote access QR code"),className:"settings-qr-preview-image"})}),e.jsxs("details",{children:[e.jsx("summary",{children:r("settings.remote.qRSVGMarkup","QR SVG markup")}),e.jsx("pre",{className:"settings-raw-output",children:k})]})]})]})]})]})}const yc={enabled:!1,servers:[]};let pn=0;function Xs(){return pn+=1,`mcp-sensitive-${pn}`}function hn(a){return{enabled:a?.enabled===!0,servers:Array.isArray(a?.servers)?a.servers:[]}}function gn(a){return Object.entries(a??{}).map(([t,s])=>{const c=Ze(s)?s:{secretRef:"",scope:"project"};return{id:Xs(),key:t,secretRef:c.secretRef,scope:c.scope,createKey:t,createValue:"",required:!1}})}function Lt(a){return a?{originalName:a.name,name:a.name,enabled:a.enabled!==!1,transport:a.transport,command:a.transport==="stdio"?a.command:"",argsText:a.transport==="stdio"?(a.args??[]).join(" "):"",url:a.transport==="stdio"?"":a.url,env:a.transport==="stdio"?gn(a.env):[],headers:a.transport==="stdio"?[]:gn(a.headers)}:{name:"",enabled:!0,transport:"stdio",command:"",argsText:"",url:"",env:[],headers:[]}}function jc(a,t){const s=Lt(a),c=r=>t.filter(m=>m.field===r||r==="headers"&&m.field==="token").map(m=>({id:Xs(),key:m.key,secretRef:"",scope:m.scope,createKey:m.suggestedKey,createValue:"",required:!0}));return a.transport==="stdio"?{...s,env:c("env")}:{...s,headers:c("headers")}}function Ft(a){const t={};for(const s of a){const c=s.key.trim();!c||!s.secretRef.trim()||(t[c]={secretRef:s.secretRef.trim(),scope:s.scope})}return Object.keys(t).length>0?t:void 0}function kc(a){const t={name:a.name.trim(),...a.enabled?{}:{enabled:!1}};if(a.transport==="stdio"){const s=a.argsText.split(/\s+/u).map(c=>c.trim()).filter(Boolean);return{...t,transport:"stdio",command:a.command.trim(),...s.length>0?{args:s}:{},...Ft(a.env)?{env:Ft(a.env)}:{}}}return{...t,transport:a.transport,url:a.url.trim(),...Ft(a.headers)?{headers:Ft(a.headers)}:{}}}function ot(a,t){return fetch(a,{...t,headers:{"Content-Type":"application/json",...t?.headers??{}}}).then(async s=>{if(!s.ok){const c=await s.json().catch(()=>({error:"Request failed"}));throw new Error(String(c?.error??"Request failed"))}return s.json()})}function bn(a){return a.transport==="stdio"?`${a.command}${a.args?.length?` ${a.args.join(" ")}`:""}`:a.url}function wc(a){return a==="valid"?"status-dot status-dot--online":a==="pending"?"status-dot status-dot--pending":a==="unreachable"||a==="error"?"status-dot status-dot--error":"status-dot"}function Cc(a){return a==="disabled-global"?"disabled global":a==="project-local"?"project local":a}function fn(a){return a==="idle"?"Not tested":a==="pending"?"Testing…":a}function Bn({scope:a,form:t,setForm:s,globalSettings:c,projectId:r,addToast:m}){const{t:i}=Z("app"),n=o.useRef(null),p=hn(t.mcpServers??yc),A=hn(c?.mcpServers),j=p.servers??[],u=A.servers??[],[d,C]=o.useState(null),[b,h]=o.useState(null),[f,S]=o.useState([]),[w,I]=o.useState(null),[x,v]=o.useState(""),[B,k]=o.useState(null),[Y,W]=o.useState(""),[J,V]=o.useState({}),[ne,ae]=o.useState(null),[$,_]=o.useState(!1),[T,D]=o.useState(null),re=o.useCallback(async()=>{try{const N=await ot("/api/secrets");S(N.secrets),I(null)}catch(N){I(N instanceof Error?N.message:String(N))}},[]);o.useEffect(()=>{re()},[re]);const U=o.useCallback(async()=>{_(!0),D(null);try{const N=new URLSearchParams({scope:a});r&&N.set("projectId",r),ae(await ot(`/api/mcp/discovered?${N.toString()}`))}catch(N){D(N instanceof Error?N.message:String(N)),ae({sources:[],servers:[],errors:[]})}finally{_(!1)}},[r,a]);o.useEffect(()=>{U()},[U]);const ie=o.useMemo(()=>a==="project"?Qo({mcpServers:A},{mcpServers:t.mcpServers}):j.filter(N=>N.enabled!==!1),[j,t.mcpServers,A,a]),ve=o.useMemo(()=>new Map(u.map(N=>[N.name,N])),[u]),y=o.useMemo(()=>new Map(j.map(N=>[N.name,N])),[j]),H=o.useMemo(()=>new Set(j.map(N=>N.name)),[j]),he=o.useMemo(()=>{const N=new Map;for(const O of ne?.servers??[]){const L=N.get(O.source.label)??[];L.push(O),N.set(O.source.label,L)}return[...N.entries()]},[ne?.servers]),xe=o.useMemo(()=>{if(a==="global")return j.map(L=>({server:L,state:L.enabled===!1?"disabled":"configured"}));const N=new Set(ie.map(L=>L.name)),O=[];for(const L of u){const Q=y.get(L.name);Q?.enabled===!1?O.push({server:Q,state:"disabled-global"}):Q?O.push({server:Q,state:N.has(Q.name)?"overridden":"disabled"}):O.push({server:L,state:N.has(L.name)?"inherited":"disabled"})}for(const L of j)ve.has(L.name)||O.push({server:L,state:L.enabled===!1||!N.has(L.name)?"disabled":"project-local"});return O},[j,ie,ve,u,y,a]),fe=N=>{s(O=>({...O,mcpServers:N}))},K=N=>fe({...p,enabled:N}),P=()=>{if(!d)return;if(h(null),[...d.env,...d.headers].filter(le=>le.required&&(!le.key.trim()||!le.secretRef.trim())).length>0){h(i("settings.mcp.discoverySecretsRequired","Bind or create Fusion secret references before saving this discovered server."));return}const O=Js(kc(d));if(!O.value){h(O.errors.map(le=>le.message).join("; "));return}const L=j.filter(le=>le.name!==(d.originalName??O.value.name));if(L.some(le=>le.name===O.value.name)){h(i("settings.mcp.duplicateName","Duplicate MCP server name"));return}const se=[...L,O.value],me=Yo(se);if(!me.value){h(me.errors.map(le=>le.message).join("; "));return}fe({...p,enabled:!0,servers:me.value}),C(null)},F=N=>{fe({...p,servers:j.filter(O=>O.name!==N)}),V(O=>{const L={...O};return delete L[N],L})},X=N=>{if(H.has(N.definition.name))return;if(N.secretDescriptors.length>0||N.hasPlaintextSecrets){C(jc(N.definition,N.secretDescriptors)),h(i("settings.mcp.discoverySecretsRequired","Bind or create Fusion secret references before saving this discovered server."));return}const O=[...j.filter(L=>L.name!==N.definition.name),N.definition];fe({...p,enabled:!0,servers:O}),m(i("settings.mcp.discoveredAdded","Discovered MCP server added"),"success")},ce=N=>{const O=ve.get(N),L=O?.transport==="sse"||O?.transport==="streamable-http"?{name:N,enabled:!1,transport:O.transport,url:O.url}:{name:N,enabled:!1,transport:"stdio",command:O?.transport==="stdio"?O.command:"disabled"};fe({...p,enabled:!0,servers:[...j.filter(Q=>Q.name!==N),L]})},de=async(N,O)=>{if(!d)return;const L=N.createKey.trim()||N.key.trim();if(!L||!N.createValue){h(i("settings.mcp.secretCreateRequired","Secret key and value are required."));return}try{const Q=await ot("/api/secrets",{method:"POST",body:JSON.stringify({scope:N.scope,key:L,value:N.createValue,description:`MCP ${d.name||"server"} ${O} ${N.key}`,accessPolicy:"prompt",envExportable:!1,envExportKey:null})});C(se=>se&&{...se,[O]:se[O].map(me=>me.id===N.id?{...me,secretRef:Q.id,scope:Q.scope,createKey:Q.key,createValue:""}:me)}),await re(),m(i("settings.mcp.secretCreated","Secret created"),"success")}catch(Q){h(Q instanceof Error?Q.message:String(Q))}},te=async N=>{V(O=>({...O,[N.name]:{status:"pending",message:i("settings.mcp.testing","Testing…")}}));try{const O=await ot("/api/mcp/validate",{method:"POST",body:JSON.stringify({server:N})});V(L=>({...L,[N.name]:{status:O.status,message:O.message??fn(O.status)}}))}catch(O){V(L=>({...L,[N.name]:{status:"error",message:O instanceof Error?O.message:String(O)}}))}},R=async N=>{k(null);const O=Zo(N,{scope:a});if(O.errors.length>0){k(O.errors.join("; "));return}const L=new Set(j.map(se=>se.name)),Q=O.definitions.find(se=>L.has(se.name));if(Q){k(i("settings.mcp.importDuplicate","Duplicate MCP server name: {{name}}",{name:Q.name}));return}try{const se=new Map;for(const le of O.secretsToCreate){const we=await ot("/api/secrets",{method:"POST",body:JSON.stringify({scope:le.scope,key:le.suggestedKey,value:le.plaintextValue,description:`MCP import ${le.serverName} ${le.field} ${le.key}`,accessPolicy:"prompt",envExportable:!1,envExportKey:null})});se.set(le.suggestedKey,{secretRef:we.id,scope:we.scope})}const me=O.definitions.map(le=>{if(le.transport==="stdio"){const ge=Object.fromEntries(Object.entries(le.env??{}).map(([Ee,Le])=>[Ee,Ze(Le)&&se.has(Le.secretRef)?se.get(Le.secretRef):Le]));return{...le,...Object.keys(ge).length>0?{env:ge}:{}}}const we=Object.fromEntries(Object.entries(le.headers??{}).map(([ge,Ee])=>[ge,Ze(Ee)&&se.has(Ee.secretRef)?se.get(Ee.secretRef):Ee]));return{...le,...Object.keys(we).length>0?{headers:we}:{}}});fe({...p,enabled:!0,servers:[...j,...me]}),v(""),await re(),m(i("settings.mcp.imported","MCP servers imported"),"success")}catch(se){k(se instanceof Error?se.message:String(se))}},E=async()=>{const N=JSON.stringify(ec(j),null,2);W(N);try{await navigator.clipboard?.writeText(N),m(i("settings.mcp.exportCopied","MCP JSON copied"),"success")}catch{m(i("settings.mcp.exportReady","MCP JSON ready to copy"),"info")}},z=(N,O)=>e.jsxs("div",{className:"mcp-sensitive-list","data-testid":`mcp-${N}-rows`,children:[e.jsx("div",{className:"mcp-subheading",children:N==="env"?i("settings.mcp.env","Environment secret refs"):i("settings.mcp.headers","Header secret refs")}),O.length===0?e.jsx("p",{className:"mcp-empty-inline",children:i("settings.mcp.noSensitiveRows","No secret references configured.")}):null,O.map(L=>e.jsxs("div",{className:"mcp-sensitive-row",children:[e.jsx("input",{className:"input","aria-label":i("settings.mcp.sensitiveKey","Sensitive field name"),value:L.key,onChange:Q=>C(se=>se&&{...se,[N]:se[N].map(me=>me.id===L.id?{...me,key:Q.target.value}:me)}),placeholder:N==="env"?"API_KEY":"Authorization",readOnly:L.required}),L.required?e.jsx("span",{className:"mcp-state-badge mcp-state-badge--required",children:i("settings.mcp.requiredSecret","Required")}):null,e.jsxs("select",{className:"select","aria-label":i("settings.mcp.secretReference","Secret reference"),value:`${L.scope}:${L.secretRef}`,onChange:Q=>{const[se,me]=Q.target.value.split(":");C(le=>le&&{...le,[N]:le[N].map(we=>we.id===L.id?{...we,scope:se,secretRef:me}:we)})},children:[e.jsx("option",{value:`${L.scope}:`,children:i("settings.mcp.chooseSecret","Choose a secret…")}),f.map(Q=>e.jsxs("option",{value:`${Q.scope}:${Q.id}`,children:[Q.scope,": ",Q.key]},`${Q.scope}:${Q.id}`))]}),e.jsx("input",{className:"input","aria-label":i("settings.mcp.newSecretKey","New secret key"),value:L.createKey,onChange:Q=>C(se=>se&&{...se,[N]:se[N].map(me=>me.id===L.id?{...me,createKey:Q.target.value}:me)}),placeholder:i("settings.mcp.newSecretKey","New secret key")}),e.jsx("input",{className:"input",type:"password","aria-label":i("settings.mcp.newSecretValue","New secret value (not stored in settings)"),value:L.createValue,onChange:Q=>C(se=>se&&{...se,[N]:se[N].map(me=>me.id===L.id?{...me,createValue:Q.target.value}:me)}),placeholder:i("settings.mcp.createSecretPlaceholder","Create secret value")}),e.jsx("button",{type:"button",className:"btn btn-sm touch-target",onClick:()=>void de(L,N),children:i("settings.mcp.createSecret","Create secret")}),L.required?null:e.jsx("button",{type:"button",className:"btn btn-icon touch-target","aria-label":i("settings.mcp.removeSensitive","Remove secret reference"),onClick:()=>C(Q=>Q&&{...Q,[N]:Q[N].filter(se=>se.id!==L.id)}),children:e.jsx(Gt,{"aria-hidden":"true"})})]},L.id)),e.jsxs("button",{type:"button",className:"btn btn-sm touch-target",onClick:()=>C(L=>L&&{...L,[N]:[...L[N],{id:Xs(),key:"",secretRef:"",scope:a,createKey:"",createValue:"",required:!1}]}),children:[e.jsx(Ot,{"aria-hidden":"true"})," ",i("settings.mcp.addSecretRef","Add secret reference")]}),w?e.jsx("p",{className:"form-error",children:w}):null]});return e.jsxs("section",{className:"card mcp-servers-card","data-testid":`mcp-servers-card-${a}`,children:[e.jsxs("div",{className:"mcp-servers-card__header",children:[e.jsxs("div",{children:[e.jsx("h5",{className:"mcp-servers-card__title",children:a==="global"?i("settings.mcp.globalTitle","Global MCP servers"):i("settings.mcp.projectTitle","Project MCP servers")}),e.jsx("p",{className:"mcp-servers-card__description",children:a==="global"?i("settings.mcp.globalDescription","Configure MCP servers shared by all projects. Project settings may override or disable these servers by name."):i("settings.mcp.projectDescription","Configure project-specific MCP servers, overrides, and disabled inherited servers.")})]}),e.jsxs("button",{type:"button",className:"btn btn-primary touch-target",onClick:()=>{C(Lt()),h(null)},children:[e.jsx(Ot,{"aria-hidden":"true"})," ",i("settings.mcp.addServer","Add server")]})]}),e.jsxs("label",{className:"checkbox-label mcp-enabled-toggle",children:[e.jsx("input",{type:"checkbox",checked:p.enabled===!0,onChange:N=>K(N.target.checked)}),i("settings.mcp.enabled","Enable MCP servers for this scope")]}),e.jsxs("div",{className:"mcp-discovery card","data-testid":`mcp-discovery-${a}`,children:[e.jsxs("div",{className:"mcp-discovery__header",children:[e.jsxs("div",{children:[e.jsx("h6",{children:i("settings.mcp.discoveryTitle","Discovered on this machine")}),e.jsx("p",{children:i("settings.mcp.discoveryDescription","Read-only scan of Claude, Cursor, Windsurf, and VS Code MCP config files. Add a server to enable it in Fusion.")})]}),e.jsxs("button",{type:"button",className:"btn btn-sm touch-target",onClick:()=>void U(),disabled:$,children:[e.jsx(Ks,{"aria-hidden":"true"})," ",$?i("settings.mcp.scanning","Scanning…"):i("settings.mcp.scanAgain","Scan again")]})]}),T?e.jsx("p",{className:"form-error",children:T}):null,(ne?.errors.length??0)>0?e.jsx("div",{className:"mcp-discovery__notes",role:"note",children:ne?.errors.map(N=>e.jsx("p",{children:N},N))}):null,!$&&he.length===0?e.jsx("p",{className:"mcp-empty","data-testid":`mcp-discovery-empty-${a}`,children:i("settings.mcp.discoveryEmpty","No MCP servers found in supported tool configs yet.")}):null,he.map(([N,O])=>e.jsxs("div",{className:"mcp-discovery__group",children:[e.jsx("div",{className:"mcp-subheading",children:N}),O.map(L=>{const Q=L.alreadyConfigured||H.has(L.definition.name);return e.jsxs("article",{className:"mcp-discovery-row","data-testid":`mcp-discovery-row-${a}-${L.source.id}-${L.definition.name}`,children:[e.jsxs("div",{className:"mcp-server-row__main",children:[e.jsxs("div",{className:"mcp-server-row__titleline",children:[e.jsx("strong",{children:L.definition.name}),e.jsx("span",{className:"mcp-transport-badge",children:L.definition.transport}),Q?e.jsx("span",{className:"mcp-state-badge mcp-state-badge--configured",children:i("settings.mcp.configuredBadge","Configured")}):null]}),e.jsx("p",{children:bn(L.definition)}),L.secretDescriptors.length>0?e.jsx("p",{className:"mcp-discovery-row__note",children:i("settings.mcp.discoverySecrets","Requires Fusion secret references before saving.")}):null]}),e.jsx("div",{className:"mcp-server-row__actions",children:e.jsx("button",{type:"button",className:"btn btn-sm touch-target",onClick:()=>X(L),disabled:Q,children:Q?i("settings.mcp.configured","Configured"):i("settings.mcp.addDiscovered","Add")})})]},`${L.source.id}:${L.definition.name}`)})]},N))]}),xe.length===0?e.jsx("p",{className:"mcp-empty","data-testid":`mcp-empty-${a}`,children:i("settings.mcp.empty","No MCP servers configured.")}):e.jsx("div",{className:"mcp-server-list",children:xe.map(({server:N,state:O})=>{const L=J[N.name]??{status:"idle"},Q=a==="global"||O!=="inherited";return e.jsxs("article",{className:"mcp-server-row","data-testid":`mcp-server-row-${N.name}`,children:[e.jsxs("div",{className:"mcp-server-row__main",children:[e.jsxs("div",{className:"mcp-server-row__titleline",children:[e.jsx("strong",{children:N.name}),e.jsx("span",{className:`mcp-state-badge mcp-state-badge--${O}`,"data-state":O,children:Cc(O)}),e.jsx("span",{className:"mcp-transport-badge",children:N.transport})]}),e.jsx("p",{children:bn(N)}),e.jsxs("p",{className:`mcp-validation-status mcp-validation-status--${L.status}`,"data-testid":`mcp-validation-${N.name}`,"aria-live":"polite",children:[e.jsx("span",{className:wc(L.status),"aria-hidden":"true"})," ",e.jsx("span",{className:"mcp-validation-status__badge",children:L.status==="idle"?i("settings.mcp.notTested","Not tested"):fn(L.status)}),L.message?e.jsx("span",{children:L.message}):null]})]}),e.jsxs("div",{className:"mcp-server-row__actions",children:[e.jsxs("button",{type:"button",className:"btn btn-sm touch-target",onClick:()=>void te(N),disabled:L.status==="pending",children:[e.jsx(ol,{"aria-hidden":"true"})," ",L.status==="pending"?i("settings.mcp.testing","Testing…"):i("settings.mcp.test","Test")]}),O==="inherited"?e.jsxs("button",{type:"button",className:"btn btn-sm touch-target",onClick:()=>{C(Lt(N)),h(null)},children:[e.jsx(Bt,{"aria-hidden":"true"})," ",i("settings.mcp.override","Override")]}):null,O==="inherited"?e.jsx("button",{type:"button",className:"btn btn-warning btn-sm touch-target",onClick:()=>ce(N.name),children:i("settings.mcp.disableInherited","Disable")}):null,Q?e.jsxs("button",{type:"button",className:"btn btn-sm touch-target",onClick:()=>{C(Lt(N)),h(null)},children:[e.jsx(Bt,{"aria-hidden":"true"})," ",i("actions.edit","Edit")]}):null,Q?e.jsx("button",{type:"button",className:"btn btn-icon touch-target","aria-label":i("settings.mcp.removeServer","Remove {{name}}",{name:N.name}),onClick:()=>F(N.name),children:e.jsx(Gt,{"aria-hidden":"true"})}):null]})]},`${O}:${N.name}`)})}),d?e.jsxs("div",{className:"mcp-editor card","data-testid":"mcp-server-editor",children:[e.jsxs("div",{className:"mcp-editor-grid",children:[e.jsxs("label",{className:"form-group",children:[e.jsx("span",{children:i("settings.mcp.name","Name")}),e.jsx("input",{className:"input",value:d.name,onChange:N=>C({...d,name:N.target.value})})]}),e.jsxs("label",{className:"form-group",children:[e.jsx("span",{children:i("settings.mcp.transport","Transport")}),e.jsxs("select",{className:"select",value:d.transport,onChange:N=>C({...d,transport:N.target.value}),children:[e.jsx("option",{value:"stdio",children:"stdio"}),e.jsx("option",{value:"sse",children:"SSE"}),e.jsx("option",{value:"streamable-http",children:"HTTP"})]})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:d.enabled,onChange:N=>C({...d,enabled:N.target.checked})})," ",i("settings.mcp.serverEnabled","Server enabled")]}),d.transport==="stdio"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"form-group",children:[e.jsx("span",{children:i("settings.mcp.command","Command")}),e.jsx("input",{className:"input",value:d.command,onChange:N=>C({...d,command:N.target.value})})]}),e.jsxs("label",{className:"form-group",children:[e.jsx("span",{children:i("settings.mcp.args","Arguments")}),e.jsx("input",{className:"input",value:d.argsText,onChange:N=>C({...d,argsText:N.target.value})})]})]}):e.jsxs("label",{className:"form-group mcp-editor-grid__wide",children:[e.jsx("span",{children:i("settings.mcp.url","URL")}),e.jsx("input",{className:"input",value:d.url,onChange:N=>C({...d,url:N.target.value})})]})]}),d.transport==="stdio"?z("env",d.env):z("headers",d.headers),b?e.jsx("p",{className:"form-error",children:b}):null,e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{type:"button",className:"btn",onClick:()=>{C(null),h(null)},children:i("actions.cancel","Cancel")}),e.jsx("button",{type:"button",className:"btn btn-primary",onClick:P,children:i("actions.save","Save")})]})]}):null,e.jsxs("div",{className:"mcp-import-export",children:[e.jsxs("div",{className:"mcp-import-export__pane",children:[e.jsx("h6",{children:i("settings.mcp.import","Import")}),e.jsx("textarea",{className:"input mcp-json-textarea",value:x,onChange:N=>v(N.target.value),placeholder:i("settings.mcp.importPlaceholder","Paste Claude Desktop mcpServers JSON")}),e.jsx("input",{ref:n,className:"visually-hidden",type:"file",accept:"application/json,.json",onChange:N=>{const O=N.target.files?.[0];O&&(O.text().then(v),N.target.value="")}}),e.jsxs("div",{className:"mcp-inline-actions",children:[e.jsxs("button",{type:"button",className:"btn btn-sm touch-target",onClick:()=>n.current?.click(),children:[e.jsx(_o,{"aria-hidden":"true"})," ",i("settings.mcp.uploadJson","Upload JSON")]}),e.jsx("button",{type:"button",className:"btn btn-sm touch-target",onClick:()=>void R(x),children:i("settings.mcp.import","Import")})]}),B?e.jsx("p",{className:"form-error",children:B}):null]}),e.jsxs("div",{className:"mcp-import-export__pane",children:[e.jsx("h6",{children:i("settings.mcp.export","Export")}),e.jsxs("button",{type:"button",className:"btn btn-sm touch-target",onClick:()=>void E(),children:[e.jsx(cl,{"aria-hidden":"true"})," ",i("settings.mcp.copyExport","Copy Fusion MCP JSON")]}),Y?e.jsx("a",{className:"btn btn-sm touch-target",download:"fusion-mcp-servers.json",href:`data:application/json;charset=utf-8,${encodeURIComponent(Y)}`,children:i("settings.mcp.downloadExport","Download JSON")}):null,Y?e.jsx("textarea",{className:"input mcp-json-textarea",readOnly:!0,value:Y,"aria-label":i("settings.mcp.exportedJson","Exported MCP JSON")}):null]})]}),a==="project"?e.jsx("p",{className:"mcp-effective-count",children:i("settings.mcp.effectiveCount","Effective enabled servers: {{count}}",{count:ie.length})}):null]})}function Nc({scopeBanner:a,form:t,setForm:s,projectId:c,addToast:r}){const{t:m}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:m("settings.nav.globalMcp","MCP Servers")}),e.jsx(Bn,{scope:"global",form:t,setForm:s,projectId:c,addToast:r})]})}function Sc(a,t){return{key:a,...t}}function Pc(a){return a.trim().toLowerCase()}function We(a){const t=Number(a);return Number.isFinite(t)?t:0}function Ac(a){return a?`/command-center/pricing/fetch?projectId=${encodeURIComponent(a)}`:"/command-center/pricing/fetch"}function Is(a,t){a(s=>({...s,modelPricingOverrides:t}))}function Mc({form:a,setForm:t,addToast:s,projectId:c}){const{t:r}=Z("app"),[m,i]=o.useState({key:"",inputPer1M:0,outputPer1M:0,cacheReadPer1M:0,cacheWritePer1M:0,source:"manual"}),[n,p]=o.useState(!1),[A,j]=o.useState(!1),u=o.useMemo(()=>Object.entries(a.modelPricingOverrides??{}).sort(([v],[B])=>v.localeCompare(B)),[a.modelPricingOverrides]),d=o.useCallback(()=>j(!1),[]);o.useEffect(()=>{if(!A)return;const v=B=>{B.key==="Escape"&&(B.preventDefault(),d())};return document.addEventListener("keydown",v),()=>document.removeEventListener("keydown",v)},[d,A]);const C=o.useCallback(v=>{v.target===v.currentTarget&&d()},[d]),b=(v,B)=>{const k=a.modelPricingOverrides??{},Y=k[v];Y&&Is(t,{...k,[v]:{...Y,...B}})},h=v=>{const B={...a.modelPricingOverrides??{}};delete B[v],Is(t,B)},f=()=>{const v=Pc(m.key);if(!v||!v.includes(":")){s(r("settings.modelPricing.invalidKey","Use a provider:model key before adding a pricing row."),"error");return}Is(t,{...a.modelPricingOverrides??{},[v]:{inputPer1M:m.inputPer1M,outputPer1M:m.outputPer1M,cacheReadPer1M:m.cacheReadPer1M,cacheWritePer1M:m.cacheWritePer1M,source:m.source||"manual"}}),i({key:"",inputPer1M:0,outputPer1M:0,cacheReadPer1M:0,cacheWritePer1M:0,source:"manual"})},S=async()=>{p(!0);try{const v=await Ha(Ac(c),{method:"POST"}),B=await Ha("/settings/global");t(k=>({...k,modelPricingOverrides:B.modelPricingOverrides??k.modelPricingOverrides,modelPricingFetchedAt:B.modelPricingFetchedAt??v.fetchedAt,modelPricingSource:B.modelPricingSource??v.source})),s(r("settings.modelPricing.fetchSuccess","Fetched {{count}} model prices.",{count:v.count}),"success")}catch(v){s(v instanceof Error?v.message:r("settings.modelPricing.fetchFailed","Failed to fetch latest model prices."),"error")}finally{p(!1)}},w=r("settings.modelPricing.empty","No model pricing overrides yet. Add one manually or fetch the latest LiteLLM prices."),I=r("settings.modelPricing.overrideCount",u.length===1?"{{count}} pricing override":"{{count}} pricing overrides",{count:u.length}),x=()=>A?e.jsx("div",{className:"modal-overlay open",onClick:C,role:"dialog","aria-modal":"true","aria-labelledby":"model-pricing-table-title","data-testid":"model-pricing-table-modal",children:e.jsxs("div",{className:"modal modal-lg model-pricing-modal",children:[e.jsxs("div",{className:"modal-header",children:[e.jsxs("div",{children:[e.jsx("h3",{id:"model-pricing-table-title",children:r("settings.modelPricing.tableTitle","Model pricing table")}),e.jsx("p",{className:"settings-muted model-pricing-modal__subtitle",children:r("settings.modelPricing.saveHint","Manual edits are saved with the rest of Global settings.")})]}),e.jsx("button",{type:"button",className:"modal-close",onClick:d,"aria-label":r("actions.close","Close"),"data-testid":"model-pricing-close",children:e.jsx(dl,{size:20})})]}),e.jsx("div",{className:"model-pricing-modal__body",children:e.jsxs("div",{className:"model-pricing-table",role:"table","aria-label":r("settings.modelPricing.overrides","Model pricing overrides"),children:[e.jsxs("div",{className:"model-pricing-row model-pricing-row--head",role:"row",children:[e.jsx("span",{role:"columnheader",children:r("settings.modelPricing.modelKey","provider:model")}),e.jsx("span",{role:"columnheader",children:r("settings.modelPricing.input","Input / 1M")}),e.jsx("span",{role:"columnheader",children:r("settings.modelPricing.output","Output / 1M")}),e.jsx("span",{role:"columnheader",children:r("settings.modelPricing.cacheRead","Cache read / 1M")}),e.jsx("span",{role:"columnheader",children:r("settings.modelPricing.cacheWrite","Cache write / 1M")}),e.jsx("span",{role:"columnheader",children:r("settings.modelPricing.source","Source")}),e.jsx("span",{role:"columnheader",children:r("settings.modelPricing.actions","Actions")})]}),u.length===0?e.jsx("div",{className:"settings-empty-state model-pricing-empty",role:"row",children:w}):u.map(([v,B])=>{const k=Sc(v,B);return e.jsxs("div",{className:"model-pricing-row",role:"row",children:[e.jsx("code",{className:"model-pricing-key",role:"cell",children:k.key}),e.jsx("input",{"aria-label":`${v} input per 1M`,className:"input",type:"number",step:"any",value:k.inputPer1M,onChange:Y=>b(v,{inputPer1M:We(Y.target.value)})}),e.jsx("input",{"aria-label":`${v} output per 1M`,className:"input",type:"number",step:"any",value:k.outputPer1M,onChange:Y=>b(v,{outputPer1M:We(Y.target.value)})}),e.jsx("input",{"aria-label":`${v} cache read per 1M`,className:"input",type:"number",step:"any",value:k.cacheReadPer1M,onChange:Y=>b(v,{cacheReadPer1M:We(Y.target.value)})}),e.jsx("input",{"aria-label":`${v} cache write per 1M`,className:"input",type:"number",step:"any",value:k.cacheWritePer1M,onChange:Y=>b(v,{cacheWritePer1M:We(Y.target.value)})}),e.jsx("input",{"aria-label":`${v} source`,className:"input",value:k.source,onChange:Y=>b(v,{source:Y.target.value})}),e.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",onClick:()=>h(v),children:r("settings.modelPricing.delete","Delete")})]},v)}),e.jsxs("div",{className:"model-pricing-row model-pricing-row--add",role:"row",children:[e.jsx("input",{"aria-label":r("settings.modelPricing.newKey","New provider:model key"),className:"input",placeholder:"openai:gpt-4o",value:m.key,onChange:v=>i(B=>({...B,key:v.target.value}))}),e.jsx("input",{"aria-label":r("settings.modelPricing.newInput","New input rate"),className:"input",type:"number",step:"any",value:m.inputPer1M,onChange:v=>i(B=>({...B,inputPer1M:We(v.target.value)}))}),e.jsx("input",{"aria-label":r("settings.modelPricing.newOutput","New output rate"),className:"input",type:"number",step:"any",value:m.outputPer1M,onChange:v=>i(B=>({...B,outputPer1M:We(v.target.value)}))}),e.jsx("input",{"aria-label":r("settings.modelPricing.newCacheRead","New cache read rate"),className:"input",type:"number",step:"any",value:m.cacheReadPer1M,onChange:v=>i(B=>({...B,cacheReadPer1M:We(v.target.value)}))}),e.jsx("input",{"aria-label":r("settings.modelPricing.newCacheWrite","New cache write rate"),className:"input",type:"number",step:"any",value:m.cacheWritePer1M,onChange:v=>i(B=>({...B,cacheWritePer1M:We(v.target.value)}))}),e.jsx("input",{"aria-label":r("settings.modelPricing.newSource","New source"),className:"input",value:m.source,onChange:v=>i(B=>({...B,source:v.target.value}))}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:f,children:r("settings.modelPricing.addRow","Add row")})]})]})})]})}):null;return e.jsxs("section",{className:"model-pricing-section","aria-label":r("settings.modelPricing.title","Model pricing overrides"),children:[e.jsxs("div",{className:"model-pricing-section__header",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:r("settings.modelPricing.title","Model Pricing")}),e.jsx("p",{className:"settings-description",children:r("settings.modelPricing.description","Override per-1M token rates used by Command Center cost estimates. Overrides win over the built-in baseline; unlisted models still use the baseline.")}),e.jsxs("p",{className:"settings-muted model-pricing-section__meta",children:[a.modelPricingFetchedAt?r("settings.modelPricing.pricesAsOf","Prices as of {{date}}",{date:new Date(a.modelPricingFetchedAt).toLocaleString()}):r("settings.modelPricing.noFetchYet","No fetched pricing snapshot yet."),a.modelPricingSource?` · ${a.modelPricingSource}`:""]})]}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>void S(),disabled:n,children:n?r("settings.modelPricing.fetching","Fetching…"):r("settings.modelPricing.fetchLatest","Fetch latest prices")})]}),e.jsxs("div",{className:"model-pricing-summary",children:[e.jsxs("div",{children:[e.jsx("strong",{children:I}),u.length===0?e.jsx("p",{className:"settings-muted model-pricing-summary__empty",children:w}):null]}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>j(!0),children:r("settings.modelPricing.viewTable","View pricing table")})]}),e.jsx("small",{children:r("settings.modelPricing.saveHint","Manual edits are saved with the rest of Global settings.")}),x()]})}function ct(a){return a?.join(", ")??""}function dt(a){return a.split(",").map(t=>t.trim()).filter(t=>t.length>0)}function Tc({scopeBanner:a,form:t,setForm:s,availableModels:c,modelsLoading:r,globalModelLanes:m,favoriteProviders:i,favoriteModels:n,onToggleFavorite:p,onToggleModelFavorite:A,addToast:j,projectId:u}){const{t:d}=Z("app"),C=t.defaultProvider&&t.defaultModelId?`${t.defaultProvider}/${t.defaultModelId}`:"";return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:d("settings.globalModels.defaultModel","Default Model")}),r?e.jsx("div",{className:"settings-empty-state",children:e.jsx(ze,{label:d("settings.models.loadingModels","Loading available models…")})}):c.length===0?e.jsx("div",{className:"settings-empty-state settings-muted",children:d("settings.models.noModels","No models available. Configure authentication first.")}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"defaultModel",children:d("settings.globalModels.defaultModel","Default Model")}),e.jsx(Ke,{id:"defaultModel",label:"Default Model",models:c,value:C,onChange:b=>{if(!b)s(h=>({...h,defaultProvider:void 0,defaultModelId:void 0}));else{const h=b.indexOf("/");s(f=>({...f,defaultProvider:b.slice(0,h),defaultModelId:b.slice(h+1)}))}},placeholder:d("settings.globalModels.useDefault","Use default"),favoriteProviders:i,onToggleFavorite:p,favoriteModels:n,onToggleModelFavorite:A}),e.jsx("small",{children:d("settings.globalModels.defaultAIModelUsedForTaskExecutionWhen","Default AI model used for task execution when no per-task override is set. &quot;Use default&quot; lets the engine choose automatically.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"fallbackModel",children:d("settings.globalModels.fallbackModel","Fallback Model")}),e.jsx(Ke,{id:"fallbackModel",label:"Fallback Model",models:c,value:t.fallbackProvider&&t.fallbackModelId?`${t.fallbackProvider}/${t.fallbackModelId}`:"",onChange:b=>{if(!b)s(h=>({...h,fallbackProvider:void 0,fallbackModelId:void 0}));else{const h=b.indexOf("/");s(f=>({...f,fallbackProvider:b.slice(0,h),fallbackModelId:b.slice(h+1)}))}},placeholder:d("settings.globalModels.noFallback","No fallback"),favoriteProviders:i,onToggleFavorite:p,favoriteModels:n,onToggleModelFavorite:A}),e.jsx("small",{children:d("settings.globalModels.usedAutomaticallyIfThePrimaryDefaultModelHits","Used automatically if the primary default model hits a retryable provider error like rate limiting or overload.")})]})]}),(()=>{const b=c.find(h=>h.provider===t.defaultProvider&&h.id===t.defaultModelId);return b&&!b.reasoning?null:e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"defaultThinkingLevel",children:d("settings.globalModels.thinkingEffort","Thinking Effort")}),e.jsxs("select",{id:"defaultThinkingLevel",value:t.defaultThinkingLevel||"",onChange:h=>{const f=h.target.value;s(S=>({...S,defaultThinkingLevel:f||void 0}))},children:[e.jsx("option",{value:"",children:d("settings.globalModels.default","Default")}),ul.map(h=>e.jsx("option",{value:h,children:h.charAt(0).toUpperCase()+h.slice(1)},h))]}),e.jsx("small",{children:d("settings.globalModels.controlsHowMuchReasoningEffortTheAIModel","Controls how much reasoning effort the AI model uses. Higher levels produce better results but cost more.")})]})})(),c.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:d("settings.globalModels.modelLanes","Model Lanes")}),e.jsx("p",{className:"settings-description",children:d("settings.globalModels.globalBaselineModelsForEachAIRoleProject"," Global baseline models for each AI role. Project settings can override these per-project. ")}),m.map(b=>{const h=t[b.globalProviderKey],f=t[b.globalModelKey],S=h&&f?`${h}/${f}`:"";return e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:`global-${b.laneId}-model`,children:b.label}),e.jsx(Ke,{id:`global-${b.laneId}-model`,label:b.label,models:c,value:S,onChange:w=>{if(!w){s(x=>({...x,[b.globalProviderKey]:void 0,[b.globalModelKey]:void 0}));return}const I=w.indexOf("/");s(x=>({...x,[b.globalProviderKey]:w.slice(0,I),[b.globalModelKey]:w.slice(I+1)}))},placeholder:d("settings.globalModels.useDefault","Use default"),favoriteProviders:i,onToggleFavorite:p,favoriteModels:n,onToggleModelFavorite:A}),e.jsx("small",{children:b.helperText})]},`global-${b.laneId}`)})]}),e.jsx(Mc,{form:t,setForm:s,addToast:j,projectId:u}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:d("settings.globalModels.startupModelSync","Startup Model Sync")}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"openrouterModelSync",className:"checkbox-label",children:[e.jsx("input",{id:"openrouterModelSync",type:"checkbox",checked:t.openrouterModelSync!==!1,onChange:b=>s(h=>({...h,openrouterModelSync:b.target.checked}))}),d("settings.globalModels.syncOpenRouterModelListAtStartup"," Sync OpenRouter model list at startup ")]}),e.jsx("small",{children:d("settings.globalModels.whenEnabledStartupFetchesTheLatestAvailableModels"," When enabled, startup fetches the latest available models from the OpenRouter API so model pickers always include the newest catalog. ")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"opencodeGoModelSync",className:"checkbox-label",children:[e.jsx("input",{id:"opencodeGoModelSync",type:"checkbox",checked:t.opencodeGoModelSync!==!1,onChange:b=>s(h=>({...h,opencodeGoModelSync:b.target.checked}))}),d("settings.globalModels.syncOpencodeGoModelListAtStartup"," Sync opencode-go model list at startup ")]}),e.jsxs("small",{children:[d("settings.globalModels.whenEnabledStartupRefreshesModelsThroughTheLocal"," When enabled, startup refreshes models through the local "),e.jsx("code",{children:"opencode models opencode --refresh"}),d("settings.globalModels.flowAndPublishesThemUnderTheOpencodeGo"," flow and publishes them under the opencode-go provider in model pickers. ")]})]}),e.jsxs("details",{children:[e.jsx("summary",{children:d("settings.globalModels.openRouterAdvanced","OpenRouter advanced")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openrouterAppAttributionReferer",children:d("settings.globalModels.openRouterHTTPReferer","OpenRouter HTTP-Referer")}),e.jsx("input",{id:"openrouterAppAttributionReferer",className:"input",placeholder:d("settings.globalModels.httpsRunfusionAi","https://runfusion.ai"),value:t.openrouterAppAttribution?.referer??"",onChange:b=>s(h=>({...h,openrouterAppAttribution:{...h.openrouterAppAttribution||{},referer:b.target.value}}))}),e.jsx("small",{children:d("settings.globalModels.leaveEmptyToOmitThisHeaderDefaultHttps","Leave empty to omit this header. Default: https://runfusion.ai.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openrouterAppAttributionTitle",children:d("settings.globalModels.openRouterXTitle","OpenRouter X-Title")}),e.jsx("input",{id:"openrouterAppAttributionTitle",className:"input",placeholder:d("settings.globalModels.fusion","Fusion"),value:t.openrouterAppAttribution?.title??"",onChange:b=>s(h=>({...h,openrouterAppAttribution:{...h.openrouterAppAttribution||{},title:b.target.value}}))}),e.jsx("small",{children:d("settings.globalModels.leaveEmptyToOmitThisHeaderDefaultFusion","Leave empty to omit this header. Default: Fusion.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openrouterModelFiltersSupportedParameters",children:d("settings.globalModels.openRouterSupportedParametersFilter","OpenRouter supported_parameters filter")}),e.jsx("input",{id:"openrouterModelFiltersSupportedParameters",className:"input",placeholder:d("settings.globalModels.toolsStructuredOutputs","tools, structured_outputs"),value:ct(t.openrouterModelFilters?.supported_parameters),onChange:b=>{const h=dt(b.target.value);s(f=>({...f,openrouterModelFilters:{...f.openrouterModelFilters||{},supported_parameters:h.length>0?h:void 0}}))}}),e.jsx("small",{children:d("settings.globalModels.commaSeparatedValuesSentToOpenRouterModelSync","Comma-separated values sent to OpenRouter model sync.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openrouterModelFiltersOutputModalities",children:d("settings.globalModels.openRouterOutputModalitiesFilter","OpenRouter output_modalities filter")}),e.jsx("input",{id:"openrouterModelFiltersOutputModalities",className:"input",placeholder:d("settings.globalModels.text","text"),value:ct(t.openrouterModelFilters?.output_modalities),onChange:b=>{const h=dt(b.target.value);s(f=>({...f,openrouterModelFilters:{...f.openrouterModelFilters||{},output_modalities:h.length>0?h:void 0}}))}}),e.jsx("small",{children:d("settings.globalModels.commaSeparatedValuesSentToOpenRouterModelSync","Comma-separated values sent to OpenRouter model sync.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openrouterProviderPreferencesOrder",children:d("settings.globalModels.openRouterRoutingOrder","OpenRouter routing order")}),e.jsx("input",{id:"openrouterProviderPreferencesOrder",className:"input",placeholder:d("settings.globalModels.openaiAnthropic","openai, anthropic"),value:ct(t.openrouterProviderPreferences?.order),onChange:b=>{const h=dt(b.target.value);s(f=>({...f,openrouterProviderPreferences:{...f.openrouterProviderPreferences||{},order:h.length>0?h:void 0}}))}})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openrouterProviderPreferencesIgnore",children:d("settings.globalModels.openRouterRoutingIgnore","OpenRouter routing ignore")}),e.jsx("input",{id:"openrouterProviderPreferencesIgnore",className:"input",placeholder:d("settings.globalModels.providerName","provider-name"),value:ct(t.openrouterProviderPreferences?.ignore),onChange:b=>{const h=dt(b.target.value);s(f=>({...f,openrouterProviderPreferences:{...f.openrouterProviderPreferences||{},ignore:h.length>0?h:void 0}}))}})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openrouterProviderPreferencesOnly",children:d("settings.globalModels.openRouterRoutingOnly","OpenRouter routing only")}),e.jsx("input",{id:"openrouterProviderPreferencesOnly",className:"input",placeholder:d("settings.globalModels.providerName","provider-name"),value:ct(t.openrouterProviderPreferences?.only),onChange:b=>{const h=dt(b.target.value);s(f=>({...f,openrouterProviderPreferences:{...f.openrouterProviderPreferences||{},only:h.length>0?h:void 0}}))}})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openrouterProviderPreferencesAllowFallbacks",children:d("settings.globalModels.openRouterAllowFallbacks","OpenRouter allow fallbacks")}),e.jsxs("select",{id:"openrouterProviderPreferencesAllowFallbacks",className:"select",value:t.openrouterProviderPreferences?.allow_fallbacks===void 0?"default":t.openrouterProviderPreferences.allow_fallbacks?"allow":"deny",onChange:b=>{const h=b.target.value;s(f=>({...f,openrouterProviderPreferences:{...f.openrouterProviderPreferences||{},allow_fallbacks:h==="default"?void 0:h==="allow"}}))},children:[e.jsx("option",{value:"default",children:d("settings.globalModels.default2","default")}),e.jsx("option",{value:"allow",children:d("settings.globalModels.allow","allow")}),e.jsx("option",{value:"deny",children:d("settings.globalModels.deny","deny")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openrouterProviderPreferencesSort",children:d("settings.globalModels.openRouterRoutingSort","OpenRouter routing sort")}),e.jsxs("select",{id:"openrouterProviderPreferencesSort",className:"select",value:t.openrouterProviderPreferences?.sort??"default",onChange:b=>{const h=b.target.value;s(f=>({...f,openrouterProviderPreferences:{...f.openrouterProviderPreferences||{},sort:h==="default"?void 0:h}}))},children:[e.jsx("option",{value:"default",children:d("settings.globalModels.default2","default")}),e.jsx("option",{value:"price",children:d("settings.globalModels.price","price")}),e.jsx("option",{value:"throughput",children:d("settings.globalModels.throughput","throughput")}),e.jsx("option",{value:"latency",children:d("settings.globalModels.latency","latency")})]})]}),e.jsx("div",{className:"form-group",children:e.jsxs("label",{htmlFor:"openrouterProviderPreferencesRequireParameters",className:"checkbox-label",children:[e.jsx("input",{id:"openrouterProviderPreferencesRequireParameters",type:"checkbox",checked:t.openrouterProviderPreferences?.require_parameters===!0,onChange:b=>s(h=>({...h,openrouterProviderPreferences:{...h.openrouterProviderPreferences||{},require_parameters:b.target.checked}}))}),d("settings.globalModels.requireParameters"," Require parameters ")]})})]})]})}const Rc=["openai-compatible","openai-responses","anthropic-compatible","google-generative-ai"];function Ic(a){return(Array.isArray(a)?a:a.providers??[]).map(s=>"apiType"in s?s:{id:s.id,name:s.name?.trim()||s.id,apiType:s.api==="anthropic-messages"?"anthropic-compatible":s.api==="openai-responses"?"openai-responses":s.api==="google-generative-ai"?"google-generative-ai":"openai-compatible",baseUrl:s.baseUrl,...s.apiKey?{apiKey:s.apiKey}:{},models:(s.models??[]).map(c=>({id:c.id,name:c.name??c.id}))})}function Ec(a){return a.split(",").map(t=>t.trim()).filter(Boolean).map(t=>({id:t,name:t}))}function Fc({embedded:a=!1,onProviderChange:t}){const{t:s}=Z("app"),[c,r]=o.useState([]),[m,i]=o.useState(!1),[n,p]=o.useState(!1),[A,j]=o.useState(null),[u,d]=o.useState(null),[C,b]=o.useState(!1),[h,f]=o.useState(""),[S,w]=o.useState("openai-compatible"),[I,x]=o.useState(""),[v,B]=o.useState(""),[k,Y]=o.useState(""),[W,J]=o.useState(!1),[V,ne]=o.useState(null),[ae,$]=o.useState(!1),[_,T]=o.useState(null),D=o.useCallback(async()=>{i(!0),j(null);try{const K=await ml();r(Ic(K)),p(!0)}catch(K){j(K instanceof Error?K.message:s("providers.failedLoad","Failed to load custom providers."))}finally{i(!1)}},[s]),re=o.useCallback(K=>{K&&!n&&!m&&D()},[n,m,D]);o.useEffect(()=>{a&&!n&&!m&&D()},[a,n,m,D]);const U=o.useCallback(()=>{d(null),f(""),w("openai-compatible"),x(""),B(""),Y(""),ne(null),T(null),$(!1),b(!1)},[]),ie=o.useCallback(()=>{d(null),f(""),w("openai-compatible"),x(""),B(""),Y(""),ne(null),T(null),$(!1),b(!0)},[]),ve=o.useCallback(K=>{d(K),f(K.name),w(K.apiType),x(K.baseUrl),B(""),Y((K.models??[]).map(P=>P.id).join(", ")),ne(null),T(null),$(!1),b(!0)},[]),y=o.useCallback(()=>{if(!h.trim())return s("providers.nameRequired","Provider name is required.");if(!I.trim())return s("providers.urlRequired","Base URL is required.");let K=!1;try{const P=new URL(I.trim());K=P.protocol==="http:"||P.protocol==="https:"}catch{K=!1}return K?Rc.includes(S)?null:s("providers.apiTypeInvalid","API type is invalid."):s("providers.urlInvalid","Base URL must be a valid http/https URL.")},[S,I,h,s]),H=o.useCallback(async()=>{const K=I.trim();if(!K){T(s("providers.urlRequiredForDetect","Base URL is required to detect models."));return}$(!0),T(null);try{const P=await pl({baseUrl:K,apiKey:v.trim()||void 0,apiType:S});P.models.length>0?Y(F=>{const X=new Set(F.split(",").map(te=>te.trim()).filter(Boolean)),ce=P.models.map(te=>te.id.trim()).filter(te=>!X.has(te));if(ce.length===0)return F;const de=F.trim();return ce.join(", ")+(de?", "+de:"")}):T(s("providers.noModelsFound","No models found. The provider may require an API key."))}catch(P){T(P instanceof Error?P.message:s("providers.failedDetect","Failed to detect models"))}finally{$(!1)}},[I,v,S,s]),he=o.useCallback(async()=>{const K=y();if(ne(K),K)return;const P=Ec(k),F={name:h.trim(),apiType:S,baseUrl:I.trim(),...v.trim()?{apiKey:v.trim()}:{},...P.length>0?{models:P}:{}};J(!0),j(null);try{u?await hl(u.id,F):await gl(F),await D(),t?.(),U()}catch(X){ne(X instanceof Error?X.message:s("providers.failedSave","Failed to save provider."))}finally{J(!1)}},[v,S,I,u,D,k,h,U,y,s]),xe=o.useCallback(async K=>{if(window.confirm(s("providers.deleteConfirm",'Delete custom provider "{{name}}"?',{name:K.name}))){j(null);try{await bl(K.id),await D(),t?.()}catch(P){j(P instanceof Error?P.message:s("providers.failedDelete","Failed to delete provider."))}}},[D,t,s]),fe=e.jsxs(e.Fragment,{children:[a?null:m?e.jsxs("div",{className:"custom-provider-empty",role:"status",children:[e.jsx(qe,{"aria-hidden":"true",className:"custom-provider-spin"})," ",s("providers.loading","Loading custom providers…")]}):null,a?null:!m&&A?e.jsxs("div",{className:"custom-provider-form-error",role:"alert",children:[e.jsx(fl,{"aria-hidden":"true"}),e.jsx("span",{children:A})]}):null,!m&&c.length>0?e.jsx("div",{className:"custom-provider-list",children:c.map(K=>{const P=C&&u?.id===K.id;return e.jsxs("div",{children:[e.jsxs("div",{className:"auth-provider-card custom-provider-item",children:[e.jsxs("div",{className:"custom-provider-item-info",children:[e.jsx("div",{className:"custom-provider-item-name",children:K.name}),e.jsxs("div",{className:"custom-provider-item-meta",children:[e.jsx("span",{className:"custom-provider-badge",children:K.apiType})," ",K.baseUrl]})]}),e.jsxs("div",{className:"custom-provider-item-actions",children:[e.jsx("button",{type:"button",className:"btn btn-icon btn-sm",onClick:()=>ve(K),"aria-label":s("providers.editLabel","Edit {{name}}",{name:K.name}),children:e.jsx(Bt,{"aria-hidden":"true"})}),e.jsx("button",{type:"button",className:"btn btn-icon btn-sm",onClick:()=>void xe(K),"aria-label":s("providers.deleteLabel","Delete {{name}}",{name:K.name}),children:e.jsx(Gt,{"aria-hidden":"true"})})]})]}),P?e.jsxs("div",{className:"custom-provider-form custom-provider-item-edit-form",children:[e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-name",children:s("providers.nameLabel","Provider name")}),e.jsx("input",{id:"custom-provider-name",className:"input",value:h,onChange:F=>f(F.target.value),disabled:W})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-api-type",children:s("providers.apiTypeLabel","API type")}),e.jsxs("select",{id:"custom-provider-api-type",className:"select",value:S,onChange:F=>w(F.target.value),disabled:W,children:[e.jsx("option",{value:"openai-compatible",children:s("providers.apiTypeOpenAi","OpenAI-compatible")}),e.jsx("option",{value:"openai-responses",children:s("providers.apiTypeOpenAiResp","OpenAI Responses")}),e.jsx("option",{value:"anthropic-compatible",children:s("providers.apiTypeAnthropic","Anthropic-compatible")}),e.jsx("option",{value:"google-generative-ai",children:s("providers.apiTypeGoogle","Google Generative AI")})]})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-base-url",children:s("providers.baseUrlLabel","Base URL")}),e.jsx("input",{id:"custom-provider-base-url",className:"input",placeholder:"https://api.example.com/v1",value:I,onChange:F=>x(F.target.value),disabled:W})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-api-key",children:s("providers.apiKeyLabel","API key")}),e.jsx("input",{id:"custom-provider-api-key",type:"password",className:"input",placeholder:u?.apiKey?s("providers.apiKeyKeepPlaceholder","Leave blank to keep current key"):void 0,value:v,onChange:F=>B(F.target.value),disabled:W})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-models",children:s("providers.modelsLabel","Available models")}),e.jsx("input",{id:"custom-provider-models",className:"input",placeholder:"e.g., gpt-4, gpt-3.5-turbo",value:k,onChange:F=>Y(F.target.value),disabled:W})]}),e.jsx("div",{style:{display:"flex",gap:"8px",alignItems:"center",marginTop:"4px"},children:e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>void H(),disabled:W||ae||!I.trim(),title:s("providers.detectTitle","Auto-detect models from the provider's /models endpoint"),children:ae?e.jsxs(e.Fragment,{children:[e.jsx(qe,{className:"custom-provider-spin",size:14})," ",s("providers.detecting","Detecting…")]}):e.jsxs(e.Fragment,{children:[e.jsx(Ka,{size:14})," ",s("providers.detectModels","Detect Models")]})})}),_?e.jsx("div",{className:"custom-provider-form-error",children:_}):null,V?e.jsx("div",{className:"custom-provider-form-error",children:V}):null,e.jsxs("div",{className:"custom-provider-form-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:U,disabled:W,children:s("actions.cancel","Cancel")}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:()=>void he(),disabled:W,children:W?s("providers.saving","Saving…"):s("providers.saveChanges","Save Changes")})]})]}):null]},K.id)})}):null,!m&&c.length===0&&!A?e.jsx("div",{className:"custom-provider-empty",children:s("providers.noneConfigured","No custom providers configured.")}):null,e.jsxs("button",{type:"button",className:"btn btn-sm custom-provider-add-btn",onClick:ie,children:[e.jsx(Ot,{"aria-hidden":"true"})," ",s("providers.addCustom","Add Custom Provider")]}),C&&!u?e.jsxs("div",{className:"custom-provider-form",children:[e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-name",children:s("providers.nameLabel","Provider name")}),e.jsx("input",{id:"custom-provider-name",className:"input",value:h,onChange:K=>f(K.target.value),disabled:W})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-api-type",children:s("providers.apiTypeLabel","API type")}),e.jsxs("select",{id:"custom-provider-api-type",className:"select",value:S,onChange:K=>w(K.target.value),disabled:W,children:[e.jsx("option",{value:"openai-compatible",children:s("providers.apiTypeOpenAi","OpenAI-compatible")}),e.jsx("option",{value:"openai-responses",children:s("providers.apiTypeOpenAiResp","OpenAI Responses")}),e.jsx("option",{value:"anthropic-compatible",children:s("providers.apiTypeAnthropic","Anthropic-compatible")}),e.jsx("option",{value:"google-generative-ai",children:s("providers.apiTypeGoogle","Google Generative AI")})]})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-base-url",children:s("providers.baseUrlLabel","Base URL")}),e.jsx("input",{id:"custom-provider-base-url",className:"input",placeholder:"https://api.example.com/v1",value:I,onChange:K=>x(K.target.value),disabled:W})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-api-key",children:s("providers.apiKeyLabel","API key")}),e.jsx("input",{id:"custom-provider-api-key",type:"password",className:"input",value:v,onChange:K=>B(K.target.value),disabled:W})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-models",children:s("providers.modelsLabel","Available models")}),e.jsx("input",{id:"custom-provider-models",className:"input",placeholder:"e.g., gpt-4, gpt-3.5-turbo",value:k,onChange:K=>Y(K.target.value),disabled:W})]}),e.jsx("div",{style:{display:"flex",gap:"8px",alignItems:"center",marginTop:"4px"},children:e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>void H(),disabled:W||ae||!I.trim(),title:s("providers.detectTitle","Auto-detect models from the provider's /models endpoint"),children:ae?e.jsxs(e.Fragment,{children:[e.jsx(qe,{className:"custom-provider-spin",size:14})," ",s("providers.detecting","Detecting…")]}):e.jsxs(e.Fragment,{children:[e.jsx(Ka,{size:14})," ",s("providers.detectModels","Detect Models")]})})}),_?e.jsx("div",{className:"custom-provider-form-error",children:_}):null,V?e.jsx("div",{className:"custom-provider-form-error",children:V}):null,e.jsxs("div",{className:"custom-provider-form-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:U,disabled:W,children:s("actions.cancel","Cancel")}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:()=>void he(),disabled:W,children:W?s("providers.saving","Saving…"):s("providers.saveProvider","Save Provider")})]})]}):null]});return e.jsx("div",{className:"custom-providers-section",children:a?fe:e.jsx(vl,{summary:"Advanced: Custom Providers",onToggle:re,children:fe})})}function Dc({auth:a}){const{t}=Z("app"),{projectId:s,addToast:c,authProviders:r,authLoading:m,authActionInProgress:i,apiKeyInputs:n,setApiKeyInputs:p,apiKeyErrors:A,opencodeApiKeyRefreshStatus:j,deviceCodes:u,loginInstructions:d,manualCodeConfigs:C,manualCodeInputs:b,setManualCodeInputs:h,manualCodeSubmitInProgress:f,loadAuthStatus:S,handleLogin:w,handleLogout:I,handleCancelLogin:x,handleSaveApiKey:v,handleClearApiKey:B,handleSubmitManualCode:k,onReopenOnboarding:Y}=a,W=r.filter(y=>y.type==="cli"),V=[...r.filter(y=>y.type!=="cli")].sort((y,H)=>y.authenticated!==H.authenticated?y.authenticated?-1:1:y.name.localeCompare(H.name)),ne=V.filter(y=>y.authenticated),ae=V.filter(y=>!y.authenticated),$=W.find(y=>y.id==="claude-cli"),_=W.find(y=>y.id==="cursor-cli"),T=W.find(y=>y.id==="llama-cpp"),D=$?e.jsx(xl,{compact:!0,authenticated:$.authenticated,onToggled:()=>{S()}}):null,re=_?e.jsx(yl,{compact:!0,authenticated:_.authenticated,onToggled:()=>{S()}}):null,U=T?e.jsx(jl,{compact:!0,authenticated:T.authenticated,onToggled:()=>{S()}}):null,ie=ne.length>0||($?.authenticated??!1)||(_?.authenticated??!1)||(T?.authenticated??!1),ve=ae.length>0||$&&!$.authenticated||_&&!_.authenticated||T&&!T.authenticated;return e.jsxs(e.Fragment,{children:[e.jsx("h4",{className:"settings-section-heading",children:t("settings.auth.title","Authentication")}),m?e.jsx("div",{className:"settings-empty-state",children:e.jsx(ze,{label:t("settings.auth.loadingStatus","Loading authentication status…")})}):r.length===0?e.jsx("div",{className:"settings-empty-state settings-muted",children:t("settings.auth.noProviders","No providers available")}):e.jsxs("div",{className:"auth-panel-body",children:[e.jsx(qs,{slotId:"settings-provider-card",projectId:s,renderPlaceholder:!1,actions:{refreshAuthProviders:()=>{S()}}}),e.jsx(qs,{slotId:"settings-integration-card",projectId:s,renderPlaceholder:!1,actions:{refreshAuthProviders:()=>{S()}}}),!ie&&e.jsx("div",{className:"auth-section-hint",children:t("settings.auth.signInHint","Sign in to at least one provider to get started with AI models.")}),ie&&e.jsxs("div",{className:"auth-provider-group",children:[e.jsx("div",{className:"auth-group-label",children:t("settings.auth.groupAuthenticated","Authenticated")}),$?.authenticated&&D,_?.authenticated&&re,T?.authenticated&&U,ne.map(y=>e.jsx("div",{className:"auth-provider-card auth-provider-card--authenticated",children:e.jsxs("div",{className:"auth-provider-header",children:[e.jsxs("div",{className:"auth-provider-info",children:[e.jsx("span",{className:"auth-provider-icon-slot","data-testid":`auth-provider-icon-${y.id}`,"aria-hidden":"true",children:e.jsx(bt,{provider:y.id,size:"md"})}),e.jsx("strong",{children:y.name}),e.jsx("span",{"data-testid":`auth-status-${y.id}`,className:`auth-status-badge ${y.authenticated?"authenticated":"not-authenticated"}`,children:t("settings.auth.statusActive","✓ Active")}),y.authenticated&&y.keyHint&&e.jsxs("span",{className:"auth-key-hint",children:[t("settings.authentication.key","Key: "),y.keyHint]})]}),y.type==="api_key"?e.jsxs("div",{className:"auth-apikey-section",children:[e.jsxs("div",{className:"auth-apikey-input-row",children:[e.jsx("input",{type:"password",className:"auth-apikey-input",placeholder:t("settings.authentication.enterAPIKey","Enter API key"),value:n[y.id]??"",onChange:H=>p(he=>({...he,[y.id]:H.target.value})),disabled:i===y.id}),y.authenticated&&!n[y.id]?e.jsx("button",{className:"btn btn-sm",onClick:()=>B(y.id),disabled:i===y.id,children:t("settings.auth.clearKey","Clear")}):e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>v(y.id),disabled:i===y.id,children:t("settings.actions.save","Save")})]}),i===y.id&&e.jsx("small",{className:"auth-apikey-progress",children:t("settings.auth.savingKey","Saving…")}),A[y.id]&&e.jsx("small",{className:"auth-apikey-error",children:A[y.id]}),(y.id==="opencode"||y.id==="opencode-go")&&j[y.id]&&e.jsx("small",{className:j[y.id].tone==="error"?"form-error":"text-muted",children:j[y.id].message})]}):e.jsx("div",{children:i===y.id?e.jsx("button",{className:"btn btn-sm",disabled:!0,children:t("settings.auth.loggingOut","Logging out…")}):y.loginInProgress?e.jsxs("div",{className:"auth-provider-actions-row",children:[e.jsx("button",{className:"btn btn-sm",disabled:!0,children:t("settings.auth.waitingForLogin","Waiting for login…")}),e.jsx("button",{className:"btn btn-sm",onClick:()=>x(y.id),children:t("settings.actions.cancel","Cancel")})]}):e.jsx("button",{className:"btn btn-sm",onClick:()=>I(y.id),children:t("settings.auth.logout","Logout")})})]})},y.id))]}),ve&&e.jsxs("div",{className:"auth-provider-group",children:[e.jsx("div",{className:"auth-group-label",children:t("settings.auth.groupAvailable","Available")}),$&&!$.authenticated&&D,_&&!_.authenticated&&re,T&&!T.authenticated&&U,ae.map(y=>e.jsx("div",{className:"auth-provider-card",children:e.jsxs("div",{className:"auth-provider-header",children:[e.jsxs("div",{className:"auth-provider-info",children:[e.jsx("span",{className:"auth-provider-icon-slot","data-testid":`auth-provider-icon-${y.id}`,"aria-hidden":"true",children:e.jsx(bt,{provider:y.id,size:"md"})}),e.jsx("strong",{children:y.name}),e.jsx("span",{"data-testid":`auth-status-${y.id}`,className:`auth-status-badge ${y.authenticated?"authenticated":"not-authenticated"}`,children:t("settings.auth.statusNotConnected","✗ Not connected")})]}),y.type==="api_key"?e.jsxs("div",{className:"auth-apikey-section",children:[e.jsxs("div",{className:"auth-apikey-input-row",children:[e.jsx("input",{type:"password",className:"auth-apikey-input",placeholder:t("settings.authentication.enterAPIKey","Enter API key"),value:n[y.id]??"",onChange:H=>p(he=>({...he,[y.id]:H.target.value})),disabled:i===y.id}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>v(y.id),disabled:i===y.id,children:t("settings.actions.save","Save")})]}),i===y.id&&e.jsx("small",{className:"auth-apikey-progress",children:t("settings.auth.savingKey","Saving…")}),A[y.id]&&e.jsx("small",{className:"auth-apikey-error",children:A[y.id]}),(y.id==="opencode"||y.id==="opencode-go")&&j[y.id]&&e.jsx("small",{className:j[y.id].tone==="error"?"form-error":"text-muted",children:j[y.id].message})]}):e.jsxs("div",{children:[i===y.id?e.jsx("button",{className:"btn btn-sm",disabled:!0,children:t("settings.auth.waitingForLogin","Waiting for login…")}):y.loginInProgress?e.jsxs("div",{className:"auth-provider-actions-row",children:[e.jsx("button",{className:"btn btn-sm",disabled:!0,children:t("settings.auth.waitingForLogin","Waiting for login…")}),e.jsx("button",{className:"btn btn-sm",onClick:()=>x(y.id),children:t("settings.actions.cancel","Cancel")})]}):e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>w(y.id),children:t("settings.auth.login","Login")}),y.id==="github-copilot"&&u[y.id]&&(y.loginInProgress||i===y.id)&&e.jsxs("div",{className:"auth-device-code-panel","data-testid":`auth-device-code-${y.id}`,children:[e.jsx("strong",{children:t("settings.auth.enterCodeOnGitHub","Enter this code on GitHub")}),e.jsx("div",{className:"auth-device-code-pill",children:u[y.id].userCode}),e.jsxs("div",{className:"auth-provider-actions-row",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>{(async()=>{if(await In(u[y.id].userCode)){c(t("settings.auth.copiedCodeToClipboard","Copied code to clipboard"),"success");return}c(t("settings.auth.failedToCopyCode","Failed to copy code — copy it manually from the box above"),"error")})()},children:t("settings.auth.copyCode","Copy code")}),e.jsx("button",{className:"btn btn-sm",onClick:()=>window.open(En(u[y.id].verificationUri),"_blank"),children:t("settings.auth.openGitHub","Open GitHub")})]})]}),d[y.id]&&(y.loginInProgress||i===y.id)&&e.jsx(kl,{instructions:d[y.id],"data-testid":`auth-login-instructions-${y.id}`}),C[y.id]&&(y.loginInProgress||i===y.id)&&e.jsx(wl,{value:b[y.id]??"",onChange:H=>h(he=>({...he,[y.id]:H})),onSubmit:()=>void k(y.id),prompt:C[y.id].prompt,placeholder:C[y.id].placeholder,helpText:C[y.id].helpText,disabled:f===y.id,submitLabel:f===y.id?"Submitting…":"Submit code","data-testid":`auth-manual-code-${y.id}`})]})]})},y.id))]})]}),e.jsx("small",{className:"auth-hint",children:t("settings.auth.hint","Authentication changes take effect immediately — no need to save.")}),Y&&e.jsxs("div",{className:"form-group",style:{marginTop:"var(--space-md)"},children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:Y,children:t("settings.auth.reopenOnboarding","Reopen onboarding guide")}),e.jsx("small",{className:"settings-muted",children:t("settings.auth.reopenOnboardingHint","Re-run the setup wizard to review or update your AI provider and model configuration.")})]}),e.jsx(Fc,{})]})}function Zs(a){const{t}=Z("app"),{name:s,subname:c,logo:r,learnMoreHref:m,statusKind:i,statusText:n,description:p,tabs:A,children:j,busy:u,canTest:d=!0,toast:C,onTest:b,onSave:h,onSaveAndTest:f,belowForm:S,testId:w}=a,I=i==="ok"?"runtime-card__status runtime-card__status--ok":i==="err"?"runtime-card__status runtime-card__status--err":"runtime-card__status runtime-card__status--neutral";return e.jsxs("div",{className:"runtime-card","data-testid":w,"aria-live":"polite",children:[e.jsxs("header",{className:"runtime-card__header",children:[e.jsx("span",{className:"runtime-card__logo",children:r}),e.jsxs("div",{className:"runtime-card__title",children:[e.jsx("h3",{className:"runtime-card__name",children:s}),c&&e.jsx("small",{className:"runtime-card__cobrand",children:c}),e.jsxs("small",{className:I,children:[i==="loading"&&e.jsx(qe,{size:12,className:"animate-spin"}),n]})]}),e.jsx("a",{className:"runtime-card__learn-more btn btn-sm btn-ghost",href:m,target:"_blank",rel:"noreferrer",children:t("common.learnMore","Learn more →")})]}),e.jsx("p",{className:"runtime-card__description",children:p}),A,e.jsx("div",{className:"runtime-card__form",children:j}),S,e.jsxs("footer",{className:"runtime-card__footer",children:[C&&e.jsx("span",{className:C.kind==="ok"?"runtime-card__toast runtime-card__toast--ok":"runtime-card__toast runtime-card__toast--err",role:"status",children:C.message}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:b,disabled:u!==null||!d,children:u==="testing"?e.jsxs(e.Fragment,{children:[e.jsx(qe,{size:12,className:"animate-spin"})," ",t("common.testing","Testing…")]}):t("common.test","Test")}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:h,disabled:u!==null,children:u==="saving"?t("common.saving","Saving…"):t("common.save","Save")}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:f,disabled:u!==null||!d,children:u==="save-test"?e.jsxs(e.Fragment,{children:[e.jsx(qe,{size:12,className:"animate-spin"})," ",t("common.saving","Saving…")]}):t("common.saveAndTest","Save & Test")})]})]})}const Es="fusion-plugin-hermes-runtime",vn="https://github.com/NousResearch/hermes-agent",Lc=["auto","anthropic","openrouter","gemini","openai-codex","copilot","copilot-acp","huggingface","zai","kimi-coding","minimax","minimax-cn","kilocode","xiaomi","nous"],Re={binaryPath:"",model:"",provider:"auto",maxTurns:12,yolo:!1,cliTimeoutMs:3e5,profile:""};function Oc(a){return{binaryPath:typeof a.binaryPath=="string"?a.binaryPath:Re.binaryPath,model:typeof a.model=="string"?a.model:Re.model,provider:typeof a.provider=="string"?a.provider:Re.provider,maxTurns:typeof a.maxTurns=="number"?a.maxTurns:Re.maxTurns,yolo:typeof a.yolo=="boolean"?a.yolo:Re.yolo,cliTimeoutMs:typeof a.cliTimeoutMs=="number"?a.cliTimeoutMs:Re.cliTimeoutMs,profile:typeof a.profile=="string"?a.profile:Re.profile}}function Bc(){const{t:a}=Z("app"),[t,s]=o.useState(Re),[c,r]=o.useState(null),[m,i]=o.useState([]),[n,p]=o.useState(null),[A,j]=o.useState(null),u=o.useRef(!0);o.useEffect(()=>(u.current=!0,()=>{u.current=!1}),[]),o.useEffect(()=>{p("loading"),Qs(Es).then(x=>{u.current&&s(Oc(x))}).catch(()=>{}).finally(()=>{u.current&&p(null)})},[]),o.useEffect(()=>{Cl(t.binaryPath?{binaryPath:t.binaryPath}:{}).then(x=>{u.current&&i(x)}).catch(()=>{})},[t.binaryPath]);const d=o.useCallback(async()=>{try{const x=await Nl(t.binaryPath?{binaryPath:t.binaryPath}:{});return u.current&&r(x),x}catch(x){return u.current&&j({kind:"err",message:x instanceof Error?x.message:String(x)}),null}},[t.binaryPath]);o.useEffect(()=>{d()},[d]);const C=o.useCallback(()=>({binaryPath:t.binaryPath,model:t.model,provider:t.provider,maxTurns:t.maxTurns,yolo:t.yolo,cliTimeoutMs:t.cliTimeoutMs,profile:t.profile}),[t]),b=o.useCallback(async()=>{p("testing"),j(null);const x=await d();u.current&&(p(null),x?x.binary.available?j({kind:"ok",message:a("hermes.detected","✓ hermes detected{{version}}{{path}}.",{version:x.binary.version?` (${x.binary.version})`:"",path:x.binary.binaryPath?` at ${x.binary.binaryPath}`:""})}):j({kind:"err",message:a("hermes.notFound","✗ {{reason}}",{reason:x.binary.reason??"hermes not found"})}):j({kind:"err",message:a("hermes.testFailed","Test failed — see status above.")}))},[d,a]),h=o.useCallback(async()=>{p("saving"),j(null);try{await et(Es,C()),u.current&&j({kind:"ok",message:a("hermes.settingsSaved","Settings saved.")})}catch(x){u.current&&j({kind:"err",message:x instanceof Error?x.message:String(x)})}finally{u.current&&p(null)}},[C,a]),f=o.useCallback(async()=>{p("save-test"),j(null);try{await et(Es,C());const x=await d();if(!u.current)return;x?x.binary.available?j({kind:"ok",message:a("hermes.savedDetected","Saved · ✓ hermes detected{{version}}.",{version:x.binary.version?` (${x.binary.version})`:""})}):j({kind:"err",message:a("hermes.savedNotFound","Saved · ✗ {{reason}}",{reason:x.binary.reason??"hermes not found"})}):j({kind:"err",message:a("hermes.savedProbeFailed","Saved, but probe failed.")})}catch(x){u.current&&j({kind:"err",message:x instanceof Error?x.message:String(x)})}finally{u.current&&p(null)}},[C,d,a]),S=c?.binary,w=c===null?"loading":S?.available?"ok":"err",I=c===null?a("hermes.probing","Probing local hermes binary…"):S?.available?a("hermes.statusDetected","✓ Detected{{version}}{{path}}",{version:S.version?` ${S.version}`:"",path:S.binaryPath?` · ${S.binaryPath}`:""}):a("hermes.statusNotDetected","✗ {{reason}}",{reason:S?.reason??"not detected on PATH"});return e.jsxs(Zs,{testId:"hermes-runtime-card",logo:e.jsx("span",{style:{width:40,height:40,display:"inline-flex",alignItems:"center",justifyContent:"center",borderRadius:"50%",background:"#fff"},children:e.jsx("img",{src:"/brands/hermes-logo.svg",alt:a("runtimes.nousResearchLogoAlt","Nous Research"),style:{width:28,height:28,display:"block",filter:"invert(1) brightness(0)"}})}),name:"Hermes",subname:a("hermes.subname","by Nous Research"),learnMoreHref:vn,statusKind:w,statusText:I,description:e.jsx(e.Fragment,{children:a("hermes.description","Drives the local {{cmd}} CLI as a subprocess. Each Fusion prompt is sent as {{chatCmd}}; subsequent prompts resume the same hermes session via {{resumeFlag}}. Provider, model, and skills are configured inside hermes itself; this card only chooses overrides.",{cmd:"hermes",chatCmd:"hermes chat -q …",resumeFlag:"--resume"})}),busy:n,toast:A,onTest:()=>void b(),onSave:()=>void h(),onSaveAndTest:()=>void f(),belowForm:S?.available===!1?e.jsxs("div",{className:"onboarding-helper-text",children:[e.jsx("p",{children:a("hermes.notDetected","{{cmd}} not detected. Install the upstream agent:",{cmd:"hermes"})}),e.jsx("pre",{children:e.jsx("code",{children:"pipx install hermes-agent"})}),e.jsx("p",{children:e.jsx("a",{href:vn,target:"_blank",rel:"noreferrer",children:a("hermes.gitHubLink","Hermes on GitHub")})})]}):null,children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-profile",children:a("hermes.profileLabel","Profile (optional)")}),e.jsxs("select",{id:"hermes-profile",value:t.profile,onChange:x=>s(v=>({...v,profile:x.target.value})),children:[e.jsx("option",{value:"",children:a("hermes.autoProfile","Auto / use Hermes default")}),m.map(x=>e.jsxs("option",{value:x.name,children:[x.name,x.model?a("hermes.profileModelSeparator"," — {{model}}",{model:x.model}):"",x.isDefault?a("hermes.defaultProfile"," (default)"):""]},x.name))]}),e.jsx("small",{children:a("hermes.profileHelp","Select a Hermes profile to use. Activates the profile by setting {{env}} to the profile directory when invoking {{cmd}}.",{env:"HERMES_HOME",cmd:"hermes chat"})})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-binary",children:a("hermes.binaryPathLabel","Binary path")}),e.jsx("input",{id:"hermes-binary",type:"text",placeholder:a("hermes.binaryPathPlaceholder","hermes (defaults to PATH)"),value:t.binaryPath,onChange:x=>s(v=>({...v,binaryPath:x.target.value}))}),e.jsx("small",{children:a("hermes.binaryPathHelp","Leave blank to resolve {{cmd}} from your PATH.",{cmd:"hermes"})})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-model",children:a("hermes.modelLabel","Model override")}),e.jsx("input",{id:"hermes-model",type:"text",placeholder:a("hermes.modelPlaceholder","e.g. claude-sonnet-4-5, MiniMax-M3"),value:t.model,disabled:!!t.profile,onChange:x=>s(v=>({...v,model:x.target.value}))}),t.profile?e.jsx("small",{children:a("hermes.modelControlled","Controlled by profile: {{profile}}",{profile:t.profile})}):e.jsx("small",{children:a("hermes.modelHelp","Optional — overrides Hermes's configured default model.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-provider",children:a("hermes.providerLabel","Provider")}),e.jsx("select",{id:"hermes-provider",value:t.provider,disabled:!!t.profile,onChange:x=>s(v=>({...v,provider:x.target.value})),children:Lc.map(x=>e.jsx("option",{value:x,children:x},x))}),t.profile?e.jsx("small",{children:a("hermes.providerControlled","Controlled by profile: {{profile}}",{profile:t.profile})}):e.jsx("small",{children:a("hermes.providerHelp","Inference provider Hermes routes calls through (default: {{default}}).",{default:"auto"})})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-maxTurns",children:a("hermes.maxTurnsLabel","Max turns")}),e.jsx("input",{id:"hermes-maxTurns",type:"number",min:1,max:500,value:t.maxTurns,onChange:x=>s(v=>({...v,maxTurns:Number(x.target.value)||Re.maxTurns}))}),e.jsx("small",{children:a("hermes.maxTurnsHelp","Cap per Hermes turn. Hermes's own default is 90; we cap lower.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"hermes-yolo",style:{display:"inline-flex",alignItems:"center",gap:"var(--space-xs)"},children:[e.jsx("input",{id:"hermes-yolo",type:"checkbox",checked:t.yolo,onChange:x=>s(v=>({...v,yolo:x.target.checked}))}),a("hermes.yoloLabel","Auto-approve dangerous tool calls ({{flag}})",{flag:"--yolo"})]}),e.jsx("small",{children:a("hermes.yoloHelp","Required for non-interactive sessions that trigger shell-style tools.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-timeoutMs",children:a("hermes.timeoutLabel","CLI hard-kill timeout (ms)")}),e.jsx("input",{id:"hermes-timeoutMs",type:"number",min:1e3,step:1e3,value:t.cliTimeoutMs,onChange:x=>s(v=>({...v,cliTimeoutMs:Number(x.target.value)||Re.cliTimeoutMs}))}),e.jsx("small",{children:a("hermes.timeoutHelp","Fusion-side hard cap. Default 5 min.")})]})]})}const Fs="fusion-plugin-openclaw-runtime",Gc="https://docs.openclaw.ai/",_c="https://github.com/openclaw/openclaw",Gn=["off","minimal","low","medium","high","xhigh","adaptive","max"],Ie={binaryPath:"",agentId:"main",model:"",thinking:"off",useGateway:!1,cliTimeoutSec:0,cliTimeoutMs:3e5};function Wc(a){return{binaryPath:typeof a.binaryPath=="string"?a.binaryPath:Ie.binaryPath,agentId:typeof a.agentId=="string"?a.agentId:Ie.agentId,model:typeof a.model=="string"?a.model:Ie.model,thinking:Gn.includes(a.thinking)?a.thinking:Ie.thinking,useGateway:typeof a.useGateway=="boolean"?a.useGateway:Ie.useGateway,cliTimeoutSec:typeof a.cliTimeoutSec=="number"?a.cliTimeoutSec:Ie.cliTimeoutSec,cliTimeoutMs:typeof a.cliTimeoutMs=="number"?a.cliTimeoutMs:Ie.cliTimeoutMs}}function $c(){const{t:a}=Z("app"),[t,s]=o.useState(Ie),[c,r]=o.useState(null),[m,i]=o.useState(null),[n,p]=o.useState(null),A=o.useRef(!0);o.useEffect(()=>(A.current=!0,()=>{A.current=!1}),[]),o.useEffect(()=>{i("loading"),Qs(Fs).then(w=>{A.current&&s(Wc(w))}).catch(()=>{}).finally(()=>{A.current&&i(null)})},[]);const j=o.useCallback(async()=>{try{const w=await Sl(t.binaryPath?{binaryPath:t.binaryPath}:void 0);return A.current&&r(w),w}catch(w){return A.current&&p({kind:"err",message:w instanceof Error?w.message:String(w)}),null}},[t.binaryPath]);o.useEffect(()=>{j()},[j]);const u=o.useCallback(()=>({binaryPath:t.binaryPath,agentId:t.agentId,model:t.model,thinking:t.thinking,useGateway:t.useGateway,cliTimeoutSec:t.cliTimeoutSec,cliTimeoutMs:t.cliTimeoutMs}),[t]),d=o.useCallback(async()=>{i("testing"),p(null);const w=await j();A.current&&(i(null),w?w.binary.available?p({kind:"ok",message:a("openclaw.detected","✓ openclaw detected{{version}}{{path}}.",{version:w.binary.version?` (${w.binary.version})`:"",path:w.binary.binaryPath?` at ${w.binary.binaryPath}`:""})}):p({kind:"err",message:a("openclaw.notFound",`✗ ${w.binary.reason??"openclaw not found"}`)}):p({kind:"err",message:a("openclaw.testFailed","Test failed — see status above.")}))},[j,a]),C=o.useCallback(async()=>{i("saving"),p(null);try{await et(Fs,u()),A.current&&p({kind:"ok",message:a("openclaw.saved","Settings saved.")})}catch(w){A.current&&p({kind:"err",message:w instanceof Error?w.message:String(w)})}finally{A.current&&i(null)}},[u,a]),b=o.useCallback(async()=>{i("save-test"),p(null);try{await et(Fs,u());const w=await j();if(!A.current)return;w?w.binary.available?p({kind:"ok",message:a("openclaw.savedDetected","Saved · ✓ openclaw detected{{version}}{{path}}.",{version:w.binary.version?` (${w.binary.version})`:"",path:w.binary.binaryPath?` at ${w.binary.binaryPath}`:""})}):p({kind:"err",message:a("openclaw.savedNotFound",`Saved · ✗ ${w.binary.reason??"openclaw not found"}`)}):p({kind:"err",message:a("openclaw.savedProbeFailed","Saved, but probe failed.")})}catch(w){A.current&&p({kind:"err",message:w instanceof Error?w.message:String(w)})}finally{A.current&&i(null)}},[u,j,a]),h=c?.binary,f=c===null?"loading":h?.available?"ok":"err",S=c===null?a("openclaw.probing","Probing local openclaw binary…"):h?.available?a("openclaw.statusDetected","✓ Detected{{version}}{{path}}",{version:h.version?` ${h.version}`:"",path:h.binaryPath?` · ${h.binaryPath}`:""}):a("openclaw.statusNotFound",`✗ ${h?.reason??"not detected on PATH"}`);return e.jsxs(Zs,{testId:"openclaw-runtime-card",logo:e.jsx(bt,{provider:"openclaw",size:"lg"}),name:"OpenClaw",learnMoreHref:Gc,statusKind:f,statusText:S,description:e.jsx(zs,{i18nKey:"app:openclaw.description",defaults:"Drives the local <code1>openclaw</code1> CLI as a subprocess. Each Fusion prompt is dispatched via <code2>openclaw agent --local --json</code2>; the agent definition, model, and thinking level are resolved by OpenClaw. This card only sets overrides and the binary path.",components:{code1:e.jsx("code",{}),code2:e.jsx("code",{})}}),busy:m,toast:n,onTest:()=>void d(),onSave:()=>void C(),onSaveAndTest:()=>void b(),belowForm:h?.available===!1?e.jsxs("div",{className:"onboarding-helper-text",children:[e.jsx("p",{children:e.jsx(zs,{i18nKey:"app:openclaw.notDetectedInstall",defaults:"<code>openclaw</code> not detected. Install the upstream agent:",components:{code:e.jsx("code",{})}})}),e.jsx("pre",{children:e.jsx("code",{children:"npm install -g openclaw"})}),e.jsx("p",{children:e.jsx("a",{href:_c,target:"_blank",rel:"noreferrer",children:a("openclaw.githubLink","openclaw on GitHub")})})]}):null,children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-binaryPath",children:a("openclaw.binaryPath","Binary path")}),e.jsx("input",{id:"openclaw-binaryPath",type:"text",placeholder:a("openclaw.binaryPathPlaceholder","openclaw (defaults to PATH)"),value:t.binaryPath,onChange:w=>s(I=>({...I,binaryPath:w.target.value}))}),e.jsx("small",{children:a("openclaw.binaryPathHint","Leave blank to resolve openclaw from your PATH.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-agentId",children:a("openclaw.agentId","Agent ID")}),e.jsx("input",{id:"openclaw-agentId",type:"text",placeholder:a("openclaw.agentIdPlaceholder","main"),value:t.agentId,onChange:w=>s(I=>({...I,agentId:w.target.value}))}),e.jsx("small",{children:a("openclaw.agentIdHint","OpenClaw agent definition to run (default: main).")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-model",children:a("openclaw.model","Model override")}),e.jsx("input",{id:"openclaw-model",type:"text",placeholder:a("openclaw.modelPlaceholder","e.g. anthropic/claude-haiku-4-5, minimax/MiniMax-M3"),value:t.model,onChange:w=>s(I=>({...I,model:w.target.value}))}),e.jsx("small",{children:a("openclaw.modelHint","Optional — overrides the OpenClaw default model.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-thinking",children:a("openclaw.thinking","Thinking level")}),e.jsx("select",{id:"openclaw-thinking",value:t.thinking,onChange:w=>s(I=>({...I,thinking:w.target.value})),children:Gn.map(w=>e.jsx("option",{value:w,children:w},w))}),e.jsx("small",{children:a("openclaw.thinkingHint","Controls how much extended thinking the model uses.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"openclaw-useGateway",style:{display:"inline-flex",alignItems:"center",gap:"var(--space-xs)"},children:[e.jsx("input",{id:"openclaw-useGateway",type:"checkbox",checked:t.useGateway,onChange:w=>s(I=>({...I,useGateway:w.target.checked}))}),a("openclaw.gateway","Route through OpenClaw gateway (otherwise embedded)")]}),e.jsx("small",{children:a("openclaw.gatewayHint","When enabled, calls pass through the OpenClaw gateway service.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-cliTimeoutSec",children:a("openclaw.cliTimeout","OpenClaw timeout (sec)")}),e.jsx("input",{id:"openclaw-cliTimeoutSec",type:"number",min:0,step:1,value:t.cliTimeoutSec,onChange:w=>s(I=>({...I,cliTimeoutSec:parseInt(w.target.value,10)||0}))}),e.jsx("small",{children:a("openclaw.cliTimeoutHint","OpenClaw-side run timeout in seconds (0 = no timeout).")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-cliTimeoutMs",children:a("openclaw.subprocess","CLI subprocess timeout (ms)")}),e.jsx("input",{id:"openclaw-cliTimeoutMs",type:"number",min:0,step:1e3,value:t.cliTimeoutMs,onChange:w=>s(I=>({...I,cliTimeoutMs:parseInt(w.target.value,10)||Ie.cliTimeoutMs}))}),e.jsx("small",{children:a("openclaw.subprocessHint","Fusion-side hard cap before the CLI subprocess is killed (default: {{default}}s).",{default:Ie.cliTimeoutMs/1e3})})]})]})}const Ds="fusion-plugin-paperclip-runtime",xn="https://paperclip.ing/",Uc="https://github.com/paperclipai/paperclip",yn=[{value:"rolling-issue",label:"Rolling issue (default)",help:"One Paperclip issue per Fusion session; subsequent prompts are added as comments. Closest to a chat experience."},{value:"issue-per-prompt",label:"Issue per prompt",help:"Each prompt creates a new top-level Paperclip issue. Maximally explicit; tends to clutter the board."},{value:"wakeup-only",label:"Wakeup only (advanced)",help:"No issue side-effects; the prompt is delivered via the wakeup payload only. Requires the agent's prompt template to know how to handle a payload-driven wake."}],ke={transport:"api",apiUrl:"http://localhost:3100",apiKey:"",cliBinaryPath:"paperclipai",cliConfigPath:"",agentId:"",companyId:"",mode:"rolling-issue",parentIssueId:"",projectId:"",goalId:"",runTimeoutMs:6e5},Hc=new Set(["issue-per-prompt","rolling-issue","wakeup-only"]);function Kc(a){const t=(m,i)=>typeof a[m]=="string"?a[m]:i,s=(m,i)=>typeof a[m]=="number"?a[m]:i,c=a.transport==="cli"?"cli":"api",r=Hc.has(a.mode)?a.mode:ke.mode;return{transport:c,apiUrl:t("apiUrl",ke.apiUrl),apiKey:t("apiKey",ke.apiKey),cliBinaryPath:t("cliBinaryPath",ke.cliBinaryPath),cliConfigPath:t("cliConfigPath",ke.cliConfigPath),agentId:t("agentId",ke.agentId),companyId:t("companyId",ke.companyId),mode:r,parentIssueId:t("parentIssueId",ke.parentIssueId),projectId:t("projectId",ke.projectId),goalId:t("goalId",ke.goalId),runTimeoutMs:s("runTimeoutMs",ke.runTimeoutMs)}}function qc(){const{t:a}=Z("app"),[t,s]=o.useState(ke),[c,r]=o.useState(null),[m,i]=o.useState(null),[n,p]=o.useState([]),[A,j]=o.useState([]),[u,d]=o.useState(null),[C,b]=o.useState(null),[h,f]=o.useState(!1),S=o.useRef(!0);o.useEffect(()=>(S.current=!0,()=>{S.current=!1}),[]);const w=o.useMemo(()=>t.transport==="cli"&&m&&m.ok?{apiUrl:m.apiUrl,apiKey:t.apiKey||m.apiKey||void 0}:{apiUrl:t.apiUrl,apiKey:t.apiKey||void 0},[t.transport,t.apiUrl,t.apiKey,m]);o.useEffect(()=>{d("loading"),Qs(Ds).then(T=>{S.current&&s(Kc(T))}).catch(()=>{}).finally(()=>{S.current&&d(null)})},[]),o.useEffect(()=>{if(t.transport!=="cli"){i(null);return}let T=!1;return Pl({cliConfigPath:t.cliConfigPath||void 0}).then(D=>{!T&&S.current&&i(D)}).catch(()=>{!T&&S.current&&i({ok:!1,reason:"Discovery request failed"})}),()=>{T=!0}},[t.transport,t.cliConfigPath]);const I=t.transport==="cli",x=o.useMemo(()=>({cliBinaryPath:t.cliBinaryPath||void 0,cliConfigPath:t.cliConfigPath||void 0}),[t.cliBinaryPath,t.cliConfigPath]),v=o.useCallback(async()=>{if(!I&&!w.apiUrl)return null;try{const T=I?await Al(x):await Ml(w);S.current&&r(T);const D=I?await Tl(x):await Rl(w);if(!S.current)return T;p(D);let re=t.companyId;if(D.some(U=>U.id===re)||(re=T.connection.identity?.companyId??D[0]?.id??"",re&&re!==t.companyId&&s(U=>({...U,companyId:re}))),re){const U=I?await qa({...x,companyId:re}):await za({...w,companyId:re});if(S.current&&(j(U),!U.some(ie=>ie.id===t.agentId))){const ie=T.connection.identity?.agentId??U[0]?.id??"";ie&&ie!==t.agentId&&s(ve=>({...ve,agentId:ie}))}}else S.current&&j([]);return T}catch(T){return S.current&&b({kind:"err",message:T instanceof Error?T.message:String(T)}),null}},[I,x,w.apiUrl,w.apiKey,t.companyId,t.agentId]);o.useEffect(()=>{v()},[v]),o.useEffect(()=>{if(!t.companyId){j([]);return}if(!I&&!w.apiUrl){j([]);return}let T=!1;return(I?qa({...x,companyId:t.companyId}):za({...w,companyId:t.companyId})).then(re=>{!T&&S.current&&j(re)}).catch(()=>{!T&&S.current&&j([])}),()=>{T=!0}},[I,x,w.apiUrl,w.apiKey,t.companyId]);const B=o.useCallback(()=>{const T={transport:t.transport,mode:t.mode,parentIssueId:t.parentIssueId,projectId:t.projectId,goalId:t.goalId,runTimeoutMs:t.runTimeoutMs,agentId:t.agentId,companyId:t.companyId};return t.transport==="api"?T.apiUrl=t.apiUrl:(T.cliBinaryPath=t.cliBinaryPath,t.cliConfigPath&&(T.cliConfigPath=t.cliConfigPath)),h&&(T.apiKey=t.apiKey),T},[t,h]),k=o.useCallback(async()=>{d("testing"),b(null);const T=await v();if(S.current)if(d(null),!T)t.transport==="cli"&&m&&!m.ok?b({kind:"err",message:a("paperclip.cliDiscoveryFailed","✗ CLI discovery failed: {{reason}}",{reason:m.reason})}):b({kind:"err",message:a("paperclip.testFailed","Test failed — see status above.")});else if(T.connection.available){const D=T.connection.identity;b({kind:"ok",message:D?a("paperclip.connectedAsAgent","✓ Connected as {{agentName}}{{companyInfo}}.",{agentName:D.agentName,companyInfo:D.companyName?` at ${D.companyName}`:""}):a("paperclip.connected","✓ Connected.")})}else b({kind:"err",message:a("paperclip.unreachable","✗ {{reason}}",{reason:T.connection.reason??"Paperclip server unreachable"})})},[v,t.transport,m,a]),Y=o.useCallback(async()=>{d("saving"),b(null);try{await et(Ds,B()),S.current&&(b({kind:"ok",message:a("paperclip.settingsSaved","Settings saved.")}),f(!1))}catch(T){S.current&&b({kind:"err",message:T instanceof Error?T.message:String(T)})}finally{S.current&&d(null)}},[B,a]),W=o.useCallback(async()=>{d("save-test"),b(null);try{await et(Ds,B()),S.current&&f(!1);const T=await v();if(!S.current)return;if(!T)t.transport==="cli"&&m&&!m.ok?b({kind:"err",message:a("paperclip.savedCliDiscoveryFailed","Saved · ✗ CLI discovery failed: {{reason}}",{reason:m.reason})}):b({kind:"err",message:a("paperclip.savedProbeFailed","Saved, but probe failed.")});else if(T.connection.available){const D=T.connection.identity;b({kind:"ok",message:D?a("paperclip.savedConnectedAsAgent","Saved · ✓ Connected as {{agentName}}{{companyInfo}}.",{agentName:D.agentName,companyInfo:D.companyName?` at ${D.companyName}`:""}):a("paperclip.savedConnected","Saved · ✓ Connected.")})}else b({kind:"err",message:a("paperclip.savedUnreachable","Saved · ✗ {{reason}}",{reason:T.connection.reason??"Paperclip server unreachable"})})}catch(T){S.current&&b({kind:"err",message:T instanceof Error?T.message:String(T)})}finally{S.current&&d(null)}},[B,v,t.transport,m,a]),J=c?.connection.available??null,V=c?.connection.identity,ne=m?.ok===!0,ae=c===null?"loading":J?"ok":"err",$=c===null?t.transport==="cli"&&m&&!ne?a("paperclip.statusCliDiscoveryFailed","✗ CLI discovery failed: {{reason}}",{reason:m.reason}):a("paperclip.statusProbing","Probing Paperclip server…"):J?V?a("paperclip.statusConnectedAs","✓ Connected as {{agentName}}{{roleInfo}}{{companyInfo}}",{agentName:V.agentName,roleInfo:V.role?` (${V.role})`:"",companyInfo:V.companyName?` at ${V.companyName}`:""}):a("paperclip.statusConnected","✓ Connected"):a("paperclip.statusUnreachable","✗ {{reason}}",{reason:c.connection.reason??"Unreachable"}),_=e.jsxs("div",{className:"runtime-card__tabs",role:"tablist","aria-label":a("paperclip.connectionModeAriaLabel","Paperclip connection mode"),children:[e.jsx("button",{type:"button",role:"tab","aria-selected":t.transport==="api",className:"runtime-card__tab",onClick:()=>s(T=>({...T,transport:"api"})),children:a("paperclip.tabApi","API (URL + token)")}),e.jsx("button",{type:"button",role:"tab","aria-selected":t.transport==="cli",className:"runtime-card__tab",onClick:()=>s(T=>({...T,transport:"cli"})),children:a("paperclip.tabCliAutoDerve","Local CLI (auto-derive)")})]});return e.jsxs(Zs,{testId:"paperclip-runtime-card",logo:e.jsx(bt,{provider:"paperclip",size:"lg"}),name:a("paperclip.name","Paperclip"),learnMoreHref:xn,statusKind:ae,statusText:$,description:e.jsx(e.Fragment,{children:a("paperclip.description",'Drive a Paperclip agent ("employee") in a Paperclip company. Each prompt dispatches a task-shaped request; governance, budgets, and approvals are enforced by Paperclip. Expect seconds-to-minutes latency per turn.')}),tabs:_,busy:u,toast:C,onTest:()=>void k(),onSave:()=>void Y(),onSaveAndTest:()=>void W(),belowForm:J===!1?e.jsxs("div",{className:"onboarding-helper-text",children:[e.jsx("p",{children:a("paperclip.onboardingStep1","Make sure a Paperclip server is running. To install Paperclip:")}),e.jsx("pre",{children:e.jsx("code",{children:"npm install -g paperclipai"})}),e.jsxs("p",{children:[e.jsx("a",{href:xn,target:"_blank",rel:"noreferrer",children:a("paperclip.docsLink","Paperclip docs")})," ","·"," ",e.jsx("a",{href:Uc,target:"_blank",rel:"noreferrer",children:a("paperclip.githubLink","GitHub")})]})]}):null,children:[t.transport==="cli"&&m&&e.jsx("div",{className:"settings-muted",style:{marginBottom:"var(--space-sm)"},children:ne?e.jsxs("small",{children:[a("paperclip.cliConfigLabel","CLI config:")," ",e.jsx("code",{children:m.configPath})," ","· ",a("paperclip.resolved","resolved")," ",e.jsx("code",{children:m.apiUrl}),m.deploymentMode?` · ${m.deploymentMode}`:""]}):e.jsx("small",{children:a("paperclip.cliDiscoveryFailedLabel","CLI discovery failed: {{reason}}",{reason:m.reason})})}),t.transport==="api"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-apiUrl",children:a("paperclip.apiUrlLabel","API URL")}),e.jsx("input",{id:"paperclip-apiUrl",type:"text",placeholder:"http://localhost:3100",value:t.apiUrl,onChange:T=>s(D=>({...D,apiUrl:T.target.value}))}),e.jsx("small",{children:a("paperclip.apiUrlHelp","Base URL of the Paperclip server.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-apiKey",children:a("paperclip.apiKeyLabel","API key")}),e.jsx("input",{id:"paperclip-apiKey",type:"password",placeholder:h?"":a("paperclip.apiKeyPlaceholder","•••••••• (leave blank to keep existing)"),value:t.apiKey,onChange:T=>{s(D=>({...D,apiKey:T.target.value})),f(!0)}}),e.jsx("small",{children:a("paperclip.apiKeyHelp","Agent API key. Local-trusted deployments may leave this blank.")})]})]}),t.transport==="cli"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-cliBinaryPath",children:a("paperclip.cliBinaryLabel","paperclipai binary")}),e.jsx("input",{id:"paperclip-cliBinaryPath",type:"text",placeholder:"paperclipai",value:t.cliBinaryPath,onChange:T=>s(D=>({...D,cliBinaryPath:T.target.value}))}),e.jsx("small",{children:a("paperclip.cliBinaryHelp","Optional — informational; the adapter currently reads the instance config file directly.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-cliConfigPath",children:a("paperclip.cliConfigPathLabel","Instance config path")}),e.jsx("input",{id:"paperclip-cliConfigPath",type:"text",placeholder:"~/.paperclip/instances/default/config.json",value:t.cliConfigPath,onChange:T=>s(D=>({...D,cliConfigPath:T.target.value}))}),e.jsx("small",{children:a("paperclip.cliConfigPathHelp","Override the path to config.json. Leave blank for the default.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-cli-apikey",children:a("paperclip.cliApiKeyLabel","API key (override, optional)")}),e.jsx("input",{id:"paperclip-cli-apikey",type:"password",placeholder:h?"":a("paperclip.cliApiKeyPlaceholder","Optional — only required for non-local-trusted modes"),value:t.apiKey,onChange:T=>{s(D=>({...D,apiKey:T.target.value})),f(!0)}}),e.jsx("small",{children:a("paperclip.cliApiKeyHelp","Local-trusted deployments do not require a key.")}),c!==null&&J===!1&&t.agentId&&e.jsx("button",{type:"button",className:"btn btn--sm",style:{marginTop:"0.4rem"},disabled:u!==null,onClick:async()=>{const T=t.agentId,D=t.companyId.trim();if(!T||!D){b({kind:"err",message:a("paperclip.companyIdRequired","✗ Company ID is required to mint a Paperclip API key.")});return}d("testing"),b(null);const re=await Il({cliBinaryPath:t.cliBinaryPath||void 0,agentRef:T,companyId:D,keyName:"fusion-runtime",configPath:t.cliConfigPath||void 0});S.current&&(d(null),re.ok?(s(U=>({...U,apiKey:re.key.apiKey})),f(!0),b({kind:"ok",message:a("paperclip.apiKeyMinted","✓ API key minted via paperclipai (key 'fusion-runtime' installed for agent {{agentId}}). Click Save to persist.",{agentId:T})}),v()):b({kind:"err",message:a("paperclip.mintFailed","✗ Mint failed: {{reason}}. Run `paperclipai onboard` first if your CLI isn't authenticated.",{reason:re.reason})}))},children:a("paperclip.mintButton","✨ Mint API key via paperclipai")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-companyId",children:a("paperclip.companyLabel","Company")}),e.jsx("select",{id:"paperclip-companyId",value:t.companyId,onChange:T=>s(D=>({...D,companyId:T.target.value})),disabled:n.length===0,children:n.length===0?e.jsx("option",{value:"",children:J?a("paperclip.noCompaniesDiscovered","No companies discovered"):a("paperclip.connectToPopulate","Connect to populate")}):n.map(T=>e.jsxs("option",{value:T.id,children:[T.name," (",T.id,")"]},T.id))}),e.jsx("small",{children:a("paperclip.companyHelp","Select a Paperclip company.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-agentId",children:a("paperclip.agentLabel","Agent")}),e.jsx("select",{id:"paperclip-agentId",value:t.agentId,onChange:T=>s(D=>({...D,agentId:T.target.value})),disabled:A.length===0,children:A.length===0?e.jsx("option",{value:"",children:t.companyId?a("paperclip.noAgentsDiscovered","No agents discovered"):a("paperclip.pickCompanyFirst","Pick a company first")}):A.map(T=>e.jsxs("option",{value:T.id,children:[T.name,T.role?` (${T.role})`:""]},T.id))}),e.jsx("small",{children:a("paperclip.agentHelp","Pick the Paperclip agent this Fusion runtime will proxy.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-mode",children:a("paperclip.modeLabel","Conversation mode")}),e.jsx("select",{id:"paperclip-mode",value:t.mode,onChange:T=>s(D=>({...D,mode:T.target.value})),children:yn.map(T=>e.jsx("option",{value:T.value,children:a(`paperclip.mode.${T.value}`,T.label)},T.value))}),e.jsx("small",{children:a(`paperclip.modeHelp.${t.mode}`,yn.find(T=>T.value===t.mode)?.help??"")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-projectId",children:a("paperclip.projectIdLabel","Project ID (optional)")}),e.jsx("input",{id:"paperclip-projectId",type:"text",placeholder:a("paperclip.optionalPlaceholder","Optional"),value:t.projectId,onChange:T=>s(D=>({...D,projectId:T.target.value}))}),e.jsx("small",{children:a("paperclip.projectIdHelp","Pin work to a specific Paperclip project.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-parentIssueId",children:a("paperclip.parentIssueIdLabel","Parent issue ID (optional)")}),e.jsx("input",{id:"paperclip-parentIssueId",type:"text",placeholder:a("paperclip.optionalPlaceholder","Optional"),value:t.parentIssueId,onChange:T=>s(D=>({...D,parentIssueId:T.target.value}))}),e.jsx("small",{children:a("paperclip.parentIssueIdHelp","Scope work under an existing parent issue.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-goalId",children:a("paperclip.goalIdLabel","Goal ID (optional)")}),e.jsx("input",{id:"paperclip-goalId",type:"text",placeholder:a("paperclip.optionalPlaceholder","Optional"),value:t.goalId,onChange:T=>s(D=>({...D,goalId:T.target.value}))}),e.jsx("small",{children:a("paperclip.goalIdHelp","Associate work with a Paperclip goal.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-runTimeoutMs",children:a("paperclip.runTimeoutLabel","Run timeout (ms)")}),e.jsx("input",{id:"paperclip-runTimeoutMs",type:"number",min:0,step:1e3,value:t.runTimeoutMs,onChange:T=>s(D=>({...D,runTimeoutMs:parseInt(T.target.value,10)||ke.runTimeoutMs}))}),e.jsx("small",{children:a("paperclip.runTimeoutHelp","Local cap before Fusion gives up on a Paperclip run.")})]})]})}function zc(){const{t:a}=Z("app");return e.jsxs(e.Fragment,{children:[e.jsx("h4",{className:"settings-section-heading",children:a("settings.runtimesRuntimes.hermesRuntime","Hermes Runtime")}),e.jsx(Bc,{})]})}function Vc(){const{t:a}=Z("app");return e.jsxs(e.Fragment,{children:[e.jsx("h4",{className:"settings-section-heading",children:a("settings.runtimesRuntimes.openClawRuntime","OpenClaw Runtime")}),e.jsx($c,{})]})}function Yc(){const{t:a}=Z("app");return e.jsxs(e.Fragment,{children:[e.jsx("h4",{className:"settings-section-heading",children:a("settings.runtimesRuntimes.paperclipRuntime","Paperclip Runtime")}),e.jsx(qc,{})]})}function Qc({scopeBanner:a,addToast:t}){const{t:s}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:s("settings.nav.secrets","Secrets")}),e.jsx(Wo,{addToast:t})]})}const Xe=[{id:"default-executor",name:"Default Executor",description:"Standard task execution agent with full tooling and review support.",role:"executor",prompt:`You are a task execution agent for "fn", an AI-orchestrated task board.
8
-
9
- You are working in a git worktree isolated from the main branch. Your job is to implement the task described in the PROMPT.md specification you're given.`,builtIn:!0},{id:"default-triage",name:"Default Triage",description:"Standard task specification agent producing detailed PROMPT.md files.",role:"triage",prompt:`You are a task specification agent for "fn", an AI-orchestrated task board.
10
-
11
- Your job: take a rough task description and produce a fully specified PROMPT.md that another AI agent can execute autonomously.`,builtIn:!0},{id:"default-reviewer",name:"Default Reviewer",description:"Standard independent code and plan reviewer with balanced criteria.",role:"reviewer",prompt:`You are an independent code and plan reviewer.
12
-
13
- You provide quality assessment for task implementations with full read access to the codebase.`,builtIn:!0},{id:"default-merger",name:"Default Merger",description:"Standard merge agent for squash merges with conflict resolution.",role:"merger",prompt:`You are a merge agent for "fn", an AI-orchestrated task board.
14
-
15
- Your job is to finalize a squash merge: resolve any conflicts and write a good commit message.`,builtIn:!0},{id:"senior-engineer",name:"Senior Engineer",description:"Autonomous executor with architectural awareness, performance focus, and minimal hand-holding.",role:"executor",prompt:`You are a senior engineering agent for "fn", an AI-orchestrated task board.
16
-
17
- You operate with a high degree of autonomy, making architectural decisions and balancing trade-offs independently.`,builtIn:!0},{id:"strict-reviewer",name:"Strict Reviewer",description:"Rigorous reviewer with stricter criteria for security, edge cases, and type safety.",role:"reviewer",prompt:`You are a strict code and plan reviewer with rigorous standards.
18
-
19
- You hold all submissions to a high bar for correctness, security, and maintainability.`,builtIn:!0},{id:"concise-triage",name:"Concise Triage",description:"Shorter, more focused specification format with minimal prose.",role:"triage",prompt:`You are a task specification agent for "fn". Produce a concise, actionable PROMPT.md from the given task description.
20
-
21
- Be brief and precise — avoid verbosity.`,builtIn:!0}],Jc={"executor-welcome":{key:"executor-welcome",name:"Executor Welcome",roles:["executor"],description:"Introductory section for the executor agent",defaultContent:"You are a task execution agent..."},"executor-guardrails":{key:"executor-guardrails",name:"Executor Guardrails",roles:["executor"],description:"Behavioral guardrails and constraints for the executor",defaultContent:"Treat the File Scope in PROMPT.md..."},"executor-spawning":{key:"executor-spawning",name:"Executor Spawning",roles:["executor"],description:"Instructions for spawning child agents",defaultContent:"You can spawn child agents..."},"executor-completion":{key:"executor-completion",name:"Executor Completion",roles:["executor"],description:"Completion criteria and signaling for executor",defaultContent:"After all steps are done..."},"triage-welcome":{key:"triage-welcome",name:"Triage Welcome",roles:["triage"],description:"Introductory section for the triage/specification agent",defaultContent:"You are a task specification agent..."},"triage-context":{key:"triage-context",name:"Triage Context",roles:["triage"],description:"Context-gathering instructions for triage",defaultContent:"What you receive: A raw task title..."},"reviewer-verdict":{key:"reviewer-verdict",name:"Reviewer Verdict",roles:["reviewer"],description:"Verdict criteria and format for code/review agent",defaultContent:"APPROVE — Step will achieve its stated outcomes..."},"merger-conflicts":{key:"merger-conflicts",name:"Merger Conflicts",roles:["merger"],description:"Merge conflict resolution instructions for merger",defaultContent:"If there are merge conflicts..."},"agent-generation-system":{key:"agent-generation-system",name:"Agent Generation System",roles:["executor"],description:"System prompt for generating agent specifications",defaultContent:"You are an agent specification generator..."},"workflow-step-refine":{key:"workflow-step-refine",name:"Workflow Step Refine",roles:["executor"],description:"System prompt for refining workflow step descriptions",defaultContent:"You are an expert at creating detailed agent prompts..."},"planning-system":{key:"planning-system",name:"Planning System",roles:["triage"],description:"System prompt for the AI planning assistant",defaultContent:"You are a planning assistant for the fn task board system..."},"subtask-breakdown-system":{key:"subtask-breakdown-system",name:"Subtask Breakdown System",roles:["executor"],description:"System prompt for AI subtask decomposition",defaultContent:"You are a task decomposition assistant..."},"mission-interview-system":{key:"mission-interview-system",name:"Mission Interview System",roles:["triage"],description:"System prompt for AI-assisted mission planning",defaultContent:"You are a mission planning assistant..."},"ai-refine-system":{key:"ai-refine-system",name:"AI Refine System",roles:["executor"],description:"System prompt for AI-powered text refinement",defaultContent:"You are a text refinement assistant..."},"agent-onboarding-system":{key:"agent-onboarding-system",name:"Agent Onboarding System",roles:["executor"],description:"System prompt for AI-guided agent onboarding interview",defaultContent:"You are an agent onboarding assistant for the fn task board system..."}},jn=["executor","triage","reviewer","merger"],Xc={executor:{key:"agentPrompts.roles.executor",defaultValue:"Executor Agent"},triage:{key:"agentPrompts.roles.triage",defaultValue:"Triage Agent"},reviewer:{key:"agentPrompts.roles.reviewer",defaultValue:"Reviewer Agent"},merger:{key:"agentPrompts.roles.merger",defaultValue:"Merger Agent"},scheduler:{key:"agentPrompts.roles.scheduler",defaultValue:"Scheduler Agent"},engineer:{key:"agentPrompts.roles.engineer",defaultValue:"Engineer Agent"},custom:{key:"agentPrompts.roles.custom",defaultValue:"Custom Agent"}},ut=a=>`prompt-role-tone--${a}`,Ls={name:"",description:"",role:"executor",prompt:""};function Zc(a,t){const s=a.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,50),c=new Set(Xe.map(i=>i.id)),r=new Set(t.map(i=>i.id));if(!c.has(s)&&!r.has(s))return s;let m=2;for(;c.has(`${s}-${m}`)||r.has(`${s}-${m}`);)m++;return`${s}-${m}`}function ed({value:a,onChange:t,promptOverrides:s,onPromptOverridesChange:c}){const{t:r}=Z("app"),m=P=>{const F=Xc[P];return r(F.key,F.defaultValue)},[i,n]=o.useState("templates"),[p,A]=o.useState(null),[j,u]=o.useState(!1),[d,C]=o.useState(Ls),[b,h]=o.useState(null),[f,S]=o.useState(null),[w,I]=o.useState(new Set),[x,v]=o.useState(null),[B,k]=o.useState(!1),[Y,W]=o.useState(null),J=o.useRef(null),V=a?.templates??[],ne=a?.roleAssignments??{},ae=Y===null?null:Y.source==="builtin"?Xe.find(P=>P.id===Y.id):V.find(P=>P.id===Y.id),$=o.useCallback(P=>{const F=Xe.filter(ce=>ce.role===P),X=V.filter(ce=>ce.role===P);return[...F,...X]},[V]);o.useEffect(()=>{Y!==null&&J.current?.focus()},[Y]);const _=o.useCallback(()=>{u(!0),A(null),C(Ls),h(null),W(null)},[]),T=o.useCallback(P=>{A(P.id),u(!1),C({name:P.name,description:P.description,role:P.role,prompt:P.prompt}),h(null),W(null)},[]),D=o.useCallback(()=>{A(null),u(!1),C(Ls),h(null),W(null),k(!1)},[]),re=o.useCallback(()=>{const P=d.name.trim();if(!P){h(r("agentPrompts.errors.nameRequired","Template name is required"));return}let F;if(j){if(F=Zc(P,V),new Set(Xe.map(R=>R.id)).has(F)){h(r("agentPrompts.errors.idConflict",'Template ID "{{templateId}}" conflicts with a built-in template. Please use a different name.',{templateId:F}));return}}else F=p;const X={id:F,name:P,description:d.description.trim(),role:d.role,prompt:d.prompt,builtIn:!1};let ce;j?ce=[...V,X]:ce=V.map(te=>te.id===F?X:te);const de={...ne};for(const[te,R]of Object.entries(de))R===F&&d.role!==te&&delete de[te];t({...a,templates:ce,roleAssignments:Object.keys(de).length>0?de:void 0}),D()},[d,j,p,V,ne,a,t,D]),U=o.useCallback(P=>{const F=V.filter(de=>de.id!==P),X={...ne};let ce=!1;for(const[de,te]of Object.entries(X))te===P&&(delete X[de],ce=!0);t({...a,templates:F.length>0?F:void 0,roleAssignments:Object.keys(X).length>0||ce?Object.keys(X).length>0?X:void 0:ne}),S(null),p===P&&D()},[V,ne,a,t,p,D]),ie=o.useCallback((P,F)=>{const X={...ne};F===""?delete X[P]:X[P]=F,t({...a,roleAssignments:Object.keys(X).length>0?X:void 0})},[ne,a,t]),ve=o.useCallback((P,F)=>{const X={...s};X[P]=F||null,c(X)},[s,c]),y=o.useCallback(P=>{const F={...s};F[P]=null,c(F)},[s,c]),H=o.useCallback(P=>{I(F=>{const X=new Set(F);return X.has(P)?X.delete(P):X.add(P),X})},[]),he=o.useCallback(P=>{v(F=>F===P?null:P)},[]),xe=o.useCallback((P,F)=>{k(!1),W({source:P,id:F})},[]),fe=o.useCallback(()=>{W(null),k(P=>!P)},[]),K=P=>Xe.some(F=>F.id===P);return e.jsxs("div",{className:"prompt-manager",children:[e.jsxs("div",{className:"prompt-manager-tabs",children:[e.jsxs("button",{type:"button",className:`prompt-manager-tab ${i==="templates"?"active":""}`,onClick:()=>n("templates"),"data-testid":"tab-templates",children:[e.jsx($o,{size:14}),r("agentPrompts.tabs.templates","Templates")]}),e.jsxs("button",{type:"button",className:`prompt-manager-tab ${i==="assignments"?"active":""}`,onClick:()=>n("assignments"),"data-testid":"tab-assignments",children:[e.jsx(Ho,{size:14}),r("agentPrompts.tabs.assignments","Assignments")]}),e.jsxs("button",{type:"button",className:`prompt-manager-tab ${i==="overrides"?"active":""}`,onClick:()=>n("overrides"),"data-testid":"tab-overrides",children:[e.jsx(zo,{size:14}),r("agentPrompts.tabs.overrides","Overrides")]})]}),e.jsxs("div",{className:"prompt-manager-content",children:[i==="templates"&&e.jsxs("div",{className:"prompt-manager-templates-tab","data-testid":"templates-tab",children:[(j||p!==null)&&e.jsxs("div",{className:"prompt-template-editor","data-testid":"template-editor",children:[e.jsx("h4",{className:"prompt-template-editor-title",children:j?r("agentPrompts.editor.newTemplate","New Custom Template"):r("agentPrompts.editor.editTemplate","Edit Custom Template")}),e.jsxs("div",{className:"prompt-template-editor-fields",children:[e.jsxs("div",{className:"prompt-template-field",children:[e.jsx("label",{htmlFor:"template-name",children:r("agentPrompts.labels.name","Name")}),e.jsx("input",{id:"template-name",type:"text",value:d.name,onChange:P=>C(F=>({...F,name:P.target.value})),placeholder:r("agentPrompts.placeholders.templateName","e.g. My Custom Executor"),"data-testid":"template-name-input"})]}),e.jsxs("div",{className:"prompt-template-field",children:[e.jsx("label",{htmlFor:"template-description",children:r("agentPrompts.labels.description","Description")}),e.jsx("input",{id:"template-description",type:"text",value:d.description,onChange:P=>C(F=>({...F,description:P.target.value})),placeholder:r("agentPrompts.placeholders.description","Brief description of this template"),"data-testid":"template-description-input"})]}),e.jsxs("div",{className:"prompt-template-field",children:[e.jsx("label",{htmlFor:"template-role",children:r("agentPrompts.labels.role","Role")}),e.jsx("select",{id:"template-role",value:d.role,onChange:P=>C(F=>({...F,role:P.target.value})),"data-testid":"template-role-select",children:jn.map(P=>e.jsx("option",{value:P,children:m(P)},P))})]}),e.jsxs("div",{className:"prompt-template-field",children:[e.jsxs("div",{className:"prompt-template-prompt-label-row",children:[e.jsx("label",{htmlFor:"template-prompt",children:r("agentPrompts.labels.prompt","Prompt")}),e.jsx("button",{type:"button",className:"btn-icon prompt-template-fullscreen-btn",onClick:fe,"aria-label":r("agentPrompts.ariaLabels.expandPrompt","Expand prompt to fullscreen"),"data-testid":"template-prompt-fullscreen",children:e.jsx(Rt,{size:14})})]}),B?e.jsxs("div",{className:"prompt-override-fullscreen",onKeyDown:P=>{P.key==="Escape"&&(P.preventDefault(),k(!1))},children:[e.jsxs("div",{className:"prompt-override-fullscreen-header",children:[e.jsx("div",{className:"prompt-override-fullscreen-title",children:r("agentPrompts.titles.editPrompt","Edit Prompt")}),e.jsxs("button",{type:"button",className:"prompt-override-fullscreen-close",onClick:()=>k(!1),"data-testid":"template-prompt-collapse",children:[e.jsx(Ps,{size:14}),r("agentPrompts.actions.collapse","Collapse")]})]}),e.jsx("textarea",{id:"template-prompt-fullscreen","aria-label":r("agentPrompts.ariaLabels.templatePromptFullscreen","Template prompt - fullscreen"),className:"prompt-template-prompt-textarea",value:d.prompt,onChange:P=>C(F=>({...F,prompt:P.target.value})),placeholder:r("agentPrompts.placeholders.prompt","Enter the system prompt for this template..."),rows:30,autoFocus:!0,"data-testid":"template-prompt-input-fullscreen"}),e.jsx("div",{className:"prompt-override-footer",children:e.jsx("small",{className:"prompt-override-hint",children:r("agents.charactersCount","{{count}} characters",{count:d.prompt.length})})})]}):e.jsx("textarea",{id:"template-prompt",value:d.prompt,onChange:P=>C(F=>({...F,prompt:P.target.value})),placeholder:r("agentPrompts.placeholders.prompt","Enter the system prompt for this template..."),rows:8,className:"prompt-template-prompt-textarea","data-testid":"template-prompt-input"})]}),b&&e.jsx("div",{className:"prompt-template-error","data-testid":"template-error",children:b}),e.jsxs("div",{className:"prompt-template-editor-actions",children:[e.jsx("button",{type:"button",className:"btn btn-secondary",onClick:D,"data-testid":"cancel-template-btn",children:r("agentPrompts.actions.cancel","Cancel")}),e.jsx("button",{type:"button",className:"btn btn-primary",onClick:re,"data-testid":"save-template-btn",children:j?r("agentPrompts.actions.create","Create"):r("agentPrompts.actions.save","Save")})]})]})]}),e.jsxs("div",{className:"prompt-template-section","data-testid":"builtin-templates",children:[e.jsx("h4",{className:"prompt-template-section-title",children:r("agentPrompts.sections.builtinTemplates","Built-in Templates")}),e.jsx("p",{className:"prompt-template-section-desc",children:r("agentPrompts.descriptions.builtinTemplates","These templates are provided by Fusion and cannot be modified.")}),e.jsx("div",{className:"prompt-template-list",children:Xe.map(P=>e.jsxs("div",{className:"prompt-template-card","data-testid":`builtin-template-${P.id}`,children:[e.jsxs("div",{className:"prompt-template-card-header",children:[e.jsxs("div",{className:"prompt-template-card-info",children:[e.jsx("span",{className:"prompt-template-card-name",children:P.name}),e.jsx("span",{className:`prompt-template-badge-built-in ${ut(P.role)}`,children:r("agentPrompts.badges.builtin","Built-in")}),e.jsx("span",{className:`prompt-template-badge-role ${ut(P.role)}`,children:m(P.role)})]}),e.jsx("div",{className:"prompt-template-card-actions",children:e.jsx("button",{type:"button",className:"btn-icon prompt-template-fullscreen-btn",onClick:()=>xe("builtin",P.id),title:r("agentPrompts.titles.viewFullPrompt","View full prompt"),"aria-label":r("agentPrompts.ariaLabels.viewFullPromptFor","View full prompt for {{name}}",{name:P.name}),"data-testid":`expand-view-${P.id}`,children:e.jsx(Rt,{size:14})})})]}),e.jsx("p",{className:"prompt-template-card-description",children:P.description}),e.jsx("div",{className:"prompt-template-card-preview",children:e.jsx("code",{children:P.prompt})})]},P.id))})]}),e.jsxs("div",{className:"prompt-template-section","data-testid":"custom-templates",children:[e.jsx("h4",{className:"prompt-template-section-title",children:r("agentPrompts.sections.customTemplates","Custom Templates")}),e.jsx("p",{className:"prompt-template-section-desc",children:r("agentPrompts.descriptions.customTemplates","Create custom templates to override built-in prompts for specific roles.")}),V.length===0&&!j&&e.jsx("div",{className:"prompt-template-empty",children:r("agentPrompts.emptyStates.noCustomTemplates","No custom templates yet. Create one to get started.")}),V.length>0&&e.jsx("div",{className:"prompt-template-list",children:V.map(P=>e.jsx("div",{className:"prompt-template-card","data-testid":`custom-template-${P.id}`,children:f===P.id?e.jsxs("div",{className:"prompt-template-delete-confirm",children:[e.jsx("p",{children:r("agentPrompts.confirmations.deleteTemplate",'Delete "{{name}}"?',{name:P.name})}),e.jsxs("div",{className:"prompt-template-delete-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-danger",onClick:()=>U(P.id),"data-testid":`confirm-delete-${P.id}`,children:r("agentPrompts.actions.delete","Delete")}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>S(null),"data-testid":`cancel-delete-${P.id}`,children:r("agentPrompts.actions.cancel","Cancel")})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"prompt-template-card-header",children:[e.jsxs("div",{className:"prompt-template-card-info",children:[e.jsx("span",{className:"prompt-template-card-name",children:P.name}),e.jsx("span",{className:"prompt-template-badge-custom",children:r("agentPrompts.badges.custom","Custom")}),e.jsx("span",{className:`prompt-template-badge-role ${ut(P.role)}`,children:m(P.role)}),K(P.id)&&e.jsx("span",{className:"prompt-template-badge-override",children:r("agentPrompts.badges.overridesBuiltin","Overrides built-in")})]}),e.jsxs("div",{className:"prompt-template-card-actions",children:[e.jsx("button",{type:"button",className:"btn-icon prompt-template-fullscreen-btn",onClick:()=>xe("custom",P.id),title:r("agentPrompts.titles.viewFullPrompt","View full prompt"),"aria-label":r("agentPrompts.ariaLabels.viewFullPromptFor","View full prompt for {{name}}",{name:P.name}),"data-testid":`expand-view-${P.id}`,children:e.jsx(Rt,{size:14})}),e.jsx("button",{type:"button",className:"btn-icon",onClick:()=>T(P),title:r("agentPrompts.titles.edit","Edit"),"aria-label":r("agentPrompts.ariaLabels.editTemplate","Edit {{name}}",{name:P.name}),"data-testid":`edit-${P.id}`,children:e.jsx(Bt,{size:14})}),e.jsx("button",{type:"button",className:"btn-icon",onClick:()=>S(P.id),title:r("agentPrompts.titles.delete","Delete"),"aria-label":r("agentPrompts.ariaLabels.deleteTemplate","Delete {{name}}",{name:P.name}),"data-testid":`delete-${P.id}`,children:e.jsx(Gt,{size:14})})]})]}),e.jsx("p",{className:"prompt-template-card-description",children:P.description}),e.jsx("div",{className:"prompt-template-card-preview",children:e.jsx("code",{children:P.prompt})})]})},P.id))}),!j&&p===null&&e.jsxs("button",{type:"button",className:"btn btn-primary prompt-template-add-btn",onClick:_,"data-testid":"add-template-btn",children:[e.jsx(Ot,{size:14}),r("agentPrompts.actions.addCustomTemplate","Add Custom Template")]})]}),ae&&e.jsxs("div",{ref:J,className:"prompt-override-fullscreen",role:"dialog","aria-modal":"true",tabIndex:-1,onKeyDown:P=>{P.key==="Escape"&&(P.preventDefault(),W(null))},children:[e.jsxs("div",{className:"prompt-override-fullscreen-header",children:[e.jsxs("div",{className:"prompt-override-fullscreen-title",children:[ae.name,e.jsx("span",{className:`prompt-template-badge-role ${ut(ae.role)}`,children:m(ae.role)})]}),e.jsxs("button",{type:"button",className:"prompt-override-fullscreen-close",onClick:()=>W(null),"data-testid":`collapse-view-${ae.id}`,children:[e.jsx(Ps,{size:14}),r("agentPrompts.actions.collapse","Collapse")]})]}),e.jsx("pre",{className:"prompt-template-fullscreen-pre",children:ae.prompt})]})]}),i==="assignments"&&e.jsxs("div",{className:"prompt-manager-assignments-tab","data-testid":"assignments-tab",children:[e.jsx("p",{className:"prompt-assignments-desc",children:r("agentPrompts.descriptions.assignments","Assign specific templates to agent roles. When a role has an assignment, that template will be used instead of the default built-in.")}),e.jsx("div",{className:"prompt-role-assignment-list",children:jn.map(P=>{const F=$(P),X=ne[P]??"",ce=F.find(te=>te.id===X),de=!!X;return e.jsxs("div",{className:"prompt-role-assignment-row","data-testid":`assignment-${P}`,children:[e.jsxs("div",{className:"prompt-role-assignment-label",children:[e.jsx("span",{className:`prompt-role-badge ${ut(P)}`,children:m(P)}),de&&e.jsxs("span",{className:"prompt-role-assignment-status",children:[ce?.name??r("agentPrompts.labels.custom","Custom")," (",r("agentPrompts.labels.overridesDefault","overrides default"),")"]})]}),e.jsxs("select",{className:"prompt-role-select",value:X,onChange:te=>ie(P,te.target.value),"data-testid":`select-${P}`,children:[e.jsx("option",{value:"",children:r("agentPrompts.options.useDefault","Use default")}),F.map(te=>e.jsxs("option",{value:te.id,children:[te.name,K(te.id)?` (${r("agentPrompts.labels.builtIn","built-in")})`:` (${r("agentPrompts.labels.custom","custom")})`]},te.id))]})]},P)})}),Object.keys(ne).length>0&&e.jsxs("div",{className:"prompt-assignments-note",children:[e.jsxs("strong",{children:[r("agentPrompts.labels.note","Note"),":"]})," ",r("agentPrompts.descriptions.assignmentNote","Role assignments are stored in the agentPrompts configuration. Custom templates override built-ins by ID.")]})]}),i==="overrides"&&e.jsxs("div",{className:"prompt-manager-overrides-tab","data-testid":"overrides-tab",children:[e.jsx("p",{className:"prompt-overrides-desc",children:r("agentPrompts.descriptions.overrides","Customize specific segments of AI agent prompts. Edits override built-in defaults. Use the Reset button to restore the original default for any prompt.")}),e.jsx("div",{className:"prompt-overrides-list",children:Object.values(Jc).map(P=>{const F=P.key,X=s?.[F]??"",ce=X!=="",de=w.has(F);return e.jsxs("div",{className:"prompt-override-item","data-testid":`override-${F}`,children:[e.jsxs("div",{className:"prompt-override-header",children:[e.jsxs("button",{type:"button",className:"prompt-override-info",onClick:()=>H(F),children:[e.jsx("span",{className:"prompt-override-name",children:P.name}),e.jsx("code",{className:"prompt-override-key",children:F}),ce&&e.jsx("span",{className:"prompt-override-badge",children:r("agentPrompts.badges.customized","customized")})]}),e.jsxs("div",{className:"prompt-override-header-actions",children:[de&&e.jsx("button",{type:"button",className:"prompt-override-fullscreen-btn",onClick:te=>{te.stopPropagation(),he(F)},"aria-label":r("agentPrompts.ariaLabels.expandToFullscreen","Expand to fullscreen"),"data-testid":`fullscreen-${F}`,children:e.jsx(Rt,{size:14})}),e.jsx("button",{type:"button",className:"prompt-override-expand-btn","aria-label":de?r("agentPrompts.ariaLabels.collapse","Collapse"):r("agentPrompts.ariaLabels.expand","Expand"),"data-testid":`expand-${F}`,onClick:te=>{te.stopPropagation(),H(F)},children:de?e.jsx(El,{size:16}):e.jsx(Fl,{size:16})})]})]}),e.jsx("p",{className:"prompt-override-description",children:P.description}),de&&(x===F?e.jsxs("div",{className:"prompt-override-fullscreen",onKeyDown:te=>{te.key==="Escape"&&(te.preventDefault(),v(null))},children:[e.jsxs("div",{className:"prompt-override-fullscreen-header",children:[e.jsxs("div",{className:"prompt-override-fullscreen-title",children:[P.name,e.jsx("code",{className:"prompt-override-key",children:F})]}),e.jsxs("button",{type:"button",className:"prompt-override-fullscreen-close",onClick:()=>v(null),"data-testid":`collapse-fullscreen-${F}`,children:[e.jsx(Ps,{size:14}),r("agentPrompts.actions.collapse","Collapse")]})]}),e.jsx("textarea",{id:`prompt-${F}-fullscreen`,"aria-label":r("agentPrompts.ariaLabels.promptOverrideFullscreen","{{name}} prompt override ({{key}}) - fullscreen",{name:P.name,key:F}),className:"prompt-override-textarea",value:X,onChange:te=>{ve(F,te.target.value)},placeholder:`Default: ${P.defaultContent.slice(0,100)}${P.defaultContent.length>100?"...":""}`,rows:30,autoFocus:!0,"data-testid":`override-input-fullscreen-${F}`}),e.jsxs("div",{className:"prompt-override-footer",children:[ce&&e.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",onClick:()=>y(F),"data-testid":`reset-fullscreen-${F}`,children:r("agentPrompts.actions.reset","Reset")}),e.jsx("small",{className:"prompt-override-hint",children:ce?r("agentPrompts.hints.customOverrideActive","Custom override active. Click Reset to restore default."):r("agentPrompts.hints.noOverrideSet","No override set. Using built-in default ({{chars}} chars).",{chars:P.defaultContent.length})})]})]}):e.jsxs("div",{className:"prompt-override-editor",children:[e.jsx("textarea",{id:`prompt-${F}`,"aria-label":r("agentPrompts.ariaLabels.promptOverride","{{name}} prompt override ({{key}})",{name:P.name,key:F}),className:"prompt-override-textarea",value:X,onChange:te=>{ve(F,te.target.value)},placeholder:r("agentPrompts.placeholders.promptDefault","Default: {{preview}}",{preview:P.defaultContent.slice(0,100)+(P.defaultContent.length>100?"...":"")}),rows:4,"data-testid":`override-input-${F}`}),e.jsxs("div",{className:"prompt-override-footer",children:[ce&&e.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",onClick:te=>{te.stopPropagation(),y(F)},"data-testid":`reset-${F}`,children:r("agentPrompts.actions.reset","Reset")}),e.jsx("small",{className:"prompt-override-hint",children:ce?r("agentPrompts.hints.customOverrideActive","Custom override active. Click Reset to restore default."):r("agentPrompts.hints.noOverrideSet","No override set. Using built-in default ({{chars}} chars).",{chars:P.defaultContent.length})})]})]}))]},F)})})]})]})]})}function ea({message:a,onOpenWorkflowSettings:t}){const{t:s}=Z("app");return e.jsxs("div",{className:"settings-moved-stub",role:"note",children:[e.jsx("p",{className:"settings-moved-stub__message",children:a}),e.jsx("button",{type:"button",className:"settings-moved-stub__action",onClick:t,disabled:!t,children:s("settings.movedStub.openWorkflowSettings","Open workflow settings")})]})}function td({scopeBanner:a,form:t,setForm:s,onOpenWorkflowSettings:c}){const{t:r}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:r("settings.nav.prompts","Prompts")}),e.jsx("div",{className:"form-group",children:e.jsx("small",{children:r("settings.prompts.surfaceExplanation","Use this section for agent role system prompt templates, role assignments, and global PromptKey segment overrides. Per-workflow step prompts for prompt and gate nodes are edited in the Workflow Editor.")})}),e.jsx(ea,{message:r("settings.prompts.workflowPromptsRedirect","Per-workflow step prompts for prompt and gate nodes live in the Workflow Editor."),onOpenWorkflowSettings:c}),e.jsx(ed,{value:t.agentPrompts,onChange:m=>{s(i=>({...i,agentPrompts:m}))},promptOverrides:t.promptOverrides,onPromptOverridesChange:m=>{s(i=>({...i,promptOverrides:m}))}})]})}function sd({scopeBanner:a,form:t,setForm:s,projectId:c,addToast:r,prefixError:m,setPrefixError:i,projectTrackingRepoOptions:n,projectTrackingRepoLoading:p,projectTrackingRepoError:A,onQuickChatButtonModeChange:j}){const{t:u}=Z("app"),[d,C]=o.useState([]);o.useEffect(()=>{let f=!1;return Dl(c,{includeDisabledBuiltins:!0}).then(S=>{f||C(S.filter(w=>w.id.startsWith("builtin:")&&w.kind!=="fragment"))}).catch(()=>{f||C([])}),()=>{f=!0}},[c]);const b=o.useMemo(()=>{const f=Array.isArray(t.enabledBuiltinWorkflowIds)?t.enabledBuiltinWorkflowIds:void 0;return new Set(f??d.map(S=>S.id))},[d,t.enabledBuiltinWorkflowIds]),h=(f,S)=>{s(w=>{const I=d.map(B=>B.id),x=new Set(Array.isArray(w.enabledBuiltinWorkflowIds)?w.enabledBuiltinWorkflowIds:I);S?x.add(f):x.delete(f);const v=I.filter(B=>x.has(B));return{...w,enabledBuiltinWorkflowIds:v.length===I.length?void 0:v}})};return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:u("settings.general.general","General")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"taskPrefix",children:u("settings.general.taskPrefix","Task Prefix")}),e.jsx("input",{id:"taskPrefix",type:"text",placeholder:u("settings.general.fN","FN"),value:t.taskPrefix||"",onChange:f=>{const S=f.target.value;s(w=>({...w,taskPrefix:S||void 0})),S&&!/^[A-Z]{1,5}$/.test(S)?i(u("settings.general.prefixMustBe15UppercaseLetters","Prefix must be 1–5 uppercase letters")):i(null)}}),m&&e.jsx("small",{className:"field-error",children:m}),!m&&e.jsx("small",{children:u("settings.general.prefixForNewTaskIDsEGKB","Prefix for new task IDs (e.g. KB, PROJ)")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx(Ll,{projectId:c,addToast:r}),e.jsx("small",{children:u("settings.general.newTasksInheritThisCustomWorkflowsStepsOverridable","New tasks inherit this custom workflow's steps (overridable per task)")})]}),d.length>0&&e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:u("settings.general.builtInWorkflows","Built-in workflows")}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"var(--space-sm)"},children:d.map(f=>e.jsxs("label",{htmlFor:`builtin-workflow-${f.id}`,className:"checkbox-label",children:[e.jsx("input",{id:`builtin-workflow-${f.id}`,type:"checkbox",checked:b.has(f.id),onChange:S=>h(f.id,S.target.checked)}),e.jsx("span",{children:f.name})]},f.id))}),e.jsx("small",{children:u("settings.general.disabledBuiltInWorkflowsAreHiddenFromWorkflow","Disabled built-in workflows are hidden from workflow pickers. Existing tasks that already use one continue to resolve.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"ephemeralAgentsEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"ephemeralAgentsEnabled",type:"checkbox",checked:t.ephemeralAgentsEnabled!==!1,onChange:f=>s(S=>({...S,ephemeralAgentsEnabled:f.target.checked}))}),u("settings.general.useEphemeralTaskWorkerAgents"," Use ephemeral task-worker agents ")]}),e.jsxs("small",{children:[u("settings.general.whenEnabledDefaultFusionSpawnsShortLived"," When enabled (default), Fusion spawns short-lived "),e.jsx("code",{children:"executor-FN-XXXX"}),u("settings.general.agentsToRunEachTaskWhenDisabledOnly"," agents to run each task. When disabled, only permanent agents execute tasks and the scheduler auto-assigns work using the agent reporting chain. Tasks with no eligible permanent agent stay queued. ")]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"workspaceMode",className:"checkbox-label",children:[e.jsx("input",{id:"workspaceMode",type:"checkbox",checked:t.workspaceMode===!0,onChange:f=>s(S=>({...S,workspaceMode:f.target.checked}))}),u("settings.general.workspaceMode"," Workspace mode (multi-repo) ")]}),e.jsx("small",{children:u("settings.general.workspaceModeHint","When enabled, the project root is treated as a workspace containing multiple git sub-repos. Tasks run per-sub-repo and no git repo is created at the root. Disable for single-repo projects.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"completionDocumentationMode",children:u("settings.general.completionDocumentationAutomation","Completion Documentation Automation")}),e.jsxs("select",{id:"completionDocumentationMode",value:t.completionDocumentationMode||"off",onChange:f=>s(S=>({...S,completionDocumentationMode:f.target.value})),children:[e.jsx("option",{value:"off",children:u("settings.general.off","Off")}),e.jsx("option",{value:"changeset",children:u("settings.general.requireChangesetChangesetMd","Require changeset (.changeset/*.md)")}),e.jsx("option",{value:"changelog",children:u("settings.general.requireChangelogUpdateExistingChangelog","Require changelog update (existing changelog)")})]}),e.jsxs("small",{children:[u("settings.general.controlsHowFutureTaskSpecsHandleReleaseNote"," Controls how future task specs handle release-note artifacts at completion. Use changeset mode for repositories that follow "),e.jsx("code",{children:".changeset"}),u("settings.general.workflowsOrChangelogModeWhenContributorsShouldUpdate"," workflows, or changelog mode when contributors should update an existing changelog file. ")]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"quickChatButtonMode",children:u("settings.general.quickChatLauncher","Quick Chat launcher")}),e.jsxs("select",{id:"quickChatButtonMode",className:"select",value:t.quickChatButtonMode??(t.showQuickChatFAB?"floating":"off"),onChange:f=>s(S=>{const w=f.target.value;return j?.(w),{...S,quickChatButtonMode:w,showQuickChatFAB:w==="floating"}}),children:[e.jsx("option",{value:"floating",children:u("settings.general.quickChatLauncherFloating","Floating button")}),e.jsx("option",{value:"footer",children:u("settings.general.quickChatLauncherFooter","Footer button")}),e.jsx("option",{value:"off",children:u("settings.general.off","Off")})]}),e.jsx("small",{children:u("settings.general.quickChatLauncherHint","Choose whether Quick Chat opens from the draggable floating button, a footer button beside Terminal, or stays hidden.")})]}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:u("settings.general.chatHistory","Chat history")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"chatAutoCleanupDays",children:u("settings.general.autoCleanupOldChats","Auto-cleanup old chats")}),e.jsxs("select",{id:"chatAutoCleanupDays",className:"select",value:t.chatAutoCleanupDays??0,onChange:f=>s(S=>({...S,chatAutoCleanupDays:Number(f.target.value)||0})),children:[e.jsx("option",{value:0,children:u("settings.general.off","Off")}),e.jsx("option",{value:7,children:u("settings.general.7Days","7 days")}),e.jsx("option",{value:14,children:u("settings.general.14Days","14 days")}),e.jsx("option",{value:30,children:u("settings.general.30Days","30 days")}),e.jsx("option",{value:60,children:u("settings.general.60Days","60 days")}),e.jsx("option",{value:90,children:u("settings.general.90Days","90 days")})]}),e.jsx("small",{children:u("settings.general.deleteChatSessionsAndRoomsThatHaveBeen","Delete chat sessions and rooms that have been idle for this many days. Default: Off.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"mailAutoCleanupDays",children:u("settings.general.autoPruneOldMail","Auto-prune old mail")}),e.jsxs("select",{id:"mailAutoCleanupDays",className:"select",value:t.mailAutoCleanupDays??0,onChange:f=>s(S=>({...S,mailAutoCleanupDays:Number(f.target.value)||0})),children:[e.jsx("option",{value:0,children:u("settings.general.off","Off")}),e.jsx("option",{value:7,children:u("settings.general.7Days","7 days")}),e.jsx("option",{value:14,children:u("settings.general.14Days","14 days")}),e.jsx("option",{value:30,children:u("settings.general.30Days","30 days")}),e.jsx("option",{value:60,children:u("settings.general.60Days","60 days")}),e.jsx("option",{value:90,children:u("settings.general.90Days","90 days")})]}),e.jsx("small",{children:u("settings.general.deleteInboxOutboxMessagesOlderThanThisMany","Delete inbox/outbox messages older than this many days. Default: Off. 7 days is the suggested setting.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"operationalLogRetentionDays",children:u("settings.general.operationalLogRetention","Operational log retention")}),e.jsxs("select",{id:"operationalLogRetentionDays",className:"select",value:t.operationalLogRetentionDays??30,onChange:f=>s(S=>({...S,operationalLogRetentionDays:Number(f.target.value)||0})),children:[e.jsx("option",{value:0,children:u("settings.general.off","Off")}),e.jsx("option",{value:7,children:u("settings.general.7Days","7 days")}),e.jsx("option",{value:14,children:u("settings.general.14Days","14 days")}),e.jsx("option",{value:30,children:u("settings.general.30Days","30 days")}),e.jsx("option",{value:60,children:u("settings.general.60Days","60 days")}),e.jsx("option",{value:90,children:u("settings.general.90Days","90 days")})]}),e.jsx("small",{children:u("settings.general.loweringThisWindowMeansReliabilityMetricsChartsAnd"," Lowering this window means Reliability metrics/charts and the Activity feed will not show history older than the selected range. Per-task task detail history is unaffected. Default: 30 days. ")})]}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:u("settings.general.chatRooms","Chat Rooms")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"chatRoomRecentVerbatimMessages",children:u("settings.general.recentVerbatimRoomMessages","Recent verbatim room messages")}),e.jsx("input",{id:"chatRoomRecentVerbatimMessages",type:"number",min:"1",className:"input",placeholder:u("settings.general.25","25"),value:t.chatRoomRecentVerbatimMessages??"",onChange:f=>s(S=>({...S,chatRoomRecentVerbatimMessages:Number(f.target.value)||void 0}))}),e.jsx("small",{children:u("settings.general.numberOfMostRecentChatRoomMessagesKept","Number of most-recent chat-room messages kept verbatim in the responder transcript. Older messages are compacted into a summary block. Default: 25.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"chatRoomCompactionFetchLimit",children:u("settings.general.roomCompactionFetchLimit","Room compaction fetch limit")}),e.jsx("input",{id:"chatRoomCompactionFetchLimit",type:"number",min:"1",className:"input",placeholder:u("settings.general.200","200"),value:t.chatRoomCompactionFetchLimit??"",onChange:f=>s(S=>({...S,chatRoomCompactionFetchLimit:Number(f.target.value)||void 0}))}),e.jsx("small",{children:u("settings.general.upperBoundOnMessagesFetchedFromTheRoom","Upper bound on messages fetched from the room store for compaction consideration. Default: 200.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"chatRoomSummaryMaxChars",children:u("settings.general.roomSummaryMaxCharacters","Room summary max characters")}),e.jsx("input",{id:"chatRoomSummaryMaxChars",type:"number",min:"200",className:"input",placeholder:u("settings.general.3000","3000"),value:t.chatRoomSummaryMaxChars??"",onChange:f=>s(S=>({...S,chatRoomSummaryMaxChars:Number(f.target.value)||void 0}))}),e.jsx("small",{children:u("settings.general.hardCapOnTheSynthesizedEarlierRoomContext",'Hard cap on the synthesized "Earlier room context" summary block. Default: 3000.')})]}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:u("settings.general.capacityRiskBanner","Capacity Risk Banner")}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"capacityRiskBannerEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"capacityRiskBannerEnabled",type:"checkbox",checked:t.capacityRiskBannerEnabled===!0,onChange:f=>s(S=>({...S,capacityRiskBannerEnabled:f.target.checked}))}),u("settings.general.showCapacityRiskBanner"," Show capacity risk banner ")]}),e.jsx("small",{children:u("settings.general.warnOnTheBoardWhenTodoWorkExceeds","Warn on the board when todo work exceeds the threshold and no idle agents are available.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"capacityRiskTodoThresholdGeneral",children:u("settings.general.todoThreshold","Todo threshold")}),e.jsx("input",{id:"capacityRiskTodoThresholdGeneral",type:"number",min:0,className:"input",value:t.capacityRiskTodoThreshold??20,onChange:f=>s(S=>({...S,capacityRiskTodoThreshold:f.target.value===""?0:Math.max(0,Number.parseInt(f.target.value,10)||0)}))}),e.jsx("small",{children:u("settings.general.bannerFiresWhenTodoCountIsStrictlyGreater","Banner fires when todo count is strictly greater than this value (default 20). Applies when the banner is enabled.")})]}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:u("settings.general.gitHubTracking","GitHub Tracking")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"githubTrackingMode",children:u("settings.general.defaultTrackingModeForNewTasks","Default tracking mode for new tasks")}),e.jsxs("select",{id:"githubTrackingMode",className:"select",value:t.githubTrackingEnabledByDefault?"new-tasks":"off",onChange:f=>s(S=>({...S,githubTrackingEnabledByDefault:f.target.value==="new-tasks"})),children:[e.jsx("option",{value:"off",children:u("settings.general.offDefault","Off (default)")}),e.jsx("option",{value:"new-tasks",children:u("settings.general.onForNewTasks","On for new tasks")})]}),e.jsx("small",{children:u("settings.general.controlsWhetherNewlyCreatedTasksHaveGitHubIssue"," Controls whether newly created tasks have GitHub issue tracking enabled by default. Individual tasks can still override this from the task detail modal. ")}),e.jsxs("small",{children:[u("settings.general.trackingIssuesUseThisTaskAposSTitle"," Tracking issues use this task's title. If a task has no title yet, Fusion can summarize its description using the title summarization model in Project Models. "),!t.autoSummarizeTitles&&!t.useAiMergeCommitSummary&&!t.githubTrackingEnabledByDefault?u("settings.general.enableSummarizationInProjectModelsToConfigureThatModel"," Enable summarization in Project Models to configure that model."):""]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"projectGithubTrackingDefaultRepoGeneral",children:u("settings.general.projectDefaultTrackingRepo","Project default tracking repo")}),e.jsx(On,{id:"projectGithubTrackingDefaultRepoGeneral",ariaLabel:"Project default tracking repo",value:t.githubTrackingDefaultRepo??"",options:n,loading:p,error:A??void 0,placeholder:u("settings.general.ownerRepo","owner/repo"),onChange:f=>s(S=>({...S,githubTrackingDefaultRepo:f||void 0}))}),e.jsx("small",{children:u("settings.general.defaultRepoUsedWhenCreatingGitHubIssuesFor","Default repo used when creating GitHub issues for tracked tasks. Falls back to the global default if blank.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"githubTrackingDedupEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"githubTrackingDedupEnabled",type:"checkbox",checked:t.githubTrackingDedupEnabled!==!1,onChange:f=>s(S=>({...S,githubTrackingDedupEnabled:f.target.checked}))}),u("settings.general.searchTheTrackingRepoForLikelyDuplicatesBefore"," Search the tracking repo for likely duplicates before opening a new issue ")]}),e.jsx("small",{children:u("settings.general.whenEnabledFusionChecksOpenAndClosedIssues"," When enabled, Fusion checks open and closed issues in the target repo for likely duplicates (using File Scope paths and key symptoms) before creating a new tracking issue. Uncheck to always create a new issue. ")})]})]})}const Os="builtin:coding",ad=[{id:"planning",providerId:"planningProvider",modelId:"planningModelId",label:"Plan/Triage Model",help:"Provider and model used when planning or triaging tasks. Leave unset to inherit from the workflow default."},{id:"execution",providerId:"executionProvider",modelId:"executionModelId",label:"Executor Model",help:"Provider and model used while executing workflow steps. Leave unset to inherit from the workflow default."},{id:"validator",providerId:"validatorProvider",modelId:"validatorModelId",label:"Reviewer Model",help:"Provider and model used for workflow review or validation lanes. Leave unset to inherit from the workflow default."},{id:"planning-fallback",providerId:"planningFallbackProvider",modelId:"planningFallbackModelId",label:"Planning Fallback Model",help:"Fallback provider and model used when the primary Plan/Triage model cannot be used."},{id:"validator-fallback",providerId:"validatorFallbackProvider",modelId:"validatorFallbackModelId",label:"Reviewer Fallback Model",help:"Fallback provider and model used when the primary Reviewer model cannot be used."},{id:"title-summarizer-fallback",providerId:"titleSummarizerFallbackProvider",modelId:"titleSummarizerFallbackModelId",label:"Title Summarizer Fallback Model",help:"Fallback provider and model used when the primary Title Summarizer model cannot be used."}];function nd(a){const t=new Map((a??[]).map(s=>[s.id,s]));return ad.filter(s=>{const c=t.get(s.providerId),r=t.get(s.modelId);return c?.type==="string"&&r?.type==="string"})}function rd(a,t){const s=a[t.providerId],c=a[t.modelId];return typeof s=="string"&&typeof c=="string"&&s&&c?`${s}/${c}`:""}class _n extends Error{rejections;constructor(t){super("Workflow model lane settings were rejected"),this.name="WorkflowLaneFlushRejection",this.rejections=t}}function id({scopeBanner:a,form:t,setForm:s,models:c,projectId:r,onOpenWorkflowSettings:m,registerWorkflowLaneSaver:i}){const{t:n}=Z("app"),{modelLanes:p,getLaneStatus:A,getLaneValue:j,updateLaneValue:u,resetLaneValue:d,availableModels:C,modelsLoading:b,favoriteProviders:h,favoriteModels:f,onToggleFavorite:S,onToggleModelFavorite:w,editingPresetId:I,setEditingPresetId:x,presetDraft:v,setPresetDraft:B,onSavePresetDraft:k,confirmDelete:Y}=c,W=t.modelPresets||[],J=W.map(R=>({id:R.id,name:R.name})),V=new Set(Object.values(t.defaultPresetBySize||{}).filter(Boolean)),ne=typeof t.defaultWorkflowId=="string"&&t.defaultWorkflowId.trim()?t.defaultWorkflowId:Os,[ae,$]=o.useState(ne),[_,T]=o.useState(null),[D,re]=o.useState(!1),[U,ie]=o.useState({}),[ve,y]=o.useState({}),[H,he]=o.useState([]),xe=o.useRef(0),fe=Object.keys(U).length>0;o.useEffect(()=>{$(ne)},[ne]),o.useEffect(()=>{if(!r){T(null),ie({}),y({}),he([]);return}const R=++xe.current;re(!0),Promise.all([Ol(ae,r),Bl(ae,r)]).then(([E,z])=>{if(xe.current!==R)return;T(z),ie({}),y({});const N="settings"in E.ir?E.ir.settings:void 0;he(nd(N))}).catch(E=>{if(xe.current===R){if(E instanceof Va&&E.status===404&&ae!==Os){$(Os);return}T({stored:{},effective:{},orphaned:[]}),he([])}}).finally(()=>{xe.current===R&&re(!1)})},[r,ae]);const K=o.useMemo(()=>({..._?.effective??{},...Object.fromEntries(Object.entries(U).filter(([,R])=>R!==null))}),[_,U]),P=o.useCallback((R,E)=>{y(z=>{const N={...z};return delete N[R.providerId],delete N[R.modelId],N}),ie(z=>{if(!E)return{...z,[R.providerId]:null,[R.modelId]:null};const N=E.indexOf("/");return N<=0?z:{...z,[R.providerId]:E.slice(0,N),[R.modelId]:E.slice(N+1)}})},[]),F=o.useCallback(R=>{P(R,"")},[P]),X=o.useCallback(async()=>{if(!(!r||!fe))try{const R=await Gl(ae,U,r);T(R),ie({}),y({})}catch(R){if(R instanceof Va&&R.status===400&&R.details){const E=R.details.rejections??[];if(E.length>0)throw y(Object.fromEntries(E.map(z=>[z.settingId,z]))),new _n(E)}throw R}},[r,fe,ae,U]);o.useEffect(()=>(i?.(X),()=>i?.(null)),[i,X]);const ce=p.filter(R=>["default","summarization"].includes(R.laneId)),de=R=>R.laneId==="default"?"Project Default Model":R.laneId==="summarization"?"Project Summarization Model":R.label,te=R=>R.laneId==="default"?"Project-wide default AI model used when no more specific task or project lane override is set.":R.laneId==="summarization"?"Model used for title auto-summarization, merge commit summaries, GitHub tracking issue titles, and PR title/body generation.":R.helperText;return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:n("settings.projectModels.tokenCap","Token Cap")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"tokenCap",children:n("settings.projectModels.tokenCap","Token Cap")}),e.jsxs("div",{className:"settings-token-cap-row",children:[e.jsx("input",{id:"tokenCap",type:"number",placeholder:n("settings.projectModels.noCap","No cap"),value:t.tokenCap??"",onChange:R=>{const E=R.target.value;s(z=>({...z,tokenCap:E?parseInt(E,10):null}))}}),t.tokenCap!=null&&e.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",title:n("settings.projectModels.resetToDefaultNoCap","Reset to default (no cap)"),onClick:()=>s(R=>({...R,tokenCap:null})),style:{whiteSpace:"nowrap"},children:n("settings.projectModels.reset"," Reset ")})]}),e.jsx("small",{children:n("settings.projectModels.automaticallyCompactContextWhenApproachingThisTokenCount","Automatically compact context when approaching this token count. Leave empty for no cap (compact only on overflow errors). Set a number to proactively compact when reaching this token count.")})]}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:n("settings.projectModels.modelLanes","Model Lanes")}),e.jsx("p",{className:"settings-description",children:n("settings.projectModels.overrideGlobalModelSettingsAtTheProjectLevel"," Override global model settings at the project level. Each lane controls a specific AI usage context. Unset lanes inherit from the corresponding global lane. The Project Default Model is the fallback for this project when a more specific lane is unset. ")}),b?e.jsx("div",{className:"settings-empty-state",children:e.jsx(ze,{label:n("settings.projectModels.loadingAvailableModels","Loading available models…")})}):C.length===0?e.jsx("div",{className:"settings-empty-state settings-muted",children:n("settings.projectModels.noModelsAvailableConfigureAuthenticationFirst"," No models available. Configure authentication first. ")}):e.jsx(e.Fragment,{children:ce.map(R=>{const E=A(R),z=j(R),N=E==="overridden",O=de(R);return e.jsxs("div",{className:"form-group",children:[e.jsxs("div",{className:"settings-model-lane-label-row",children:[e.jsx("label",{htmlFor:`${R.laneId}Model`,children:O}),e.jsx("span",{className:`settings-lane-badge ${N?"settings-lane-badge--override":"settings-lane-badge--inherited"}`,title:N?"Explicitly set for this project":"Inherited from global settings",children:N?"Override (Project)":"Inherited (Global)"})]}),e.jsxs("div",{className:"settings-model-lane-control-row",children:[e.jsx("div",{className:"settings-model-lane-control-main",children:e.jsx(Ke,{id:`${R.laneId}Model`,label:O,models:C,value:z,onChange:L=>u(R,L),placeholder:R.laneId==="default"?"Use global default":"Use global",favoriteProviders:h,onToggleFavorite:S,favoriteModels:f,onToggleModelFavorite:w})}),N&&e.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",title:n("settings.projectModels.resetToInheritFromGlobal","Reset to inherit from global"),onClick:()=>d(R),style:{whiteSpace:"nowrap"},children:n("settings.projectModels.reset"," Reset ")})]}),e.jsxs("small",{children:[te(R),n("settings.projectModels.fallsBackTo"," Falls back to: "),R.fallbackOrder,"."]})]},R.laneId)})}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:n("settings.projectModels.defaultWorkflowModelLanes","Default workflow model lanes")}),e.jsxs("p",{className:"settings-description",children:[n("settings.movedStub.modelLanes","Per-phase model lanes (execution, planning, reviewer, and their fallbacks) now live on the workflow."),n("settings.projectModels.theseProjectOverridesApplyToTheActiveDefault"," These project overrides apply to the active default workflow. ")]}),r?D?e.jsx("div",{className:"settings-empty-state",children:e.jsx(ze,{label:n("settings.projectModels.loadingWorkflowModelLanes","Loading workflow model lanes…")})}):C.length===0?e.jsx("div",{className:"settings-empty-state settings-muted",children:n("settings.projectModels.noModelsAvailableConfigureAuthenticationBeforeSelectingWorkflow"," No models available. Configure authentication before selecting workflow model lanes. ")}):e.jsxs(e.Fragment,{children:[H.map(R=>{const E=rd(K,R),z=Object.prototype.hasOwnProperty.call(U,R.providerId)?U[R.providerId]!==null:!!(_?.stored&&(Object.prototype.hasOwnProperty.call(_.stored,R.providerId)||Object.prototype.hasOwnProperty.call(_.stored,R.modelId))),N=ve[R.providerId]?.message??ve[R.modelId]?.message;return e.jsxs("div",{className:"form-group","data-testid":`workflow-model-lane-${R.id}`,children:[e.jsxs("div",{className:"settings-model-lane-label-row",children:[e.jsx("label",{htmlFor:`workflow-${R.id}-model`,children:R.label}),e.jsx("span",{className:`settings-lane-badge ${z?"settings-lane-badge--override":"settings-lane-badge--inherited"}`,title:z?"Explicitly set for this project workflow":"Inherited from workflow defaults",children:z?"Override (Project)":"Inherited (Workflow)"})]}),e.jsxs("div",{className:"settings-model-lane-control-row",children:[e.jsx("div",{className:"settings-model-lane-control-main",children:e.jsx(Ke,{id:`workflow-${R.id}-model`,label:R.label,models:C,value:E,onChange:O=>P(R,O),placeholder:n("settings.projectModels.useWorkflowDefault","Use workflow default"),defaultOptionLabel:"Use workflow default",favoriteProviders:h,onToggleFavorite:S,favoriteModels:f,onToggleModelFavorite:w})}),z&&e.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",title:n("settings.projectModels.resetToInheritFromWorkflow","Reset to inherit from workflow"),onClick:()=>F(R),style:{whiteSpace:"nowrap"},children:n("settings.projectModels.reset"," Reset ")})]}),e.jsx("small",{children:R.help}),N?e.jsx("small",{className:"settings-error","data-testid":`workflow-model-lane-error-${R.id}`,children:N}):null]},R.id)}),m?e.jsx("div",{className:"settings-model-lane-actions","aria-label":n("settings.projectModels.defaultWorkflowModelLaneActions","Default workflow model lane actions"),children:e.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",onClick:m,children:n("settings.projectModels.advancedWorkflowPolicy"," Advanced workflow policy ")})}):null]}):e.jsx("div",{className:"settings-empty-state settings-muted",children:n("settings.projectModels.openAProjectToEditWorkflowModelLanes","Open a project to edit workflow model lanes.")}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:n("settings.projectModels.modelPresets","Model Presets")}),e.jsxs("div",{className:"form-group settings-model-presets",children:[e.jsx("label",{children:n("settings.projectModels.configuredPresets","Configured presets")}),W.length===0?e.jsx("div",{className:"settings-empty-state settings-muted",children:n("settings.projectModels.noPresetsConfiguredYet","No presets configured yet.")}):e.jsx("div",{className:"settings-preset-list",children:W.map(R=>{const E=_l(R),z=`${E.executorValue||"default"} / ${E.validatorValue||"default"}`;return e.jsxs("div",{className:"settings-preset-item",children:[e.jsxs("div",{className:"settings-preset-item-meta",children:[e.jsx("strong",{children:R.name}),e.jsx("span",{className:"settings-muted settings-preset-summary",children:z})]}),e.jsxs("div",{className:"settings-preset-item-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>{x(R.id),B({...R})},children:n("settings.projectModels.edit"," Edit ")}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:async()=>{V.has(R.id)&&!await Y({title:n("settings.models.deletePresetTitle","Delete Preset"),message:n("settings.models.deletePresetMessage",'Preset "{{name}}" is used in auto-selection. Delete it anyway?',{name:R.name}),danger:!0})||(s(N=>({...N,modelPresets:(N.modelPresets||[]).filter(O=>O.id!==R.id),defaultPresetBySize:Object.fromEntries(Object.entries(N.defaultPresetBySize||{}).filter(([,O])=>O!==R.id))})),I===R.id&&(x(null),B(null)))},children:n("settings.projectModels.delete"," Delete ")})]})]},R.id)})}),v?null:e.jsx("div",{className:"settings-preset-actions",children:e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>{x(null),B({id:"",name:"",executorProvider:void 0,executorModelId:void 0,validatorProvider:void 0,validatorModelId:void 0})},children:n("settings.projectModels.addPreset"," Add Preset ")})})]}),v?e.jsxs("div",{className:"form-group settings-preset-editor",children:[e.jsx("label",{children:n("settings.projectModels.presetEditor","Preset editor")}),e.jsxs("div",{className:"settings-preset-editor-fields",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"preset-name",children:n("settings.projectModels.name","Name")}),e.jsx("input",{id:"preset-name",type:"text",value:v.name,onChange:R=>{const E=R.target.value;B(z=>z&&{...z,name:E})}})]}),C.length===0?e.jsx("small",{children:n("settings.projectModels.noModelsAvailableConfigureAuthenticationFirst2","No models available. Configure authentication first.")}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"preset-executor-model",children:n("settings.projectModels.executorModel","Executor model")}),e.jsx(Ke,{id:"preset-executor-model",label:"Preset executor model",models:C,value:v.executorProvider&&v.executorModelId?`${v.executorProvider}/${v.executorModelId}`:"",onChange:R=>{if(!R){B(z=>z&&{...z,executorProvider:void 0,executorModelId:void 0});return}const E=R.indexOf("/");B(z=>z&&{...z,executorProvider:R.slice(0,E),executorModelId:R.slice(E+1)})},placeholder:n("settings.projectModels.useDefault","Use default"),favoriteProviders:h,onToggleFavorite:S,favoriteModels:f,onToggleModelFavorite:w})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"preset-validator-model",children:n("settings.projectModels.reviewerModel","Reviewer model")}),e.jsx(Ke,{id:"preset-validator-model",label:"Preset reviewer model",models:C,value:v.validatorProvider&&v.validatorModelId?`${v.validatorProvider}/${v.validatorModelId}`:"",onChange:R=>{if(!R){B(z=>z&&{...z,validatorProvider:void 0,validatorModelId:void 0});return}const E=R.indexOf("/");B(z=>z&&{...z,validatorProvider:R.slice(0,E),validatorModelId:R.slice(E+1)})},placeholder:n("settings.projectModels.useDefault","Use default"),favoriteProviders:h,onToggleFavorite:S,favoriteModels:f,onToggleModelFavorite:w})]})]})]}),e.jsxs("div",{className:"modal-actions settings-preset-editor-actions",children:[e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:k,children:n("settings.models.savePreset","Save preset")}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>{x(null),B(null)},children:n("settings.actions.cancel","Cancel")})]})]}):null,e.jsx("div",{className:"form-group settings-preset-auto-select",children:e.jsxs("label",{htmlFor:"autoSelectModelPreset",className:"checkbox-label",children:[e.jsx("input",{id:"autoSelectModelPreset",type:"checkbox",checked:t.autoSelectModelPreset||!1,onChange:R=>s(E=>({...E,autoSelectModelPreset:R.target.checked}))}),n("settings.projectModels.autoSelectPresetBasedOnTaskSize"," Auto-select preset based on task size ")]})}),t.autoSelectModelPreset?e.jsx("div",{className:"settings-preset-size-grid",children:["S","M","L"].map(R=>e.jsxs("div",{className:"form-group settings-preset-size-row",children:[e.jsx("label",{htmlFor:`preset-size-${R}`,children:R==="S"?"Small tasks (S):":R==="M"?"Medium tasks (M):":"Large tasks (L):"}),e.jsxs("select",{id:`preset-size-${R}`,value:t.defaultPresetBySize?.[R]||"",onChange:E=>{const z=E.target.value||void 0;s(N=>({...N,defaultPresetBySize:{...N.defaultPresetBySize||{},[R]:z}}))},children:[e.jsx("option",{value:"",children:n("settings.projectModels.noPreset","No preset")}),J.map(E=>e.jsx("option",{value:E.id,children:E.name},E.id))]})]},R))}):null,e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:n("settings.projectModels.aITitleAndGitCommitMessageSummarization"," AI Title and Git Commit Message Summarization ")}),e.jsx("p",{className:"settings-description",children:n("settings.projectModels.configuresTheModelUsedForTwoShortSummary"," Configures the model used for two short-summary jobs: auto-generating task titles from long descriptions, and generating merge commit summaries from step commits and diff stats. ")}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"autoSummarizeTitles",className:"checkbox-label",children:[e.jsx("input",{id:"autoSummarizeTitles",type:"checkbox",checked:t.autoSummarizeTitles||!1,onChange:R=>s(E=>({...E,autoSummarizeTitles:R.target.checked}))}),n("settings.projectModels.autoSummarizeLongDescriptionsAsTitles"," Auto-summarize long descriptions as titles ")]}),e.jsx("small",{children:n("settings.projectModels.whenEnabledTasksCreatedWithoutATitleBut"," When enabled, tasks created without a title but with descriptions over 200 characters will automatically get an AI-generated title (max 60 characters). The same model is also used to generate fallback merge commit message bodies when the branch's commit log is empty (e.g. squash merges with no unique commits), and GitHub tracking issue titles when a tracked task has no title yet. ")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"useAiMergeCommitSummary",className:"checkbox-label",children:[e.jsx("input",{id:"useAiMergeCommitSummary",type:"checkbox",checked:t.useAiMergeCommitSummary||!1,onChange:R=>s(E=>({...E,useAiMergeCommitSummary:R.target.checked}))}),n("settings.projectModels.aIMergeCommitSummaries"," AI merge commit summaries ")]}),e.jsx("small",{children:n("settings.projectModels.whenEnabledMergeCommitMessagesIncludeAnAI"," When enabled, merge commit messages include an AI-generated subject plus body summary (narrative + bullets + diff-stat) instead of just listing step commit subjects. Uses the title summarization model. ")})]}),(t.autoSummarizeTitles||t.useAiMergeCommitSummary||t.githubTrackingEnabledByDefault||!1)&&e.jsx("p",{className:"settings-description",children:n("settings.movedStub.summarizerModelInline","The summarization model lane above controls title auto-summarization, merge commit summaries, GitHub tracking titles, and PR metadata generation.")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"prTitlePromptInstructions",children:n("settings.projectModels.prTitlePromptInstructions","PR title prompt guidance")}),e.jsx("textarea",{id:"prTitlePromptInstructions",value:t.prTitlePromptInstructions||"",onChange:R=>s(E=>({...E,prTitlePromptInstructions:R.target.value})),rows:3,placeholder:n("settings.projectModels.prTitlePromptInstructionsPlaceholder","Example: Use conventional-commit style and keep titles under 72 characters.")}),e.jsx("small",{children:n("settings.projectModels.prTitlePromptInstructionsHelp","Guides the AI-generated Create PR title. Leave blank to use the default PR metadata prompt.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"prDescriptionPromptInstructions",children:n("settings.projectModels.prDescriptionPromptInstructions","PR description prompt guidance")}),e.jsx("textarea",{id:"prDescriptionPromptInstructions",value:t.prDescriptionPromptInstructions||"",onChange:R=>s(E=>({...E,prDescriptionPromptInstructions:R.target.value})),rows:4,placeholder:n("settings.projectModels.prDescriptionPromptInstructionsPlaceholder","Example: Emphasize operator-facing behavior and list verification commands exactly.")}),e.jsx("small",{children:n("settings.projectModels.prDescriptionPromptInstructionsHelp","Guides the AI-generated Create PR summary, changes, and testing sections. Leave blank to use the default PR metadata prompt.")})]})]})}const kn=1440*60*1e3,ld=2;function wn({title:a,caption:t,badgeLabel:s,scope:c}){return e.jsxs("div",{className:"settings-scope-group",children:[e.jsxs("div",{className:"settings-scope-group-header",children:[e.jsx("h5",{className:"settings-section-heading",children:a}),e.jsx("span",{className:`settings-scope-badge settings-scope-badge--${c}`,children:s})]}),e.jsx("small",{className:"settings-scope-caption",children:t})]})}function od({scopeBanner:a,form:t,setForm:s,globalMaxConcurrent:c,concurrencyLoading:r=!1,onGlobalMaxConcurrentChange:m,onOverlapIgnorePathChange:i,onOpenOverlapPathPicker:n,onRemoveOverlapIgnorePath:p,onAddOverlapIgnorePath:A,onOpenWorkflowSettings:j}){const{t:u}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:u("settings.scheduling.scheduling","Scheduling")}),e.jsx(wn,{scope:"global",title:u("settings.scheduling.scopeGlobalTitle","Global — applies to all projects"),caption:u("settings.scheduling.scopeGlobalCaption","Shared by every project on this machine."),badgeLabel:u("settings.scheduling.scopeBadgeGlobal","Global")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"globalMaxConcurrent",children:u("settings.scheduling.globalMaxConcurrent","Global Max Concurrent")}),e.jsx("input",{id:"globalMaxConcurrent",type:"number",min:0,max:1e4,disabled:r,value:c??"",onChange:d=>{const C=d.target.value;m(C===""?void 0:Number(C))}}),e.jsx("small",{className:"form-text text-muted",children:u("settings.scheduling.maximumConcurrentAgentsAcrossAllProjects","Maximum concurrent agents across all projects")})]}),e.jsx("div",{className:"settings-section-divider"}),e.jsx(wn,{scope:"project",title:u("settings.scheduling.scopeProjectTitle","This project"),caption:u("settings.scheduling.scopeProjectCaption","Only affects the currently selected project."),badgeLabel:u("settings.scheduling.scopeBadgeProject","Project")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"maxConcurrent",children:u("settings.scheduling.maxConcurrentTasks","Max Concurrent Tasks")}),e.jsx("input",{id:"maxConcurrent",type:"number",min:1,max:10,disabled:r,value:t.maxConcurrent??"",onChange:d=>{const C=d.target.value;s(b=>({...b,maxConcurrent:C===""?void 0:Number(C)}))}})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"maxTriageConcurrent",children:u("settings.scheduling.maxTriageConcurrent","Max Triage Concurrent")}),e.jsx("input",{id:"maxTriageConcurrent",type:"number",min:1,max:10,disabled:r,value:t.maxTriageConcurrent??"",onChange:d=>{const C=d.target.value;s(b=>({...b,maxTriageConcurrent:C===""?void 0:Number(C)}))}}),e.jsx("small",{children:u("settings.scheduling.maximumConcurrentPlanningAgents","Maximum concurrent planning agents")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"pollIntervalMs",children:u("settings.scheduling.pollIntervalMs","Poll Interval (ms)")}),e.jsx("input",{id:"pollIntervalMs",type:"number",min:5e3,step:1e3,value:t.pollIntervalMs??"",onChange:d=>{const C=d.target.value;s(b=>({...b,pollIntervalMs:C===""?void 0:Number(C)}))}})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"heartbeatScopeDiscipline",children:u("settings.scheduling.heartbeatScopeDiscipline","Heartbeat Scope Discipline")}),e.jsxs("select",{id:"heartbeatScopeDiscipline",className:"select",value:t.heartbeatScopeDiscipline??"strict",onChange:d=>{s(C=>({...C,heartbeatScopeDiscipline:d.target.value}))},children:[e.jsx("option",{value:"strict",children:u("settings.scheduling.strictDefault","Strict (default)")}),e.jsx("option",{value:"lite",children:u("settings.scheduling.lite","Lite")}),e.jsx("option",{value:"off",children:u("settings.scheduling.off","Off")})]}),e.jsx("small",{children:u("settings.scheduling.strictCoordinationFocusedHigherPerTickTokensLite","Strict — coordination-focused; higher per-tick tokens. Lite — pre-2026-05-11 behavior. Off — minimal procedure.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"engineerBacklogAutoClaim",className:"checkbox-label",children:[e.jsx("input",{id:"engineerBacklogAutoClaim",type:"checkbox",checked:t.engineerBacklogAutoClaim===!0,onChange:d=>s(C=>({...C,engineerBacklogAutoClaim:d.target.checked}))}),u("settings.scheduling.letEngineerAgentsAutoClaimBacklogTasks"," Let engineer agents auto-claim backlog tasks ")]}),e.jsx("small",{children:u("settings.scheduling.backlogNoTaskAutoClaimIsExecutorOnly","Backlog/no-task auto-claim is executor-only by default. Enable to let engineer-role agents auto-claim unowned backlog tasks; explicit routing and delegation are unchanged. Default: off.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"taskStuckTimeoutMs",children:u("settings.scheduling.stuckTaskTimeoutMinutes","Stuck Task Timeout (minutes)")}),e.jsx("input",{id:"taskStuckTimeoutMs",type:"number",min:1,step:1,value:t.taskStuckTimeoutMs?Math.round(t.taskStuckTimeoutMs/6e4):"",onChange:d=>{const C=d.target.value,b=Number(C);s(h=>({...h,taskStuckTimeoutMs:C&&b>0?b*6e4:void 0}))}}),e.jsx("small",{children:u("settings.scheduling.timeoutInMinutesForDetectingStuckTasksWhen","Timeout in minutes for detecting stuck tasks. When a task's agent session shows no activity for longer than this duration, the task is terminated and retried. Leave empty to disable. Suggested: 10.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"staleHighFanoutBlockerAgeThresholdMs",children:u("settings.scheduling.staleHighFanOutEscalationHours","Stale High Fan-out Escalation (hours)")}),e.jsx("input",{id:"staleHighFanoutBlockerAgeThresholdMs",type:"number",min:1,step:1,value:t.staleHighFanoutBlockerAgeThresholdMs?Math.round(t.staleHighFanoutBlockerAgeThresholdMs/36e5):"",onChange:d=>{const C=d.target.value,b=Number(C);s(h=>({...h,staleHighFanoutBlockerAgeThresholdMs:C&&b>0?b*36e5:void 0}))}}),e.jsx("small",{children:u("settings.scheduling.escalateHighFanOutBlockersOnlyAfterThey","Escalate high fan-out blockers only after they remain in in-progress or in-review for this many hours (age source: columnMovedAt, fallback updatedAt). Default: 2 hours.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"preserveProgressOnStuckRequeue",className:"checkbox-label",children:[e.jsx("input",{id:"preserveProgressOnStuckRequeue",type:"checkbox",checked:t.preserveProgressOnStuckRequeue!==!1,onChange:d=>s(C=>({...C,preserveProgressOnStuckRequeue:d.target.checked}))}),u("settings.scheduling.preserveStepProgressOnStuckTaskRequeue"," Preserve step progress on stuck-task requeue ")]}),e.jsx("small",{children:u("settings.scheduling.whenTheStuckDetectorKillsAndReQueues","When the stuck detector kills and re-queues a task, keep completed step statuses so the agent can resume from where it left off. Disable to reset every step to pending on each stuck retry. Default: enabled.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"specStalenessEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"specStalenessEnabled",type:"checkbox",checked:t.specStalenessEnabled||!1,onChange:d=>s(C=>({...C,specStalenessEnabled:d.target.checked}))}),u("settings.scheduling.enablePlanStalenessEnforcement"," Enable plan staleness enforcement ")]}),e.jsx("small",{children:u("settings.scheduling.whenEnabledTasksWithStalePlansPROMPTMd","When enabled, tasks with stale plans (PROMPT.md older than the threshold) are automatically sent back to planning for replanning")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"specStalenessMaxAgeMs",children:u("settings.scheduling.staleSpecThresholdHours","Stale Spec Threshold (hours)")}),e.jsx("input",{id:"specStalenessMaxAgeMs",type:"number",min:0,step:1,value:t.specStalenessMaxAgeMs!==void 0?Math.round(t.specStalenessMaxAgeMs/36e5):"",onChange:d=>{const C=d.target.value,b=Number(C);s(h=>({...h,specStalenessMaxAgeMs:C!==""?b*36e5:void 0}))},disabled:!t.specStalenessEnabled}),e.jsx("small",{children:u("settings.scheduling.maximumAgeInHoursBeforeAPlanIs","Maximum age in hours before a plan is considered stale. Default: 6 hours.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"autoArchiveDoneTasksEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"autoArchiveDoneTasksEnabled",type:"checkbox",checked:t.autoArchiveDoneTasksEnabled??!0,onChange:d=>s(C=>({...C,autoArchiveDoneTasksEnabled:d.target.checked}))}),u("settings.scheduling.enableAutomaticTaskArchiving"," Enable automatic task archiving ")]}),e.jsx("small",{children:u("settings.scheduling.completedTasksOlderThanTheThresholdAreMoved","Completed tasks older than the threshold are moved out of the active task database.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"autoArchiveDoneAfterMs",children:u("settings.scheduling.archiveCompletedTasksAfterDays","Archive Completed Tasks After (days)")}),e.jsx("input",{id:"autoArchiveDoneAfterMs",type:"number",min:1,step:1,value:t.autoArchiveDoneAfterMs!==void 0?Math.round(t.autoArchiveDoneAfterMs/kn):ld,onChange:d=>{const C=d.target.value,b=Number(C);s(h=>({...h,autoArchiveDoneAfterMs:C===""?void 0:b*kn}))},disabled:t.autoArchiveDoneTasksEnabled===!1}),e.jsx("small",{children:u("settings.scheduling.numberOfDaysATaskCanStayIn","Number of days a task can stay in Done before it is archived. Default: 2 days (48 hours).")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"archiveAgentLogMode",children:u("settings.scheduling.archiveAgentLog","Archive Agent Log")}),e.jsxs("select",{id:"archiveAgentLogMode",value:t.archiveAgentLogMode??"compact",onChange:d=>s(C=>({...C,archiveAgentLogMode:d.target.value})),disabled:t.autoArchiveDoneTasksEnabled===!1,children:[e.jsx("option",{value:"compact",children:u("settings.scheduling.compactSummaryAndRecentEntries","Compact summary and recent entries")}),e.jsx("option",{value:"none",children:u("settings.scheduling.doNotArchiveAgentLogs","Do not archive agent logs")}),e.jsx("option",{value:"full",children:u("settings.scheduling.fullAgentLog","Full agent log")})]}),e.jsx("small",{children:u("settings.scheduling.compactModeKeepsArchiveSizeLowWhilePreserving","Compact mode keeps archive size low while preserving recent agent activity for context.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"maxStuckKills",children:u("settings.scheduling.maxStuckRetries","Max Stuck Retries")}),e.jsx("input",{id:"maxStuckKills",type:"number",min:1,step:1,value:t.maxStuckKills??"",onChange:d=>{const C=d.target.value,b=Number(C);s(h=>({...h,maxStuckKills:C&&b>0?b:void 0}))}}),e.jsx("small",{children:u("settings.scheduling.maximumStuckDetectorRetriesBeforeATaskIs","Maximum stuck-detector retries before a task is marked failed. Default: 6.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"groupOverlappingFiles",className:"checkbox-label",children:[e.jsx("input",{id:"groupOverlappingFiles",type:"checkbox",checked:t.groupOverlappingFiles,onChange:d=>s(C=>({...C,groupOverlappingFiles:d.target.checked}))}),u("settings.scheduling.serializeTasksWithOverlappingFiles"," Serialize tasks with overlapping files ")]}),e.jsx("small",{children:u("settings.scheduling.whenEnabledTasksThatModifyTheSameFiles","When enabled, tasks that modify the same files are queued serially to avoid merge conflicts")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"ignoreHiddenOverlapPaths",className:"checkbox-label",children:[e.jsx("input",{id:"ignoreHiddenOverlapPaths",type:"checkbox",checked:t.ignoreHiddenOverlapPaths!==!1,onChange:d=>s(C=>({...C,ignoreHiddenOverlapPaths:d.target.checked}))}),u("settings.scheduling.ignoreHiddenDotPathsInOverlapChecks"," Ignore hidden dot paths in overlap checks ")]}),e.jsx("small",{children:u("settings.scheduling.ignoreHiddenDotPathsHelp","When enabled, overlap checks ignore hidden path segments such as .fusion/, .changeset/, .github/, .env, and nested .cache/ directories. Uncheck to restore legacy counting for stricter serialization.")})]}),e.jsxs("div",{className:"form-group settings-overlap-ignore-group",children:[e.jsx("label",{children:u("settings.scheduling.ignoredOverlapPaths","Ignored overlap paths")}),e.jsxs("small",{children:[u("settings.scheduling.optionalFileOrDirectoryPathsToIgnoreWhen"," Optional file or directory paths to ignore when overlap serialization is enabled. Paths are project-relative (for example "),e.jsx("code",{children:"docs/"}),u("settings.scheduling.or"," or "),e.jsx("code",{children:"generated/*"}),u("settings.scheduling.closeParenPeriod",").")]}),e.jsx("div",{className:"settings-overlap-ignore-list",children:(t.overlapIgnorePaths&&t.overlapIgnorePaths.length>0?t.overlapIgnorePaths:[""]).map((d,C)=>e.jsxs("div",{className:"settings-overlap-ignore-row",children:[e.jsxs("div",{className:"settings-overlap-ignore-path-controls",children:[e.jsx("input",{type:"text",value:d,placeholder:u("settings.scheduling.docs","docs/"),onChange:b=>i(C,b.target.value)}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>n(C),"aria-label":`Browse path for ignored overlap entry ${C+1}`,children:u("settings.scheduling.browse"," Browse ")})]}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>p(C),disabled:(t.overlapIgnorePaths??[]).length===0&&C===0,children:u("settings.scheduling.remove"," Remove ")})]},`overlap-ignore-${C}`))}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:A,children:u("settings.scheduling.addIgnoredPath"," Add ignored path ")})]}),e.jsx("div",{className:"settings-section-divider"}),e.jsx("h5",{className:"settings-section-heading",children:u("settings.scheduling.stepExecution","Step Execution")}),e.jsx(ea,{message:u("settings.movedStub.stepExecution","Step execution settings (run steps in new sessions, max parallel steps) now live on the workflow."),onOpenWorkflowSettings:j})]})}function cd({scopeBanner:a,form:t,setForm:s}){const{t:c}=Z("app"),r=t.evalSettings??{},m=r.enabled??!1;return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:c("settings.scheduledEvals.scheduledEvals","Scheduled Evals")}),e.jsx("div",{className:"form-group",children:e.jsxs("label",{htmlFor:"scheduled-evals-enabled",className:"checkbox-label",children:[e.jsx("input",{id:"scheduled-evals-enabled",type:"checkbox",checked:m,onChange:i=>s(n=>({...n,evalSettings:{...n.evalSettings??{},enabled:i.target.checked}}))}),c("settings.scheduledEvals.enableScheduledEvalRunsForThisProject"," Enable scheduled eval runs for this project ")]})}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"scheduled-evals-interval",children:c("settings.scheduledEvals.intervalMs","Interval (ms)")}),e.jsx("input",{id:"scheduled-evals-interval",className:"input",type:"number",min:6e4,max:6048e5,step:1e3,disabled:!m,value:r.intervalMs??864e5,onChange:i=>s(n=>({...n,evalSettings:{...n.evalSettings??{},intervalMs:i.target.value===""?void 0:Number(i.target.value)}}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"scheduled-evals-provider",children:c("settings.scheduledEvals.evaluatorProvider","Evaluator Provider")}),e.jsx("input",{id:"scheduled-evals-provider",className:"input",value:r.evaluatorProvider??"",onChange:i=>s(n=>({...n,evalSettings:{...n.evalSettings??{},evaluatorProvider:i.target.value.trim()===""?void 0:i.target.value}})),placeholder:c("settings.scheduledEvals.openai","openai")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"scheduled-evals-model",children:c("settings.scheduledEvals.evaluatorModel","Evaluator Model")}),e.jsx("input",{id:"scheduled-evals-model",className:"input",value:r.evaluatorModelId??"",onChange:i=>s(n=>({...n,evalSettings:{...n.evalSettings??{},evaluatorModelId:i.target.value.trim()===""?void 0:i.target.value}})),placeholder:c("settings.scheduledEvals.gpt5","gpt-5")}),e.jsx("small",{className:"form-text text-muted",children:c("settings.scheduledEvals.leaveProviderAndModelBlankToInheritThe"," Leave provider and model blank to inherit the project validator lane model settings. ")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"scheduled-evals-follow-up-policy",children:c("settings.scheduledEvals.followUpPolicy","Follow-up Policy")}),e.jsxs("select",{id:"scheduled-evals-follow-up-policy",className:"select",disabled:!m,value:r.followUpPolicy??"suggest-only",onChange:i=>s(n=>({...n,evalSettings:{...n.evalSettings??{},followUpPolicy:i.target.value}})),children:[e.jsx("option",{value:"disabled",children:c("settings.scheduledEvals.disabled","Disabled")}),e.jsx("option",{value:"suggest-only",children:c("settings.scheduledEvals.suggestOnly","Suggest only")}),e.jsx("option",{value:"auto-create",children:c("settings.scheduledEvals.autoCreateTasks","Auto-create tasks")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"scheduled-evals-retention-days",children:c("settings.scheduledEvals.retentionDays","Retention (days)")}),e.jsx("input",{id:"scheduled-evals-retention-days",className:"input",type:"number",min:1,max:365,step:1,disabled:!m,value:r.retentionDays??30,onChange:i=>s(n=>({...n,evalSettings:{...n.evalSettings??{},retentionDays:i.target.value===""?void 0:Number(i.target.value)}}))})]})]})}function dd(a,t){return a==="online"?t("settings.nodeRouting.statusOnline","Online"):a==="connecting"?t("settings.nodeRouting.statusConnecting","Connecting"):a==="error"?t("settings.nodeRouting.statusError","Error"):t("settings.nodeRouting.statusOffline","Offline")}function ud({scopeBanner:a,form:t,setForm:s,nodes:c}){const{t:r}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:r("settings.nodeRouting.nodeRouting","Node Routing")}),e.jsx("p",{className:"settings-section-description",children:r("settings.nodeRouting.configureHowTasksAreRoutedToExecutionNodes","Configure how tasks are routed to execution nodes.")}),e.jsx("p",{className:"settings-node-routing-note",children:r("settings.nodeRouting.theseSettingsApplyAtTheProjectLevel","These settings apply at the project level.")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"defaultNodeId",children:r("settings.nodeRouting.defaultExecutionNode","Default Execution Node")}),e.jsxs("select",{id:"defaultNodeId",className:"select",value:typeof t.defaultNodeId=="string"?t.defaultNodeId:"",onChange:m=>{const i=m.target.value;s(n=>({...n,defaultNodeId:i||void 0}))},children:[e.jsx("option",{value:"",children:r("settings.nodeRouting.localExecutionNoDefaultNode","Local execution (no default node)")}),c.map(m=>e.jsxs("option",{value:m.id,children:[m.name," (",dd(m.status,r),")"]},m.id))]}),(()=>{const m=c.find(i=>i.id===t.defaultNodeId);return m?e.jsxs("div",{className:"settings-node-status",children:[e.jsx("span",{children:r("settings.nodeRouting.selectedNode","Selected node:")}),e.jsx(Wl,{status:m.status,showLabel:!0})]}):null})(),e.jsx("small",{children:r("settings.nodeRouting.usedWhenATaskHasNoNodeOverride","Used when a task has no node override. Node status is shown for safer routing selection.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"unavailableNodePolicy",children:r("settings.nodeRouting.unavailableNodePolicy","Unavailable Node Policy")}),e.jsxs("select",{id:"unavailableNodePolicy",className:"select",value:t.unavailableNodePolicy==="fallback-local"?"fallback-local":"block",onChange:m=>s(i=>({...i,unavailableNodePolicy:m.target.value})),children:[e.jsx("option",{value:"block",children:r("settings.nodeRouting.blockExecution","Block execution")}),e.jsx("option",{value:"fallback-local",children:r("settings.nodeRouting.fallBackToLocal","Fall back to local")})]})]})]})}function md({scopeBanner:a,form:t,setForm:s,gitRemotes:c,worktrunkInstall:r,worktrunkInstallVerified:m,onOpenWorktreesDirPicker:i,onWorktreeCopyFileChange:n,onRemoveWorktreeCopyFile:p,onAddWorktreeCopyFile:A,onOpenWorktreeCopyFilePicker:j,onOpenApprovals:u}){const{t:d}=Z("app"),C=(t.worktreeCopyFiles?.length??0)>0?t.worktreeCopyFiles??[]:[""];return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:d("settings.worktrees.worktrees","Worktrees")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"maxWorktrees",children:d("settings.worktrees.maxWorktrees","Max Worktrees")}),e.jsx("input",{id:"maxWorktrees",type:"number",min:1,max:20,value:t.maxWorktrees??"",onChange:b=>{const h=b.target.value;s(f=>({...f,maxWorktrees:h===""?void 0:Number(h)}))}}),e.jsx("small",{children:d("settings.worktrees.limitsTotalGitWorktreesIncludingInReviewTasks","Limits total git worktrees including in-review tasks")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"worktreeInitCommand",children:d("settings.worktrees.worktreeInitCommand","Worktree Init Command")}),e.jsx("input",{id:"worktreeInitCommand",type:"text",placeholder:d("settings.worktrees.pnpmInstallFrozenLockfile","pnpm install --frozen-lockfile"),value:t.worktreeInitCommand||"",onChange:b=>s(h=>({...h,worktreeInitCommand:b.target.value}))}),e.jsx("small",{children:d("settings.worktrees.shellCommandToRunInEachNewWorktree","Shell command to run in each new worktree after creation")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"recycleWorktrees",className:"checkbox-label",children:[e.jsx("input",{id:"recycleWorktrees",type:"checkbox",checked:t.recycleWorktrees,onChange:b=>s(h=>({...h,recycleWorktrees:b.target.checked}))}),d("settings.worktrees.recycleWorktrees"," Recycle worktrees ")]}),e.jsx("small",{children:d("settings.worktrees.offByDefaultOptInWhenEnabledCompleted","Off by default (opt-in). When enabled, completed task worktrees are returned to an idle pool instead of being deleted, preserving build caches for faster startup")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"showWorktreeGrouping",className:"checkbox-label",children:[e.jsx("input",{id:"showWorktreeGrouping",type:"checkbox",checked:t.showWorktreeGrouping===!0,onChange:b=>s(h=>({...h,showWorktreeGrouping:b.target.checked}))}),d("settings.worktrees.showWorktreeGrouping"," Show worktree grouping on the board ")]}),e.jsx("small",{children:d("settings.worktrees.showWorktreeGroupingHelp","Off by default. When enabled, WIP and processing columns always group tasks by worktree and show worktree names, including workflow-mode processing columns.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:d("settings.worktrees.filesToCopyIntoNewWorktrees","Files to copy into new worktrees")}),e.jsx("div",{className:"settings-overlap-ignore-list","data-testid":"worktree-copy-files-list",children:C.map((b,h)=>e.jsxs("div",{className:"settings-overlap-ignore-row",children:[e.jsxs("div",{className:"settings-overlap-ignore-path-controls",children:[e.jsx("input",{id:`worktreeCopyFile-${h}`,type:"text",className:"input",placeholder:d("settings.worktrees.copyFilePlaceholder",".env"),value:b,onChange:f=>n(h,f.target.value),"aria-label":d("settings.worktrees.copyFilePathLabel","File to copy into new worktrees")}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>j(h),"aria-label":d("settings.worktrees.browseCopyFile","Browse file to copy into new worktrees"),children:d("settings.worktrees.browse"," Browse ")})]}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>p(h),"aria-label":d("settings.worktrees.removeCopyFile","Remove copied worktree file"),children:d("settings.worktrees.remove","Remove")})]},h))}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:A,children:d("settings.worktrees.addCopyFile","Add file")}),e.jsx("small",{children:d("settings.worktrees.copyFilesHelp","Optional. Repository-root-relative regular files are copied into fresh or pooled task worktrees before init commands run. Missing files or directories are skipped without exposing contents.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"executorAllowSiblingBranchRename",className:"checkbox-label",children:[e.jsx("input",{id:"executorAllowSiblingBranchRename",type:"checkbox",checked:t.executorAllowSiblingBranchRename===!0,onChange:b=>s(h=>({...h,executorAllowSiblingBranchRename:b.target.checked}))}),d("settings.worktrees.allowSilentSiblingBranchRenameDuringExecutorConflicts"," Allow silent sibling branch rename during executor conflicts ")]}),e.jsxs("small",{children:[d("settings.worktrees.discouragedThisRestoresTheLegacyBehaviorWhereA"," Discouraged. This restores the legacy behavior where a live "),e.jsx("code",{children:"fusion/<task-id>"}),d("settings.worktrees.branchCollisionSilentlyForksWorkOntoSiblingBranches"," branch collision silently forks work onto sibling branches like "),e.jsx("code",{children:"-2"}),d("settings.worktrees.andCanHidePriorCommitsFromTheDefault"," and can hide prior commits from the default recovery flow. ")]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"worktreeNaming",children:d("settings.worktrees.worktreeNamingStyle","Worktree Naming Style")}),e.jsxs("select",{id:"worktreeNaming",value:t.worktreeNaming||"random",onChange:b=>s(h=>({...h,worktreeNaming:b.target.value})),disabled:t.recycleWorktrees,children:[e.jsx("option",{value:"random",children:d("settings.worktrees.randomNamesEGSwiftFalcon","Random names (e.g., swift-falcon)")}),e.jsx("option",{value:"task-id",children:d("settings.worktrees.taskIDEGFN042","Task ID (e.g., FN-042)")}),e.jsx("option",{value:"task-title",children:d("settings.worktrees.taskTitleEGFixLoginBug","Task title (e.g., fix-login-bug)")})]}),e.jsx("small",{children:t.recycleWorktrees?"Naming style is not applicable when recycling worktrees — pooled worktrees retain their existing names":"How to name fresh worktree directories. Only applies when recycling is off."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"worktreesDir",children:d("settings.worktrees.worktreesDirectory","Worktrees Directory")}),e.jsxs("div",{className:"settings-overlap-ignore-path-controls",children:[e.jsx("input",{id:"worktreesDir",type:"text",placeholder:d("settings.worktrees.defaultsToWorktreesLeaveEmptyUnlessOverriding","Defaults to .worktrees — leave empty unless overriding"),value:t.worktreesDir||"",disabled:t.worktrunk?.enabled===!0,onChange:b=>s(h=>({...h,worktreesDir:b.target.value}))}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:i,"aria-label":d("settings.worktrees.browseWorktreesDirectory","Browse worktrees directory"),disabled:t.worktrunk?.enabled===!0,children:d("settings.worktrees.browse"," Browse ")})]}),e.jsx("small",{children:t.worktrunk?.enabled===!0?"Disabled because Worktrunk integration is enabled — worktrunk manages the worktree directory layout. Disable worktrunk integration to use a custom directory.":e.jsxs(e.Fragment,{children:[d("settings.worktrees.optionalSupports"," Optional. Supports "),e.jsx("code",{children:"~"}),d("settings.worktrees.and"," and "),e.jsx("code",{children:"{repo}"}),d("settings.worktrees.defaultsTo",". Defaults to "),e.jsx("code",{children:"<projectRoot>/.worktrees"}),d("settings.worktrees.whenUnsetOnlyAffectsNewlyCreatedWorktrees"," when unset. Only affects newly-created worktrees. ")]})})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"worktreeRebaseBeforeMerge",className:"checkbox-label",children:[e.jsx("input",{id:"worktreeRebaseBeforeMerge",type:"checkbox",checked:t.worktreeRebaseBeforeMerge!==!1,onChange:b=>s(h=>({...h,worktreeRebaseBeforeMerge:b.target.checked}))}),d("settings.worktrees.rebaseFromRemoteBeforeMerge"," Rebase from remote before merge ")]}),e.jsx("small",{children:d("settings.worktrees.whenEnabledTheMergerFetchesFromTheConfigured","When enabled, the merger fetches from the configured remote and rebases the task branch onto the latest default-branch tip before merging — catching concurrent pushes from other collaborators or fusion workers. Any conflicts the rebase surfaces flow into the existing smart/AI resolve pipeline.")})]}),t.worktreeRebaseBeforeMerge!==!1&&e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"worktreeRebaseRemote",children:d("settings.worktrees.rebaseRemote","Rebase Remote")}),e.jsxs("select",{id:"worktreeRebaseRemote",value:t.worktreeRebaseRemote??"",onChange:b=>s(h=>({...h,worktreeRebaseRemote:b.target.value||void 0})),children:[e.jsx("option",{value:"",children:d("settings.worktrees.useGitDefault","Use git default")}),c.map(b=>e.jsxs("option",{value:b.name,children:[b.name," (",b.fetchUrl,")"]},b.name))]}),e.jsxs("small",{children:[d("settings.worktrees.whichRemoteToFetchForThePreMerge",' Which remote to fetch for the pre-merge rebase. "Use git default" falls back to the remote configured for the default branch (typically '),e.jsx("code",{children:"origin"}),d("settings.worktrees.closeParenPeriod",").")]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"worktreeRebaseLocalBase",className:"checkbox-label",children:[e.jsx("input",{id:"worktreeRebaseLocalBase",type:"checkbox",checked:t.worktreeRebaseLocalBase!==!1,onChange:b=>s(h=>({...h,worktreeRebaseLocalBase:b.target.checked}))}),d("settings.worktrees.alsoRebaseOntoLocalDefaultBranchHEAD"," Also rebase onto local default-branch HEAD ")]}),e.jsx("small",{children:d("settings.worktrees.inAdditionToTheRemoteRebaseAboveAlso"," In addition to the remote rebase above, also rebase the task branch onto the local default-branch HEAD (rootDir). This catches sibling tasks that merged locally but haven't been pushed yet — without it, two concurrent tasks where one deletes code can have the other silently re-introduce it via the fallback strategy. Enabled by default; only disable if it causes issues with your workflow. ")})]}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:d("settings.worktrees.worktrunkIntegration","Worktrunk integration")}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"worktrunkEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"worktrunkEnabled",type:"checkbox",checked:t.worktrunk?.enabled===!0,disabled:!m&&t.worktrunk?.enabled!==!0,onChange:b=>s(h=>({...h,worktrunk:{enabled:b.target.checked,binaryPath:h.worktrunk?.binaryPath??"",onFailure:h.worktrunk?.onFailure??"fail"}}))}),d("settings.worktrees.enableWorktrunkIntegration"," Enable worktrunk integration ")]}),e.jsxs("small",{children:[d("settings.worktrees.disabledByDefaultOptInWhenEnabledFusion"," Disabled by default (opt-in). When enabled, Fusion shells out to "),e.jsx("code",{children:"worktrunk"}),d("settings.worktrees.forWorktreeCreateSyncPruneAndRemoveOperations"," for worktree create, sync, prune, and remove operations and follows worktrunk's directory layout. ")]}),!m&&t.worktrunk?.enabled!==!0&&e.jsx("small",{className:"settings-muted",children:d("settings.worktrees.installTheWorktrunkBinaryBelowToEnableThis","Install the worktrunk binary below to enable this integration.")})]}),e.jsxs("div",{className:"form-group","data-testid":"worktrunk-install-affordance",children:[r.status==="installed"&&e.jsxs("small",{className:"settings-muted",children:[d("settings.worktrees.worktrunk"," worktrunk "),r.version??"",d("settings.worktrees.installedAt"," installed at "),r.installPath??"~/.fusion/bin/worktrunk"]}),(r.status==="missing"||r.status==="installing")&&e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>void r.requestInstall(),disabled:r.requesting||r.status==="installing",children:d("settings.worktrees.installWorktrunk","Install worktrunk binary")}),e.jsx("small",{className:"settings-muted",children:d("settings.worktrees.enableWorktrunkAndRequestApprovalToInstallThe","Enable worktrunk and request approval to install the pinned release.")})]}),r.status==="pending-approval"&&e.jsxs(e.Fragment,{children:[e.jsx("small",{className:"settings-muted",children:d("settings.worktrees.awaitingApproval","Awaiting approval — open Approvals to continue.")}),e.jsx("button",{type:"button",className:"btn btn-secondary",onClick:()=>u?.(r.pendingApprovalId),children:d("settings.worktrees.openApprovals","Open Approvals")})]}),(r.status==="denied"||r.status==="failed")&&e.jsxs(e.Fragment,{children:[e.jsx("small",{style:{color:"var(--color-error)"},children:r.error??"Worktrunk install failed."}),e.jsx("button",{type:"button",className:"btn btn-secondary",onClick:()=>void r.requestInstall(),children:d("settings.worktrees.tryAgain","Try again")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"worktrunkBinaryPath",children:d("settings.worktrees.worktrunkBinaryPath","Worktrunk binary path")}),e.jsx("input",{id:"worktrunkBinaryPath",type:"text",className:"input",placeholder:d("settings.worktrees.autoDetectFusionBinWorktrunkOrPATH","auto-detect (~/.fusion/bin/worktrunk or $PATH)"),value:t.worktrunk?.binaryPath??"",disabled:t.worktrunk?.enabled!==!0,onChange:b=>s(h=>({...h,worktrunk:{enabled:h.worktrunk?.enabled===!0,binaryPath:b.target.value,onFailure:h.worktrunk?.onFailure??"fail"}}))}),e.jsx("small",{children:d("settings.worktrees.optionalLeaveBlankToAutoResolveFusionWill","Optional. Leave blank to auto-resolve; Fusion will offer to install on first use.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"worktrunkOnFailure",children:d("settings.worktrees.worktrunkFailureBehavior","Worktrunk failure behavior")}),e.jsxs("select",{id:"worktrunkOnFailure",className:"select",value:t.worktrunk?.onFailure??"fail",disabled:t.worktrunk?.enabled!==!0,onChange:b=>s(h=>({...h,worktrunk:{enabled:h.worktrunk?.enabled===!0,binaryPath:h.worktrunk?.binaryPath??"",onFailure:b.target.value}})),children:[e.jsx("option",{value:"fail",children:d("settings.worktrees.failAndPauseTheTaskDefault","Fail and pause the task (default)")}),e.jsx("option",{value:"fallback-native",children:d("settings.worktrees.fallBackToFusionsNativeWorktreeBackend","Fall back to Fusion's native worktree backend")})]}),e.jsxs("small",{children:[e.jsx("code",{children:"fail"}),d("settings.worktrees.stopsOnWorktrunkErrorsForExplicitOperatorRecovery"," stops on worktrunk errors for explicit operator recovery; "),e.jsx("code",{children:"fallback-native"}),d("settings.worktrees.keepsProgressMovingBySwitchingToFusionApos"," keeps progress moving by switching to Fusion's built-in worktree backend. ")]})]})]})}function pd({scopeBanner:a,form:t,setForm:s}){const{t:c}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:c("settings.commands.commands","Commands")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"testCommand",children:c("settings.commands.testCommand","Test Command")}),e.jsx("input",{id:"testCommand",type:"text",placeholder:c("settings.commands.eGPnpmTest","e.g. pnpm test"),value:t.testCommand||"",onChange:r=>s(m=>({...m,testCommand:r.target.value||void 0}))}),e.jsx("small",{children:c("settings.commands.commandUsedToRunTestsInjectedIntoGenerated","Command used to run tests — injected into generated task specs")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"buildCommand",children:c("settings.commands.buildCommand","Build Command")}),e.jsx("input",{id:"buildCommand",type:"text",placeholder:c("settings.commands.eGPnpmBuild","e.g. pnpm build"),value:t.buildCommand||"",onChange:r=>s(m=>({...m,buildCommand:r.target.value||void 0}))}),e.jsx("small",{children:c("settings.commands.commandUsedToBuildTheProjectInjectedInto","Command used to build the project — injected into generated task specs")})]})]})}function hd(a){const t=Number(a);return Number.isFinite(t)&&t>0?Math.floor(t):3}async function gd(a){if(!a.ok)throw new Error(await a.text()||"Failed to load legacy auto-merge stamps");return a.json()}function bd({scopeBanner:a,form:t,setForm:s,integrationBranchOptions:c,integrationBranchCustomMode:r,setIntegrationBranchCustomMode:m,onOpenWorkflowSettings:i}){const{t:n}=Z("app"),[p,A]=o.useState([]),[j,u]=o.useState(!0),[d,C]=o.useState(!1),[b,h]=o.useState(null),[f,S]=o.useState(null),w=o.useCallback(async()=>{u(!0),h(null);try{const x=await gd(await fetch("/api/maintenance/legacy-automerge-stamps"));A(Array.isArray(x.candidates)?x.candidates:[])}catch(x){h(x instanceof Error?x.message:"Failed to load legacy auto-merge stamps")}finally{u(!1)}},[]);o.useEffect(()=>{w()},[w]);const I=async()=>{if(window.confirm("Apply cleanup for legacy auto-merge stamps? This clears only legacy non-override in-review stamps returned by the store and never touches genuine per-task overrides.")){C(!0),h(null),S(null);try{const v=await fetch("/api/maintenance/legacy-automerge-stamps/apply",{method:"POST"});if(!v.ok)throw new Error(await v.text()||"Failed to apply legacy auto-merge stamp cleanup");const B=await v.json();S(`Cleared ${B.count} legacy auto-merge stamp${B.count===1?"":"s"}.`),await w()}catch(v){h(v instanceof Error?v.message:"Failed to apply legacy auto-merge stamp cleanup")}finally{C(!1)}}};return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:n("settings.merge.merge","Merge")}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"autoMerge",className:"checkbox-label",children:[e.jsx("input",{id:"autoMerge",type:"checkbox",checked:t.autoMerge,onChange:x=>s(v=>({...v,autoMerge:x.target.checked}))}),n("settings.merge.autoMergeCompletedTasks"," Auto-merge completed tasks ")]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsx("small",{children:n("settings.merge.whenEnabledTasksThatPassReviewAreAutomatically","When enabled, tasks that pass review are automatically merged into the main branch")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"planApprovalMode",children:n("settings.merge.planApprovalMode","Plan approval mode")}),e.jsxs("select",{id:"planApprovalMode",className:"select",value:t.planApprovalMode??"workflow",onChange:x=>{const v=x.target.value;s(B=>({...B,planApprovalMode:v}))},"data-testid":"plan-approval-mode-select",children:[e.jsx("option",{value:"workflow",children:n("settings.merge.planApprovalModeWorkflow","Use workflow setting")}),e.jsx("option",{value:"auto-approve-all",children:n("settings.merge.planApprovalModeAutoApproveAll","Auto-approve all tasks")}),e.jsx("option",{value:"require-all",children:n("settings.merge.planApprovalModeRequireAll","Require approval for all tasks")})]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsx("small",{children:n("settings.merge.planApprovalModeHelp","Project-wide override for the planning approval gate. Leave on workflow to use each workflow's Require plan approval setting, or force all approved specs to bypass or wait for manual approval.")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"maxAutoMergeRetries",children:n("settings.merge.autoMergeConflictRetries","Auto-merge conflict retries")}),e.jsx("input",{id:"maxAutoMergeRetries",type:"number",min:1,step:1,value:t.maxAutoMergeRetries??3,onChange:x=>s(v=>({...v,maxAutoMergeRetries:x.target.value===""?void 0:hd(x.target.value)}))}),e.jsx("small",{children:n("settings.merge.positiveIntegerRetryCapForAutoMergeConflict","Positive integer retry cap for auto-merge conflict resolution before a task parks for human recovery. Default 3.")})]}),e.jsxs("div",{className:"form-group","data-testid":"legacy-automerge-stamp-cleanup-panel",children:[e.jsx("h5",{className:"settings-section-heading",children:n("settings.merge.legacyAutoMergeStampCleanup","Legacy auto-merge stamp cleanup")}),e.jsx("small",{children:n("settings.merge.findsInReviewTasksWhoseAutoMergeValue"," Finds in-review tasks whose auto-merge value came from the legacy review-entry stamp. Dry-run is automatic; applying delegates to the store cleanup and preserves genuine per-task overrides. ")}),j?e.jsx("small",{"aria-live":"polite",children:n("settings.merge.checkingForLegacyAutoMergeStamps","Checking for legacy auto-merge stamps…")}):p.length===0?e.jsx("small",{"data-testid":"legacy-automerge-stamp-empty-state",children:n("settings.merge.noLegacyAutoMergeStampsToCleanUp"," No legacy auto-merge stamps to clean up. ")}):e.jsxs(e.Fragment,{children:[e.jsxs("small",{children:[p.length,n("settings.merge.legacyAutoMergeStamp"," legacy auto-merge stamp"),p.length===1?"":"s",n("settings.merge.readyToCleanUp"," ready to clean up.")]}),e.jsx("ul",{children:p.map(x=>e.jsxs("li",{"data-testid":"legacy-automerge-stamp-candidate-row",children:[e.jsx("strong",{children:x.taskId})," — ",x.column]},x.taskId))}),e.jsx("button",{type:"button",className:"btn",onClick:I,disabled:d,"data-testid":"legacy-automerge-stamp-apply-button",children:d?"Applying cleanup…":"Apply cleanup"})]}),f?e.jsx("small",{className:"settings-success","aria-live":"polite",children:f}):null,b?e.jsx("small",{className:"settings-error",role:"alert",children:b}):null]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"mergerMode",children:n("settings.merge.aIMerge","AI merge")}),e.jsxs("select",{id:"mergerMode",className:"select",value:t.merger?.mode??"ai",onChange:x=>s(v=>({...v,merger:{...v.merger??{},mode:x.target.value}})),children:[e.jsx("option",{value:"ai",children:n("settings.merge.aIMergeDefaultAIMergesInAClean","AI merge (default) — AI merges in a clean room, an AI reviewer audits with retries, then lands")}),e.jsx("option",{value:"deterministic",children:n("settings.merge.deterministicLegacyRebaseConflictStrategyAuditPipeline","Deterministic (legacy) — rebase / conflict-strategy / audit pipeline")})]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsxs("small",{children:[n("settings.merge.aIModeMergesTheTaskBranchIntoAn"," AI mode merges the task branch into an isolated clean-room checkout at the target branch's tip, has an AI reviewer audit the squash (with corrective retries — advisory concerns land with a logged warning, an unfixable correctness concern hard-fails), then fast-forwards the target branch and syncs your local checkout (AI reconciles a conflicting restore). Each task merges to its own target branch, or the default integration branch. "),e.jsx("strong",{children:n("settings.merge.theLegacyMergeSettingsBelowDoNotApply","The legacy merge settings below do not apply while AI merge is on.")})]})]})]}),(t.merger?.mode??"ai")==="ai"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"mergerMaxReviewPasses",children:n("settings.merge.maxAIReviewPasses","Max AI review passes")}),e.jsx("input",{id:"mergerMaxReviewPasses",type:"number",min:0,max:10,value:t.merger?.maxReviewPasses??3,onChange:x=>s(v=>({...v,merger:{...v.merger??{},maxReviewPasses:x.target.value===""?void 0:Number(x.target.value)}}))}),e.jsx("small",{children:n("settings.merge.aICorrectiveRoundsBeforeLandingTheBestResult","AI corrective rounds before landing the best result (advisory concern) or hard-failing (unfixable correctness concern). Default 3. The reviewer uses your project's reviewer/validator model.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"mergerAllowDirtyLocalCheckoutSync",className:"checkbox-label",children:[e.jsx("input",{id:"mergerAllowDirtyLocalCheckoutSync",type:"checkbox",checked:t.merger?.allowDirtyLocalCheckoutSync===!0,onChange:x=>s(v=>({...v,merger:{...v.merger??{},allowDirtyLocalCheckoutSync:x.target.checked}}))}),n("settings.merge.allowAIMergeToSyncADirtyChecked"," Allow AI merge to sync a dirty checked-out integration branch ")]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsx("small",{children:n("settings.merge.dangerousCompatibilityEscapeHatchLeaveOffUnlessYou"," Dangerous compatibility escape hatch. Leave off unless you explicitly want the legacy stash → fast-forward → restore behavior when your checked-out integration branch has unrelated local edits. When off, AI merge blocks before advancing the branch so dirty project-root edits cannot contaminate a completed merge. ")})]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"testMode",className:"checkbox-label",children:[e.jsx("input",{id:"testMode",type:"checkbox",checked:t.testMode===!0,onChange:x=>s(v=>({...v,testMode:x.target.checked}))}),n("settings.merge.enableTestMode"," Enable test mode ")]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsx("small",{children:n("settings.merge.forcesAllAILanesToUseTheDeterministic","Forces all AI lanes to use the deterministic mock provider. No network calls, zero token cost.")})]})]}),e.jsx(ea,{message:n("settings.movedStub.reviewVerification","Review, verification auto-fix, and scope-enforcement settings now live on the workflow."),onOpenWorkflowSettings:i}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"mergeStrategy",children:n("settings.merge.autoCompletionMode","Auto-completion mode")}),e.jsxs("select",{id:"mergeStrategy",value:t.mergeStrategy||"direct",onChange:x=>s(v=>({...v,mergeStrategy:x.target.value})),children:[e.jsx("option",{value:"direct",children:n("settings.merge.directMergeIntoTheCurrentBranch","Direct merge into the current branch")}),e.jsx("option",{value:"pull-request",children:n("settings.merge.createMonitorAndMergeAGitHubPullRequest","Create, monitor, and merge a GitHub pull request")})]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsx("small",{children:n("settings.merge.controlsWhatHappensAfterATaskReachesIn"," Controls what happens after a task reaches In Review. Direct mode merges into the current branch locally. Pull request mode keeps the task in In Review while Fusion waits for GitHub reviews and required checks before merging the PR. ")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"integrationBranch",children:n("settings.merge.integrationBranch","Integration branch")}),(()=>{const x=t.integrationBranch??"",v=x.length>0&&c.includes(x);if(r||x.length>0&&!v)return e.jsxs("div",{className:"form-inline-group",children:[e.jsx("input",{id:"integrationBranch",type:"text",className:"input",placeholder:n("settings.merge.branchName","branch name"),value:x,onChange:W=>{const J=W.target.value.trim();s(V=>({...V,integrationBranch:J.length===0?void 0:J}))},"data-testid":"integration-branch-custom-input"}),e.jsx("button",{type:"button",className:"btn-link",onClick:()=>{m(!1),s(W=>({...W,integrationBranch:void 0}))},"data-testid":"integration-branch-use-dropdown",children:n("settings.merge.useDropdown"," Use dropdown ")})]});const k="__fusion-custom__",Y="";return e.jsxs("select",{id:"integrationBranch",className:"select",value:x,onChange:W=>{const J=W.target.value;if(J===k){m(!0);return}s(V=>({...V,integrationBranch:J===Y?void 0:J}))},"data-testid":"integration-branch-select",children:[e.jsx("option",{value:Y,children:n("settings.merge.autoDetectOriginHEADMain","(auto-detect — origin/HEAD → main)")}),c.map(W=>e.jsx("option",{value:W,children:W},W)),e.jsx("option",{value:k,children:n("settings.merge.custom","Custom…")})]})})(),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsxs("small",{children:[n("settings.merge.theCanonicalBranchFusionMergesTasksIntoAnd"," The canonical branch Fusion merges tasks into and uses as the reference for all ahead/behind / overlap / pre-rebase computations. Leave on "),e.jsx("em",{children:n("settings.merge.autoDetect","auto-detect")}),n("settings.merge.toResolveViaTheStandardCascade"," to resolve via the standard cascade ("),e.jsx("code",{children:"integrationBranch"}),n("settings.merge.legacy"," → legacy "),e.jsx("code",{children:"baseBranch"})," →",e.jsx("code",{children:"origin/HEAD"}),n("settings.merge.symbolicRefFallback"," symbolic ref → fallback "),e.jsx("code",{children:"main"}),n("settings.merge.pickALocalBranchFromTheDropdownCommon","). Pick a local branch from the dropdown — common integration names like "),e.jsx("code",{children:"main"}),",",e.jsx("code",{children:"master"}),", ",e.jsx("code",{children:"trunk"}),n("settings.merge.and",", and "),e.jsx("code",{children:"develop"}),n("settings.merge.areListedFirstOrChoose"," are listed first — or choose "),e.jsx("em",{children:n("settings.merge.custom","Custom…")}),n("settings.merge.toTypeABranchThatDoesnAposT"," to type a branch that doesn't exist locally yet. Applies to both direct merges and pull-request mode; individual tasks can still override via task metadata. ")]})]})]}),t.mergeStrategy!=="pull-request"&&(t.merger?.mode??"ai")!=="ai"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"directMergeCommitStrategy",children:n("settings.merge.directMergeCommitRouting","Direct merge commit routing")}),e.jsxs("select",{id:"directMergeCommitStrategy",className:"select",value:t.directMergeCommitStrategy??"always-squash",onChange:x=>s(v=>({...v,directMergeCommitStrategy:x.target.value})),children:[e.jsx("option",{value:"auto",children:n("settings.merge.autoSquashSingleSubstantiveBranchesPreserveMultiSubstantive","Auto — squash single-substantive branches, preserve multi-substantive history")}),e.jsx("option",{value:"always-squash",children:n("settings.merge.alwaysSquashDirectMerges","Always squash direct merges")}),e.jsx("option",{value:"always-rebase",children:n("settings.merge.alwaysPreserveDirectMergeCommitHistory","Always preserve direct-merge commit history")})]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsxs("small",{children:[n("settings.merge.autoKeepsTodayAposSSquashBehaviorFor"," Auto keeps today's squash behavior for branches with zero or one substantive commit, but switches multi-substantive branches to a history-preserving rebase-and-merge path. Individual tasks can override this in PROMPT.md with "),e.jsx("code",{children:"**Direct Merge Commit Strategy:** auto|always-squash|always-rebase"}),"."]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"mergeIntegrationWorktree",children:n("settings.merge.integrationWorktree","Integration worktree")}),e.jsxs("select",{id:"mergeIntegrationWorktree",className:"select",value:t.mergeIntegrationWorktree??"reuse-task-worktree",onChange:x=>s(v=>({...v,mergeIntegrationWorktree:x.target.value})),children:[e.jsx("option",{value:"reuse-task-worktree",children:n("settings.merge.reuseTaskWorktreeDefault","Reuse task worktree (default)")}),e.jsx("option",{value:"cwd-main",children:n("settings.merge.useProjectRootLegacy","Use project root (legacy)")})]}),e.jsx("small",{children:n("settings.merge.autoMergeRunsInTheTaskWorktreeBy"," Auto-merge runs in the task worktree by default. Switch to the legacy project-root path only if you need the pre-FN-5279 fallback; worktrunk-managed projects still defer to worktrunk. ")}),(t.mergeIntegrationWorktree??"reuse-task-worktree")!=="reuse-task-worktree"&&e.jsxs("div",{className:"settings-warning-banner",role:"alert","aria-live":"polite","data-testid":"merge-integration-worktree-warning",children:[e.jsx("strong",{children:n("settings.merge.legacyIntegrationBranchMode","Legacy integration-branch mode.")})," ",n("settings.merge.autoMergeWillRunRebaseConflictResolutionAnd"," Auto-merge will run rebase, conflict resolution, and squash commits inside the project root (the user's checked-out integration-branch worktree) instead of the task worktree. Fusion assumes that directory is already on the integration branch and clean; if it isn't, merges may fail or touch the user's working tree. Reuse-task-worktree is the recommended default (FN-5279). Switch back unless you have a specific reason to opt in (FN-5348). ")]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"mergeAdvanceAutoSync",children:n("settings.merge.autoSyncProjectCheckoutAfterMerge","Auto-sync project checkout after merge")}),e.jsxs("select",{id:"mergeAdvanceAutoSync",className:"select",value:t.mergeAdvanceAutoSync??"stash-and-ff",onChange:x=>s(v=>({...v,mergeAdvanceAutoSync:x.target.value})),"data-testid":"merge-advance-auto-sync-select",children:[e.jsx("option",{value:"stash-and-ff",children:n("settings.merge.stashFastForwardDefaultPreserveLocalEdits","Stash + fast-forward (default) — preserve local edits")}),e.jsx("option",{value:"ff-only",children:n("settings.merge.fastForwardOnlySkipDirtyWorktrees","Fast-forward only — skip dirty worktrees")}),e.jsx("option",{value:"off",children:n("settings.merge.offLeaveTheProjectRootStaleLegacyBehavior","Off — leave the project root stale (legacy behavior)")})]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsxs("small",{children:[n("settings.merge.afterFusionAdvancesTheIntegrationBranchRefThe"," After Fusion advances the integration branch ref, the merger can auto-sync other worktrees still checked out on that branch (typically your project-root checkout). "),e.jsx("code",{children:"Stash + fast-forward"}),n("settings.merge.snapshotsRealLocalEditsAsAPatchAgainst"," snapshots real local edits as a patch against the previous tip, snaps the worktree to the new tip, then reapplies the patch — untracked files that collide with newly-tracked paths are left in a temp dir for manual recovery. "),e.jsx("code",{children:"Fast-forward only"}),n("settings.merge.snapsCleanlyWhenTheWorktreeHasNoEdits"," snaps cleanly when the worktree has no edits and skips otherwise. "),e.jsx("code",{children:"Off"}),n("settings.merge.isTheLegacyBehavior"," is the legacy behavior: "),e.jsx("code",{children:"git status"}),n("settings.merge.inYourProjectRootWillShowTheNew"," in your project root will show the new commits inverted as &quot;staged changes&quot; until you pull manually. Only applies to direct merges. ")]})]})]})]}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:n("settings.merge.gitHubAuthentication","GitHub Authentication")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"githubAuthMode",children:n("settings.merge.gitHubAuthMode","GitHub auth mode")}),e.jsxs("select",{id:"githubAuthMode",className:"select",value:t.githubAuthMode??"gh-cli",onChange:x=>s(v=>({...v,githubAuthMode:x.target.value})),children:[e.jsx("option",{value:"gh-cli",children:n("settings.merge.gitHubCLIGhAuth","GitHub CLI (gh auth)")}),e.jsx("option",{value:"token",children:n("settings.merge.personalAccessToken","Personal access token")})]})]}),(t.githubAuthMode??"gh-cli")==="token"&&e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"githubAuthToken",children:n("settings.merge.gitHubPersonalAccessToken","GitHub personal access token")}),e.jsx("input",{id:"githubAuthToken",type:"password",className:"input",value:t.githubAuthToken??"",onChange:x=>s(v=>({...v,githubAuthToken:x.target.value||void 0}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"includeTaskIdInCommit",className:"checkbox-label",children:[e.jsx("input",{id:"includeTaskIdInCommit",type:"checkbox",checked:t.includeTaskIdInCommit!==!1,onChange:x=>s(v=>({...v,includeTaskIdInCommit:x.target.checked}))}),n("settings.merge.includeTaskIDInCommitScope"," Include task ID in commit scope ")]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsxs("small",{children:[n("settings.merge.whenDisabledMergeCommitMessagesOmitTheTask","When disabled, merge commit messages omit the task ID from the scope (e.g. "),e.jsx("code",{children:"feat: ..."}),n("settings.merge.insteadOf"," instead of "),e.jsx("code",{children:"feat(KB-001): ..."}),")"]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"commitAuthorEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"commitAuthorEnabled",type:"checkbox",checked:t.commitAuthorEnabled!==!1,onChange:x=>s(v=>({...v,commitAuthorEnabled:x.target.checked}))}),n("settings.merge.addFusionAsCoAuthorOnCommits"," Add Fusion as co-author on commits ")]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsxs("small",{children:[n("settings.merge.whenEnabledCommitsMadeByFusionKeepYour"," When enabled, commits made by Fusion keep your git identity as the primary author and append a "),e.jsx("code",{children:"Co-authored-by"}),n("settings.merge.trailerCreditingFusionRecognizedByGitHubForShared"," trailer crediting Fusion (recognized by GitHub for shared attribution). ")]})]})]}),t.commitAuthorEnabled!==!1&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"commitAuthorName",children:n("settings.merge.coAuthorName","Co-author Name")}),e.jsx("input",{id:"commitAuthorName",type:"text",value:t.commitAuthorName??"",placeholder:n("settings.merge.fusion","Fusion"),onChange:x=>s(v=>({...v,commitAuthorName:x.target.value||void 0}))}),e.jsxs("small",{children:[n("settings.merge.nameUsedInThe","Name used in the "),e.jsx("code",{children:"Co-authored-by"}),n("settings.merge.trailer"," trailer")]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"commitAuthorEmail",children:n("settings.merge.coAuthorEmail","Co-author Email")}),e.jsx("input",{id:"commitAuthorEmail",type:"email",value:t.commitAuthorEmail??"",placeholder:n("settings.merge.noreplyRunfusionAi","noreply@runfusion.ai"),onChange:x=>s(v=>({...v,commitAuthorEmail:x.target.value||void 0}))}),e.jsxs("small",{children:[n("settings.merge.emailUsedInThe","Email used in the "),e.jsx("code",{children:"Co-authored-by"}),n("settings.merge.trailer"," trailer")]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"autoResolveConflicts",className:"checkbox-label",children:[e.jsx("input",{id:"autoResolveConflicts",type:"checkbox",checked:t.autoResolveConflicts!==!1,onChange:x=>s(v=>({...v,autoResolveConflicts:x.target.checked}))}),n("settings.merge.autoResolveConflictsInLockFilesAndGenerated"," Auto-resolve conflicts in lock files and generated files ")]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsx("small",{children:n("settings.merge.whenEnabledLockFilesPackageLockJsonPnpm","When enabled, lock files (package-lock.json, pnpm-lock.yaml, etc.), generated files (dist/*, *.gen.ts), and trivial whitespace conflicts are resolved automatically without AI intervention. Complex code conflicts still require AI review.")})]})]}),(t.merger?.mode??"ai")!=="ai"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"smartConflictResolution",className:"checkbox-label",children:[e.jsx("input",{id:"smartConflictResolution",type:"checkbox",checked:t.smartConflictResolution!==!1,onChange:x=>s(v=>({...v,smartConflictResolution:x.target.checked}))}),n("settings.merge.smartConflictResolution"," Smart conflict resolution ")]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsx("small",{children:n("settings.merge.whenEnabledLockFilesPackageLockJsonPnpm2","When enabled, lock files (package-lock.json, pnpm-lock.yaml, etc.) are resolved using 'ours' strategy, generated files (dist/*, *.gen.ts) using 'theirs' strategy, and trivial whitespace conflicts are auto-resolved without spawning an AI agent. Complex code conflicts still require AI review.")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"mergeConflictStrategy",children:n("settings.merge.conflictFallbackStrategy","Conflict Fallback Strategy")}),e.jsxs("select",{id:"mergeConflictStrategy",value:t.mergeConflictStrategy??"smart-prefer-main",onChange:x=>s(v=>({...v,mergeConflictStrategy:x.target.value})),children:[e.jsx("option",{value:"smart-prefer-main",children:n("settings.merge.smartPreferMainOnFallbackFetchFfOrigin","Smart, prefer main on fallback — fetch+ff origin → AI → auto-resolve → -X ours (default; protects just-merged sibling work)")}),e.jsx("option",{value:"smart-prefer-branch",children:n("settings.merge.smartPreferTaskOnFallbackFetchFfOrigin",'Smart, prefer task on fallback — fetch+ff origin → AI → auto-resolve → -X theirs (legacy "smart" behavior; task branch wins)')}),e.jsx("option",{value:"ai-only",children:n("settings.merge.aIOnlyAIAutoResolveAIRetryNever","AI only — AI → auto-resolve → AI retry; never silently pick a side")}),e.jsx("option",{value:"abort",children:n("settings.merge.abortOneAIAttemptRequireManualResolutionIf","Abort — one AI attempt; require manual resolution if it fails")})]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsxs("small",{children:[n("settings.merge.both"," Both "),e.jsx("strong",{children:n("settings.merge.smart","Smart")}),n("settings.merge.optionsStartWithABestEffort"," options start with a best-effort "),e.jsx("code",{children:"git fetch"}),n("settings.merge.fastForwardOfLocalMainFrom"," + fast-forward of local main from "),e.jsx("code",{children:"origin"}),n("settings.merge.soAFreshlyPushedSiblingCommitDoesntGet"," (so a freshly-pushed sibling commit doesn't get clobbered), then run an AI agent, then auto-resolve handles lock/generated/trivial files. They differ only in the "),e.jsx("em",{children:n("settings.merge.finalFallback","final fallback")}),":"," ",e.jsx("strong",{children:n("settings.merge.smartPreferMain","Smart, prefer main")}),n("settings.merge.uses"," uses "),e.jsx("code",{children:"-X ours"}),n("settings.merge.soMainWinsProtectsJustMergedSiblingWork"," so main wins — protects just-merged sibling work and is the new default. ")," ",e.jsx("strong",{children:n("settings.merge.smartPreferTask","Smart, prefer task")}),n("settings.merge.uses"," uses "),e.jsx("code",{children:"-X theirs"}),n("settings.merge.soTheTaskBranchWinsFastButCan"," so the task branch wins — fast, but can resurrect code an earlier sibling task deleted (the FN-2887 class of regression). ")," ",e.jsx("strong",{children:n("settings.merge.aIOnly","AI only")}),n("settings.merge.retriesTheAIAgentRatherThanAutoPicking"," retries the AI agent rather than auto-picking a side. ")," ",e.jsx("strong",{children:n("settings.merge.abort","Abort")}),n("settings.merge.stopsAfterTheFirstAIAttemptAndWaits"," stops after the first AI attempt and waits for a human. ")," ",e.jsxs("em",{children:[n("settings.merge.legacy2","Legacy "),e.jsx("code",{children:'"smart"'}),n("settings.merge.and2"," and "),e.jsx("code",{children:'"prefer-main"'}),n("settings.merge.valuesFromOlderSettingsAreMigratedAutomatically"," values from older settings are migrated automatically.")]})]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"mergeStrategyOverlapBehavior",children:n("settings.merge.smartPreferMainOverlapGuard","Smart Prefer Main Overlap Guard")}),e.jsxs("select",{id:"mergeStrategyOverlapBehavior",value:t.mergeStrategyOverlapBehavior??"flip-to-prefer-branch",onChange:x=>s(v=>({...v,mergeStrategyOverlapBehavior:x.target.value})),children:[e.jsx("option",{value:"flip-to-prefer-branch",children:n("settings.merge.flipOverlappingFilesToPreferTheTaskBranch","Flip overlapping files to prefer the task branch (default)")}),e.jsx("option",{value:"warn-only",children:n("settings.merge.warnOnlyKeepLegacyMainWinsFallback","Warn only — keep legacy main-wins fallback")}),e.jsx("option",{value:"ignore",children:n("settings.merge.ignoreOverlapDetectionPreserveLegacyBehavior","Ignore overlap detection — preserve legacy behavior")})]}),e.jsx("small",{children:n("settings.merge.whenUsingSmartPreferMainAutomaticallyPreferThe"," When using smart-prefer-main, automatically prefer the branch side for files that main has recently modified to avoid silently discarding branch work. ")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"postMergeAuditMode",children:n("settings.merge.postMergeAuditMode","Post-merge audit mode")}),e.jsxs("select",{className:"select",id:"postMergeAuditMode",value:t.postMergeAuditMode??"warn",onChange:x=>s(v=>({...v,postMergeAuditMode:x.target.value})),children:[e.jsx("option",{value:"block",children:n("settings.merge.blockStrict","Block (strict)")}),e.jsx("option",{value:"warn",children:n("settings.merge.warnDefaultLogFindingsContinue","Warn (default; log findings, continue)")}),e.jsx("option",{value:"off",children:n("settings.merge.offSkipAudit","Off (skip audit)")})]}),e.jsxs("small",{children:[n("settings.merge.controlsThePostMergeAuditGate"," Controls the post-merge audit gate. "),e.jsx("strong",{children:n("settings.merge.warn","Warn")}),n("settings.merge.defaultLogsFindingsButAutoCompletesTheMerge"," (default) logs findings but auto-completes the merge. "),e.jsx("strong",{children:n("settings.merge.block","Block")}),n("settings.merge.isTheStricterOptInModeThatRefuses"," is the stricter opt-in mode that refuses to auto-complete merges with duplicate-subject or touched-file overlap risks. "),e.jsx("strong",{children:n("settings.merge.off","Off")}),n("settings.merge.skipsTheAuditEntirelySwitchingToOffIs"," skips the audit entirely. Switching to Off is recommended only if you trust your branches don't silently drop edits. ")]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"pushAfterMerge",className:"checkbox-label",children:[e.jsx("input",{id:"pushAfterMerge",type:"checkbox",checked:t.pushAfterMerge===!0,onChange:x=>s(v=>({...v,pushAfterMerge:x.target.checked}))}),n("settings.merge.pushToRemoteAfterMerge"," Push to remote after merge ")]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsx("small",{children:n("settings.merge.whenEnabledTheMergedResultIsAutomaticallyPushed","When enabled, the merged result is automatically pushed to the configured git remote. This includes pulling the latest from the remote first (rebase) and resolving any conflicts with AI if needed.")})]})]}),t.pushAfterMerge&&e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"pushRemote",children:n("settings.merge.pushRemote","Push Remote")}),e.jsx("input",{id:"pushRemote",type:"text",placeholder:n("settings.merge.origin","origin"),value:t.pushRemote||"",onChange:x=>s(v=>({...v,pushRemote:x.target.value||void 0}))}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:n("settings.merge.moreDetails","More details")}),e.jsx("small",{children:n("settings.merge.gitRemoteToPushToEGOrigin",'Git remote to push to (e.g. "origin"). Can include branch name (e.g. "origin main"). Default: "origin".')})]})]})]})}function Cn(a){return Array.from(new Set(a.split(/[\n,]+/).map(t=>t.trim()).filter(t=>t.length>0)))}function fd({value:a,onChange:t,disabled:s=!1}){const{t:c}=Z("app"),r=a?.approvalMode??"trusted-only",m=a?.alwaysApproveDelete??!0,i={always:{label:c("agentProvisioning.always","Always require approval"),description:c("agentProvisioning.alwaysDesc","All fn_agent_create/fn_agent_delete requests require approval unless caller is trusted.")},"trusted-only":{label:c("agentProvisioning.trustedOnly","Trusted-only"),description:c("agentProvisioning.trustedOnlyDesc","Trusted roles/agent IDs bypass approval; other callers require approval.")},never:{label:c("agentProvisioning.never","Never require approval"),description:c("agentProvisioning.neverDesc","Allow provisioning without approval for non-privileged callers.")}},n=p=>{t({...a??{},...p})};return e.jsxs("div",{className:"agent-provisioning-policy-editor card",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"agent-provisioning-approval-mode",children:c("agentProvisioning.approvalMode","Approval mode")}),e.jsx("select",{id:"agent-provisioning-approval-mode",className:"select",value:r,onChange:p=>n({approvalMode:p.target.value}),disabled:s,children:$l.map(p=>e.jsx("option",{value:p,children:i[p].label},p))}),e.jsx("small",{className:"agent-provisioning-policy-help",children:i[r].description})]}),e.jsx("div",{className:"form-group",children:e.jsxs("label",{className:"checkbox-label",htmlFor:"agent-provisioning-always-approve-delete",children:[e.jsx("input",{id:"agent-provisioning-always-approve-delete",type:"checkbox",checked:m,onChange:p=>n({alwaysApproveDelete:p.target.checked}),disabled:s}),c("agentProvisioning.alwaysApproveDelete","Always require approval for fn_agent_delete")]})}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"agent-provisioning-trusted-roles",children:c("agentProvisioning.trustedRoles","Trusted roles")}),e.jsx("textarea",{id:"agent-provisioning-trusted-roles",className:"input agent-provisioning-policy-textarea",value:(a?.trustedRoles??[]).join(", "),onChange:p=>n({trustedRoles:Cn(p.target.value)}),disabled:s,placeholder:c("agentProvisioning.trustedRolesPlaceholder","reviewer, ceo"),rows:2})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"agent-provisioning-trusted-agent-ids",children:c("agentProvisioning.trustedAgentIds","Trusted agent IDs")}),e.jsx("textarea",{id:"agent-provisioning-trusted-agent-ids",className:"input agent-provisioning-policy-textarea",value:(a?.trustedAgentIds??[]).join(", "),onChange:p=>n({trustedAgentIds:Cn(p.target.value)}),disabled:s,placeholder:c("agentProvisioning.trustedAgentIdsPlaceholder","agent-abc123"),rows:2})]}),e.jsx("p",{className:"agent-provisioning-policy-help",children:e.jsx(zs,{i18nKey:"app:agentProvisioning.helpText",defaults:"These settings govern durable provisioning tools only: <code>fn_agent_create</code> and <code>fn_agent_delete</code>. Ephemeral <code2>fn_spawn_agent</code2> requests stay under the task/agent mutation approval gate (FN-3973).",components:{code:e.jsx("code",{}),code2:e.jsx("code",{})}})})]})}function Bs(a){return Ul.reduce((t,s)=>(t[s]=a?.[s]??"allow",t),{})}function vd({scopeBanner:a,form:t,setForm:s}){const{t:c}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:c("settings.agentPermissions.agentPermissions","Agent Permissions")}),e.jsx("div",{className:"form-group",children:e.jsx("small",{className:"settings-muted",children:c("settings.agentPermissions.perAgentSettingsOverrideProjectDefaultsEachCategory","Per-agent settings override project defaults. Each category controls a separate approval gate.")})}),e.jsx(Uo,{mode:"project-default",value:t.defaultAgentPermissionPolicy?{presetId:"custom",rules:Bs(t.defaultAgentPermissionPolicy.rules)}:{presetId:"custom",rules:Bs()},onChange:r=>s(m=>({...m,defaultAgentPermissionPolicy:{rules:Bs(r?.rules)}}))}),e.jsx("h4",{className:"settings-section-heading",children:c("settings.agentPermissions.agentProvisioningApprovals","Agent Provisioning Approvals")}),e.jsx("div",{className:"form-group",children:e.jsx("small",{className:"settings-muted",children:c("settings.agentPermissions.configureProjectLevelApprovalBehaviorForDurableProvisioning"," Configure project-level approval behavior for durable provisioning tools (fn_agent_create/fn_agent_delete). ")})}),e.jsx(fd,{value:t.agentProvisioning,onChange:r=>s(m=>({...m,agentProvisioning:r}))})]})}const xd=72;function yd(a,t){if(a.length<=t)return a;const s=Math.max(1,t-1),c=Math.ceil(s/2),r=Math.floor(s/2);return`${a.slice(0,c)}…${a.slice(a.length-r)}`}function jd(a){const t=`${a.label} — ${a.path}`;return yd(t,xd)}function kd({scopeBanner:a,form:t,setForm:s,memory:c}){const{t:r}=Z("app"),{memoryCapabilities:m,memoryBackendStatus:i,memoryBackendLoading:n,memoryBackendError:p,memoryFiles:A,selectedMemoryPath:j,setSelectedMemoryPath:u,memoryContent:d,setMemoryContent:C,memoryLoading:b,memoryDirty:h,setMemoryDirty:f,memoryTestQuery:S,setMemoryTestQuery:w,memoryTestLoading:I,memoryTestResult:x,qmdInstallLoading:v,dreamRunning:B,memoryCompactLoading:k,onInstallQmd:Y,onTestMemoryRetrieval:W,onDreamNow:J,onCompactMemory:V,onSaveMemory:ne}=c,ae=t.memoryEnabled!==!1,$=!n&&i!==null,_=$?m?.writable??!0:!0,T=ae&&_,D=A.find(U=>U.path===j),re={"long-term":"Long-term",daily:"Daily",dreams:"Dreams"};return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:r("settings.memory.memory","Memory")}),e.jsx("div",{className:"form-group",children:e.jsxs("small",{className:"settings-muted",children:[r("settings.memory.memoryLivesIn"," Memory lives in "),e.jsx("code",{children:".fusion/memory/"}),r("settings.memory.agentsSearchWithQmdFirstFallBackTo",". Agents search with qmd first, fall back to local files when qmd is missing, and open exact line windows only when needed. ")]})}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryEnabled",type:"checkbox",checked:t.memoryEnabled!==!1,onChange:U=>s(ie=>({...ie,memoryEnabled:U.target.checked}))}),r("settings.memory.enableMemoryTools"," Enable memory tools ")]}),e.jsx("small",{children:r("settings.memory.agentsGetMemorySearchMemoryGetAndMemory","Agents get memory_search, memory_get, and memory_append tools. Search defaults to qmd with a local file fallback.")})]}),n?e.jsx("div",{className:"form-group",children:e.jsx("small",{className:"settings-muted",children:r("settings.memory.checkingMemoryWriteAccess","Checking memory write access...")})}):p?e.jsx("div",{className:"form-group",children:e.jsxs("small",{className:"field-error",children:[r("settings.memory.failedToLoadBackendStatus","Failed to load backend status: "),p]})}):null,$&&i.qmdAvailable===!1&&e.jsxs("div",{className:"settings-empty-state memory-status-message",children:[e.jsxs("span",{children:[r("settings.memory.qmdIsNotInstalledSearchWillUseLocal"," qmd is not installed. Search will use local files. Install indexed retrieval: "),e.jsx("code",{children:i.qmdInstallCommand||"bun install -g @tobilu/qmd"})]}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:Y,disabled:v,children:v?r("settings.memory.installing","Installing…"):r("settings.memory.installQmd","Install qmd")})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryAutoSummarizeEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryAutoSummarizeEnabled",type:"checkbox",checked:t.memoryAutoSummarizeEnabled||!1,onChange:U=>s(ie=>({...ie,memoryAutoSummarizeEnabled:U.target.checked}))}),r("settings.memory.autoSummarizeMemory"," Auto-Summarize Memory ")]}),e.jsx("small",{children:r("settings.memory.automaticallyCompactMemoryWhenItExceedsTheThreshold","Automatically compact memory when it exceeds the threshold on a schedule")})]}),(t.memoryAutoSummarizeEnabled||!1)&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeThresholdChars",children:r("settings.memory.compactionThresholdChars","Compaction Threshold (chars)")}),e.jsx("input",{id:"memoryAutoSummarizeThresholdChars",type:"number",className:"input",value:t.memoryAutoSummarizeThresholdChars??5e4,onChange:U=>s(ie=>({...ie,memoryAutoSummarizeThresholdChars:parseInt(U.target.value,10)||5e4})),min:1e3}),e.jsx("small",{children:r("settings.memory.memoryWillBeCompactedWhenItExceedsThis","Memory will be compacted when it exceeds this character count")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeSchedule",children:r("settings.memory.scheduleCron","Schedule (cron)")}),e.jsx("input",{id:"memoryAutoSummarizeSchedule",type:"text",className:"input",value:t.memoryAutoSummarizeSchedule??"0 3 * * *",onChange:U=>s(ie=>({...ie,memoryAutoSummarizeSchedule:U.target.value})),placeholder:r("settings.memory.03","0 3 * * *")}),e.jsx("small",{children:r("settings.memory.cronExpressionForAutoSummarizeScheduleDefaultDaily","Cron expression for auto-summarize schedule (default: daily at 3 AM)")})]})]}),e.jsx("div",{style:{borderTop:"1px solid var(--border)",margin:"var(--space-lg) 0"}}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryDreamsEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryDreamsEnabled",type:"checkbox",checked:t.memoryDreamsEnabled===!0,onChange:U=>s(ie=>({...ie,memoryDreamsEnabled:U.target.checked})),disabled:!ae}),r("settings.memory.processDreamsFromDailyMemory"," Process dreams from daily memory ")]}),e.jsx("small",{children:r("settings.memory.turnsDailyNotesIntoDREAMSMdAndPromotes","Turns daily notes into DREAMS.md and promotes reusable lessons into MEMORY.md.")})]}),ae&&t.memoryDreamsEnabled===!0&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryDreamsSchedule",children:r("settings.memory.dreamSchedule","Dream Schedule")}),e.jsx("input",{id:"memoryDreamsSchedule",type:"text",value:t.memoryDreamsSchedule??"0 4 * * *",onChange:U=>s(ie=>({...ie,memoryDreamsSchedule:U.target.value}))}),e.jsx("small",{children:r("settings.memory.cronExpressionForDreamProcessing","Cron expression for dream processing.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:J,disabled:B||t.memoryDreamsEnabled!==!0,children:B?e.jsxs(e.Fragment,{children:[e.jsx(qe,{size:14,className:"animate-spin"}),r("settings.memory.dreaming"," Dreaming… ")]}):r("settings.memory.dreamNow","Dream Now")}),e.jsx("small",{children:r("settings.memory.manuallyTriggerDreamProcessingNow","Manually trigger dream processing now.")})]})]}),e.jsxs("div",{className:"memory-retrieval-test",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryRetrievalQuery",children:r("settings.memory.testRetrieval","Test Retrieval")}),e.jsx("input",{id:"memoryRetrievalQuery",type:"text",value:S,onChange:U=>w(U.target.value),placeholder:r("settings.memory.searchMemoryWithQmd","Search memory with qmd")}),e.jsx("small",{children:r("settings.memory.runsTheSameQmdBackedMemorySearchPath","Runs the same qmd-backed memory_search path agents use.")})]}),e.jsx("div",{className:"form-group",children:e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:W,disabled:I,children:I?r("settings.memory.testing","Testing…"):r("settings.memory.testRetrieval","Test Retrieval")})}),x&&e.jsxs("div",{className:"memory-test-result",children:[e.jsxs("strong",{children:[x.results.length,r("settings.memory.result"," result"),x.results.length===1?"":"s"," ",r("settings.memory.for",'for "'),x.query,'"']}),e.jsxs("small",{children:[r("settings.memory.qmd"," qmd "),x.qmdAvailable?"available":"missing"," · ",x.usedFallback?"local fallback used":"qmd path used"]}),x.results.length>0?e.jsx("ul",{children:x.results.map((U,ie)=>e.jsxs("li",{children:[e.jsxs("span",{children:[U.path,":",U.lineStart]}),e.jsx("p",{children:U.snippet})]},`${U.path}-${U.lineStart}-${ie}`))}):e.jsx("small",{children:r("settings.memory.noMatchingMemoryFound","No matching memory found.")})]})]}),!ae&&e.jsx("div",{className:"settings-empty-state memory-status-message",children:r("settings.memory.memoryIsCurrentlyDisabledYouCanViewThe"," Memory is currently disabled. You can view the file, but editing is read-only until memory is re-enabled. ")}),ae&&$&&!_&&e.jsx("div",{className:"settings-empty-state memory-status-message",children:r("settings.memory.memoryIsConfiguredWithAReadOnlyBackend"," Memory is configured with a read-only backend. You can view the file, but saving is disabled. ")}),b?e.jsx("div",{className:"settings-empty-state",children:e.jsx(ze,{label:r("settings.memory.loadingMemory","Loading memory…")})}):e.jsxs("div",{className:"memory-editor-section",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryFilePath",children:r("settings.memory.memoryFile","Memory File")}),e.jsx("select",{id:"memoryFilePath",value:j,onChange:U=>{u(U.target.value),f(!1)},disabled:h,children:A.map(U=>e.jsx("option",{value:U.path,title:`${U.label} — ${U.path}`,children:jd(U)},U.path))}),e.jsx("small",{children:h?"Save or discard the current edits before switching files.":"Choose any project memory file to view or edit. Dreams is selected by default."})]}),D&&e.jsxs("div",{className:"memory-file-summary",children:[e.jsx("span",{children:re[D.layer]}),e.jsx("strong",{children:D.path}),e.jsxs("small",{children:[D.size.toLocaleString(),r("settings.memory.bytesUpdated"," bytes · updated "),new Date(D.updatedAt).toLocaleString()]})]}),e.jsxs("div",{className:"form-group memory-editor-form-group",children:[e.jsx("label",{children:D?.label||"Memory Editor"}),e.jsxs("small",{children:[D?.layer==="long-term"&&"Curated durable decisions, conventions, constraints, and pitfalls promoted from dreams.",D?.layer==="daily"&&"Raw daily observations, open loops, and running context for dream processing.",D?.layer==="dreams"&&"Synthesized patterns and open loops promoted from daily memory.",!D&&"Edits the selected memory file."]}),e.jsx("div",{className:"memory-editor-frame",children:e.jsx(Hl,{content:d,onChange:U=>{C(U),f(!0)},readOnly:!T,filePath:j})})]})]}),!b&&e.jsxs("div",{className:"form-group",children:[e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:V,disabled:!T||h||k,children:k?r("settings.memory.compacting","Compacting…"):r("settings.memory.compactSelectedFile","Compact Selected File")}),e.jsx("small",{children:h?"Save or discard edits before compacting this file.":`Compacts ${j} and writes the result back to the same file.`})]}),h&&T&&e.jsx("div",{className:"form-group",children:e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:ne,children:r("settings.memory.saveMemory","Save Memory")})}),h&&!T&&e.jsx("div",{className:"form-group",children:e.jsxs("small",{className:"field-error",children:[r("settings.memory.cannotSave","Cannot save: "),ae?"Backend is read-only":"Memory is disabled"]})})]})}function wd({scopeBanner:a,form:t,setForm:s,researchLimitError:c}){const{t:r}=Z("app"),m=t.researchSettings?.limits,i=t.researchSettings?.enabledSources;return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:r("settings.researchProject.projectResearchSettings","Project Research Settings")}),e.jsx("div",{className:"form-group",children:e.jsxs("label",{htmlFor:"research-project-enabled",className:"checkbox-label",children:[e.jsx("input",{id:"research-project-enabled",type:"checkbox",checked:t.researchSettings?.enabled??!0,onChange:n=>s(p=>({...p,researchSettings:{...p.researchSettings??{},enabled:n.target.checked}}))}),r("settings.researchProject.enableResearchInThisProject"," Enable research in this project ")]})}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:r("settings.researchProject.enabledSources","Enabled Sources")}),e.jsxs("label",{htmlFor:"research-project-source-webSearch",className:"checkbox-label settings-research-source-locked",children:[e.jsx("input",{id:"research-project-source-webSearch",type:"checkbox",checked:!0,disabled:!0,readOnly:!0}),r("settings.researchProject.webSearch"," Web Search "),e.jsx("span",{className:"settings-muted",children:r("settings.researchProject.alwaysOn","Always on")})]}),e.jsx("small",{className:"settings-muted",children:r("settings.researchProject.webSearchIsAlwaysEnabledConfigureTheSearch"," Web search is always enabled. Configure the search provider under Research Defaults. ")}),e.jsx("div",{className:"settings-research-source-grid",children:[["pageFetch",r("settings.researchProject.pageFetch","Page Fetch")],["github",r("settings.researchProject.github","GitHub")],["localDocs",r("settings.researchProject.localDocs","Local Docs")],["llmSynthesis",r("settings.researchProject.llmSynthesis","LLM Synthesis")]].map(([n,p])=>e.jsxs("label",{htmlFor:`research-project-source-${n}`,className:"checkbox-label",children:[e.jsx("input",{id:`research-project-source-${n}`,type:"checkbox",checked:i?.[n]??!1,onChange:A=>s(j=>({...j,researchSettings:{...j.researchSettings??{},enabledSources:{...j.researchSettings?.enabledSources??{},[n]:A.target.checked}}}))}),p]},n))})]}),e.jsx("div",{className:"form-group",children:e.jsxs("div",{className:"settings-research-limits-grid",children:[e.jsxs("div",{className:"settings-research-limit-field",children:[e.jsx("label",{htmlFor:"research-project-max-concurrent",children:r("settings.researchProject.maxConcurrentRuns","Max Concurrent Runs")}),e.jsx("input",{id:"research-project-max-concurrent",className:"input",type:"number",min:1,value:m?.maxConcurrentRuns??3,onChange:n=>s(p=>({...p,researchSettings:{...p.researchSettings??{},limits:{...p.researchSettings?.limits??{},maxConcurrentRuns:n.target.value===""?void 0:Number(n.target.value)}}}))})]}),e.jsxs("div",{className:"settings-research-limit-field",children:[e.jsx("label",{htmlFor:"research-project-max-sources",children:r("settings.researchProject.maxSourcesPerRun","Max Sources Per Run")}),e.jsx("input",{id:"research-project-max-sources",className:"input",type:"number",min:1,value:m?.maxSourcesPerRun??20,onChange:n=>s(p=>({...p,researchSettings:{...p.researchSettings??{},limits:{...p.researchSettings?.limits??{},maxSourcesPerRun:n.target.value===""?void 0:Number(n.target.value)}}}))})]}),e.jsxs("div",{className:"settings-research-limit-field",children:[e.jsx("label",{htmlFor:"research-project-max-duration",children:r("settings.researchProject.maxDurationMs","Max Duration (ms)")}),e.jsx("input",{id:"research-project-max-duration",className:"input",type:"number",min:1e3,value:m?.maxDurationMs??3e5,onChange:n=>s(p=>({...p,researchSettings:{...p.researchSettings??{},limits:{...p.researchSettings?.limits??{},maxDurationMs:n.target.value===""?void 0:Number(n.target.value)}}}))})]}),e.jsxs("div",{className:"settings-research-limit-field",children:[e.jsx("label",{htmlFor:"research-project-request-timeout",children:r("settings.researchProject.requestTimeoutMs","Request Timeout (ms)")}),e.jsx("input",{id:"research-project-request-timeout",className:"input",type:"number",min:1e3,value:m?.requestTimeoutMs??3e4,onChange:n=>s(p=>({...p,researchSettings:{...p.researchSettings??{},limits:{...p.researchSettings?.limits??{},requestTimeoutMs:n.target.value===""?void 0:Number(n.target.value)}}}))})]}),c&&e.jsx("small",{className:"field-error settings-research-limits-error",children:c})]})})]})}function Cd({scopeBanner:a,form:t,setForm:s,globalSettings:c,projectId:r,addToast:m}){const{t:i}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:i("settings.nav.mcp","MCP Servers")}),e.jsx(Bn,{scope:"project",form:t,setForm:s,globalSettings:c,projectId:r,addToast:m})]})}function Nd({scopeBanner:a,form:t,setForm:s,backupInfo:c,backupLoading:r,onBackupNow:m}){const{t:i}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:i("settings.backups.databaseBackups","Database Backups")}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"autoBackupEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"autoBackupEnabled",type:"checkbox",checked:t.autoBackupEnabled||!1,onChange:n=>s(p=>({...p,autoBackupEnabled:n.target.checked}))}),i("settings.backups.enableAutomaticDatabaseBackups"," Enable automatic database backups ")]}),e.jsx("small",{children:i("settings.backups.whenEnabledTheDatabaseIsBackedUpAutomatically","When enabled, the database is backed up automatically on a schedule")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"autoBackupSchedule",children:i("settings.backups.backupScheduleCron","Backup Schedule (Cron)")}),e.jsx("input",{id:"autoBackupSchedule",type:"text",placeholder:i("settings.backups.02","0 2 * * *"),value:t.autoBackupSchedule||"0 2 * * *",onChange:n=>s(p=>({...p,autoBackupSchedule:n.target.value})),disabled:!t.autoBackupEnabled}),e.jsx("small",{children:i("settings.backups.cronExpressionForBackupTimingDefault02"," Cron expression for backup timing. Default: 0 2 * * * (daily at 2 AM). Examples: 0 * * * * (hourly), 0 0 * * 0 (weekly), */15 * * * * (every 15 min) ")}),t.autoBackupSchedule&&!/^[\s\d*,/-]+$/.test(t.autoBackupSchedule)&&e.jsx("small",{className:"field-error",children:i("settings.backups.invalidCronExpressionFormat","Invalid cron expression format")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"autoBackupRetention",children:i("settings.backups.retentionCount","Retention Count")}),e.jsx("input",{id:"autoBackupRetention",type:"number",min:1,max:100,value:t.autoBackupRetention??"",onChange:n=>{const p=n.target.value;s(A=>({...A,autoBackupRetention:p===""?void 0:Number(p)}))},disabled:!t.autoBackupEnabled}),e.jsx("small",{children:i("settings.backups.numberOfBackupFilesToKeepOldestAre","Number of backup files to keep (oldest are deleted first). Range: 1-100.")}),t.autoBackupRetention!==void 0&&(t.autoBackupRetention<1||t.autoBackupRetention>100)&&e.jsx("small",{className:"field-error",children:i("settings.backups.mustBeBetween1And100","Must be between 1 and 100")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"autoBackupDir",children:i("settings.backups.backupDirectory","Backup Directory")}),e.jsx("input",{id:"autoBackupDir",type:"text",placeholder:i("settings.backups.fusionBackups",".fusion/backups"),value:t.autoBackupDir||".fusion/backups",onChange:n=>s(p=>({...p,autoBackupDir:n.target.value})),disabled:!t.autoBackupEnabled}),e.jsx("small",{children:i("settings.backups.directoryForBackupFilesRelativeToProjectRoot","Directory for backup files, relative to project root")}),t.autoBackupDir&&t.autoBackupDir.includes("..")&&e.jsx("small",{className:"field-error",children:i("settings.backups.pathCannotContainParentDirectoryTraversal","Path cannot contain parent directory traversal (..)")})]}),e.jsx("h4",{className:"settings-section-heading",children:i("settings.backups.memoryBackups","Memory Backups")}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"memoryBackupEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"memoryBackupEnabled",type:"checkbox",checked:t.memoryBackupEnabled||!1,onChange:n=>s(p=>({...p,memoryBackupEnabled:n.target.checked}))}),i("settings.backups.enableAutomaticMemoryBackups"," Enable automatic memory backups ")]}),e.jsx("small",{children:i("settings.backups.whenEnabledProjectAndAgentMemoryFilesAre","When enabled, project and agent memory files are backed up automatically on a schedule.")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryBackupSchedule",children:i("settings.backups.memoryBackupScheduleCron","Memory Backup Schedule (Cron)")}),e.jsx("input",{id:"memoryBackupSchedule",type:"text",placeholder:i("settings.backups.03","0 3 * * *"),value:t.memoryBackupSchedule||"0 3 * * *",onChange:n=>s(p=>({...p,memoryBackupSchedule:n.target.value})),disabled:!t.memoryBackupEnabled}),e.jsx("small",{children:i("settings.backups.cronExpressionForMemoryBackupTimingDefault0","Cron expression for memory backup timing. Default: 0 3 * * * (daily at 3 AM).")}),t.memoryBackupSchedule&&!/^[\s\d*,/-]+$/.test(t.memoryBackupSchedule)&&e.jsx("small",{className:"field-error",children:i("settings.backups.invalidCronExpressionFormat","Invalid cron expression format")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryBackupRetention",children:i("settings.backups.memoryRetentionCount","Memory Retention Count")}),e.jsx("input",{id:"memoryBackupRetention",type:"number",min:1,max:100,value:t.memoryBackupRetention??"",onChange:n=>{const p=n.target.value;s(A=>({...A,memoryBackupRetention:p===""?void 0:Number(p)}))},disabled:!t.memoryBackupEnabled}),e.jsx("small",{children:i("settings.backups.numberOfMemoryBackupsToKeepOldestAre","Number of memory backups to keep (oldest are deleted first). Range: 1-100.")}),t.memoryBackupRetention!==void 0&&(t.memoryBackupRetention<1||t.memoryBackupRetention>100)&&e.jsx("small",{className:"field-error",children:i("settings.backups.mustBeBetween1And100","Must be between 1 and 100")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryBackupDir",children:i("settings.backups.memoryBackupDirectory","Memory Backup Directory")}),e.jsx("input",{id:"memoryBackupDir",type:"text",placeholder:i("settings.backups.fusionBackupsMemory",".fusion/backups/memory"),value:t.memoryBackupDir||".fusion/backups/memory",onChange:n=>s(p=>({...p,memoryBackupDir:n.target.value})),disabled:!t.memoryBackupEnabled}),e.jsx("small",{children:i("settings.backups.directoryForMemoryBackupsRelativeToProjectRoot","Directory for memory backups, relative to project root.")}),t.memoryBackupDir&&t.memoryBackupDir.includes("..")&&e.jsx("small",{className:"field-error",children:i("settings.backups.pathCannotContainParentDirectoryTraversal","Path cannot contain parent directory traversal (..)")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryBackupScope",children:i("settings.backups.memoryBackupScope","Memory Backup Scope")}),e.jsxs("select",{id:"memoryBackupScope",value:t.memoryBackupScope||"all",onChange:n=>s(p=>({...p,memoryBackupScope:n.target.value})),disabled:!t.memoryBackupEnabled,children:[e.jsx("option",{value:"all",children:i("settings.backups.allProjectAgents","All (project + agents)")}),e.jsx("option",{value:"project",children:i("settings.backups.projectOnlyFusionMemory","Project only (.fusion/memory)")}),e.jsx("option",{value:"agents",children:i("settings.backups.agentsOnlyFusionAgentMemory","Agents only (.fusion/agent-memory)")})]})]}),r?e.jsx("div",{className:"settings-empty-state",children:e.jsx(ze,{label:i("settings.backups.loadingBackupInfo","Loading backup info…")})}):c?e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:i("settings.backups.currentBackups","Current Backups")}),e.jsxs("div",{className:"backup-stats",children:[e.jsxs("div",{className:"backup-stat",children:[e.jsx("span",{className:"backup-stat-value",children:c.count}),e.jsx("span",{className:"backup-stat-label",children:i("settings.backups.backups","backups")})]}),e.jsxs("div",{className:"backup-stat",children:[e.jsx("span",{className:"backup-stat-value",children:c.totalSize>1024*1024?`${(c.totalSize/(1024*1024)).toFixed(1)} MB`:`${(c.totalSize/1024).toFixed(1)} KB`}),e.jsx("span",{className:"backup-stat-label",children:i("settings.backups.totalSize","total size")})]})]}),c.backups.length>0&&e.jsxs("details",{className:"backup-list",children:[e.jsxs("summary",{children:[i("settings.backups.view","View "),c.backups.length,i("settings.backups.backupS"," backup(s)")]}),e.jsxs("ul",{children:[c.backups.slice(0,10).map(n=>e.jsxs("li",{children:[e.jsx("code",{children:n.filename}),e.jsx("span",{className:"backup-size",children:n.size>1024*1024?`${(n.size/(1024*1024)).toFixed(1)} MB`:`${(n.size/1024).toFixed(1)} KB`})]},n.filename)),c.backups.length>10&&e.jsx("li",{children:e.jsxs("em",{children:[i("settings.backups.and","...and "),c.backups.length-10,i("settings.backups.more"," more")]})})]})]})]}):null,e.jsx("div",{className:"form-group",children:e.jsx("button",{type:"button",className:"btn btn-sm",onClick:m,disabled:r,children:r?i("settings.backups.creating","Creating…"):i("settings.backups.backupNow","Backup Now")})})]})}const Sd=o.lazy(()=>Fn(()=>import("./PluginManager-DEsUstVo.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13])).then(a=>({default:a.PluginManager}))),Pd=o.lazy(()=>Fn(()=>import("./PiExtensionsManager-BQt3JU60.js"),__vite__mapDeps([14,1,2,3,4,5,6,7,8,9,15,16,17])).then(a=>({default:a.PiExtensionsManager})));function Ad({scopeBanner:a,projectId:t,addToast:s,activePluginsSubsection:c,setActivePluginsSubsection:r}){const{t:m}=Z("app");return e.jsxs(e.Fragment,{children:[a,e.jsx("h4",{className:"settings-section-heading",children:m("settings.plugins.plugins","Plugins")}),e.jsxs("div",{className:"settings-plugins-subsection-toggle",role:"tablist","aria-label":m("settings.plugins.pluginManagerType","Plugin manager type"),children:[e.jsx("button",{type:"button",id:"plugins-tab-fusion-plugins",role:"tab","aria-controls":"plugins-panel-fusion-plugins","aria-selected":c==="fusion-plugins",tabIndex:c==="fusion-plugins"?0:-1,className:`settings-plugins-subsection-btn${c==="fusion-plugins"?" active":""}`,onClick:()=>r("fusion-plugins"),children:m("settings.plugins.fusionPlugins"," Fusion Plugins ")}),e.jsx("button",{type:"button",id:"plugins-tab-pi-extensions",role:"tab","aria-controls":"plugins-panel-pi-extensions","aria-selected":c==="pi-extensions",tabIndex:c==="pi-extensions"?0:-1,className:`settings-plugins-subsection-btn${c==="pi-extensions"?" active":""}`,onClick:()=>r("pi-extensions"),children:m("settings.plugins.piExtensions"," Pi Extensions ")})]}),e.jsx("div",{id:"plugins-panel-fusion-plugins",role:"tabpanel","aria-labelledby":"plugins-tab-fusion-plugins",className:"settings-plugins-subsection-panel",hidden:c!=="fusion-plugins",children:c==="fusion-plugins"&&e.jsxs(e.Fragment,{children:[e.jsx(o.Suspense,{fallback:null,children:e.jsx(Sd,{addToast:s,projectId:t})}),e.jsx(qs,{slotId:"settings-section",projectId:t})]})}),e.jsx("div",{id:"plugins-panel-pi-extensions",role:"tabpanel","aria-labelledby":"plugins-tab-pi-extensions",className:"settings-plugins-subsection-panel",hidden:c!=="pi-extensions",children:c==="pi-extensions"&&e.jsx(o.Suspense,{fallback:null,children:e.jsx(Pd,{addToast:s,projectId:t})})})]})}function Gs(a,t){if(!t)return a;const s=a.includes("?")?"&":"?";return`${a}${s}projectId=${encodeURIComponent(t)}`}async function Nn(a,t){const s=await fetch(a,{credentials:"same-origin",...t,headers:{"Content-Type":"application/json",...t?.headers??{}}}),c=await s.json();if(!s.ok)throw new Error(c.error??`Request failed (${s.status})`);return c}function Md(a){const[t,s]=o.useState({status:"missing"}),[c,r]=o.useState(!1),m=o.useCallback(async()=>{try{const n=await Nn(Gs("/api/worktrunk/status",a));s(n)}catch(n){s({status:"failed",error:n instanceof Error?n.message:"Failed to load worktrunk status"})}},[a]);o.useEffect(()=>{m()},[m]),o.useEffect(()=>Kl(Gs("/api/events",a),{events:{"approval:updated":()=>{t.pendingApprovalId&&m()},"approval:decided":()=>{t.pendingApprovalId&&m()}}}),[a,m,t.pendingApprovalId]);const i=o.useCallback(async()=>{r(!0),s(n=>({...n,status:"installing",error:void 0}));try{const n=await Nn(Gs("/api/worktrunk/install-request",a),{method:"POST",body:JSON.stringify({})});s({status:n.status,version:n.version,installPath:n.installPath,pendingApprovalId:n.pendingApprovalId??n.approvalRequestId,error:n.error})}catch(n){s({status:"failed",error:n instanceof Error?n.message:"Failed to request install"})}finally{r(!1)}},[a]);return{...t,requestInstall:i,requesting:c}}const _s="fusion_github_star_count",Sn=3600*1e3,Pn="fusion:github-star-clicked";function Td({size:a=13}){return e.jsx("svg",{"data-testid":"discord-icon",width:a,height:a,viewBox:"0 0 24 24",role:"img","aria-hidden":"true",fill:"currentColor",children:e.jsx("path",{d:"M20.317 4.369A19.791 19.791 0 0 0 15.885 3a13.66 13.66 0 0 0-.696 1.412 18.27 18.27 0 0 0-6.378 0A13.627 13.627 0 0 0 8.115 3a19.736 19.736 0 0 0-4.432 1.369C.878 8.604.111 12.734.494 16.803a19.916 19.916 0 0 0 5.993 3.048 14.43 14.43 0 0 0 1.286-2.106 12.94 12.94 0 0 1-2.024-.977c.17-.122.337-.249.499-.381 3.908 1.838 8.149 1.838 12.01 0 .163.132.329.259.5.381a12.936 12.936 0 0 1-2.028.978 14.344 14.344 0 0 0 1.287 2.105 19.85 19.85 0 0 0 5.996-3.049c.449-4.713-.766-8.806-3.696-12.433zM8.02 14.335c-1.184 0-2.157-1.085-2.157-2.419 0-1.334.95-2.418 2.157-2.418 1.217 0 2.167 1.095 2.157 2.418 0 1.334-.95 2.419-2.157 2.419zm7.975 0c-1.184 0-2.157-1.085-2.157-2.419 0-1.334.95-2.418 2.157-2.418 1.217 0 2.167 1.095 2.157 2.418 0 1.334-.94 2.419-2.157 2.419z"})})}function Rd(a){const t=new Map;for(const s of a){const c=`${s.owner}/${s.repo}`;t.has(c)||t.set(c,{value:c,label:c})}return[...t.values()].sort((s,c)=>s.value.localeCompare(c.value))}function Id(){const[a,t]=o.useState(()=>{try{return localStorage.getItem(Pn)==="true"}catch{return!1}}),s=o.useCallback(()=>{t(!0);try{localStorage.setItem(Pn,"true")}catch{}},[]);return[a,s]}function Ed(){const[a,t]=o.useState(()=>{try{const s=localStorage.getItem(_s);if(s){const c=JSON.parse(s);if(Date.now()-c.fetchedAt<Sn)return c.count}}catch{}return null});return o.useEffect(()=>{try{const s=localStorage.getItem(_s);if(s){const c=JSON.parse(s);if(Date.now()-c.fetchedAt<Sn)return}}catch{}fetch("https://api.github.com/repos/Runfusion/Fusion").then(s=>{if(s.ok)return s.json()}).then(s=>{if(s&&typeof s.stargazers_count=="number"){const c={count:s.stargazers_count,fetchedAt:Date.now()};try{localStorage.setItem(_s,JSON.stringify(c))}catch{}t(s.stargazers_count)}}).catch(()=>{})},[]),a}const An="(max-width: 768px)",Ws=".fusion/memory/DREAMS.md";function Mn(a){const t=Number(a?.maxAutoMergeRetries);return Number.isFinite(t)&&t>0?Math.floor(t):3}const Tn=[{id:"__global_header",label:"Global",labelKey:"settings.nav.globalHeader",scope:void 0,isGroupHeader:!0},{id:"global-general",label:"General",labelKey:"settings.nav.globalGeneral",scope:"global"},{id:"authentication",label:"Authentication",labelKey:"settings.nav.authentication",scope:void 0,icon:gt},{id:"appearance",label:"Appearance",labelKey:"settings.nav.appearance",scope:"global"},{id:"notifications",label:"Notifications",labelKey:"settings.nav.notifications",scope:"global"},{id:"node-sync",label:"Node Sync",labelKey:"settings.nav.nodeSync",scope:"global"},{id:"global-models",label:"Models",labelKey:"settings.nav.globalModels",scope:"global"},{id:"global-mcp",label:"MCP Servers",labelKey:"settings.nav.globalMcp",scope:"global"},{id:"cli-agents",label:"CLI Agents",labelKey:"settings.nav.cliAgents",scope:"global"},{id:"research-global",label:"Research Defaults",labelKey:"settings.nav.researchGlobal",scope:"global"},{id:"remote",label:"Remote Access",labelKey:"settings.nav.remote",scope:"global"},{id:"experimental",label:"Experimental Features",labelKey:"settings.nav.experimental",scope:"global"},{id:"__runtimes_header",label:"Runtimes",labelKey:"settings.nav.runtimesHeader",scope:void 0,isGroupHeader:!0},{id:"hermes-runtime",label:"Hermes",labelKey:"settings.nav.hermesRuntime",scope:"global"},{id:"openclaw-runtime",label:"OpenClaw",labelKey:"settings.nav.openclawRuntime",scope:"global"},{id:"paperclip-runtime",label:"Paperclip",labelKey:"settings.nav.paperclipRuntime",scope:"global"},{id:"__project_header",label:"Project",labelKey:"settings.nav.projectHeader",scope:void 0,isGroupHeader:!0},{id:"general",label:"Project General",labelKey:"settings.nav.projectGeneral",scope:"project"},{id:"commands",label:"Commands & Scripts",labelKey:"settings.nav.commands",scope:"project"},{id:"worktrees",label:"Worktrees",labelKey:"settings.nav.worktrees",scope:"project"},{id:"scheduling",label:"Scheduling & Capacity",labelKey:"settings.nav.scheduling",scope:"project"},{id:"scheduled-evals",label:"Scheduled Evals",labelKey:"settings.nav.scheduledEvals",scope:"project"},{id:"node-routing",label:"Node Routing",labelKey:"settings.nav.nodeRouting",scope:"project"},{id:"merge",label:"Merge",labelKey:"settings.nav.merge",scope:"project"},{id:"agent-permissions",label:"Agents & Permissions",labelKey:"settings.nav.agentPermissions",scope:"project"},{id:"memory",label:"Memory",labelKey:"settings.nav.memory",scope:"project"},{id:"backups",label:"Backups",labelKey:"settings.nav.backups",scope:"project"},{id:"research-project",label:"Research",labelKey:"settings.nav.researchProject",scope:"project"},{id:"project-models",label:"Project Models",labelKey:"settings.nav.projectModels",scope:"project"},{id:"secrets",label:"Secrets",labelKey:"settings.nav.secrets",scope:"project"},{id:"mcp",label:"MCP Servers",labelKey:"settings.nav.mcp",scope:"project"},{id:"prompts",label:"Prompts",labelKey:"settings.nav.prompts",scope:"project"},{id:"plugins",label:"Plugins",labelKey:"settings.nav.plugins",scope:"project"}],Fd={insights:"Insights",memoryView:"Memory Editor",skillsView:"Skills View",nodesView:"Nodes View",devServerView:"Dev Server",todoView:"Todo List",researchView:"Research View",evalsView:"Evals View",goalsView:"Goals View",subtaskBreakdown:"Subtask Breakdown",leftSidebarNav:"Left Sidebar Navigation",sandbox:"Sandbox (command isolation)",chatRooms:"Chat Rooms",agentOnboarding:"Planning-style Agent Onboarding",workflowInterpreterDualObserve:"Workflow Graph Engine — dual-observe parity (diagnostic)"},Dd=new Set(["chatRooms","goalsView","insights","memoryView","remoteAccess","roadmap","rightDock","skillsView","todoView","workflowColumns","workflowGraphExecutor","workflowInterpreterDualObserve"]),Wn=new Set(["leftSidebarNav"]),$t={devServer:"devServerView"};function ta(a){return $t[a]??a}function Ys(a,t){return a[t]===!0?!0:a[t]===!1?!1:Object.entries($t).some(([s,c])=>c===t&&a[s]===!0)?!0:Wn.has(t)}function Ld(a,t){const s=ta(t);return Wn.has(s)&&a[s]===void 0?!0:Ys(a,s)}function Od(a){if(!a)return{};const t={};for(const[s,c]of Object.entries(a))t[ta(s)]=c;for(const[s,c]of Object.entries($t))t[c]!==void 0&&!(s in t)&&(t[s]=null);return t}function Bd(a){const t=new Set,s=[];for(const c of a??[]){const r=c.trim();!r||t.has(r)||(t.add(r),s.push(r))}return s}const $s="global-general";function Gd({projectId:a,addToast:t}){const{t:s}=Z("app"),{confirm:c}=Dn(),[r,m]=o.useState([]),[i,n]=o.useState({}),[p,A]=o.useState({}),[j,u]=o.useState("");o.useEffect(()=>{let f=!1;return(async()=>{try{const[S,w]=await Promise.all([fetch("/api/cli-agents"),fetch("/api/cli-agents/settings")]),I=S.ok?await S.json():{adapters:[]},x=w.ok?await w.json():{cliAgents:{}};if(f)return;const v=I.adapters??[];m(v),n(x.cliAgents??{}),v.length>0&&u(B=>B||v[0].id)}catch{}})(),()=>{f=!0}},[]),o.useEffect(()=>{if(!j)return;let f=!1;return fetch(`/api/cli-agents/${j}/autonomy`).then(S=>S.ok?S.json():null).then(S=>{f||!S||A(w=>({...w,[j]:!!S.approved}))}).catch(()=>{}),()=>{f=!0}},[j]);const d=i[j]??{},C=o.useCallback(async(f,S)=>{try{const w=await fetch("/api/cli-agents/settings",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({adapterId:f,config:S})});if(!w.ok)throw new Error(`HTTP ${w.status}`);const I=await w.json();n(I.cliAgents??{})}catch(w){t(pe(w)||s("settings.cliAgents.saveFailed"),"error")}},[t,s]),b=o.useCallback(f=>{if(!j)return;const S={...d,...f};n(w=>({...w,[j]:S})),C(j,S)},[j,d,C]),h=o.useCallback(async f=>{if(j){if(f==="elevated"){if(!await c({title:s("settings.cliAgents.elevatedConfirmTitle"),message:s("settings.cliAgents.elevatedConfirmBody"),confirmLabel:s("settings.cliAgents.elevatedConfirmAction"),danger:!0}))return;try{const w=await fetch(`/api/cli-agents/${j}/approve-autonomy`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({confirm:!0})});if(!w.ok)throw new Error(`HTTP ${w.status}`);A(I=>({...I,[j]:!0}))}catch(w){t(pe(w)||s("settings.cliAgents.approveFailed"),"error");return}}b({autonomyMode:f})}},[j,c,s,t,b]);return e.jsxs("div",{"data-testid":"cli-agents-settings",children:[e.jsx("h4",{className:"settings-section-heading",children:s("settings.cliAgents.heading")}),e.jsx("p",{className:"settings-section-description",children:s("settings.cliAgents.description")}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"cliAgentAdapter",children:s("settings.cliAgents.adapterLabel")}),e.jsx("select",{id:"cliAgentAdapter",value:j,onChange:f=>u(f.target.value),children:r.map(f=>e.jsxs("option",{value:f.id,children:[f.name," (",s(`settings.cliAgents.tier.${f.tier}`),")"]},f.id))})]}),j&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"cliAgentCommand",children:s("settings.cliAgents.commandLabel")}),e.jsx("input",{id:"cliAgentCommand",type:"text",placeholder:r.find(f=>f.id===j)?.defaultCommand??"",value:d.commandOverride??"",onChange:f=>b({commandOverride:f.target.value||void 0})}),e.jsx("p",{className:"settings-field-help",children:s("settings.cliAgents.commandHelp")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"cliAgentExtraArgs",children:s("settings.cliAgents.extraArgsLabel")}),e.jsx("input",{id:"cliAgentExtraArgs",type:"text",value:(d.extraArgs??[]).join(" "),onChange:f=>b({extraArgs:f.target.value.split(/\s+/).filter(S=>S.length>0)})}),e.jsx("p",{className:"settings-field-help",children:s("settings.cliAgents.extraArgsHelp")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"cliAgentEnv",children:s("settings.cliAgents.envLabel")}),e.jsx("input",{id:"cliAgentEnv",type:"text",value:(d.envAdditions??[]).join(", "),onChange:f=>b({envAdditions:f.target.value.split(",").map(S=>S.trim()).filter(S=>S.length>0)})}),e.jsx("p",{className:"settings-field-help",children:s("settings.cliAgents.envHelp")})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"cliAgentAutonomy",children:s("settings.cliAgents.autonomyLabel")}),e.jsxs("select",{id:"cliAgentAutonomy",value:d.autonomyMode??"default",onChange:f=>void h(f.target.value),children:[e.jsx("option",{value:"default",children:s("settings.cliAgents.autonomy.default")}),e.jsx("option",{value:"elevated",children:s("settings.cliAgents.autonomy.elevated")})]}),e.jsx("p",{className:"settings-field-help",children:p[j]?s("settings.cliAgents.approvedNote"):s("settings.cliAgents.autonomyHelp")})]})]})]})}function _d({onClose:a,addToast:t,projectId:s,initialSection:c,themeMode:r="dark",colorTheme:m="ocean",onThemeModeChange:i,onColorThemeChange:n,dashboardFontScalePct:p=100,shadcnCustomColors:A={},resolvedThemeMode:j,onDashboardFontScaleChange:u,onShadcnCustomColorsChange:d,onQuickChatButtonModeChange:C,onReopenOnboarding:b,onOpenApprovals:h,onOpenWorkflowSettings:f,presentation:S="modal"}){const{isEmbedded:w,scrollLockEnabled:I,resizePersistEnabled:x,escapeEnabled:v,overlayDismissEnabled:B}=Eo(S),{t:k}=Z("app"),{confirm:Y}=Dn(),W=Md(s),J=W.status==="installed",V=ql();zl(I);const{keyboardOverlap:ne,viewportHeight:ae,viewportOffsetTop:$,keyboardOpen:_}=Vl({enabled:V==="mobile"}),T=_?{"--keyboard-overlap":`${ne}px`,"--vv-offset-top":`${$}px`,...ae!==null?{"--vv-height":`${ae}px`}:{}}:{},D=o.useRef(null),re=o.useRef(null),U=o.useRef(null),ie=o.useCallback(l=>{U.current=l},[]);Yl(D,x,"fusion:settings-modal-size");const ve=Ql(),[y,H]=o.useState({maxConcurrent:2,maxTriageConcurrent:2,maxWorktrees:4,pollIntervalMs:15e3,heartbeatMultiplier:1,groupOverlappingFiles:!0,ignoreHiddenOverlapPaths:!0,overlapIgnorePaths:[],autoMerge:!0,planApprovalMode:"workflow",mergeStrategy:"direct",maxAutoMergeRetries:3,mergeIntegrationWorktree:"reuse-task-worktree",mergeAdvanceAutoSync:"stash-and-ff",merger:{mode:"ai",maxReviewPasses:3,allowDirtyLocalCheckoutSync:!0},recycleWorktrees:!1,showWorktreeGrouping:!1,openTasksInRightSidebar:!1,executorAllowSiblingBranchRename:!1,worktreeNaming:"random",worktreeCopyFiles:[],worktreesDir:"",worktrunk:{enabled:!1,binaryPath:"",onFailure:"fail"},includeTaskIdInCommit:!0,worktreeInitCommand:"",ntfyEnabled:!1,ntfyTopic:void 0,ntfyAccessToken:void 0,failureNotificationMode:"sticky-only",failureNotificationDelayMs:3e4,webhookEnabled:!1,webhookUrl:void 0,webhookFormat:"generic",webhookEvents:void 0,prTitlePromptInstructions:"",prDescriptionPromptInstructions:""}),[he,xe]=o.useState(!0),[fe,K]=o.useState(!1),[P,F]=o.useState(null),[X,ce]=o.useState(null),[de,te]=o.useState(null),R=Tn.find(l=>!l.isGroupHeader),[E,z]=o.useState(()=>c==="pi-extensions"?"plugins":c??$s),[N,O]=o.useState(()=>c==="pi-extensions"?"pi-extensions":"fusion-plugins"),[L,Q]=o.useState(()=>typeof window<"u"&&typeof window.matchMedia=="function"?window.matchMedia(An)?.matches===!0:!1),[se,me]=o.useState(null),[le,we]=o.useState(!1),[ge,Ee]=o.useState(null),[Le,sa]=o.useState(!1),[ft,vt]=o.useState(null),tt=Ed(),[$n,Un]=Id(),[Ut,Hn]=o.useState(null),[Kn,st]=o.useState(null),[Se,Ht]=o.useState(null),[aa,na]=o.useState(!1),[Pe,Kt]=o.useState(null),{entries:qn,currentPath:Fe,setPath:qt,loading:zn,error:Vn,refresh:Yn}=As("project",Se!==null,s),{entries:Qn,currentPath:Oe,setPath:zt,loading:Jn,error:Xn,refresh:Zn}=As("project",aa,s),{entries:er,currentPath:Vt,setPath:Yt,loading:tr,error:sr,refresh:ar}=As("project",Pe!==null,s),{nodes:nr}=Jl(),ra=y.experimentalFeatures??{},Qt=Ys(ra,"researchView"),Jt=Ys(ra,"evalsView"),$e=Tn.filter(l=>l.id==="research-global"||l.id==="research-project"?Qt:l.id==="scheduled-evals"?Jt:!0),xt=$e.some(l=>l.id===$s)?$s:$e.find(l=>!l.isGroupHeader)?.id??R?.id??"general",at=$e.find(l=>l.id===E)?.scope;o.useEffect(()=>{if((E==="research-global"||E==="research-project")&&!Qt){z(xt);return}if(E==="scheduled-evals"&&!Jt){z(xt);return}$e.some(l=>l.id===E)||z(xt)},[E,Qt,Jt,xt,$e]);const[Ve,Xt]=o.useState([]),[rr,ia]=o.useState(!1),[ir,Ce]=o.useState(null),[lr,Zt]=o.useState({}),[or,la]=o.useState({}),[es,oa]=o.useState({}),[ts,ss]=o.useState({}),[cr,as]=o.useState(null),[ns,rs]=o.useState({}),[dr,yt]=o.useState({}),[ur,nt]=o.useState({}),je=o.useRef(null),rt=o.useRef({}),[ca,da]=o.useState([]),[ua,ma]=o.useState(!1),[Ye,is]=o.useState([]),[Qe,ls]=o.useState([]),[mr,pa]=o.useState({}),[pr,jt]=o.useState({}),[it,ha]=o.useState(null),[De,ga]=o.useState(null),[hr,os]=o.useState(null),[gr,kt]=o.useState(!1),[Ae,wt]=o.useState(null),[cs,ds]=o.useState(null),[br,ba]=o.useState(null),[fr,fa]=o.useState(!1),[vr,us]=o.useState(null),[xr,yr]=o.useState("persistent"),[jr,kr]=o.useState(null),[wr,Cr]=o.useState(null),[Nr,Sr]=o.useState(null),[Pr,Je]=o.useState(null),[ms,Ct]=o.useState(""),[Ar,va]=o.useState(!1),[ps,Nt]=o.useState(!1),[Mr,xa]=o.useState([]),[Tr,ya]=o.useState([]),[Rr,Ir]=o.useState(!1),[Er,ja]=o.useState([]),[Fr,ka]=o.useState(!1),[Dr,wa]=o.useState(null),[Lr,Ca]=o.useState([]),[Or,Na]=o.useState(!1),[Br,hs]=o.useState(null),gs=o.useRef(!1),[Gr,Sa]=o.useState([]),[Me,bs]=o.useState(Ws),[fs,_r]=o.useState(""),[Wr,Pa]=o.useState(!1),[$r,Aa]=o.useState(null),[Ur,Ma]=o.useState(!1),[Hr,Ta]=o.useState(!1),[Kr,Ra]=o.useState(!1),vs=o.useRef(!1),[St,Ia]=o.useState(4),Ea=o.useRef(4),Fa=o.useRef(!1),xs=o.useRef(!1),[qr,Da]=o.useState(!1),[zr,lt]=o.useState(!1),[,ys]=o.useState(null),[Te,La]=o.useState(null),[Pt,At]=o.useState(!1),[js,Vr]=o.useState("both"),[ks,Yr]=o.useState(!0),Oa=o.useRef(null),{status:Qr,capabilities:Jr,loading:Xr,error:Zr,refresh:Ba}=Ko({projectId:s,enabled:E==="memory"});o.useEffect(()=>{if(typeof window>"u"||typeof window.matchMedia!="function")return;const l=window.matchMedia(An);if(!l)return;const g=M=>{Q(M?M.matches:l.matches)};return g(),l.addEventListener("change",g),()=>l.removeEventListener("change",g)},[]),o.useEffect(()=>{Promise.all([Ya(s),Xl(s)]).then(([l,g])=>{const M={...l,ignoreHiddenOverlapPaths:l.ignoreHiddenOverlapPaths??!0,mergeIntegrationWorktree:Ja(l.mergeIntegrationWorktree),mergeAdvanceAutoSync:Qa(l.mergeAdvanceAutoSync),maxAutoMergeRetries:Mn(l),worktreeCopyFiles:Array.isArray(l.worktreeCopyFiles)?l.worktreeCopyFiles:[]};H(M),F(M),ce(g),te({...g,project:{...g.project,mergeIntegrationWorktree:g.project.mergeIntegrationWorktree===void 0?void 0:Ja(g.project.mergeIntegrationWorktree),mergeAdvanceAutoSync:g.project.mergeAdvanceAutoSync===void 0?void 0:Qa(g.project.mergeAdvanceAutoSync)}}),xe(!1)}).catch(l=>{t(pe(l),"error"),xe(!1)})},[t,s]),o.useEffect(()=>{if(E!=="scheduling"||Fa.current)return;let l=!1;return Zl().then(g=>{l||(xs.current||Ia(g.globalMaxConcurrent),Ea.current=g.globalMaxConcurrent,Fa.current=!0,Da(!0))}).catch(()=>{Da(!0)}),()=>{l=!0}},[E]),o.useEffect(()=>{let l=!1;return eo().then(g=>{l||typeof g.version=="string"&&g.version.trim().length>0&&me(g.version)}).catch(()=>{}),()=>{l=!0}},[]);const ei=o.useCallback(async()=>{we(!0),vt(null);try{const l=await to();Ee(l),l.error&&t(l.error,"error")}catch(l){const g=pe(l)||k("settings.general.updateCheckFailed","Failed to check for updates");Ee({currentVersion:se??"unknown",latestVersion:null,updateAvailable:!1,error:g}),t(g,"error")}finally{we(!1)}},[t,se,k]),Ga=o.useCallback(async()=>{sa(!0),vt(null);try{const l=await so(s);if(vt(l),l.error){t(l.error,"error");return}l.updated&&t(k("settings.general.updateSuccessToast","Update installed. Restart Fusion to apply it."),"success")}catch(l){const g=pe(l)||k("settings.general.updateFailed","Update failed");vt({currentVersion:ge?.currentVersion??se??"unknown",latestVersion:ge?.latestVersion??null,updated:!1,error:g}),t(g,"error")}finally{sa(!1)}},[t,se,s,k,ge]),ti=o.useCallback(()=>{if(!ge)return null;if(ge.error)return ge.error;if(ge.updateAvailable&&ge.latestVersion){const l=ft?.updated===!0,g=ft?.error;return e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:[k("settings.general.updateAvailablePrefix","v{{version}} available",{version:ge.latestVersion})," ·"," ",e.jsx("a",{href:"https://runfusion.ai",target:"_blank",rel:"noreferrer",className:"settings-update-result-link",children:k("settings.general.learnMore","Learn more")})]}),l?e.jsx("span",{className:"settings-update-install-status settings-update-install-status--success","aria-live":"polite",children:k("settings.general.updateSuccess","Updated to v{{version}} — restart Fusion to apply",{version:ft.latestVersion??ge.latestVersion})}):e.jsx("button",{type:"button",className:"btn btn-sm settings-update-now-btn",onClick:()=>{Ga()},disabled:Le,children:Le?e.jsxs(e.Fragment,{children:[e.jsx(Ks,{size:12,className:"spinning","aria-hidden":"true"}),k("settings.general.updating","Updating…")]}):k("settings.general.updateNow","Update now")}),g&&e.jsx("span",{className:"settings-update-install-status settings-update-install-status--error","aria-live":"polite",children:k("settings.general.updateFailedWithMessage","Update failed: {{message}}",{message:g})})]})}return k("settings.general.upToDate","You're up to date ✓")},[Ga,k,ge,Le,ft]),ye=o.useCallback(async()=>{try{const{providers:l}=await Xa(),g=Za(l);Xt(g),Zt(M=>{const G={};for(const[q,ee]of Object.entries(M)){const oe=g.find(be=>be.id===q);oe&&!oe.authenticated&&(G[q]=ee)}return Object.keys(G).length===Object.keys(M).length?M:G})}catch{}},[]);o.useEffect(()=>{(E==="global-models"||E==="project-models")&&(ma(!0),ao().then(l=>{da(l.models),is(l.favoriteProviders),ls(l.favoriteModels)}).catch(()=>da([])).finally(()=>ma(!1)))},[E]),o.useEffect(()=>{E==="backups"&&(kt(!0),en(s).then(l=>os(l)).catch(()=>os(null)).finally(()=>kt(!1)))},[E,s]);const Mt=o.useCallback(async()=>{const[l,g]=await Promise.allSettled([no(s),Ms(s)]);l.status==="fulfilled"&&H(M=>({...M,...l.value.settings})),g.status==="fulfilled"&&(wt(g.value),ds(g.value.externalTunnel??null))},[s]);o.useEffect(()=>{const l=Ae?.state;(l==="running"||l==="starting")&&ds(null)},[Ae?.state]),o.useEffect(()=>{E==="remote"&&Mt().catch(()=>{wt(null)})},[E,Mt]),o.useEffect(()=>{if(E!=="remote")return;const l=Ae?.state;if(l!=="starting"&&l!=="stopping")return;const g=setInterval(()=>{Ms(s).then(M=>{wt(M),ds(M.externalTunnel??null)}).catch(()=>{})},1e3);return()=>clearInterval(g)},[E,s,Ae?.state]),o.useEffect(()=>{if(E!=="remote")return;if(Ae?.state!=="running"){Je(null);return}let l=!1;return(async()=>{try{const g=await Hs("image/svg",{projectId:s,tokenType:"persistent"});if(l)return;Je({url:g.url,qrSvg:g.data??null})}catch{if(l)return;try{const g=await Rn({projectId:s,tokenType:"persistent"});if(l)return;Je({url:g.url,qrSvg:null})}catch{l||Je(null)}}})(),()=>{l=!0}},[E,s,Ae?.state,Ae?.url]),o.useEffect(()=>{if(E!=="remote")return;const l=cs?.url;if(Ae?.state!=="stopped"||!l)return;let g=!1;return(async()=>{try{const M=await Hs("image/svg",{projectId:s,tokenType:"persistent"});if(g)return;Je({url:l,qrSvg:M.data??null})}catch{g||Je({url:l,qrSvg:null})}})(),()=>{g=!0}},[E,cs?.url,s,Ae?.state]),o.useEffect(()=>{E==="worktrees"&&ro(s).then(l=>xa(l)).catch(()=>xa([]))},[E,s]),o.useEffect(()=>{E==="merge"&&io(s).then(l=>{const g=l.map(ee=>ee.name).filter(ee=>typeof ee=="string"&&ee.length>0),M=new Set,G=["main","master","trunk","develop"],q=[];for(const ee of G)g.includes(ee)&&!M.has(ee)&&(q.push(ee),M.add(ee));for(const ee of[...g].sort((oe,be)=>oe.localeCompare(be)))M.has(ee)||(M.add(ee),q.push(ee));ya(q)}).catch(()=>ya([]))},[E,s]),o.useEffect(()=>{if(E!=="general")return;let l=!1;return ka(!0),wa(null),tn(s).then(g=>{l||ja(Rd(g))}).catch(()=>{l||(ja([]),wa("Could not load detected remotes. Enter a custom owner/repo value."))}).finally(()=>{l||ka(!1)}),()=>{l=!0}},[E,s]),o.useEffect(()=>{if(E!=="global-general"||gs.current)return;let l=!1;return Na(!0),hs(null),lo().then(async g=>{const M=await Promise.allSettled(g.map(async oe=>(await tn(oe.id)).map(He=>({value:`${He.owner}/${He.repo}`,label:`${He.owner}/${He.repo}`,source:oe.name}))));if(l)return;const G=new Map;let q=0;for(const oe of M)if(oe.status==="fulfilled"){q+=1;for(const be of oe.value)G.has(be.value)||G.set(be.value,be)}const ee=[...G.values()].sort((oe,be)=>oe.value.localeCompare(be.value));Ca(ee),g.length>0&&q===0&&hs("Could not load remotes from registered projects. Enter a custom owner/repo value."),gs.current=!0}).catch(()=>{l||(Ca([]),hs("Could not load project list. Enter a custom owner/repo value."),gs.current=!0)}).finally(()=>{l||Na(!1)}),()=>{l=!0}},[E,s]),o.useEffect(()=>{if(E!=="memory"||ps)return;if(vs.current){vs.current=!1;return}let l=!1;return va(!0),sn(s).then(async({files:g})=>{if(l)return;Sa(g);const M=g.some(q=>q.path===Me)?Me:g.find(q=>q.path===Ws)?.path??g.find(q=>q.layer==="dreams")?.path??g[0]?.path??Ws;bs(M);const{content:G}=await oo(M,s);l||(Ct(G),Nt(!1))}).catch(g=>{l||(t(pe(g)||"Failed to load project memory","error"),Ct(""))}).finally(()=>{l||va(!1)}),()=>{l=!0}},[E,ps,Me,s,t]),o.useEffect(()=>((E==="authentication"||E==="research-global")&&(ia(!0),ye().finally(()=>ia(!1))),()=>{je.current&&(clearInterval(je.current),je.current=null)}),[E,ye]),o.useEffect(()=>{if(E!=="authentication"||!Ve.some(M=>M.type!=="api_key"&&M.loginInProgress))return;const g=setInterval(()=>{ye()},2e3);return()=>clearInterval(g)},[E,Ve,ye]);const Tt=o.useCallback(()=>{re.current?.scrollTo({top:0,behavior:"smooth"})},[]),Ue=o.useCallback(l=>{if(l in rt.current){const g={...rt.current};delete g[l],rt.current=g}Zt(g=>{if(!(l in g))return g;const M={...g};return delete M[l],M}),la(g=>{if(!(l in g))return g;const M={...g};return delete M[l],M}),ss(g=>{if(!(l in g))return g;const M={...g};return delete M[l],M}),oa(g=>{if(!(l in g))return g;const M={...g};return delete M[l],M})},[]);o.useEffect(()=>{const l=es["github-copilot"];l?.userCode&&rt.current["github-copilot"]!==l.userCode&&(rt.current["github-copilot"]=l.userCode,In(l.userCode))},[es]);const si=o.useCallback(async l=>{const g=Ve.find(M=>M.id===l);if(!(g?.requiresManualCode===!0&&!await Y({title:k("settings.auth.manualPasteTitle","Heads up — manual paste-back required"),message:k("settings.auth.manualPasteMessage","After you sign in with {{name}}, the browser will try to redirect to a localhost address that this dashboard can't reach. The redirect tab will look like it failed. Before that happens, copy the full URL from the browser address bar — you'll paste it back here to finish login. Continue?",{name:g.name}),confirmLabel:k("settings.auth.continueToLogin","Continue to login"),cancelLabel:k("settings.actions.cancel","Cancel")}))){Ce(l),Ue(l);try{const{url:M,instructions:G,manualCode:q,deviceCode:ee}=await co(l);G?.trim()&&!(l==="github-copilot"&&ee)&&Zt(oe=>({...oe,[l]:G})),q&&la(oe=>({...oe,[l]:q})),ee&&l==="github-copilot"&&oa(oe=>({...oe,[l]:ee})),(l!=="github-copilot"||!ee)&&window.open(En(ee?.verificationUri??M),"_blank"),je.current=setInterval(async()=>{try{const{providers:oe}=await Xa(),be=Za(oe);Xt(be);const He=be.find(qi=>qi.id===l);if(He?.authenticated){je.current&&(clearInterval(je.current),je.current=null),Ce(null),Ue(l),t(k("settings.auth.loginSuccessful","Login successful"),"success"),window.dispatchEvent(new CustomEvent(uo,{detail:{providerId:l}})),Tt();return}He?.loginInProgress||(je.current&&(clearInterval(je.current),je.current=null),Ce(null),Ue(l),t(k("settings.auth.loginDidNotComplete","Login did not complete. Please try again."),"error"))}catch{}},2e3)}catch(M){const G=pe(M)||"Login failed";G.includes("already in progress")||typeof M=="object"&&M!==null&&"status"in M&&M.status===409?(t(k("settings.auth.loginAlreadyInProgress","Login already in progress. You can cancel it and retry."),"warning"),await ye()):t(G,"error"),Ce(null),Ue(l)}}},[t,Ve,Ue,Y,ye,Tt]),ai=o.useCallback(async l=>{const g=ts[l]?.trim();if(!g){t(k("settings.auth.pasteRedirectUrlFirst","Paste the full redirect URL or authorization code first."),"warning");return}as(l);try{(await mo(l,g)).submitted?(ss(G=>{if(!(l in G))return G;const q={...G};return delete q[l],q}),t(k("settings.auth.authCodeReceived","Authorization code received. Finishing login…"),"success")):t(k("settings.auth.authCodeAlreadySubmitted","That authorization code was already submitted. Waiting for login…"),"warning")}catch(M){t(pe(M)||"Failed to submit authorization code","error")}finally{as(null)}},[t,ts]),ni=o.useCallback(async l=>{Ce(l),Xt(g=>g.map(M=>M.id===l?{...M,loginInProgress:!1}:M));try{await po(l),Ue(l),await ye().catch(()=>{}),t(k("settings.auth.loginCancelled","Login cancelled"),"success")}catch(g){t(pe(g)||"Failed to cancel login","error")}finally{Ce(null),as(g=>g===l?null:g),je.current&&(clearInterval(je.current),je.current=null)}},[t,Ue,ye]),ri=o.useCallback(async l=>{Ce(l);try{await ho(l),await ye(),t(k("settings.auth.loggedOut","Logged out"),"success")}catch(g){t(pe(g)||"Logout failed","error")}finally{Ce(null)}},[t,ye]),ii=o.useCallback(async l=>{const g=ns[l]?.trim();if(!g){yt(M=>({...M,[l]:"API key is required"}));return}Ce(l),yt(M=>{const G={...M};return delete G[l],G});try{const M=await go(l,g);if(rs(G=>{const q={...G};return delete q[l],q}),await ye(),l==="opencode"||l==="opencode-go"){const G=M.modelsRefreshed,q=M.refreshReason,ee=M.refreshError;ee?nt(oe=>({...oe,[l]:{tone:"error",message:`Saved, but model refresh failed: ${ee}. Make sure the \`opencode\` CLI is installed on PATH.`}})):q==="no-models-from-cli"?nt(oe=>({...oe,[l]:{tone:"error",message:"Saved. The local `opencode` CLI returned no models — run `opencode auth login` and `opencode models opencode --refresh`, then click Save again."}})):typeof G=="number"&&G>0?nt(oe=>({...oe,[l]:{tone:"success",message:`Refreshed ${G} opencode-go models.`}})):nt(oe=>{const be={...oe};return delete be[l],be})}t(k("settings.auth.apiKeySaved","API key saved"),"success"),Tt()}catch(M){yt(G=>({...G,[l]:pe(M)||"Failed to save API key"})),(l==="opencode"||l==="opencode-go")&&nt(G=>{const q={...G};return delete q[l],q})}finally{Ce(null)}},[ns,t,ye,Tt]),li=o.useCallback(async l=>{Ce(l);try{await bo(l),rs(g=>{const M={...g};return delete M[l],M}),yt(g=>{const M={...g};return delete M[l],M}),await ye(),t(k("settings.auth.apiKeyCleared","API key cleared"),"success")}catch(g){t(pe(g)||"Failed to clear API key","error")}finally{Ce(null)}},[t,ye]),oi=o.useCallback(async l=>{if(!((l==="ntfy"||l==="ntfy-message"||l==="ntfy-room")&&(!y.ntfyEnabled||!y.ntfyTopic||!/^[a-zA-Z0-9_-]{1,64}$/.test(y.ntfyTopic)))){if(l==="webhook"){if(!y.webhookEnabled||!y.webhookUrl?.trim())return;try{const g=new URL(y.webhookUrl.trim());if(g.protocol!=="http:"&&g.protocol!=="https:")return}catch{return}}pa(g=>({...g,[l]:!0})),jt(g=>{const M={...g};return delete M[l],M});try{const g={ntfyEnabled:y.ntfyEnabled,ntfyTopic:y.ntfyTopic,...y.ntfyBaseUrl?.trim()?{ntfyBaseUrl:y.ntfyBaseUrl.trim()}:{},...y.ntfyAccessToken?.trim()?{ntfyAccessToken:y.ntfyAccessToken.trim()}:{}},M=l==="ntfy"?g:l==="ntfy-message"?{...g,messageEventType:"message:agent-to-user"}:l==="ntfy-room"?{...g,messageEventType:"message:room"}:{webhookUrl:y.webhookUrl,webhookFormat:y.webhookFormat||"generic"};if((await fo(l==="ntfy-message"||l==="ntfy-room"?"ntfy":l,M,s)).success){const q=l==="ntfy"?"Test notification sent — check your ntfy app!":l==="ntfy-message"?"Message inbox test sent — check your ntfy inbox for the agent-to-user message.":l==="ntfy-room"?"Room reply test sent — check your ntfy inbox for the room reply.":"Test notification sent — check your webhook endpoint!";jt(ee=>({...ee,[l]:{status:"success",message:q}})),t(q,"success")}else{const q=l==="ntfy-message"?"Failed to send message inbox test":l==="ntfy-room"?"Failed to send room reply test":"Failed to send test notification";jt(ee=>({...ee,[l]:{status:"error",message:q}})),t(q,"error")}}catch(g){const M=pe(g)||"Failed to send test notification";jt(G=>({...G,[l]:{status:"error",message:M}})),t(M,"error")}finally{pa(g=>({...g,[l]:!1}))}}},[t,y.ntfyAccessToken,y.ntfyBaseUrl,y.ntfyEnabled,y.ntfyTopic,y.webhookEnabled,y.webhookFormat,y.webhookUrl,s]),ci=o.useCallback(async()=>{kt(!0);try{const l=await vo(s);if(l.success){t(k("settings.backups.backupCreated","Backup created successfully"),"success");const g=await en(s);os(g)}else t(l.error||k("settings.backups.createFailed","Failed to create backup"),"error")}catch(l){t(pe(l)||k("settings.backups.createFailed","Failed to create backup"),"error")}finally{kt(!1)}},[t,s]),di=o.useCallback(async()=>{try{const l=at==="global"?"global":at==="project"?"project":"both",g=await xo(l,s),M=new Blob([JSON.stringify(g,null,2)],{type:"application/json"}),G=URL.createObjectURL(M),q=document.createElement("a"),ee=`fusion-settings-${new Date().toISOString().replace(/[:.]/g,"-").slice(0,19)}.json`;q.href=G,q.download=ee,document.body.appendChild(q),q.click(),document.body.removeChild(q),URL.revokeObjectURL(G);const oe=l==="global"?k("settings.importExport.scopeLabel.global","global"):l==="project"?k("settings.importExport.scopeLabel.project","project"):k("settings.importExport.scopeLabel.all","all");t(k("settings.importExport.exported","Settings exported ({{scope}} scope)",{scope:oe}),"success")}catch(l){t(pe(l)||k("settings.importExport.exportFailed","Failed to export settings"),"error")}},[t,at,s]),ui=o.useCallback(async l=>{const g=l.target.files?.[0];if(g){ys(g),At(!0);try{const M=await g.text(),G=JSON.parse(M);La(G),lt(!0)}catch(M){t(k("settings.importExport.invalidJson","Invalid JSON file: {{error}}",{error:pe(M)}),"error"),ys(null)}finally{At(!1)}}},[t]),mi=o.useCallback(async()=>{if(Te){At(!0);try{const l=await yo(Te,{scope:js,merge:ks},s);if(l.success){const g=[];l.globalCount>0&&g.push(k("settings.importExport.counts.global","{{count}} global",{count:l.globalCount})),l.projectCount>0&&g.push(k("settings.importExport.counts.project","{{count}} project",{count:l.projectCount})),l.workflowSettingsCount>0&&g.push(k("settings.importExport.counts.workflowSettings","{{count}} workflow setting value",{count:l.workflowSettingsCount})),t(k("settings.importExport.imported","Imported {{counts}} setting(s)",{counts:g.join(", ")}),"success"),lt(!1),La(null),ys(null);const M=await Ya(s);H({...M,ignoreHiddenOverlapPaths:M.ignoreHiddenOverlapPaths??!0})}else t(l.error||k("settings.importExport.importFailed","Import failed"),"error")}catch(l){t(pe(l)||k("settings.importExport.importFailedDetailed","Failed to import settings"),"error")}finally{At(!1)}}},[t,Te,js,ks,s]),_a=o.useCallback(async l=>{const g=Ye,G=g.includes(l)?g.filter(q=>q!==l):[l,...g];is(G);try{await pt({favoriteProviders:G,favoriteModels:Qe})}catch{is(g)}},[Ye,Qe]),Wa=o.useCallback(async l=>{const g=Qe,G=g.includes(l)?g.filter(q=>q!==l):[l,...g];ls(G);try{await pt({favoriteProviders:Ye,favoriteModels:G})}catch{ls(g)}},[Qe,Ye]);o.useEffect(()=>{if(!v)return;const l=g=>{g.key==="Escape"&&a()};return document.addEventListener("keydown",l),()=>document.removeEventListener("keydown",l)},[a,v]);const pi=jo(a),hi=B?pi:{},$a=[{laneId:"default",label:"Default Model",globalProviderKey:"defaultProvider",globalModelKey:"defaultModelId",projectProviderKey:"defaultProviderOverride",projectModelKey:"defaultModelIdOverride",helperText:"Default AI model used for task execution when no per-task override is set.",fallbackOrder:"Project override → Global default lane → Automatic resolution"},{laneId:"execution",label:"Execution Model",globalProviderKey:"executionGlobalProvider",globalModelKey:"executionGlobalModelId",projectProviderKey:"executionProvider",projectModelKey:"executionModelId",helperText:"AI model used for task implementation (executor agent).",fallbackOrder:"Project override → Global execution lane → Global default lane → Automatic resolution"},{laneId:"planning",label:"Planning Model",globalProviderKey:"planningGlobalProvider",globalModelKey:"planningGlobalModelId",projectProviderKey:"planningProvider",projectModelKey:"planningModelId",helperText:"AI model used for task planning.",fallbackOrder:"Project override → Global planning lane → Global default lane → Automatic resolution"},{laneId:"validator",label:"Reviewer Model",globalProviderKey:"validatorGlobalProvider",globalModelKey:"validatorGlobalModelId",projectProviderKey:"validatorProvider",projectModelKey:"validatorModelId",helperText:"AI model used for code and specification review.",fallbackOrder:"Project override → Global reviewer lane → Global default lane → Automatic resolution"},{laneId:"summarization",label:"Title and Git Commit Message Summarization Model",globalProviderKey:"titleSummarizerGlobalProvider",globalModelKey:"titleSummarizerGlobalModelId",projectProviderKey:"titleSummarizerProvider",projectModelKey:"titleSummarizerModelId",helperText:"AI model used for auto-generating task titles and merge commit summaries.",fallbackOrder:"Project override → Global summarization lane → Project planning lane → Project default lane → Global default lane → Automatic resolution"}];function ws(l){if(!X?.project)return"inherited";const g=X.project[l.projectProviderKey],M=X.project[l.projectModelKey];return g!==void 0||M!==void 0?"overridden":"inherited"}function gi(l){const g=y[l.projectProviderKey],M=y[l.projectModelKey];return g&&M?`${g}/${M}`:""}function bi(l,g){if(g){const M=g.indexOf("/");H(G=>({...G,[l.projectProviderKey]:g.slice(0,M),[l.projectModelKey]:g.slice(M+1)}))}else{if(ws(l)==="inherited")return;H(G=>({...G,[l.projectProviderKey]:void 0,[l.projectModelKey]:void 0}))}}function fi(l){ws(l)!=="inherited"&&H(M=>({...M,[l.projectProviderKey]:void 0,[l.projectModelKey]:void 0}))}const vi=o.useCallback(l=>{Ht(l),qt(".")},[qt]),Be=o.useCallback(()=>{Ht(null)},[]),Cs=o.useCallback(l=>{Se!==null&&(H(g=>{const M=g.overlapIgnorePaths&&g.overlapIgnorePaths.length>0?[...g.overlapIgnorePaths]:[""];return M[Se]=l,{...g,overlapIgnorePaths:M}}),Be())},[Se,Be]),xi=o.useCallback(()=>{if(Fe===".")return;const l=Fe.endsWith("/")?Fe:`${Fe}/`;Cs(l)},[Fe,Cs]),yi=o.useCallback(l=>{l.target===l.currentTarget&&Be()},[Be]),ji=o.useCallback(()=>{zt("."),na(!0)},[zt]),Ge=o.useCallback(()=>{na(!1)},[]),ki=o.useCallback(l=>{const g=l.endsWith("/")?l:`${l}/`;H(M=>({...M,worktreesDir:g})),Ge()},[Ge]),wi=o.useCallback(()=>{const l=Oe==="."?"./":Oe.endsWith("/")?Oe:`${Oe}/`;H(g=>({...g,worktreesDir:l})),Ge()},[Oe,Ge]),Ci=o.useCallback(l=>{l.target===l.currentTarget&&Ge()},[Ge]),Ni=o.useCallback(l=>{Kt(l),Yt(".")},[Yt]),_e=o.useCallback(()=>{Kt(null)},[]),Si=o.useCallback(l=>{Pe!==null&&(H(g=>{const M=g.worktreeCopyFiles&&g.worktreeCopyFiles.length>0?[...g.worktreeCopyFiles]:[""];return M[Pe]=l,{...g,worktreeCopyFiles:M}}),_e())},[Pe,_e]),Pi=o.useCallback(l=>{l.target===l.currentTarget&&_e()},[_e]),Ai=o.useCallback((l,g)=>{H(M=>{const G=M.worktreeCopyFiles&&M.worktreeCopyFiles.length>0?[...M.worktreeCopyFiles]:[""];return G[l]=g,{...M,worktreeCopyFiles:G}})},[]),Mi=o.useCallback(l=>{if(H(g=>{const G=(g.worktreeCopyFiles&&g.worktreeCopyFiles.length>0?[...g.worktreeCopyFiles]:[""]).filter((q,ee)=>ee!==l);return{...g,worktreeCopyFiles:G.length>0?G:[]}}),Pe===l){_e();return}Pe!==null&&Pe>l&&Kt(Pe-1)},[Pe,_e]),Ti=o.useCallback(()=>{H(l=>{const g=l.worktreeCopyFiles&&l.worktreeCopyFiles.length>0?l.worktreeCopyFiles:[""];return{...l,worktreeCopyFiles:[...g,""]}})},[]),Ri=o.useCallback((l,g)=>{H(M=>{const G=M.overlapIgnorePaths&&M.overlapIgnorePaths.length>0?[...M.overlapIgnorePaths]:[""];return G[l]=g,{...M,overlapIgnorePaths:G}})},[]),Ii=o.useCallback(l=>{if(H(g=>{const G=(g.overlapIgnorePaths&&g.overlapIgnorePaths.length>0?[...g.overlapIgnorePaths]:[""]).filter((q,ee)=>ee!==l);return{...g,overlapIgnorePaths:G.length>0?G:[]}}),Se===l){Be();return}Se!==null&&Se>l&&Ht(Se-1)},[Se,Be]),Ei=o.useCallback(()=>{H(l=>{const g=l.overlapIgnorePaths&&l.overlapIgnorePaths.length>0?l.overlapIgnorePaths:[""];return{...l,overlapIgnorePaths:[...g,""]}})},[]),Fi=o.useCallback(async()=>{if(fe||Ut||De)return;const l=y.researchSettings?.limits;if(l?.maxConcurrentRuns!==void 0&&(!Number.isFinite(l.maxConcurrentRuns)||l.maxConcurrentRuns<1)){st("Research max concurrent runs must be at least 1.");return}if(l?.maxSourcesPerRun!==void 0&&(!Number.isFinite(l.maxSourcesPerRun)||l.maxSourcesPerRun<1)){st("Research max sources per run must be at least 1.");return}if(l?.maxDurationMs!==void 0&&(!Number.isFinite(l.maxDurationMs)||l.maxDurationMs<1e3)){st("Research max duration must be at least 1000 ms.");return}if(l?.requestTimeoutMs!==void 0&&(!Number.isFinite(l.requestTimeoutMs)||l.requestTimeoutMs<1e3)){st("Research request timeout must be at least 1000 ms.");return}st(null),K(!0);try{const g=Bd(y.worktreeCopyFiles),M={...y,worktreeInitCommand:y.worktreeInitCommand?.trim()||void 0,worktreesDir:y.worktreesDir?.trim()||void 0,worktrunk:{enabled:J&&y.worktrunk?.enabled===!0,binaryPath:y.worktrunk?.binaryPath?.trim()||void 0,onFailure:y.worktrunk?.onFailure??"fail"},maxAutoMergeRetries:Mn(y),taskPrefix:y.taskPrefix?.trim()||void 0,githubTrackingDefaultRepo:y.githubTrackingDefaultRepo?.trim()||void 0,githubAuthToken:y.githubAuthToken?.trim()||void 0,prTitlePromptInstructions:y.prTitlePromptInstructions?.trim()||void 0,prDescriptionPromptInstructions:y.prDescriptionPromptInstructions?.trim()||void 0,overlapIgnorePaths:(y.overlapIgnorePaths??[]).map(ee=>ee.trim()).filter(ee=>ee.length>0),worktreeCopyFiles:g.length>0||de?.project?.worktreeCopyFiles!==void 0?g:void 0,experimentalFeatures:Od(y.experimentalFeatures)},{globalPatch:G,projectPatch:q}=rc({payload:M,initialValues:P,initialScopedValues:de,activeSection:E});await Promise.all([Object.keys(G).length>0?pt(G):Promise.resolve(),Object.keys(q).length>0?ko(q,s):Promise.resolve(),St!==Ea.current?wo({globalMaxConcurrent:St??4}):Promise.resolve()]),await U.current?.(),t(k("settings.general.settingsSaved","Settings saved"),"success"),a()}catch(g){if(g instanceof _n)return;t(pe(g),"error")}finally{K(!1)}},[y,St,Ut,De,P,de,a,t,s,E,fe,k]),Di=o.useCallback(async()=>{try{await Co(Me,ms,s),Nt(!1),t(k("settings.memory.memorySaved","Memory saved"),"success")}catch(l){t(pe(l)||"Failed to save memory","error")}},[Me,ms,s,t]),Li=o.useCallback(async()=>{Ta(!0);try{const{path:l,content:g}=await No(Me,s),M=l??Me;Me!==M&&(vs.current=!0),bs(M),Ct(g),Nt(!1);const{files:G}=await sn(s);Sa(G),t(k("settings.memory.memoryCompacted","Memory file compacted"),"success")}catch(l){t(pe(l)||"Failed to compact memory","error")}finally{Ta(!1)}},[Me,s,t]),Oi=o.useCallback(async()=>{Pa(!0),Aa(null);try{const l=await So(fs,s);Aa(l),t(l.qmdAvailable?"Memory retrieval test complete":"qmd is not installed; local fallback was used",l.qmdAvailable?"success":"warning")}catch(l){t(pe(l)||"Failed to test memory retrieval","error")}finally{Pa(!1)}},[fs,s,t]),Bi=o.useCallback(async()=>{Ma(!0);try{await Po(s),t(k("settings.memory.dreamCompleted","Dream processing completed"),"success")}catch(l){t(l instanceof Error?l.message:"Failed to run dream processing","error")}finally{Ma(!1)}},[s,t]),Gi=o.useCallback(async()=>{Ra(!0);try{const l=await Ao(s);await Ba(),t(l.qmdAvailable?k("settings.memory.qmdInstalled","qmd installed successfully"):k("settings.memory.qmdInstallUnavailable","qmd install finished, but qmd is still unavailable"),l.qmdAvailable?"success":"warning")}catch(l){t(pe(l)||k("settings.memory.qmdInstallFailed","Failed to install qmd"),"error")}finally{Ra(!1)}},[s,Ba,t]),_i=()=>{if(!De)return;const l=De.name.trim();if(!l){t(k("settings.models.presetNameRequired","Preset name is required"),"error");return}const g=y.modelPresets||[];let M;it?M=it:M=Do(l,g);const G={id:M,name:l,executorProvider:De.executorProvider,executorModelId:De.executorModelId,validatorProvider:De.validatorProvider,validatorModelId:De.validatorModelId};H(q=>{const ee=q.modelPresets||[],oe=it?ee.map(be=>be.id===it?G:be):[...ee,G];return{...q,modelPresets:oe}}),ha(null),ga(null)},Wi=o.useCallback(async(l,g)=>{ba(l);try{await g(),await Mt()}catch(M){t(pe(M)||`Failed to ${l}`,"error")}finally{ba(null)}},[t,Mt]),$i=o.useCallback(()=>{if(typeof navigator<"u"&&navigator.userAgent.includes("Windows"))return"winget install Cloudflare.cloudflared";const l=typeof navigator<"u"?navigator.platform:"",g=typeof navigator<"u"?navigator.userAgent:"",M=/(Mac|iPhone|iPad|iPod)/i.test(l),G=/(arm64|aarch64)/i.test(`${l} ${g}`);return M?"brew install cloudflared":`curl -L --output /tmp/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${G?"arm64":"amd64"} && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared # If sudo is unavailable, use: mkdir -p ~/.local/bin && mv /tmp/cloudflared ~/.local/bin/cloudflared`},[]),Ui=o.useCallback(()=>typeof navigator>"u"||!/(Mac|iPhone|iPad|iPod)/i.test(navigator.platform)?null:`curl -L --output /tmp/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-darwin-${/(arm64|aarch64)/i.test(`${navigator.platform} ${navigator.userAgent}`)?"arm64":"amd64"} && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared`,[]),Hi=o.useCallback(async()=>{fa(!0),us(null);try{const l=await Mo(s);if(!l.success){us(l.error??k("settings.remote.installationFailed","Installation failed"));return}const g=await Ms(s);wt(g),t(k("settings.remote.cloudflaredInstalled","cloudflared installed successfully"),"success")}catch(l){us(l instanceof Error?l.message:k("settings.remote.installationFailed","Installation failed"))}finally{fa(!1)}},[t,s]),ue=()=>at==="global"?e.jsxs("div",{className:"settings-scope-banner settings-scope-global",children:[e.jsx("span",{className:"settings-scope-icon",children:e.jsx(gt,{size:14})}),e.jsx("span",{children:k("settings.scope.globalBanner","These settings are shared across all your Fusion projects.")})]}):at==="project"?e.jsxs("div",{className:"settings-scope-banner settings-scope-project",children:[e.jsx("span",{className:"settings-scope-icon",children:e.jsx(an,{size:14})}),e.jsx("span",{children:k("settings.scope.projectBanner","These settings only affect this project.")})]}):null,Ki=()=>{switch(E){case"cli-agents":return e.jsxs(e.Fragment,{children:[ue(),e.jsx(Gd,{projectId:s,addToast:t})]});case"general":return e.jsx(sd,{scopeBanner:ue(),form:y,setForm:H,projectId:s,addToast:t,prefixError:Ut,setPrefixError:Hn,projectTrackingRepoOptions:Er,projectTrackingRepoLoading:Fr,projectTrackingRepoError:Dr,onQuickChatButtonModeChange:C});case"global-general":return e.jsx(fc,{scopeBanner:ue(),form:y,setForm:H,globalTrackingRepoOptions:Lr,globalTrackingRepoLoading:Or,globalTrackingRepoError:Br});case"global-models":return e.jsx(Tc,{scopeBanner:ue(),form:y,setForm:H,availableModels:ca,modelsLoading:ua,globalModelLanes:$a.filter(l=>l.laneId!=="default"),favoriteProviders:Ye,favoriteModels:Qe,onToggleFavorite:_a,onToggleModelFavorite:Wa,addToast:t,projectId:s});case"secrets":return e.jsx(Qc,{scopeBanner:ue(),addToast:t});case"global-mcp":return e.jsx(Nc,{scopeBanner:ue(),form:y,setForm:H,projectId:s,addToast:t});case"mcp":return e.jsx(Cd,{scopeBanner:ue(),form:y,setForm:H,globalSettings:X?.global??null,projectId:s,addToast:t});case"project-models":return e.jsx(id,{scopeBanner:ue(),form:y,setForm:H,projectId:s,addToast:t,onOpenWorkflowSettings:f,registerWorkflowLaneSaver:ie,models:{modelLanes:$a,getLaneStatus:ws,getLaneValue:gi,updateLaneValue:bi,resetLaneValue:fi,availableModels:ca,modelsLoading:ua,favoriteProviders:Ye,favoriteModels:Qe,onToggleFavorite:_a,onToggleModelFavorite:Wa,editingPresetId:it,setEditingPresetId:ha,presetDraft:De,setPresetDraft:ga,onSavePresetDraft:_i,confirmDelete:Y}});case"appearance":return e.jsx(uc,{scopeBanner:ue(),form:y,setForm:H,themeMode:r,colorTheme:m,dashboardFontScalePct:p,shadcnCustomColors:A,resolvedThemeMode:j,onThemeModeChange:i,onColorThemeChange:n,onDashboardFontScaleChange:u,onShadcnCustomColorsChange:d,sessionBannersHidden:ve,setSessionBannersHidden:Fo});case"scheduling":return e.jsx(od,{scopeBanner:ue(),form:y,setForm:H,globalMaxConcurrent:St,concurrencyLoading:E==="scheduling"&&!qr&&!xs.current,onGlobalMaxConcurrentChange:l=>{xs.current=!0,Ia(l)},onOverlapIgnorePathChange:Ri,onOpenOverlapPathPicker:vi,onRemoveOverlapIgnorePath:Ii,onAddOverlapIgnorePath:Ei,onOpenWorkflowSettings:f});case"scheduled-evals":return e.jsx(cd,{scopeBanner:ue(),form:y,setForm:H});case"node-routing":return e.jsx(ud,{scopeBanner:ue(),form:y,setForm:H,nodes:nr});case"worktrees":return e.jsx(md,{scopeBanner:ue(),form:y,setForm:H,gitRemotes:Mr,worktrunkInstall:W,worktrunkInstallVerified:J,onOpenWorktreesDirPicker:ji,onWorktreeCopyFileChange:Ai,onRemoveWorktreeCopyFile:Mi,onAddWorktreeCopyFile:Ti,onOpenWorktreeCopyFilePicker:Ni,onOpenApprovals:h});case"commands":return e.jsx(pd,{scopeBanner:ue(),form:y,setForm:H});case"merge":return e.jsx(bd,{scopeBanner:ue(),form:y,setForm:H,integrationBranchOptions:Tr,integrationBranchCustomMode:Rr,setIntegrationBranchCustomMode:Ir,onOpenWorkflowSettings:f});case"agent-permissions":return e.jsx(vd,{scopeBanner:ue(),form:y,setForm:H});case"memory":return e.jsx(kd,{scopeBanner:ue(),form:y,setForm:H,memory:{memoryCapabilities:Jr,memoryBackendStatus:Qr,memoryBackendLoading:Xr,memoryBackendError:Zr,memoryFiles:Gr,selectedMemoryPath:Me,setSelectedMemoryPath:bs,memoryContent:ms,setMemoryContent:Ct,memoryLoading:Ar,memoryDirty:ps,setMemoryDirty:Nt,memoryTestQuery:fs,setMemoryTestQuery:_r,memoryTestLoading:Wr,memoryTestResult:$r,qmdInstallLoading:Kr,dreamRunning:Ur,memoryCompactLoading:Hr,onInstallQmd:Gi,onTestMemoryRetrieval:Oi,onDreamNow:Bi,onCompactMemory:Li,onSaveMemory:Di}});case"research-global":return e.jsx(vc,{scopeBanner:ue(),form:y,setForm:H,authProviders:Ve,onNavigateToSection:z});case"research-project":return e.jsx(wd,{scopeBanner:ue(),form:y,setForm:H,researchLimitError:Kn});case"experimental":return e.jsx(mc,{scopeBanner:ue(),form:y,setForm:H,knownFeatures:Fd,legacyAliases:$t,getCanonicalKey:ta,isFeatureEnabled:Ld,hiddenFeatureKeys:Dd});case"backups":return e.jsx(Nd,{scopeBanner:ue(),form:y,setForm:H,backupInfo:hr,backupLoading:gr,onBackupNow:ci});case"notifications":return e.jsx(hc,{scopeBanner:ue(),form:y,setForm:H,testNotificationLoading:mr,testNotificationResult:pr,onTestProviderNotification:oi});case"node-sync":return e.jsx(pc,{scopeBanner:ue(),form:y,setForm:H});case"remote":return e.jsx(xc,{scopeBanner:ue(),form:y,setForm:H,remote:{projectId:s,addToast:t,remoteStatus:Ae,externalTunnel:cs,tunnelShareLink:Pr,remoteBusyAction:br,cloudflaredInstalling:fr,cloudflaredInstallError:vr,cloudflaredManualInstallCommand:$i,cloudflaredMacFallbackCommand:Ui,handleInstallCloudflared:Hi,runRemoteAction:Wi,remoteShortLivedToken:Nr,setRemoteShortLivedToken:Sr,remoteAuthLinkTokenType:xr,setRemoteAuthLinkTokenType:yr,remoteUrlPreview:jr,setRemoteUrlPreview:kr,remoteQrSvg:wr,setRemoteQrSvg:Cr}});case"prompts":return e.jsx(td,{scopeBanner:ue(),form:y,setForm:H,onOpenWorkflowSettings:f});case"plugins":return e.jsx(Ad,{scopeBanner:ue(),projectId:s,addToast:t,activePluginsSubsection:N,setActivePluginsSubsection:O});case"authentication":return e.jsx(Dc,{auth:{projectId:s,addToast:t,authProviders:Ve,authLoading:rr,authActionInProgress:ir,apiKeyInputs:ns,setApiKeyInputs:rs,apiKeyErrors:dr,opencodeApiKeyRefreshStatus:ur,deviceCodes:es,loginInstructions:lr,manualCodeConfigs:or,manualCodeInputs:ts,setManualCodeInputs:ss,manualCodeSubmitInProgress:cr,loadAuthStatus:ye,handleLogin:si,handleLogout:ri,handleCancelLogin:ni,handleSaveApiKey:ii,handleClearApiKey:li,handleSubmitManualCode:ai,onReopenOnboarding:b}});case"hermes-runtime":return e.jsx(zc,{});case"openclaw-runtime":return e.jsx(Vc,{});case"paperclip-runtime":return e.jsx(Yc,{})}};return e.jsxs("div",{className:w?"settings-embedded right-dock-embedded-view":"modal-overlay open settings-modal-overlay",...hi,"data-testid":w?"settings-view":void 0,role:w?"region":"dialog","aria-label":w?k("settings.title","Settings"):void 0,"aria-modal":w?void 0:"true",children:[e.jsxs("div",{className:w?"modal modal-lg settings-modal settings-modal--embedded":"modal modal-lg settings-modal",ref:D,style:w?void 0:T,children:[e.jsxs("div",{className:w?"modal-header modal-header--embedded":"modal-header",children:[e.jsx("div",{className:"settings-modal-heading",children:e.jsxs("h3",{children:[w&&e.jsx(To,{size:20,"aria-hidden":"true"}),e.jsx("span",{children:k("settings.title","Settings")})]})}),e.jsxs("div",{className:"settings-header-actions",children:[e.jsxs("a",{href:"https://github.com/Runfusion/Fusion",target:"_blank",rel:"noopener noreferrer",className:"settings-github-star-btn","aria-label":k("settings.header.starFusion","Star Fusion on GitHub"),title:k("settings.header.starFusion","Star Fusion on GitHub"),onClick:Un,"data-clicked":$n?"true":"false",children:[e.jsxs("span",{className:"settings-github-star-btn__action",children:[e.jsx(bt,{provider:"github",size:"sm"}),e.jsx(Ro,{size:11,"aria-hidden":"true"}),k("settings.header.star","Star")]}),tt!==null&&e.jsx("span",{className:"settings-github-star-btn__count","aria-label":`${tt.toLocaleString()} stars`,children:tt>=1e3?`${(tt/1e3).toFixed(1)}k`:tt.toLocaleString()})]}),e.jsxs("a",{href:"https://discord.gg/ksrfuy7WYR",target:"_blank",rel:"noopener noreferrer",className:"btn btn-sm settings-header-discord-btn","aria-label":k("settings.header.joinDiscord","Join our Discord"),title:k("settings.header.joinDiscord","Join our Discord"),children:[e.jsx(Td,{size:13}),k("settings.header.discord","Discord")]})]}),!w&&e.jsx("button",{className:"modal-close",onClick:a,"aria-label":k("actions.close","Close"),children:"×"})]}),he?e.jsx("div",{className:"settings-empty-state settings-loading",children:e.jsx(ze,{label:k("settings.loading","Loading…")})}):e.jsxs("div",{className:"settings-layout",children:[L&&e.jsxs("div",{className:"settings-mobile-section-picker",children:[e.jsx("label",{htmlFor:"settings-mobile-section",children:k("settings.mobileNav.label","Settings Section")}),e.jsx("select",{id:"settings-mobile-section",className:"select touch-target",value:E,onChange:l=>z(l.target.value),children:$e.filter(l=>!l.isGroupHeader).map(l=>e.jsx("option",{value:l.id,children:k(l.labelKey,l.label)},l.id))})]}),e.jsx("nav",{className:"settings-sidebar",children:$e.map(l=>l.isGroupHeader?e.jsx("div",{className:"settings-group-header",children:k(l.labelKey,l.label)},l.id):e.jsxs("button",{className:`settings-nav-item${E===l.id?" active":""}`,onClick:()=>z(l.id),title:l.scope==="global"?k("settings.nav.tooltip.global","Shared across all projects"):l.scope==="project"?k("settings.nav.tooltip.project","Specific to this project"):void 0,children:[l.scope==="global"&&e.jsx(gt,{className:"settings-scope-icon","aria-label":k("settings.nav.aria.global","Global setting"),size:16}),l.scope==="project"&&e.jsx(an,{className:"settings-scope-icon","aria-label":k("settings.nav.aria.project","Project setting"),size:16}),l.icon&&!l.scope&&e.jsx(l.icon,{className:"settings-scope-icon","aria-label":k("settings.nav.aria.global","Global setting"),size:16}),k(l.labelKey,l.label)]},l.id))}),e.jsx("div",{className:"settings-content",ref:re,children:Ki()})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsxs("div",{className:"settings-modal-footer-version",children:[e.jsxs("a",{href:"https://github.com/Runfusion/Fusion/discussions",target:"_blank",rel:"noopener noreferrer",className:"btn btn-sm settings-footer-help-btn","aria-label":k("settings.footer.helpDiscussions","Help and discussions"),title:k("settings.footer.helpDiscussions","Help and discussions"),children:[e.jsx(Io,{size:13,"aria-hidden":"true"}),k("settings.footer.help","Help")]}),e.jsxs("div",{className:"settings-update-check",children:[se&&e.jsxs("button",{type:"button",className:"settings-version-check-btn",onClick:()=>{ei()},disabled:le,"aria-label":k("settings.footer.checkUpdates","Check for updates"),title:k("settings.footer.checkUpdates","Check for updates"),children:[e.jsx("span",{className:"settings-modal-version",children:k("settings.footer.version","Version {{version}}",{version:se})}),e.jsx(Ks,{size:12,className:le?"spinning":void 0})]}),ge&&e.jsx("span",{"aria-live":"polite",className:`settings-update-result ${ge.error?"settings-update-result--error":ge.updateAvailable?"settings-update-result--available":"settings-update-result--up-to-date"}`,children:ti()})]})]}),e.jsxs("div",{className:"modal-actions-left",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:di,title:k("settings.importExport.exportTitle","Export settings to JSON file"),children:k("settings.importExport.exportBtn","Export")}),e.jsx("input",{type:"file",ref:Oa,accept:".json,application/json",style:{display:"none"},onChange:ui}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>Oa.current?.click(),disabled:Pt,title:k("settings.importExport.importTitleAttr","Import settings from JSON file"),children:Pt?k("settings.importExport.loadingFile","Loading…"):k("settings.importExport.importBtn","Import")})]}),e.jsxs("div",{className:"modal-actions-right",children:[!w&&e.jsx("button",{className:"btn btn-sm",onClick:a,children:k("settings.actions.cancel","Cancel")}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:Fi,disabled:he||fe,children:k("settings.actions.save","Save")})]})]})]}),Se!==null&&e.jsx("div",{className:"modal-overlay open",onClick:yi,role:"dialog","aria-modal":"true","aria-label":k("settings.scheduling.browseWorkspacePath","Browse workspace path"),children:e.jsxs("div",{className:"modal modal-lg settings-overlap-path-picker-modal",onClick:l=>l.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:k("settings.scheduling.selectIgnoredOverlapPath","Select ignored overlap path")}),e.jsx("button",{className:"modal-close",onClick:Be,"aria-label":k("actions.close","Close"),children:"×"})]}),e.jsxs("div",{className:"modal-body settings-overlap-path-picker-body",children:[e.jsx("p",{className:"settings-overlap-path-picker-note",children:k("settings.scheduling.overlapPickerNote","Choose a file to ignore directly, or navigate into a folder and select the current directory.")}),e.jsx(Ts,{entries:qn,currentPath:Fe,onSelectFile:Cs,onNavigate:qt,loading:zn,error:Vn,onRetry:Yn,workspace:"project",projectId:s})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("div",{className:"modal-actions-left",children:e.jsxs("small",{children:[k("settings.fileBrowser.currentDirectory","Current directory:")," ",e.jsx("code",{children:Fe==="."?k("settings.fileBrowser.projectRoot","(project root)"):Fe})]})}),e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn btn-sm",onClick:Be,children:k("settings.actions.cancel","Cancel")}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:xi,disabled:Fe===".",children:k("settings.scheduling.selectCurrentDir","Select current directory")})]})]})]})}),aa&&e.jsx("div",{className:"modal-overlay open",onClick:Ci,role:"dialog","aria-modal":"true","aria-label":k("settings.worktrees.browseWorktreesDirectory","Browse worktrees directory"),children:e.jsxs("div",{className:"modal modal-lg settings-overlap-path-picker-modal",onClick:l=>l.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:k("settings.worktrees.selectWorktreesDir","Select worktrees directory")}),e.jsx("button",{className:"modal-close",onClick:Ge,"aria-label":k("actions.close","Close"),children:"×"})]}),e.jsxs("div",{className:"modal-body settings-overlap-path-picker-body",children:[e.jsx("p",{className:"settings-overlap-path-picker-note",children:k("settings.worktrees.worktreesPickerNote","Navigate to the folder where Fusion should create task worktrees, then select the current directory.")}),e.jsx(Ts,{entries:Qn,currentPath:Oe,onSelectFile:ki,onNavigate:zt,loading:Jn,error:Xn,onRetry:Zn,workspace:"project",projectId:s})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("div",{className:"modal-actions-left",children:e.jsxs("small",{children:[k("settings.fileBrowser.currentDirectory","Current directory:")," ",e.jsx("code",{children:Oe==="."?k("settings.fileBrowser.projectRoot","(project root)"):Oe})]})}),e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn btn-sm",onClick:Ge,children:k("settings.actions.cancel","Cancel")}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:wi,children:k("settings.scheduling.selectCurrentDir","Select current directory")})]})]})]})}),Pe!==null&&e.jsx("div",{className:"modal-overlay open",onClick:Pi,role:"dialog","aria-modal":"true","aria-label":k("settings.worktrees.browseCopyFile","Browse file to copy into new worktrees"),children:e.jsxs("div",{className:"modal modal-lg settings-overlap-path-picker-modal",onClick:l=>l.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:k("settings.worktrees.selectCopyFile","Select file to copy")}),e.jsx("button",{className:"modal-close",onClick:_e,"aria-label":k("actions.close","Close"),children:"×"})]}),e.jsxs("div",{className:"modal-body settings-overlap-path-picker-body",children:[e.jsx("p",{className:"settings-overlap-path-picker-note",children:k("settings.worktrees.copyFilePickerNote","Choose a repository file to copy into each newly assigned task worktree. Directories are not selected from this picker.")}),e.jsx(Ts,{entries:er,currentPath:Vt,onSelectFile:Si,onNavigate:Yt,loading:tr,error:sr,onRetry:ar,workspace:"project",projectId:s})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("div",{className:"modal-actions-left",children:e.jsxs("small",{children:[k("settings.fileBrowser.currentDirectory","Current directory:")," ",e.jsx("code",{children:Vt==="."?k("settings.fileBrowser.projectRoot","(project root)"):Vt})]})}),e.jsx("div",{className:"modal-actions-right",children:e.jsx("button",{className:"btn btn-sm",onClick:_e,children:k("settings.actions.cancel","Cancel")})})]})]})}),zr&&Te&&e.jsx("div",{className:"modal-overlay open",onClick:l=>l.target===l.currentTarget&&lt(!1),role:"dialog","aria-modal":"true",children:e.jsxs("div",{className:"modal modal-md",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:k("settings.importExport.importTitle","Import Settings")}),e.jsx("button",{className:"modal-close",onClick:()=>lt(!1),"aria-label":k("actions.close","Close"),children:"×"})]}),e.jsxs("div",{className:"modal-body",children:[e.jsx("p",{children:k("settings.importExport.reviewPrompt","Review the settings to be imported:")}),Te.global&&Object.keys(Te.global).length>0&&e.jsxs("div",{className:"form-group",children:[e.jsx("strong",{children:k("settings.importExport.globalSettings","Global Settings:")}),e.jsx("ul",{className:"import-preview-list",children:Object.entries(Te.global).filter(([,l])=>l!==void 0).map(([l])=>e.jsx("li",{children:l},l))})]}),Te.project&&Object.keys(Te.project).length>0&&e.jsxs("div",{className:"form-group",children:[e.jsx("strong",{children:k("settings.importExport.projectSettings","Project Settings:")}),e.jsx("ul",{className:"import-preview-list",children:Object.entries(Te.project).filter(([,l])=>l!==void 0).map(([l])=>e.jsx("li",{children:l},l))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"import-scope",children:k("settings.importExport.importScope","Import Scope:")}),e.jsxs("select",{id:"import-scope",value:js,onChange:l=>Vr(l.target.value),children:[e.jsx("option",{value:"both",children:k("settings.importExport.scopeBoth","Both global and project settings")}),e.jsx("option",{value:"global",children:k("settings.importExport.scopeGlobal","Global settings only")}),e.jsx("option",{value:"project",children:k("settings.importExport.scopeProject","Project settings only")})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"import-merge",className:"checkbox-label",children:[e.jsx("input",{id:"import-merge",type:"checkbox",checked:ks,onChange:l=>Yr(l.target.checked)}),k("settings.importExport.mergeExisting","Merge with existing settings (recommended)")]}),e.jsx("small",{children:k("settings.importExport.replaceWarning","If unchecked, existing settings will be replaced with imported values.")})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>lt(!1),children:k("settings.actions.cancel","Cancel")}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:mi,disabled:Pt,children:Pt?k("settings.importExport.importing","Importing…"):k("settings.importExport.confirmImport","Confirm Import")})]})]})})]})}function Zd(a){return e.jsx(_d,{presentation:"embedded",...a})}export{_d as SettingsModal,Zd as SettingsView};