@runfusion/fusion 0.15.0 → 0.17.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.
- package/README.md +3 -19
- package/dist/bin.js +7005 -2992
- package/dist/client/assets/AgentDetailView-DGqT1oDt.js +18 -0
- package/dist/client/assets/AgentDetailView-yu8Xltqk.css +1 -0
- package/dist/client/assets/AgentsView-BmemrfrO.js +517 -0
- package/dist/client/assets/AgentsView-Bs03ptrd.css +1 -0
- package/dist/client/assets/ChatView-CZQUBFlV.js +1 -0
- package/dist/client/assets/{DevServerView-CV_PpbnZ.js → DevServerView-C3Q0XqDA.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-DPfkGnj5.js → DirectoryPicker-BZWVA9ND.js} +1 -1
- package/dist/client/assets/{DocumentsView-CESb6RI7.js → DocumentsView-DO48ivSq.js} +1 -1
- package/dist/client/assets/InsightsView-CAngTfMf.js +11 -0
- package/dist/client/assets/MemoryView-B3rNcAOW.js +2 -0
- package/dist/client/assets/NodesView-BnV1LWa8.js +14 -0
- package/dist/client/assets/NodesView-DuAXX_0j.css +1 -0
- package/dist/client/assets/{PiExtensionsManager-C4fTzemh.js → PiExtensionsManager-C3_Lw4sa.js} +3 -3
- package/dist/client/assets/{PluginManager-C2-dExUL.js → PluginManager-Vv3nzrJ1.js} +1 -1
- package/dist/client/assets/ResearchView-BzCcDAS4.css +1 -0
- package/dist/client/assets/ResearchView-Dfdsuc21.js +1 -0
- package/dist/client/assets/RoadmapsView-BiIpE-b8.js +6 -0
- package/dist/client/assets/RoadmapsView-DdGlfuu-.css +1 -0
- package/dist/client/assets/SettingsModal-BN00HYJ2.js +31 -0
- package/dist/client/assets/{SettingsModal-BGnSAeqa.js → SettingsModal-CK4w8Ztb.js} +1 -1
- package/dist/client/assets/SettingsModal-Dq4a5KSX.css +1 -0
- package/dist/client/assets/{SetupWizardModal-C_d9clJp.js → SetupWizardModal-Dw6N4UvY.js} +1 -1
- package/dist/client/assets/{SkillsView-C096TB7i.js → SkillsView-C1196wgA.js} +1 -1
- package/dist/client/assets/{folder-open-CKivQd8c.js → folder-open-WVtgE4k3.js} +1 -1
- package/dist/client/assets/index-BIJgrHEn.css +1 -0
- package/dist/client/assets/index-Bv0TGzDH.js +682 -0
- package/dist/client/assets/{star-damu_EYz.js → star-MSImEC8V.js} +1 -1
- package/dist/client/assets/{upload-uH6CHlEw.js → upload-Dmvy3xXd.js} +1 -1
- package/dist/client/assets/{users-CUySbfji.js → users-CncYvHNf.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/extension.js +6220 -3829
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/pi-claude-cli/src/__tests__/process-manager.test.ts +11 -0
- package/dist/pi-claude-cli/src/__tests__/provider.test.ts +25 -0
- package/dist/plugins/fusion-plugin-dependency-graph/manifest.json +16 -0
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +34 -0
- package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraphView.css +132 -0
- package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraphView.tsx +428 -0
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraphView.test.tsx +261 -0
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/storage.test.ts +31 -0
- package/dist/plugins/fusion-plugin-dependency-graph/src/index.ts +25 -0
- package/dist/plugins/fusion-plugin-dependency-graph/src/storage.ts +23 -0
- package/package.json +8 -4
- package/skill/fusion/SKILL.md +5 -5
- package/skill/fusion/references/engine-tools.md +4 -4
- package/skill/fusion/references/extension-tools.md +3 -3
- package/skill/fusion/references/fusion-capabilities.md +1 -1
- package/skill/fusion/references/skill-patterns.md +1 -1
- package/skill/fusion/workflows/dashboard-cli.md +3 -3
- package/skill/fusion/workflows/task-management.md +1 -1
- package/dist/client/assets/AgentDetailView-B1zViykq.js +0 -18
- package/dist/client/assets/AgentDetailView-B5tq9ius.css +0 -1
- package/dist/client/assets/AgentsView-Bl9JH5C8.js +0 -522
- package/dist/client/assets/AgentsView-V5GhlBYu.css +0 -1
- package/dist/client/assets/ChatView-liNErE53.js +0 -1
- package/dist/client/assets/InsightsView-BKhvyEyQ.js +0 -11
- package/dist/client/assets/MemoryView-DB-l2miV.js +0 -2
- package/dist/client/assets/NodesView-DCoS6iYh.css +0 -1
- package/dist/client/assets/NodesView-DgTXO8mm.js +0 -14
- package/dist/client/assets/ResearchView-BzRdUzNq.css +0 -1
- package/dist/client/assets/ResearchView-CkVwRDVA.js +0 -1
- package/dist/client/assets/RoadmapsView-BOYnyMCh.css +0 -1
- package/dist/client/assets/RoadmapsView-Cu85_XrQ.js +0 -6
- package/dist/client/assets/SettingsModal-C0DokcId.js +0 -31
- package/dist/client/assets/SettingsModal-DcGFm6NR.css +0 -1
- package/dist/client/assets/SkillMultiselect-DDHJnrkn.css +0 -1
- package/dist/client/assets/SkillMultiselect-DwGWYZi6.js +0 -1
- package/dist/client/assets/TodoView-CUiAt2mR.js +0 -6
- package/dist/client/assets/TodoView-SeO9o7km.css +0 -1
- package/dist/client/assets/index-B4StE1qN.js +0 -662
- package/dist/client/assets/index-DYJk0WDc.css +0 -1
- package/dist/client/assets/list-checks-B3oufblU.js +0 -6
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/PluginManager-C2-dExUL.js","assets/vendor-react-K0fH_qHe.js","assets/index-B4StE1qN.js","assets/vendor-xterm-DzcZoU0P.js","assets/vendor-xterm-LZoznX6r.css","assets/index-DYJk0WDc.css","assets/DirectoryPicker-DPfkGnj5.js","assets/folder-open-CKivQd8c.js","assets/DirectoryPicker-DzKVmxOf.css","assets/PluginManager-DA_T0GHn.css","assets/PiExtensionsManager-C4fTzemh.js","assets/PiExtensionsManager-kgTOHPE9.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{c as es,bZ as da,cc as dl,cd as ml,L as tt,ce as ts,cf as ul,cg as hl,ch as qe,ci as pl,P as st,cj as gl,ck as bl,cl as fl,cm as xl,cn as vl,co as Gs,cp as Ks,cq as jl,cr as yl,bX as ft,bW as _t,aH as ma,V as ua,J as ha,ad as kl,W as Nl,cs as Cl,ct as Sl,cu as wl,cv as Pl,ak as Il,cw as Ml,w as Fl,cx as Tl,cy as Al,G as xt,cz as El,aJ as Rl,x as Hs,cA as Ll,z as se,cB as Dl,cC as $l,cD as Ol,ay as qs,cE as Ws,h as Bl,cF as Vs,cG as _l,cH as Ut,cI as zt,cJ as Ys,cK as Ul,bs as Qs,br as zl,cL as Gl,cM as Kl,cN as Hl,cO as ql,cP as Wl,cQ as Vl,cR as Yl,cS as Ql,cT as Jl,cU as Xl,u as Gt,cV as Zl,cW as en,cX as tn,y as sn,cY as an,bu as ln,bC as nn,bw as rn,bB as on,bv as cn,cZ as dn,R as mn,c_ as un,c$ as Js,d0 as hn,d1 as pn,d2 as gn,d3 as bn,d4 as fn,C as xn,T as vn,d5 as jn,d6 as Kt,d7 as yn,d8 as Ht,d9 as kn,da as Nn,bF as Cn,db as Sn,dc as wn,dd as Pn,de as In,df as Mn,k as Me,dg as Fn,dh as Tn,a4 as pa,di as An}from"./index-B4StE1qN.js";import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{u as En}from"./SettingsModal-BGnSAeqa.js";import{U as Rn}from"./users-CUySbfji.js";import{S as Ln}from"./star-damu_EYz.js";import"./vendor-xterm-DzcZoU0P.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 Dn=[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]],ga=es("moon",Dn);/**
|
|
8
|
-
* @license lucide-react v1.7.0 - ISC
|
|
9
|
-
*
|
|
10
|
-
* This source code is licensed under the ISC license.
|
|
11
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
12
|
-
*/const $n=[["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"}]],On=es("settings-2",$n);/**
|
|
13
|
-
* @license lucide-react v1.7.0 - ISC
|
|
14
|
-
*
|
|
15
|
-
* This source code is licensed under the ISC license.
|
|
16
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
17
|
-
*/const Bn=[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]],ba=es("sun",Bn),_n=[{value:"light",label:"Light",icon:ba},{value:"dark",label:"Dark",icon:ga},{value:"system",label:"System",icon:da}],Un=[{value:90,label:"Small"},{value:100,label:"Default"},{value:110,label:"Large"},{value:120,label:"Largest"}],Xs=[{value:"default",label:"Default",className:"theme-swatch-default"},{value:"ocean",label:"Ocean",className:"theme-swatch-ocean"},{value:"forest",label:"Forest",className:"theme-swatch-forest"},{value:"sunset",label:"Sunset",className:"theme-swatch-sunset"},{value:"zen",label:"Zen",className:"theme-swatch-zen"},{value:"berry",label:"Berry",className:"theme-swatch-berry"},{value:"high-contrast",label:"High Contrast",className:"theme-swatch-high-contrast"},{value:"industrial",label:"Industrial",className:"theme-swatch-industrial"},{value:"monochrome",label:"Mono",className:"theme-swatch-monochrome"},{value:"slate",label:"Slate",className:"theme-swatch-slate"},{value:"ash",label:"Ash",className:"theme-swatch-ash"},{value:"graphite",label:"Graphite",className:"theme-swatch-graphite"},{value:"silver",label:"Silver",className:"theme-swatch-silver"},{value:"solarized",label:"Solarized",className:"theme-swatch-solarized"},{value:"factory",label:"Factory",className:"theme-swatch-factory"},{value:"ayu",label:"Ayu",className:"theme-swatch-ayu"},{value:"one-dark",label:"One Dark",className:"theme-swatch-one-dark"},{value:"nord",label:"Nord",className:"theme-swatch-nord"},{value:"dracula",label:"Dracula",className:"theme-swatch-dracula"},{value:"gruvbox",label:"Gruvbox",className:"theme-swatch-gruvbox"},{value:"tokyo-night",label:"Tokyo Night",className:"theme-swatch-tokyo-night"},{value:"catppuccin-mocha",label:"Catppuccin Mocha",className:"theme-swatch-catppuccin-mocha"},{value:"github-dark",label:"GitHub Dark",className:"theme-swatch-github-dark"},{value:"everforest",label:"Everforest",className:"theme-swatch-everforest"},{value:"rose-pine",label:"Rosé Pine",className:"theme-swatch-rose-pine"},{value:"kanagawa",label:"Kanagawa",className:"theme-swatch-kanagawa"},{value:"night-owl",label:"Night Owl",className:"theme-swatch-night-owl"},{value:"palenight",label:"Palenight",className:"theme-swatch-palenight"},{value:"monokai-pro",label:"Monokai Pro",className:"theme-swatch-monokai-pro"},{value:"slime",label:"Slime",className:"theme-swatch-slime"},{value:"brutalist",label:"Brutalist",className:"theme-swatch-brutalist"},{value:"neon-city",label:"Neon City",className:"theme-swatch-neon-city"},{value:"parchment",label:"Parchment",className:"theme-swatch-parchment"},{value:"terminal",label:"Terminal",className:"theme-swatch-terminal"},{value:"glass",label:"Glass",className:"theme-swatch-glass"},{value:"horizon",label:"Horizon",className:"theme-swatch-horizon"},{value:"vitesse",label:"Vitesse",className:"theme-swatch-vitesse"},{value:"outrun",label:"Outrun",className:"theme-swatch-outrun"},{value:"snazzy",label:"Snazzy",className:"theme-swatch-snazzy"},{value:"porple",label:"Porple",className:"theme-swatch-porple"},{value:"espresso",label:"Espresso",className:"theme-swatch-espresso"},{value:"mars",label:"Mars",className:"theme-swatch-mars"},{value:"poimandres",label:"Poimandres",className:"theme-swatch-poimandres"},{value:"ember",label:"Ember",className:"theme-swatch-ember"},{value:"rust",label:"Rust",className:"theme-swatch-rust"},{value:"copper",label:"Copper",className:"theme-swatch-copper"},{value:"foundry",label:"Foundry",className:"theme-swatch-foundry"},{value:"carbon",label:"Carbon",className:"theme-swatch-carbon"},{value:"sandstone",label:"Sandstone",className:"theme-swatch-sandstone"},{value:"lagoon",label:"Lagoon",className:"theme-swatch-lagoon"},{value:"frost",label:"Frost",className:"theme-swatch-frost"},{value:"lavender",label:"Lavender",className:"theme-swatch-lavender"},{value:"neon-bloom",label:"Neon Bloom",className:"theme-swatch-neon-bloom"},{value:"sepia",label:"Sepia",className:"theme-swatch-sepia"}];function zn({themeMode:n,colorTheme:o,dashboardFontScalePct:d=100,onThemeModeChange:F,onColorThemeChange:N,onDashboardFontScaleChange:T=()=>{}}){const D=a.useCallback(()=>{F("dark"),N("default"),T(100)},[F,N,T]);return e.jsxs("div",{className:"theme-selector",children:[e.jsx("div",{className:"theme-mode-toggle",role:"radiogroup","aria-label":"Theme mode",children:_n.map(({value:y,label:I,icon:M})=>e.jsxs("button",{className:`theme-mode-btn${n===y?" active":""}`,onClick:()=>F(y),"aria-pressed":n===y,"aria-label":`${I} mode`,title:`${I} mode`,children:[e.jsx(M,{size:16}),e.jsx("span",{children:I})]},y))}),e.jsxs("div",{className:"theme-current-preview",children:[e.jsx("div",{className:"theme-preview-icon",children:n==="light"?e.jsx(ba,{size:20}):n==="dark"?e.jsx(ga,{size:20}):e.jsx(da,{size:20})}),e.jsxs("div",{className:"theme-preview-info",children:[e.jsx("div",{className:"theme-preview-label",children:"Current theme"}),e.jsxs("div",{className:"theme-preview-value",children:[n==="system"?"System":`${n.charAt(0).toUpperCase()+n.slice(1)}`," / ",Xs.find(y=>y.value===o)?.label]})]})]}),e.jsx("div",{className:"theme-section-title",children:"Font Size"}),e.jsx("div",{className:"theme-font-size-toggle",role:"radiogroup","aria-label":"Dashboard font size",children:Un.map(({value:y,label:I})=>e.jsx("button",{className:`theme-font-size-btn${d===y?" active":""}`,onClick:()=>T(y),"aria-pressed":d===y,children:e.jsx("span",{children:I})},y))}),e.jsx("div",{className:"theme-section-title",children:"Color Theme"}),e.jsx("div",{className:"theme-grid",role:"radiogroup","aria-label":"Color theme",children:Xs.map(({value:y,label:I,className:M})=>e.jsxs("button",{className:`theme-option${o===y?" active":""}`,onClick:()=>N(y),"aria-pressed":o===y,"aria-label":`${I} theme`,title:I,children:[e.jsxs("div",{className:`theme-option-swatch ${M}`,"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:I})]},y))}),e.jsx("button",{className:"theme-reset-btn",onClick:D,"aria-label":"Reset to default theme",children:e.jsx("span",{children:"Reset to defaults"})})]})}const Gn={installed:{text:"Installed",tone:"ok"},missing:{text:"Not installed",tone:"err"},"version-mismatch":{text:"Version mismatch",tone:"warn"},skipped:{text:"Check disabled",tone:"warn"}};function Kn({defer:n=!1}){const[o,d]=a.useState(null),[F,N]=a.useState(!1),[T,D]=a.useState(!1),[y,I]=a.useState(null),[M,C]=a.useState(null),[R,G]=a.useState(null),E=a.useCallback(async()=>{N(!0),C(null);try{const g=await dl();d(g)}catch(g){C(g instanceof Error?g.message:String(g))}finally{N(!1)}},[]);a.useEffect(()=>{n||E()},[n,E]);const _=a.useCallback(async()=>{D(!0),I(null),C(null);try{const g=await ml();d({binary:g.binary,expectedVersion:g.expectedVersion,state:g.state,install:g.install}),I(g.installResult)}catch(g){C(g instanceof Error?g.message:String(g))}finally{D(!1)}},[]),l=a.useCallback(async(g,A)=>{try{await navigator.clipboard.writeText(A),G(g),setTimeout(()=>G(x=>x===g?null:x),1500)}catch{}},[]),i=o?Gn[o.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:"CLI Binary"}),i&&e.jsx("span",{className:`cli-binary-pill cli-binary-pill--${i.tone}`,children:i.text})]}),e.jsxs("small",{className:"cli-binary-help",children:["Installing the global CLI lets you run ",e.jsx("code",{children:"fn"})," and ",e.jsx("code",{children:"fusion"})," from any terminal. Automations and scripts work without it via ",e.jsx("code",{children:"npx"}),", but a global install is faster and more convenient."]}),F&&!o&&e.jsx("p",{className:"cli-binary-status-line",children:"Checking…"}),o&&e.jsxs("div",{className:"cli-binary-detail",children:[o.binary.installed?e.jsxs("ul",{className:"cli-binary-info-list",children:[e.jsxs("li",{children:[e.jsx("span",{children:"Binary:"}),e.jsx("code",{children:o.binary.binary})]}),o.binary.path&&e.jsxs("li",{children:[e.jsx("span",{children:"Path:"}),e.jsx("code",{children:o.binary.path})]}),e.jsxs("li",{children:[e.jsx("span",{children:"Version:"}),e.jsx("code",{children:o.binary.version??"unknown"}),e.jsxs("span",{className:"cli-binary-expected",children:["(expected ",o.expectedVersion,")"]})]})]}):e.jsxs("p",{className:"cli-binary-status-line",children:["Neither ",e.jsx("code",{children:"fn"})," nor ",e.jsx("code",{children:"fusion"})," was found on PATH."]}),e.jsxs("div",{className:"cli-binary-actions",children:[e.jsx("button",{type:"button",className:"cli-binary-install-btn",onClick:_,disabled:T,children:T?"Installing…":o.binary.installed?"Reinstall":"Install with npm"}),e.jsx("button",{type:"button",className:"cli-binary-refresh-btn",onClick:()=>void E(),disabled:F||T,children:"Refresh"})]}),e.jsxs("div",{className:"cli-binary-commands",children:[e.jsx("label",{children:"Or copy and run yourself:"}),[{label:"npm",command:o.install.npm},{label:"curl",command:o.install.curl}].map(({label:g,command:A})=>e.jsxs("div",{className:"cli-binary-command-row",children:[e.jsx("code",{children:A}),e.jsx("button",{type:"button",onClick:()=>void l(g,A),className:"cli-binary-copy-btn",children:R===g?"Copied":"Copy"})]},g))]})]}),y&&e.jsxs("details",{className:"cli-binary-install-log",open:!y.success,children:[e.jsx("summary",{children:y.success?`Install succeeded in ${(y.durationMs/1e3).toFixed(1)}s`:`Install failed (exit ${y.exitCode??"n/a"})`}),y.permissionsHint&&e.jsx("p",{className:"cli-binary-permissions-hint",children:y.permissionsHint}),y.stdout&&e.jsx("pre",{className:"cli-binary-install-output",children:y.stdout}),y.stderr&&e.jsx("pre",{className:"cli-binary-install-output cli-binary-install-output--err",children:y.stderr})]}),M&&e.jsx("p",{className:"field-error",children:M})]})}function ss(n){const{name:o,subname:d,logo:F,learnMoreHref:N,statusKind:T,statusText:D,description:y,tabs:I,children:M,busy:C,canTest:R=!0,toast:G,onTest:E,onSave:_,onSaveAndTest:l,belowForm:i,testId:g}=n,A=T==="ok"?"runtime-card__status runtime-card__status--ok":T==="err"?"runtime-card__status runtime-card__status--err":"runtime-card__status runtime-card__status--neutral";return e.jsxs("div",{className:"runtime-card","data-testid":g,"aria-live":"polite",children:[e.jsxs("header",{className:"runtime-card__header",children:[e.jsx("span",{className:"runtime-card__logo",children:F}),e.jsxs("div",{className:"runtime-card__title",children:[e.jsx("h3",{className:"runtime-card__name",children:o}),d&&e.jsx("small",{className:"runtime-card__cobrand",children:d}),e.jsxs("small",{className:A,children:[T==="loading"&&e.jsx(tt,{size:12,className:"animate-spin"}),D]})]}),e.jsx("a",{className:"runtime-card__learn-more btn btn-sm btn-ghost",href:N,target:"_blank",rel:"noreferrer",children:"Learn more →"})]}),e.jsx("p",{className:"runtime-card__description",children:y}),I,e.jsx("div",{className:"runtime-card__form",children:M}),i,e.jsxs("footer",{className:"runtime-card__footer",children:[G&&e.jsx("span",{className:G.kind==="ok"?"runtime-card__toast runtime-card__toast--ok":"runtime-card__toast runtime-card__toast--err",role:"status",children:G.message}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:E,disabled:C!==null||!R,children:C==="testing"?e.jsxs(e.Fragment,{children:[e.jsx(tt,{size:12,className:"animate-spin"})," Testing…"]}):"Test"}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:_,disabled:C!==null,children:C==="saving"?"Saving…":"Save"}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:l,disabled:C!==null||!R,children:C==="save-test"?e.jsxs(e.Fragment,{children:[e.jsx(tt,{size:12,className:"animate-spin"})," Saving…"]}):"Save & Test"})]})]})}const qt="fusion-plugin-hermes-runtime",Zs="https://github.com/NousResearch/hermes-agent",Hn=["auto","anthropic","openrouter","gemini","openai-codex","copilot","copilot-acp","huggingface","zai","kimi-coding","minimax","minimax-cn","kilocode","xiaomi","nous"],Se={binaryPath:"",model:"",provider:"auto",maxTurns:12,yolo:!1,cliTimeoutMs:3e5,profile:""};function qn(n){return{binaryPath:typeof n.binaryPath=="string"?n.binaryPath:Se.binaryPath,model:typeof n.model=="string"?n.model:Se.model,provider:typeof n.provider=="string"?n.provider:Se.provider,maxTurns:typeof n.maxTurns=="number"?n.maxTurns:Se.maxTurns,yolo:typeof n.yolo=="boolean"?n.yolo:Se.yolo,cliTimeoutMs:typeof n.cliTimeoutMs=="number"?n.cliTimeoutMs:Se.cliTimeoutMs,profile:typeof n.profile=="string"?n.profile:Se.profile}}function Wn(){const[n,o]=a.useState(Se),[d,F]=a.useState(null),[N,T]=a.useState([]),[D,y]=a.useState(null),[I,M]=a.useState(null),C=a.useRef(!0);a.useEffect(()=>(C.current=!0,()=>{C.current=!1}),[]),a.useEffect(()=>{y("loading"),ts(qt).then(x=>{C.current&&o(qn(x))}).catch(()=>{}).finally(()=>{C.current&&y(null)})},[]),a.useEffect(()=>{ul(n.binaryPath?{binaryPath:n.binaryPath}:{}).then(x=>{C.current&&T(x)}).catch(()=>{})},[n.binaryPath]);const R=a.useCallback(async()=>{try{const x=await hl(n.binaryPath?{binaryPath:n.binaryPath}:{});return C.current&&F(x),x}catch(x){return C.current&&M({kind:"err",message:x instanceof Error?x.message:String(x)}),null}},[n.binaryPath]);a.useEffect(()=>{R()},[R]);const G=a.useCallback(()=>({binaryPath:n.binaryPath,model:n.model,provider:n.provider,maxTurns:n.maxTurns,yolo:n.yolo,cliTimeoutMs:n.cliTimeoutMs,profile:n.profile}),[n]),E=a.useCallback(async()=>{y("testing"),M(null);const x=await R();C.current&&(y(null),x?x.binary.available?M({kind:"ok",message:`✓ hermes detected${x.binary.version?` (${x.binary.version})`:""}${x.binary.binaryPath?` at ${x.binary.binaryPath}`:""}.`}):M({kind:"err",message:`✗ ${x.binary.reason??"hermes not found"}`}):M({kind:"err",message:"Test failed — see status above."}))},[R]),_=a.useCallback(async()=>{y("saving"),M(null);try{await qe(qt,G()),C.current&&M({kind:"ok",message:"Settings saved."})}catch(x){C.current&&M({kind:"err",message:x instanceof Error?x.message:String(x)})}finally{C.current&&y(null)}},[G]),l=a.useCallback(async()=>{y("save-test"),M(null);try{await qe(qt,G());const x=await R();if(!C.current)return;x?x.binary.available?M({kind:"ok",message:`Saved · ✓ hermes detected${x.binary.version?` (${x.binary.version})`:""}.`}):M({kind:"err",message:`Saved · ✗ ${x.binary.reason??"hermes not found"}`}):M({kind:"err",message:"Saved, but probe failed."})}catch(x){C.current&&M({kind:"err",message:x instanceof Error?x.message:String(x)})}finally{C.current&&y(null)}},[G,R]),i=d?.binary,g=d===null?"loading":i?.available?"ok":"err",A=d===null?"Probing local hermes binary…":i?.available?`✓ Detected${i.version?` ${i.version}`:""}${i.binaryPath?` · ${i.binaryPath}`:""}`:`✗ ${i?.reason??"not detected on PATH"}`;return e.jsxs(ss,{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:"Nous Research",style:{width:28,height:28,display:"block",filter:"invert(1) brightness(0)"}})}),name:"Hermes",subname:"by Nous Research",learnMoreHref:Zs,statusKind:g,statusText:A,description:e.jsxs(e.Fragment,{children:["Drives the local ",e.jsx("code",{children:"hermes"})," CLI as a subprocess. Each Fusion prompt is sent as ",e.jsx("code",{children:"hermes chat -q …"}),"; subsequent prompts resume the same hermes session via ",e.jsx("code",{children:"--resume"}),". Provider, model, and skills are configured inside hermes itself; this card only chooses overrides."]}),busy:D,toast:I,onTest:()=>void E(),onSave:()=>void _(),onSaveAndTest:()=>void l(),belowForm:i?.available===!1?e.jsxs("div",{className:"onboarding-helper-text",children:[e.jsxs("p",{children:[e.jsx("code",{children:"hermes"})," not detected. Install the upstream agent:"]}),e.jsx("pre",{children:e.jsx("code",{children:"pipx install hermes-agent"})}),e.jsx("p",{children:e.jsx("a",{href:Zs,target:"_blank",rel:"noreferrer",children:"Hermes on GitHub"})})]}):null,children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-profile",children:"Profile (optional)"}),e.jsxs("select",{id:"hermes-profile",value:n.profile,onChange:x=>o(B=>({...B,profile:x.target.value})),children:[e.jsx("option",{value:"",children:"Auto / use Hermes default"}),N.map(x=>e.jsxs("option",{value:x.name,children:[x.name,x.model?` — ${x.model}`:"",x.isDefault?" (default)":""]},x.name))]}),e.jsxs("small",{children:["Select a Hermes profile to use. Activates the profile by setting"," ",e.jsx("code",{children:"HERMES_HOME"})," to the profile directory when invoking"," ",e.jsx("code",{children:"hermes chat"}),"."]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-binary",children:"Binary path"}),e.jsx("input",{id:"hermes-binary",type:"text",placeholder:"hermes (defaults to PATH)",value:n.binaryPath,onChange:x=>o(B=>({...B,binaryPath:x.target.value}))}),e.jsxs("small",{children:["Leave blank to resolve ",e.jsx("code",{children:"hermes"})," from your PATH."]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-model",children:"Model override"}),e.jsx("input",{id:"hermes-model",type:"text",placeholder:"e.g. claude-sonnet-4-5, MiniMax-M2.7",value:n.model,disabled:!!n.profile,onChange:x=>o(B=>({...B,model:x.target.value}))}),n.profile?e.jsxs("small",{children:["Controlled by profile: ",e.jsx("strong",{children:n.profile})]}):e.jsx("small",{children:"Optional — overrides Hermes's configured default model."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-provider",children:"Provider"}),e.jsx("select",{id:"hermes-provider",value:n.provider,disabled:!!n.profile,onChange:x=>o(B=>({...B,provider:x.target.value})),children:Hn.map(x=>e.jsx("option",{value:x,children:x},x))}),n.profile?e.jsxs("small",{children:["Controlled by profile: ",e.jsx("strong",{children:n.profile})]}):e.jsxs("small",{children:["Inference provider Hermes routes calls through (default: ",e.jsx("code",{children:"auto"}),"))."]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-maxTurns",children:"Max turns"}),e.jsx("input",{id:"hermes-maxTurns",type:"number",min:1,max:500,value:n.maxTurns,onChange:x=>o(B=>({...B,maxTurns:Number(x.target.value)||Se.maxTurns}))}),e.jsx("small",{children:"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:n.yolo,onChange:x=>o(B=>({...B,yolo:x.target.checked}))}),"Auto-approve dangerous tool calls (",e.jsx("code",{children:"--yolo"}),")"]}),e.jsx("small",{children:"Required for non-interactive sessions that trigger shell-style tools."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"hermes-timeoutMs",children:"CLI hard-kill timeout (ms)"}),e.jsx("input",{id:"hermes-timeoutMs",type:"number",min:1e3,step:1e3,value:n.cliTimeoutMs,onChange:x=>o(B=>({...B,cliTimeoutMs:Number(x.target.value)||Se.cliTimeoutMs}))}),e.jsx("small",{children:"Fusion-side hard cap. Default 5 min."})]})]})}const Wt="fusion-plugin-openclaw-runtime",Vn="https://docs.openclaw.ai/",Yn="https://github.com/openclaw/openclaw",fa=["off","minimal","low","medium","high","xhigh","adaptive","max"],we={binaryPath:"",agentId:"main",model:"",thinking:"off",useGateway:!1,cliTimeoutSec:0,cliTimeoutMs:3e5};function Qn(n){return{binaryPath:typeof n.binaryPath=="string"?n.binaryPath:we.binaryPath,agentId:typeof n.agentId=="string"?n.agentId:we.agentId,model:typeof n.model=="string"?n.model:we.model,thinking:fa.includes(n.thinking)?n.thinking:we.thinking,useGateway:typeof n.useGateway=="boolean"?n.useGateway:we.useGateway,cliTimeoutSec:typeof n.cliTimeoutSec=="number"?n.cliTimeoutSec:we.cliTimeoutSec,cliTimeoutMs:typeof n.cliTimeoutMs=="number"?n.cliTimeoutMs:we.cliTimeoutMs}}function Jn(){const[n,o]=a.useState(we),[d,F]=a.useState(null),[N,T]=a.useState(null),[D,y]=a.useState(null),I=a.useRef(!0);a.useEffect(()=>(I.current=!0,()=>{I.current=!1}),[]),a.useEffect(()=>{T("loading"),ts(Wt).then(g=>{I.current&&o(Qn(g))}).catch(()=>{}).finally(()=>{I.current&&T(null)})},[]);const M=a.useCallback(async()=>{try{const g=await pl(n.binaryPath?{binaryPath:n.binaryPath}:void 0);return I.current&&F(g),g}catch(g){return I.current&&y({kind:"err",message:g instanceof Error?g.message:String(g)}),null}},[n.binaryPath]);a.useEffect(()=>{M()},[M]);const C=a.useCallback(()=>({binaryPath:n.binaryPath,agentId:n.agentId,model:n.model,thinking:n.thinking,useGateway:n.useGateway,cliTimeoutSec:n.cliTimeoutSec,cliTimeoutMs:n.cliTimeoutMs}),[n]),R=a.useCallback(async()=>{T("testing"),y(null);const g=await M();I.current&&(T(null),g?g.binary.available?y({kind:"ok",message:`✓ openclaw detected${g.binary.version?` (${g.binary.version})`:""}${g.binary.binaryPath?` at ${g.binary.binaryPath}`:""}.`}):y({kind:"err",message:`✗ ${g.binary.reason??"openclaw not found"}`}):y({kind:"err",message:"Test failed — see status above."}))},[M]),G=a.useCallback(async()=>{T("saving"),y(null);try{await qe(Wt,C()),I.current&&y({kind:"ok",message:"Settings saved."})}catch(g){I.current&&y({kind:"err",message:g instanceof Error?g.message:String(g)})}finally{I.current&&T(null)}},[C]),E=a.useCallback(async()=>{T("save-test"),y(null);try{await qe(Wt,C());const g=await M();if(!I.current)return;g?g.binary.available?y({kind:"ok",message:`Saved · ✓ openclaw detected${g.binary.version?` (${g.binary.version})`:""}${g.binary.binaryPath?` at ${g.binary.binaryPath}`:""}.`}):y({kind:"err",message:`Saved · ✗ ${g.binary.reason??"openclaw not found"}`}):y({kind:"err",message:"Saved, but probe failed."})}catch(g){I.current&&y({kind:"err",message:g instanceof Error?g.message:String(g)})}finally{I.current&&T(null)}},[C,M]),_=d?.binary,l=d===null?"loading":_?.available?"ok":"err",i=d===null?"Probing local openclaw binary…":_?.available?`✓ Detected${_.version?` ${_.version}`:""}${_.binaryPath?` · ${_.binaryPath}`:""}`:`✗ ${_?.reason??"not detected on PATH"}`;return e.jsxs(ss,{testId:"openclaw-runtime-card",logo:e.jsx(st,{provider:"openclaw",size:"lg"}),name:"OpenClaw",learnMoreHref:Vn,statusKind:l,statusText:i,description:e.jsxs(e.Fragment,{children:["Drives the local ",e.jsx("code",{children:"openclaw"})," CLI as a subprocess. Each Fusion prompt is dispatched via"," ",e.jsx("code",{children:"openclaw agent --local --json"}),"; the agent definition, model, and thinking level are resolved by OpenClaw. This card only sets overrides and the binary path."]}),busy:N,toast:D,onTest:()=>void R(),onSave:()=>void G(),onSaveAndTest:()=>void E(),belowForm:_?.available===!1?e.jsxs("div",{className:"onboarding-helper-text",children:[e.jsxs("p",{children:[e.jsx("code",{children:"openclaw"})," not detected. Install the upstream agent:"]}),e.jsx("pre",{children:e.jsx("code",{children:"npm install -g openclaw"})}),e.jsx("p",{children:e.jsx("a",{href:Yn,target:"_blank",rel:"noreferrer",children:"openclaw on GitHub"})})]}):null,children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-binaryPath",children:"Binary path"}),e.jsx("input",{id:"openclaw-binaryPath",type:"text",placeholder:"openclaw (defaults to PATH)",value:n.binaryPath,onChange:g=>o(A=>({...A,binaryPath:g.target.value}))}),e.jsxs("small",{children:["Leave blank to resolve ",e.jsx("code",{children:"openclaw"})," from your PATH."]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-agentId",children:"Agent ID"}),e.jsx("input",{id:"openclaw-agentId",type:"text",placeholder:"main",value:n.agentId,onChange:g=>o(A=>({...A,agentId:g.target.value}))}),e.jsxs("small",{children:["OpenClaw agent definition to run (default: ",e.jsx("code",{children:"main"}),")."]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-model",children:"Model override"}),e.jsx("input",{id:"openclaw-model",type:"text",placeholder:"e.g. anthropic/claude-haiku-4-5, minimax/MiniMax-M2.7",value:n.model,onChange:g=>o(A=>({...A,model:g.target.value}))}),e.jsx("small",{children:"Optional — overrides the OpenClaw default model."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-thinking",children:"Thinking level"}),e.jsx("select",{id:"openclaw-thinking",value:n.thinking,onChange:g=>o(A=>({...A,thinking:g.target.value})),children:fa.map(g=>e.jsx("option",{value:g,children:g},g))}),e.jsx("small",{children:"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:n.useGateway,onChange:g=>o(A=>({...A,useGateway:g.target.checked}))}),"Route through OpenClaw gateway (otherwise embedded)"]}),e.jsx("small",{children:"When enabled, calls pass through the OpenClaw gateway service."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-cliTimeoutSec",children:"OpenClaw timeout (sec)"}),e.jsx("input",{id:"openclaw-cliTimeoutSec",type:"number",min:0,step:1,value:n.cliTimeoutSec,onChange:g=>o(A=>({...A,cliTimeoutSec:parseInt(g.target.value,10)||0}))}),e.jsx("small",{children:"OpenClaw-side run timeout in seconds (0 = no timeout)."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"openclaw-cliTimeoutMs",children:"CLI subprocess timeout (ms)"}),e.jsx("input",{id:"openclaw-cliTimeoutMs",type:"number",min:0,step:1e3,value:n.cliTimeoutMs,onChange:g=>o(A=>({...A,cliTimeoutMs:parseInt(g.target.value,10)||we.cliTimeoutMs}))}),e.jsxs("small",{children:["Fusion-side hard cap before the CLI subprocess is killed (default:"," ",we.cliTimeoutMs/1e3,"s)."]})]})]})}const Vt="fusion-plugin-paperclip-runtime",ea="https://paperclip.ing/",Xn="https://github.com/paperclipai/paperclip",ta=[{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."}],be={transport:"api",apiUrl:"http://localhost:3100",apiKey:"",cliBinaryPath:"paperclipai",cliConfigPath:"",agentId:"",companyId:"",mode:"rolling-issue",parentIssueId:"",projectId:"",goalId:"",runTimeoutMs:6e5},Zn=new Set(["issue-per-prompt","rolling-issue","wakeup-only"]);function er(n){const o=(T,D)=>typeof n[T]=="string"?n[T]:D,d=(T,D)=>typeof n[T]=="number"?n[T]:D,F=n.transport==="cli"?"cli":"api",N=Zn.has(n.mode)?n.mode:be.mode;return{transport:F,apiUrl:o("apiUrl",be.apiUrl),apiKey:o("apiKey",be.apiKey),cliBinaryPath:o("cliBinaryPath",be.cliBinaryPath),cliConfigPath:o("cliConfigPath",be.cliConfigPath),agentId:o("agentId",be.agentId),companyId:o("companyId",be.companyId),mode:N,parentIssueId:o("parentIssueId",be.parentIssueId),projectId:o("projectId",be.projectId),goalId:o("goalId",be.goalId),runTimeoutMs:d("runTimeoutMs",be.runTimeoutMs)}}function tr(){const[n,o]=a.useState(be),[d,F]=a.useState(null),[N,T]=a.useState(null),[D,y]=a.useState([]),[I,M]=a.useState([]),[C,R]=a.useState(null),[G,E]=a.useState(null),[_,l]=a.useState(!1),i=a.useRef(!0);a.useEffect(()=>(i.current=!0,()=>{i.current=!1}),[]);const g=a.useMemo(()=>n.transport==="cli"&&N&&N.ok?{apiUrl:N.apiUrl,apiKey:n.apiKey||N.apiKey||void 0}:{apiUrl:n.apiUrl,apiKey:n.apiKey||void 0},[n.transport,n.apiUrl,n.apiKey,N]);a.useEffect(()=>{R("loading"),ts(Vt).then(p=>{i.current&&o(er(p))}).catch(()=>{}).finally(()=>{i.current&&R(null)})},[]),a.useEffect(()=>{if(n.transport!=="cli"){T(null);return}let p=!1;return gl({cliConfigPath:n.cliConfigPath||void 0}).then(w=>{!p&&i.current&&T(w)}).catch(()=>{!p&&i.current&&T({ok:!1,reason:"Discovery request failed"})}),()=>{p=!0}},[n.transport,n.cliConfigPath]);const A=n.transport==="cli",x=a.useMemo(()=>({cliBinaryPath:n.cliBinaryPath||void 0,cliConfigPath:n.cliConfigPath||void 0}),[n.cliBinaryPath,n.cliConfigPath]),B=a.useCallback(async()=>{if(!A&&!g.apiUrl)return null;try{const p=A?await bl(x):await fl(g);i.current&&F(p);const w=A?await xl(x):await vl(g);if(!i.current)return p;y(w);let V=n.companyId;if(w.some(ne=>ne.id===V)||(V=p.connection.identity?.companyId??w[0]?.id??"",V&&V!==n.companyId&&o(ne=>({...ne,companyId:V}))),V){const ne=A?await Gs({...x,companyId:V}):await Ks({...g,companyId:V});if(i.current&&(M(ne),!ne.some(de=>de.id===n.agentId))){const de=p.connection.identity?.agentId??ne[0]?.id??"";de&&de!==n.agentId&&o(le=>({...le,agentId:de}))}}else i.current&&M([]);return p}catch(p){return i.current&&E({kind:"err",message:p instanceof Error?p.message:String(p)}),null}},[A,x,g.apiUrl,g.apiKey,n.companyId,n.agentId]);a.useEffect(()=>{B()},[B]),a.useEffect(()=>{if(!n.companyId){M([]);return}if(!A&&!g.apiUrl){M([]);return}let p=!1;return(A?Gs({...x,companyId:n.companyId}):Ks({...g,companyId:n.companyId})).then(V=>{!p&&i.current&&M(V)}).catch(()=>{!p&&i.current&&M([])}),()=>{p=!0}},[A,x,g.apiUrl,g.apiKey,n.companyId]);const Q=a.useCallback(()=>{const p={transport:n.transport,mode:n.mode,parentIssueId:n.parentIssueId,projectId:n.projectId,goalId:n.goalId,runTimeoutMs:n.runTimeoutMs,agentId:n.agentId,companyId:n.companyId};return n.transport==="api"?p.apiUrl=n.apiUrl:(p.cliBinaryPath=n.cliBinaryPath,n.cliConfigPath&&(p.cliConfigPath=n.cliConfigPath)),_&&(p.apiKey=n.apiKey),p},[n,_]),ce=a.useCallback(async()=>{R("testing"),E(null);const p=await B();if(i.current)if(R(null),!p)n.transport==="cli"&&N&&!N.ok?E({kind:"err",message:`✗ CLI discovery failed: ${N.reason}`}):E({kind:"err",message:"Test failed — see status above."});else if(p.connection.available){const w=p.connection.identity;E({kind:"ok",message:w?`✓ Connected as ${w.agentName}${w.companyName?` at ${w.companyName}`:""}.`:"✓ Connected."})}else E({kind:"err",message:`✗ ${p.connection.reason??"Paperclip server unreachable"}`})},[B,n.transport,N]),ae=a.useCallback(async()=>{R("saving"),E(null);try{await qe(Vt,Q()),i.current&&(E({kind:"ok",message:"Settings saved."}),l(!1))}catch(p){i.current&&E({kind:"err",message:p instanceof Error?p.message:String(p)})}finally{i.current&&R(null)}},[Q]),K=a.useCallback(async()=>{R("save-test"),E(null);try{await qe(Vt,Q()),i.current&&l(!1);const p=await B();if(!i.current)return;if(!p)n.transport==="cli"&&N&&!N.ok?E({kind:"err",message:`Saved · ✗ CLI discovery failed: ${N.reason}`}):E({kind:"err",message:"Saved, but probe failed."});else if(p.connection.available){const w=p.connection.identity;E({kind:"ok",message:w?`Saved · ✓ Connected as ${w.agentName}${w.companyName?` at ${w.companyName}`:""}.`:"Saved · ✓ Connected."})}else E({kind:"err",message:`Saved · ✗ ${p.connection.reason??"Paperclip server unreachable"}`})}catch(p){i.current&&E({kind:"err",message:p instanceof Error?p.message:String(p)})}finally{i.current&&R(null)}},[Q,B,n.transport,N]),H=d?.connection.available??null,S=d?.connection.identity,q=N?.ok===!0,W=d===null?"loading":H?"ok":"err",Te=d===null?n.transport==="cli"&&N&&!q?`✗ CLI discovery failed: ${N.reason}`:"Probing Paperclip server…":H?S?`✓ Connected as ${S.agentName}${S.role?` (${S.role})`:""}${S.companyName?` at ${S.companyName}`:""}`:"✓ Connected":`✗ ${d.connection.reason??"Unreachable"}`,xe=e.jsxs("div",{className:"runtime-card__tabs",role:"tablist","aria-label":"Paperclip connection mode",children:[e.jsx("button",{type:"button",role:"tab","aria-selected":n.transport==="api",className:"runtime-card__tab",onClick:()=>o(p=>({...p,transport:"api"})),children:"API (URL + token)"}),e.jsx("button",{type:"button",role:"tab","aria-selected":n.transport==="cli",className:"runtime-card__tab",onClick:()=>o(p=>({...p,transport:"cli"})),children:"Local CLI (auto-derive)"})]});return e.jsxs(ss,{testId:"paperclip-runtime-card",logo:e.jsx(st,{provider:"paperclip",size:"lg"}),name:"Paperclip",learnMoreHref:ea,statusKind:W,statusText:Te,description:e.jsx(e.Fragment,{children:'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:xe,busy:C,toast:G,onTest:()=>void ce(),onSave:()=>void ae(),onSaveAndTest:()=>void K(),belowForm:H===!1?e.jsxs("div",{className:"onboarding-helper-text",children:[e.jsx("p",{children:"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:ea,target:"_blank",rel:"noreferrer",children:"Paperclip docs"})," ","·"," ",e.jsx("a",{href:Xn,target:"_blank",rel:"noreferrer",children:"GitHub"})]})]}):null,children:[n.transport==="cli"&&N&&e.jsx("div",{className:"settings-muted",style:{marginBottom:"var(--space-sm)"},children:q?e.jsxs("small",{children:["CLI config: ",e.jsx("code",{children:N.configPath})," ","· resolved ",e.jsx("code",{children:N.apiUrl}),N.deploymentMode?` · ${N.deploymentMode}`:""]}):e.jsxs("small",{children:["CLI discovery failed: ",N.reason]})}),n.transport==="api"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-apiUrl",children:"API URL"}),e.jsx("input",{id:"paperclip-apiUrl",type:"text",placeholder:"http://localhost:3100",value:n.apiUrl,onChange:p=>o(w=>({...w,apiUrl:p.target.value}))}),e.jsx("small",{children:"Base URL of the Paperclip server."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-apiKey",children:"API key"}),e.jsx("input",{id:"paperclip-apiKey",type:"password",placeholder:_?"":"•••••••• (leave blank to keep existing)",value:n.apiKey,onChange:p=>{o(w=>({...w,apiKey:p.target.value})),l(!0)}}),e.jsx("small",{children:"Agent API key. Local-trusted deployments may leave this blank."})]})]}),n.transport==="cli"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-cliBinaryPath",children:"paperclipai binary"}),e.jsx("input",{id:"paperclip-cliBinaryPath",type:"text",placeholder:"paperclipai",value:n.cliBinaryPath,onChange:p=>o(w=>({...w,cliBinaryPath:p.target.value}))}),e.jsx("small",{children:"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:"Instance config path"}),e.jsx("input",{id:"paperclip-cliConfigPath",type:"text",placeholder:"~/.paperclip/instances/default/config.json",value:n.cliConfigPath,onChange:p=>o(w=>({...w,cliConfigPath:p.target.value}))}),e.jsxs("small",{children:["Override the path to ",e.jsx("code",{children:"config.json"}),". Leave blank for the default."]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-cli-apikey",children:"API key (override, optional)"}),e.jsx("input",{id:"paperclip-cli-apikey",type:"password",placeholder:_?"":"Optional — only required for non-local-trusted modes",value:n.apiKey,onChange:p=>{o(w=>({...w,apiKey:p.target.value})),l(!0)}}),e.jsx("small",{children:"Local-trusted deployments do not require a key."}),d!==null&&H===!1&&n.agentId&&e.jsx("button",{type:"button",className:"btn btn--sm",style:{marginTop:"0.4rem"},disabled:C!==null,onClick:async()=>{const p=n.agentId,w=n.companyId.trim();if(!p||!w){E({kind:"err",message:"✗ Company ID is required to mint a Paperclip API key."});return}R("testing"),E(null);const V=await jl({cliBinaryPath:n.cliBinaryPath||void 0,agentRef:p,companyId:w,keyName:"fusion-runtime",configPath:n.cliConfigPath||void 0});i.current&&(R(null),V.ok?(o(ne=>({...ne,apiKey:V.key.apiKey})),l(!0),E({kind:"ok",message:`✓ API key minted via paperclipai (key 'fusion-runtime' installed for agent ${p}). Click Save to persist.`}),B()):E({kind:"err",message:`✗ Mint failed: ${V.reason}. Run \`paperclipai onboard\` first if your CLI isn't authenticated.`}))},children:"✨ Mint API key via paperclipai"})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-companyId",children:"Company"}),e.jsx("select",{id:"paperclip-companyId",value:n.companyId,onChange:p=>o(w=>({...w,companyId:p.target.value})),disabled:D.length===0,children:D.length===0?e.jsx("option",{value:"",children:H?"No companies discovered":"Connect to populate"}):D.map(p=>e.jsxs("option",{value:p.id,children:[p.name," (",p.id,")"]},p.id))}),e.jsx("small",{children:"Select a Paperclip company."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-agentId",children:"Agent"}),e.jsx("select",{id:"paperclip-agentId",value:n.agentId,onChange:p=>o(w=>({...w,agentId:p.target.value})),disabled:I.length===0,children:I.length===0?e.jsx("option",{value:"",children:n.companyId?"No agents discovered":"Pick a company first"}):I.map(p=>e.jsxs("option",{value:p.id,children:[p.name,p.role?` (${p.role})`:""]},p.id))}),e.jsx("small",{children:"Pick the Paperclip agent this Fusion runtime will proxy."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-mode",children:"Conversation mode"}),e.jsx("select",{id:"paperclip-mode",value:n.mode,onChange:p=>o(w=>({...w,mode:p.target.value})),children:ta.map(p=>e.jsx("option",{value:p.value,children:p.label},p.value))}),e.jsx("small",{children:ta.find(p=>p.value===n.mode)?.help})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-projectId",children:"Project ID (optional)"}),e.jsx("input",{id:"paperclip-projectId",type:"text",placeholder:"Optional",value:n.projectId,onChange:p=>o(w=>({...w,projectId:p.target.value}))}),e.jsx("small",{children:"Pin work to a specific Paperclip project."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-parentIssueId",children:"Parent issue ID (optional)"}),e.jsx("input",{id:"paperclip-parentIssueId",type:"text",placeholder:"Optional",value:n.parentIssueId,onChange:p=>o(w=>({...w,parentIssueId:p.target.value}))}),e.jsx("small",{children:"Scope work under an existing parent issue."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-goalId",children:"Goal ID (optional)"}),e.jsx("input",{id:"paperclip-goalId",type:"text",placeholder:"Optional",value:n.goalId,onChange:p=>o(w=>({...w,goalId:p.target.value}))}),e.jsx("small",{children:"Associate work with a Paperclip goal."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"paperclip-runTimeoutMs",children:"Run timeout (ms)"}),e.jsx("input",{id:"paperclip-runTimeoutMs",type:"number",min:0,step:1e3,value:n.runTimeoutMs,onChange:p=>o(w=>({...w,runTimeoutMs:parseInt(p.target.value,10)||be.runTimeoutMs}))}),e.jsx("small",{children:"Local cap before Fusion gives up on a Paperclip run."})]})]})}const He=[{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.
|
|
18
|
-
|
|
19
|
-
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.
|
|
20
|
-
|
|
21
|
-
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.
|
|
22
|
-
|
|
23
|
-
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.
|
|
24
|
-
|
|
25
|
-
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.
|
|
26
|
-
|
|
27
|
-
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.
|
|
28
|
-
|
|
29
|
-
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.
|
|
30
|
-
|
|
31
|
-
Be brief and precise — avoid verbosity.`,builtIn:!0}],sr={"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..."}},sa=["executor","triage","reviewer","merger"],et={executor:"Executor Agent",triage:"Triage Agent",reviewer:"Reviewer Agent",merger:"Merger Agent",scheduler:"Scheduler Agent",engineer:"Engineer Agent",custom:"Custom Agent"},Fe={executor:"#3b82f6",triage:"#f59e0b",reviewer:"#8b5cf6",merger:"#10b981",scheduler:"#06b6d4",engineer:"#ec4899",custom:"#6b7280"},Yt={name:"",description:"",role:"executor",prompt:""};function ar(n,o){const d=n.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,50),F=new Set(He.map(D=>D.id)),N=new Set(o.map(D=>D.id));if(!F.has(d)&&!N.has(d))return d;let T=2;for(;F.has(`${d}-${T}`)||N.has(`${d}-${T}`);)T++;return`${d}-${T}`}function lr({value:n,onChange:o,promptOverrides:d,onPromptOverridesChange:F}){const[N,T]=a.useState("templates"),[D,y]=a.useState(null),[I,M]=a.useState(!1),[C,R]=a.useState(Yt),[G,E]=a.useState(null),[_,l]=a.useState(null),[i,g]=a.useState(new Set),[A,x]=a.useState(null),[B,Q]=a.useState(!1),[ce,ae]=a.useState(null),K=a.useRef(null),H=n?.templates??[],S=n?.roleAssignments??{},q=ce===null?null:ce.source==="builtin"?He.find(u=>u.id===ce.id):H.find(u=>u.id===ce.id),W=a.useCallback(u=>{const j=He.filter(U=>U.role===u),L=H.filter(U=>U.role===u);return[...j,...L]},[H]);a.useEffect(()=>{ce!==null&&K.current?.focus()},[ce]);const Te=a.useCallback(()=>{M(!0),y(null),R(Yt),E(null),ae(null)},[]),xe=a.useCallback(u=>{y(u.id),M(!1),R({name:u.name,description:u.description,role:u.role,prompt:u.prompt}),E(null),ae(null)},[]),p=a.useCallback(()=>{y(null),M(!1),R(Yt),E(null),ae(null),Q(!1)},[]),w=a.useCallback(()=>{const u=C.name.trim();if(!u){E("Template name is required");return}let j;if(I){if(j=ar(u,H),new Set(He.map(me=>me.id)).has(j)){E(`Template ID "${j}" conflicts with a built-in template. Please use a different name.`);return}}else j=D;const L={id:j,name:u,description:C.description.trim(),role:C.role,prompt:C.prompt,builtIn:!1};let U;I?U=[...H,L]:U=H.map($=>$.id===j?L:$);const Z={...S};for(const[$,me]of Object.entries(Z))me===j&&C.role!==$&&delete Z[$];o({...n,templates:U,roleAssignments:Object.keys(Z).length>0?Z:void 0}),p()},[C,I,D,H,S,n,o,p]),V=a.useCallback(u=>{const j=H.filter(Z=>Z.id!==u),L={...S};let U=!1;for(const[Z,$]of Object.entries(L))$===u&&(delete L[Z],U=!0);o({...n,templates:j.length>0?j:void 0,roleAssignments:Object.keys(L).length>0||U?Object.keys(L).length>0?L:void 0:S}),l(null),D===u&&p()},[H,S,n,o,D,p]),ne=a.useCallback((u,j)=>{const L={...S};j===""?delete L[u]:L[u]=j,o({...n,roleAssignments:Object.keys(L).length>0?L:void 0})},[S,n,o]),de=a.useCallback((u,j)=>{const L={...d};L[u]=j||null,F(L)},[d,F]),le=a.useCallback(u=>{const j={...d};j[u]=null,F(j)},[d,F]),P=a.useCallback(u=>{g(j=>{const L=new Set(j);return L.has(u)?L.delete(u):L.add(u),L})},[]),J=a.useCallback(u=>{x(j=>j===u?null:u)},[]),re=a.useCallback((u,j)=>{Q(!1),ae({source:u,id:j})},[]),Be=a.useCallback(()=>{ae(null),Q(u=>!u)},[]),Ae=u=>He.some(j=>j.id===u);return e.jsxs("div",{className:"prompt-manager",children:[e.jsxs("div",{className:"prompt-manager-tabs",children:[e.jsxs("button",{className:`prompt-manager-tab ${N==="templates"?"active":""}`,onClick:()=>T("templates"),"data-testid":"tab-templates",children:[e.jsx(yl,{size:14}),"Templates"]}),e.jsxs("button",{className:`prompt-manager-tab ${N==="assignments"?"active":""}`,onClick:()=>T("assignments"),"data-testid":"tab-assignments",children:[e.jsx(Rn,{size:14}),"Assignments"]}),e.jsxs("button",{className:`prompt-manager-tab ${N==="overrides"?"active":""}`,onClick:()=>T("overrides"),"data-testid":"tab-overrides",children:[e.jsx(On,{size:14}),"Overrides"]})]}),e.jsxs("div",{className:"prompt-manager-content",children:[N==="templates"&&e.jsxs("div",{className:"prompt-manager-templates-tab","data-testid":"templates-tab",children:[(I||D!==null)&&e.jsxs("div",{className:"prompt-template-editor","data-testid":"template-editor",children:[e.jsx("h4",{className:"prompt-template-editor-title",children:I?"New Custom Template":"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:"Name"}),e.jsx("input",{id:"template-name",type:"text",value:C.name,onChange:u=>R(j=>({...j,name:u.target.value})),placeholder:"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:"Description"}),e.jsx("input",{id:"template-description",type:"text",value:C.description,onChange:u=>R(j=>({...j,description:u.target.value})),placeholder:"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:"Role"}),e.jsx("select",{id:"template-role",value:C.role,onChange:u=>R(j=>({...j,role:u.target.value})),"data-testid":"template-role-select",children:sa.map(u=>e.jsx("option",{value:u,children:et[u]},u))})]}),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:"Prompt"}),e.jsx("button",{type:"button",className:"btn-icon prompt-template-fullscreen-btn",onClick:Be,"aria-label":"Expand prompt to fullscreen","data-testid":"template-prompt-fullscreen",children:e.jsx(ft,{size:14})})]}),B?e.jsxs("div",{className:"prompt-override-fullscreen",onKeyDown:u=>{u.key==="Escape"&&(u.preventDefault(),Q(!1))},children:[e.jsxs("div",{className:"prompt-override-fullscreen-header",children:[e.jsx("div",{className:"prompt-override-fullscreen-title",children:"Edit Prompt"}),e.jsxs("button",{type:"button",className:"prompt-override-fullscreen-close",onClick:()=>Q(!1),"data-testid":"template-prompt-collapse",children:[e.jsx(_t,{size:14}),"Collapse"]})]}),e.jsx("textarea",{id:"template-prompt-fullscreen","aria-label":"Template prompt - fullscreen",className:"prompt-template-prompt-textarea",value:C.prompt,onChange:u=>R(j=>({...j,prompt:u.target.value})),placeholder:"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.jsxs("small",{className:"prompt-override-hint",children:[C.prompt.length," characters"]})})]}):e.jsx("textarea",{id:"template-prompt",value:C.prompt,onChange:u=>R(j=>({...j,prompt:u.target.value})),placeholder:"Enter the system prompt for this template...",rows:8,className:"prompt-template-prompt-textarea","data-testid":"template-prompt-input"})]}),G&&e.jsx("div",{className:"prompt-template-error","data-testid":"template-error",children:G}),e.jsxs("div",{className:"prompt-template-editor-actions",children:[e.jsx("button",{className:"btn btn-secondary",onClick:p,"data-testid":"cancel-template-btn",children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",onClick:w,"data-testid":"save-template-btn",children:I?"Create":"Save"})]})]})]}),e.jsxs("div",{className:"prompt-template-section","data-testid":"builtin-templates",children:[e.jsx("h4",{className:"prompt-template-section-title",children:"Built-in Templates"}),e.jsx("p",{className:"prompt-template-section-desc",children:"These templates are provided by Fusion and cannot be modified."}),e.jsx("div",{className:"prompt-template-list",children:He.map(u=>e.jsxs("div",{className:"prompt-template-card","data-testid":`builtin-template-${u.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:u.name}),e.jsx("span",{className:"prompt-template-badge-built-in",style:{borderColor:Fe[u.role]},children:"Built-in"}),e.jsx("span",{className:"prompt-template-badge-role",style:{backgroundColor:Fe[u.role]+"20",color:Fe[u.role]},children:et[u.role]})]}),e.jsx("div",{className:"prompt-template-card-actions",children:e.jsx("button",{type:"button",className:"btn-icon prompt-template-fullscreen-btn",onClick:()=>re("builtin",u.id),title:"View full prompt","aria-label":`View full prompt for ${u.name}`,"data-testid":`expand-view-${u.id}`,children:e.jsx(ft,{size:14})})})]}),e.jsx("p",{className:"prompt-template-card-description",children:u.description}),e.jsx("div",{className:"prompt-template-card-preview",children:e.jsx("code",{children:u.prompt})})]},u.id))})]}),e.jsxs("div",{className:"prompt-template-section","data-testid":"custom-templates",children:[e.jsx("h4",{className:"prompt-template-section-title",children:"Custom Templates"}),e.jsx("p",{className:"prompt-template-section-desc",children:"Create custom templates to override built-in prompts for specific roles."}),H.length===0&&!I&&e.jsx("div",{className:"prompt-template-empty",children:"No custom templates yet. Create one to get started."}),H.length>0&&e.jsx("div",{className:"prompt-template-list",children:H.map(u=>e.jsx("div",{className:"prompt-template-card","data-testid":`custom-template-${u.id}`,children:_===u.id?e.jsxs("div",{className:"prompt-template-delete-confirm",children:[e.jsxs("p",{children:['Delete "',u.name,'"?']}),e.jsxs("div",{className:"prompt-template-delete-actions",children:[e.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>V(u.id),"data-testid":`confirm-delete-${u.id}`,children:"Delete"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>l(null),"data-testid":`cancel-delete-${u.id}`,children:"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:u.name}),e.jsx("span",{className:"prompt-template-badge-custom",children:"Custom"}),e.jsx("span",{className:"prompt-template-badge-role",style:{backgroundColor:Fe[u.role]+"20",color:Fe[u.role]},children:et[u.role]}),Ae(u.id)&&e.jsx("span",{className:"prompt-template-badge-override",children:"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:()=>re("custom",u.id),title:"View full prompt","aria-label":`View full prompt for ${u.name}`,"data-testid":`expand-view-${u.id}`,children:e.jsx(ft,{size:14})}),e.jsx("button",{className:"btn-icon",onClick:()=>xe(u),title:"Edit","aria-label":`Edit ${u.name}`,"data-testid":`edit-${u.id}`,children:e.jsx(ma,{size:14})}),e.jsx("button",{className:"btn-icon",onClick:()=>l(u.id),title:"Delete","aria-label":`Delete ${u.name}`,"data-testid":`delete-${u.id}`,children:e.jsx(ua,{size:14})})]})]}),e.jsx("p",{className:"prompt-template-card-description",children:u.description}),e.jsx("div",{className:"prompt-template-card-preview",children:e.jsx("code",{children:u.prompt})})]})},u.id))}),!I&&D===null&&e.jsxs("button",{className:"btn btn-primary prompt-template-add-btn",onClick:Te,"data-testid":"add-template-btn",children:[e.jsx(ha,{size:14}),"Add Custom Template"]})]}),q&&e.jsxs("div",{ref:K,className:"prompt-override-fullscreen",role:"dialog","aria-modal":"true",tabIndex:-1,onKeyDown:u=>{u.key==="Escape"&&(u.preventDefault(),ae(null))},children:[e.jsxs("div",{className:"prompt-override-fullscreen-header",children:[e.jsxs("div",{className:"prompt-override-fullscreen-title",children:[q.name,e.jsx("span",{className:"prompt-template-badge-role",style:{backgroundColor:Fe[q.role]+"20",color:Fe[q.role]},children:et[q.role]})]}),e.jsxs("button",{type:"button",className:"prompt-override-fullscreen-close",onClick:()=>ae(null),"data-testid":`collapse-view-${q.id}`,children:[e.jsx(_t,{size:14}),"Collapse"]})]}),e.jsx("pre",{className:"prompt-template-fullscreen-pre",children:q.prompt})]})]}),N==="assignments"&&e.jsxs("div",{className:"prompt-manager-assignments-tab","data-testid":"assignments-tab",children:[e.jsx("p",{className:"prompt-assignments-desc",children:"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:sa.map(u=>{const j=W(u),L=S[u]??"",U=j.find($=>$.id===L),Z=!!L;return e.jsxs("div",{className:"prompt-role-assignment-row","data-testid":`assignment-${u}`,children:[e.jsxs("div",{className:"prompt-role-assignment-label",children:[e.jsx("span",{className:"prompt-role-badge",style:{backgroundColor:Fe[u]+"20",color:Fe[u]},children:et[u]}),Z&&e.jsxs("span",{className:"prompt-role-assignment-status",children:[U?.name??"Custom"," (overrides default)"]})]}),e.jsxs("select",{className:"prompt-role-select",value:L,onChange:$=>ne(u,$.target.value),"data-testid":`select-${u}`,children:[e.jsx("option",{value:"",children:"Use default"}),j.map($=>e.jsxs("option",{value:$.id,children:[$.name,Ae($.id)?" (built-in)":" (custom)"]},$.id))]})]},u)})}),Object.keys(S).length>0&&e.jsxs("div",{className:"prompt-assignments-note",children:[e.jsx("strong",{children:"Note:"})," Role assignments are stored in the agentPrompts configuration. Custom templates override built-ins by ID."]})]}),N==="overrides"&&e.jsxs("div",{className:"prompt-manager-overrides-tab","data-testid":"overrides-tab",children:[e.jsx("p",{className:"prompt-overrides-desc",children:"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(sr).map(u=>{const j=u.key,L=d?.[j]??"",U=L!=="",Z=i.has(j);return e.jsxs("div",{className:"prompt-override-item","data-testid":`override-${j}`,children:[e.jsxs("div",{className:"prompt-override-header",children:[e.jsxs("div",{className:"prompt-override-info",onClick:()=>P(j),role:"button",tabIndex:0,onKeyDown:$=>{($.key==="Enter"||$.key===" ")&&P(j)},children:[e.jsx("span",{className:"prompt-override-name",children:u.name}),e.jsx("code",{className:"prompt-override-key",children:j}),U&&e.jsx("span",{className:"prompt-override-badge",children:"customized"})]}),e.jsxs("div",{className:"prompt-override-header-actions",children:[Z&&e.jsx("button",{className:"prompt-override-fullscreen-btn",onClick:$=>{$.stopPropagation(),J(j)},"aria-label":"Expand to fullscreen","data-testid":`fullscreen-${j}`,children:e.jsx(ft,{size:14})}),e.jsx("button",{className:"prompt-override-expand-btn","aria-label":Z?"Collapse":"Expand","data-testid":`expand-${j}`,onClick:$=>{$.stopPropagation(),P(j)},children:Z?e.jsx(kl,{size:16}):e.jsx(Nl,{size:16})})]})]}),e.jsx("p",{className:"prompt-override-description",children:u.description}),Z&&(A===j?e.jsxs("div",{className:"prompt-override-fullscreen",onKeyDown:$=>{$.key==="Escape"&&($.preventDefault(),x(null))},children:[e.jsxs("div",{className:"prompt-override-fullscreen-header",children:[e.jsxs("div",{className:"prompt-override-fullscreen-title",children:[u.name,e.jsx("code",{className:"prompt-override-key",children:j})]}),e.jsxs("button",{type:"button",className:"prompt-override-fullscreen-close",onClick:()=>x(null),"data-testid":`collapse-fullscreen-${j}`,children:[e.jsx(_t,{size:14}),"Collapse"]})]}),e.jsx("textarea",{id:`prompt-${j}-fullscreen`,"aria-label":`${u.name} prompt override (${j}) - fullscreen`,className:"prompt-override-textarea",value:L,onChange:$=>{de(j,$.target.value)},placeholder:`Default: ${u.defaultContent.slice(0,100)}${u.defaultContent.length>100?"...":""}`,rows:30,autoFocus:!0,"data-testid":`override-input-fullscreen-${j}`}),e.jsxs("div",{className:"prompt-override-footer",children:[U&&e.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",onClick:()=>le(j),"data-testid":`reset-fullscreen-${j}`,children:"Reset"}),e.jsx("small",{className:"prompt-override-hint",children:U?"Custom override active. Click Reset to restore default.":`No override set. Using built-in default (${u.defaultContent.length} chars).`})]})]}):e.jsxs("div",{className:"prompt-override-editor",children:[e.jsx("textarea",{id:`prompt-${j}`,"aria-label":`${u.name} prompt override (${j})`,className:"prompt-override-textarea",value:L,onChange:$=>{de(j,$.target.value)},placeholder:`Default: ${u.defaultContent.slice(0,100)}${u.defaultContent.length>100?"...":""}`,rows:4,"data-testid":`override-input-${j}`}),e.jsxs("div",{className:"prompt-override-footer",children:[U&&e.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",onClick:$=>{$.stopPropagation(),le(j)},"data-testid":`reset-${j}`,children:"Reset"}),e.jsx("small",{className:"prompt-override-hint",children:U?"Custom override active. Click Reset to restore default.":`No override set. Using built-in default (${u.defaultContent.length} chars).`})]})]}))]},j)})})]})]})]})}const nr=["openai-compatible","anthropic-compatible"];function rr(n){return(Array.isArray(n)?n:n.providers??[]).map(d=>"apiType"in d?d:{id:d.id,name:d.name?.trim()||d.id,apiType:d.api==="anthropic-messages"?"anthropic-compatible":"openai-compatible",baseUrl:d.baseUrl,...d.apiKey?{apiKey:d.apiKey}:{},models:(d.models??[]).map(F=>({id:F.id,name:F.name??F.id}))})}function ir(n){return n.split(",").map(o=>o.trim()).filter(Boolean).map(o=>({id:o,name:o}))}function or({embedded:n=!1,onProviderChange:o}){const[d,F]=a.useState([]),[N,T]=a.useState(!1),[D,y]=a.useState(!1),[I,M]=a.useState(null),[C,R]=a.useState(null),[G,E]=a.useState(!1),[_,l]=a.useState(""),[i,g]=a.useState("openai-compatible"),[A,x]=a.useState(""),[B,Q]=a.useState(""),[ce,ae]=a.useState(""),[K,H]=a.useState(!1),[S,q]=a.useState(null),W=a.useCallback(async()=>{T(!0),M(null);try{const P=await Cl();F(rr(P)),y(!0)}catch(P){M(P instanceof Error?P.message:"Failed to load custom providers.")}finally{T(!1)}},[]),Te=a.useCallback(P=>{P&&!D&&!N&&W()},[D,N,W]);a.useEffect(()=>{n&&!D&&!N&&W()},[n,D,N,W]);const xe=a.useCallback(()=>{R(null),l(""),g("openai-compatible"),x(""),Q(""),ae(""),q(null),E(!1)},[]),p=a.useCallback(()=>{R(null),l(""),g("openai-compatible"),x(""),Q(""),ae(""),q(null),E(!0)},[]),w=a.useCallback(P=>{R(P),l(P.name),g(P.apiType),x(P.baseUrl),Q(P.apiKey??""),ae((P.models??[]).map(J=>J.id).join(", ")),q(null),E(!0)},[]),V=a.useCallback(()=>{if(!_.trim())return"Provider name is required.";if(!A.trim())return"Base URL is required.";let P=!1;try{const J=new URL(A.trim());P=J.protocol==="http:"||J.protocol==="https:"}catch{P=!1}return P?nr.includes(i)?null:"API type is invalid.":"Base URL must be a valid http/https URL."},[i,A,_]),ne=a.useCallback(async()=>{const P=V();if(q(P),P)return;const J=ir(ce),re={name:_.trim(),apiType:i,baseUrl:A.trim(),...B.trim()?{apiKey:B.trim()}:{},...J.length>0?{models:J}:{}};H(!0),M(null);try{C?await Sl(C.id,re):await wl(re),await W(),o?.(),xe()}catch(Be){q(Be instanceof Error?Be.message:"Failed to save provider.")}finally{H(!1)}},[B,i,A,C,W,ce,_,xe,V]),de=a.useCallback(async P=>{if(window.confirm(`Delete custom provider "${P.name}"?`)){M(null);try{await Pl(P.id),await W(),o?.()}catch(J){M(J instanceof Error?J.message:"Failed to delete provider.")}}},[W,o]),le=e.jsxs(e.Fragment,{children:[n?null:N?e.jsxs("div",{className:"custom-provider-empty",role:"status",children:[e.jsx(tt,{"aria-hidden":"true",className:"spin"})," Loading custom providers…"]}):null,n?null:!N&&I?e.jsxs("div",{className:"custom-provider-form-error",role:"alert",children:[e.jsx(Il,{"aria-hidden":"true"}),e.jsx("span",{children:I})]}):null,!N&&d.length>0?e.jsx("div",{className:"custom-provider-list",children:d.map(P=>{const J=G&&C?.id===P.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:P.name}),e.jsxs("div",{className:"custom-provider-item-meta",children:[e.jsx("span",{className:"custom-provider-badge",children:P.apiType})," ",P.baseUrl]})]}),e.jsxs("div",{className:"custom-provider-item-actions",children:[e.jsx("button",{type:"button",className:"btn btn-icon btn-sm",onClick:()=>w(P),"aria-label":`Edit ${P.name}`,children:e.jsx(ma,{"aria-hidden":"true"})}),e.jsx("button",{type:"button",className:"btn btn-icon btn-sm",onClick:()=>void de(P),"aria-label":`Delete ${P.name}`,children:e.jsx(ua,{"aria-hidden":"true"})})]})]}),J?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:"Provider name"}),e.jsx("input",{id:"custom-provider-name",className:"input",value:_,onChange:re=>l(re.target.value),disabled:K})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-api-type",children:"API type"}),e.jsxs("select",{id:"custom-provider-api-type",className:"select",value:i,onChange:re=>g(re.target.value),disabled:K,children:[e.jsx("option",{value:"openai-compatible",children:"OpenAI-compatible"}),e.jsx("option",{value:"anthropic-compatible",children:"Anthropic-compatible"})]})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-base-url",children:"Base URL"}),e.jsx("input",{id:"custom-provider-base-url",className:"input",placeholder:"https://api.example.com/v1",value:A,onChange:re=>x(re.target.value),disabled:K})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-api-key",children:"API key"}),e.jsx("input",{id:"custom-provider-api-key",type:"password",className:"input",value:B,onChange:re=>Q(re.target.value),disabled:K})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-models",children:"Available models"}),e.jsx("input",{id:"custom-provider-models",className:"input",placeholder:"e.g., gpt-4, gpt-3.5-turbo",value:ce,onChange:re=>ae(re.target.value),disabled:K})]}),S?e.jsx("div",{className:"custom-provider-form-error",children:S}):null,e.jsxs("div",{className:"custom-provider-form-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:xe,disabled:K,children:"Cancel"}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:()=>void ne(),disabled:K,children:K?"Saving…":"Save Changes"})]})]}):null]},P.id)})}):null,!N&&d.length===0&&!I?e.jsx("div",{className:"custom-provider-empty",children:"No custom providers configured."}):null,e.jsxs("button",{type:"button",className:"btn btn-sm custom-provider-add-btn",onClick:p,children:[e.jsx(ha,{"aria-hidden":"true"})," Add Custom Provider"]}),G&&!C?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:"Provider name"}),e.jsx("input",{id:"custom-provider-name",className:"input",value:_,onChange:P=>l(P.target.value),disabled:K})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-api-type",children:"API type"}),e.jsxs("select",{id:"custom-provider-api-type",className:"select",value:i,onChange:P=>g(P.target.value),disabled:K,children:[e.jsx("option",{value:"openai-compatible",children:"OpenAI-compatible"}),e.jsx("option",{value:"anthropic-compatible",children:"Anthropic-compatible"})]})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-base-url",children:"Base URL"}),e.jsx("input",{id:"custom-provider-base-url",className:"input",placeholder:"https://api.example.com/v1",value:A,onChange:P=>x(P.target.value),disabled:K})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-api-key",children:"API key"}),e.jsx("input",{id:"custom-provider-api-key",type:"password",className:"input",value:B,onChange:P=>Q(P.target.value),disabled:K})]}),e.jsxs("div",{className:"form-group custom-provider-form-row",children:[e.jsx("label",{htmlFor:"custom-provider-models",children:"Available models"}),e.jsx("input",{id:"custom-provider-models",className:"input",placeholder:"e.g., gpt-4, gpt-3.5-turbo",value:ce,onChange:P=>ae(P.target.value),disabled:K})]}),S?e.jsx("div",{className:"custom-provider-form-error",children:S}):null,e.jsxs("div",{className:"custom-provider-form-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:xe,disabled:K,children:"Cancel"}),e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:()=>void ne(),disabled:K,children:K?"Saving…":"Save Provider"})]})]}):null]});return e.jsx("div",{className:"custom-providers-section",children:n?le:e.jsx(Ml,{summary:"Advanced: Custom Providers",onToggle:Te,children:le})})}const cr=a.lazy(()=>pa(()=>import("./PluginManager-C2-dExUL.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9])).then(n=>({default:n.PluginManager}))),dr=a.lazy(()=>pa(()=>import("./PiExtensionsManager-C4fTzemh.js"),__vite__mapDeps([10,1,2,3,4,5,11])).then(n=>({default:n.PiExtensionsManager}))),Qt="fusion_github_star_count",aa=3600*1e3,la="fusion:github-star-clicked";function mr(n){return n==="online"?"Online":n==="connecting"?"Connecting":n==="error"?"Error":"Offline"}function ur(){const[n,o]=a.useState(()=>{try{return localStorage.getItem(la)==="true"}catch{return!1}}),d=a.useCallback(()=>{o(!0);try{localStorage.setItem(la,"true")}catch{}},[]);return[n,d]}function hr(){const[n,o]=a.useState(()=>{try{const d=localStorage.getItem(Qt);if(d){const F=JSON.parse(d);if(Date.now()-F.fetchedAt<aa)return F.count}}catch{}return null});return a.useEffect(()=>{try{const d=localStorage.getItem(Qt);if(d){const F=JSON.parse(d);if(Date.now()-F.fetchedAt<aa)return}}catch{}fetch("https://api.github.com/repos/Runfusion/Fusion").then(d=>{if(d.ok)return d.json()}).then(d=>{if(d&&typeof d.stargazers_count=="number"){const F={count:d.stargazers_count,fetchedAt:Date.now()};try{localStorage.setItem(Qt,JSON.stringify(F))}catch{}o(d.stargazers_count)}}).catch(()=>{})},[]),n}const na="(max-width: 768px)",Jt=".fusion/memory/DREAMS.md",ra=[{id:"__account_header",label:"Account",scope:void 0,isGroupHeader:!0},{id:"authentication",label:"Authentication",scope:void 0,icon:xt},{id:"__global_header",label:"Global",scope:void 0,isGroupHeader:!0},{id:"global-general",label:"General",scope:"global"},{id:"appearance",label:"Appearance",scope:"global"},{id:"notifications",label:"Notifications",scope:"global"},{id:"node-sync",label:"Node Sync",scope:"global"},{id:"global-models",label:"Models",scope:"global"},{id:"research-global",label:"Research Defaults",scope:"global"},{id:"experimental",label:"Experimental Features",scope:"global"},{id:"remote",label:"Remote Access",scope:"global"},{id:"__runtimes_header",label:"Runtimes",scope:void 0,isGroupHeader:!0},{id:"hermes-runtime",label:"Hermes",scope:"global"},{id:"openclaw-runtime",label:"OpenClaw",scope:"global"},{id:"paperclip-runtime",label:"Paperclip",scope:"global"},{id:"__project_header",label:"Project",scope:void 0,isGroupHeader:!0},{id:"general",label:"General",scope:"project"},{id:"project-models",label:"Project Models",scope:"project"},{id:"scheduling",label:"Scheduling",scope:"project"},{id:"node-routing",label:"Node Routing",scope:"project"},{id:"worktrees",label:"Worktrees",scope:"project"},{id:"commands",label:"Commands",scope:"project"},{id:"merge",label:"Merge",scope:"project"},{id:"memory",label:"Memory",scope:"project"},{id:"research-project",label:"Research",scope:"project"},{id:"prompts",label:"Prompts",scope:"project"},{id:"backups",label:"Backups",scope:"project"},{id:"plugins",label:"Plugins",scope:"project"}],ia=1440*60*1e3,pr=2,Xt=["in-review","merged","failed","awaiting-approval","awaiting-user-review","planning-awaiting-input","gridlock"],oa=[{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:"gridlock",label:"Pipeline gridlocked",description:"When all schedulable todo tasks are blocked and work cannot advance"}],ca={insights:"Insights",roadmap:"Roadmaps",memoryView:"Memory Editor",remoteAccess:"Remote Access",skillsView:"Skills View",nodesView:"Nodes View",devServerView:"Dev Server",todoView:"Todo List",researchView:"Research View",agentOnboarding:"Planning-style Agent Onboarding"},vt={devServer:"devServerView"};function xa(n){return vt[n]??n}function Zt(n,o){return n[o]===!0?!0:Object.entries(vt).some(([d,F])=>F===o&&n[d]===!0)}function gr(n){if(!n)return{};const o={};for(const[d,F]of Object.entries(n))o[xa(d)]=F;for(const[d,F]of Object.entries(vt))o[F]!==void 0&&!(d in o)&&(o[d]=null);return o}function kr({onClose:n,addToast:o,projectId:d,initialSection:F,themeMode:N="dark",colorTheme:T="default",onThemeModeChange:D,onColorThemeChange:y,dashboardFontScalePct:I=100,onDashboardFontScaleChange:M,onReopenOnboarding:C}){const{confirm:R}=Fl(),G=a.useRef(null),E=a.useRef(null);Tl(G,!0,"fusion:settings-modal-size");const _=Al(),[l,i]=a.useState({maxConcurrent:2,maxTriageConcurrent:2,maxWorktrees:4,pollIntervalMs:15e3,heartbeatMultiplier:1,groupOverlappingFiles:!0,overlapIgnorePaths:[],autoMerge:!0,mergeStrategy:"direct",recycleWorktrees:!1,worktreeNaming:"random",includeTaskIdInCommit:!0,worktreeInitCommand:"",ntfyEnabled:!1,ntfyTopic:void 0,webhookEnabled:!1,webhookUrl:void 0,webhookFormat:"generic",webhookEvents:void 0}),[g,A]=a.useState(!0),[x,B]=a.useState(null),[Q,ce]=a.useState(null),[ae,K]=a.useState(null),H=ra.find(t=>!t.isGroupHeader),[S,q]=a.useState(()=>F==="pi-extensions"?"plugins":F??H?.id??"authentication"),[W,Te]=a.useState(()=>F==="pi-extensions"?"pi-extensions":"fusion-plugins"),[xe,p]=a.useState(()=>typeof window<"u"&&typeof window.matchMedia=="function"?window.matchMedia(na)?.matches===!0:!1),[w,V]=a.useState(null),[ne,de]=a.useState(!1),[le,P]=a.useState(null),J=hr(),[re,Be]=ur(),[Ae,u]=a.useState(null),[j,L]=a.useState(null),[U,Z]=a.useState(null),{entries:$,currentPath:me,setPath:jt,loading:va,error:ja,refresh:ya}=El("project",U!==null,d),{nodes:as}=Rl(),ls=l.experimentalFeatures??{},yt=Zt(ls,"remoteAccess"),kt=Zt(ls,"researchView"),_e=ra.filter(t=>t.id==="remote"?yt:t.id==="research-global"||t.id==="research-project"?kt:!0),at=_e.find(t=>!t.isGroupHeader)?.id??"general",We=_e.find(t=>t.id===S)?.scope;a.useEffect(()=>{if(S==="remote"&&!yt){q(at);return}if((S==="research-global"||S==="research-project")&&!kt){q(at);return}_e.some(t=>t.id===S)||q(at)},[S,yt,kt,at,_e]);const[Ue,ns]=a.useState([]),[ka,rs]=a.useState(!1),[ve,fe]=a.useState(null),[is,ze]=a.useState({}),[Ve,lt]=a.useState({}),[nt,rt]=a.useState({}),je=a.useRef(null),[ie,os]=a.useState([]),[it,cs]=a.useState(!1),[ue,Nt]=a.useState([]),[he,Ct]=a.useState([]),[ot,ds]=a.useState({}),[Ye,Qe]=a.useState(null),[ee,ye]=a.useState(null),[ke,St]=a.useState(null),[wt,ct]=a.useState(!1),[Y,dt]=a.useState(null),[$e,Pt]=a.useState(null),[pe,ms]=a.useState(null),[us,hs]=a.useState(!1),[ps,It]=a.useState(null),[Ge,Na]=a.useState("persistent"),[Je,gs]=a.useState(null),[Mt,bs]=a.useState(null),[Ft,Ca]=a.useState(null),[Oe,Ke]=a.useState(null),[Tt,mt]=a.useState(""),[fs,xs]=a.useState(!1),[Ee,Xe]=a.useState(!1),[Sa,vs]=a.useState([]),[js,ys]=a.useState([]),[ge,At]=a.useState(Jt),[Et,wa]=a.useState(""),[ks,Ns]=a.useState(!1),[Re,Cs]=a.useState(null),[Ss,ws]=a.useState(!1),[Ps,Is]=a.useState(!1),[Ms,Fs]=a.useState(!1),Rt=a.useRef(!1),[ut,Ts]=a.useState(4),As=a.useRef(4),Es=a.useRef(!1),Rs=a.useRef(!1),[Pa,Ze]=a.useState(!1),[,Lt]=a.useState(null),[Ne,Ls]=a.useState(null),[ht,pt]=a.useState(!1),[Dt,Ia]=a.useState("both"),[$t,Ma]=a.useState(!0),Ds=a.useRef(null),{status:Fa,capabilities:Ta,loading:Aa,error:Ea,refresh:$s}=En({projectId:d,enabled:S==="memory"});a.useEffect(()=>{if(typeof window>"u"||typeof window.matchMedia!="function")return;const t=window.matchMedia(na);if(!t)return;const s=r=>{p(r?r.matches:t.matches)};return s(),t.addEventListener("change",s),()=>t.removeEventListener("change",s)},[]),a.useEffect(()=>{Promise.all([Hs(d),Ll(d)]).then(([t,s])=>{i(t),B(t),ce(s),K(s),A(!1)}).catch(t=>{o(se(t),"error"),A(!1)})},[o,d]),a.useEffect(()=>{if(S!=="scheduling"||Es.current)return;let t=!1;return Dl().then(s=>{t||(Rs.current||Ts(s.globalMaxConcurrent),As.current=s.globalMaxConcurrent,Es.current=!0)}).catch(()=>{}),()=>{t=!0}},[S]),a.useEffect(()=>{let t=!1;return $l().then(s=>{t||typeof s.version=="string"&&s.version.trim().length>0&&V(s.version)}).catch(()=>{}),()=>{t=!0}},[]);const Ra=a.useCallback(async()=>{de(!0);try{const t=await Ol();P(t),t.error&&o(t.error,"error")}catch(t){const s=se(t)||"Failed to check for updates";P({currentVersion:w??"unknown",latestVersion:null,updateAvailable:!1,error:s}),o(s,"error")}finally{de(!1)}},[o,w]),La=a.useCallback(()=>le?le.error?le.error:le.updateAvailable&&le.latestVersion?e.jsxs(e.Fragment,{children:["v",le.latestVersion," available ·"," ",e.jsx("a",{href:"https://runfusion.ai",target:"_blank",rel:"noreferrer",className:"settings-update-result-link",children:"Learn more"})]}):"You're up to date ✓":null,[le]),oe=a.useCallback(async()=>{try{const{providers:t}=await qs(),s=Ws(t);ns(s),ze(r=>{const m={};for(const[c,b]of Object.entries(r)){const k=s.find(O=>O.id===c);k&&!k.authenticated&&(m[c]=b)}return Object.keys(m).length===Object.keys(r).length?r:m})}catch{}},[]);a.useEffect(()=>{(S==="global-models"||S==="project-models")&&(cs(!0),Bl().then(t=>{os(t.models),Nt(t.favoriteProviders),Ct(t.favoriteModels)}).catch(()=>os([])).finally(()=>cs(!1)))},[S]),a.useEffect(()=>{S==="backups"&&(ct(!0),Vs(d).then(t=>St(t)).catch(()=>St(null)).finally(()=>ct(!1)))},[S,d]);const gt=a.useCallback(async()=>{const[t,s]=await Promise.allSettled([_l(d),Ut(d)]);t.status==="fulfilled"&&i(r=>({...r,...t.value.settings})),s.status==="fulfilled"&&(dt(s.value),Pt(s.value.externalTunnel??null))},[d]);a.useEffect(()=>{const t=Y?.state;(t==="running"||t==="starting")&&Pt(null)},[Y?.state]),a.useEffect(()=>{S==="remote"&>().catch(()=>{dt(null)})},[S,gt]),a.useEffect(()=>{if(S!=="remote")return;const t=Y?.state;if(t!=="starting"&&t!=="stopping")return;const s=setInterval(()=>{Ut(d).then(r=>{dt(r),Pt(r.externalTunnel??null)}).catch(()=>{})},1e3);return()=>clearInterval(s)},[S,d,Y?.state]),a.useEffect(()=>{if(S!=="remote")return;if(Y?.state!=="running"){Ke(null);return}let t=!1;return(async()=>{try{const s=await zt("image/svg",{projectId:d,tokenType:"persistent"});if(t)return;Ke({url:s.url,qrSvg:s.data??null})}catch{if(t)return;try{const s=await Ys({projectId:d,tokenType:"persistent"});if(t)return;Ke({url:s.url,qrSvg:null})}catch{t||Ke(null)}}})(),()=>{t=!0}},[S,d,Y?.state,Y?.url]),a.useEffect(()=>{if(S!=="remote")return;const t=$e?.url;if(Y?.state!=="stopped"||!t)return;let s=!1;return(async()=>{try{const r=await zt("image/svg",{projectId:d,tokenType:"persistent"});if(s)return;Ke({url:t,qrSvg:r.data??null})}catch{s||Ke({url:t,qrSvg:null})}})(),()=>{s=!0}},[S,$e?.url,d,Y?.state]),a.useEffect(()=>{S==="worktrees"&&Ul(d).then(t=>vs(t)).catch(()=>vs([]))},[S,d]),a.useEffect(()=>{if(S!=="memory"||Ee)return;if(Rt.current){Rt.current=!1;return}let t=!1;return xs(!0),Qs(d).then(async({files:s})=>{if(t)return;ys(s);const r=s.some(c=>c.path===ge)?ge:s.find(c=>c.path===Jt)?.path??s.find(c=>c.layer==="dreams")?.path??s[0]?.path??Jt;At(r);const{content:m}=await zl(r,d);t||(mt(m),Xe(!1))}).catch(s=>{t||(o(se(s)||"Failed to load project memory","error"),mt(""))}).finally(()=>{t||xs(!1)}),()=>{t=!0}},[S,Ee,ge,d,o]),a.useEffect(()=>((S==="authentication"||S==="research-global")&&(rs(!0),oe().finally(()=>rs(!1))),()=>{je.current&&(clearInterval(je.current),je.current=null)}),[S,oe]),a.useEffect(()=>{if(S!=="authentication"||!Ue.some(r=>r.type!=="api_key"&&r.loginInProgress))return;const s=setInterval(()=>{oe()},2e3);return()=>clearInterval(s)},[S,Ue,oe]);const bt=a.useCallback(()=>{E.current?.scrollTo({top:0,behavior:"smooth"})},[]),Da=a.useCallback(async t=>{fe(t),ze(s=>{if(!(t in s))return s;const r={...s};return delete r[t],r});try{const{url:s,instructions:r}=await Gl(t);r?.trim()&&ze(m=>({...m,[t]:r})),window.open(Kl(s),"_blank"),je.current=setInterval(async()=>{try{const{providers:m}=await qs(),c=Ws(m);ns(c),c.find(k=>k.id===t)?.authenticated&&(je.current&&(clearInterval(je.current),je.current=null),fe(null),ze(k=>{if(!(t in k))return k;const O={...k};return delete O[t],O}),o("Login successful","success"),bt())}catch{}},2e3)}catch(s){const r=se(s)||"Login failed";r.includes("already in progress")||typeof s=="object"&&s!==null&&"status"in s&&s.status===409?(o("Login already in progress. You can cancel it and retry.","warning"),await oe()):o(r,"error"),fe(null),ze(c=>{if(!(t in c))return c;const b={...c};return delete b[t],b})}},[o,oe,bt]),Os=a.useCallback(async t=>{fe(t);try{await Hl(t),ze(s=>{if(!(t in s))return s;const r={...s};return delete r[t],r}),await oe(),o("Login cancelled","success")}catch(s){o(se(s)||"Failed to cancel login","error")}finally{fe(null),je.current&&(clearInterval(je.current),je.current=null)}},[o,oe]),$a=a.useCallback(async t=>{fe(t);try{await ql(t),await oe(),o("Logged out","success")}catch(s){o(se(s)||"Logout failed","error")}finally{fe(null)}},[o,oe]),Bs=a.useCallback(async t=>{const s=Ve[t]?.trim();if(!s){rt(r=>({...r,[t]:"API key is required"}));return}fe(t),rt(r=>{const m={...r};return delete m[t],m});try{await Wl(t,s),lt(r=>{const m={...r};return delete m[t],m}),await oe(),o("API key saved","success"),bt()}catch(r){rt(m=>({...m,[t]:se(r)||"Failed to save API key"}))}finally{fe(null)}},[Ve,o,oe,bt]),Oa=a.useCallback(async t=>{fe(t);try{await Vl(t),lt(s=>{const r={...s};return delete r[t],r}),rt(s=>{const r={...s};return delete r[t],r}),await oe(),o("API key cleared","success")}catch(s){o(se(s)||"Failed to clear API key","error")}finally{fe(null)}},[o,oe]),_s=a.useCallback(async t=>{if(!(t==="ntfy"&&(!l.ntfyEnabled||!l.ntfyTopic||!/^[a-zA-Z0-9_-]{1,64}$/.test(l.ntfyTopic)))){if(t==="webhook"){if(!l.webhookEnabled||!l.webhookUrl?.trim())return;try{const s=new URL(l.webhookUrl.trim());if(s.protocol!=="http:"&&s.protocol!=="https:")return}catch{return}}ds(s=>({...s,[t]:!0}));try{const s=t==="ntfy"?{ntfyEnabled:l.ntfyEnabled,ntfyTopic:l.ntfyTopic,...l.ntfyBaseUrl?.trim()?{ntfyBaseUrl:l.ntfyBaseUrl.trim()}:{}}:{webhookUrl:l.webhookUrl,webhookFormat:l.webhookFormat||"generic"};(await Yl(t,s,d)).success?o(`Test notification sent — check your ${t==="ntfy"?"ntfy app":"webhook endpoint"}!`,"success"):o("Failed to send test notification","error")}catch(s){o(se(s)||"Failed to send test notification","error")}finally{ds(s=>({...s,[t]:!1}))}}},[o,l.ntfyBaseUrl,l.ntfyEnabled,l.ntfyTopic,l.webhookEnabled,l.webhookFormat,l.webhookUrl,d]),Ba=a.useCallback(async()=>{ct(!0);try{const t=await Ql(d);if(t.success){o("Backup created successfully","success");const s=await Vs(d);St(s)}else o(t.error||"Failed to create backup","error")}catch(t){o(se(t)||"Failed to create backup","error")}finally{ct(!1)}},[o,d]),_a=a.useCallback(async()=>{try{const t=We==="global"?"global":We==="project"?"project":"both",s=await Jl(t,d),r=new Blob([JSON.stringify(s,null,2)],{type:"application/json"}),m=URL.createObjectURL(r),c=document.createElement("a"),b=`fusion-settings-${new Date().toISOString().replace(/[:.]/g,"-").slice(0,19)}.json`;c.href=m,c.download=b,document.body.appendChild(c),c.click(),document.body.removeChild(c),URL.revokeObjectURL(m),o(`Settings exported (${t==="global"?"global":t==="project"?"project":"all"} scope)`,"success")}catch(t){o(se(t)||"Failed to export settings","error")}},[o,We,d]),Ua=a.useCallback(async t=>{const s=t.target.files?.[0];if(s){Lt(s),pt(!0);try{const r=await s.text(),m=JSON.parse(r);Ls(m),Ze(!0)}catch(r){o(`Invalid JSON file: ${se(r)}`,"error"),Lt(null)}finally{pt(!1)}}},[o]),za=a.useCallback(async()=>{if(Ne){pt(!0);try{const t=await Xl(Ne,{scope:Dt,merge:$t},d);if(t.success){const s=[];t.globalCount>0&&s.push(`${t.globalCount} global`),t.projectCount>0&&s.push(`${t.projectCount} project`),o(`Imported ${s.join(", ")} setting(s)`,"success"),Ze(!1),Ls(null),Lt(null);const r=await Hs(d);i(r)}else o(t.error||"Import failed","error")}catch(t){o(se(t)||"Failed to import settings","error")}finally{pt(!1)}}},[o,Ne,Dt,$t,d]),Pe=a.useCallback(async t=>{const s=ue,m=s.includes(t)?s.filter(c=>c!==t):[t,...s];Nt(m);try{await Gt({favoriteProviders:m,favoriteModels:he})}catch{Nt(s)}},[ue,he]),Ie=a.useCallback(async t=>{const s=he,m=s.includes(t)?s.filter(c=>c!==t):[t,...s];Ct(m);try{await Gt({favoriteProviders:ue,favoriteModels:m})}catch{Ct(s)}},[he,ue]);a.useEffect(()=>{const t=s=>{s.key==="Escape"&&n()};return document.addEventListener("keydown",t),()=>document.removeEventListener("keydown",t)},[n]);const Ga=Zl(n),Us=[{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 Ot(t){if(!Q?.project)return"inherited";const s=Q.project[t.projectProviderKey],r=Q.project[t.projectModelKey];return s!==void 0||r!==void 0?"overridden":"inherited"}function Ka(t){const s=l[t.projectProviderKey],r=l[t.projectModelKey];return s&&r?`${s}/${r}`:""}function Ha(t,s){if(s){const r=s.indexOf("/");i(m=>({...m,[t.projectProviderKey]:s.slice(0,r),[t.projectModelKey]:s.slice(r+1)}))}else{if(Ot(t)==="inherited")return;i(m=>({...m,[t.projectProviderKey]:void 0,[t.projectModelKey]:void 0}))}}function qa(t){Ot(t)!=="inherited"&&i(r=>({...r,[t.projectProviderKey]:void 0,[t.projectModelKey]:void 0}))}const Wa=a.useCallback(t=>{Z(t),jt(".")},[jt]),Le=a.useCallback(()=>{Z(null)},[]),Bt=a.useCallback(t=>{U!==null&&(i(s=>{const r=s.overlapIgnorePaths&&s.overlapIgnorePaths.length>0?[...s.overlapIgnorePaths]:[""];return r[U]=t,{...s,overlapIgnorePaths:r}}),Le())},[U,Le]),Va=a.useCallback(()=>{if(me===".")return;const t=me.endsWith("/")?me:`${me}/`;Bt(t)},[me,Bt]),Ya=a.useCallback(t=>{t.target===t.currentTarget&&Le()},[Le]),Qa=a.useCallback((t,s)=>{i(r=>{const m=r.overlapIgnorePaths&&r.overlapIgnorePaths.length>0?[...r.overlapIgnorePaths]:[""];return m[t]=s,{...r,overlapIgnorePaths:m}})},[]),Ja=a.useCallback(t=>{if(i(s=>{const m=(s.overlapIgnorePaths&&s.overlapIgnorePaths.length>0?[...s.overlapIgnorePaths]:[""]).filter((c,b)=>b!==t);return{...s,overlapIgnorePaths:m.length>0?m:[]}}),U===t){Le();return}U!==null&&U>t&&Z(U-1)},[U,Le]),Xa=a.useCallback(()=>{i(t=>{const s=t.overlapIgnorePaths&&t.overlapIgnorePaths.length>0?t.overlapIgnorePaths:[""];return{...t,overlapIgnorePaths:[...s,""]}})},[]),Za=a.useCallback(async()=>{if(Ae||ee)return;const t=l.researchSettings?.limits;if(t?.maxConcurrentRuns!==void 0&&(!Number.isFinite(t.maxConcurrentRuns)||t.maxConcurrentRuns<1)){L("Research max concurrent runs must be at least 1.");return}if(t?.maxSourcesPerRun!==void 0&&(!Number.isFinite(t.maxSourcesPerRun)||t.maxSourcesPerRun<1)){L("Research max sources per run must be at least 1.");return}if(t?.maxDurationMs!==void 0&&(!Number.isFinite(t.maxDurationMs)||t.maxDurationMs<1e3)){L("Research max duration must be at least 1000 ms.");return}if(t?.requestTimeoutMs!==void 0&&(!Number.isFinite(t.requestTimeoutMs)||t.requestTimeoutMs<1e3)){L("Research request timeout must be at least 1000 ms.");return}L(null);try{const s={...l,worktreeInitCommand:l.worktreeInitCommand?.trim()||void 0,taskPrefix:l.taskPrefix?.trim()||void 0,overlapIgnorePaths:(l.overlapIgnorePaths??[]).map(c=>c.trim()).filter(c=>c.length>0),experimentalFeatures:gr(l.experimentalFeatures)},r={};for(const[c,b]of Object.entries(s))if(en(c)){const k=x?.[c];b===void 0&&k!==void 0?r[c]=null:r[c]=b}const m={};for(const[c,b]of Object.entries(s)){if(c==="githubTokenConfigured"||c==="prAuthAvailable"||!tn(c))continue;const k=ae?.project?.[c];["planningProvider","planningModelId","validatorProvider","validatorModelId","executionProvider","executionModelId","titleSummarizerProvider","titleSummarizerModelId","defaultProviderOverride","defaultModelIdOverride","planningFallbackProvider","planningFallbackModelId","validatorFallbackProvider","validatorFallbackModelId","titleSummarizerFallbackProvider","titleSummarizerFallbackModelId"].includes(c)?b!==k&&(b==null&&k!==void 0&&k!==null?m[c]=null:b!==void 0&&(m[c]=b)):m[c]=b}await Promise.all([Object.keys(r).length>0?Gt(r):Promise.resolve(),Object.keys(m).length>0?sn(m,d):Promise.resolve(),ut!==As.current?an({globalMaxConcurrent:ut??4}):Promise.resolve()]),o("Settings saved","success"),n()}catch(s){o(se(s),"error")}},[l,ut,Ae,ee,x,ae,n,o,d]),el=a.useCallback(async()=>{try{await ln(ge,Tt,d),Xe(!1),o("Memory saved","success")}catch(t){o(se(t)||"Failed to save memory","error")}},[ge,Tt,d,o]),tl=a.useCallback(async()=>{Is(!0);try{const{path:t,content:s}=await nn(ge,d),r=t??ge;ge!==r&&(Rt.current=!0),At(r),mt(s),Xe(!1);const{files:m}=await Qs(d);ys(m),o("Memory file compacted","success")}catch(t){o(se(t)||"Failed to compact memory","error")}finally{Is(!1)}},[ge,d,o]),sl=a.useCallback(async()=>{Ns(!0),Cs(null);try{const t=await rn(Et,d);Cs(t),o(t.qmdAvailable?"Memory retrieval test complete":"qmd is not installed; local fallback was used",t.qmdAvailable?"success":"warning")}catch(t){o(se(t)||"Failed to test memory retrieval","error")}finally{Ns(!1)}},[Et,d,o]),al=a.useCallback(async()=>{ws(!0);try{await on(d),o("Dream processing completed","success")}catch(t){o(t instanceof Error?t.message:"Failed to run dream processing","error")}finally{ws(!1)}},[d,o]),ll=a.useCallback(async()=>{Fs(!0);try{const t=await cn(d);await $s(),o(t.qmdAvailable?"qmd installed successfully":"qmd install finished, but qmd is still unavailable",t.qmdAvailable?"success":"warning")}catch(t){o(se(t)||"Failed to install qmd","error")}finally{Fs(!1)}},[d,$s,o]),nl=()=>{if(!ee)return;const t=ee.name.trim();if(!t){o("Preset name is required","error");return}const s=l.modelPresets||[];let r;Ye?r=Ye:r=An(t,s);const m={id:r,name:t,executorProvider:ee.executorProvider,executorModelId:ee.executorModelId,validatorProvider:ee.validatorProvider,validatorModelId:ee.validatorModelId};i(c=>{const b=c.modelPresets||[],k=Ye?b.map(O=>O.id===Ye?m:O):[...b,m];return{...c,modelPresets:k}}),Qe(null),ye(null)},De=a.useCallback(async(t,s)=>{ms(t);try{await s(),await gt()}catch(r){o(se(r)||`Failed to ${t}`,"error")}finally{ms(null)}},[o,gt]),rl=a.useCallback(()=>{if(typeof navigator<"u"&&navigator.userAgent.includes("Windows"))return"winget install Cloudflare.cloudflared";const t=typeof navigator<"u"?navigator.platform:"",s=typeof navigator<"u"?navigator.userAgent:"",r=/(Mac|iPhone|iPad|iPod)/i.test(t),m=/(arm64|aarch64)/i.test(`${t} ${s}`);return r?"brew install cloudflared":`curl -L --output /tmp/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${m?"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`},[]),zs=a.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`,[]),il=a.useCallback(async()=>{hs(!0),It(null);try{const t=await dn(d);if(!t.success){It(t.error??"Installation failed");return}const s=await Ut(d);dt(s),o("cloudflared installed successfully","success")}catch(t){It(t instanceof Error?t.message:"Installation failed")}finally{hs(!1)}},[o,d]),X=()=>We==="global"?e.jsxs("div",{className:"settings-scope-banner settings-scope-global",children:[e.jsx("span",{className:"settings-scope-icon",children:e.jsx(xt,{size:14})}),e.jsx("span",{children:"These settings are shared across all your Fusion projects."})]}):We==="project"?e.jsxs("div",{className:"settings-scope-banner settings-scope-project",children:[e.jsx("span",{className:"settings-scope-icon",children:e.jsx(Js,{size:14})}),e.jsx("span",{children:"These settings only affect this project."})]}):null,ol=()=>{switch(S){case"general":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"General"}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"taskPrefix",children:"Task Prefix"}),e.jsx("input",{id:"taskPrefix",type:"text",placeholder:"FN",value:l.taskPrefix||"",onChange:t=>{const s=t.target.value;i(r=>({...r,taskPrefix:s||void 0})),s&&!/^[A-Z]{1,10}$/.test(s)?u("Prefix must be 1–10 uppercase letters"):u(null)}}),Ae&&e.jsx("small",{className:"field-error",children:Ae}),!Ae&&e.jsx("small",{children:"Prefix for new task IDs (e.g. KB, PROJ)"})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"requirePlanApproval",className:"checkbox-label",children:[e.jsx("input",{id:"requirePlanApproval",type:"checkbox",checked:l.requirePlanApproval||!1,onChange:t=>i(s=>({...s,requirePlanApproval:t.target.checked}))}),"Require plan approval"]}),e.jsx("small",{children:"When enabled, AI-generated task specifications require manual approval before moving to Todo"})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"showQuickChatFAB",className:"checkbox-label",children:[e.jsx("input",{id:"showQuickChatFAB",type:"checkbox",checked:l.showQuickChatFAB===!0,onChange:t=>i(s=>({...s,showQuickChatFAB:t.target.checked}))}),"Show quick chat button"]}),e.jsx("small",{children:"Show the floating chat button in the dashboard. Chat is still accessible from the Chat tab in the mobile navigation."})]})]});case"global-general":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"General"}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"showGitHubStarButton",className:"checkbox-label",children:[e.jsx("input",{id:"showGitHubStarButton",type:"checkbox",checked:l.showGitHubStarButton!==!1,onChange:t=>i(s=>({...s,showGitHubStarButton:t.target.checked}))}),'Show "Star on GitHub" button in Settings header']}),e.jsx("small",{children:"Once you click the Star button it's hidden automatically. Uncheck this to keep it hidden even before clicking."})]}),e.jsx(Kn,{}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"fnBinaryCheckEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"fnBinaryCheckEnabled",type:"checkbox",checked:l.fnBinaryCheckEnabled!==!1,onChange:t=>i(s=>({...s,fnBinaryCheckEnabled:t.target.checked}))}),"Check for the ",e.jsx("code",{children:"fn"})," CLI binary on PATH"]}),e.jsxs("small",{children:["When enabled, the dashboard probes for a globally-installed"," ",e.jsx("code",{children:"fn"})," / ",e.jsx("code",{children:"fusion"})," CLI by spawning"," ",e.jsx("code",{children:"<bin> --version"}),". 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:"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:l.updateCheckEnabled!==!1,onChange:t=>i(s=>({...s,updateCheckEnabled:t.target.checked}))}),"Check for updates automatically"]}),e.jsxs("small",{children:["When enabled, Fusion checks npm for new versions of"," ",e.jsx("code",{children:"@runfusion/fusion"})," 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:"Frequency"}),e.jsxs("select",{id:"updateCheckFrequency",value:l.updateCheckFrequency??"daily",onChange:t=>i(s=>({...s,updateCheckFrequency:t.target.value})),disabled:l.updateCheckEnabled===!1,children:[e.jsx("option",{value:"manual",children:"Manual only — never auto-check"}),e.jsx("option",{value:"on-startup",children:"On startup — once per server launch"}),e.jsx("option",{value:"daily",children:"Daily (recommended)"}),e.jsx("option",{value:"weekly",children:"Weekly"})]}),e.jsx("small",{children:"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."})]})]});case"global-models":{const t=l.defaultProvider&&l.defaultModelId?`${l.defaultProvider}/${l.defaultModelId}`:"",s=Us.filter(r=>r.laneId!=="default");return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Default Model"}),it?e.jsx("div",{className:"settings-empty-state",children:"Loading available models…"}):ie.length===0?e.jsx("div",{className:"settings-empty-state settings-muted",children:"No models available. Configure authentication first."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"defaultModel",children:"Default Model"}),e.jsx(Me,{id:"defaultModel",label:"Default Model",models:ie,value:t,onChange:r=>{if(!r)i(m=>({...m,defaultProvider:void 0,defaultModelId:void 0}));else{const m=r.indexOf("/");i(c=>({...c,defaultProvider:r.slice(0,m),defaultModelId:r.slice(m+1)}))}},placeholder:"Use default",favoriteProviders:ue,onToggleFavorite:Pe,favoriteModels:he,onToggleModelFavorite:Ie}),e.jsx("small",{children:'Default AI model used for task execution when no per-task override is set. "Use default" lets the engine choose automatically.'})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"fallbackModel",children:"Fallback Model"}),e.jsx(Me,{id:"fallbackModel",label:"Fallback Model",models:ie,value:l.fallbackProvider&&l.fallbackModelId?`${l.fallbackProvider}/${l.fallbackModelId}`:"",onChange:r=>{if(!r)i(m=>({...m,fallbackProvider:void 0,fallbackModelId:void 0}));else{const m=r.indexOf("/");i(c=>({...c,fallbackProvider:r.slice(0,m),fallbackModelId:r.slice(m+1)}))}},placeholder:"No fallback",favoriteProviders:ue,onToggleFavorite:Pe,favoriteModels:he,onToggleModelFavorite:Ie}),e.jsx("small",{children:"Used automatically if the primary default model hits a retryable provider error like rate limiting or overload."})]})]}),(()=>{const r=ie.find(m=>m.provider===l.defaultProvider&&m.id===l.defaultModelId);return r&&!r.reasoning?null:e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"defaultThinkingLevel",children:"Thinking Effort"}),e.jsxs("select",{id:"defaultThinkingLevel",value:l.defaultThinkingLevel||"",onChange:m=>{const c=m.target.value;i(b=>({...b,defaultThinkingLevel:c||void 0}))},children:[e.jsx("option",{value:"",children:"Default"}),Tn.map(m=>e.jsx("option",{value:m,children:m.charAt(0).toUpperCase()+m.slice(1)},m))]}),e.jsx("small",{children:"Controls how much reasoning effort the AI model uses. Higher levels produce better results but cost more."})]})})(),ie.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:"Model Lanes"}),e.jsx("p",{className:"settings-description",children:"Global baseline models for each AI role. Project settings can override these per-project."}),s.map(r=>{const m=l[r.globalProviderKey],c=l[r.globalModelKey],b=m&&c?`${m}/${c}`:"";return e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:`global-${r.laneId}-model`,children:r.label}),e.jsx(Me,{id:`global-${r.laneId}-model`,label:r.label,models:ie,value:b,onChange:k=>{if(!k){i(z=>({...z,[r.globalProviderKey]:void 0,[r.globalModelKey]:void 0}));return}const O=k.indexOf("/");i(z=>({...z,[r.globalProviderKey]:k.slice(0,O),[r.globalModelKey]:k.slice(O+1)}))},placeholder:"Use default",favoriteProviders:ue,onToggleFavorite:Pe,favoriteModels:he,onToggleModelFavorite:Ie}),e.jsx("small",{children:r.helperText})]},`global-${r.laneId}`)})]}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:"OpenRouter Models"}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"openrouterModelSync",className:"checkbox-label",children:[e.jsx("input",{id:"openrouterModelSync",type:"checkbox",checked:l.openrouterModelSync!==!1,onChange:r=>i(m=>({...m,openrouterModelSync:r.target.checked}))}),"Sync OpenRouter model list at dashboard startup"]}),e.jsx("small",{children:"When enabled, the dashboard fetches the latest available models from the OpenRouter API on startup, so the model picker always shows the most up-to-date catalog. Disable to skip the initial API call and use only the built-in model list."})]})]})}case"project-models":{const t=l.modelPresets||[],s=t.map(f=>({id:f.id,name:f.name})),r=new Set(Object.values(l.defaultPresetBySize||{}).filter(Boolean)),m=Us.filter(f=>f.laneId==="default"||f.laneId==="execution"||f.laneId==="planning"||f.laneId==="validator"),c=Pn(l),b=In(l),k=Mn(l),O=f=>f.laneId==="default"?"Project Default Model":f.label,z=f=>f.laneId==="default"?"Project-wide default AI model used when no more specific task or project lane override is set.":f.helperText;return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Token Cap"}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"tokenCap",children:"Token Cap"}),e.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[e.jsx("input",{id:"tokenCap",type:"number",placeholder:"No cap",value:l.tokenCap??"",onChange:f=>{const v=f.target.value;i(h=>({...h,tokenCap:v?parseInt(v,10):null}))}}),l.tokenCap!=null&&e.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",title:"Reset to default (no cap)",onClick:()=>i(f=>({...f,tokenCap:null})),style:{whiteSpace:"nowrap"},children:"Reset"})]}),e.jsx("small",{children:"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:"Model Lanes"}),e.jsx("p",{className:"settings-description",children:"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."}),it?e.jsx("div",{className:"settings-empty-state",children:"Loading available models…"}):ie.length===0?e.jsx("div",{className:"settings-empty-state settings-muted",children:"No models available. Configure authentication first."}):e.jsx(e.Fragment,{children:m.map(f=>{const v=Ot(f),h=Ka(f),te=v==="overridden",Ce=O(f);return e.jsxs("div",{className:"form-group",children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.25rem"},children:[e.jsx("label",{htmlFor:`${f.laneId}Model`,children:Ce}),e.jsx("span",{className:`settings-lane-badge ${te?"settings-lane-badge--override":"settings-lane-badge--inherited"}`,title:te?"Explicitly set for this project":"Inherited from global settings",children:te?"Override (Project)":"Inherited (Global)"})]}),e.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[e.jsx("div",{style:{flex:1},children:e.jsx(Me,{id:`${f.laneId}Model`,label:Ce,models:ie,value:h,onChange:cl=>Ha(f,cl),placeholder:f.laneId==="default"?"Use global default":"Use global",favoriteProviders:ue,onToggleFavorite:Pe,favoriteModels:he,onToggleModelFavorite:Ie})}),te&&e.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",title:"Reset to inherit from global",onClick:()=>qa(f),style:{whiteSpace:"nowrap"},children:"Reset"})]}),e.jsxs("small",{children:[z(f)," Falls back to: ",f.fallbackOrder,"."]})]},f.laneId)})}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:"Fallback Models"}),it?e.jsx("div",{className:"settings-empty-state",children:"Loading available models…"}):ie.length===0?e.jsx("div",{className:"settings-empty-state settings-muted",children:"No models available."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"planningFallbackModel",children:"Planning Fallback Model"}),e.jsx(Me,{id:"planningFallbackModel",label:"Planning Fallback Model",models:ie,value:l.planningFallbackProvider&&l.planningFallbackModelId?`${l.planningFallbackProvider}/${l.planningFallbackModelId}`:"",onChange:f=>{if(!f)i(v=>({...v,planningFallbackProvider:void 0,planningFallbackModelId:void 0}));else{const v=f.indexOf("/");i(h=>({...h,planningFallbackProvider:f.slice(0,v),planningFallbackModelId:f.slice(v+1)}))}},placeholder:"Use global fallback",favoriteProviders:ue,onToggleFavorite:Pe,favoriteModels:he,onToggleModelFavorite:Ie}),e.jsx("small",{children:"Used if the planning model fails due to rate limits or provider overload. Defaults to the global fallback model."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"validatorFallbackModel",children:"Reviewer Fallback Model"}),e.jsx(Me,{id:"validatorFallbackModel",label:"Reviewer Fallback Model",models:ie,value:l.validatorFallbackProvider&&l.validatorFallbackModelId?`${l.validatorFallbackProvider}/${l.validatorFallbackModelId}`:"",onChange:f=>{if(!f)i(v=>({...v,validatorFallbackProvider:void 0,validatorFallbackModelId:void 0}));else{const v=f.indexOf("/");i(h=>({...h,validatorFallbackProvider:f.slice(0,v),validatorFallbackModelId:f.slice(v+1)}))}},placeholder:"Use global fallback",favoriteProviders:ue,onToggleFavorite:Pe,favoriteModels:he,onToggleModelFavorite:Ie}),e.jsx("small",{children:"Used if the reviewer model fails due to rate limits or provider overload. Defaults to the global fallback model."})]})]}),e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:"Model Presets"}),e.jsxs("div",{className:"form-group settings-model-presets",children:[e.jsx("label",{children:"Configured presets"}),t.length===0?e.jsx("div",{className:"settings-empty-state settings-muted",children:"No presets configured yet."}):e.jsx("div",{className:"settings-preset-list",children:t.map(f=>{const v=Fn(f),h=`${v.executorValue||"default"} / ${v.validatorValue||"default"}`;return e.jsxs("div",{className:"settings-preset-item",children:[e.jsxs("div",{className:"settings-preset-item-meta",children:[e.jsx("strong",{children:f.name}),e.jsx("span",{className:"settings-muted settings-preset-summary",children:h})]}),e.jsxs("div",{className:"settings-preset-item-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>{Qe(f.id),ye({...f})},children:"Edit"}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:async()=>{r.has(f.id)&&!await R({title:"Delete Preset",message:`Preset "${f.name}" is used in auto-selection. Delete it anyway?`,danger:!0})||(i(te=>({...te,modelPresets:(te.modelPresets||[]).filter(Ce=>Ce.id!==f.id),defaultPresetBySize:Object.fromEntries(Object.entries(te.defaultPresetBySize||{}).filter(([,Ce])=>Ce!==f.id))})),Ye===f.id&&(Qe(null),ye(null)))},children:"Delete"})]})]},f.id)})}),ee?null:e.jsx("div",{className:"settings-preset-actions",children:e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>{Qe(null),ye({id:"",name:"",executorProvider:void 0,executorModelId:void 0,validatorProvider:void 0,validatorModelId:void 0})},children:"Add Preset"})})]}),ee?e.jsxs("div",{className:"form-group settings-preset-editor",children:[e.jsx("label",{children:"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:"Name"}),e.jsx("input",{id:"preset-name",type:"text",value:ee.name,onChange:f=>{const v=f.target.value;ye(h=>h&&{...h,name:v})}})]}),ie.length===0?e.jsx("small",{children:"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:"Executor model"}),e.jsx(Me,{id:"preset-executor-model",label:"Preset executor model",models:ie,value:ee.executorProvider&&ee.executorModelId?`${ee.executorProvider}/${ee.executorModelId}`:"",onChange:f=>{if(!f){ye(h=>h&&{...h,executorProvider:void 0,executorModelId:void 0});return}const v=f.indexOf("/");ye(h=>h&&{...h,executorProvider:f.slice(0,v),executorModelId:f.slice(v+1)})},placeholder:"Use default",favoriteProviders:ue,onToggleFavorite:Pe,favoriteModels:he,onToggleModelFavorite:Ie})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"preset-validator-model",children:"Reviewer model"}),e.jsx(Me,{id:"preset-validator-model",label:"Preset reviewer model",models:ie,value:ee.validatorProvider&&ee.validatorModelId?`${ee.validatorProvider}/${ee.validatorModelId}`:"",onChange:f=>{if(!f){ye(h=>h&&{...h,validatorProvider:void 0,validatorModelId:void 0});return}const v=f.indexOf("/");ye(h=>h&&{...h,validatorProvider:f.slice(0,v),validatorModelId:f.slice(v+1)})},placeholder:"Use default",favoriteProviders:ue,onToggleFavorite:Pe,favoriteModels:he,onToggleModelFavorite:Ie})]})]})]}),e.jsxs("div",{className:"modal-actions settings-preset-editor-actions",children:[e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:nl,children:"Save preset"}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>{Qe(null),ye(null)},children:"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:l.autoSelectModelPreset||!1,onChange:f=>i(v=>({...v,autoSelectModelPreset:f.target.checked}))}),"Auto-select preset based on task size"]})}),l.autoSelectModelPreset?e.jsx("div",{className:"settings-preset-size-grid",children:["S","M","L"].map(f=>e.jsxs("div",{className:"form-group settings-preset-size-row",children:[e.jsx("label",{htmlFor:`preset-size-${f}`,children:f==="S"?"Small tasks (S):":f==="M"?"Medium tasks (M):":"Large tasks (L):"}),e.jsxs("select",{id:`preset-size-${f}`,value:l.defaultPresetBySize?.[f]||"",onChange:v=>{const h=v.target.value||void 0;i(te=>({...te,defaultPresetBySize:{...te.defaultPresetBySize||{},[f]:h}}))},children:[e.jsx("option",{value:"",children:"No preset"}),s.map(v=>e.jsx("option",{value:v.id,children:v.name},v.id))]})]},f))}):null,e.jsx("h4",{className:"settings-section-heading settings-section-heading--spaced",children:"AI Title and Git Commit Message Summarization"}),e.jsx("p",{className:"settings-description",children:"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:l.autoSummarizeTitles||!1,onChange:f=>i(v=>({...v,autoSummarizeTitles:f.target.checked}))}),"Auto-summarize long descriptions as titles"]}),e.jsx("small",{children:"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)."})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"useAiMergeCommitSummary",className:"checkbox-label",children:[e.jsx("input",{id:"useAiMergeCommitSummary",type:"checkbox",checked:l.useAiMergeCommitSummary||!1,onChange:f=>i(v=>({...v,useAiMergeCommitSummary:f.target.checked}))}),"AI merge commit summaries"]}),e.jsx("small",{children:"When enabled, merge commit messages will include an AI-generated summary of the changes instead of just listing step commit subjects. Uses the title summarization model."})]}),(l.autoSummarizeTitles||l.useAiMergeCommitSummary||!1)&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Title and commit message summarization model"}),it?e.jsx("small",{children:"Loading available models..."}):ie.length===0?e.jsx("small",{children:"No models available. Configure authentication first."}):e.jsx(Me,{id:"titleSummarizerModel",label:"Title and commit message summarization model",models:ie,value:l.titleSummarizerProvider&&l.titleSummarizerModelId?`${l.titleSummarizerProvider}/${l.titleSummarizerModelId}`:"",onChange:f=>{if(!f){i(h=>({...h,titleSummarizerProvider:void 0,titleSummarizerModelId:void 0}));return}const v=f.indexOf("/");i(h=>({...h,titleSummarizerProvider:f.slice(0,v),titleSummarizerModelId:f.slice(v+1)}))},placeholder:"Use fallback model",favoriteProviders:ue,onToggleFavorite:Pe,favoriteModels:he,onToggleModelFavorite:Ie}),e.jsx("small",{children:l.titleSummarizerProvider&&l.titleSummarizerModelId?"Using explicitly configured model":k.provider&&k.modelId?k.provider===c.provider&&k.modelId===c.modelId?"(using planning model)":k.provider===b.provider&&k.modelId===b.modelId?l.defaultProviderOverride&&l.defaultModelIdOverride?"(using project default model)":"(using global default model)":"(using global summarization model)":"(using automatic model selection)"})]}),e.jsx("div",{className:"form-group",children:e.jsxs("div",{className:"modal-actions",style:{justifyContent:"flex-start"},children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>i(f=>({...f,titleSummarizerProvider:c.provider,titleSummarizerModelId:c.modelId})),disabled:!c.provider||!c.modelId,children:"Use planning model"}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>i(f=>({...f,titleSummarizerProvider:b.provider,titleSummarizerModelId:b.modelId})),disabled:!b.provider||!b.modelId,children:"Use default model"})]})})]})]})}case"appearance":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Appearance"}),e.jsx(zn,{themeMode:N,colorTheme:T,dashboardFontScalePct:I,onThemeModeChange:t=>{i(s=>({...s,themeMode:t})),D?.(t)},onColorThemeChange:t=>{i(s=>({...s,colorTheme:t})),y?.(t)},onDashboardFontScaleChange:t=>{i(s=>({...s,dashboardFontScalePct:t})),M?.(t)}}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:_,onChange:t=>wn(t.target.checked)}),e.jsx("span",{children:"Hide AI session notification banners"})]}),e.jsx("small",{className:"form-text text-muted",children:"Suppress the “needs your input” banner that appears when AI sessions are awaiting input or have failed."})]})]});case"scheduling":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Scheduling"}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"globalMaxConcurrent",children:"Global Max Concurrent"}),e.jsx("input",{id:"globalMaxConcurrent",type:"number",min:0,max:1e4,value:ut??"",onChange:t=>{const s=t.target.value;Rs.current=!0,Ts(s===""?void 0:Number(s))}}),e.jsx("small",{className:"form-text text-muted",children:"Maximum concurrent agents across all projects"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"maxConcurrent",children:"Max Concurrent Tasks"}),e.jsx("input",{id:"maxConcurrent",type:"number",min:1,max:10,value:l.maxConcurrent??"",onChange:t=>{const s=t.target.value;i(r=>({...r,maxConcurrent:s===""?void 0:Number(s)}))}})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"maxTriageConcurrent",children:"Max Triage Concurrent"}),e.jsx("input",{id:"maxTriageConcurrent",type:"number",min:1,max:10,value:l.maxTriageConcurrent??"",onChange:t=>{const s=t.target.value;i(r=>({...r,maxTriageConcurrent:s===""?void 0:Number(s)}))}}),e.jsx("small",{children:"Maximum concurrent planning agents"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"pollIntervalMs",children:"Poll Interval (ms)"}),e.jsx("input",{id:"pollIntervalMs",type:"number",min:5e3,step:1e3,value:l.pollIntervalMs??"",onChange:t=>{const s=t.target.value;i(r=>({...r,pollIntervalMs:s===""?void 0:Number(s)}))}})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"taskStuckTimeoutMs",children:"Stuck Task Timeout (minutes)"}),e.jsx("input",{id:"taskStuckTimeoutMs",type:"number",min:1,step:1,value:l.taskStuckTimeoutMs?Math.round(l.taskStuckTimeoutMs/6e4):"",onChange:t=>{const s=t.target.value,r=Number(s);i(m=>({...m,taskStuckTimeoutMs:s&&r>0?r*6e4:void 0}))}}),e.jsx("small",{children:"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.jsxs("label",{htmlFor:"specStalenessEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"specStalenessEnabled",type:"checkbox",checked:l.specStalenessEnabled||!1,onChange:t=>i(s=>({...s,specStalenessEnabled:t.target.checked}))}),"Enable plan staleness enforcement"]}),e.jsx("small",{children:"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:"Stale Spec Threshold (hours)"}),e.jsx("input",{id:"specStalenessMaxAgeMs",type:"number",min:0,step:1,value:l.specStalenessMaxAgeMs!==void 0?Math.round(l.specStalenessMaxAgeMs/36e5):"",onChange:t=>{const s=t.target.value,r=Number(s);i(m=>({...m,specStalenessMaxAgeMs:s!==""?r*36e5:void 0}))},disabled:!l.specStalenessEnabled}),e.jsx("small",{children:"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:l.autoArchiveDoneTasksEnabled??!0,onChange:t=>i(s=>({...s,autoArchiveDoneTasksEnabled:t.target.checked}))}),"Enable automatic task archiving"]}),e.jsx("small",{children:"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:"Archive Completed Tasks After (days)"}),e.jsx("input",{id:"autoArchiveDoneAfterMs",type:"number",min:1,step:1,value:l.autoArchiveDoneAfterMs!==void 0?Math.round(l.autoArchiveDoneAfterMs/ia):pr,onChange:t=>{const s=t.target.value,r=Number(s);i(m=>({...m,autoArchiveDoneAfterMs:s===""?void 0:r*ia}))},disabled:l.autoArchiveDoneTasksEnabled===!1}),e.jsx("small",{children:"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:"Archive Agent Log"}),e.jsxs("select",{id:"archiveAgentLogMode",value:l.archiveAgentLogMode??"compact",onChange:t=>i(s=>({...s,archiveAgentLogMode:t.target.value})),disabled:l.autoArchiveDoneTasksEnabled===!1,children:[e.jsx("option",{value:"compact",children:"Compact summary and recent entries"}),e.jsx("option",{value:"none",children:"Do not archive agent logs"}),e.jsx("option",{value:"full",children:"Full agent log"})]}),e.jsx("small",{children:"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:"Max Stuck Retries"}),e.jsx("input",{id:"maxStuckKills",type:"number",min:1,step:1,value:l.maxStuckKills??"",onChange:t=>{const s=t.target.value,r=Number(s);i(m=>({...m,maxStuckKills:s&&r>0?r:void 0}))}}),e.jsx("small",{children:"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:l.groupOverlappingFiles,onChange:t=>i(s=>({...s,groupOverlappingFiles:t.target.checked}))}),"Serialize tasks with overlapping files"]}),e.jsx("small",{children:"When enabled, tasks that modify the same files are queued serially to avoid merge conflicts"})]}),e.jsxs("div",{className:"form-group settings-overlap-ignore-group",children:[e.jsx("label",{children:"Ignored overlap paths"}),e.jsxs("small",{children:["Optional file or directory paths to ignore when overlap serialization is enabled. Paths are project-relative (for example ",e.jsx("code",{children:"docs/"})," or ",e.jsx("code",{children:"generated/*"}),")."]}),e.jsx("div",{className:"settings-overlap-ignore-list",children:(l.overlapIgnorePaths&&l.overlapIgnorePaths.length>0?l.overlapIgnorePaths:[""]).map((t,s)=>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:t,placeholder:"docs/",onChange:r=>Qa(s,r.target.value)}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>Wa(s),"aria-label":`Browse path for ignored overlap entry ${s+1}`,children:"Browse"})]}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>Ja(s),disabled:(l.overlapIgnorePaths??[]).length===0&&s===0,children:"Remove"})]},`overlap-ignore-${s}`))}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:Xa,children:"Add ignored path"})]}),e.jsx("div",{className:"settings-section-divider"}),e.jsx("h5",{className:"settings-section-heading",children:"Step Execution"}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"runStepsInNewSessions",className:"checkbox-label",children:[e.jsx("input",{id:"runStepsInNewSessions",type:"checkbox",checked:l.runStepsInNewSessions||!1,onChange:t=>i(s=>({...s,runStepsInNewSessions:t.target.checked}))}),"Run each step in a new session"]}),e.jsx("small",{children:"Run each task step in its own fresh agent session for better isolation and error recovery. Failed steps can be retried individually."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"maxParallelSteps",children:"Maximum parallel steps"}),e.jsx("input",{id:"maxParallelSteps",type:"number",min:1,max:4,value:l.maxParallelSteps??"",onChange:t=>{const s=t.target.value;i(r=>({...r,maxParallelSteps:s===""?void 0:Number(s)}))},disabled:!l.runStepsInNewSessions}),e.jsx("small",{children:"Maximum number of steps to run in parallel when file scopes don't overlap (1-4)"})]})]});case"node-routing":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Node Routing"}),e.jsx("p",{className:"settings-section-description",children:"Configure how tasks are routed to execution nodes."}),e.jsx("p",{className:"settings-node-routing-note",children:"These settings apply at the project level."}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"defaultNodeId",children:"Default Execution Node"}),e.jsxs("select",{id:"defaultNodeId",className:"select",value:typeof l.defaultNodeId=="string"?l.defaultNodeId:"",onChange:t=>{const s=t.target.value;i(r=>({...r,defaultNodeId:s||void 0}))},children:[e.jsx("option",{value:"",children:"Local execution (no default node)"}),as.map(t=>e.jsxs("option",{value:t.id,children:[t.name," (",mr(t.status),")"]},t.id))]}),(()=>{const t=as.find(s=>s.id===l.defaultNodeId);return t?e.jsxs("div",{className:"settings-node-status",children:[e.jsx("span",{children:"Selected node:"}),e.jsx(Sn,{status:t.status,showLabel:!0})]}):null})(),e.jsx("small",{children:"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:"Unavailable Node Policy"}),e.jsxs("select",{id:"unavailableNodePolicy",className:"select",value:l.unavailableNodePolicy==="fallback-local"?"fallback-local":"block",onChange:t=>i(s=>({...s,unavailableNodePolicy:t.target.value})),children:[e.jsx("option",{value:"block",children:"Block execution"}),e.jsx("option",{value:"fallback-local",children:"Fall back to local"})]})]})]});case"worktrees":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Worktrees"}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"maxWorktrees",children:"Max Worktrees"}),e.jsx("input",{id:"maxWorktrees",type:"number",min:1,max:20,value:l.maxWorktrees??"",onChange:t=>{const s=t.target.value;i(r=>({...r,maxWorktrees:s===""?void 0:Number(s)}))}}),e.jsx("small",{children:"Limits total git worktrees including in-review tasks"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"worktreeInitCommand",children:"Worktree Init Command"}),e.jsx("input",{id:"worktreeInitCommand",type:"text",placeholder:"pnpm install --frozen-lockfile",value:l.worktreeInitCommand||"",onChange:t=>i(s=>({...s,worktreeInitCommand:t.target.value}))}),e.jsx("small",{children:"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:l.recycleWorktrees,onChange:t=>i(s=>({...s,recycleWorktrees:t.target.checked}))}),"Recycle worktrees"]}),e.jsx("small",{children:"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.jsx("label",{htmlFor:"worktreeNaming",children:"Worktree Naming Style"}),e.jsxs("select",{id:"worktreeNaming",value:l.worktreeNaming||"random",onChange:t=>i(s=>({...s,worktreeNaming:t.target.value})),disabled:l.recycleWorktrees,children:[e.jsx("option",{value:"random",children:"Random names (e.g., swift-falcon)"}),e.jsx("option",{value:"task-id",children:"Task ID (e.g., FN-042)"}),e.jsx("option",{value:"task-title",children:"Task title (e.g., fix-login-bug)"})]}),e.jsx("small",{children:l.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.jsxs("label",{htmlFor:"worktreeRebaseBeforeMerge",className:"checkbox-label",children:[e.jsx("input",{id:"worktreeRebaseBeforeMerge",type:"checkbox",checked:l.worktreeRebaseBeforeMerge!==!1,onChange:t=>i(s=>({...s,worktreeRebaseBeforeMerge:t.target.checked}))}),"Rebase from remote before merge"]}),e.jsx("small",{children:"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."})]}),l.worktreeRebaseBeforeMerge!==!1&&e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"worktreeRebaseRemote",children:"Rebase Remote"}),e.jsxs("select",{id:"worktreeRebaseRemote",value:l.worktreeRebaseRemote??"",onChange:t=>i(s=>({...s,worktreeRebaseRemote:t.target.value||void 0})),children:[e.jsx("option",{value:"",children:"Use git default"}),Sa.map(t=>e.jsxs("option",{value:t.name,children:[t.name," (",t.fetchUrl,")"]},t.name))]}),e.jsxs("small",{children:['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"}),")."]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"worktreeRebaseLocalBase",className:"checkbox-label",children:[e.jsx("input",{id:"worktreeRebaseLocalBase",type:"checkbox",checked:l.worktreeRebaseLocalBase!==!1,onChange:t=>i(s=>({...s,worktreeRebaseLocalBase:t.target.checked}))}),"Also rebase onto local default-branch HEAD"]}),e.jsx("small",{children:"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."})]})]});case"commands":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Commands"}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"testCommand",children:"Test Command"}),e.jsx("input",{id:"testCommand",type:"text",placeholder:"e.g. pnpm test",value:l.testCommand||"",onChange:t=>i(s=>({...s,testCommand:t.target.value||void 0}))}),e.jsx("small",{children:"Command used to run tests — injected into generated task specs"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"buildCommand",children:"Build Command"}),e.jsx("input",{id:"buildCommand",type:"text",placeholder:"e.g. pnpm build",value:l.buildCommand||"",onChange:t=>i(s=>({...s,buildCommand:t.target.value||void 0}))}),e.jsx("small",{children:"Command used to build the project — injected into generated task specs"})]})]});case"merge":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"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:l.autoMerge,onChange:t=>i(s=>({...s,autoMerge:t.target.checked}))}),"Auto-merge completed tasks"]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:"More details"}),e.jsx("small",{children:"When enabled, tasks that pass review are automatically merged into the main branch"})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"mergeStrategy",children:"Auto-completion mode"}),e.jsxs("select",{id:"mergeStrategy",value:l.mergeStrategy||"direct",onChange:t=>i(s=>({...s,mergeStrategy:t.target.value})),children:[e.jsx("option",{value:"direct",children:"Direct merge into the current branch"}),e.jsx("option",{value:"pull-request",children:"Create, monitor, and merge a GitHub pull request"})]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:"More details"}),e.jsx("small",{children:"Controls what happens after a task reaches In Review. Direct mode preserves Fusion's current local squash-merge behavior. Pull request mode keeps the task in In Review while Fusion waits for GitHub reviews and required checks before merging the PR."})]})]}),l.mergeStrategy==="pull-request"&&e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"requirePrApproval",className:"checkbox-label",children:[e.jsx("input",{id:"requirePrApproval",type:"checkbox",checked:l.requirePrApproval??!1,onChange:t=>i(s=>({...s,requirePrApproval:t.target.checked}))}),"Wait for an approving review before merging the PR"]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:"More details"}),e.jsx("small",{children:"When enabled, Fusion holds the PR in In Review until at least one approving GitHub review has been submitted. Useful on free private repos where GitHub's required-reviewer enforcement isn't available — without this, a fresh PR with no required checks is treated as immediately mergeable."})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"includeTaskIdInCommit",className:"checkbox-label",children:[e.jsx("input",{id:"includeTaskIdInCommit",type:"checkbox",checked:l.includeTaskIdInCommit!==!1,onChange:t=>i(s=>({...s,includeTaskIdInCommit:t.target.checked}))}),"Include task ID in commit scope"]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:"More details"}),e.jsxs("small",{children:["When disabled, merge commit messages omit the task ID from the scope (e.g. ",e.jsx("code",{children:"feat: ..."})," 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:l.commitAuthorEnabled!==!1,onChange:t=>i(s=>({...s,commitAuthorEnabled:t.target.checked}))}),"Add author attribution to commits"]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:"More details"}),e.jsxs("small",{children:["When enabled, all commits made by Fusion include ",e.jsx("code",{children:"--author"})," ","attribution identifying them as AI-generated"]})]})]}),l.commitAuthorEnabled!==!1&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"commitAuthorName",children:"Author Name"}),e.jsx("input",{id:"commitAuthorName",type:"text",value:l.commitAuthorName??"",placeholder:"Fusion",onChange:t=>i(s=>({...s,commitAuthorName:t.target.value||void 0}))}),e.jsx("small",{children:"Name used in commit author attribution"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"commitAuthorEmail",children:"Author Email"}),e.jsx("input",{id:"commitAuthorEmail",type:"email",value:l.commitAuthorEmail??"",placeholder:"noreply@runfusion.ai",onChange:t=>i(s=>({...s,commitAuthorEmail:t.target.value||void 0}))}),e.jsx("small",{children:"Email used in commit author attribution"})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"autoResolveConflicts",className:"checkbox-label",children:[e.jsx("input",{id:"autoResolveConflicts",type:"checkbox",checked:l.autoResolveConflicts!==!1,onChange:t=>i(s=>({...s,autoResolveConflicts:t.target.checked}))}),"Auto-resolve conflicts in lock files and generated files"]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:"More details"}),e.jsx("small",{children:"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."})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"smartConflictResolution",className:"checkbox-label",children:[e.jsx("input",{id:"smartConflictResolution",type:"checkbox",checked:l.smartConflictResolution!==!1,onChange:t=>i(s=>({...s,smartConflictResolution:t.target.checked}))}),"Smart conflict resolution"]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:"More details"}),e.jsx("small",{children:"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:"Conflict Fallback Strategy"}),e.jsxs("select",{id:"mergeConflictStrategy",value:l.mergeConflictStrategy??"smart-prefer-main",onChange:t=>i(s=>({...s,mergeConflictStrategy:t.target.value})),children:[e.jsx("option",{value:"smart-prefer-main",children:"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:'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:"AI only — AI → auto-resolve → AI retry; never silently pick a side"}),e.jsx("option",{value:"abort",children:"Abort — one AI attempt; require manual resolution if it fails"})]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:"More details"}),e.jsxs("small",{children:["Both ",e.jsx("strong",{children:"Smart"})," options start with a best-effort ",e.jsx("code",{children:"git fetch"})," + fast-forward of local main from ",e.jsx("code",{children:"origin"})," (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:"final fallback"}),":"," ",e.jsx("strong",{children:"Smart, prefer main"})," uses ",e.jsx("code",{children:"-X ours"})," so main wins — protects just-merged sibling work and is the new default."," ",e.jsx("strong",{children:"Smart, prefer task"})," uses ",e.jsx("code",{children:"-X theirs"})," 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:"AI only"})," retries the AI agent rather than auto-picking a side."," ",e.jsx("strong",{children:"Abort"})," stops after the first AI attempt and waits for a human."," ",e.jsxs("em",{children:["Legacy ",e.jsx("code",{children:'"smart"'})," and ",e.jsx("code",{children:'"prefer-main"'})," values from older settings are migrated automatically."]})]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:"pushAfterMerge",className:"checkbox-label",children:[e.jsx("input",{id:"pushAfterMerge",type:"checkbox",checked:l.pushAfterMerge===!0,onChange:t=>i(s=>({...s,pushAfterMerge:t.target.checked}))}),"Push to remote after merge"]}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:"More details"}),e.jsx("small",{children:"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."})]})]}),l.pushAfterMerge&&e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"pushRemote",children:"Push Remote"}),e.jsx("input",{id:"pushRemote",type:"text",placeholder:"origin",value:l.pushRemote||"",onChange:t=>i(s=>({...s,pushRemote:t.target.value||void 0}))}),e.jsxs("details",{className:"settings-option-details",children:[e.jsx("summary",{children:"More details"}),e.jsx("small",{children:'Git remote to push to (e.g. "origin"). Can include branch name (e.g. "origin main"). Default: "origin".'})]})]})]});case"memory":{const{capabilities:t,status:s,loading:r,error:m}={capabilities:Ta,status:Fa,loading:Aa,error:Ea},c=l.memoryEnabled!==!1,b=!r&&s!==null,k=b?t?.writable??!0:!0,O=c&&k,z=js.find(v=>v.path===ge),f={"long-term":"Long-term",daily:"Daily",dreams:"Dreams"};return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Memory"}),e.jsx("div",{className:"form-group",children:e.jsxs("small",{className:"settings-muted",children:["Memory lives in ",e.jsx("code",{children:".fusion/memory/"}),". 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:l.memoryEnabled!==!1,onChange:v=>i(h=>({...h,memoryEnabled:v.target.checked}))}),"Enable memory tools"]}),e.jsx("small",{children:"Agents get memory_search, memory_get, and memory_append tools. Search defaults to qmd with a local file fallback."})]}),r?e.jsx("div",{className:"form-group",children:e.jsx("small",{className:"settings-muted",children:"Checking memory write access..."})}):m?e.jsx("div",{className:"form-group",children:e.jsxs("small",{className:"field-error",children:["Failed to load backend status: ",m]})}):null,b&&s.qmdAvailable===!1&&e.jsxs("div",{className:"settings-empty-state memory-status-message",children:[e.jsxs("span",{children:["qmd is not installed. Search will use local files. Install indexed retrieval: ",e.jsx("code",{children:s.qmdInstallCommand||"bun install -g @tobilu/qmd"})]}),e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:ll,disabled:Ms,children:Ms?"Installing…":"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:l.memoryAutoSummarizeEnabled||!1,onChange:v=>i(h=>({...h,memoryAutoSummarizeEnabled:v.target.checked}))}),"Auto-Summarize Memory"]}),e.jsx("small",{children:"Automatically compact memory when it exceeds the threshold on a schedule"})]}),(l.memoryAutoSummarizeEnabled||!1)&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeThresholdChars",children:"Compaction Threshold (chars)"}),e.jsx("input",{id:"memoryAutoSummarizeThresholdChars",type:"number",className:"input",value:l.memoryAutoSummarizeThresholdChars??5e4,onChange:v=>i(h=>({...h,memoryAutoSummarizeThresholdChars:parseInt(v.target.value,10)||5e4})),min:1e3}),e.jsx("small",{children:"Memory will be compacted when it exceeds this character count"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryAutoSummarizeSchedule",children:"Schedule (cron)"}),e.jsx("input",{id:"memoryAutoSummarizeSchedule",type:"text",className:"input",value:l.memoryAutoSummarizeSchedule??"0 3 * * *",onChange:v=>i(h=>({...h,memoryAutoSummarizeSchedule:v.target.value})),placeholder:"0 3 * * *"}),e.jsx("small",{children:"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:l.memoryDreamsEnabled===!0,onChange:v=>i(h=>({...h,memoryDreamsEnabled:v.target.checked})),disabled:!c}),"Process dreams from daily memory"]}),e.jsx("small",{children:"Turns daily notes into DREAMS.md and promotes reusable lessons into MEMORY.md."})]}),c&&l.memoryDreamsEnabled===!0&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryDreamsSchedule",children:"Dream Schedule"}),e.jsx("input",{id:"memoryDreamsSchedule",type:"text",value:l.memoryDreamsSchedule??"0 4 * * *",onChange:v=>i(h=>({...h,memoryDreamsSchedule:v.target.value}))}),e.jsx("small",{children:"Cron expression for dream processing."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:al,disabled:Ss||l.memoryDreamsEnabled!==!0,children:Ss?e.jsxs(e.Fragment,{children:[e.jsx(tt,{size:14,className:"animate-spin"}),"Dreaming…"]}):"Dream Now"}),e.jsx("small",{children:"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:"Test Retrieval"}),e.jsx("input",{id:"memoryRetrievalQuery",type:"text",value:Et,onChange:v=>wa(v.target.value),placeholder:"Search memory with qmd"}),e.jsx("small",{children:"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:sl,disabled:ks,children:ks?"Testing…":"Test Retrieval"})}),Re&&e.jsxs("div",{className:"memory-test-result",children:[e.jsxs("strong",{children:[Re.results.length," result",Re.results.length===1?"":"s"," ",'for "',Re.query,'"']}),e.jsxs("small",{children:["qmd ",Re.qmdAvailable?"available":"missing"," · ",Re.usedFallback?"local fallback used":"qmd path used"]}),Re.results.length>0?e.jsx("ul",{children:Re.results.map((v,h)=>e.jsxs("li",{children:[e.jsxs("span",{children:[v.path,":",v.lineStart]}),e.jsx("p",{children:v.snippet})]},`${v.path}-${v.lineStart}-${h}`))}):e.jsx("small",{children:"No matching memory found."})]})]}),!c&&e.jsx("div",{className:"settings-empty-state memory-status-message",children:"Memory is currently disabled. You can view the file, but editing is read-only until memory is re-enabled."}),c&&b&&!k&&e.jsx("div",{className:"settings-empty-state memory-status-message",children:"Memory is configured with a read-only backend. You can view the file, but saving is disabled."}),fs?e.jsx("div",{className:"settings-empty-state",children:"Loading memory…"}):e.jsxs("div",{className:"memory-editor-section",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"memoryFilePath",children:"Memory File"}),e.jsx("select",{id:"memoryFilePath",value:ge,onChange:v=>{At(v.target.value),Xe(!1)},disabled:Ee,children:js.map(v=>e.jsxs("option",{value:v.path,children:[v.label," - ",v.path]},v.path))}),e.jsx("small",{children:Ee?"Save or discard the current edits before switching files.":"Choose any project memory file to view or edit. Dreams is selected by default."})]}),z&&e.jsxs("div",{className:"memory-file-summary",children:[e.jsx("span",{children:f[z.layer]}),e.jsx("strong",{children:z.path}),e.jsxs("small",{children:[z.size.toLocaleString()," bytes · updated ",new Date(z.updatedAt).toLocaleString()]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:z?.label||"Memory Editor"}),e.jsxs("small",{children:[z?.layer==="long-term"&&"Curated durable decisions, conventions, constraints, and pitfalls promoted from dreams.",z?.layer==="daily"&&"Raw daily observations, open loops, and running context for dream processing.",z?.layer==="dreams"&&"Synthesized patterns and open loops promoted from daily memory.",!z&&"Edits the selected memory file."]}),e.jsx("div",{className:"memory-editor-frame",children:e.jsx(Cn,{content:Tt,onChange:v=>{mt(v),Xe(!0)},readOnly:!O,filePath:ge})})]})]}),!fs&&e.jsxs("div",{className:"form-group",children:[e.jsx("button",{type:"button",className:"btn btn-secondary btn-sm",onClick:tl,disabled:!O||Ee||Ps,children:Ps?"Compacting…":"Compact Selected File"}),e.jsx("small",{children:Ee?"Save or discard edits before compacting this file.":`Compacts ${ge} and writes the result back to the same file.`})]}),Ee&&O&&e.jsx("div",{className:"form-group",children:e.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:el,children:"Save Memory"})}),Ee&&!O&&e.jsx("div",{className:"form-group",children:e.jsxs("small",{className:"field-error",children:["Cannot save: ",c?"Backend is read-only":"Memory is disabled"]})})]})}case"research-global":{const s=Ue.filter(r=>r.id==="brave"||r.id==="tavily").some(r=>!r.authenticated);return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Research Defaults"}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-global-search-provider",children:"Default Search Provider"}),e.jsx("input",{id:"research-global-search-provider",className:"input",value:l.researchGlobalDefaults?.searchProvider??"",onChange:r=>i(m=>({...m,researchGlobalDefaults:{...m.researchGlobalDefaults??{},searchProvider:r.target.value||void 0}})),placeholder:"tavily"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-global-max-sources",children:"Default Max Sources Per Run"}),e.jsx("input",{id:"research-global-max-sources",className:"input",type:"number",min:1,value:l.researchGlobalDefaults?.maxSourcesPerRun??20,onChange:r=>i(m=>({...m,researchGlobalDefaults:{...m.researchGlobalDefaults??{},maxSourcesPerRun:Number(r.target.value)||1}}))})]}),s&&e.jsxs("div",{className:"settings-empty-state",role:"alert",children:["Missing credentials for one or more research providers.",e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>q("authentication"),children:"Open Authentication"})]})]})}case"research-project":{const t=l.researchSettings?.limits,s=l.researchSettings?.enabledSources;return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"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:l.researchSettings?.enabled??!0,onChange:r=>i(m=>({...m,researchSettings:{...m.researchSettings??{},enabled:r.target.checked}}))}),"Enable research in this project"]})}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Enabled Sources"}),e.jsx("div",{className:"settings-research-source-grid",children:[["webSearch","Web Search"],["pageFetch","Page Fetch"],["github","GitHub"],["localDocs","Local Docs"],["llmSynthesis","LLM Synthesis"]].map(([r,m])=>e.jsxs("label",{htmlFor:`research-project-source-${r}`,className:"checkbox-label",children:[e.jsx("input",{id:`research-project-source-${r}`,type:"checkbox",checked:s?.[r]??!1,onChange:c=>i(b=>({...b,researchSettings:{...b.researchSettings??{},enabledSources:{...b.researchSettings?.enabledSources??{},[r]:c.target.checked}}}))}),m]},r))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-project-max-concurrent",children:"Max Concurrent Runs"}),e.jsx("input",{id:"research-project-max-concurrent",className:"input",type:"number",min:1,value:t?.maxConcurrentRuns??3,onChange:r=>i(m=>({...m,researchSettings:{...m.researchSettings??{},limits:{...m.researchSettings?.limits??{},maxConcurrentRuns:r.target.value===""?void 0:Number(r.target.value)}}}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-project-max-sources",children:"Max Sources Per Run"}),e.jsx("input",{id:"research-project-max-sources",className:"input",type:"number",min:1,value:t?.maxSourcesPerRun??20,onChange:r=>i(m=>({...m,researchSettings:{...m.researchSettings??{},limits:{...m.researchSettings?.limits??{},maxSourcesPerRun:r.target.value===""?void 0:Number(r.target.value)}}}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-project-max-duration",children:"Max Duration (ms)"}),e.jsx("input",{id:"research-project-max-duration",className:"input",type:"number",min:1e3,value:t?.maxDurationMs??3e5,onChange:r=>i(m=>({...m,researchSettings:{...m.researchSettings??{},limits:{...m.researchSettings?.limits??{},maxDurationMs:r.target.value===""?void 0:Number(r.target.value)}}}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-project-request-timeout",children:"Request Timeout (ms)"}),e.jsx("input",{id:"research-project-request-timeout",className:"input",type:"number",min:1e3,value:t?.requestTimeoutMs??3e4,onChange:r=>i(m=>({...m,researchSettings:{...m.researchSettings??{},limits:{...m.researchSettings?.limits??{},requestTimeoutMs:r.target.value===""?void 0:Number(r.target.value)}}}))}),j&&e.jsx("small",{className:"field-error",children:j})]})]})}case"experimental":{const t=l.experimentalFeatures??{},r=Array.from(new Set([...Object.keys(ca),...Object.keys(t).map(xa)])).sort((m,c)=>m.localeCompare(c)).map(m=>[m,Zt(t,m)]);return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Experimental Features"}),e.jsx("div",{className:"form-group",children:e.jsx("small",{children:"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:"Feature Flags"}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"var(--space-sm)"},children:r.map(([m,c])=>e.jsxs("label",{htmlFor:`experimental-${m}`,className:"checkbox-label",children:[e.jsx("input",{id:`experimental-${m}`,type:"checkbox",checked:c,onChange:b=>{i(k=>{const O={...k.experimentalFeatures??{},[m]:b.target.checked};for(const[z,f]of Object.entries(vt))f===m&&delete O[z];return{...k,experimentalFeatures:O}})}}),e.jsx("span",{children:ca[m]??m})]},m))})]})]})}case"backups":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"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:l.autoBackupEnabled||!1,onChange:t=>i(s=>({...s,autoBackupEnabled:t.target.checked}))}),"Enable automatic database backups"]}),e.jsx("small",{children:"When enabled, the database is backed up automatically on a schedule"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"autoBackupSchedule",children:"Backup Schedule (Cron)"}),e.jsx("input",{id:"autoBackupSchedule",type:"text",placeholder:"0 2 * * *",value:l.autoBackupSchedule||"0 2 * * *",onChange:t=>i(s=>({...s,autoBackupSchedule:t.target.value})),disabled:!l.autoBackupEnabled}),e.jsx("small",{children:"Cron expression for backup timing. Default: 0 2 * * * (daily at 2 AM). Examples: 0 * * * * (hourly), 0 0 * * 0 (weekly), */15 * * * * (every 15 min)"}),l.autoBackupSchedule&&!/^[\s\d*,/-]+$/.test(l.autoBackupSchedule)&&e.jsx("small",{className:"field-error",children:"Invalid cron expression format"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"autoBackupRetention",children:"Retention Count"}),e.jsx("input",{id:"autoBackupRetention",type:"number",min:1,max:100,value:l.autoBackupRetention??"",onChange:t=>{const s=t.target.value;i(r=>({...r,autoBackupRetention:s===""?void 0:Number(s)}))},disabled:!l.autoBackupEnabled}),e.jsx("small",{children:"Number of backup files to keep (oldest are deleted first). Range: 1-100."}),l.autoBackupRetention!==void 0&&(l.autoBackupRetention<1||l.autoBackupRetention>100)&&e.jsx("small",{className:"field-error",children:"Must be between 1 and 100"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"autoBackupDir",children:"Backup Directory"}),e.jsx("input",{id:"autoBackupDir",type:"text",placeholder:".fusion/backups",value:l.autoBackupDir||".fusion/backups",onChange:t=>i(s=>({...s,autoBackupDir:t.target.value})),disabled:!l.autoBackupEnabled}),e.jsx("small",{children:"Directory for backup files, relative to project root"}),l.autoBackupDir&&l.autoBackupDir.includes("..")&&e.jsx("small",{className:"field-error",children:"Path cannot contain parent directory traversal (..)"})]}),wt?e.jsx("div",{className:"settings-empty-state",children:"Loading backup info…"}):ke?e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Current Backups"}),e.jsxs("div",{className:"backup-stats",children:[e.jsxs("div",{className:"backup-stat",children:[e.jsx("span",{className:"backup-stat-value",children:ke.count}),e.jsx("span",{className:"backup-stat-label",children:"backups"})]}),e.jsxs("div",{className:"backup-stat",children:[e.jsx("span",{className:"backup-stat-value",children:ke.totalSize>1024*1024?`${(ke.totalSize/(1024*1024)).toFixed(1)} MB`:`${(ke.totalSize/1024).toFixed(1)} KB`}),e.jsx("span",{className:"backup-stat-label",children:"total size"})]})]}),ke.backups.length>0&&e.jsxs("details",{className:"backup-list",children:[e.jsxs("summary",{children:["View ",ke.backups.length," backup(s)"]}),e.jsxs("ul",{children:[ke.backups.slice(0,10).map(t=>e.jsxs("li",{children:[e.jsx("code",{children:t.filename}),e.jsx("span",{className:"backup-size",children:t.size>1024*1024?`${(t.size/(1024*1024)).toFixed(1)} MB`:`${(t.size/1024).toFixed(1)} KB`})]},t.filename)),ke.backups.length>10&&e.jsx("li",{children:e.jsxs("em",{children:["...and ",ke.backups.length-10," more"]})})]})]})]}):null,e.jsx("div",{className:"form-group",children:e.jsx("button",{type:"button",className:"btn btn-sm",onClick:Ba,disabled:wt,children:wt?"Creating…":"Backup Now"})})]});case"notifications":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Notifications"}),e.jsxs("div",{className:"notification-provider-card",children:[e.jsxs("div",{className:"notification-provider-header",children:[e.jsx("strong",{children:"ntfy"}),e.jsxs("label",{htmlFor:"ntfyEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"ntfyEnabled",type:"checkbox",checked:l.ntfyEnabled||!1,onChange:t=>i(s=>({...s,ntfyEnabled:t.target.checked}))}),"Enable"]})]}),l.ntfyEnabled&&e.jsxs("div",{className:"notification-provider-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"ntfyTopic",children:"ntfy Topic"}),e.jsx("input",{id:"ntfyTopic",type:"text",placeholder:"my-topic-name",value:l.ntfyTopic||"",onChange:t=>{const s=t.target.value;i(r=>({...r,ntfyTopic:s||void 0}))}}),e.jsxs("small",{children:["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:"Learn more about ntfy.sh"})]}),l.ntfyTopic&&!/^[a-zA-Z0-9_-]{1,64}$/.test(l.ntfyTopic)&&e.jsx("small",{className:"field-error",children:"Topic must be 1–64 alphanumeric, hyphen, or underscore characters"}),e.jsxs("details",{className:"ntfy-advanced-disclosure",children:[e.jsx("summary",{children:"Advanced"}),e.jsxs("div",{className:"ntfy-advanced-content",children:[e.jsx("label",{htmlFor:"ntfyBaseUrl",children:"Custom ntfy server URL (optional)"}),e.jsx("input",{id:"ntfyBaseUrl",type:"url",placeholder:"https://ntfy.sh",value:l.ntfyBaseUrl||"",onChange:t=>{const s=t.target.value;i(r=>({...r,ntfyBaseUrl:s||void 0}))}}),e.jsx("small",{children:"Leave blank to keep the default server: https://ntfy.sh. Custom servers must use http:// or https://."})]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Notify on events"}),e.jsx("div",{className:"ntfy-events-list",children:oa.map(({event:t,label:s,description:r})=>{const m=l.ntfyEvents?.includes(t)??!0;return e.jsxs("div",{children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:m,onChange:c=>{const b=l.ntfyEvents??[...Xt],k=c.target.checked?b.includes(t)?b:[...b,t]:b.filter(O=>O!==t);i(O=>({...O,ntfyEvents:k.length>0?k:void 0}))}}),s]}),e.jsx("small",{children:r})]},`ntfy-${t}`)})})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"ntfyDashboardHost",children:"Dashboard Hostname"}),e.jsx("input",{id:"ntfyDashboardHost",type:"text",placeholder:"http://localhost:3000",value:l.ntfyDashboardHost||"",onChange:t=>{const s=t.target.value;i(r=>({...r,ntfyDashboardHost:s||void 0}))}}),e.jsx("small",{children:"Base URL for deep links in notifications. When set, clicking a notification opens the dashboard directly to the task."}),l.ntfyDashboardHost&&!/^https?:\/\/.+/.test(l.ntfyDashboardHost)&&e.jsx("small",{className:"field-error",children:"Must be a valid URL starting with http:// or https://"})]}),e.jsx("div",{className:"notification-provider-actions",children:e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>_s("ntfy"),disabled:ot.ntfy||!l.ntfyTopic||!/^[a-zA-Z0-9_-]{1,64}$/.test(l.ntfyTopic),children:ot.ntfy?"Sending…":"Test notification"})})]})]}),e.jsxs("div",{className:"notification-provider-card",children:[e.jsxs("div",{className:"notification-provider-header",children:[e.jsx("strong",{children:"Webhook"}),e.jsxs("label",{htmlFor:"webhookEnabled",className:"checkbox-label",children:[e.jsx("input",{id:"webhookEnabled",type:"checkbox",checked:l.webhookEnabled||!1,onChange:t=>i(s=>({...s,webhookEnabled:t.target.checked}))}),"Webhook notifications"]})]}),l.webhookEnabled&&e.jsxs("div",{className:"notification-provider-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"webhookUrl",children:"Webhook URL"}),e.jsx("input",{id:"webhookUrl",type:"text",placeholder:"https://hooks.example.com/...",value:l.webhookUrl||"",onChange:t=>{const s=t.target.value;i(r=>({...r,webhookUrl:s||void 0}))}})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"webhookFormat",children:"Format"}),e.jsxs("select",{id:"webhookFormat",value:l.webhookFormat||"generic",onChange:t=>{const s=t.target.value;i(r=>({...r,webhookFormat:s}))},children:[e.jsx("option",{value:"slack",children:"Slack"}),e.jsx("option",{value:"discord",children:"Discord"}),e.jsx("option",{value:"generic",children:"Generic"})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Notify on events"}),e.jsx("div",{className:"ntfy-events-list",children:oa.map(({event:t,label:s,description:r})=>{const c=(l.webhookEvents??[...Xt]).includes(t);return e.jsxs("div",{children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:c,onChange:b=>{const k=l.webhookEvents??[...Xt],O=b.target.checked?k.includes(t)?k:[...k,t]:k.filter(z=>z!==t);i(z=>({...z,webhookEvents:O.length>0?O:void 0}))}}),s]}),e.jsx("small",{children:r})]},`webhook-${t}`)})})]}),e.jsx("div",{className:"notification-provider-actions",children:e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>_s("webhook"),disabled:ot.webhook||!l.webhookUrl,children:ot.webhook?"Sending…":"Test notification"})})]})]})]});case"node-sync":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"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:l.settingsSyncEnabled||!1,onChange:t=>i(s=>({...s,settingsSyncEnabled:t.target.checked}))}),"Enable automatic settings sync"]}),e.jsx("small",{children:"Automatically synchronize settings between this node and connected remote nodes"})]}),l.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:l.settingsSyncAuth||!1,onChange:t=>i(s=>({...s,settingsSyncAuth:t.target.checked}))}),"Sync model auth credentials"]}),e.jsx("small",{children:"Include API keys and OAuth tokens in sync operations"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"settingsSyncInterval",children:"Sync interval"}),e.jsxs("select",{id:"settingsSyncInterval",className:"select",value:l.settingsSyncInterval||9e5,onChange:t=>i(s=>({...s,settingsSyncInterval:parseInt(t.target.value,10)})),children:[e.jsx("option",{value:3e5,children:"Every 5 minutes"}),e.jsx("option",{value:9e5,children:"Every 15 minutes"}),e.jsx("option",{value:18e5,children:"Every 30 minutes"}),e.jsx("option",{value:36e5,children:"Every 1 hour"})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"settingsSyncConflictResolution",children:"Conflict resolution"}),e.jsxs("select",{id:"settingsSyncConflictResolution",className:"select",value:l.settingsSyncConflictResolution||"last-write-wins",onChange:t=>i(s=>({...s,settingsSyncConflictResolution:t.target.value})),children:[e.jsx("option",{value:"last-write-wins",children:"Last write wins"}),e.jsx("option",{value:"always-ask",children:"Always ask"}),e.jsx("option",{value:"keep-local",children:"Keep local"}),e.jsx("option",{value:"keep-remote",children:"Keep remote"})]})]})]})]});case"remote":{const t=l,s=t.remoteActiveProvider??null,r=Y?.state??"stopped",m=r==="running"?"running":r==="starting"?"starting":r==="failed"||r==="error"?"error":"stopped";return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Remote Access"}),e.jsxs("div",{className:`remote-status-bar remote-status-bar--${m}`,children:[e.jsx("span",{className:`remote-status-dot remote-status-dot--${m}`}),e.jsx("strong",{children:r}),Y?.provider&&e.jsxs("span",{children:[" · ",Y.provider]}),Y?.url&&e.jsx("code",{className:"remote-status-url",children:Y.url}),Y?.lastError&&e.jsx("span",{className:"field-error",children:Y.lastError})]}),r==="stopped"&&$e&&e.jsxs("div",{className:"remote-external-tunnel-panel",role:"status",children:[e.jsxs("div",{className:"remote-external-tunnel-header",children:[e.jsx(xt,{"aria-hidden":"true"}),e.jsxs("strong",{children:["External ",$e.provider," tunnel detected"]})]}),$e.url&&e.jsx("code",{className:"settings-url-output",children:$e.url}),Oe?.qrSvg&&e.jsxs("div",{className:"remote-external-tunnel-qr",children:[e.jsx("small",{children:"Scan to open:"}),e.jsx("img",{src:`data:image/svg+xml;utf8,${encodeURIComponent(Oe.qrSvg)}`,alt:"External tunnel QR code",className:"settings-qr-preview-image"})]})]}),r==="running"&&(Y?.url||Oe)&&(()=>{let c=null,b=Y?.url??null;if(Oe?.url)try{const k=new URL(Oe.url);c=k.searchParams.get("rt"),b||(b=`${k.origin}/`)}catch{}return e.jsxs("div",{className:"remote-share-block",children:[b&&e.jsxs("div",{className:"remote-share-row",children:[e.jsx("small",{children:"Tailnet URL:"}),e.jsx("code",{className:"settings-url-output",children:b})]}),c&&e.jsxs("div",{className:"remote-share-row",children:[e.jsx("small",{children:"Remote access code:"}),e.jsx("code",{className:"settings-url-output",children:c})]}),Oe?.qrSvg&&e.jsxs("div",{className:"remote-share-row",children:[e.jsx("small",{children:"Scan to connect:"}),e.jsx("img",{src:`data:image/svg+xml;utf8,${encodeURIComponent(Oe.qrSvg)}`,alt:"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":"Remote provider",children:[e.jsxs("label",{className:"remote-provider-option",children:[e.jsx("input",{type:"radio",name:"remoteProvider",value:"tailscale",checked:s==="tailscale",onChange:()=>i(c=>({...c,remoteActiveProvider:"tailscale"}))}),e.jsx("span",{children:"Tailscale"})]}),e.jsxs("label",{className:"remote-provider-option",children:[e.jsx("input",{type:"radio",name:"remoteProvider",value:"cloudflare",checked:s==="cloudflare",onChange:()=>i(c=>({...c,remoteActiveProvider:"cloudflare"}))}),e.jsx("span",{children:"Cloudflare"})]})]}),!s&&e.jsx("small",{children:"Select a provider above to configure remote access."})]}),s==="cloudflare"&&Y?.cloudflaredAvailable===!0&&e.jsxs("div",{className:"remote-cli-detection remote-cli-detection--available",role:"status",children:[e.jsx(xn,{"aria-hidden":"true"}),e.jsx("span",{children:"cloudflared is installed"})]}),s==="cloudflare"&&Y?.cloudflaredAvailable===!1&&e.jsxs("div",{className:"remote-cli-detection remote-cli-detection--missing",role:"status",children:[e.jsx(vn,{"aria-hidden":"true"}),e.jsxs("div",{className:"remote-cli-detection-content",children:[e.jsx("span",{children:"cloudflared is not installed"}),e.jsx("button",{type:"button",className:"btn btn-sm",disabled:us||pe!==null,onClick:()=>void il(),children:us?"Installing…":"Install cloudflared"}),ps&&e.jsx("small",{className:"remote-cli-install-error",children:ps}),e.jsxs("small",{className:"remote-cli-manual",children:["Manual install: ",e.jsx("code",{children:rl()})]}),zs()?e.jsxs("small",{className:"remote-cli-manual",children:["If Homebrew is unavailable: ",e.jsx("code",{children:zs()})]}):null]})]}),s&&e.jsx("div",{className:"form-group remote-provider-settings",children:s==="tailscale"?e.jsxs(e.Fragment,{children:[e.jsxs("small",{children:["Tailscale Funnel will expose this dashboard on your tailnet's public ","https://<machine>.<tailnet>.ts.net/"," URL — no hostname or port configuration needed."]}),e.jsxs("label",{htmlFor:"remoteTailscaleAcceptRoutes",className:"checkbox-label",children:[e.jsx("input",{id:"remoteTailscaleAcceptRoutes",type:"checkbox",checked:!!t.remoteTailscaleAcceptRoutes,onChange:c=>i(b=>({...b,remoteTailscaleAcceptRoutes:c.target.checked}))}),"Accept routes"]})]}):e.jsxs(e.Fragment,{children:[e.jsx("small",{children:t.remoteCloudflareQuickTunnel??!0?"Using Quick Tunnel — automatically creates a random trycloudflare.com URL, no account needed.":"Named Tunnel mode enabled — configure tunnel name, token, and ingress URL below."}),e.jsxs("details",{className:"remote-cf-advanced-details",open:!(t.remoteCloudflareQuickTunnel??!0),onToggle:c=>{const b=c.currentTarget.open;i(k=>{const O=!!(k.remoteCloudflareQuickTunnel??!0),z=!b;return O===z?k:{...k,remoteCloudflareQuickTunnel:z}})},children:[e.jsx("summary",{children:"Advanced (Named Tunnel)"}),t.remoteCloudflareQuickTunnel??!0?null:e.jsxs("div",{className:"remote-cf-advanced-fields",children:[e.jsx("label",{htmlFor:"remoteCloudflareTunnelName",children:"Tunnel name"}),e.jsx("input",{id:"remoteCloudflareTunnelName",type:"text",placeholder:"Tunnel name",value:String(t.remoteCloudflareTunnelName??""),onChange:c=>i(b=>({...b,remoteCloudflareTunnelName:c.target.value}))}),e.jsx("label",{htmlFor:"remoteCloudflareTunnelToken",children:"Tunnel token"}),e.jsx("input",{id:"remoteCloudflareTunnelToken",type:"password",placeholder:"Tunnel token",value:String(t.remoteCloudflareTunnelToken??""),onChange:c=>i(b=>({...b,remoteCloudflareTunnelToken:c.target.value}))}),e.jsx("label",{htmlFor:"remoteCloudflareIngressUrl",children:"Ingress URL"}),e.jsx("input",{id:"remoteCloudflareIngressUrl",type:"text",placeholder:"https://your-domain.example",value:String(t.remoteCloudflareIngressUrl??""),onChange:c=>i(b=>({...b,remoteCloudflareIngressUrl:c.target.value}))})]})]})]})}),e.jsx("div",{className:"form-group remote-tunnel-actions",children:r==="running"||r==="starting"?e.jsx("button",{type:"button",className:"btn btn-danger",disabled:pe!==null,onClick:()=>void De("stop",async()=>{await jn(d),o("Remote tunnel stopped","success")}),children:pe==="stop"?"Stopping…":"Stop Tunnel"}):e.jsxs(e.Fragment,{children:[$e?e.jsxs("div",{className:"remote-external-tunnel-actions",children:[e.jsx("button",{type:"button",className:"btn",disabled:!s||pe!==null,onClick:()=>void De("start fresh",async()=>{const c=l,b={remoteActiveProvider:s,remoteTailscaleEnabled:s==="tailscale",remoteTailscaleHostname:String(c.remoteTailscaleHostname??""),remoteTailscaleTargetPort:Number(c.remoteTailscaleTargetPort??4040),remoteTailscaleAcceptRoutes:!!c.remoteTailscaleAcceptRoutes,remoteCloudflareEnabled:s==="cloudflare",remoteCloudflareQuickTunnel:!!(c.remoteCloudflareQuickTunnel??!0),remoteCloudflareTunnelName:String(c.remoteCloudflareTunnelName??""),remoteCloudflareTunnelToken:c.remoteCloudflareTunnelToken||null,remoteCloudflareIngressUrl:String(c.remoteCloudflareIngressUrl??""),remoteShortLivedEnabled:!!c.remoteShortLivedEnabled,remoteShortLivedTtlMs:Number(c.remoteShortLivedTtlMs??9e5),remoteRememberLastRunning:!!c.remoteRememberLastRunning};await Kt(b,d),await yn(d),await Ht(d),o("Remote tunnel restarted","success")}),children:pe==="start fresh"?"Restarting…":"Start Fresh"}),e.jsx("button",{type:"button",className:"btn btn-primary",disabled:!s||pe!==null,onClick:()=>void De("use existing",async()=>{const c=l,b={remoteActiveProvider:s,remoteTailscaleEnabled:s==="tailscale",remoteTailscaleHostname:String(c.remoteTailscaleHostname??""),remoteTailscaleTargetPort:Number(c.remoteTailscaleTargetPort??4040),remoteTailscaleAcceptRoutes:!!c.remoteTailscaleAcceptRoutes,remoteCloudflareEnabled:s==="cloudflare",remoteCloudflareQuickTunnel:!!(c.remoteCloudflareQuickTunnel??!0),remoteCloudflareTunnelName:String(c.remoteCloudflareTunnelName??""),remoteCloudflareTunnelToken:c.remoteCloudflareTunnelToken||null,remoteCloudflareIngressUrl:String(c.remoteCloudflareIngressUrl??""),remoteShortLivedEnabled:!!c.remoteShortLivedEnabled,remoteShortLivedTtlMs:Number(c.remoteShortLivedTtlMs??9e5),remoteRememberLastRunning:!!c.remoteRememberLastRunning};await Kt(b,d),await Ht(d),o("Remote tunnel started","success")}),children:pe==="use existing"?"Starting…":"Use Existing"})]}):e.jsx("button",{type:"button",className:"btn btn-primary",disabled:!s||pe!==null,onClick:()=>void De("start",async()=>{const c=l,b={remoteActiveProvider:s,remoteTailscaleEnabled:s==="tailscale",remoteTailscaleHostname:String(c.remoteTailscaleHostname??""),remoteTailscaleTargetPort:Number(c.remoteTailscaleTargetPort??4040),remoteTailscaleAcceptRoutes:!!c.remoteTailscaleAcceptRoutes,remoteCloudflareEnabled:s==="cloudflare",remoteCloudflareQuickTunnel:!!(c.remoteCloudflareQuickTunnel??!0),remoteCloudflareTunnelName:String(c.remoteCloudflareTunnelName??""),remoteCloudflareTunnelToken:c.remoteCloudflareTunnelToken||null,remoteCloudflareIngressUrl:String(c.remoteCloudflareIngressUrl??""),remoteShortLivedEnabled:!!c.remoteShortLivedEnabled,remoteShortLivedTtlMs:Number(c.remoteShortLivedTtlMs??9e5),remoteRememberLastRunning:!!c.remoteRememberLastRunning};await Kt(b,d),await Ht(d),o("Remote tunnel started","success")}),children:pe==="start"?"Starting…":"Start Tunnel"}),s==="cloudflare"&&Y?.cloudflaredAvailable===!1?e.jsx("small",{className:"field-error",children:"cloudflared must be installed to start the tunnel"}):null]})}),e.jsxs("details",{className:"remote-advanced-details",children:[e.jsx("summary",{children:"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:!!t.remoteShortLivedEnabled,onChange:c=>i(b=>({...b,remoteShortLivedEnabled:c.target.checked}))}),"Enable short-lived tokens"]}),e.jsx("label",{htmlFor:"remoteShortLivedTtlMs",children:"Short-lived TTL (ms)"}),e.jsx("input",{id:"remoteShortLivedTtlMs",type:"number",min:6e4,max:864e5,value:Number(t.remoteShortLivedTtlMs??9e5),onChange:c=>i(b=>({...b,remoteShortLivedTtlMs:Number(c.target.value||9e5)}))}),Ft&&e.jsxs("small",{children:["Last short-lived token expires at ",new Date(Ft.expiresAt).toLocaleString()," (",Ft.ttlMs,"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:!!t.remoteRememberLastRunning,onChange:c=>i(b=>({...b,remoteRememberLastRunning:c.target.checked}))}),"Remember last running state"]}),e.jsx("small",{children:"Automatically restore tunnel on startup if it was running when last stopped."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Auth Links"}),e.jsxs("div",{className:"settings-button-row",children:[e.jsx("button",{type:"button",className:"btn btn-sm",disabled:pe!==null,onClick:()=>void De("regenerate persistent token",async()=>{await kn(d),o("Persistent token regenerated","success")}),children:"Regenerate persistent token"}),e.jsx("button",{type:"button",className:"btn btn-sm",disabled:pe!==null,onClick:()=>void De("generate short-lived token",async()=>{const c=Number(t.remoteShortLivedTtlMs??9e5),b=await Nn(c,d);Ca(b),o("Short-lived token generated","success")}),children:"Generate short-lived token"}),e.jsx("button",{type:"button",className:"btn btn-sm",disabled:pe!==null,onClick:()=>void De("fetch remote url",async()=>{const c=Number(t.remoteShortLivedTtlMs??9e5),b=await Ys({projectId:d,tokenType:Ge,ttlMs:Ge==="short-lived"?c:void 0});gs(b),bs(null)}),children:"Show URL"}),e.jsx("button",{type:"button",className:"btn btn-sm",disabled:pe!==null,onClick:()=>void De("generate QR",async()=>{const c=Number(t.remoteShortLivedTtlMs??9e5),b=await zt("image/svg",{projectId:d,tokenType:Ge,ttlMs:Ge==="short-lived"?c:void 0});gs({url:b.url,expiresAt:b.expiresAt,tokenType:b.tokenType}),bs(b.data??null)}),children:"Generate QR"})]}),e.jsx("label",{htmlFor:"remoteAuthLinkTokenType",children:"Auth link token type"}),e.jsxs("select",{id:"remoteAuthLinkTokenType",value:Ge,onChange:c=>Na(c.target.value),children:[e.jsx("option",{value:"persistent",children:"Persistent token"}),e.jsx("option",{value:"short-lived",children:"Short-lived token"})]}),e.jsxs("small",{children:["URL and QR generation use the selected token type.",Ge==="short-lived"?` TTL: ${Number(t.remoteShortLivedTtlMs??9e5)}ms.`:""]}),Je?.url&&e.jsxs(e.Fragment,{children:[e.jsxs("small",{children:["Authenticated URL:",e.jsx("code",{className:"settings-url-output",children:Je.url})]}),e.jsxs("small",{children:["Token type: ",e.jsx("strong",{children:Je.tokenType}),Je.expiresAt?` · Expires at ${new Date(Je.expiresAt).toLocaleString()}`:" · No expiry"]})]}),Mt&&e.jsxs("div",{className:"settings-qr-preview","aria-live":"polite",children:[e.jsx("p",{className:"settings-qr-preview-label",children:"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(Mt)}`,alt:"Remote access QR code",className:"settings-qr-preview-image"})}),e.jsxs("details",{children:[e.jsx("summary",{children:"QR SVG markup"}),e.jsx("pre",{className:"settings-raw-output",children:Mt})]})]})]})]})]})}case"prompts":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Prompts"}),e.jsx(lr,{value:l.agentPrompts,onChange:t=>{i(s=>({...s,agentPrompts:t}))},promptOverrides:l.promptOverrides,onPromptOverridesChange:t=>{i(s=>({...s,promptOverrides:t}))}})]});case"plugins":return e.jsxs(e.Fragment,{children:[X(),e.jsx("h4",{className:"settings-section-heading",children:"Plugins"}),e.jsxs("div",{className:"settings-plugins-subsection-toggle",role:"tablist","aria-label":"Plugin manager type",children:[e.jsx("button",{type:"button",id:"plugins-tab-fusion-plugins",role:"tab","aria-controls":"plugins-panel-fusion-plugins","aria-selected":W==="fusion-plugins",tabIndex:W==="fusion-plugins"?0:-1,className:`settings-plugins-subsection-btn${W==="fusion-plugins"?" active":""}`,onClick:()=>Te("fusion-plugins"),children:"Fusion Plugins"}),e.jsx("button",{type:"button",id:"plugins-tab-pi-extensions",role:"tab","aria-controls":"plugins-panel-pi-extensions","aria-selected":W==="pi-extensions",tabIndex:W==="pi-extensions"?0:-1,className:`settings-plugins-subsection-btn${W==="pi-extensions"?" active":""}`,onClick:()=>Te("pi-extensions"),children:"Pi Extensions"})]}),e.jsx("div",{id:"plugins-panel-fusion-plugins",role:"tabpanel","aria-labelledby":"plugins-tab-fusion-plugins",className:"settings-plugins-subsection-panel",hidden:W!=="fusion-plugins",children:W==="fusion-plugins"&&e.jsxs(e.Fragment,{children:[e.jsx(a.Suspense,{fallback:null,children:e.jsx(cr,{addToast:o,projectId:d})}),e.jsx(fn,{slotId:"settings-section",projectId:d})]})}),e.jsx("div",{id:"plugins-panel-pi-extensions",role:"tabpanel","aria-labelledby":"plugins-tab-pi-extensions",className:"settings-plugins-subsection-panel",hidden:W!=="pi-extensions",children:W==="pi-extensions"&&e.jsx(a.Suspense,{fallback:null,children:e.jsx(dr,{addToast:o,projectId:d})})})]});case"authentication":{const t=Ue.filter(h=>h.type==="cli"),r=[...Ue.filter(h=>h.type!=="cli")].sort((h,te)=>h.authenticated!==te.authenticated?h.authenticated?-1:1:h.name.localeCompare(te.name)),m=r.filter(h=>h.authenticated),c=r.filter(h=>!h.authenticated),b=t.find(h=>h.id==="claude-cli"),k=t.find(h=>h.id==="droid-cli"),O=b?e.jsx(pn,{compact:!0,authenticated:b.authenticated,onToggled:()=>{oe()}}):null,z=k?e.jsx(gn,{compact:!0,authenticated:k.authenticated,onToggled:()=>{oe()}}):null,f=m.length>0||(b?.authenticated??!1)||(k?.authenticated??!1),v=c.length>0||b&&!b.authenticated||k&&!k.authenticated;return e.jsxs(e.Fragment,{children:[e.jsx("h4",{className:"settings-section-heading",children:"Authentication"}),ka?e.jsx("div",{className:"settings-empty-state",children:"Loading authentication status…"}):Ue.length===0?e.jsx("div",{className:"settings-empty-state settings-muted",children:"No providers available"}):e.jsxs("div",{className:"auth-panel-body",children:[!f&&e.jsx("div",{className:"auth-section-hint",children:"Sign in to at least one provider to get started with AI models."}),f&&e.jsxs("div",{className:"auth-provider-group",children:[e.jsx("div",{className:"auth-group-label",children:"Authenticated"}),b?.authenticated&&O,k?.authenticated&&z,m.map(h=>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-${h.id}`,"aria-hidden":"true",children:e.jsx(st,{provider:h.id,size:"md"})}),e.jsx("strong",{children:h.name}),e.jsx("span",{"data-testid":`auth-status-${h.id}`,className:`auth-status-badge ${h.authenticated?"authenticated":"not-authenticated"}`,children:"✓ Active"}),h.authenticated&&h.keyHint&&e.jsxs("span",{className:"auth-key-hint",children:["Key: ",h.keyHint]})]}),h.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:"Enter API key",value:Ve[h.id]??"",onChange:te=>lt(Ce=>({...Ce,[h.id]:te.target.value})),disabled:ve===h.id}),h.authenticated&&!Ve[h.id]?e.jsx("button",{className:"btn btn-sm",onClick:()=>Oa(h.id),disabled:ve===h.id,children:"Clear"}):e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>Bs(h.id),disabled:ve===h.id,children:"Save"})]}),ve===h.id&&e.jsx("small",{className:"auth-apikey-progress",children:"Saving…"}),nt[h.id]&&e.jsx("small",{className:"auth-apikey-error",children:nt[h.id]})]}):e.jsx("div",{children:ve===h.id?e.jsx("button",{className:"btn btn-sm",disabled:!0,children:"Logging out…"}):h.loginInProgress?e.jsxs("div",{className:"auth-provider-actions-row",children:[e.jsx("button",{className:"btn btn-sm",disabled:!0,children:"Waiting for login…"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>Os(h.id),children:"Cancel"})]}):e.jsx("button",{className:"btn btn-sm",onClick:()=>$a(h.id),children:"Logout"})})]})},h.id))]}),v&&e.jsxs("div",{className:"auth-provider-group",children:[e.jsx("div",{className:"auth-group-label",children:"Available"}),b&&!b.authenticated&&O,k&&!k.authenticated&&z,c.map(h=>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-${h.id}`,"aria-hidden":"true",children:e.jsx(st,{provider:h.id,size:"md"})}),e.jsx("strong",{children:h.name}),e.jsx("span",{"data-testid":`auth-status-${h.id}`,className:`auth-status-badge ${h.authenticated?"authenticated":"not-authenticated"}`,children:"✗ Not connected"})]}),h.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:"Enter API key",value:Ve[h.id]??"",onChange:te=>lt(Ce=>({...Ce,[h.id]:te.target.value})),disabled:ve===h.id}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>Bs(h.id),disabled:ve===h.id,children:"Save"})]}),ve===h.id&&e.jsx("small",{className:"auth-apikey-progress",children:"Saving…"}),nt[h.id]&&e.jsx("small",{className:"auth-apikey-error",children:nt[h.id]})]}):e.jsxs("div",{children:[ve===h.id?e.jsx("button",{className:"btn btn-sm",disabled:!0,children:"Waiting for login…"}):h.loginInProgress?e.jsxs("div",{className:"auth-provider-actions-row",children:[e.jsx("button",{className:"btn btn-sm",disabled:!0,children:"Waiting for login…"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>Os(h.id),children:"Cancel"})]}):e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>Da(h.id),children:"Login"}),is[h.id]&&(h.loginInProgress||ve===h.id)&&e.jsx(bn,{instructions:is[h.id],"data-testid":`auth-login-instructions-${h.id}`})]})]})},h.id))]})]}),e.jsx("small",{className:"auth-hint",children:"Authentication changes take effect immediately — no need to save."}),C&&e.jsxs("div",{className:"form-group",style:{marginTop:"var(--space-md)"},children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:C,children:"Reopen onboarding guide"}),e.jsx("small",{className:"settings-muted",children:"Re-run the setup wizard to review or update your AI provider and model configuration."})]}),e.jsx(or,{})]})}case"hermes-runtime":return e.jsxs(e.Fragment,{children:[e.jsx("h4",{className:"settings-section-heading",children:"Hermes Runtime"}),e.jsx(Wn,{})]});case"openclaw-runtime":return e.jsxs(e.Fragment,{children:[e.jsx("h4",{className:"settings-section-heading",children:"OpenClaw Runtime"}),e.jsx(Jn,{})]});case"paperclip-runtime":return e.jsxs(e.Fragment,{children:[e.jsx("h4",{className:"settings-section-heading",children:"Paperclip Runtime"}),e.jsx(tr,{})]})}};return e.jsxs("div",{className:"modal-overlay open",...Ga,role:"dialog","aria-modal":"true",children:[e.jsxs("div",{className:"modal modal-lg settings-modal",ref:G,children:[e.jsxs("div",{className:"modal-header",children:[e.jsxs("div",{className:"settings-modal-heading",children:[e.jsx("h3",{children:"Settings"}),e.jsxs("div",{className:"settings-update-check",children:[w&&e.jsxs("button",{type:"button",className:"settings-version-check-btn",onClick:()=>{Ra()},disabled:ne,"aria-label":"Check for updates",title:"Check for updates",children:[e.jsxs("span",{className:"settings-modal-version",children:["Version ",w]}),e.jsx(mn,{size:12,className:ne?"spinning":void 0})]}),le&&e.jsx("span",{"aria-live":"polite",className:`settings-update-result ${le.error?"settings-update-result--error":le.updateAvailable?"settings-update-result--available":"settings-update-result--up-to-date"}`,children:La()})]})]}),e.jsxs("div",{className:"settings-header-actions",children:[l.showGitHubStarButton!==!1&&e.jsxs("a",{href:"https://github.com/Runfusion/Fusion",target:"_blank",rel:"noopener noreferrer",className:"settings-github-star-btn","aria-label":"Star Fusion on GitHub",title:"Star Fusion on GitHub",onClick:Be,"data-clicked":re?"true":"false",children:[e.jsxs("span",{className:"settings-github-star-btn__action",children:[e.jsx(st,{provider:"github",size:"sm"}),e.jsx(Ln,{size:11,"aria-hidden":"true"}),"Star"]}),J!==null&&e.jsx("span",{className:"settings-github-star-btn__count","aria-label":`${J.toLocaleString()} stars`,children:J>=1e3?`${(J/1e3).toFixed(1)}k`:J.toLocaleString()})]}),e.jsxs("a",{href:"https://github.com/Runfusion/Fusion/discussions",target:"_blank",rel:"noopener noreferrer",className:"btn btn-sm","aria-label":"Help and discussions",title:"Help and discussions",children:[e.jsx(un,{size:13,"aria-hidden":"true"}),"Help"]})]}),e.jsx("button",{className:"modal-close",onClick:n,"aria-label":"Close",children:"×"})]}),g?e.jsx("div",{className:"settings-empty-state settings-loading",children:"Loading…"}):e.jsxs("div",{className:"settings-layout",children:[xe&&e.jsxs("div",{className:"settings-mobile-section-picker",children:[e.jsx("label",{htmlFor:"settings-mobile-section",children:"Settings Section"}),e.jsx("select",{id:"settings-mobile-section",className:"select touch-target",value:S,onChange:t=>q(t.target.value),children:_e.filter(t=>!t.isGroupHeader).map(t=>e.jsx("option",{value:t.id,children:t.label},t.id))})]}),e.jsx("nav",{className:"settings-sidebar",children:_e.map(t=>t.isGroupHeader?e.jsx("div",{className:"settings-group-header",children:t.label},t.id):e.jsxs("button",{className:`settings-nav-item${S===t.id?" active":""}`,onClick:()=>q(t.id),title:t.scope==="global"?"Shared across all projects":t.scope==="project"?"Specific to this project":void 0,children:[t.scope==="global"&&e.jsx(xt,{className:"settings-scope-icon","aria-label":"Global setting",size:16}),t.scope==="project"&&e.jsx(Js,{className:"settings-scope-icon","aria-label":"Project setting",size:16}),t.icon&&!t.scope&&e.jsx(t.icon,{className:"settings-scope-icon","aria-label":"Global setting",size:16}),t.label]},t.id))}),e.jsx("div",{className:"settings-content",ref:E,children:ol()})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsxs("div",{className:"modal-actions-left",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:_a,title:"Export settings to JSON file",children:"Export"}),e.jsx("input",{type:"file",ref:Ds,accept:".json,application/json",style:{display:"none"},onChange:Ua}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>Ds.current?.click(),disabled:ht,title:"Import settings from JSON file",children:ht?"Loading…":"Import"})]}),e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn btn-sm",onClick:n,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:Za,disabled:g,children:"Save"})]})]})]}),U!==null&&e.jsx("div",{className:"modal-overlay open",onClick:Ya,role:"dialog","aria-modal":"true","aria-label":"Browse workspace path",children:e.jsxs("div",{className:"modal modal-lg settings-overlap-path-picker-modal",onClick:t=>t.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Select ignored overlap path"}),e.jsx("button",{className:"modal-close",onClick:Le,"aria-label":"Close",children:"×"})]}),e.jsxs("div",{className:"modal-body settings-overlap-path-picker-body",children:[e.jsx("p",{className:"settings-overlap-path-picker-note",children:"Choose a file to ignore directly, or navigate into a folder and select the current directory."}),e.jsx(hn,{entries:$,currentPath:me,onSelectFile:Bt,onNavigate:jt,loading:va,error:ja,onRetry:ya,workspace:"project",projectId:d})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("div",{className:"modal-actions-left",children:e.jsxs("small",{children:["Current directory: ",e.jsx("code",{children:me==="."?"(project root)":me})]})}),e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn btn-sm",onClick:Le,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:Va,disabled:me===".",children:"Select current directory"})]})]})]})}),Pa&&Ne&&e.jsx("div",{className:"modal-overlay open",onClick:t=>t.target===t.currentTarget&&Ze(!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:"Import Settings"}),e.jsx("button",{className:"modal-close",onClick:()=>Ze(!1),"aria-label":"Close",children:"×"})]}),e.jsxs("div",{className:"modal-body",children:[e.jsx("p",{children:"Review the settings to be imported:"}),Ne.global&&Object.keys(Ne.global).length>0&&e.jsxs("div",{className:"form-group",children:[e.jsx("strong",{children:"Global Settings:"}),e.jsx("ul",{className:"import-preview-list",children:Object.entries(Ne.global).filter(([,t])=>t!==void 0).map(([t])=>e.jsx("li",{children:t},t))})]}),Ne.project&&Object.keys(Ne.project).length>0&&e.jsxs("div",{className:"form-group",children:[e.jsx("strong",{children:"Project Settings:"}),e.jsx("ul",{className:"import-preview-list",children:Object.entries(Ne.project).filter(([,t])=>t!==void 0).map(([t])=>e.jsx("li",{children:t},t))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"import-scope",children:"Import Scope:"}),e.jsxs("select",{id:"import-scope",value:Dt,onChange:t=>Ia(t.target.value),children:[e.jsx("option",{value:"both",children:"Both global and project settings"}),e.jsx("option",{value:"global",children:"Global settings only"}),e.jsx("option",{value:"project",children:"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:$t,onChange:t=>Ma(t.target.checked)}),"Merge with existing settings (recommended)"]}),e.jsx("small",{children:"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:()=>Ze(!1),children:"Cancel"}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:za,disabled:ht,children:ht?"Importing…":"Confirm Import"})]})]})})]})}export{kr as SettingsModal};
|