local-operator-ui 0.31.11 → 0.31.13
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/out/main/index.js +156 -7
- package/out/renderer/assets/{_basePickBy-DfG4wjig.js → _basePickBy-DjjQEvSb.js} +1 -1
- package/out/renderer/assets/{_baseUniq-BGWDx1XP.js → _baseUniq-BqECYZsi.js} +1 -1
- package/out/renderer/assets/agent-details-page-DWSkiNxw.js +6 -0
- package/out/renderer/assets/agent-hub-page-D_c8J10-.js +6 -0
- package/out/renderer/assets/agents-page-GjfdafAi.js +2 -0
- package/out/renderer/assets/{arc-BbZdEs1w.js → arc-DLAhhRoh.js} +1 -1
- package/out/renderer/assets/{architectureDiagram-IEHRJDOE-4lLfeFcj.js → architectureDiagram-IEHRJDOE-Dz9DJe6U.js} +1 -1
- package/out/renderer/assets/{blockDiagram-JOT3LUYC-CzCeK4l6.js → blockDiagram-JOT3LUYC-B1abEmJ8.js} +1 -1
- package/out/renderer/assets/{book-open-CNgko0U5.js → book-open-4wp9tz_T.js} +1 -1
- package/out/renderer/assets/browser-page-O2yUi_D9.js +1 -0
- package/out/renderer/assets/{browser-webauthn-prompt-Bynwfiuq.js → browser-webauthn-prompt-DIxt4Z0f.js} +1 -1
- package/out/renderer/assets/{c4Diagram-VJAJSXHY-DV6jCVYX.js → c4Diagram-VJAJSXHY-DFUTE5Ky.js} +1 -1
- package/out/renderer/assets/channel-DwtjXPiQ.js +1 -0
- package/out/renderer/assets/{chunk-4BMEZGHF-oN7e33U6.js → chunk-4BMEZGHF-BwRplWr0.js} +1 -1
- package/out/renderer/assets/{chunk-A2AXSNBT-BY7xgPLa.js → chunk-A2AXSNBT-CojVy5BF.js} +1 -1
- package/out/renderer/assets/{chunk-AEK57VVT-CdvId8Is.js → chunk-AEK57VVT-BbTJ2nr6.js} +1 -1
- package/out/renderer/assets/{chunk-D6G4REZN-BnHX7WDi.js → chunk-D6G4REZN-Rb5cgSb4.js} +1 -1
- package/out/renderer/assets/{chunk-RZ5BOZE2-D-FjPJs7.js → chunk-RZ5BOZE2-B04F7M_0.js} +1 -1
- package/out/renderer/assets/{chunk-XZIHB7SX-DE_XcGmS.js → chunk-XZIHB7SX-tjI4W2Za.js} +1 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-I8f9T0d1.js +1 -0
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-I8f9T0d1.js +1 -0
- package/out/renderer/assets/clone-WON5xoYU.js +1 -0
- package/out/renderer/assets/{console-mirror-DjoNpI7u.js → console-mirror-Cp8JlE_x.js} +13 -13
- package/out/renderer/assets/{consoleCapture-BTYJP9Fs.js → consoleCapture-BuuG2eYo.js} +1 -1
- package/out/renderer/assets/{dagre-OKDRZEBW-DSno4uDg.js → dagre-OKDRZEBW-Yr1p9tqE.js} +1 -1
- package/out/renderer/assets/{diagram-SSKATNLV-Cta_mlzh.js → diagram-SSKATNLV-CUK31Gls.js} +1 -1
- package/out/renderer/assets/{diagram-VNBRO52H-DXZvuw9Y.js → diagram-VNBRO52H-DIjVl2yr.js} +1 -1
- package/out/renderer/assets/{erDiagram-Q7BY3M3F-DX_NZcvT.js → erDiagram-Q7BY3M3F-DfFyzWJt.js} +1 -1
- package/out/renderer/assets/{error-boundary-Be38BRVp.js → error-boundary-BxKgKUoO.js} +2 -2
- package/out/renderer/assets/{flowDiagram-4HSFHLVR-CkKn14vu.js → flowDiagram-4HSFHLVR-DcwqvGRJ.js} +1 -1
- package/out/renderer/assets/{ganttDiagram-APWFNJXF-pfUZL8XQ.js → ganttDiagram-APWFNJXF-CYwBjlHW.js} +4 -4
- package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-DyxkVnKD.js → gitGraphDiagram-7IBYFJ6S-Do6CcWt4.js} +1 -1
- package/out/renderer/assets/{graph-CS6U_APD.js → graph-CQQogzkE.js} +1 -1
- package/out/renderer/assets/{index-BoBj0LUC.js → index-BGpQvlC-.js} +390 -394
- package/out/renderer/assets/{index-C-P4UaBn.js → index-Biw7WGBF.js} +5 -5
- package/out/renderer/assets/{index-W19BqfEn.js → index-BwDDMKpx.js} +1 -1
- package/out/renderer/assets/index-C9VwzLl-.css +1 -0
- package/out/renderer/assets/{index-0hsmy_dv.js → index-Go5S7QEQ.js} +1 -1
- package/out/renderer/assets/{infoDiagram-PH2N3AL5-DstV9F9y.js → infoDiagram-PH2N3AL5-DO8p7Ibe.js} +1 -1
- package/out/renderer/assets/{installer-DOOu7eM6.js → installer-iwJK_r4X.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-U35MCT3I-DMxIQQHc.js → journeyDiagram-U35MCT3I-BzyoDXz6.js} +1 -1
- package/out/renderer/assets/{kanban-definition-NDS4AKOZ-DwCNWIKf.js → kanban-definition-NDS4AKOZ-C5KJJD3f.js} +1 -1
- package/out/renderer/assets/{layout-rRE-L5H5.js → layout-DBWsZr1z.js} +1 -1
- package/out/renderer/assets/{legacy-agents-page-D3XdLDk2.js → legacy-agents-page-BDjH2h53.js} +3 -3
- package/out/renderer/assets/{mermaid.core-CHO9EN5d.js → mermaid.core-DjEcfQ2P.js} +5 -5
- package/out/renderer/assets/mesh-page-sfL6urAN.js +2 -0
- package/out/renderer/assets/{mindmap-definition-ALO5MXBD-C0TbE2NA.js → mindmap-definition-ALO5MXBD-DbBMNkp2.js} +1 -1
- package/out/renderer/assets/{org-surface-gate-CyrcQL7E.js → org-surface-gate-BDsBqFdT.js} +1 -1
- package/out/renderer/assets/{page-header-BXIWLsA1.js → page-header-7eTvlPad.js} +1 -1
- package/out/renderer/assets/{pieDiagram-IB7DONF6-psQNoVHK.js → pieDiagram-IB7DONF6-BOUMap4K.js} +1 -1
- package/out/renderer/assets/projects-page-CjiztSuz.js +11 -0
- package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-DAX1qBwZ.js → quadrantDiagram-7GDLP6J5-KVdqTwJk.js} +1 -1
- package/out/renderer/assets/{radar-MK3ICKWK-BRutmqUf.js → radar-MK3ICKWK-CTQEOe3H.js} +1 -1
- package/out/renderer/assets/{radient-auth-buttons-fe1Bn89n.js → radient-auth-buttons-BazI7e18.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-KVF5MWMF-PTinIVCd.js → requirementDiagram-KVF5MWMF-CpsfwkBd.js} +1 -1
- package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-DuPXhi_4.js → sankeyDiagram-QLVOVGJD-2Z-78WfE.js} +1 -1
- package/out/renderer/assets/{schedules-page-Bxn30SeI.js → schedules-page-Ban3orsO.js} +10 -10
- package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-CSbiipy3.js → sequenceDiagram-X6HHIX6F-C2dIRuZz.js} +1 -1
- package/out/renderer/assets/{settings-page-DeQ29q0v.js → settings-page-DhuCeNKV.js} +10 -10
- package/out/renderer/assets/{settings-section-BeU3N8-t.js → settings-section-JVdUSFVI.js} +1 -1
- package/out/renderer/assets/{stateDiagram-DGXRK772-B0olW3ZC.js → stateDiagram-DGXRK772-soqNXJ79.js} +1 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-Bn8yI4B0.js +1 -0
- package/out/renderer/assets/{timeline-definition-BDJGKUSR-DrFO8Scg.js → timeline-definition-BDJGKUSR-DFPF4fnf.js} +1 -1
- package/out/renderer/assets/{use-download-agent-mutation-DB-9HDGk.js → use-download-agent-mutation-BJVETEyg.js} +2 -2
- package/out/renderer/assets/{use-memberships-query-DJonF1zy.js → use-memberships-query-CIdgBOGr.js} +1 -1
- package/out/renderer/assets/{xychartDiagram-VJFVF3MP-ResXi4IE.js → xychartDiagram-VJFVF3MP---VkBu3L.js} +1 -1
- package/out/renderer/console-capture.html +4 -4
- package/out/renderer/index.html +5 -5
- package/out/renderer/installer.html +4 -4
- package/package.json +4 -2
- package/out/renderer/assets/agent-details-page-DhkOKq6G.js +0 -6
- package/out/renderer/assets/agent-hub-page-BRjvfsAy.js +0 -6
- package/out/renderer/assets/agents-page-DgY_6v2S.js +0 -2
- package/out/renderer/assets/browser-page-BVkXt8Il.js +0 -1
- package/out/renderer/assets/channel-DZvj1zQv.js +0 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-CxG-TQSG.js +0 -1
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-CxG-TQSG.js +0 -1
- package/out/renderer/assets/clone-CzEyof2a.js +0 -1
- package/out/renderer/assets/index-BjeBA__i.css +0 -1
- package/out/renderer/assets/mesh-page-Bo6Mw1uW.js +0 -1
- package/out/renderer/assets/projects-page-DLrWcA92.js +0 -11
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-DesKgCmL.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as i,j as t,c as se,t as Bn}from"./index-
|
|
1
|
+
import{r as i,j as t,c as se,t as Bn}from"./index-Biw7WGBF.js";import{cw as an,cx as Hn,cy as Kn,cz as Et,cA as Ot,cB as Gn,cb as qn,h as _e,cc as sn,be as gt,ad as on,g as rn,as as Vn,at as Yn,cC as Wn,cD as Zn,cE as Qn,cF as Jn,cG as cn,cH as xt,cI as ln,az as Xn,cJ as It,cK as ea,c as yt,d as Fe,a4 as ta,cL as na,cM as aa,ae as sa,k as fe,cN as dn,cO as oa,ch as un,cP as mn,a8 as vt,cQ as ra,cR as ia,ac as hn,aB as ct,aC as lt,cS as ca,aY as la,aE as da,cT as dt,j as qe,cU as ua,cV as ut,cW as ma,i as ha,P as Lt,cX as pn,cY as pa,cZ as fa,c_ as ga,ar as xa,c$ as fn,aA as gn,d0 as ya,d1 as xn,d2 as va,d3 as ka,d4 as ba,au as wa,d5 as yn,cn as _a,d6 as ja,d7 as Na,u as Sa,ck as Ca,d8 as Ma,d9 as Aa,ce as Ra,da as Ta,db as Ea,dc as Oa,dd as Ia,c7 as Ft,c0 as La,cj as $t,de as Fa,cl as $a,cm as Da,df as Ua,dg as za,dh as Pa,di as Ba}from"./index-BGpQvlC-.js";import{P as Ha}from"./page-header-7eTvlPad.js";import{c as j,B as $,S as ue,a2 as vn,f as $e,$ as Qe,R as Ka,I as ye,T as Je,p as Ga,q as qa,r as Va,s as Ya,t as Wa,A as de,X as Za,N as kn,L as we,W as Dt,Y as Ut,Z as Ke,a3 as zt,U as Qa,v as Ja,w as Xa,x as es,z as ts,F as Pt,u as ns,a1 as as,i as ss,e as bn}from"./error-boundary-BxKgKUoO.js";import{u as wn,R as os}from"./radient-auth-buttons-BazI7e18.js";import{u as mt}from"./console-mirror-Cp8JlE_x.js";import{S as he,I as kt,a as pe,N as rs}from"./settings-section-JVdUSFVI.js";import{B as is}from"./book-open-4wp9tz_T.js";import{i as cs,a as Ce,b as ls,p as at,f as ds}from"./parseISO-BWtr7JL9.js";import{t as us}from"./en-US-BkS8Ixxl.js";/**
|
|
2
2
|
* @license lucide-react v0.507.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -58,7 +58,7 @@ import{r as i,j as t,c as se,t as Bn}from"./index-C-P4UaBn.js";import{ce as an,c
|
|
|
58
58
|
*
|
|
59
59
|
* This source code is licensed under the ISC license.
|
|
60
60
|
* See the LICENSE file in the root directory of this source tree.
|
|
61
|
-
*/const
|
|
61
|
+
*/const Is=[["path",{d:"M6 16.326A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 .5 8.973",key:"1cez44"}],["path",{d:"m13 12-3 5h4l-3 5",key:"1t22er"}]],Ls=j("cloud-lightning",Is);/**
|
|
62
62
|
* @license lucide-react v0.507.0 - ISC
|
|
63
63
|
*
|
|
64
64
|
* This source code is licensed under the ISC license.
|
|
@@ -98,12 +98,12 @@ import{r as i,j as t,c as se,t as Bn}from"./index-C-P4UaBn.js";import{ce as an,c
|
|
|
98
98
|
*
|
|
99
99
|
* This source code is licensed under the ISC license.
|
|
100
100
|
* See the LICENSE file in the root directory of this source tree.
|
|
101
|
-
*/const Ws=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M6 12c0-1.7.7-3.2 1.8-4.2",key:"oqkarx"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}],["path",{d:"M18 12c0 1.7-.7 3.2-1.8 4.2",key:"1eah9h"}]],
|
|
101
|
+
*/const Ws=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M6 12c0-1.7.7-3.2 1.8-4.2",key:"oqkarx"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}],["path",{d:"M18 12c0 1.7-.7 3.2-1.8 4.2",key:"1eah9h"}]],Zs=j("disc-3",Ws);/**
|
|
102
102
|
* @license lucide-react v0.507.0 - ISC
|
|
103
103
|
*
|
|
104
104
|
* This source code is licensed under the ISC license.
|
|
105
105
|
* See the LICENSE file in the root directory of this source tree.
|
|
106
|
-
*/const
|
|
106
|
+
*/const Qs=[["path",{d:"M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z",key:"c7niix"}]],Js=j("droplet",Qs);/**
|
|
107
107
|
* @license lucide-react v0.507.0 - ISC
|
|
108
108
|
*
|
|
109
109
|
* This source code is licensed under the ISC license.
|
|
@@ -193,7 +193,7 @@ import{r as i,j as t,c as se,t as Bn}from"./index-C-P4UaBn.js";import{ce as an,c
|
|
|
193
193
|
*
|
|
194
194
|
* This source code is licensed under the ISC license.
|
|
195
195
|
* See the LICENSE file in the root directory of this source tree.
|
|
196
|
-
*/const
|
|
196
|
+
*/const Io=[["path",{d:"m8 3 4 8 5-5 5 15H2L8 3z",key:"otkl63"}]],Lo=j("mountain",Io);/**
|
|
197
197
|
* @license lucide-react v0.507.0 - ISC
|
|
198
198
|
*
|
|
199
199
|
* This source code is licensed under the ISC license.
|
|
@@ -233,7 +233,7 @@ import{r as i,j as t,c as se,t as Bn}from"./index-C-P4UaBn.js";import{ce as an,c
|
|
|
233
233
|
*
|
|
234
234
|
* This source code is licensed under the ISC license.
|
|
235
235
|
* See the LICENSE file in the root directory of this source tree.
|
|
236
|
-
*/const
|
|
236
|
+
*/const Zo=[["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"}]],Qo=j("sun",Zo);/**
|
|
237
237
|
* @license lucide-react v0.507.0 - ISC
|
|
238
238
|
*
|
|
239
239
|
* This source code is licensed under the ISC license.
|
|
@@ -298,10 +298,10 @@ import{r as i,j as t,c as se,t as Bn}from"./index-C-P4UaBn.js";import{ce as an,c
|
|
|
298
298
|
*
|
|
299
299
|
* This source code is licensed under the ISC license.
|
|
300
300
|
* See the LICENSE file in the root directory of this source tree.
|
|
301
|
-
*/const wr=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],_r=j("zap",wr),jr=({appVersion:e=null,slowWaitHintMs:n})=>{const a="https://local-operator.com/download",[s,o]=i.useState(!1),r=an(s,n??Hn),[l,d]=i.useState(!1),[c,u]=i.useState(null),[g,x]=i.useState("info"),[y,f]=i.useState(null),[k,E]=i.useState(null),R=e?.trim()?e.trim():null,K=i.useRef(!1),_=i.useRef(!1),V=i.useRef(0),z=i.useRef(!1),L=i.useCallback((P,w)=>{_.current=!1,u(P),x(w),d(!0)},[]),T=i.useCallback(P=>{_.current=!0,u(P),x("success"),d(!0)},[]),Q=i.useCallback(()=>{_.current&&(_.current=!1,d(!1),u(null))},[]),{clearDeferredUpdate:I}=Kn();i.useEffect(()=>{const P=window.api.updater.onUpdateError(ne=>{K.current&&ne.includes("manually")&&(f({message:"The server is installed outside the app, so use the tool you installed it with - uv, pipx or pip.",command:""}),_.current=!1,u(null),x("warning"),d(!0))}),w=window.api.updater.onBackendUpdateDevMode(ne=>{K.current&&L(ne,"info")}),q=()=>{z.current=!0,Q()},ee=window.api.updater.onUpdateAvailable(q),W=window.api.updater.onUpdateNpxAvailable(q),D=window.api.updater.onBackendUpdateAvailable(q);return()=>{P(),w(),ee(),W(),D()}},[Q,L]),i.useEffect(()=>{let P=!1;const w=()=>{window.api.updater.getLastInstallAttempt().then(ee=>{P||E(ee)}).catch(()=>{})};w();const q=window.api.updater.onUpdateInstallFailed(()=>w());return()=>{P=!0,q()}},[]);const X=async()=>{const P=++V.current;Q(),z.current=!1;try{o(!0),K.current=!0,I(Ot.UI),I(Ot.BACKEND);const w=await window.api.updater.checkForAllUpdates({manual:!0});if(P!==V.current)return;w?.affirmation&&!z.current?T(w.affirmation):Q()}catch(w){if(P!==V.current)return;console.warn(`Update check failed; the app-level alert owns the report: ${Gn(w)}`)}finally{P===V.current&&o(!1),setTimeout(()=>{K.current=!1},2e3)}},Z=()=>{_.current=!1,d(!1),u(null)};return t.jsxs(t.Fragment,{children:[k&&t.jsxs("div",{className:"mb-3 rounded-sm bg-sunken p-3",children:[t.jsxs("p",{className:"text-body-sm text-ink",children:["The last update to version ",k.targetVersion," didn't finish",k.attempts>1?` (${k.attempts} attempts)`:"",".",R?` Version ${R} is running.`:null]}),t.jsxs("p",{className:"mt-1 text-meta text-ink-dim",children:["Detected"," ",k.detectedAt?new Date(k.detectedAt).toLocaleString():"at an unknown time",". ",k.detail]}),t.jsx($,{variant:"outline",size:"sm",className:"mt-2",onClick:()=>void window.api.openExternal(a),children:"Download a fresh copy"})]}),t.jsxs($,{variant:"outline",onClick:()=>void X(),disabled:s,children:[s?t.jsx(ue,{size:"sm"}):null,s?"Checking...":"Check for updates"]}),r&&t.jsx("p",{className:"mt-2 text-meta text-ink-muted",children:"Still checking. A slow or stalled connection can hold this for about a minute and a half - the app stops waiting on its own."}),y&&t.jsxs(Et,{open:l,autoHideDuration:1e4,onClose:Z,variant:"warning",children:[t.jsx("p",{className:"text-body-sm",children:y.message}),y.command&&t.jsx("code",{className:"mt-2 block rounded-sm bg-sunken p-2 text-mono-sm text-ink",children:y.command})]}),c&&g!=="danger"&&t.jsx(Et,{open:l,autoHideDuration:6e3,onClose:Z,variant:g,children:c})]})},Ve=["system-prompt"],Nr=()=>{const{shouldEnableQuery:e}=qn();return _e({enabled:e({bypassInternetCheck:!0}),queryKey:Ve,queryFn:async()=>{try{const a=await sn(gt.baseUrl).config.getSystemPrompt();if(a===null)return null;if(a.status>=400)throw new Error(a.message||"Failed to fetch system prompt");return a.result}catch(n){const a=n instanceof Error?n.message:"An unknown error occurred while fetching system prompt";throw on(a),n}},refetchOnWindowFocus:!1,staleTime:5e3})},Sr=()=>{const e=rn(),n=sn(gt.baseUrl);return Vn({mutationFn:async a=>{try{const s=await n.config.updateSystemPrompt(a);if(s.status>=400)throw new Error(s.message||"Failed to update system prompt");return s.result}catch(s){const o=s instanceof Error?s.message:"An unknown error occurred while updating system prompt";throw on(o),s}},onSuccess:async a=>{await e.invalidateQueries({queryKey:Ve,refetchType:"none"}),e.setQueryData(Ve,s=>s&&{...s,...a}),await e.refetchQueries({queryKey:Ve,type:"all"}),Yn("System prompt updated")},onError:a=>{console.error("Error updating system prompt:",a)}})},Cr=({value:e,label:n,description:a,onChange:s,icon:o,isSaving:r=!1})=>{const[l,d]=i.useState(e),c=i.useId(),u=`${c}-label`,g=`${c}-description`,x=async y=>{if(!r){d(y);try{await s(y)}catch(f){d(!y),console.error("Error toggling setting:",f)}}};return t.jsxs("div",{className:"flex items-start justify-between gap-4",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsxs("span",{id:u,className:"flex min-h-6 items-center gap-2 text-body text-ink",children:[o&&t.jsx(o,{size:14,"aria-hidden":"true",className:"shrink-0 text-ink-dim"}),n]}),a&&t.jsx("p",{id:g,className:"mt-0.5 max-w-2xl text-body-sm text-ink-muted",children:a})]}),t.jsx("div",{className:"flex h-6 shrink-0 items-center",children:r?t.jsx(ue,{size:"md",label:`Saving ${n}`}):t.jsx(vn,{checked:l,onCheckedChange:x,"aria-labelledby":u,"aria-describedby":a?g:void 0})})]})};var Mr=Wn({chartName:"LineChart",GraphicalChild:cn,axisComponents:[{axisType:"xAxis",AxisComp:Qn},{axisType:"yAxis",AxisComp:Zn}],formatAxisMap:Jn});function Bt(e,n){const a=us(e,n?.in);if(!cs(a))throw new RangeError("Invalid time value");const s=Ce(a.getDate(),2),o=Ce(a.getMonth()+1,2),r=a.getFullYear(),l=Ce(a.getHours(),2),d=Ce(a.getMinutes(),2),c=Ce(a.getSeconds(),2);let u="",g="";const x=a.getTimezoneOffset();if(x!==0){const y=Math.abs(x),f=Ce(Math.trunc(y/60),2),k=Ce(y%60,2);g=`${x<0?"+":"-"}${f}:${k}`}else g="Z";return`${r}-${o}-${s}T${l}:${d}:${c}${u}${g}`}function Ar(e,n,a){return ls(e,-30,a)}const Rr=["radient","creditBalance"],Tr=e=>{const{user:n,isAuthenticated:a}=xt(),s=n?.account?.tenant_id,o=a&&!!s&&e?.enabled;return _e({queryKey:[Rr,s],queryFn:async()=>{if(!s)throw new Error("Tenant ID not available");const r=await ln({operation:"credits",tenantId:s});if(!r||typeof r.balance!="number")throw new Error("Invalid credit balance response format");return r},enabled:o,staleTime:5*60*1e3,refetchOnWindowFocus:!0})},Er=["radient","usageRollup"],Or=(e,n)=>{const{user:a,isAuthenticated:s}=xt(),o=a?.account?.tenant_id,r=s&&!!o&&n?.enabled;return _e({queryKey:[...Er,o,e],queryFn:async()=>{if(!o)throw new Error("Tenant ID not available");const l={};for(const[c,u]of Object.entries(e))u!=null&&(l[c]=String(u));const d=await ln({operation:"usage",tenantId:o,query:l});if(!d)throw new Error("Invalid usage rollup response format");return d},enabled:r,staleTime:5*60*1e3,refetchOnWindowFocus:!0})},Lr=({appVersion:e})=>t.jsx(jr,{appVersion:e}),Ir=e=>{if(!e)return null;try{return new URL(e).host}catch{return null}},Fr=()=>{const[e,n]=i.useState(null),[a,s]=i.useState({value:"Loading...",detail:null,degraded:!1}),[o,r]=i.useState({platform:"Loading...",arch:"...",nodeVersion:"Loading...",electronVersion:"Loading...",chromeVersion:"Loading..."});i.useEffect(()=>{let d=!0;const c=f=>{if(!d)return;const k=Ir(f.url);if(f.state==="connecting"){s({value:"Loading...",detail:null,degraded:!1});return}if(f.state==="detached"){s({value:"Not connected",detail:f.detail||null,degraded:!1});return}if(f.state==="wedged"){s({value:"Not attached",detail:f.detail||null,degraded:!1});return}const E=f.version||"Version unknown";s({value:k?`${E} · ${k}`:E,detail:f.detail||null,degraded:f.state==="degraded"})};let u=!1;const g=window.api?.backend?.onStatusChange(f=>{u=!0,c(f)}),x=async()=>{try{const[f,k]=await Promise.all([window.api.systemInfo.getAppVersion(),window.api.systemInfo.getPlatformInfo()]);d&&(n(f),r(k))}catch(f){console.error("Error fetching app information:",f)}},y=async()=>{try{const f=window.api?.backend;if(f){const R=await f.getStatus();u||c(R);return}const k=await Lt.healthCheck(gt.baseUrl),E=Lt.getServerVersion(k);d&&s({value:E,detail:null,degraded:!1})}catch(f){console.error("Error fetching server version:",f),d&&s({value:"Unavailable",detail:null,degraded:!1})}};return x(),y(),()=>{d=!1,g?.()}},[]);const l=(d,c,u,g={})=>t.jsx(pe,{label:t.jsx($e,{content:u,children:t.jsxs("span",{className:"inline-flex cursor-help items-center gap-1.5",children:[t.jsx(Ze,{size:12,className:"shrink-0"}),d]})}),valueClassName:g.valueClassName,value:t.jsxs(t.Fragment,{children:[g.valueTooltip?t.jsx($e,{content:g.valueTooltip,children:t.jsx("span",{"data-backend-version":g.valueHoverTarget?"":void 0,className:"cursor-help",children:c})}):c,g.statusNote?t.jsx("span",{className:"mt-0.5 block text-meta text-ink-dim",children:g.statusNote}):null]})});return t.jsx(he,{title:"Application updates and info",icon:Xn,description:"Check for updates and view information about your Local Operator installation.",dataTourTag:"settings-app-updates-section",children:t.jsxs("div",{className:"flex flex-col gap-6",children:[t.jsxs(kt,{children:[l("Application version",e??"Loading...","The version of the Local Operator user interface application."),l("Server version",a.value,"The version of the Local Operator API server backend, and the address of the daemon it was read from.",{valueTooltip:a.detail,valueHoverTarget:!0,statusNote:a.degraded?"Not answering":void 0,valueClassName:a.degraded?"text-ink-muted":void 0}),l("Platform",`${o.platform} (${o.arch})`,"The operating system and architecture your application is running on."),l("Node.js version",o.nodeVersion,"The JavaScript runtime environment version."),l("Electron version",o.electronVersion,"The framework version enabling this desktop application.")]}),t.jsx(Lr,{appVersion:e})]})})},$r={hosting:"core",model_name:"core",model_effort:"core","providers.openai.use_max_context_window":"advanced","providers.openai.api":"advanced","providers.anthropic.cache_ttl_1h_min_context_tokens":"advanced","providers.openrouter.provider_affinity":"advanced","providers.openrouter.sort":"advanced","providers.openrouter.order":"advanced","providers.openrouter.only":"advanced","providers.openrouter.ignore":"advanced","providers.openrouter.allow_fallbacks":"advanced","providers.openrouter.require_parameters":"advanced","providers.openrouter.data_collection":"advanced","providers.openrouter.zdr":"advanced","providers.openrouter.enforce_distillable_text":"advanced","providers.openrouter.quantizations":"advanced","providers.openrouter.max_price":"advanced","providers.openrouter.preferred_min_throughput":"advanced","providers.openrouter.preferred_max_latency":"advanced","retry.enabled":"core","retry.maxRetries":"advanced","retry.baseDelayMs":"advanced","retry.connectivityMaxRetries":"advanced","retry.connectivityBackoffCapMs":"advanced","retry.modelFallback":"advanced","retry.usageAwareFallback":"advanced","retry.usageAwareAccountPick":"advanced","retry.usageReservePercent":"advanced","retry.fallbackChains":"advanced","tui.theme":"advanced","display.shimmer":"advanced","display.comfortable_rows":"advanced","display.nerd_icons":"advanced","display.heading_markers":"advanced","display.terminal_title":"advanced","display.images":"advanced","display.notifications":"core","display.notification_session_name":"advanced","display.time_format":"advanced","display.dock":"advanced","tui.sidebar_visible":"advanced","tui.sidebar_position":"advanced","keymap.new_session":"advanced","keymap.resume":"advanced",tool_approval_mode:"core",auto_save_conversation:"core","session.cleanup.enabled":"core","session.cleanup.max_sessions":"advanced","session.cleanup.max_inactive_days":"advanced","session.cleanup.max_total_bytes":"advanced","session.cleanup.remove_empty":"advanced","runtime.background_on_resume":"advanced","runtime.unattended_gate_timeout":"advanced","subagents.max_running":"advanced","subagents.model_choice":"advanced","subagents.models.lo":"advanced","subagents.models.med":"advanced","subagents.models.hi":"advanced","fork.mode":"core","fork.cmux_placement":"advanced","compaction.enabled":"core","compaction.strategy":"advanced","compaction.threshold_percent":"advanced","compaction.threshold_tokens":"advanced","compaction.keep_recent_tokens":"advanced","compaction.auto_continue":"advanced","compaction.mid_turn_enabled":"advanced","compaction.wire_bytes_budget":"advanced","compaction.wire_bytes_trigger":"advanced","web_search.enabled":"core","web_fetch.enabled":"core","web_search.strategy":"advanced","web_search.providers":"advanced","web_search.timeout_seconds":"advanced","web_search.searxng_endpoint":"advanced","web_search.deepseek_evidence":"advanced","web_search.read_enabled":"advanced","web_fetch.timeout_seconds":"advanced","web_fetch.max_bytes":"advanced","web_fetch.max_redirects":"advanced","web_fetch.cache_ttl_seconds":"advanced","web_fetch.allow_private":"advanced","web_fetch.render_backend":"advanced","web_fetch.enrich":"advanced","web_fetch.max_attempts":"advanced","web_fetch.blocked_retry":"advanced","bash.shell":"advanced","providers.lmstudio.base_url":"advanced","providers.lmstudio.models":"advanced","providers.ollama.base_url":"advanced","providers.ollama.models":"advanced","providers.vllm.base_url":"advanced","providers.vllm.models":"advanced","providers.llamacpp.base_url":"advanced","providers.llamacpp.models":"advanced","providers.openai-compatible.base_url":"advanced","providers.openai-compatible.models":"advanced",conversation_length:"advanced",detail_length:"advanced",max_learnings_history:"advanced","desktop.launch_command":"advanced"},Dr={model:"core",approvals:"core",web_tools:"core",desktop:"advanced"};function Me(e){return e.tier==="core"||e.tier==="advanced"?e.tier:$r[e.key]??Dr[e.section]??"advanced"}function Ur(e){return e.length===0?!1:e.filter(a=>Me(a)==="core").length*2>=e.length}function zr(e,n,a){return n?{layout:null,filter:e?[]:[...a]}:{layout:{opened:e?[...a]:[],closed:e?[]:[...a]},filter:[]}}const jn="__cascade__";function Ee(e){return e==null?"":typeof e=="object"?JSON.stringify(e):String(e)}function be(e){return{value:e.kind==="list"?(e.value??[]).join(`
|
|
301
|
+
*/const wr=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],_r=j("zap",wr),jr=({appVersion:e=null,slowWaitHintMs:n})=>{const a="https://local-operator.com/download",[s,o]=i.useState(!1),r=an(s,n??Hn),[l,d]=i.useState(!1),[c,u]=i.useState(null),[g,x]=i.useState("info"),[y,f]=i.useState(null),[k,E]=i.useState(null),R=e?.trim()?e.trim():null,K=i.useRef(!1),_=i.useRef(!1),V=i.useRef(0),z=i.useRef(!1),I=i.useCallback((P,w)=>{_.current=!1,u(P),x(w),d(!0)},[]),T=i.useCallback(P=>{_.current=!0,u(P),x("success"),d(!0)},[]),Z=i.useCallback(()=>{_.current&&(_.current=!1,d(!1),u(null))},[]),{clearDeferredUpdate:L}=Kn();i.useEffect(()=>{const P=window.api.updater.onUpdateError(ne=>{K.current&&ne.includes("manually")&&(f({message:"The server is installed outside the app, so use the tool you installed it with - uv, pipx or pip.",command:""}),_.current=!1,u(null),x("warning"),d(!0))}),w=window.api.updater.onBackendUpdateDevMode(ne=>{K.current&&I(ne,"info")}),q=()=>{z.current=!0,Z()},ee=window.api.updater.onUpdateAvailable(q),W=window.api.updater.onUpdateNpxAvailable(q),D=window.api.updater.onBackendUpdateAvailable(q);return()=>{P(),w(),ee(),W(),D()}},[Z,I]),i.useEffect(()=>{let P=!1;const w=()=>{window.api.updater.getLastInstallAttempt().then(ee=>{P||E(ee)}).catch(()=>{})};w();const q=window.api.updater.onUpdateInstallFailed(()=>w());return()=>{P=!0,q()}},[]);const X=async()=>{const P=++V.current;Z(),z.current=!1;try{o(!0),K.current=!0,L(Ot.UI),L(Ot.BACKEND);const w=await window.api.updater.checkForAllUpdates({manual:!0});if(P!==V.current)return;w?.affirmation&&!z.current?T(w.affirmation):Z()}catch(w){if(P!==V.current)return;console.warn(`Update check failed; the app-level alert owns the report: ${Gn(w)}`)}finally{P===V.current&&o(!1),setTimeout(()=>{K.current=!1},2e3)}},Q=()=>{_.current=!1,d(!1),u(null)};return t.jsxs(t.Fragment,{children:[k&&t.jsxs("div",{className:"mb-3 rounded-sm bg-sunken p-3",children:[t.jsxs("p",{className:"text-body-sm text-ink",children:["The last update to version ",k.targetVersion," didn't finish",k.attempts>1?` (${k.attempts} attempts)`:"",".",R?` Version ${R} is running.`:null]}),t.jsxs("p",{className:"mt-1 text-meta text-ink-dim",children:["Detected"," ",k.detectedAt?new Date(k.detectedAt).toLocaleString():"at an unknown time",". ",k.detail]}),t.jsx($,{variant:"outline",size:"sm",className:"mt-2",onClick:()=>void window.api.openExternal(a),children:"Download a fresh copy"})]}),t.jsxs($,{variant:"outline",onClick:()=>void X(),disabled:s,children:[s?t.jsx(ue,{size:"sm"}):null,s?"Checking...":"Check for updates"]}),r&&t.jsx("p",{className:"mt-2 text-meta text-ink-muted",children:"Still checking. A slow or stalled connection can hold this for about a minute and a half - the app stops waiting on its own."}),y&&t.jsxs(Et,{open:l,autoHideDuration:1e4,onClose:Q,variant:"warning",children:[t.jsx("p",{className:"text-body-sm",children:y.message}),y.command&&t.jsx("code",{className:"mt-2 block rounded-sm bg-sunken p-2 text-mono-sm text-ink",children:y.command})]}),c&&g!=="danger"&&t.jsx(Et,{open:l,autoHideDuration:6e3,onClose:Q,variant:g,children:c})]})},Ve=["system-prompt"],Nr=()=>{const{shouldEnableQuery:e}=qn();return _e({enabled:e({bypassInternetCheck:!0}),queryKey:Ve,queryFn:async()=>{try{const a=await sn(gt.baseUrl).config.getSystemPrompt();if(a===null)return null;if(a.status>=400)throw new Error(a.message||"Failed to fetch system prompt");return a.result}catch(n){const a=n instanceof Error?n.message:"An unknown error occurred while fetching system prompt";throw on(a),n}},refetchOnWindowFocus:!1,staleTime:5e3})},Sr=()=>{const e=rn(),n=sn(gt.baseUrl);return Vn({mutationFn:async a=>{try{const s=await n.config.updateSystemPrompt(a);if(s.status>=400)throw new Error(s.message||"Failed to update system prompt");return s.result}catch(s){const o=s instanceof Error?s.message:"An unknown error occurred while updating system prompt";throw on(o),s}},onSuccess:async a=>{await e.invalidateQueries({queryKey:Ve,refetchType:"none"}),e.setQueryData(Ve,s=>s&&{...s,...a}),await e.refetchQueries({queryKey:Ve,type:"all"}),Yn("System prompt updated")},onError:a=>{console.error("Error updating system prompt:",a)}})},Cr=({value:e,label:n,description:a,onChange:s,icon:o,isSaving:r=!1})=>{const[l,d]=i.useState(e),c=i.useId(),u=`${c}-label`,g=`${c}-description`,x=async y=>{if(!r){d(y);try{await s(y)}catch(f){d(!y),console.error("Error toggling setting:",f)}}};return t.jsxs("div",{className:"flex items-start justify-between gap-4",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsxs("span",{id:u,className:"flex min-h-6 items-center gap-2 text-body text-ink",children:[o&&t.jsx(o,{size:14,"aria-hidden":"true",className:"shrink-0 text-ink-dim"}),n]}),a&&t.jsx("p",{id:g,className:"mt-0.5 max-w-2xl text-body-sm text-ink-muted",children:a})]}),t.jsx("div",{className:"flex h-6 shrink-0 items-center",children:r?t.jsx(ue,{size:"md",label:`Saving ${n}`}):t.jsx(vn,{checked:l,onCheckedChange:x,"aria-labelledby":u,"aria-describedby":a?g:void 0})})]})};var Mr=Wn({chartName:"LineChart",GraphicalChild:cn,axisComponents:[{axisType:"xAxis",AxisComp:Zn},{axisType:"yAxis",AxisComp:Qn}],formatAxisMap:Jn});function Bt(e,n){const a=us(e,n?.in);if(!cs(a))throw new RangeError("Invalid time value");const s=Ce(a.getDate(),2),o=Ce(a.getMonth()+1,2),r=a.getFullYear(),l=Ce(a.getHours(),2),d=Ce(a.getMinutes(),2),c=Ce(a.getSeconds(),2);let u="",g="";const x=a.getTimezoneOffset();if(x!==0){const y=Math.abs(x),f=Ce(Math.trunc(y/60),2),k=Ce(y%60,2);g=`${x<0?"+":"-"}${f}:${k}`}else g="Z";return`${r}-${o}-${s}T${l}:${d}:${c}${u}${g}`}function Ar(e,n,a){return ls(e,-30,a)}const Rr=["radient","creditBalance"],Tr=e=>{const{user:n,isAuthenticated:a}=xt(),s=n?.account?.tenant_id,o=a&&!!s&&e?.enabled;return _e({queryKey:[Rr,s],queryFn:async()=>{if(!s)throw new Error("Tenant ID not available");const r=await ln({operation:"credits",tenantId:s});if(!r||typeof r.balance!="number")throw new Error("Invalid credit balance response format");return r},enabled:o,staleTime:5*60*1e3,refetchOnWindowFocus:!0})},Er=["radient","usageRollup"],Or=(e,n)=>{const{user:a,isAuthenticated:s}=xt(),o=a?.account?.tenant_id,r=s&&!!o&&n?.enabled;return _e({queryKey:[...Er,o,e],queryFn:async()=>{if(!o)throw new Error("Tenant ID not available");const l={};for(const[c,u]of Object.entries(e))u!=null&&(l[c]=String(u));const d=await ln({operation:"usage",tenantId:o,query:l});if(!d)throw new Error("Invalid usage rollup response format");return d},enabled:r,staleTime:5*60*1e3,refetchOnWindowFocus:!0})},Ir=({appVersion:e})=>t.jsx(jr,{appVersion:e}),Lr=e=>{if(!e)return null;try{return new URL(e).host}catch{return null}},Fr=()=>{const[e,n]=i.useState(null),[a,s]=i.useState({value:"Loading...",detail:null,degraded:!1}),[o,r]=i.useState({platform:"Loading...",arch:"...",nodeVersion:"Loading...",electronVersion:"Loading...",chromeVersion:"Loading..."});i.useEffect(()=>{let d=!0;const c=f=>{if(!d)return;const k=Lr(f.url);if(f.state==="connecting"){s({value:"Loading...",detail:null,degraded:!1});return}if(f.state==="detached"){s({value:"Not connected",detail:f.detail||null,degraded:!1});return}if(f.state==="wedged"){s({value:"Not attached",detail:f.detail||null,degraded:!1});return}const E=f.version||"Version unknown";s({value:k?`${E} · ${k}`:E,detail:f.detail||null,degraded:f.state==="degraded"})};let u=!1;const g=window.api?.backend?.onStatusChange(f=>{u=!0,c(f)}),x=async()=>{try{const[f,k]=await Promise.all([window.api.systemInfo.getAppVersion(),window.api.systemInfo.getPlatformInfo()]);d&&(n(f),r(k))}catch(f){console.error("Error fetching app information:",f)}},y=async()=>{try{const f=window.api?.backend;if(f){const R=await f.getStatus();u||c(R);return}const k=await It.healthCheck(gt.baseUrl),E=It.getServerVersion(k);d&&s({value:E,detail:null,degraded:!1})}catch(f){console.error("Error fetching server version:",f),d&&s({value:"Unavailable",detail:null,degraded:!1})}};return x(),y(),()=>{d=!1,g?.()}},[]);const l=(d,c,u,g={})=>t.jsx(pe,{label:t.jsx($e,{content:u,children:t.jsxs("span",{className:"inline-flex cursor-help items-center gap-1.5",children:[t.jsx(Qe,{size:12,className:"shrink-0"}),d]})}),valueClassName:g.valueClassName,value:t.jsxs(t.Fragment,{children:[g.valueTooltip?t.jsx($e,{content:g.valueTooltip,children:t.jsx("span",{"data-backend-version":g.valueHoverTarget?"":void 0,className:"cursor-help",children:c})}):c,g.statusNote?t.jsx("span",{className:"mt-0.5 block text-meta text-ink-dim",children:g.statusNote}):null]})});return t.jsx(he,{title:"Application updates and info",icon:Xn,description:"Check for updates and view information about your Local Operator installation.",dataTourTag:"settings-app-updates-section",children:t.jsxs("div",{className:"flex flex-col gap-6",children:[t.jsxs(kt,{children:[l("Application version",e??"Loading...","The version of the Local Operator user interface application."),l("Server version",a.value,"The version of the Local Operator API server backend, and the address of the daemon it was read from.",{valueTooltip:a.detail,valueHoverTarget:!0,statusNote:a.degraded?"Not answering":void 0,valueClassName:a.degraded?"text-ink-muted":void 0}),l("Platform",`${o.platform} (${o.arch})`,"The operating system and architecture your application is running on."),l("Node.js version",o.nodeVersion,"The JavaScript runtime environment version."),l("Electron version",o.electronVersion,"The framework version enabling this desktop application.")]}),t.jsx(Ir,{appVersion:e})]})})},$r={hosting:"core",model_name:"core",model_effort:"core","providers.openai.use_max_context_window":"advanced","providers.openai.api":"advanced","providers.anthropic.cache_ttl_1h_min_context_tokens":"advanced","providers.openrouter.provider_affinity":"advanced","providers.openrouter.sort":"advanced","providers.openrouter.order":"advanced","providers.openrouter.only":"advanced","providers.openrouter.ignore":"advanced","providers.openrouter.allow_fallbacks":"advanced","providers.openrouter.require_parameters":"advanced","providers.openrouter.data_collection":"advanced","providers.openrouter.zdr":"advanced","providers.openrouter.enforce_distillable_text":"advanced","providers.openrouter.quantizations":"advanced","providers.openrouter.max_price":"advanced","providers.openrouter.preferred_min_throughput":"advanced","providers.openrouter.preferred_max_latency":"advanced","retry.enabled":"core","retry.maxRetries":"advanced","retry.baseDelayMs":"advanced","retry.connectivityMaxRetries":"advanced","retry.connectivityBackoffCapMs":"advanced","retry.modelFallback":"advanced","retry.usageAwareFallback":"advanced","retry.usageAwareAccountPick":"advanced","retry.usageReservePercent":"advanced","retry.fallbackChains":"advanced","tui.theme":"advanced","display.shimmer":"advanced","display.comfortable_rows":"advanced","display.nerd_icons":"advanced","display.heading_markers":"advanced","display.terminal_title":"advanced","display.images":"advanced","display.notifications":"core","display.notification_session_name":"advanced","display.time_format":"advanced","display.dock":"advanced","tui.sidebar_visible":"advanced","tui.sidebar_position":"advanced","keymap.new_session":"advanced","keymap.resume":"advanced",tool_approval_mode:"core",auto_save_conversation:"core","session.cleanup.enabled":"core","session.cleanup.max_sessions":"advanced","session.cleanup.max_inactive_days":"advanced","session.cleanup.max_total_bytes":"advanced","session.cleanup.remove_empty":"advanced","runtime.background_on_resume":"advanced","runtime.unattended_gate_timeout":"advanced","subagents.max_running":"advanced","subagents.model_choice":"advanced","subagents.models.lo":"advanced","subagents.models.med":"advanced","subagents.models.hi":"advanced","fork.mode":"core","fork.cmux_placement":"advanced","compaction.enabled":"core","compaction.strategy":"advanced","compaction.threshold_percent":"advanced","compaction.threshold_tokens":"advanced","compaction.keep_recent_tokens":"advanced","compaction.auto_continue":"advanced","compaction.mid_turn_enabled":"advanced","compaction.wire_bytes_budget":"advanced","compaction.wire_bytes_trigger":"advanced","web_search.enabled":"core","web_fetch.enabled":"core","web_search.strategy":"advanced","web_search.providers":"advanced","web_search.timeout_seconds":"advanced","web_search.searxng_endpoint":"advanced","web_search.deepseek_evidence":"advanced","web_search.read_enabled":"advanced","web_fetch.timeout_seconds":"advanced","web_fetch.max_bytes":"advanced","web_fetch.max_redirects":"advanced","web_fetch.cache_ttl_seconds":"advanced","web_fetch.allow_private":"advanced","web_fetch.render_backend":"advanced","web_fetch.enrich":"advanced","web_fetch.max_attempts":"advanced","web_fetch.blocked_retry":"advanced","bash.shell":"advanced","providers.lmstudio.base_url":"advanced","providers.lmstudio.models":"advanced","providers.ollama.base_url":"advanced","providers.ollama.models":"advanced","providers.vllm.base_url":"advanced","providers.vllm.models":"advanced","providers.llamacpp.base_url":"advanced","providers.llamacpp.models":"advanced","providers.openai-compatible.base_url":"advanced","providers.openai-compatible.models":"advanced",conversation_length:"advanced",detail_length:"advanced",max_learnings_history:"advanced","desktop.launch_command":"advanced"},Dr={model:"core",approvals:"core",web_tools:"core",desktop:"advanced"};function Me(e){return e.tier==="core"||e.tier==="advanced"?e.tier:$r[e.key]??Dr[e.section]??"advanced"}function Ur(e){return e.length===0?!1:e.filter(a=>Me(a)==="core").length*2>=e.length}function zr(e,n,a){return n?{layout:null,filter:e?[]:[...a]}:{layout:{opened:e?[...a]:[],closed:e?[]:[...a]},filter:[]}}const jn="__cascade__";function Ee(e){return e==null?"":typeof e=="object"?JSON.stringify(e):String(e)}function be(e){return{value:e.kind==="list"?(e.value??[]).join(`
|
|
302
302
|
`):e.kind==="cascade"?jn:Ee(e.value),cascadeBase:null}}function Ye(e,n){return n.cascadeBase!==null?!0:e.kind==="cascade"?n.value!==jn:e.kind==="list"?n.value!==e.value?.join(`
|
|
303
303
|
`):n.value!==Ee(e.value)}function Pr(e,n){let a=null,s;switch(e.kind){case"bool":a=n.value==="true";break;case"int":{const o=Number.parseInt(n.value,10);if(Number.isNaN(o))return{ok:!1,error:"Enter a whole number."};a=o;break}case"float":{const o=Number.parseFloat(n.value);if(!Number.isFinite(o))return{ok:!1,error:"Enter a finite number."};a=o;break}case"enum":{const o=e.choices.find(r=>Ee(r.value)===n.value);a=o?o.value:n.value;break}case"list":a=n.value.split(`
|
|
304
|
-
`).map(o=>o.trim()).filter(Boolean);break;case"cascade":{if(!n.cascadeBase)return{ok:!1,error:"Nothing has been edited yet."};const o={};for(const[r,l]of Object.entries(n.cascadeBase))o[r]=l;a=o,s=e.value??void 0;break}default:e.empty_unsets&&n.value.trim()===""?a="":a=n.value}return{ok:!0,request:{op:"settings.edit",key:e.key,value:a,...s?{base:s}:{}}}}const Br={hosting:"provider",model_name:"model","subagents.models.lo":"provider-model","subagents.models.med":"provider-model","subagents.models.hi":"provider-model"};function Hr(e){return Br[e]??null}const Kr={provider:"Search providers",model:"Search models","provider-model":"Search models"},Gr="Sign-in state unknown",qr="Current value",Vr="Signed in",Yr="Needs sign-in",bt=e=>e&&e.charAt(0).toUpperCase()+e.slice(1),Ht=["Ready to use","Needs a running server","Needs sign-in"];function Wr(e){const n=new Map(Ht.map(a=>[a,[]]));for(const a of e){const s=ea(a),o=n.get(s.group);o&&o.push({id:a.id,name:a.name,description:s.label,group:s.group})}return Ht.flatMap(a=>n.get(a)??[])}function Kt(e,n,a){if(e.connected!==n.connected)return e.connected?-1:1;const s=a!==""&&e.provider===a,o=a!==""&&n.provider===a;return s!==o?s?-1:1:0}function
|
|
304
|
+
`).map(o=>o.trim()).filter(Boolean);break;case"cascade":{if(!n.cascadeBase)return{ok:!1,error:"Nothing has been edited yet."};const o={};for(const[r,l]of Object.entries(n.cascadeBase))o[r]=l;a=o,s=e.value??void 0;break}default:e.empty_unsets&&n.value.trim()===""?a="":a=n.value}return{ok:!0,request:{op:"settings.edit",key:e.key,value:a,...s?{base:s}:{}}}}const Br={hosting:"provider",model_name:"model","subagents.models.lo":"provider-model","subagents.models.med":"provider-model","subagents.models.hi":"provider-model"};function Hr(e){return Br[e]??null}const Kr={provider:"Search providers",model:"Search models","provider-model":"Search models"},Gr="Sign-in state unknown",qr="Current value",Vr="Signed in",Yr="Needs sign-in",bt=e=>e&&e.charAt(0).toUpperCase()+e.slice(1),Ht=["Ready to use","Needs a running server","Needs sign-in"];function Wr(e){const n=new Map(Ht.map(a=>[a,[]]));for(const a of e){const s=ea(a),o=n.get(s.group);o&&o.push({id:a.id,name:a.name,description:s.label,group:s.group})}return Ht.flatMap(a=>n.get(a)??[])}function Kt(e,n,a){if(e.connected!==n.connected)return e.connected?-1:1;const s=a!==""&&e.provider===a,o=a!==""&&n.provider===a;return s!==o?s?-1:1:0}function Zr(e,n){const a=new Map;for(const s of e){const o=n(s),r=a.get(o);r?r.push(s):a.set(o,[s])}return a}function Qr(e,n){const a=[...e?.models??[]];if(n.kind!=="model")return a;const s=n.hosting.trim();if(!s)return a;const o=a.filter(r=>r.provider===s);return o.length>0?o:a}function Jr(e,n){const a=e?.credentials_known!==!1,s=Qr(e,n),o=c=>a?c.connected?Vr:Yr:Gr,r=c=>n.kind==="provider-model"?c.provider:o(c),l=n.kind==="provider-model"?s:[...s].sort((c,u)=>Kt(c,u,n.hosting)),d=[];for(const[,c]of Zr(l,r)){const u=n.kind==="provider-model"?[...c].sort((g,x)=>Kt(g,x,n.hosting)):c;for(const g of u)d.push({id:n.kind==="model"?g.model_id:g.selector,name:g.selector,description:n.kind==="provider-model"?a?g.connected?"Signed in":"Needs sign-in":void 0:`${n.providerNames?.[g.provider]??bt(g.provider)}${g.aggregated?", aggregated":""}${a&&!g.connected?", no credential":""}`,group:r(g)})}return d.push(...ei(s,e,n)),d}function Xr(e,n){if(e.kind!=="model")return null;const a=e.hosting.trim();if(!a)return null;const s=n?.models??[];if(s.length===0)return null;const o=e.hostingLabel??bt(a);return s.some(l=>l.provider===a)?`Models for ${o}`:`No models listed for ${o}. Showing all models.`}function ei(e,n,a){const s=a.current.trim();if(!s)return[];const o=l=>a.kind==="model"?l.model_id:l.selector;if(e.some(l=>o(l)===s))return[];const r=(n?.models??[]).find(l=>o(l)===s);return[{id:s,name:r?.selector??s,description:r?`${a.providerNames?.[r.provider]??bt(r.provider)}${n?.credentials_known===!1?"":r.connected?", signed in":", no credential"}`:a.kind==="model"?"Custom model":"Custom value",group:qr}]}function ti(e,n,a){const s=n.trim();if(!s)return null;const o=e.filter(r=>r.id===s);if(a){const r=o.find(l=>l.name===a);if(r)return r}return o[0]??{id:s,name:s}}const Gt=e=>`setting-help-${e}`,ni=({setting:e,kind:n,value:a,disabled:s=!1,onValueChange:o,effectiveHosting:r,helpId:l})=>{const d=yt(),c=Fe(d.data,"auth"),u=ta(c),g=n!=="provider"&&Fe(d.data,"catalogues"),[x,y]=i.useState(!1),[f,k]=i.useState(void 0),E=_e({queryKey:[...na.catalogue,!1],queryFn:()=>fe({op:"models.catalogue",live:!1}),enabled:g&&x,staleTime:6e4}),R=i.useMemo(()=>Object.fromEntries((u.data??[]).map(L=>[L.id,L.name])),[u.data]),K=i.useMemo(()=>n==="provider"?u.data?Wr(u.data):[]:Jr(E.data,{kind:n,hosting:n==="model"?r:"",current:a,providerNames:R}),[n,u.data,E.data,r,a,R]),_=aa(E.data,E,L=>sa("Could not list models.",L),!1),V=_.loadError?t.jsx("span",{className:"text-danger",children:_.loadError}):_.notice,z=_.noticeDetail?{title:_.noticeDetail}:{},I=ti(K,a,f),T=i.useMemo(()=>n==="provider"?null:Xr({kind:n,hosting:n==="model"?r:"",hostingLabel:u.data?.find(L=>L.id===r)?.name},E.data),[n,r,u.data,E.data]),Z=i.useMemo(()=>n==="provider"?u.isError?"Could not list providers":c?"No providers":"Provider list unavailable":_.loadError?"Could not list models":g?"Nothing matches that model":"Model list unavailable",[n,u.isError,c,_.loadError,g]);return t.jsx(Ka,{showLabel:!1,ariaLabel:e.label,ariaDescribedBy:l,label:e.label,placeholder:Kr[n],options:K,selected:I,disabled:s,busy:n==="provider"?u.isFetching:E.isFetching,busyLabel:n==="provider"?"Loading providers":"Loading models",onOpenChange:L=>{L&&y(!0)},onSelect:L=>{k(L.name),o(L.id)},onCustomSubmit:L=>o(L),customRowLabel:L=>`Use "${L}"`,listNotice:T,onClear:()=>o(""),emptyText:Z,helperText:V?t.jsx("span",{...z,children:V}):void 0})},qt={bool:"w-9",int:"w-28",float:"w-28",enum:"w-64",text:"w-96",hotkey:"w-56",list:"w-full min-w-0",cascade:"w-full min-w-0",readonly:"w-40"};function ai(e){return qt[e]??qt.text}const si={" ":"space",Spacebar:"space",Escape:"escape",Esc:"escape",Enter:"enter",Tab:"tab",Backspace:"backspace",Delete:"delete",ArrowUp:"up",ArrowDown:"down",ArrowLeft:"left",ArrowRight:"right",Home:"home",End:"end",PageUp:"pageup",PageDown:"pagedown"},oi=new Set(["Control","Shift","Alt","Meta","AltGraph"]),ri=new Set(["Escape","Esc","Enter"]);function ii(e){if(oi.has(e.key)||e.nativeEvent.isComposing)return"";const n=[];e.ctrlKey&&n.push("ctrl"),e.altKey&&n.push("alt"),e.shiftKey&&n.push("shift"),e.metaKey&&n.push("meta");const a=si[e.key]??e.key.toLowerCase();return a?[...n,a].join("+"):""}const ci=({value:e,label:n,disabled:a,onChange:s})=>t.jsxs("span",{className:"flex w-full flex-col gap-0.5",children:[t.jsx(ye,{readOnly:!0,value:e,disabled:a,"aria-label":`${n}: press the key you want`,className:"font-mono text-body-sm",onKeyDown:o=>{if(ri.has(o.key)){o.currentTarget.blur();return}const r=ii(o);r&&(o.preventDefault(),s(r))}}),t.jsx("span",{className:"text-meta text-ink-dim",children:"Press the keys you want; Esc cancels."})]}),li=({setting:e,value:n,chains:a,disabled:s=!1,onValueChange:o,onChainsChange:r,effectiveHosting:l="",helpId:d})=>{const c=Hr(e.key);if(c)return t.jsx(ni,{setting:e,kind:c,value:n,disabled:s,onValueChange:o,effectiveHosting:l,helpId:d});switch(e.kind){case"bool":return t.jsx(vn,{checked:n==="true",disabled:s,onCheckedChange:u=>o(u?"true":"false"),"aria-label":e.label});case"enum":return t.jsxs(Ga,{value:n,disabled:s,onValueChange:o,children:[t.jsx(qa,{"aria-label":e.label,className:"w-full",children:t.jsx(Va,{})}),t.jsx(Ya,{children:e.choices.map(u=>t.jsx(Wa,{value:Ee(u.value),title:u.description||void 0,children:u.label},Ee(u.value)))})]});case"int":case"float":return t.jsx(ye,{type:"number",value:n,disabled:s,min:e.minimum??void 0,max:e.maximum??void 0,step:e.kind==="int"?1:"any",onChange:u=>o(u.target.value),"aria-label":e.label});case"hotkey":return t.jsx(ci,{value:n,label:e.label,disabled:s,onChange:o});case"list":return t.jsx(Je,{value:n,disabled:s,rows:Math.min(6,e.members.length+2),onChange:u=>o(u.target.value),"aria-label":e.label,placeholder:e.placeholder,className:"font-mono text-body-sm"});case"cascade":{const u=a??e.value??{};return t.jsxs("div",{className:"flex flex-col gap-3",children:[Object.entries(u).map(([g,x])=>t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("span",{className:"font-mono text-meta text-ink-dim",children:g}),t.jsx(Je,{value:x.join(`
|
|
305
305
|
`),disabled:s,rows:Math.max(2,x.length+1),onChange:y=>r?.({...u,[g]:y.target.value.split(`
|
|
306
|
-
`).map(f=>f.trim()).filter(Boolean)}),"aria-label":`${e.label}: ${g}`,className:"font-mono text-body-sm"})]},g)),t.jsx("p",{className:"text-meta text-ink-dim",children:"One hop per line, as provider/model (effort). An empty chain moves to the next provider."})]})}default:return t.jsx(ye,{value:n,disabled:s,onChange:u=>o(u.target.value),"aria-label":e.label,placeholder:e.placeholder})}},Nn=({className:e})=>t.jsx("span",{role:"img","aria-label":"Changed from the default",title:"Changed from the default",className:se("size-1.5 shrink-0 rounded-full bg-accent",e)}),di=({title:e,rowCount:n,advancedCount:a,scope:s,modified:o,onOpenChange:r,defaultOpen:l=!1})=>t.jsx("div",{"data-section-header":e,className:"flex w-full flex-col",children:t.jsx(dn,{defaultOpen:l,onOpenChange:r,triggerClassName:"text-ink hover:bg-row-hover hover:text-ink",chevronClassName:"text-ink-dim",rowClassName:"min-h-10 py-0",className:"w-full",summary:t.jsxs("span",{className:"flex w-full min-w-0 items-center gap-2",children:[t.jsxs("span",{className:"flex min-w-0 items-center gap-2",children:[t.jsx("span",{className:"truncate text-heading text-ink",children:e}),n>0&&t.jsx("span",{className:"shrink-0 text-meta text-ink-dim",children:n===1?"1 setting":`${n} settings`}),s&&t.jsx("span",{className:"shrink-0 text-meta text-ink-dim",children:s}),a>0&&t.jsxs("span",{className:"shrink-0 text-meta text-ink-dim",children:[a," advanced"]})]}),o&&t.jsx(Nn,{className:"ml-auto"})]})})}),ui="size-3.5 shrink-0",mi=({setting:e,draft:n,tier:a,gate:s,saving:o,error:r,onDraftChange:l,onSave:d,onReset:c,effectiveHosting:u=""})=>{const g=!!(s&&!s.on),x=Ye(e,n),y=o||g,f=e.kind==="list"||e.kind==="cascade",k=t.jsxs("span",{className:"flex min-w-0 flex-col gap-0.5",children:[t.jsx("span",{className:"truncate text-body-sm text-ink",children:e.label}),e.kind==="readonly"&&t.jsx("span",{className:"text-meta text-ink-dim",children:"Read-only"}),e.warning&&t.jsx("span",{className:"text-meta text-danger",children:e.warning})]}),E=g&&s&&t.jsxs("p",{className:"text-meta text-ink-dim",children:["Needs ",s.label," on. Nothing here is saved while it is off."]});return t.jsx("div",{"data-setting-key":e.key,"data-tier":a,className:"border-b border-hairline",children:t.jsxs("div",{className:"flex flex-wrap items-start gap-x-4 gap-y-1 px-1 py-2.5",children:[t.jsxs("div",{className:se("flex min-w-44 flex-col gap-0.5",f?"shrink-0 basis-2/5":"flex-1"),children:[a==="advanced"&&e.help?t.jsx(dn,{summary:k,triggerClassName:"min-h-5 py-0 px-0 text-body-sm text-ink hover:text-ink",chevronClassName:"text-ink-dim",summaryAlign:"firstLine",rowClassName:"min-h-5 py-0",className:"w-full",children:t.jsx("span",{className:"text-meta text-ink-dim",children:e.help})}):t.jsxs("span",{className:"flex min-h-5 items-center gap-1.5",children:[t.jsx("span",{"aria-hidden":!0,className:ui}),k]}),a==="core"&&e.help&&t.jsx("p",{id:Gt(e.key),className:"ml-5 text-meta text-ink-dim",children:e.help}),E]}),t.jsxs("div",{className:se("flex shrink-0 items-center gap-2 self-center",f&&"min-w-0 flex-1 items-start"),children:[(!e.is_default||x)&&t.jsx(Nn,{}),!e.is_default&&e.kind!=="readonly"&&t.jsxs($,{variant:"ghost",size:"sm",disabled:y,onClick:c,"aria-label":`Use default for ${e.label}`,children:[t.jsx(fr,{"aria-hidden":"true"}),"Use default"]}),x&&t.jsx($,{variant:"primary",size:"sm",disabled:y,onClick:d,children:o?"Saving":"Save"}),t.jsx("div",{className:ai(e.kind),"data-setting-control":"",children:e.redacted?t.jsx("span",{className:"text-meta text-ink-dim",children:"Set in the credential manager: this value carries inline credentials or query parameters."}):e.kind==="readonly"?t.jsx("span",{className:"text-body-sm text-ink-muted",children:Ee(e.value)||"Not set"}):t.jsx(li,{setting:e,value:n.value,chains:n.cascadeBase??void 0,disabled:y,effectiveHosting:u,helpId:a==="core"&&e.help?Gt(e.key):void 0,onValueChange:R=>l({...n,value:R}),onChainsChange:R=>l({...n,cascadeBase:R})})})]}),r&&t.jsx(de,{variant:"danger",role:"alert",className:"w-full",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsx("span",{children:r}),t.jsxs($,{variant:"secondary",size:"sm",disabled:o,onClick:d,children:[t.jsx(oa,{"aria-hidden":"true"}),"Retry"]})]})})]})})},hi="w-full max-w-[400px]",pi=({query:e,onQueryChange:n,matchCount:a,matchSections:s,coreCount:o,advancedCount:r,modifiedCount:l,modifiedOnly:d,onModifiedOnlyChange:c,showAdvanced:u,onShowAdvancedChange:g,onExpandAll:x,onCollapseAll:y,unsavedCount:f,savingAll:k,onSaveAll:E,onDiscardAll:R})=>t.jsxs("div",{className:"flex flex-col gap-2",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[t.jsxs("div",{className:se("relative",hi),children:[t.jsx(un,{size:16,className:"pointer-events-none absolute top-1/2 left-3 -translate-y-1/2 text-ink-dim","aria-hidden":"true"}),t.jsx(ye,{value:e,onChange:K=>n(K.target.value),onKeyDown:K=>{K.key==="Escape"&&e&&n("")},placeholder:"Search settings by name, description or key","aria-label":"Search settings",className:"pl-9"}),e&&t.jsx($,{variant:"ghost",size:"icon-sm",className:"absolute top-1/2 right-1 -translate-y-1/2",onClick:()=>n(""),"aria-label":"Clear search",children:t.jsx(Qa,{"aria-hidden":"true"})})]}),t.jsxs("fieldset",{className:"m-0 border-0 p-0",children:[t.jsx("legend",{className:"sr-only",children:"Settings filters"}),t.jsxs("div",{className:"flex gap-0.5 rounded-md bg-sunken p-0.5",children:[t.jsxs($,{variant:"ghost",size:"sm","aria-pressed":d,onClick:()=>c(!d),className:se(d&&"bg-surface text-ink hover:bg-surface"),children:["Modified",t.jsx(kn,{variant:"neutral",children:l})]}),t.jsx($,{variant:"ghost",size:"sm","aria-pressed":u,onClick:()=>g(!u),className:se(u&&"bg-surface text-ink hover:bg-surface"),children:"Show advanced"})]})]}),t.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[f>0&&t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"text-meta text-ink-dim",children:f===1?"1 unsaved change":`${f} unsaved changes`}),t.jsx($,{variant:"primary",size:"sm",disabled:k,onClick:E,children:k?"Saving":"Save all"}),t.jsx($,{variant:"ghost",size:"sm",disabled:k,onClick:R,children:"Discard all"})]}),t.jsx($,{variant:"ghost",size:"sm",onClick:x,children:"Expand all"}),t.jsx($,{variant:"ghost",size:"sm",onClick:y,children:"Collapse all"})]})]}),t.jsx("p",{className:"text-meta text-ink-dim","aria-live":"polite",children:a!==null?`${a} ${a===1?"result":"results"} in ${s} ${s===1?"section":"sections"}`:d?`${l} modified ${l===1?"setting":"settings"}`:u?`${r} advanced settings shown — Expand all to see them`:`${o} core settings, ${r} advanced`})]}),fi={all:["desktop","settings"]},gi={live:"Takes effect immediately","new launch":"Takes effect the next time the app starts","new sessions":"Takes effect for new conversations"},xi=40,Te=e=>e.toLowerCase().replace(/[-_.]/g," "),yi=({focusKey:e,initialFilter:n=""})=>{const a=yt(),s=wn(),o=Fe(a.data,"settings"),[r,l]=i.useState(n),[d,c]=i.useState(!1),[u,g]=i.useState(!1),[x,y]=i.useState({}),[f,k]=i.useState({}),[E,R]=i.useState({}),[K,_]=i.useState(!1),[V,z]=i.useState(new Set),[L,T]=i.useState(new Set),[Q,I]=i.useState(new Set),X=i.useRef(null),Z=i.useRef(null),P=_e({queryKey:fi.all,queryFn:()=>fe({op:"settings.list"}),enabled:o,staleTime:1e4}),w=P.data;i.useEffect(()=>{w&&y(m=>{let b=!1;const N={...m};for(const C of w.settings){const G=m[C.key];if(!G){N[C.key]=be(C),b=!0;continue}if(Ye(C,G))continue;const F=be(C);(F.value!==G.value||F.cascadeBase!==G.cascadeBase)&&(N[C.key]=F,b=!0)}return b?N:m})},[w]);const q=i.useCallback(m=>!m.is_default||Ye(m,x[m.key]??be(m)),[x]),ee=i.useMemo(()=>{const m=(w?.settings??[]).find(b=>b.key==="hosting");return m?(x.hosting??be(m)).value:""},[w,x]),W=i.useMemo(()=>{if(!w)return[];const m=Te(r.trim()),b=m.length>0||u;return w.settings.filter(N=>!b&&Me(N)==="advanced"&&!d||u&&!q(N)?!1:m?Te([N.label,N.help,N.key,N.section,N.warning??""].join(" ")).includes(m):!0)},[w,r,d,u,q]),D=r.trim().length>0||u,ne=i.useMemo(()=>w?.sections??[],[w]),U=i.useCallback(m=>(w?.settings??[]).filter(b=>b.section===m),[w]),ce=m=>W.filter(b=>b.section===m),O=m=>V.has(m)?!0:L.has(m)?!1:Ur(U(m)),ae=(m,b)=>{z(N=>{const C=new Set(N);return b?C.add(m):C.delete(m),C}),T(N=>{const C=new Set(N);return b?C.delete(m):C.add(m),C})},oe=(m,b)=>{I(N=>{const C=new Set(N);return b?C.delete(m):C.add(m),C})},re=m=>{const b=ne.filter(C=>m||ce(C.name).length>0).map(C=>C.name),N=zr(m,D,b);N.layout&&(z(new Set(N.layout.opened)),T(new Set(N.layout.closed))),I(new Set(N.filter))};i.useEffect(()=>{r.trim()||I(new Set)},[r]);const te=i.useCallback(m=>{const b=m.gated_by;if(!b||!w)return null;const N=w.settings.find(C=>C.key===b);return{key:b,label:N?.label??b,on:N?.value===!0||N?.value==="true"}},[w]),J=i.useCallback((m,b)=>k(N=>({...N,[m]:b})),[]),ie=i.useCallback((m,b)=>R(N=>({...N,[m]:b})),[]),ve=i.useCallback(async m=>{const b=x[m.key];if(!b)return!1;const N=Pr(m,b);if(!N.ok)return ie(m.key,N.error),!1;J(m.key,!0),ie(m.key,null);try{await fe(N.request),J(m.key,!1);const G=(await P.refetch()).data?.settings.find(F=>F.key===m.key);return G&&y(F=>{const ke=F[m.key];return ke&&ke.value===b.value&&ke.cascadeBase===b.cascadeBase?{...F,[m.key]:be(G)}:F}),!0}catch(C){return J(m.key,!1),ie(m.key,C instanceof Error?C.message:"The setting could not be saved."),!1}},[x,P,J,ie]),me=i.useCallback(async m=>{J(m.key,!0),ie(m.key,null);try{await fe({op:"settings.reset",key:m.key}),y(b=>({...b,[m.key]:be({...m,value:m.default,is_default:!0})})),J(m.key,!1),await P.refetch()}catch(b){J(m.key,!1),ie(m.key,b instanceof Error?b.message:"The setting could not be reset.")}},[P,J,ie]),ge=i.useMemo(()=>(w?.settings??[]).filter(m=>Ye(m,x[m.key]??be(m))),[w,x]),p=async()=>{_(!0);for(const m of ge)await ve(m);_(!1)},M=()=>{w&&(y(m=>{const b={...m};for(const N of w.settings)b[N.key]=be(N);return b}),R({}))};i.useEffect(()=>{if(!e||!w||X.current===e)return;const m=w.settings.find(C=>C.key===e);if(!m)return;X.current=e,Me(m)==="advanced"&&c(!0);const b=Te(r.trim());!b||Te([m.label,m.help,m.key,m.section].join(" ")).includes(b)||l(""),g(!1),z(C=>new Set(C).add(m.section)),T(C=>{const G=new Set(C);return G.delete(m.section),G})},[e,w,r]);const S=i.useMemo(()=>{if(!e||!w)return!1;const m=w.settings.find(N=>N.key===e);if(!m||Me(m)==="advanced"&&!d)return!1;const b=Te(r.trim());return b?Te([m.label,m.help,m.key,m.section].join(" ")).includes(b):!0},[e,w,r,d]);if(i.useEffect(()=>{if(!S||!e||Z.current===e)return;let m=0,b=0;const N=()=>{const C=document.querySelector(`[data-setting-key="${CSS.escape(e)}"]`),G=C?.querySelector('[data-setting-control] :is(input, textarea, select, button[role="switch"], button)')??C;if(G){G===C&&(G.tabIndex=-1),G.focus(),G.scrollIntoView({block:"center"}),Z.current=e;return}b+=1,b<xi&&(m=requestAnimationFrame(N))};return m=requestAnimationFrame(N),()=>cancelAnimationFrame(m)},[S,e]),a.data&&!o)return t.jsx(de,{variant:"warning",children:"Searchable settings need a newer Local Operator server. Update the server and restart the app to manage these settings here."});if(P.isLoading||a.isLoading)return t.jsx("div",{className:"flex h-40 items-center justify-center",children:t.jsx(ue,{size:"lg",label:"Loading settings"})});const Y=(a.data?null:a.error)??P.error;if(Y||!w){const m=a.isFetching||P.isFetching,{sentence:b,remedy:N}=mn(s,"Your settings could not be loaded.",Y);return t.jsx(de,{variant:"warning",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsx("span",{children:b}),N&&t.jsx($,{variant:"secondary",size:"sm",className:"shrink-0",onClick:()=>{a.isError?a.refetch():P.refetch()},disabled:m,children:m?"Retrying":"Retry"})]})})}const B=w.settings.reduce((m,b)=>(m[Me(b)]+=1,m),{core:0,advanced:0}),le=new Set(W.map(m=>m.section)).size;return t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsx(pi,{query:r,onQueryChange:l,matchCount:r.trim()?W.length:null,matchSections:le,coreCount:B.core,advancedCount:B.advanced,modifiedCount:w.settings.filter(q).length,modifiedOnly:u,onModifiedOnlyChange:g,showAdvanced:d,onShowAdvancedChange:c,onExpandAll:()=>re(!0),onCollapseAll:()=>re(!1),unsavedCount:ge.length,savingAll:K,onSaveAll:()=>void p(),onDiscardAll:M}),D&&W.length===0&&t.jsx("div",{className:"flex flex-col items-center py-6 text-center",children:t.jsx("p",{className:"text-body-sm text-ink-muted",children:"No settings match this search. Clear the search field to see every setting again."})}),t.jsx("div",{className:"flex flex-col gap-1",children:ne.map(m=>{const b=ce(m.name),N=U(m.name),C=D?0:N.filter(F=>Me(F)==="advanced").length;if(D&&b.length===0)return null;const G=D?b.length>0&&!Q.has(m.name):O(m.name);return t.jsxs("section",{"data-settings-section":m.name,"data-open":G,className:"flex flex-col",children:[t.jsx(di,{title:m.title,rowCount:b.length,advancedCount:C,scope:gi[m.scope],modified:N.some(q),defaultOpen:G,onOpenChange:F=>D?oe(m.name,F):ae(m.name,F)},`${m.name}:${G?"open":"closed"}`),t.jsxs("div",{hidden:!G,className:"flex flex-col pb-3",children:[m.description&&t.jsx("p",{className:"px-1 pb-1 text-meta text-ink-dim",children:m.description}),b.length===0?t.jsxs("div",{className:"flex items-center gap-2 px-1 py-2",children:[t.jsx("p",{className:"text-body-sm text-ink-muted",children:C>0?"Advanced settings are hidden here.":"Nothing in this section matches."}),C>0&&t.jsxs($,{variant:"secondary",size:"sm",onClick:()=>c(!0),children:["Show ",C," advanced"]})]}):b.map(F=>t.jsx(mi,{setting:F,draft:x[F.key]??be(F),tier:Me(F),gate:te(F),effectiveHosting:ee,saving:!!f[F.key],error:E[F.key]??null,onDraftChange:ke=>y(je=>({...je,[F.key]:ke})),onSave:()=>void ve(F),onReset:()=>void me(F)},F.key))]})]},m.name)})})]})},vi=[[[".claude.json"],"Claude Code"],[[".claude",".mcp.json"],"Claude Code"],[[".cursor","mcp.json"],"Cursor"],[[".vscode","mcp.json"],"VS Code"],[[".codex","config.toml"],"Codex CLI"]];function Sn(e){if(!e)return null;const n=e.split("\\").join("/").split("/").filter(Boolean);for(const[a,s]of vi)if(!(n.length<a.length)&&n.slice(-a.length).join("/")===a.join("/"))return s;return null}const We=e=>`${e} ${e===1?"tool":"tools"}`,ki=e=>`${e} ${e===1?"integration":"integrations"}`,bi=["connected","needs_sign_in","not_started","connecting","error"],Cn=e=>bi.includes(e),Oe=(e,n)=>[...n].filter(a=>a.name===e&&a.status==="running").sort((a,s)=>s.created_at-a.created_at)[0]??null,wi={connectedAt:null,connectedToolCount:null,settledGroup:null,pinnedGroup:null,pinnedOperationId:null,needsKey:!1,needsSignIn:!1,disconnectedAt:null,holdUntil:null,lastDecisive:null},_i=1e12,ji=1e9,Ni=60*60*1e3,Mn=(e,n=Date.now())=>{if(typeof e!="number"||!Number.isFinite(e))return null;const a=e>=_i?e:e<ji?null:e*1e3;return a===null||a>n+Ni?null:Math.min(a,n)},Ae=(e,n)=>e?.[n]??wi,Ue=(e,n,a)=>Mi(e,n)??a?.lastDecisive??null,Si=e=>({id:e.id,name:e.name,action:e.action,status:e.status,created_at:e.created_at,credential_removed:e.credential_removed,...e.message?{message:e.message}:{}}),wt=(e,n)=>e.status==="not_started"&&typeof e.tool_count=="number"&&(n.connectedAt!==null||e.status_basis==="stored"&&e.tool_count_basis==="last_seen"),Ci=(e,n)=>[...n].filter(a=>a.name===e).sort((a,s)=>s.created_at-a.created_at)[0]??null,Mi=(e,n)=>Ci(e,n.filter(a=>a.status!=="cancelled")),Xe=e=>e.actions.includes("set_key")||e.actions.includes("add_key");function Ai(e,n){const a=Math.max(0,Math.round((e-n)/1e3));if(a<60)return"just now";const s=Math.round(a/60);if(s<60)return`${s} min ago`;const o=Math.round(s/60);return o<24?`${o} h ago`:`${Math.round(o/24)} d ago`}function st(e){if(!e)return null;const n=e.trim();if(!n||/^\/\w/.test(n)||/\/mcp\s+\w+/.test(n))return null;let a=n;for(let s=0;s<3;s+=1){const o=a.replace(/^(?:connection (?:closed|error|refused)|error|closed|failed)\s*:\s*/i,"").trim();if(o===a)break;a=o}return a=a.replace(/\s*\(\s*\d{3}\s*\)/g,"").replace(/\s+([.,;])/g,"$1").replace(/\s{2,}/g," ").trim(),a||null}function Ri(e,n=[],a,s=Date.now()){const o=Ae(a,e.name),r=Oe(e.name,n);if(r){if(r.action==="login"||r.action==="reauth")return{label:"Signing in…",tone:"info",detail:null,busy:!0};if(r.action==="logout")return{label:"Signing out…",tone:"info",detail:null,busy:!0}}if(!Cn(e.status))return{label:"Status unavailable",tone:"neutral",detail:null,busy:!1};const l=Ue(e.name,n,o),d=et(l)&&e.status!=="connected",c=wt(e,o),u=Nt(l)&&e.status!=="connected",g=(l?.action==="login"||l?.action==="reauth")&&l.status==="failed";if(o.disconnectedAt!==null)return{label:"Not connected",tone:"neutral",detail:null,busy:!1};switch(e.status){case"connected":return{label:typeof e.tool_count=="number"?`Connected · ${We(e.tool_count)}`:"Connected",tone:"success",detail:null,busy:!1};case"connecting":return{label:"Connecting…",tone:"info",detail:null,busy:!0};case"needs_sign_in":return{label:e.auth.kind==="api_key"||Ie(e,n,o)?"Needs a key":"Needs sign-in",tone:"warning",detail:st(e.status_reason),busy:!1};case"error":return{label:"Couldn't start",tone:"danger",detail:st(e.status_reason)??"No reason was given.",busy:!1};default:if(d)return{label:"Signed out",tone:"warning",detail:null,busy:!1};if(u)return{label:"Sign-out didn't finish",tone:"warning",detail:"The sign-in is still saved.",busy:!1};if(Ie(e,n,o))return{label:"Needs a key",tone:"warning",detail:null,busy:!1};if(g)return{label:"Sign-in didn't finish",tone:"warning",detail:null,busy:!1};if(o.needsSignIn)return{label:e.auth.kind==="api_key"||Ie(e,n,o)?"Needs a key":"Needs sign-in",tone:"warning",detail:st(e.status_reason),busy:!1};if(e.status_basis==="stored"&&c&&o.disconnectedAt===null){const x=o.connectedAt??Mn(e.last_seen_at,s);return{label:x!==null?`Worked ${Ai(s,x)} · ${We(e.tool_count)}`:`Worked earlier · ${We(e.tool_count)}`,tone:"success",detail:null,busy:!1}}return e.status_basis==="live"?{label:"Not connected",tone:"neutral",detail:null,busy:!1}:{label:"Ready",tone:"neutral",detail:null,busy:!1}}}const An=e=>e===1?"Replace the saved key":"Replace saved keys",Ti=/[,;]?\s*(?:or|and)?\s*add (?:its|a|the) key instead\.?\s*$/i;function Ei(e,n){const a=e?.trim()??"";if(!a)return null;if(n)return a;const s=a.replace(Ti,"").trim();return s?/\.$/.test(s)?s:`${s}.`:a}const Oi="Nothing is wrong. It starts when a chat uses it.",Li="Not running in this chat.",Ii=e=>e.transport==="local_command"?"Local command":"Remote URL";function Rn(e){switch(e.source.kind){case"local-operator":case"project-mcp-json":return null;case"claude-code":return"Claude Code";case"cursor":return"Cursor";case"vscode":return"VS Code";case"codex":return"Codex CLI";default:return Sn(e.source.path)}}function Fi(e,n){const a=[Ii(e)];e.status!=="connected"&&e.tool_count_basis==="last_seen"&&typeof e.tool_count=="number"&&a.push(`${We(e.tool_count)} when last checked`),n&&a.push(e.scope==="project"?"This project":"Global");const s=Rn(e);return s?a.push(`Imported from ${s}`):e.source.editable||a.push("Imported from a project file"),a}const _t=(e,n)=>n.disconnectedAt!==null?"not_started":e.status;function jt(e,n=[],a){const s=Ae(a,e.name),o=Oe(e.name,n);if(o)return o.action==="login"||o.action==="reauth"?{kind:"sign_in",label:"Continue sign-in"}:null;const r=g=>e.actions.includes(g),l=Xe(e),d=Ie(e,n,s);if(!Cn(e.status))return r("test")?{kind:"test",label:"Check again"}:null;const c=Ue(e.name,n,s),u=c?.status==="failed"&&ze(c);switch(_t(e,s)){case"connected":case"connecting":return null;case"needs_sign_in":return d?{kind:"set_key",label:"Add key"}:r("sign_in")?{kind:"sign_in",label:"Sign in"}:l?{kind:"set_key",label:"Add key"}:r("reauth")?{kind:"reauth",label:"Sign in again"}:{kind:"fix",label:"Fix"};case"error":return r("connect")?{kind:"connect",label:"Reconnect"}:r("test")?{kind:"test",label:"Retry"}:{kind:"fix",label:"Fix"};default:{if(et(c)&&r("sign_in"))return{kind:"sign_in",label:"Sign in"};if(Nt(c)&&r("sign_out"))return{kind:"sign_out",label:"Sign out again"};if(s.disconnectedAt!==null&&r("connect"))return{kind:"connect",label:"Connect"};if(s.needsSignIn){if(d&&l)return{kind:"set_key",label:"Add key"};if(r("sign_in"))return{kind:"sign_in",label:"Sign in"}}return d&&l?{kind:"set_key",label:"Add key"}:u&&r("sign_in")?{kind:"sign_in",label:"Try again"}:wt(e,s)&&!r("connect")?null:r("connect")?{kind:"connect",label:"Connect",...s.connectedAt===null&&e.status_basis!=="live"?{variant:"ghost"}:{}}:r("test")&&e.tool_count===null&&e.tool_count_basis===null?{kind:"test",label:"Test",variant:"ghost"}:null}}}const ze=e=>e.action==="login"||e.action==="reauth",et=e=>!!(e&&e.action==="logout"&&e.status==="complete"),Nt=e=>!!(e&&e.action==="logout"&&e.status!=="running"&&e.status!=="complete"),Tn=/no oauth authorization server/i;function Ie(e,n,a){if(!Xe(e))return!1;const s=Ue(e.name,n,a);return s&&ze(s)&&s.status==="failed"&&Tn.test(s.message??"")?!0:a.needsKey}function $i(e,n=[],a){const s=jt(e,n,a)?.kind,o=_t(e,Ae(a,e.name)),r=c=>e.actions.includes(c),l=[],d=Oe(e.name,n);if(d&&l.push({kind:"cancel",label:"Cancel"}),!d&&r("test")&&s!=="test"&&l.push({kind:"test",label:"Test connection"}),r("connect")&&s!=="connect"&&o!=="connected"&&l.push({kind:"connect",label:"Reconnect"}),!d&&r("sign_in")&&s!=="sign_in"&&o!=="connected"&&l.push({kind:"sign_in",label:"Sign in"}),r("reload")&&l.push({kind:"reload",label:"Reload"}),!d&&r("reauth")&&s!=="reauth"&&l.push({kind:"reauth",label:"Sign in again"}),Xe(e)&&s!=="set_key"&&l.push({kind:"set_key",label:e.auth.secret_refs.length>0?"Update key":"Add key"}),r("sign_out")&&l.push({kind:"sign_out",label:"Sign out"}),r("disconnect")&&o==="connected"&&l.push({kind:"disconnect",label:"Disconnect"}),r("copy_setup")&&e.setup_prompt&&l.push({kind:"copy_setup",label:"Copy setup prompt"}),s!=="fix"&&l.push({kind:"open_config",label:"Open config file"}),r("remove"))l.push({kind:"remove",label:"Remove",destructive:!0});else if(!e.source.editable){const c=Rn(e);l.push({kind:"remove_elsewhere",label:c?`Remove in ${c}`:"Remove in its own file",hint:c?`Defined in ${c}'s config. Remove it there.`:"Defined in a file this app doesn't write. Remove it there."})}return l}const Di={attention:"Needs attention",connected:"Connected",ready:"Available"};function En(e,n=[],a){const s=Ae(a,e.name),o=Oe(e.name,n),r=_t(e,s);if(o&&s.pinnedGroup&&s.pinnedOperationId===o.id)return s.pinnedGroup;if(r==="needs_sign_in"||r==="error")return"attention";const l=Ue(e.name,n,s);return et(l)&&r!=="connected"||Nt(l)&&r!=="connected"?"attention":s.disconnectedAt!==null?"ready":Ie(e,n,s)||s.needsSignIn&&r!=="connected"||l?.status==="failed"&&ze(l)&&r!=="connected"?"attention":r==="connected"||e.status_basis==="stored"&&wt(e,s)?"connected":o&&o.action!=="test"?"attention":"ready"}function Ui(e,n=[],a){return["attention","connected","ready"].map(o=>({id:o,title:Di[o],rows:e.filter(r=>En(r,n,a)===o)})).filter(o=>o.rows.length>0)}function zi(e,n,a=Date.now()){if(!n)return e??{};const s={};for(const o of n.servers){const r=Ae(e,o.name),l=Oe(o.name,n.operations),d=Ue(o.name,n.operations,r),c=et(d),u=o.status==="connected"&&(o.status_basis==="probe"||o.status_basis==="live"),g=r.holdUntil!==null&&a<r.holdUntil,x=!g&&!c&&r.connectedAt===null&&o.status_basis==="stored"&&o.tool_count_basis==="last_seen"?Mn(o.last_seen_at,a):null,y=!c,f=d?.status==="failed"&&ze(d)&&Tn.test(d.message??""),k={connectedAt:u&&!g?a:x!==null?x:y?r.connectedAt:null,connectedToolCount:u&&!g||x!==null?o.tool_count??r.connectedToolCount:y?r.connectedToolCount:null,settledGroup:r.settledGroup,pinnedGroup:l&&r.pinnedOperationId===l.id?r.pinnedGroup:l?r.settledGroup:null,pinnedOperationId:l?l.id:null,needsKey:u?!1:r.needsKey||f,needsSignIn:u||c?!1:r.needsSignIn||o.status==="needs_sign_in",disconnectedAt:u&&!g?null:r.disconnectedAt,holdUntil:g?r.holdUntil:null,lastDecisive:d?Si(d):null};l||(k.settledGroup=En(o,n.operations,{...s,[o.name]:k})),s[o.name]=k}return s}const Pi=(e,n)=>e!==null&&n===e,ht="local-operator.settings.integrations.row-memory",On=(e,n)=>`${e}#${n}`;function Bi(e,n){const a={};if(!n)return a;for(const s of n.servers){const o=e[s.name];o&&(a[On(s.source.path,s.name)]=o)}return a}function Hi(e,n,a){if(!n)return e;let s=null;for(const o of n.servers){if(Object.prototype.hasOwnProperty.call(e,o.name))continue;const r=qi(a[On(o.source.path,o.name)]);r&&(s=s??{...e},s[o.name]=r)}return s??e}const Ki=["attention","connected","ready"],Ln=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),St=e=>typeof e=="number"&&Number.isFinite(e)?e:null,Vt=e=>Ki.includes(e)?e:null,ot=e=>{const n=St(e);return n!==null&&n>=1e12?n:null};function Gi(e){if(!Ln(e)||typeof e.id!="string"||typeof e.name!="string")return null;const n=e.action,a=e.status;return n!=="login"&&n!=="logout"&&n!=="reauth"&&n!=="test"||a!=="running"&&a!=="complete"&&a!=="cancelled"&&a!=="failed"?null:{id:e.id,name:e.name,action:n,status:a,created_at:St(e.created_at)??0,credential_removed:e.credential_removed===!0,...typeof e.message=="string"?{message:e.message}:{}}}function qi(e){if(!Ln(e))return null;const n=ot(e.connectedAt),a=ot(e.disconnectedAt),s=e.needsKey===!0,o=e.needsSignIn===!0,r=Gi(e.lastDecisive);return n===null&&a===null&&!s&&!o&&!r?null:{connectedAt:n,connectedToolCount:St(e.connectedToolCount),settledGroup:Vt(e.settledGroup),pinnedGroup:Vt(e.pinnedGroup),pinnedOperationId:typeof e.pinnedOperationId=="string"?e.pinnedOperationId:null,needsKey:s,needsSignIn:o,disconnectedAt:a,holdUntil:ot(e.holdUntil),lastDecisive:r}}const In=2e3,Yt=8e3;function Vi(e){return e&&(e.servers.some(a=>a.status==="connecting")||e.operations.some(a=>a.status==="running"))?In:!1}const Yi=/^[A-Za-z0-9_.:-]{1,100}$/,Wi=/:\/\//;function Qi(e,n){const a=e.trim();return a?Yi.test(a)?n.includes(a)?`An integration named ${a} already exists.`:null:"Use letters, numbers, dots, dashes, underscores or colons, with no spaces.":"Give it a name."}function Zi(e){const n=e.trim();if(!n)return"Enter the server's URL.";let a;try{a=new URL(n)}catch{return"Enter a full URL, like https://mcp.example.com/mcp."}return a.protocol!=="https:"&&a.protocol!=="http:"?"The URL must start with https:// or http://.":a.hostname?a.username||a.password?"Remove the username or password from the URL. Keys are added after it's saved.":a.search||a.hash?"Remove the ? or # part of the URL. Keys are added after it's saved.":Wi.test(n.slice(a.protocol.length+2))?"This looks like two URLs pasted together. Enter just one.":null:"The URL needs a host name."}const Ji=e=>e.split(`
|
|
307
|
-
`).map(n=>n.trim()).filter(Boolean);function pt(e,n){const a=!!e?.cold,s=(e?.servers??[]).map(o=>{const r=o.transport==="http",l=o.secret_refs??[],d=o.status==="connected"?"connected":o.status==="connecting"?"connecting":o.status==="auth-required"?"needs_sign_in":"not_started",c=[];d!=="connected"&&c.push("connect"),d==="connected"&&c.push("disconnect"),a||c.push("reload"),r&&o.transport_oauth_supported!==!1&&c.push("sign_in"),l.length>0&&c.push("set_key"),o.owned_scope&&c.push("remove"),o.setup?.text&&c.push("copy_setup");const u=Sn(o.source);return{id:o.name,name:o.name,scope:o.owned_scope??"global",project_cwd:null,source:{kind:Xi(o.source,u,o.owned_scope),path:o.source??"",editable:o.owned_scope!==null,owned_scope:o.owned_scope},transport:r?"remote_url":"local_command",endpoint:{command:null,url:null,endpoint_redacted:!1},status:d,status_reason:null,status_observed_at:null,last_seen_at:null,status_basis:a?"stored":"live",auth:{kind:l.length?"api_key":r?"unknown":"none",signed_in:null,secret_refs:l.map(g=>({id:g.id,state:"missing"}))},tool_count:typeof o.tool_count=="number"?o.tool_count:null,tool_count_basis:typeof o.tool_count=="number"?"live":null,actions:c,setup_prompt:o.setup?.text??null}});return{cwd:"",project_scope_available:s.some(o=>o.source.owned_scope==="project"),global_path:"",project_path:null,status_source:a?"config":"live",session_id:n,servers:s,operations:(e?.operations??[]).map(o=>({...o}))}}const Xi=(e,n,a)=>n==="Claude Code"?"claude-code":n==="Cursor"?"cursor":n==="VS Code"?"vscode":n==="Codex CLI"?"codex":a?"local-operator":e?"project-mcp-json":"local-operator",Wt={invalid_config:"That configuration isn't valid. Check the command or the URL, then try again.",operation_unavailable:"That sign-in or test isn't running any more. Try again.",exists:"An integration with this name already exists. Choose another name.",not_owned:"It's defined in another tool's config, so it can't be changed here. Edit it in that file.",project_scope_unavailable:"There's no separate project config here, so it can only be added globally.",unknown_server:"It no longer exists. The list has been refreshed.",oauth_unsupported:"It doesn't use browser sign-in.",grant_running:"A sign-in or test is already running. Wait for it to finish, or cancel it.",too_many_operations:"Too many sign-ins and tests are waiting. Try again in a moment.",write_failed:"The config file couldn't be written. Check that it isn't read-only.",mcp_starting:"Integrations are still starting. Try again in a moment.",mcp_control_refused:"The server refused it, so nothing was changed."},ec="The server refused it, so nothing was changed. Try again.";function Ge(e,n,a){if(n instanceof vt&&n.status===409){const s=typeof n.code=="string"&&Object.prototype.hasOwnProperty.call(Wt,n.code)?Wt[n.code]:ec;return`${ra[e]}. ${s}`}return ia(e,n,a).message}const tc="New chats can use it right away. Open chats pick it up when you start a new chat or reload integrations there.",nc="Most services give you a URL. Use Local command when their setup says npx or uvx.",ac=({existingNames:e,projectScopeAvailable:n,projectLabel:a,onSubmit:s,onCancel:o,initial:r})=>{const[l,d]=i.useState(r?.name??""),[c,u]=i.useState(r?.mode??"command"),[g,x]=i.useState(r?.command??""),[y,f]=i.useState(r?.args??""),[k,E]=i.useState(r?.url??""),[R,K]=i.useState("global"),[_,V]=i.useState(r?.touched?{name:!0,command:!0,url:!0}:{}),[z,L]=i.useState(!!r?.touched),[T,Q]=i.useState(!1),[I,X]=i.useState(null),Z=i.useRef(null),P=i.useRef(null),w=i.useRef(null);i.useEffect(()=>{Z.current?.focus()},[]);const q=Qi(l,e),ee=c==="command"&&!g.trim()?"Enter the command to run.":null,W=c==="url"?Zi(k):null,D=O=>z||_[O],ne=async O=>{if(O.preventDefault(),L(!0),q||ee||W){q?Z.current?.focus():ee?P.current?.focus():w.current?.focus();return}Q(!0),X(null);const ae=n?R:"global",oe=c==="command"?{name:l.trim(),scope:ae,mode:c,command:g.trim(),args:Ji(y)}:{name:l.trim(),scope:ae,mode:c,url:k.trim()},re=await s(oe);Q(!1),X(re)},U=(O,ae,oe)=>ae&&D(oe)?t.jsx("p",{id:O,className:"text-body-sm text-danger",children:ae}):null,ce=O=>O.preventDefault();return t.jsxs("form",{noValidate:!0,"aria-label":"Add integration",className:"flex flex-col gap-4 rounded-lg bg-surface p-4",onSubmit:O=>void ne(O),onKeyDown:O=>{O.key==="Escape"&&(O.stopPropagation(),o())},children:[t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsx(we,{htmlFor:"integration-add-name",children:"Name"}),t.jsx(ye,{ref:Z,id:"integration-add-name",value:l,placeholder:"e.g. notion",autoComplete:"off","aria-invalid":!!(q&&D("name")),"aria-describedby":q&&D("name")?"integration-add-name-error":void 0,onChange:O=>d(O.target.value),onBlur:()=>V(O=>({...O,name:!0}))}),U("integration-add-name-error",q,"name")]}),t.jsxs(Dt,{value:c,onValueChange:O=>u(O==="url"?"url":"command"),className:"flex flex-col gap-1.5",children:[t.jsx("span",{id:"integration-add-transport-label",className:"font-medium text-body-sm text-ink",children:"How it runs"}),t.jsxs(Ut,{"aria-labelledby":"integration-add-transport-label",children:[t.jsx(Ke,{value:"command","data-integration-transport":"command",children:"Local command"}),t.jsx(Ke,{value:"url","data-integration-transport":"url",children:"Remote URL"})]}),t.jsx("p",{className:"text-ink-dim text-meta",children:nc}),t.jsxs(zt,{value:"command",className:"mt-0 flex flex-col gap-4",children:[t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsx(we,{htmlFor:"integration-add-command",children:"Command"}),t.jsx(ye,{ref:P,id:"integration-add-command",value:g,placeholder:"e.g. npx",autoComplete:"off",className:"font-mono","aria-invalid":!!(ee&&D("command")),"aria-describedby":ee&&D("command")?"integration-add-command-error":void 0,onChange:O=>x(O.target.value),onBlur:()=>V(O=>({...O,command:!0}))}),U("integration-add-command-error",ee,"command")]}),t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsxs(we,{htmlFor:"integration-add-args",children:["Arguments"," ",t.jsx("span",{className:"font-normal text-ink-dim",children:"(one per line)"})]}),t.jsx(Je,{id:"integration-add-args",value:y,rows:2,className:"font-mono",onChange:O=>f(O.target.value)})]})]}),t.jsx(zt,{value:"url",className:"mt-0 flex flex-col gap-4",children:t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsx(we,{htmlFor:"integration-add-url",children:"URL"}),t.jsx(ye,{ref:w,id:"integration-add-url",type:"url",value:k,placeholder:"https://mcp.example.com/mcp",autoComplete:"off",className:"font-mono","aria-invalid":!!(W&&D("url")),"aria-describedby":W&&D("url")?"integration-add-url-error":"integration-add-url-help",onChange:O=>E(O.target.value),onBlur:()=>V(O=>({...O,url:!0}))}),U("integration-add-url-error",W,"url")??t.jsx("p",{id:"integration-add-url-help",className:"text-ink-dim text-meta",children:"If it needs a sign-in or a key, you'll be asked after it's added."})]})})]}),n?t.jsxs(Dt,{value:R,onValueChange:O=>K(O==="project"?"project":"global"),className:"flex flex-col gap-1.5",children:[t.jsx("span",{id:"integration-add-scope-label",className:"font-medium text-body-sm text-ink",children:"Available in"}),t.jsxs(Ut,{"aria-labelledby":"integration-add-scope-label",children:[t.jsx(Ke,{value:"global","data-integration-scope":"global",children:"All chats"}),t.jsx(Ke,{value:"project","data-integration-scope":"project",children:"This project"})]}),a?t.jsx("p",{className:"text-ink-dim text-meta",children:R==="project"?`Only chats working in ${a}.`:"Every chat, in any folder."}):null]}):null,I?t.jsx("p",{className:"text-body-sm text-danger",role:"alert",children:I}):null,t.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[t.jsx("p",{className:se("text-body-sm text-ink-dim"),children:tc}),t.jsxs("div",{className:"flex gap-2",children:[t.jsx($,{type:"button",variant:"ghost",size:"md",onMouseDown:ce,onClick:o,children:"Cancel"}),t.jsxs($,{type:"submit",variant:"primary",size:"md",disabled:T,onMouseDown:ce,children:[T?t.jsx(ue,{size:"xs"}):null,"Add integration"]})]})]})]})},sc=4;function oc(e){return e.rowMoving?e.now+e.windowMs:Math.max(e.hold.until,e.lastMovingAt+e.windowMs)}function rc(e){return e.now>e.hold.until||e.hold.reanchors>=sc?"drop":e.hold.landedOn.isConnected&&(!e.candidate||e.candidate===e.hold.landedOn)?"settled":e.active&&e.active!==e.body&&e.active!==e.hold.landedOn?"drop":e.candidate?.isConnected?"restore":"drop"}function ic(e){const n=oc({hold:e.hold,now:e.now,windowMs:e.windowMs,rowMoving:e.rowMoving,lastMovingAt:e.lastMovingAt});if(e.now>n)return{hold:null,land:null};const a=e.hold.landedOn??null,s=e.candidate;if(!s)return{hold:{until:n,reanchors:e.hold.reanchors,landedOn:a},land:null};if(!a)return{hold:{until:n,reanchors:e.hold.reanchors,landedOn:s},land:s};const o=rc({hold:{until:n,reanchors:e.hold.reanchors,landedOn:a},candidate:s,active:e.active,body:e.body,now:e.now});if(o==="settled")return{hold:{until:n,reanchors:e.hold.reanchors,landedOn:a},land:null};if(o==="drop")return{hold:null,land:null};const r=!a.isConnected;return{hold:{until:r?e.now+e.windowMs:n,reanchors:r?e.hold.reanchors+1:e.hold.reanchors,landedOn:s},land:s}}function cc(e){const{row:n,target:a}=e;return!n||!a||typeof a.nodeType!="number"?!1:!n.contains(a)}const Qt=250;function Zt(e){return e?!e.disabled:!1}function lc(e){return Zt(e.primary)?e.primary??null:Zt(e.overflow)?e.overflow??null:null}function dc(e){return e.verdict==="finished"?null:e.watchMs}const Fn="key";function uc(e){const{name:n,keyless:a,freeName:s,names:o,values:r,replace:l,canReplace:d}=e;if(a){const c=ft(n,s);return{values:{[c]:(r[Fn]??"").trim()},confirmedReplace:l&&d?[c]:[],header:s.trim()}}return{values:Object.fromEntries(o.map(c=>[c,(r[c]??"").trim()])),confirmedReplace:l&&d?o:[],header:void 0}}function ft(e,n){const a=Jt(e),s=Jt(n);if(!s)return"";const o=[a,s].filter(Boolean).join("_"),r=/^[A-Za-z_]/.test(o)?o:`K_${o}`;if(r.length<=rt)return r;const l=mc(a),d=rt-s.length-l.length-2,c=[a.slice(0,Math.max(d,0)),l,s].filter(Boolean).join("_");return c.length<=rt?c:c.slice(-128)}const rt=128,Jt=e=>e.trim().toUpperCase().replace(/[^A-Z0-9]+/g,"_").replace(/^_+|_+$/g,""),mc=e=>{let n=2166136261;for(let a=0;a<e.length;a+=1)n^=e.charCodeAt(a),n=Math.imul(n,16777619)>>>0;return n.toString(36).toUpperCase().slice(0,5)},hc=({name:e,keyNames:n,keyless:a=!1,savedKeys:s=[],saving:o,failure:r,onSave:l,onClose:d})=>{const[c,u]=i.useState({}),[g,x]=i.useState(!1),[y,f]=i.useState(""),k=a?[ft(e,y)]:[...n],E=a?[Fn]:k,R=(a?ft(e,y).length>0:!0)&&E.every(_=>(c[_]??"").trim()),K=k.some(_=>s.includes(_));return t.jsx(hn,{open:!0,onClose:d,maxWidth:"xs",title:a||n.length===1?`Add the key for ${e}`:`Add keys for ${e}`,actions:t.jsxs(t.Fragment,{children:[t.jsx(ct,{onClick:d,children:"Cancel"}),t.jsx(lt,{disabled:!R||o,onClick:()=>{const _=uc({name:e,keyless:a,freeName:y,names:k,values:c,replace:g,canReplace:K});l(_.values,_.confirmedReplace,_.header)},children:o?"Saving…":"Save and test"})]}),children:t.jsxs("div",{className:"flex flex-col gap-3 p-1.5 text-body text-ink-muted",children:[t.jsx("p",{className:"-mx-1.5",children:a?"Keys are saved encrypted on this computer. This one is stored under a name derived from this integration, so no other server shares it.":"Keys are saved encrypted on this computer. Other integrations that use the same key name share it."}),a?t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsx(we,{htmlFor:"integration-key-name",children:"The header this server wants the key in"}),t.jsx(ye,{id:"integration-key-name",autoComplete:"off",placeholder:"e.g. Authorization or X-Api-Key",value:y,onChange:_=>f(_.target.value)}),t.jsx("p",{className:"-mx-1.5 text-ink-dim text-meta",children:"This server declares no key of its own, so Local Operator adds one to its config for you."})]}):null,E.filter(_=>a!==!0||_.trim().length>0).map(_=>t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsx(we,{htmlFor:`integration-key-${_}`,className:"font-mono",children:a?"Key":_}),t.jsx(ye,{id:`integration-key-${_}`,type:"password",autoComplete:"off",value:c[_]??"",onChange:V=>u(z=>({...z,[_]:V.target.value}))})]},_)),K?t.jsxs("div",{className:"flex items-center gap-2 text-body-sm",children:[t.jsx(Za,{id:"integration-key-replace",checked:g,onCheckedChange:_=>x(_===!0)}),t.jsx(we,{htmlFor:"integration-key-replace",className:"font-normal",children:An(k.length)})]}):null,r?t.jsx("p",{className:"-mx-1.5 text-body-sm text-danger",role:"alert",children:r}):null]})})},pc={success:"bg-success",warning:"bg-warning",danger:"bg-danger",info:"bg-info",neutral:"bg-ink-dim"},fc={success:"text-ink-muted",warning:"text-warning",danger:"text-danger",info:"text-ink-muted",neutral:"text-ink-dim"},Xt={Ready:Oi,"Not connected":Li},gc=({row:e,operations:n,memories:a,now:s,projectScopeAvailable:o,highlighted:r=!1,rowRef:l,primaryRef:d,overflowRef:c,pending:u,failure:g,confirm:x,onPrimary:y,onOverflow:f,onConfirm:k,onCancelConfirm:E})=>{const R=Ri(e,n,a,s),K=r&&R.tone==="danger"?"text-ink":fc[R.tone],_=jt(e,n,a),V=$i(e,n,a),z=Fi(e,o),L=V.findIndex(T=>T.kind==="remove"||T.kind==="remove_elsewhere");return t.jsxs("li",{ref:l,"data-integration":e.name,"data-status":e.status,className:se("flex min-h-14 flex-col justify-center gap-1 px-4 py-2.5",r&&"bg-row-selected"),onKeyDown:T=>{!x||T.key!=="Escape"||(T.stopPropagation(),E())},children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("span",{className:"flex size-4 shrink-0 items-center justify-center",children:R.busy?t.jsx(ue,{size:"xs"}):t.jsx("span",{"aria-hidden":"true","data-tone":R.tone,className:se("size-2 rounded-full",pc[R.tone])})}),t.jsxs("div",{className:"flex min-w-0 flex-1 flex-col",children:[t.jsx("span",{className:"truncate font-medium text-body text-ink",title:e.name,children:e.name}),t.jsx("span",{className:"truncate text-ink-dim text-meta",children:z.map((T,Q)=>t.jsxs("span",{children:[Q>0?" · ":null,T.startsWith("Imported from")&&e.source.path?t.jsx($e,{content:ca(e.source.path),children:t.jsx("span",{className:"underline decoration-dotted underline-offset-2",children:T})}):T]},T))})]}),Xt[R.label]?t.jsx($e,{content:Xt[R.label],children:t.jsx("span",{className:se("shrink-0 text-body-sm",K),children:R.label})}):t.jsx("span",{className:se("shrink-0 text-body-sm",K),children:R.label}),_?t.jsxs($,{ref:d,variant:_.variant??"secondary",size:"sm","aria-label":`${_.label} ${e.name}`,disabled:u,"data-integration-action":_.kind,onClick:()=>y(_),children:[u?t.jsx(ue,{size:"xs"}):null,_.label]}):null,t.jsxs(Ja,{children:[t.jsx(Xa,{asChild:!0,children:t.jsx($,{ref:c,variant:"ghost",size:"icon-sm","aria-label":`More actions for ${e.name}`,disabled:u,children:t.jsx(la,{"aria-hidden":"true"})})}),t.jsx(es,{align:"end",className:"min-w-48",children:V.map((T,Q)=>t.jsx(xc,{item:T,separated:Q===L&&Q>0,onSelect:()=>f(T)},T.kind))})]})]}),R.detail?t.jsx("p",{className:se("pl-7 text-body-sm",R.tone==="danger"?"text-ink-muted":"text-ink-dim"),children:R.detail}):null,g?t.jsx("p",{className:se("pl-7 text-body-sm",r?"text-ink":"text-danger"),role:"alert",children:g}):null,x?t.jsxs("div",{className:"flex flex-wrap items-center gap-2 pl-7",children:[t.jsx("span",{className:"text-body-sm text-ink",children:x.kind==="remove"?`Remove ${e.name}?`:`Sign out of ${e.name}?`}),t.jsx("span",{className:"text-body-sm text-ink-muted",children:x.kind==="remove"?`Agents in every chat lose access to ${e.name}.`:e.auth.kind==="oauth"?"The saved sign-in is removed too.":"Its saved credential is removed too."}),t.jsx($,{variant:"danger",size:"sm",onClick:k,"data-integration-confirm":x.kind,children:x.kind==="remove"?"Remove":"Sign out"}),t.jsx($,{variant:"ghost",size:"sm",onClick:E,children:"Keep"})]}):null]})},xc=({item:e,separated:n,onSelect:a})=>t.jsxs(t.Fragment,{children:[n?t.jsx(ts,{}):null,e.kind==="remove_elsewhere"?t.jsxs(Pt,{disabled:!0,className:"flex-col items-start gap-0.5",children:[t.jsx("span",{children:e.label}),t.jsx("span",{className:"text-meta text-ink-dim",children:e.hint})]}):t.jsx(Pt,{destructive:e.kind==="remove",onSelect:a,"data-integration-menu":e.kind,children:e.label})]});function yc(e,n,a){return!n||n.status==="running"?n?.browser_opened===!0?{message:`Your browser opened. Approve access to ${e} there, then come back here.`,tone:"progress",link:n.authorization_url??null}:n?.browser_opened===!1?{message:n.authorization_url?"Your browser didn't open. Open this link to approve access:":"Your browser didn't open, and no link was provided. Cancel and try again.",tone:"progress",link:n.authorization_url??null}:{message:`Waiting for you to approve access to ${e}…`,tone:"progress",link:n?.authorization_url??null}:n.status==="complete"?{message:`Signed in to ${e}. Agents can use it now.`,tone:"success",link:null}:n.status==="cancelled"?{message:"Sign-in cancelled.",tone:"failure",link:null,reason:null,nextStep:"Press Try again when you are ready."}:{message:"Sign-in didn't finish.",tone:"failure",link:null,reason:Ei(n.message,a)??"The server didn't say why.",nextStep:vc(n.message??null,a)}}function vc(e,n){const a=(e??"").toLowerCase();return a.includes("redirect")?n?"This server may not accept sign-ins from Local Operator. Check the server's settings, or add a key instead.":"This server may not accept sign-ins from Local Operator. Check the server's settings, then try again.":a.includes("no oauth")||a.includes("authorization server")?n?"This server doesn't publish a browser sign-in. Add its key instead.":"This server doesn't publish a browser sign-in. Check the server's settings, then try again.":a.includes("network")||a.includes("connect")?"Check the server's URL and your network, then try again.":"Check the server's settings, then try again."}function kc(e,n){return e.kind==="ready"?"ready":e.kind==="running"&&n&&n.tone!=="progress"?n.tone==="success"?"success":"failure":"running"}const bc=({name:e,action:n,keyRoute:a,phase:s,onStart:o,onCancel:r,onOpenLink:l,onClose:d})=>{const c=s.kind==="running"?s.operation:null,u=s.kind==="running"?yc(e,c,a):null,g=s.kind==="starting"||s.kind==="running"&&u?.tone==="progress",x=u&&u.tone!=="progress",y=i.useRef(null),f=i.useRef(!1),k=kc(s,u);i.useEffect(()=>{if(!f.current){f.current=!0;return}k&&y.current?.focus()},[k]);const E=()=>d(u?.tone==="success"?"signed-in":"dismissed");return t.jsx(hn,{open:!0,onClose:E,maxWidth:"xs",fullWidth:!0,title:`Sign in to ${e}`,dialogProps:{onOpenAutoFocus:R=>{R.preventDefault(),y.current?.focus()}},actions:t.jsxs(t.Fragment,{children:[g&&c?t.jsx(ct,{ref:y,onClick:()=>r(c.id),children:"Cancel sign-in"}):t.jsx(ct,{ref:s.kind==="ready"?void 0:y,onClick:E,children:u?.tone==="success"?"Done":"Close"}),s.kind==="ready"?t.jsx(lt,{ref:y,onClick:o,children:"Continue in browser"}):null,s.kind==="refused"||u?.tone==="failure"?t.jsx(lt,{ref:u?.tone==="failure"?y:void 0,onClick:o,children:"Try again"}):null]}),children:t.jsxs("div",{className:"flex flex-col gap-3 p-1.5 text-body text-ink-muted","aria-live":"polite",children:[s.kind==="ready"?t.jsxs("p",{className:"-mx-1.5",children:["Local Operator opens your browser so you can approve access to"," ",e,".",n==="reauth"?" This replaces the sign-in it has now.":""]}):null,s.kind==="starting"?t.jsxs("p",{className:"-mx-1.5 flex items-center gap-2",children:[t.jsx(ue,{size:"xs"}),"Starting sign-in…"]}):null,u?t.jsxs("div",{className:"flex flex-col gap-1",role:x?"status":void 0,children:[t.jsxs("p",{className:(u.tone==="success","-mx-1.5 flex items-start gap-2 text-ink"),children:[u.tone==="progress"?t.jsx(ue,{size:"xs",className:"mt-0.5"}):null,u.tone==="failure"?t.jsx(ns,{"aria-hidden":"true",className:"mt-0.5 size-4 shrink-0 text-danger"}):null,t.jsx("span",{children:u.message})]}),u.reason?t.jsx("p",{className:"-mx-1.5 text-ink-muted",children:u.reason}):null,u.nextStep?t.jsx("p",{className:"-mx-1.5 text-ink-muted",children:u.nextStep}):null]}):null,u?.link&&u.tone==="progress"?t.jsxs("div",{className:"flex flex-col items-start gap-1",children:[t.jsxs("div",{className:"flex w-full min-w-0 items-center gap-1",children:[t.jsx("span",{className:"min-w-0 flex-1 truncate font-mono text-ink-dim text-mono-sm",title:u.link,children:u.link}),t.jsx($,{variant:"ghost",size:"icon-sm","aria-label":"Copy the sign-in link",title:"Copy the sign-in link",onClick:()=>{navigator.clipboard.writeText(u.link??"").then(()=>dt("Sign-in link copied.")).catch(()=>{})},children:t.jsx(da,{"aria-hidden":"true"})})]}),t.jsx($,{variant:"link",size:"sm",onClick:()=>l(u.link??""),children:"Open the sign-in page"})]}):null,s.kind==="refused"?t.jsx("p",{className:"text-danger",role:"alert",children:s.message}):null]})})},wc={catalog:(e,n)=>["desktop","mcp-catalog",e??"",n??""],all:["desktop","mcp-catalog"]},_c=async(e,n)=>(await fe({op:"mcp.catalog",...e?{cwd:e}:{},...n?{sessionId:n}:{}})).data,jc=async(e,n)=>(await fe({op:"mcp.catalog.control",...e?{cwd:e}:{},control:n})).data,Nc=async(e,n,a,s,o)=>(await fe({op:"mcp.catalog.credentials",...e?{cwd:e}:{},name:n,values:a,confirmedReplace:s,...o?{header:o}:{}})).data,Sc=e=>e.reduce((n,a)=>n?(a.updated_at??0)>(n.updated_at??0)?a:n:a,null),Cc=/^[A-Za-z]:[\\/]/,Qe=e=>{const n=e?.trim();return n&&(n.startsWith("/")||Cc.test(n))?n:null};function Mc(e){const o=e?.payload?.frontend?.snapshot?.cwd;return typeof o=="string"&&o.trim()?o:null}const De="local-operator.settings.integrations.last-cwd";function Ac(e,n,a=typeof localStorage>"u"?null:localStorage){const s=Qe(n);if(!(!e||!s||!a))try{const o=a.getItem(De),r=o?JSON.parse(o):{};if(r[e]===s)return;a.setItem(De,JSON.stringify({...r,[e]:s}))}catch{}}const $n=()=>typeof localStorage>"u"?null:localStorage;function Dn(e=$n()){if(!e)return{};try{const n=e.getItem(ht);if(!n)return{};const a=JSON.parse(n);return!a||typeof a!="object"||Array.isArray(a)?{}:a}catch{return{}}}const en=256;function Rc(e,n=$n()){if(n)try{const a={...Dn(n),...e},s=Object.keys(a);if(s.length>en){const o={};for(const r of s.slice(-en))o[r]=a[r];n.setItem(ht,JSON.stringify(o));return}n.setItem(ht,JSON.stringify(a))}catch{}}function tn(e,n,a){return e==="saved"?null:e==="replace_confirmation_required"?`A saved value already exists for this key. Tick “${An(Object.keys(a).length)}” to overwrite it.`:e==="invalid_target"?"That header can't carry this key. It may already be set on the server, or belong to the transport - try a different header name. Nothing was saved.":`Not saved: ${(n.length?n:Object.keys(a)).join(", ")}. The encrypted store may be locked.`}function Tc(e,n=typeof localStorage>"u"?null:localStorage){if(!(!e||!n))try{const a=n.getItem(De);if(!a)return;const s=JSON.parse(a);if(!(e in s))return;const o={...s};delete o[e],n.setItem(De,JSON.stringify(o))}catch{}}const Ec=e=>!!(e&&typeof e=="object"&&"code"in e&&e.code==="invalid_cwd"),Oc=(e,n)=>n!==null&&e===n?null:e;function Lc(e,n=typeof localStorage>"u"?null:localStorage){if(!e||!n)return null;try{const a=n.getItem(De);if(!a)return null;const o=JSON.parse(a)[e];return typeof o=="string"?o:null}catch{return null}}const Ic=e=>e.action==="disconnect"?"disconnected":"connected";function Fc(e){switch(e.action){case"cancel":return{action:"cancel",operation_id:e.operationId};case"connect":case"disconnect":case"reload":return null;case"test":return{action:"test",name:e.name};default:return{...e,confirmed:!0}}}function $c(e){switch(e.action){case"cancel":return{action:"cancel",operation_id:e.operationId};case"test":case"connect":return{action:"connect",name:e.name};case"reload":return{action:"reload",name:e.name};case"add":return e;case"remove":return{...e,confirmed:!0};default:return{action:e.action,name:e.name,confirmed:!0}}}function Dc({sessionId:e}){const n=yt(),a=Fe(n.data,"mcp_catalog"),s=Fe(n.data,"mcp"),o=a?"catalog":s?"session":null,[r,l]=i.useState(null),d=rn(),c=qe(p=>p.sessions),u=qe(p=>p.fetchSessions),g=qe(p=>p.loading),x=i.useMemo(()=>c.find(p=>p.session_id===e)??null,[c,e]),y=i.useMemo(()=>o==="session"&&!e?Sc(c):null,[o,e,c]),f=o==="session"?e??y?.session_id??null:null;i.useEffect(()=>{o!=="session"||e||c.length>0||u(ua)},[o,e,c.length,u]);const k=o==="catalog"?Qe(x?.cwd):null,E=o==="catalog"&&!!e&&k===null,R=_e({queryKey:["desktop","session-cwd",e??""],queryFn:()=>fe({op:"sessions.get",sessionId:e??""}),enabled:E,staleTime:Number.POSITIVE_INFINITY,retry:!1}),K=E&&!R.isFetched,_=k??Qe(Mc(R.data))??(R.isFetched?Qe(Lc(e)):null),V=Oc(_,r),z=o==="catalog"?V:null,L=o==="catalog"?e??null:null,T=wc.catalog(z,L);i.useEffect(()=>{o!=="catalog"||!e||!z||Ac(e,z)},[o,e,z]);const Q=i.useRef(0),[I,X]=i.useState(0),Z=i.useRef(null),P=i.useCallback((p,M)=>{const S=Date.now()+Yt;Q.current=S,Z.current={name:p,expect:M},X(S)},[]),w=i.useCallback(p=>Date.now()<Q.current?In:Vi(p),[]),q=_e({queryKey:T,queryFn:()=>_c(z,L),enabled:o==="catalog"&&!K,staleTime:1e4,refetchInterval:p=>w(p.state.data)}),ee=Ec(q.error);i.useEffect(()=>{!ee||!_||r===_||(l(_),Tc(e))},[ee,_,r,e]);const W=_e({queryKey:ut.list(f??""),queryFn:()=>ma(f??""),enabled:o==="session"&&!!f,staleTime:1e4,refetchInterval:p=>w(p.state.data?pt(p.state.data,f??""):void 0)}),D=i.useMemo(()=>{if(o==="catalog")return q.data;if(o==="session"&&W.data&&f)return pt(W.data,f)},[o,q.data,W.data,f]),ne=i.useCallback(()=>Uc({queryClient:d,route:o,catalogKey:T,sessionId:f}),[o,T,d,f]);i.useEffect(()=>{if(!I)return;const p=Z.current;if(!p)return;const M=D?.servers.find(Y=>Y.name===p.name);!M||!(p.expect==="connected"?M.status==="connected":M.status_basis==="live"&&M.status!=="connected")||(Q.current=0,Z.current=null,X(0))},[D,I]);const U=i.useRef({}),[ce,O]=i.useState(0),ae=i.useMemo(()=>(U.current=zi(Hi(U.current,D,Dn()),D),U.current),[D,ce]),oe=i.useRef("");i.useEffect(()=>{const p=Bi(ae,D);if(!Object.keys(p).length)return;const M=JSON.stringify(p);M!==oe.current&&(oe.current=M,Rc(p))},[ae,D]);const re=i.useCallback(p=>{const M=Ae(U.current,p);M.needsKey||(U.current={...U.current,[p]:{...M,needsKey:!0}},O(S=>S+1))},[]),te=i.useCallback(p=>{if(p.action!=="disconnect"&&p.action!=="connect"&&p.action!=="reload")return;const M=Ae(U.current,p.name),S=Date.now()+Yt,Y=p.action==="disconnect"?{...M,connectedAt:null,disconnectedAt:Date.now(),holdUntil:S}:{...M,disconnectedAt:null,holdUntil:S};U.current={...U.current,[p.name]:Y},P(p.name,Ic(p)),O(B=>B+1)},[P]),J=i.useCallback(async p=>{if(o==="catalog"){const M=Fc(p);if(!M)return null;try{const S=await jc(z,M);return d.setQueryData(T,S),te(p),S.operation?.id??null}catch(S){throw S instanceof vt&&S.status===409&&d.invalidateQueries({queryKey:T}),S}}if(o==="session"&&f){const M=await fe({op:"mcp.control",sessionId:f,control:$c(p)});te(p);const S=ut.list(f),Y=M?.data;return Y&&"servers"in Y&&Array.isArray(Y.servers)?(d.setQueryData(S,Y),null):(d.invalidateQueries({queryKey:S}),Y&&"id"in Y&&typeof Y.id=="string"?Y.id:null)}return null},[o,z,T,d,f,te]),ie=i.useCallback(async p=>{if(o==="catalog"&&L&&(p.action==="connect"||p.action==="disconnect"||p.action==="reload")){try{await fe({op:"mcp.control",sessionId:L,control:{action:p.action,name:p.name,...p.action==="disconnect"?{confirmed:!0}:{}}})}catch(M){throw d.invalidateQueries({queryKey:T}),M}return te(p),await d.invalidateQueries({queryKey:T}),null}return J(p)},[o,L,d,T,J,te]),ve=i.useCallback(async(p,M,S,Y)=>{if(o==="catalog"){const B=await Nc(z,p,M,S,Y);if(B.catalog&&d.setQueryData(T,B.catalog),B.code!=="saved")return{saved:!1,message:tn(B.code,B.failed_ids,M)};try{await J({action:"test",name:p})}catch{}return{saved:!0,message:null}}if(o==="session"&&f){const B=await fe({op:"mcp.credentials.store",sessionId:f,name:p,values:M,confirmedReplace:S});if(B.data?.code!=="saved")return{saved:!1,message:tn(B.data?.code,B.data?.failed_ids??[],M)};try{await J({action:"connect",name:p})}catch{}return{saved:!0,message:null}}return{saved:!1,message:null}},[o,z,T,d,J,f]),me=o==="catalog"?q:W,ge=i.useCallback(()=>{me.refetch()},[me]);return{enabled:o!==null,route:o,sessionId:o==="catalog"?L:f,borrowed:y,noConversation:o==="session"&&!f&&!g,document:D,isLoading:n.isLoading||o==="catalog"&&(K||q.isLoading)||o==="session"&&(f?W.isLoading:g),isError:me.isError,folderUnavailable:Pi(r,_),refetch:ge,readDocument:ne,control:ie,storeKeys:ve,memories:ae,markNeedsKey:re}}function Uc(e){if(e.route==="catalog")return e.queryClient.getQueryData(e.catalogKey);if(e.route==="session"&&e.sessionId){const n=e.queryClient.getQueryData(ut.list(e.sessionId));return n?pt(n,e.sessionId):void 0}}const zc=(e,n)=>{const a=e?.trim();if(!a)return null;const s=fa(a,n);return s.kind==="auth"?{kind:"matched",name:s.name,unresolved:null}:{kind:"miss",asked:a}},Pc=6,it="Integrations",Bc="Let agents use your tools and accounts, like Notion, Linear or GitHub.",Hc={test:"test",connect:"reconnect",disconnect:"disconnect",reload:"reload",remove:"remove",sign_out:"disconnect",cancel:"cancel",login:"grant",reauth:"grant"},Kc=({sessionId:e,sectionRef:n,highlightServer:a})=>{const s=Dc({sessionId:e}),{document:o,control:r,readDocument:l}=s,d=ha(),c=o?.servers??[],u=o?.operations??[],g=o?.project_scope_available??!1,[x,y]=i.useState(!1),[f,k]=i.useState(""),[E,R]=i.useState(null),[K,_]=i.useState({}),[V,z]=i.useState(null),[L,T]=i.useState(null),[Q,I]=i.useState({kind:"ready"}),[X,Z]=i.useState(null),[P,w]=i.useState(null),[q,ee]=i.useState(!1),W=i.useRef({}),D=i.useRef({}),ne=i.useRef({}),U=i.useRef(0),ce=i.useRef(null),O=i.useRef(null),ae=i.useRef(null),[oe,re]=i.useState(null),[te,J]=i.useState(null),[ie,ve]=i.useState(null),me=i.useCallback(()=>{const h=ae.current;ae.current=null,T(null),Z(null),window.setTimeout(()=>{h?.isConnected&&h.focus()},0)},[]),ge=i.useCallback(h=>{const v=window.document.activeElement;ae.current=v instanceof HTMLElement?v:null,T(h)},[]),p=i.useCallback((h,v)=>{J({name:h,waitForSignIn:v==="signed-in",until:Date.now()+Le,reanchors:0}),me()},[me]),M=i.useMemo(()=>zc(a,c.map(h=>h.name)),[a,c]),S=M?.kind==="matched"?M.name:null,Y=i.useRef(null),B=i.useRef(null),le=f.trim().toLowerCase(),m=i.useMemo(()=>le?c.filter(h=>h.name.toLowerCase().includes(le)):c,[c,le]),b=i.useMemo(()=>Ui(m,u,s.memories),[m,u,s.memories]),N=L?.kind==="sign_in"?c.find(h=>h.name===L.name)??null:null;i.useEffect(()=>{!S||B.current===S||!f||k("")},[S,f]),i.useEffect(()=>{!S||B.current===S||m.some(h=>h.name===S)&&(B.current=S,Y.current?.scrollIntoView({block:"center",behavior:"smooth"}))},[S,m]),i.useEffect(()=>{if(!X)return;const h=u.find(v=>v.id===X)??null;I({kind:"running",operation:h})},[u,X]);const C=u.some(h=>h.status==="running"),G=h=>{const v=window.document.activeElement;v&&v!==window.document.body&&v.isConnected||J({name:h,waitForSignIn:!1,until:Date.now()+Le,reanchors:0})},F=async(h,v,A)=>{R(h),_(({[h]:Ne,...Se})=>Se);let H=null,xe=!1;try{H=await A()}catch(Ne){xe=!0,_(Se=>({...Se,[h]:Ge(Hc[v]??"status",Ne,C)}))}finally{R(null),v!=="sign_out"&&(v!=="remove"||xe)&&G(h)}return{operationId:H,failed:xe}},ke=h=>c.find(v=>v.name===h),je=h=>{h.source.path&&ga(h.source.path)},tt=async(h,v)=>{I({kind:"starting"}),Z(null);try{const A=await r({action:v,name:h});A?Z(A):I({kind:"running",operation:null})}catch(A){A instanceof vt&&A.code==="oauth_unsupported"&&s.markNeedsKey(h),I({kind:"refused",message:Ge("grant",A,C)})}},Pe=(h,v)=>{switch(v.kind){case"sign_in":case"reauth":{const A=u.find(H=>H.name===h.name&&H.status==="running");A&&ze(A)?(I({kind:"running",operation:A}),Z(A.id)):(I({kind:"ready"}),Z(null)),ge({kind:"sign_in",name:h.name,action:v.kind==="reauth"?"reauth":"login"});return}case"set_key":w(null),ge({kind:"key",name:h.name,keyNames:h.auth.secret_refs.map(A=>A.id)});return;case"fix":je(h);return;case"sign_out":z({name:h.name,kind:"sign_out"});return;default:{const A=v.kind;F(h.name,A,()=>r({action:A,name:h.name}))}}},Ct=(h,v)=>{switch(v.kind){case"remove":case"sign_out":z({name:h.name,kind:v.kind});return;case"sign_in":case"reauth":case"set_key":Pe(h,{kind:v.kind,label:v.label});return;case"open_config":je(h);return;case"copy_setup":navigator.clipboard.writeText(h.setup_prompt??"").then(()=>dt("Setup steps copied. Paste them into a chat.")).catch(()=>{});return;case"cancel":{const A=u.find(H=>H.name===h.name&&H.status==="running");A&&F(h.name,"cancel",()=>r({action:"cancel",operationId:A.id}));return}case"test":case"connect":case"disconnect":case"reload":{const A=v.kind;F(h.name,A,()=>r({action:A,name:h.name}));return}default:return}},Be=(h,v)=>{if(z(null),v==="remove"){const A=h.source.owned_scope;if(!A)return;const H=m.findIndex(xe=>xe.name===h.name);F(h.name,"remove",()=>r({action:"remove",name:h.name,scope:A})).then(({operationId:xe,failed:Ne})=>{Ne||xe!==null||(dt(`Removed ${h.name}.`),H>=0&&ve({index:H}))});return}F(h.name,"sign_out",()=>r({action:"logout",name:h.name})).then(()=>{J({name:h.name,waitForSignIn:!1,until:Date.now()+Le,reanchors:0})})},He=async h=>{try{return await r({action:"add",name:h.name,scope:h.scope,...h.mode==="command"?{command:h.command,args:h.args}:{url:h.url}}),y(!1),re(h.name),null}catch(v){return Ge("add",v,!1)}},Mt=t.jsxs("div",{className:"flex items-start justify-between gap-4",children:[t.jsxs("div",{className:"min-w-0",children:[t.jsx("h2",{className:"text-heading text-ink",children:it}),t.jsx("p",{className:"mt-1 max-w-2xl text-body-sm text-ink-muted",children:Bc})]}),s.enabled&&c.length>0&&!x?t.jsxs($,{ref:ce,variant:"secondary",size:"sm",onClick:()=>y(!0),"data-tour-tag":"mcp-add-server",children:[t.jsx(It,{"aria-hidden":"true"}),"Add integration"]}):null]});if(!s.enabled&&!s.isLoading)return t.jsx(he,{title:it,titleComponent:Mt,sectionRef:n,children:t.jsx(de,{variant:"warning",children:"Integrations need a newer Local Operator backend. Update it and restart the app to manage them here."})});const At=t.jsx(ac,{existingNames:c.map(h=>h.name),projectScopeAvailable:g,projectLabel:o?.cwd?qc(o.cwd):null,onSubmit:He,onCancel:()=>{y(!1),window.setTimeout(()=>ce.current?.focus(),0)}}),Rt=L?ke(L.name):void 0,Un=Object.entries(K).filter(([h])=>!c.some(v=>v.name===h)),zn=h=>_(({[h]:v,...A})=>A);i.useEffect(()=>{if(!oe)return;const h=W.current[oe];if(!h){c.some(v=>v.name===oe)&&(D.current[oe]?.focus(),re(null));return}h.focus(),re(null)},[oe,c]),i.useEffect(()=>{if(!ie)return;const v=m[Math.min(ie.index,m.length-1)]??m.at(-1);if(v){const A=W.current[v.name]??D.current[v.name];if(!A)return;A.focus()}else ce.current?.focus();ve(null)},[ie,m]);const nt=i.useCallback((h,v)=>{const A=l()??o,H=A?.servers.find(Pn=>Pn.name===h.name),xe=A?.operations??[],Ne=H?H.status==="connecting"||Oe(H.name,xe)!==null:!1;Ne&&H&&(U.current=v);const Se=H?jt(H,xe,s.memories):null;if(H&&h.waitForSignIn&&(Se?.kind==="sign_in"||Se?.kind==="reauth"))return"kept";const Re=ic({hold:h,now:v,windowMs:Le,rowMoving:Ne,lastMovingAt:U.current,candidate:H?lc({primary:Se?W.current[H.name]:null,overflow:D.current[H.name]}):void 0,active:window.document.activeElement,body:window.document.body});if(!Re.hold)return J(null),"finished";if(!Re.land)return"kept";J({name:h.name,waitForSignIn:!1,until:Re.hold.until,landedOn:Re.land,reanchors:Re.hold.reanchors});const Tt=Re.land;return window.setTimeout(()=>{Tt.isConnected&&Tt.focus()},0),"landed"},[l,o,s.memories]);return i.useEffect(()=>{if(!te)return;nt(te,Date.now());let h=0,v=!1;const A=()=>{if(v)return;const H=dc({verdict:nt(te,Date.now()),watchMs:Qt});H!==null&&(h=window.setTimeout(A,H))};return h=window.setTimeout(A,Qt),()=>{v=!0,window.clearTimeout(h)}},[te,nt]),i.useEffect(()=>{if(!te)return;const h=v=>{cc({target:v.target,row:ne.current[te.name]})&&J(null)};return window.document.addEventListener("pointerdown",h,!0),()=>{window.document.removeEventListener("pointerdown",h,!0)}},[te]),t.jsxs(he,{title:it,titleComponent:Mt,sectionRef:n,children:[t.jsxs("div",{className:"flex flex-col gap-4",children:[s.route==="session"&&s.borrowed?t.jsxs("p",{className:"text-body-sm text-ink-muted",children:["Showing the integrations for"," ",s.borrowed.title?.trim()||s.borrowed.session_id.slice(0,6),", your most recent chat."]}):null,s.noConversation?t.jsxs("div",{className:"flex flex-col items-start gap-2",children:[t.jsx("p",{className:"text-body-sm text-ink-muted",children:"Integrations can be managed here once a chat has started."}),t.jsx($,{variant:"primary",size:"sm",onClick:()=>d("/chat"),children:"Start a chat"}),t.jsx("p",{className:"text-ink-dim text-meta",children:"Updating Local Operator removes this step."})]}):null,s.isLoading?t.jsx("div",{className:"flex h-24 items-center justify-center",children:t.jsx(ue,{size:"lg",label:"Loading integrations"})}):null,s.folderUnavailable?t.jsx(de,{variant:"warning",children:t.jsx("span",{children:"This chat's folder no longer exists, so only global integrations are shown."})}):null,s.isError?t.jsx(de,{variant:"warning",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsx("span",{children:"Integrations couldn't be loaded."}),t.jsx($,{variant:"secondary",size:"sm",onClick:s.refetch,children:"Retry"})]})}):null,Un.map(([h,v])=>t.jsx(de,{variant:"warning",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsx("span",{children:v}),t.jsx($,{variant:"ghost",size:"sm",onClick:()=>zn(h),children:"Dismiss"})]})},h)),x&&c.length>0?At:null,c.length>=Pc?t.jsxs("div",{className:"relative",children:[t.jsx(un,{"aria-hidden":"true",className:"pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-ink-dim"}),t.jsx(ye,{ref:O,value:f,onChange:h=>k(h.target.value),onKeyDown:h=>{h.key!=="Escape"||!f||(h.preventDefault(),k(""))},placeholder:`Search ${ki(c.length)}`,"aria-label":"Search integrations",className:"pl-9"})]}):null,M?.kind==="miss"&&c.length>0?t.jsx("p",{className:"text-body-sm text-ink-muted",children:`No integration matches "${M.asked}".`}):null,M?.kind==="matched"&&M.unresolved?t.jsx("p",{className:"text-body-sm text-ink-muted",children:`Showing "${M.name}" — "${M.unresolved}" is not one of your integrations.`}):null,o&&c.length===0&&!s.isLoading?x?At:t.jsxs("div",{className:"flex flex-col items-start gap-3 rounded-lg bg-surface p-6",children:[t.jsx(pn,{"aria-hidden":"true",className:"size-5 text-ink-muted"}),t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("h3",{className:"text-heading text-ink",children:"No integrations yet"}),t.jsx("p",{className:"max-w-xl text-body-sm text-ink-muted",children:"Integrations let agents read and act in your other tools, like Notion or Linear. Add one with a command that runs on this computer, or a server's URL."})]}),t.jsxs($,{variant:"primary",size:"md",onClick:()=>y(!0),"data-tour-tag":"mcp-add-server",children:[t.jsx(It,{"aria-hidden":"true"}),"Add integration"]})]}):null,c.length>0&&m.length===0?t.jsxs("div",{className:"flex flex-col items-start gap-2",children:[t.jsx("p",{className:"text-body-sm text-ink-muted",children:"No integrations match this search."}),t.jsx($,{variant:"secondary",size:"sm",onClick:()=>{k(""),window.setTimeout(()=>{(O.current??ce.current)?.focus()},0)},children:"Clear search"})]}):null,b.map(h=>t.jsxs("section",{"aria-labelledby":`integrations-group-${h.id}`,className:"flex flex-col gap-1.5",children:[t.jsxs("h3",{id:`integrations-group-${h.id}`,className:"px-1 text-ink-dim text-meta",children:[h.title," · ",h.rows.length]}),t.jsx("ul",{className:"flex flex-col divide-y divide-hairline overflow-hidden rounded-lg bg-surface",children:h.rows.map(v=>t.jsx(gc,{row:v,operations:u,memories:s.memories,projectScopeAvailable:g,highlighted:v.name===S,rowRef:A=>{ne.current[v.name]=A,v.name===S&&(Y.current=A)},primaryRef:A=>{W.current[v.name]=A},overflowRef:A=>{D.current[v.name]=A},pending:E===v.name,failure:K[v.name]??null,confirm:V?.name===v.name?{kind:V.kind}:null,onPrimary:A=>Pe(v,A),onOverflow:A=>Ct(v,A),onConfirm:()=>V&&Be(v,V.kind),onCancelConfirm:()=>{z(null),window.setTimeout(()=>{D.current[v.name]?.focus()},0)}},v.id))})]},h.id))]}),L?.kind==="sign_in"?t.jsx(bc,{name:L.name,action:L.action,keyRoute:N?Xe(N):!1,phase:Q,onStart:()=>void tt(L.name,L.action),onCancel:h=>void r({action:"cancel",operationId:h}).catch(()=>{}),onOpenLink:h=>void pa(h),onClose:h=>p(L.name,h)}):null,L?.kind==="key"?t.jsx(hc,{name:L.name,keyNames:L.keyNames.length?L.keyNames:Rt?.auth.secret_refs.map(h=>h.id)??[],keyless:L.keyNames.length===0,savedKeys:Rt?.auth.secret_refs.filter(h=>h.state==="encrypted").map(h=>h.id),saving:q,failure:P,onClose:me,onSave:(h,v,A)=>{ee(!0),w(null),s.storeKeys(L.name,h,v,A).then(H=>{if(!H.saved){w(H.message);return}T(null),J({name:L.name,waitForSignIn:!1,until:Date.now()+Le,reanchors:0})}).catch(H=>w(Ge("key",H,!1))).finally(()=>ee(!1))}}):null]})},Le=4e3,Gc=/^\/(?:Users|home)\/[^/]+(?=\/|$)/,qc=e=>e.replace(Gc,"~"),Vc=e=>typeof e!="number"||!Number.isFinite(e)?"your free credits":`$${e.toFixed(2)} in free credits`,Yc="https://console.radienthq.com/dashboard/verification",Wc=(e,n)=>e==="pending"?{sentence:`Verify your email to claim ${n}. Check your inbox for the link Radient sent.`,action:"Open verification page"}:e==="expired"?{sentence:`The link to claim ${n} has expired. Request a new one from the verification page.`,action:"Request a new link"}:{sentence:"No signup grant is attached to this account. Open the verification page to check the account.",action:"Open verification page"},Qc=({verification:e})=>{const{prices:n}=va(),a=e.grant_amount??n?.default_new_credits,{sentence:s,action:o}=Wc(e.signup_grant,Vc(a)),r=e.claim_url||Yc;return t.jsxs("div",{className:"mt-8 flex items-start gap-3 rounded-sm border border-hairline bg-surface p-3",children:[t.jsx(Ze,{className:"mt-0.5 size-4 shrink-0 text-ink-muted","aria-hidden":"true"}),t.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-2",children:[t.jsx("p",{className:"text-body-sm text-ink",children:s}),t.jsx($,{variant:"secondary",size:"sm",onClick:()=>{window.api?.openExternal?window.api.openExternal(r):window.open(r,"_blank")},children:o})]})]})},Zc=({onAfterCredentialUpdate:e})=>{const{isAuthenticated:n,user:a,isLoading:s,accountRead:o,signOut:r}=xa(),l=fn(x=>x.isSigningOut),d=i.useCallback(async()=>{try{await r()}catch(x){console.error("Error signing out:",x)}},[r]),c=i.useMemo(()=>{if(!n||!a?.radientUser)return null;const{account:x,identity:y,verification:f}=a.radientUser,k=f!=null&&!f.email_verified&&f.signup_grant!=="claimed";return t.jsxs(t.Fragment,{children:[t.jsxs(kt,{children:[t.jsx(pe,{label:"Status",value:t.jsxs("span",{className:"inline-flex items-center gap-2",children:["Connected",t.jsx(kn,{variant:"success",className:"capitalize",children:x.status})]})}),t.jsx(pe,{label:"Name",value:x.name||"Not provided"}),t.jsx(pe,{label:"Email",value:x.email}),t.jsx(pe,{label:"Account ID",value:t.jsx("span",{className:"text-mono-sm",children:x.id})}),t.jsx(pe,{label:"Tenant ID",value:t.jsx("span",{className:"text-mono-sm",children:x.tenant_id})}),t.jsx(pe,{label:"Provider",value:t.jsx("span",{className:"capitalize",children:y.provider})}),t.jsx(pe,{label:"Created",value:gn(x.created_at)})]}),k&&f?t.jsx(Qc,{verification:f}):null,t.jsxs("div",{className:"mt-8",children:[t.jsx("p",{className:"text-body-sm text-ink-muted",children:"Need to sign out or switch accounts?"}),t.jsxs($,{variant:"danger",className:"mt-3",onClick:d,children:[t.jsx(ya,{}),"Sign out from Radient"]})]})]})},[n,a?.radientUser,d]),u=i.useMemo(()=>o==="refused"?"Radient refused the sign-in this app is holding, so your account details could not be read. Signing in again below replaces it.":xn(o)?"Your Radient account could not be read, so this app cannot show your account details.":"You are not currently signed in to Radient.",[o]),g=i.useMemo(()=>n&&a?null:t.jsxs("div",{children:[t.jsxs("p",{className:"text-body-sm text-ink-muted",children:[u," Sign in to access your account details or sign up to get free credits and unified access to models, tools, and more with Radient Pass. Radient's automatic model router will automatically select the best model for your agents to balance cost and performance. It is often cheaper to use Radient Pass than to use single AI providers due to automatic cost optimization."]}),t.jsx("div",{className:"mt-6",children:t.jsx(os,{titleText:"",onAfterCredentialUpdate:e,descriptionText:"",onSignInSuccess:()=>{}})})]}),[n,a,u,e]);return s||l?t.jsxs("div",{className:"flex min-h-36 flex-col items-center justify-center gap-3",children:[t.jsx(ue,{size:"lg",label:"Loading account"}),!l&&t.jsx("p",{className:"text-meta text-ink-dim",children:"Loading your Radient account details…"})]}):n&&a?.radientUser?c:t.jsx("div",{className:"flex flex-col gap-4",children:g})};function Jc({metric:e,data:n}){return t.jsx(ka,{title:"",heightClassName:"h-62",yAxisWidth:48,unit:e==="credits"?"credits":"tokens",srSummary:`${e==="credits"?"Credits consumed":"Tokens used"} over the last 30 days, plotted per day across ${n.length} days.`,xTickFormatter:a=>a,yTickFormatter:a=>e==="credits"?`$${a.toFixed(2)}`:ba(a),children:t.jsx(Mr,{data:n,children:t.jsx(cn,{type:"monotone",dataKey:"value",strokeWidth:2,dot:!1,activeDot:{r:4,strokeWidth:0},name:e==="credits"?"Credits consumed":"Tokens used"})})})}const Xc=()=>{const{data:e,isLoading:n,error:a,refetch:s}=Nr(),o=Sr(),[r,l]=i.useState(""),[d,c]=i.useState(!1);i.useEffect(()=>{l(e?.content??""),c(!1)},[e]);const u=k=>{const E=k.target.value;l(E),c(E!==(e?.content??""))},g=async()=>{if(!(!d||o.isPending))try{const k={content:r};await o.mutateAsync(k),await s(),c(!1)}catch(k){console.error("Error updating system prompt:",k)}},x=()=>{l(e?.content??""),c(!1)},y=o.isPending,f=()=>t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsxs("div",{className:"flex flex-col gap-2",children:[t.jsx(we,{htmlFor:"app-system-prompt",children:"Instructions"}),t.jsx(Je,{id:"app-system-prompt",name:"systemPrompt",value:r,onChange:u,placeholder:"Enter instructions for how all agents should behave and respond to your requests...",className:"min-h-50"})]}),t.jsxs("div",{className:"flex gap-3",children:[t.jsxs($,{variant:"primary",onClick:g,disabled:!d||y,children:[y?t.jsx(ue,{size:"sm"}):t.jsx(wa,{}),y?"Saving...":"Save changes"]}),t.jsx($,{onClick:x,disabled:!d||y,children:"Cancel"})]}),e?.last_modified&&t.jsxs("p",{className:"text-ink-dim text-meta",children:["Last modified:"," ",t.jsx("span",{className:"font-mono text-mono-sm",children:yn(e.last_modified)})]})]});return t.jsx(he,{title:"System prompt",icon:rs,description:"Every Local Operator agent receives this prompt in addition to its own instructions, so it is the place for baseline expectations and for details you want every agent to know about you, such as your name, location, or preferences. It is sent to your selected hosting provider.",children:n?t.jsx("div",{className:"flex min-h-50 items-center justify-center",children:t.jsx(ue,{size:"lg",label:"Loading system prompt"})}):a?t.jsxs(de,{variant:"danger",children:["Failed to load system prompt:"," ",a instanceof Error?a.message:"Unknown error"]}):f()})},el=["ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Home","End"],tl=e=>el.includes(e),nl=e=>{const n=[];let a=0;for(const s of e){const o=Math.max(0,Math.floor(s.count)),r=Math.max(1,Math.floor(s.columns));for(let l=0;l<o;l+=r)n.push({start:a+l,count:Math.min(r,o-l)});a+=o}return n},al=({index:e,key:n,groups:a})=>{const s=nl(a),o=s.reduce((r,l)=>r+l.count,0);if(!Number.isInteger(e)||e<0||e>=o)return e;switch(n){case"Home":return 0;case"End":return o-1;case"ArrowLeft":return Math.max(0,e-1);case"ArrowRight":return Math.min(o-1,e+1);case"ArrowUp":case"ArrowDown":{const r=s.findIndex(c=>e>=c.start&&e<c.start+c.count),l=s[r+(n==="ArrowDown"?1:-1)];if(!l)return e;const d=e-s[r].start;return l.start+Math.min(d,l.count-1)}default:return e}},sl={localOperatorDark:To,localOperatorLight:Zo,dracula:Ho,dune:so,sage:_o,monokai:Na,tokyoNight:Io,iceberg:Go,radient:xo,neon:_r,obsidian:_n,synth:xs,catppuccinMocha:Hs,catppuccinLatte:Co,tokyoNightStorm:Is,gruvbox:Ns,nord:br,oneDark:fs,solarizedDark:Wo,rosePine:co,rosePineMoon:Ao,rosePineDawn:Ps,alucard:uo,gruvboxLight:Qs,tokyoNightDay:Oo,oneLight:No,catppuccinFrappe:Ys,catppuccinMacchiato:vo,palenight:ja,everforest:ur,everforestLight:lr,kanagawaWave:xr,kanagawaLotus:ro,ayuDark:Js,ayuMirage:eo,ayuLight:Uo,nightfox:$s,duskfox:tr,synthwave:$o,matrix:vs,tron:Os,cyberpunk:_a,vaporwave:ir,outrun:_s,neonNoir:hr,arcade:bo,forest:or,ocean:no,desert:ar,autumn:vr,lavender:Vo,arctic:Us,rosewood:fo,solarizedLight:Xo,githubLight:ho,paper:is,linen:Po,highContrastLight:hs,mintLight:bs},nn="bg-[color-mix(in_srgb,var(--color-accent)_8%,var(--color-accent-wash))]",ol=({id:e})=>t.jsxs("div",{"data-theme":e,"aria-hidden":"true",className:"flex h-full bg-canvas",children:[t.jsxs("div",{className:"flex w-1/4 flex-col gap-1 bg-sunken p-1",children:[t.jsx("span",{className:"flex h-2.5 items-center rounded-xs bg-accent-wash px-1",children:t.jsx("span",{className:"h-1 w-full rounded-xs bg-accent"})}),t.jsx("span",{className:"mx-1 h-1 w-2/3 rounded-xs bg-ink-dim"}),t.jsx("span",{className:"mx-1 h-1 w-1/2 rounded-xs bg-ink-dim"})]}),t.jsxs("div",{className:"flex flex-1 flex-col justify-between p-1",children:[t.jsxs("div",{className:"flex flex-col gap-1 rounded-xs bg-surface p-1",children:[t.jsx("span",{className:"h-1 w-3/5 rounded-xs bg-ink"}),t.jsx("span",{className:"h-1 w-full rounded-xs bg-ink-dim"})]}),t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"h-2.5 w-6 rounded-xs bg-elevated"}),t.jsx("span",{className:"h-2.5 w-5 rounded-xs bg-accent"}),t.jsx("span",{className:"h-2.5 w-4 rounded-xs bg-accent-alt"}),t.jsx("span",{className:"h-2.5 w-4 rounded-xs border border-control"})]})]})]}),rl=({id:e,name:n,description:a,isSelected:s,isTabStop:o,onSelect:r,onFocusTile:l})=>{const d=sl[e];return t.jsx($e,{side:"bottom",align:"start",content:a,children:t.jsxs("button",{type:"button","data-theme-tile":e,"aria-pressed":s,tabIndex:o?0:-1,onFocus:l,onClick:r,className:se("relative flex flex-col gap-1.5 rounded-md p-1 text-left transition-colors duration-fast ease-out-quart",s?nn:"hover:bg-surface"),children:[t.jsxs("span",{className:se("relative block h-10 overflow-hidden rounded-sm border transition-colors duration-fast ease-out-quart",s?"border-accent":"border-hairline"),children:[t.jsx(ol,{id:e}),s&&t.jsx("span",{className:se("pointer-events-none absolute top-0.5 right-0.5 flex h-4 w-4 items-center justify-center rounded-full",nn),children:t.jsx(ss,{size:12,className:"text-accent","aria-hidden":"true"})})]}),t.jsxs("span",{className:"flex items-center gap-1.5",children:[t.jsx(d,{size:12,className:"shrink-0 text-ink-dim","aria-hidden":"true"}),t.jsx("span",{className:"min-w-0 flex-1 truncate text-meta text-ink",children:n})]})]})})},il=e=>[...e.querySelectorAll("[data-theme-grid]")].map(n=>{const a=[...n.querySelectorAll("[data-theme-tile]")],s=a[0]?.getBoundingClientRect().top??0;return{count:a.length,columns:Math.max(1,a.filter(o=>Math.abs(o.getBoundingClientRect().top-s)<1).length)}}),cl=()=>{const{themeName:e,setTheme:n}=mt(),a=i.useMemo(()=>{const d=Object.values(Bn);return[{label:"Dark",items:d.filter(c=>c.theme.palette.mode==="dark")},{label:"Light",items:d.filter(c=>c.theme.palette.mode==="light")}].filter(c=>c.items.length>0)},[]),[s,o]=i.useState(null),r=i.useMemo(()=>{const d=a.flatMap(c=>c.items.map(u=>u.id));return s&&d.includes(s)?s:d.includes(e)?e:d[0]},[a,s,e]),l=d=>{if(!tl(d.key))return;const c=[...d.currentTarget.querySelectorAll("[data-theme-tile]")],u=c.indexOf(d.target);if(u<0)return;d.preventDefault();const g=al({index:u,key:d.key,groups:il(d.currentTarget)});g!==u&&c[g]?.focus()};return t.jsx(as,{children:t.jsx("div",{onKeyDown:l,className:"flex flex-col gap-6",children:a.map(d=>t.jsxs("div",{children:[t.jsx("h3",{className:"px-1 pb-2 text-meta text-ink-dim",children:d.label}),t.jsx("div",{"data-theme-grid":d.label,className:"grid grid-cols-[repeat(auto-fill,minmax(160px,1fr))] gap-2",children:d.items.map(({id:c,name:u,description:g})=>t.jsx(rl,{id:c,name:u,description:g,isSelected:c===e,isTabStop:c===r,onSelect:()=>n(c),onFocusTile:()=>o(c)},c))})]},d.label))})})},ll=()=>{const{data:e,isLoading:n,error:a}=Tr({enabled:!0});return t.jsxs("div",{children:[t.jsxs("h3",{className:"mb-3 flex items-center gap-2 text-heading text-ink",children:[t.jsx(qs,{size:16,className:"shrink-0 text-ink-dim"}),"Radient Pass"]}),n&&t.jsx(bn,{className:"h-6 w-36"}),a&&t.jsxs(de,{variant:"warning",children:["Could not load your credit balance. ",a.message]}),e&&!n&&!a&&t.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center",children:[t.jsxs("p",{className:"flex-1 text-body-sm text-ink-muted",children:["Available credits"," ",t.jsx("span",{className:"font-medium text-ink",children:e.balance.toFixed(2)})]}),t.jsx($,{variant:"secondary",size:"sm",asChild:!0,children:t.jsxs("a",{href:"https://console.radienthq.com/dashboard/billing",target:"_blank",rel:"noopener noreferrer",children:[t.jsx(Ts,{}),"Add credits"]})})]})]})},dl=[{id:"credits",label:"Credits"},{id:"tokens",label:"Tokens"}],ul=()=>{const[e,n]=i.useState("credits"),a=i.useMemo(()=>{const d=new Date,c=Ar(d);return{start_date:Bt(c),end_date:Bt(d),rollup:"daily"}},[]),{data:s,isLoading:o,error:r}=Or(a,{enabled:!0}),l=i.useMemo(()=>s?.data_points?[...s.data_points].sort((c,u)=>at(c.timestamp).getTime()-at(u.timestamp).getTime()).map(c=>({bucket:za(ds(at(c.timestamp),"yyyy-MM-dd")),value:e==="credits"?Number.parseFloat(c.total_cost.toFixed(2)):c.total_tokens})):[],[s,e]);return t.jsxs("div",{children:[t.jsxs("div",{className:"mb-5 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[t.jsxs("h3",{className:"flex items-center gap-2 text-heading text-ink",children:[t.jsx(Cs,{size:16,className:"shrink-0 text-ink-dim"}),"Usage (last 30 days)"]}),t.jsxs("fieldset",{className:"m-0 w-fit border-0 p-0",children:[t.jsx("legend",{className:"sr-only",children:"Usage metric"}),t.jsx("div",{className:"flex gap-0.5 rounded-md bg-sunken p-0.5",children:dl.map(({id:d,label:c})=>t.jsx($,{variant:"ghost",size:"sm","aria-pressed":e===d,onClick:()=>n(d),className:se(e===d&&"bg-surface text-ink hover:bg-surface"),children:c},d))})]})]}),o&&t.jsx(bn,{className:"h-62 w-full"}),r&&t.jsxs(de,{variant:"warning",children:["Could not load your usage data. ",r.message]}),!o&&!r&&s&&l.length>0&&t.jsx(Jc,{metric:e,data:l}),!o&&!r&&(!s||l.length===0)&&t.jsx("p",{className:"text-body-sm text-ink-muted",children:"No usage recorded in the last 30 days."})]})},ml=()=>t.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[t.jsxs("h2",{className:"flex items-center gap-2 text-heading text-ink",children:[t.jsx(Pa,{size:16,className:"shrink-0 text-ink-dim"}),"Radient account"]}),t.jsx($,{variant:"secondary",size:"sm",className:"self-start sm:self-center",asChild:!0,children:t.jsxs("a",{href:"https://console.radienthq.com",target:"_blank",rel:"noopener noreferrer",children:["Go to Radient console",t.jsx(Ba,{})]})})]}),_l=()=>{const e=Sa(),n=mt(p=>p.showAgentReasoning),a=mt(p=>p.setShowAgentReasoning),{data:s,isLoading:o,isFetching:r,error:l,refetch:d}=Ca(),c=wn(),{sentence:u,remedy:g}=mn(c,"Your settings could not be loaded.",l),x=Ma(),[y,f]=i.useState(null),k=fn(),{isAuthenticated:E,accountRead:R,isFetching:K,isRefreshing:_,refreshUser:V}=xt(),z=qe(p=>p.activeSessionId),[L,T]=i.useState("general"),[Q,I]=i.useState(!1),X=i.useRef(null),Z=i.useRef(null),{startTour:P}=Aa(),w=Ra(),{data:q,refetch:ee}=Ta(),{refreshModels:W}=Ea(),D=i.useMemo(()=>q?.keys?[...q.keys].sort():[],[q?.keys]),ne=i.useRef({keys:"",hosting:void 0});i.useEffect(()=>{const p=D.join(","),M=s?.values?.hosting;(ne.current.keys!==p||ne.current.hosting!==M)&&(ne.current={keys:p,hosting:M},W().catch(S=>{console.error("Failed to refresh models after credentials or hosting change:",S)}))},[D,s?.values?.hosting,W]);const U=i.useRef({general:i.useRef(null),radient:i.useRef(null),integrations:i.useRef(null),appearance:i.useRef(null),providers:i.useRef(null),backend:i.useRef(null),updates:i.useRef(null)}).current,ce=i.useMemo(()=>new URLSearchParams(w.search).get("setting"),[w.search]),O=i.useMemo(()=>new URLSearchParams(w.search).get("filter")??"",[w.search]),ae=i.useMemo(()=>new URLSearchParams(w.search).get("mcp")??void 0,[w.search]),oe=i.useMemo(()=>new URLSearchParams(w.search).get("provider"),[w.search]),re=i.useCallback(p=>{T(p),I(!0);const M=U[p],S=Z.current;if(M?.current&&S){const B=M.current.getBoundingClientRect().top-S.getBoundingClientRect().top;S.scrollHeight>S.clientHeight?S.scrollTo({top:Math.max(0,S.scrollTop+B-80),behavior:"smooth"}):window.scrollTo({top:Math.max(0,M.current.getBoundingClientRect().top+window.scrollY-80),behavior:"smooth"}),clearTimeout(X.current??void 0),X.current=setTimeout(()=>{I(!1),X.current=null},800)}else I(!1)},[U]);i.useEffect(()=>{const p=setTimeout(()=>{const M=Z.current;if(!M)return;const S=()=>{if(Q)return;const Y=M.getBoundingClientRect(),B=Y.height;let le="",m=0;for(const[b,N]of Object.entries(U))if(N.current){const C=N.current.getBoundingClientRect(),G=Y.top,F=C.top-G,ke=C.bottom-G,je=C.height,tt=Math.max(0,F),Pe=Math.min(B,ke),Be=Math.max(0,Pe-tt)/je,He=Be+(F<B*.3?.1:0);He>m&&Be>.1&&(m=He,le=b)}le&&le!==L&&T(le)};return S(),M.addEventListener("scroll",S,{passive:!0}),()=>{M.removeEventListener("scroll",S),clearTimeout(X.current??void 0)}},100);return()=>clearTimeout(p)},[U,L,Q]),i.useEffect(()=>{const p=new URLSearchParams(w.search),M=p.get("section"),S=p.get("setting")?"backend":M,Y=S?U[S]:void 0;if(!S||!Y)return;let B=!1,le=Number.NaN,m=0;const b=window.setTimeout(()=>{B||(B=!0,C.disconnect(),re(S))},2e3),N=()=>{if(B)return;const G=Y.current;if(!G){m=requestAnimationFrame(N);return}const F=Math.round(G.getBoundingClientRect().top+window.scrollY);if(F===le&&F>0){B=!0,C.disconnect(),window.clearTimeout(b),re(S);return}le=F,m=requestAnimationFrame(N)},C=new ResizeObserver(()=>{B||(cancelAnimationFrame(m),m=requestAnimationFrame(N))});return Z.current&&C.observe(Z.current),m=requestAnimationFrame(N),()=>{B=!0,cancelAnimationFrame(m),C.disconnect(),window.clearTimeout(b)}},[w.search,U,re]);const te=async(p,M)=>{f(p);try{await x.mutateAsync({[p]:M}),await d()}catch(S){console.error(`Error updating ${p}:`,S)}finally{f(null)}},J=o,ie=R==="checking",ve=xn(R),me=R==="ready"||R==="checking"||K,ge=an(J,4e3);return l?t.jsx("div",{className:"flex h-full w-full items-center justify-center bg-canvas p-6",children:t.jsx(de,{variant:"warning",className:"w-full max-w-xl",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsx("span",{children:u}),g&&t.jsx($,{variant:"secondary",size:"sm",className:"shrink-0",onClick:()=>void d(),disabled:r,children:r?"Retrying":"Retry"})]})})}):J?t.jsxs("div",{role:"status",className:"flex h-full w-full flex-col items-center justify-center gap-3 bg-canvas",children:[t.jsx(ue,{size:"lg",label:ge?void 0:"Loading settings"}),ge&&t.jsx("p",{className:"max-w-sm text-center text-body-sm text-ink-muted",children:"The Local Operator server is taking longer than usual to answer. If it does not respond, you will be able to retry from here."})]}):s?t.jsxs("div",{className:"flex h-full w-full overflow-hidden bg-canvas",children:[t.jsx("div",{ref:e,className:"w-12 shrink-0 overflow-y-auto border-r border-hairline min-[1040px]:w-55",children:t.jsx(Oa,{activeSection:L,onSelectSection:re,sections:La})}),t.jsx("div",{ref:Z,"data-settings-content":!0,"data-tour-tag":"settings-general-section",className:"flex-1 overflow-y-auto overflow-x-hidden p-4 sm:p-6 md:p-8",children:t.jsxs("div",{className:"mx-auto flex w-full max-w-4xl flex-col gap-8 pb-8",children:[t.jsx(Ha,{title:"Settings",icon:Ft}),t.jsxs("div",{className:"flex flex-col gap-8",children:[t.jsxs("div",{ref:U.general,className:"flex flex-col gap-8",children:[t.jsxs(he,{title:"User profile",icon:Ia,description:`Your user profile information displayed in the application. This information is not provided to the agents. ${E?"These details are provided through your Radient account.":""}`,children:[ie&&t.jsx("p",{className:"text-meta text-ink-dim",children:"Checking your Radient account…"}),ve&&t.jsx(de,{variant:"warning",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsxs("span",{children:["Your Radient account could not be read, so the name and email below are placeholders rather than your account details.",R==="refused"?" Retry, or sign in to Radient again.":" Retry."]}),t.jsx($,{variant:"secondary",size:"sm",className:"shrink-0",onClick:()=>V(),disabled:_,children:_?"Retrying":"Retry"})]})}),t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsx($t,{value:k.profile.name,label:"Display name",placeholder:"Enter your name...",isSaving:y==="user_name",onSave:async p=>{f("user_name");try{k.updateName(p)}finally{f(null)}},readOnly:me}),t.jsx($t,{value:k.profile.email,label:"Email address",placeholder:"Enter your email...",isSaving:y==="user_email",onSave:async p=>{f("user_email");try{k.updateEmail(p)}finally{f(null)}},readOnly:me})]})]}),t.jsx(he,{title:"Application tour",description:"Missed the application onboarding tour or want a refresher? Start it again here.",children:t.jsxs($,{variant:"secondary",onClick:()=>{P({forceModalCompleted:!0})},children:[t.jsx(As,{}),"Take the tour"]})}),t.jsx(he,{id:"model-settings",title:"Model settings",icon:Fa,description:"Configure the default AI model and hosting providers used for generating responses. This will be used for all agents that don't have a specific model or hosting provider configured. You can override these settings for individual agents in the agent settings.",children:t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsx($a,{value:s.values.hosting,isSaving:y==="hosting",onSave:p=>te("hosting",p),filterByCredentials:!0,allowCustom:!0,allowDefault:!1,emptyHelperText:"No hosting providers available. Sign in to a provider, or add a provider's API key below, under Providers."}),t.jsx(Da,{value:s.values.model_name,hostingId:s.values.hosting,isSaving:y==="model_name",onSave:p=>te("model_name",p),allowCustom:!0,allowDefault:!1}),t.jsx(de,{variant:"neutral",icon:t.jsx(Ze,{className:"size-4","aria-hidden":"true"}),children:"You need a Radient account or your own API keys to reach cloud providers. If you don't see more hosting providers and models here, sign in to Radient, or add a provider's API key below, under Providers."})]})}),t.jsx(Xc,{}),t.jsx(he,{title:"Configuration information",icon:Ze,description:"System information about the current configuration.",children:t.jsxs(kt,{children:[t.jsx(pe,{label:"Version",value:t.jsx("span",{className:"text-mono-sm",children:s.version})}),t.jsx(pe,{label:"Created",value:gn(s.metadata.created_at)}),t.jsx(pe,{label:"Last modified",value:yn(s.metadata.last_modified)}),t.jsx(pe,{label:"Description",value:s.metadata.description||"No description available"})]})})]}),t.jsx(he,{title:"Appearance",icon:_n,description:"Customize the look and feel of Local Operator",sectionRef:U.appearance,dataTourTag:"settings-appearance-section",children:t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsx(cl,{}),t.jsx(Cr,{value:n,label:"Show agent reasoning",description:"Adds the agent's Reasoning and Thinking rows to conversations. They stay closed until you open one.",onChange:async p=>a(p)})]})}),t.jsx(he,{title:"Model providers",icon:pn,description:"Sign in to the services your agents think with. New chats use your default model.",sectionRef:U.providers,children:t.jsx(Ua,{initialProviderId:oe,onChangeModel:()=>re("general")})}),t.jsx(Kc,{sessionId:z??void 0,sectionRef:U.integrations,highlightServer:ae}),t.jsx(he,{title:"Radient account",titleComponent:t.jsx(ml,{}),description:"Your Radient account, Radient Pass details and credits. To use Radient models, sign in under Model providers.",sectionRef:U.radient,dataTourTag:"settings-radient-account-section",children:t.jsxs("div",{className:"flex flex-col gap-8",children:[t.jsx(Zc,{onAfterCredentialUpdate:()=>{W(),ee()}}),E&&t.jsxs(t.Fragment,{children:[t.jsx(ll,{}),t.jsx(ul,{})]})]})}),t.jsx(he,{title:"Backend settings",icon:Ft,description:"Every setting the backend registry owns, searchable, with typed editors and scopes.",sectionRef:U.backend,children:t.jsx(yi,{focusKey:ce,initialFilter:O})}),t.jsx("div",{ref:U.updates,children:t.jsx(Fr,{})})]})]})})]}):t.jsx("div",{className:"flex h-full w-full items-center justify-center bg-canvas p-6",children:t.jsx(de,{variant:"warning",className:"w-full max-w-xl",children:"Your settings could not be loaded."})})};export{_l as SettingsPage};
|
|
306
|
+
`).map(f=>f.trim()).filter(Boolean)}),"aria-label":`${e.label}: ${g}`,className:"font-mono text-body-sm"})]},g)),t.jsx("p",{className:"text-meta text-ink-dim",children:"One hop per line, as provider/model (effort). An empty chain moves to the next provider."})]})}default:return t.jsx(ye,{value:n,disabled:s,onChange:u=>o(u.target.value),"aria-label":e.label,placeholder:e.placeholder})}},Nn=({className:e})=>t.jsx("span",{role:"img","aria-label":"Changed from the default",title:"Changed from the default",className:se("size-1.5 shrink-0 rounded-full bg-accent",e)}),di=({title:e,rowCount:n,advancedCount:a,scope:s,modified:o,onOpenChange:r,defaultOpen:l=!1})=>t.jsx("div",{"data-section-header":e,className:"flex w-full flex-col",children:t.jsx(dn,{defaultOpen:l,onOpenChange:r,triggerClassName:"text-ink hover:bg-row-hover hover:text-ink",chevronClassName:"text-ink-dim",rowClassName:"min-h-10 py-0",className:"w-full",summary:t.jsxs("span",{className:"flex w-full min-w-0 items-center gap-2",children:[t.jsxs("span",{className:"flex min-w-0 items-center gap-2",children:[t.jsx("span",{className:"truncate text-heading text-ink",children:e}),n>0&&t.jsx("span",{className:"shrink-0 text-meta text-ink-dim",children:n===1?"1 setting":`${n} settings`}),s&&t.jsx("span",{className:"shrink-0 text-meta text-ink-dim",children:s}),a>0&&t.jsxs("span",{className:"shrink-0 text-meta text-ink-dim",children:[a," advanced"]})]}),o&&t.jsx(Nn,{className:"ml-auto"})]})})}),ui="size-3.5 shrink-0",mi=({setting:e,draft:n,tier:a,gate:s,saving:o,error:r,onDraftChange:l,onSave:d,onReset:c,effectiveHosting:u=""})=>{const g=!!(s&&!s.on),x=Ye(e,n),y=o||g,f=e.kind==="list"||e.kind==="cascade",k=t.jsxs("span",{className:"flex min-w-0 flex-col gap-0.5",children:[t.jsx("span",{className:"truncate text-body-sm text-ink",children:e.label}),e.kind==="readonly"&&t.jsx("span",{className:"text-meta text-ink-dim",children:"Read-only"}),e.warning&&t.jsx("span",{className:"text-meta text-danger",children:e.warning})]}),E=g&&s&&t.jsxs("p",{className:"text-meta text-ink-dim",children:["Needs ",s.label," on. Nothing here is saved while it is off."]});return t.jsx("div",{"data-setting-key":e.key,"data-tier":a,className:"border-b border-hairline",children:t.jsxs("div",{className:"flex flex-wrap items-start gap-x-4 gap-y-1 px-1 py-2.5",children:[t.jsxs("div",{className:se("flex min-w-44 flex-col gap-0.5",f?"shrink-0 basis-2/5":"flex-1"),children:[a==="advanced"&&e.help?t.jsx(dn,{summary:k,triggerClassName:"min-h-5 py-0 px-0 text-body-sm text-ink hover:text-ink",chevronClassName:"text-ink-dim",summaryAlign:"firstLine",rowClassName:"min-h-5 py-0",className:"w-full",children:t.jsx("span",{className:"text-meta text-ink-dim",children:e.help})}):t.jsxs("span",{className:"flex min-h-5 items-center gap-1.5",children:[t.jsx("span",{"aria-hidden":!0,className:ui}),k]}),a==="core"&&e.help&&t.jsx("p",{id:Gt(e.key),className:"ml-5 text-meta text-ink-dim",children:e.help}),E]}),t.jsxs("div",{className:se("flex shrink-0 items-center gap-2 self-center",f&&"min-w-0 flex-1 items-start"),children:[(!e.is_default||x)&&t.jsx(Nn,{}),!e.is_default&&e.kind!=="readonly"&&t.jsxs($,{variant:"ghost",size:"sm",disabled:y,onClick:c,"aria-label":`Use default for ${e.label}`,children:[t.jsx(fr,{"aria-hidden":"true"}),"Use default"]}),x&&t.jsx($,{variant:"primary",size:"sm",disabled:y,onClick:d,children:o?"Saving":"Save"}),t.jsx("div",{className:ai(e.kind),"data-setting-control":"",children:e.redacted?t.jsx("span",{className:"text-meta text-ink-dim",children:"Set in the credential manager: this value carries inline credentials or query parameters."}):e.kind==="readonly"?t.jsx("span",{className:"text-body-sm text-ink-muted",children:Ee(e.value)||"Not set"}):t.jsx(li,{setting:e,value:n.value,chains:n.cascadeBase??void 0,disabled:y,effectiveHosting:u,helpId:a==="core"&&e.help?Gt(e.key):void 0,onValueChange:R=>l({...n,value:R}),onChainsChange:R=>l({...n,cascadeBase:R})})})]}),r&&t.jsx(de,{variant:"danger",role:"alert",className:"w-full",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsx("span",{children:r}),t.jsxs($,{variant:"secondary",size:"sm",disabled:o,onClick:d,children:[t.jsx(oa,{"aria-hidden":"true"}),"Retry"]})]})})]})})},hi="w-full max-w-[400px]",pi=({query:e,onQueryChange:n,matchCount:a,matchSections:s,coreCount:o,advancedCount:r,modifiedCount:l,modifiedOnly:d,onModifiedOnlyChange:c,showAdvanced:u,onShowAdvancedChange:g,onExpandAll:x,onCollapseAll:y,unsavedCount:f,savingAll:k,onSaveAll:E,onDiscardAll:R})=>t.jsxs("div",{className:"flex flex-col gap-2",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[t.jsxs("div",{className:se("relative",hi),children:[t.jsx(un,{size:16,className:"pointer-events-none absolute top-1/2 left-3 -translate-y-1/2 text-ink-dim","aria-hidden":"true"}),t.jsx(ye,{value:e,onChange:K=>n(K.target.value),onKeyDown:K=>{K.key==="Escape"&&e&&n("")},placeholder:"Search settings by name, description or key","aria-label":"Search settings",className:"pl-9"}),e&&t.jsx($,{variant:"ghost",size:"icon-sm",className:"absolute top-1/2 right-1 -translate-y-1/2",onClick:()=>n(""),"aria-label":"Clear search",children:t.jsx(Za,{"aria-hidden":"true"})})]}),t.jsxs("fieldset",{className:"m-0 border-0 p-0",children:[t.jsx("legend",{className:"sr-only",children:"Settings filters"}),t.jsxs("div",{className:"flex gap-0.5 rounded-md bg-sunken p-0.5",children:[t.jsxs($,{variant:"ghost",size:"sm","aria-pressed":d,onClick:()=>c(!d),className:se(d&&"bg-surface text-ink hover:bg-surface"),children:["Modified",t.jsx(kn,{variant:"neutral",children:l})]}),t.jsx($,{variant:"ghost",size:"sm","aria-pressed":u,onClick:()=>g(!u),className:se(u&&"bg-surface text-ink hover:bg-surface"),children:"Show advanced"})]})]}),t.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[f>0&&t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"text-meta text-ink-dim",children:f===1?"1 unsaved change":`${f} unsaved changes`}),t.jsx($,{variant:"primary",size:"sm",disabled:k,onClick:E,children:k?"Saving":"Save all"}),t.jsx($,{variant:"ghost",size:"sm",disabled:k,onClick:R,children:"Discard all"})]}),t.jsx($,{variant:"ghost",size:"sm",onClick:x,children:"Expand all"}),t.jsx($,{variant:"ghost",size:"sm",onClick:y,children:"Collapse all"})]})]}),t.jsx("p",{className:"text-meta text-ink-dim","aria-live":"polite",children:a!==null?`${a} ${a===1?"result":"results"} in ${s} ${s===1?"section":"sections"}`:d?`${l} modified ${l===1?"setting":"settings"}`:u?`${r} advanced settings shown — Expand all to see them`:`${o} core settings, ${r} advanced`})]}),fi={all:["desktop","settings"]},gi={live:"Takes effect immediately","new launch":"Takes effect the next time the app starts","new sessions":"Takes effect for new conversations"},xi=40,Te=e=>e.toLowerCase().replace(/[-_.]/g," "),yi=({focusKey:e,initialFilter:n=""})=>{const a=yt(),s=wn(),o=Fe(a.data,"settings"),[r,l]=i.useState(n),[d,c]=i.useState(!1),[u,g]=i.useState(!1),[x,y]=i.useState({}),[f,k]=i.useState({}),[E,R]=i.useState({}),[K,_]=i.useState(!1),[V,z]=i.useState(new Set),[I,T]=i.useState(new Set),[Z,L]=i.useState(new Set),X=i.useRef(null),Q=i.useRef(null),P=_e({queryKey:fi.all,queryFn:()=>fe({op:"settings.list"}),enabled:o,staleTime:1e4}),w=P.data;i.useEffect(()=>{w&&y(m=>{let b=!1;const N={...m};for(const C of w.settings){const G=m[C.key];if(!G){N[C.key]=be(C),b=!0;continue}if(Ye(C,G))continue;const F=be(C);(F.value!==G.value||F.cascadeBase!==G.cascadeBase)&&(N[C.key]=F,b=!0)}return b?N:m})},[w]);const q=i.useCallback(m=>!m.is_default||Ye(m,x[m.key]??be(m)),[x]),ee=i.useMemo(()=>{const m=(w?.settings??[]).find(b=>b.key==="hosting");return m?(x.hosting??be(m)).value:""},[w,x]),W=i.useMemo(()=>{if(!w)return[];const m=Te(r.trim()),b=m.length>0||u;return w.settings.filter(N=>!b&&Me(N)==="advanced"&&!d||u&&!q(N)?!1:m?Te([N.label,N.help,N.key,N.section,N.warning??""].join(" ")).includes(m):!0)},[w,r,d,u,q]),D=r.trim().length>0||u,ne=i.useMemo(()=>w?.sections??[],[w]),U=i.useCallback(m=>(w?.settings??[]).filter(b=>b.section===m),[w]),ce=m=>W.filter(b=>b.section===m),O=m=>V.has(m)?!0:I.has(m)?!1:Ur(U(m)),ae=(m,b)=>{z(N=>{const C=new Set(N);return b?C.add(m):C.delete(m),C}),T(N=>{const C=new Set(N);return b?C.delete(m):C.add(m),C})},oe=(m,b)=>{L(N=>{const C=new Set(N);return b?C.delete(m):C.add(m),C})},re=m=>{const b=ne.filter(C=>m||ce(C.name).length>0).map(C=>C.name),N=zr(m,D,b);N.layout&&(z(new Set(N.layout.opened)),T(new Set(N.layout.closed))),L(new Set(N.filter))};i.useEffect(()=>{r.trim()||L(new Set)},[r]);const te=i.useCallback(m=>{const b=m.gated_by;if(!b||!w)return null;const N=w.settings.find(C=>C.key===b);return{key:b,label:N?.label??b,on:N?.value===!0||N?.value==="true"}},[w]),J=i.useCallback((m,b)=>k(N=>({...N,[m]:b})),[]),ie=i.useCallback((m,b)=>R(N=>({...N,[m]:b})),[]),ve=i.useCallback(async m=>{const b=x[m.key];if(!b)return!1;const N=Pr(m,b);if(!N.ok)return ie(m.key,N.error),!1;J(m.key,!0),ie(m.key,null);try{await fe(N.request),J(m.key,!1);const G=(await P.refetch()).data?.settings.find(F=>F.key===m.key);return G&&y(F=>{const ke=F[m.key];return ke&&ke.value===b.value&&ke.cascadeBase===b.cascadeBase?{...F,[m.key]:be(G)}:F}),!0}catch(C){return J(m.key,!1),ie(m.key,C instanceof Error?C.message:"The setting could not be saved."),!1}},[x,P,J,ie]),me=i.useCallback(async m=>{J(m.key,!0),ie(m.key,null);try{await fe({op:"settings.reset",key:m.key}),y(b=>({...b,[m.key]:be({...m,value:m.default,is_default:!0})})),J(m.key,!1),await P.refetch()}catch(b){J(m.key,!1),ie(m.key,b instanceof Error?b.message:"The setting could not be reset.")}},[P,J,ie]),ge=i.useMemo(()=>(w?.settings??[]).filter(m=>Ye(m,x[m.key]??be(m))),[w,x]),p=async()=>{_(!0);for(const m of ge)await ve(m);_(!1)},M=()=>{w&&(y(m=>{const b={...m};for(const N of w.settings)b[N.key]=be(N);return b}),R({}))};i.useEffect(()=>{if(!e||!w||X.current===e)return;const m=w.settings.find(C=>C.key===e);if(!m)return;X.current=e,Me(m)==="advanced"&&c(!0);const b=Te(r.trim());!b||Te([m.label,m.help,m.key,m.section].join(" ")).includes(b)||l(""),g(!1),z(C=>new Set(C).add(m.section)),T(C=>{const G=new Set(C);return G.delete(m.section),G})},[e,w,r]);const S=i.useMemo(()=>{if(!e||!w)return!1;const m=w.settings.find(N=>N.key===e);if(!m||Me(m)==="advanced"&&!d)return!1;const b=Te(r.trim());return b?Te([m.label,m.help,m.key,m.section].join(" ")).includes(b):!0},[e,w,r,d]);if(i.useEffect(()=>{if(!S||!e||Q.current===e)return;let m=0,b=0;const N=()=>{const C=document.querySelector(`[data-setting-key="${CSS.escape(e)}"]`),G=C?.querySelector('[data-setting-control] :is(input, textarea, select, button[role="switch"], button)')??C;if(G){G===C&&(G.tabIndex=-1),G.focus(),G.scrollIntoView({block:"center"}),Q.current=e;return}b+=1,b<xi&&(m=requestAnimationFrame(N))};return m=requestAnimationFrame(N),()=>cancelAnimationFrame(m)},[S,e]),a.data&&!o)return t.jsx(de,{variant:"warning",children:"Searchable settings need a newer Local Operator server. Update the server and restart the app to manage these settings here."});if(P.isLoading||a.isLoading)return t.jsx("div",{className:"flex h-40 items-center justify-center",children:t.jsx(ue,{size:"lg",label:"Loading settings"})});const Y=(a.data?null:a.error)??P.error;if(Y||!w){const m=a.isFetching||P.isFetching,{sentence:b,remedy:N}=mn(s,"Your settings could not be loaded.",Y);return t.jsx(de,{variant:"warning",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsx("span",{children:b}),N&&t.jsx($,{variant:"secondary",size:"sm",className:"shrink-0",onClick:()=>{a.isError?a.refetch():P.refetch()},disabled:m,children:m?"Retrying":"Retry"})]})})}const B=w.settings.reduce((m,b)=>(m[Me(b)]+=1,m),{core:0,advanced:0}),le=new Set(W.map(m=>m.section)).size;return t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsx(pi,{query:r,onQueryChange:l,matchCount:r.trim()?W.length:null,matchSections:le,coreCount:B.core,advancedCount:B.advanced,modifiedCount:w.settings.filter(q).length,modifiedOnly:u,onModifiedOnlyChange:g,showAdvanced:d,onShowAdvancedChange:c,onExpandAll:()=>re(!0),onCollapseAll:()=>re(!1),unsavedCount:ge.length,savingAll:K,onSaveAll:()=>void p(),onDiscardAll:M}),D&&W.length===0&&t.jsx("div",{className:"flex flex-col items-center py-6 text-center",children:t.jsx("p",{className:"text-body-sm text-ink-muted",children:"No settings match this search. Clear the search field to see every setting again."})}),t.jsx("div",{className:"flex flex-col gap-1",children:ne.map(m=>{const b=ce(m.name),N=U(m.name),C=D?0:N.filter(F=>Me(F)==="advanced").length;if(D&&b.length===0)return null;const G=D?b.length>0&&!Z.has(m.name):O(m.name);return t.jsxs("section",{"data-settings-section":m.name,"data-open":G,className:"flex flex-col",children:[t.jsx(di,{title:m.title,rowCount:b.length,advancedCount:C,scope:gi[m.scope],modified:N.some(q),defaultOpen:G,onOpenChange:F=>D?oe(m.name,F):ae(m.name,F)},`${m.name}:${G?"open":"closed"}`),t.jsxs("div",{hidden:!G,className:"flex flex-col pb-3",children:[m.description&&t.jsx("p",{className:"px-1 pb-1 text-meta text-ink-dim",children:m.description}),b.length===0?t.jsxs("div",{className:"flex items-center gap-2 px-1 py-2",children:[t.jsx("p",{className:"text-body-sm text-ink-muted",children:C>0?"Advanced settings are hidden here.":"Nothing in this section matches."}),C>0&&t.jsxs($,{variant:"secondary",size:"sm",onClick:()=>c(!0),children:["Show ",C," advanced"]})]}):b.map(F=>t.jsx(mi,{setting:F,draft:x[F.key]??be(F),tier:Me(F),gate:te(F),effectiveHosting:ee,saving:!!f[F.key],error:E[F.key]??null,onDraftChange:ke=>y(je=>({...je,[F.key]:ke})),onSave:()=>void ve(F),onReset:()=>void me(F)},F.key))]})]},m.name)})})]})},vi=[[[".claude.json"],"Claude Code"],[[".claude",".mcp.json"],"Claude Code"],[[".cursor","mcp.json"],"Cursor"],[[".vscode","mcp.json"],"VS Code"],[[".codex","config.toml"],"Codex CLI"]];function Sn(e){if(!e)return null;const n=e.split("\\").join("/").split("/").filter(Boolean);for(const[a,s]of vi)if(!(n.length<a.length)&&n.slice(-a.length).join("/")===a.join("/"))return s;return null}const We=e=>`${e} ${e===1?"tool":"tools"}`,ki=e=>`${e} ${e===1?"integration":"integrations"}`,bi=["connected","needs_sign_in","not_started","connecting","error"],Cn=e=>bi.includes(e),Oe=(e,n)=>[...n].filter(a=>a.name===e&&a.status==="running").sort((a,s)=>s.created_at-a.created_at)[0]??null,wi={connectedAt:null,connectedToolCount:null,settledGroup:null,pinnedGroup:null,pinnedOperationId:null,needsKey:!1,needsSignIn:!1,disconnectedAt:null,holdUntil:null,lastDecisive:null},_i=1e12,ji=1e9,Ni=60*60*1e3,Mn=(e,n=Date.now())=>{if(typeof e!="number"||!Number.isFinite(e))return null;const a=e>=_i?e:e<ji?null:e*1e3;return a===null||a>n+Ni?null:Math.min(a,n)},Ae=(e,n)=>e?.[n]??wi,Ue=(e,n,a)=>Mi(e,n)??a?.lastDecisive??null,Si=e=>({id:e.id,name:e.name,action:e.action,status:e.status,created_at:e.created_at,credential_removed:e.credential_removed,...e.message?{message:e.message}:{}}),wt=(e,n)=>e.status==="not_started"&&typeof e.tool_count=="number"&&(n.connectedAt!==null||e.status_basis==="stored"&&e.tool_count_basis==="last_seen"),Ci=(e,n)=>[...n].filter(a=>a.name===e).sort((a,s)=>s.created_at-a.created_at)[0]??null,Mi=(e,n)=>Ci(e,n.filter(a=>a.status!=="cancelled")),Xe=e=>e.actions.includes("set_key")||e.actions.includes("add_key");function Ai(e,n){const a=Math.max(0,Math.round((e-n)/1e3));if(a<60)return"just now";const s=Math.round(a/60);if(s<60)return`${s} min ago`;const o=Math.round(s/60);return o<24?`${o} h ago`:`${Math.round(o/24)} d ago`}function st(e){if(!e)return null;const n=e.trim();if(!n||/^\/\w/.test(n)||/\/mcp\s+\w+/.test(n))return null;let a=n;for(let s=0;s<3;s+=1){const o=a.replace(/^(?:connection (?:closed|error|refused)|error|closed|failed)\s*:\s*/i,"").trim();if(o===a)break;a=o}return a=a.replace(/\s*\(\s*\d{3}\s*\)/g,"").replace(/\s+([.,;])/g,"$1").replace(/\s{2,}/g," ").trim(),a||null}function Ri(e,n=[],a,s=Date.now()){const o=Ae(a,e.name),r=Oe(e.name,n);if(r){if(r.action==="login"||r.action==="reauth")return{label:"Signing in…",tone:"info",detail:null,busy:!0};if(r.action==="logout")return{label:"Signing out…",tone:"info",detail:null,busy:!0}}if(!Cn(e.status))return{label:"Status unavailable",tone:"neutral",detail:null,busy:!1};const l=Ue(e.name,n,o),d=et(l)&&e.status!=="connected",c=wt(e,o),u=Nt(l)&&e.status!=="connected",g=(l?.action==="login"||l?.action==="reauth")&&l.status==="failed";if(o.disconnectedAt!==null)return{label:"Not connected",tone:"neutral",detail:null,busy:!1};switch(e.status){case"connected":return{label:typeof e.tool_count=="number"?`Connected · ${We(e.tool_count)}`:"Connected",tone:"success",detail:null,busy:!1};case"connecting":return{label:"Connecting…",tone:"info",detail:null,busy:!0};case"needs_sign_in":return{label:e.auth.kind==="api_key"||Le(e,n,o)?"Needs a key":"Needs sign-in",tone:"warning",detail:st(e.status_reason),busy:!1};case"error":return{label:"Couldn't start",tone:"danger",detail:st(e.status_reason)??"No reason was given.",busy:!1};default:if(d)return{label:"Signed out",tone:"warning",detail:null,busy:!1};if(u)return{label:"Sign-out didn't finish",tone:"warning",detail:"The sign-in is still saved.",busy:!1};if(Le(e,n,o))return{label:"Needs a key",tone:"warning",detail:null,busy:!1};if(g)return{label:"Sign-in didn't finish",tone:"warning",detail:null,busy:!1};if(o.needsSignIn)return{label:e.auth.kind==="api_key"||Le(e,n,o)?"Needs a key":"Needs sign-in",tone:"warning",detail:st(e.status_reason),busy:!1};if(e.status_basis==="stored"&&c&&o.disconnectedAt===null){const x=o.connectedAt??Mn(e.last_seen_at,s);return{label:x!==null?`Worked ${Ai(s,x)} · ${We(e.tool_count)}`:`Worked earlier · ${We(e.tool_count)}`,tone:"success",detail:null,busy:!1}}return e.status_basis==="live"?{label:"Not connected",tone:"neutral",detail:null,busy:!1}:{label:"Ready",tone:"neutral",detail:null,busy:!1}}}const An=e=>e===1?"Replace the saved key":"Replace saved keys",Ti=/[,;]?\s*(?:or|and)?\s*add (?:its|a|the) key instead\.?\s*$/i;function Ei(e,n){const a=e?.trim()??"";if(!a)return null;if(n)return a;const s=a.replace(Ti,"").trim();return s?/\.$/.test(s)?s:`${s}.`:a}const Oi="Nothing is wrong. It starts when a chat uses it.",Ii="Not running in this chat.",Li=e=>e.transport==="local_command"?"Local command":"Remote URL";function Rn(e){switch(e.source.kind){case"local-operator":case"project-mcp-json":return null;case"claude-code":return"Claude Code";case"cursor":return"Cursor";case"vscode":return"VS Code";case"codex":return"Codex CLI";default:return Sn(e.source.path)}}function Fi(e,n){const a=[Li(e)];e.status!=="connected"&&e.tool_count_basis==="last_seen"&&typeof e.tool_count=="number"&&a.push(`${We(e.tool_count)} when last checked`),n&&a.push(e.scope==="project"?"This project":"Global");const s=Rn(e);return s?a.push(`Imported from ${s}`):e.source.editable||a.push("Imported from a project file"),a}const _t=(e,n)=>n.disconnectedAt!==null?"not_started":e.status;function jt(e,n=[],a){const s=Ae(a,e.name),o=Oe(e.name,n);if(o)return o.action==="login"||o.action==="reauth"?{kind:"sign_in",label:"Continue sign-in"}:null;const r=g=>e.actions.includes(g),l=Xe(e),d=Le(e,n,s);if(!Cn(e.status))return r("test")?{kind:"test",label:"Check again"}:null;const c=Ue(e.name,n,s),u=c?.status==="failed"&&ze(c);switch(_t(e,s)){case"connected":case"connecting":return null;case"needs_sign_in":return d?{kind:"set_key",label:"Add key"}:r("sign_in")?{kind:"sign_in",label:"Sign in"}:l?{kind:"set_key",label:"Add key"}:r("reauth")?{kind:"reauth",label:"Sign in again"}:{kind:"fix",label:"Fix"};case"error":return r("connect")?{kind:"connect",label:"Reconnect"}:r("test")?{kind:"test",label:"Retry"}:{kind:"fix",label:"Fix"};default:{if(et(c)&&r("sign_in"))return{kind:"sign_in",label:"Sign in"};if(Nt(c)&&r("sign_out"))return{kind:"sign_out",label:"Sign out again"};if(s.disconnectedAt!==null&&r("connect"))return{kind:"connect",label:"Connect"};if(s.needsSignIn){if(d&&l)return{kind:"set_key",label:"Add key"};if(r("sign_in"))return{kind:"sign_in",label:"Sign in"}}return d&&l?{kind:"set_key",label:"Add key"}:u&&r("sign_in")?{kind:"sign_in",label:"Try again"}:wt(e,s)&&!r("connect")?null:r("connect")?{kind:"connect",label:"Connect",...s.connectedAt===null&&e.status_basis!=="live"?{variant:"ghost"}:{}}:r("test")&&e.tool_count===null&&e.tool_count_basis===null?{kind:"test",label:"Test",variant:"ghost"}:null}}}const ze=e=>e.action==="login"||e.action==="reauth",et=e=>!!(e&&e.action==="logout"&&e.status==="complete"),Nt=e=>!!(e&&e.action==="logout"&&e.status!=="running"&&e.status!=="complete"),Tn=/no oauth authorization server/i;function Le(e,n,a){if(!Xe(e))return!1;const s=Ue(e.name,n,a);return s&&ze(s)&&s.status==="failed"&&Tn.test(s.message??"")?!0:a.needsKey}function $i(e,n=[],a){const s=jt(e,n,a)?.kind,o=_t(e,Ae(a,e.name)),r=c=>e.actions.includes(c),l=[],d=Oe(e.name,n);if(d&&l.push({kind:"cancel",label:"Cancel"}),!d&&r("test")&&s!=="test"&&l.push({kind:"test",label:"Test connection"}),r("connect")&&s!=="connect"&&o!=="connected"&&l.push({kind:"connect",label:"Reconnect"}),!d&&r("sign_in")&&s!=="sign_in"&&o!=="connected"&&l.push({kind:"sign_in",label:"Sign in"}),r("reload")&&l.push({kind:"reload",label:"Reload"}),!d&&r("reauth")&&s!=="reauth"&&l.push({kind:"reauth",label:"Sign in again"}),Xe(e)&&s!=="set_key"&&l.push({kind:"set_key",label:e.auth.secret_refs.length>0?"Update key":"Add key"}),r("sign_out")&&l.push({kind:"sign_out",label:"Sign out"}),r("disconnect")&&o==="connected"&&l.push({kind:"disconnect",label:"Disconnect"}),r("copy_setup")&&e.setup_prompt&&l.push({kind:"copy_setup",label:"Copy setup prompt"}),s!=="fix"&&l.push({kind:"open_config",label:"Open config file"}),r("remove"))l.push({kind:"remove",label:"Remove",destructive:!0});else if(!e.source.editable){const c=Rn(e);l.push({kind:"remove_elsewhere",label:c?`Remove in ${c}`:"Remove in its own file",hint:c?`Defined in ${c}'s config. Remove it there.`:"Defined in a file this app doesn't write. Remove it there."})}return l}const Di={attention:"Needs attention",connected:"Connected",ready:"Available"};function En(e,n=[],a){const s=Ae(a,e.name),o=Oe(e.name,n),r=_t(e,s);if(o&&s.pinnedGroup&&s.pinnedOperationId===o.id)return s.pinnedGroup;if(r==="needs_sign_in"||r==="error")return"attention";const l=Ue(e.name,n,s);return et(l)&&r!=="connected"||Nt(l)&&r!=="connected"?"attention":s.disconnectedAt!==null?"ready":Le(e,n,s)||s.needsSignIn&&r!=="connected"||l?.status==="failed"&&ze(l)&&r!=="connected"?"attention":r==="connected"||e.status_basis==="stored"&&wt(e,s)?"connected":o&&o.action!=="test"?"attention":"ready"}function Ui(e,n=[],a){return["attention","connected","ready"].map(o=>({id:o,title:Di[o],rows:e.filter(r=>En(r,n,a)===o)})).filter(o=>o.rows.length>0)}function zi(e,n,a=Date.now()){if(!n)return e??{};const s={};for(const o of n.servers){const r=Ae(e,o.name),l=Oe(o.name,n.operations),d=Ue(o.name,n.operations,r),c=et(d),u=o.status==="connected"&&(o.status_basis==="probe"||o.status_basis==="live"),g=r.holdUntil!==null&&a<r.holdUntil,x=!g&&!c&&r.connectedAt===null&&o.status_basis==="stored"&&o.tool_count_basis==="last_seen"?Mn(o.last_seen_at,a):null,y=!c,f=d?.status==="failed"&&ze(d)&&Tn.test(d.message??""),k={connectedAt:u&&!g?a:x!==null?x:y?r.connectedAt:null,connectedToolCount:u&&!g||x!==null?o.tool_count??r.connectedToolCount:y?r.connectedToolCount:null,settledGroup:r.settledGroup,pinnedGroup:l&&r.pinnedOperationId===l.id?r.pinnedGroup:l?r.settledGroup:null,pinnedOperationId:l?l.id:null,needsKey:u?!1:r.needsKey||f,needsSignIn:u||c?!1:r.needsSignIn||o.status==="needs_sign_in",disconnectedAt:u&&!g?null:r.disconnectedAt,holdUntil:g?r.holdUntil:null,lastDecisive:d?Si(d):null};l||(k.settledGroup=En(o,n.operations,{...s,[o.name]:k})),s[o.name]=k}return s}const Pi=(e,n)=>e!==null&&n===e,ht="local-operator.settings.integrations.row-memory",On=(e,n)=>`${e}#${n}`;function Bi(e,n){const a={};if(!n)return a;for(const s of n.servers){const o=e[s.name];o&&(a[On(s.source.path,s.name)]=o)}return a}function Hi(e,n,a){if(!n)return e;let s=null;for(const o of n.servers){if(Object.prototype.hasOwnProperty.call(e,o.name))continue;const r=qi(a[On(o.source.path,o.name)]);r&&(s=s??{...e},s[o.name]=r)}return s??e}const Ki=["attention","connected","ready"],In=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),St=e=>typeof e=="number"&&Number.isFinite(e)?e:null,Vt=e=>Ki.includes(e)?e:null,ot=e=>{const n=St(e);return n!==null&&n>=1e12?n:null};function Gi(e){if(!In(e)||typeof e.id!="string"||typeof e.name!="string")return null;const n=e.action,a=e.status;return n!=="login"&&n!=="logout"&&n!=="reauth"&&n!=="test"||a!=="running"&&a!=="complete"&&a!=="cancelled"&&a!=="failed"?null:{id:e.id,name:e.name,action:n,status:a,created_at:St(e.created_at)??0,credential_removed:e.credential_removed===!0,...typeof e.message=="string"?{message:e.message}:{}}}function qi(e){if(!In(e))return null;const n=ot(e.connectedAt),a=ot(e.disconnectedAt),s=e.needsKey===!0,o=e.needsSignIn===!0,r=Gi(e.lastDecisive);return n===null&&a===null&&!s&&!o&&!r?null:{connectedAt:n,connectedToolCount:St(e.connectedToolCount),settledGroup:Vt(e.settledGroup),pinnedGroup:Vt(e.pinnedGroup),pinnedOperationId:typeof e.pinnedOperationId=="string"?e.pinnedOperationId:null,needsKey:s,needsSignIn:o,disconnectedAt:a,holdUntil:ot(e.holdUntil),lastDecisive:r}}const Ln=2e3,Yt=8e3;function Vi(e){return e&&(e.servers.some(a=>a.status==="connecting")||e.operations.some(a=>a.status==="running"))?Ln:!1}const Yi=/^[A-Za-z0-9_.:-]{1,100}$/,Wi=/:\/\//;function Zi(e,n){const a=e.trim();return a?Yi.test(a)?n.includes(a)?`An integration named ${a} already exists.`:null:"Use letters, numbers, dots, dashes, underscores or colons, with no spaces.":"Give it a name."}function Qi(e){const n=e.trim();if(!n)return"Enter the server's URL.";let a;try{a=new URL(n)}catch{return"Enter a full URL, like https://mcp.example.com/mcp."}return a.protocol!=="https:"&&a.protocol!=="http:"?"The URL must start with https:// or http://.":a.hostname?a.username||a.password?"Remove the username or password from the URL. Keys are added after it's saved.":a.search||a.hash?"Remove the ? or # part of the URL. Keys are added after it's saved.":Wi.test(n.slice(a.protocol.length+2))?"This looks like two URLs pasted together. Enter just one.":null:"The URL needs a host name."}const Ji=e=>e.split(`
|
|
307
|
+
`).map(n=>n.trim()).filter(Boolean);function pt(e,n){const a=!!e?.cold,s=(e?.servers??[]).map(o=>{const r=o.transport==="http",l=o.secret_refs??[],d=o.status==="connected"?"connected":o.status==="connecting"?"connecting":o.status==="auth-required"?"needs_sign_in":"not_started",c=[];d!=="connected"&&c.push("connect"),d==="connected"&&c.push("disconnect"),a||c.push("reload"),r&&o.transport_oauth_supported!==!1&&c.push("sign_in"),l.length>0&&c.push("set_key"),o.owned_scope&&c.push("remove"),o.setup?.text&&c.push("copy_setup");const u=Sn(o.source);return{id:o.name,name:o.name,scope:o.owned_scope??"global",project_cwd:null,source:{kind:Xi(o.source,u,o.owned_scope),path:o.source??"",editable:o.owned_scope!==null,owned_scope:o.owned_scope},transport:r?"remote_url":"local_command",endpoint:{command:null,url:null,endpoint_redacted:!1},status:d,status_reason:null,status_observed_at:null,last_seen_at:null,status_basis:a?"stored":"live",auth:{kind:l.length?"api_key":r?"unknown":"none",signed_in:null,secret_refs:l.map(g=>({id:g.id,state:"missing"}))},tool_count:typeof o.tool_count=="number"?o.tool_count:null,tool_count_basis:typeof o.tool_count=="number"?"live":null,actions:c,setup_prompt:o.setup?.text??null}});return{cwd:"",project_scope_available:s.some(o=>o.source.owned_scope==="project"),global_path:"",project_path:null,status_source:a?"config":"live",session_id:n,servers:s,operations:(e?.operations??[]).map(o=>({...o}))}}const Xi=(e,n,a)=>n==="Claude Code"?"claude-code":n==="Cursor"?"cursor":n==="VS Code"?"vscode":n==="Codex CLI"?"codex":a?"local-operator":e?"project-mcp-json":"local-operator",Wt={invalid_config:"That configuration isn't valid. Check the command or the URL, then try again.",operation_unavailable:"That sign-in or test isn't running any more. Try again.",exists:"An integration with this name already exists. Choose another name.",not_owned:"It's defined in another tool's config, so it can't be changed here. Edit it in that file.",project_scope_unavailable:"There's no separate project config here, so it can only be added globally.",unknown_server:"It no longer exists. The list has been refreshed.",oauth_unsupported:"It doesn't use browser sign-in.",grant_running:"A sign-in or test is already running. Wait for it to finish, or cancel it.",too_many_operations:"Too many sign-ins and tests are waiting. Try again in a moment.",write_failed:"The config file couldn't be written. Check that it isn't read-only.",mcp_starting:"Integrations are still starting. Try again in a moment.",mcp_control_refused:"The server refused it, so nothing was changed."},ec="The server refused it, so nothing was changed. Try again.";function Ge(e,n,a){if(n instanceof vt&&n.status===409){const s=typeof n.code=="string"&&Object.prototype.hasOwnProperty.call(Wt,n.code)?Wt[n.code]:ec;return`${ra[e]}. ${s}`}return ia(e,n,a).message}const tc="New chats can use it right away. Open chats pick it up when you start a new chat or reload integrations there.",nc="Most services give you a URL. Use Local command when their setup says npx or uvx.",ac=({existingNames:e,projectScopeAvailable:n,projectLabel:a,onSubmit:s,onCancel:o,initial:r})=>{const[l,d]=i.useState(r?.name??""),[c,u]=i.useState(r?.mode??"command"),[g,x]=i.useState(r?.command??""),[y,f]=i.useState(r?.args??""),[k,E]=i.useState(r?.url??""),[R,K]=i.useState("global"),[_,V]=i.useState(r?.touched?{name:!0,command:!0,url:!0}:{}),[z,I]=i.useState(!!r?.touched),[T,Z]=i.useState(!1),[L,X]=i.useState(null),Q=i.useRef(null),P=i.useRef(null),w=i.useRef(null);i.useEffect(()=>{Q.current?.focus()},[]);const q=Zi(l,e),ee=c==="command"&&!g.trim()?"Enter the command to run.":null,W=c==="url"?Qi(k):null,D=O=>z||_[O],ne=async O=>{if(O.preventDefault(),I(!0),q||ee||W){q?Q.current?.focus():ee?P.current?.focus():w.current?.focus();return}Z(!0),X(null);const ae=n?R:"global",oe=c==="command"?{name:l.trim(),scope:ae,mode:c,command:g.trim(),args:Ji(y)}:{name:l.trim(),scope:ae,mode:c,url:k.trim()},re=await s(oe);Z(!1),X(re)},U=(O,ae,oe)=>ae&&D(oe)?t.jsx("p",{id:O,className:"text-body-sm text-danger",children:ae}):null,ce=O=>O.preventDefault();return t.jsxs("form",{noValidate:!0,"aria-label":"Add integration",className:"flex flex-col gap-4 rounded-lg bg-surface p-4",onSubmit:O=>void ne(O),onKeyDown:O=>{O.key==="Escape"&&(O.stopPropagation(),o())},children:[t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsx(we,{htmlFor:"integration-add-name",children:"Name"}),t.jsx(ye,{ref:Q,id:"integration-add-name",value:l,placeholder:"e.g. notion",autoComplete:"off","aria-invalid":!!(q&&D("name")),"aria-describedby":q&&D("name")?"integration-add-name-error":void 0,onChange:O=>d(O.target.value),onBlur:()=>V(O=>({...O,name:!0}))}),U("integration-add-name-error",q,"name")]}),t.jsxs(Dt,{value:c,onValueChange:O=>u(O==="url"?"url":"command"),className:"flex flex-col gap-1.5",children:[t.jsx("span",{id:"integration-add-transport-label",className:"font-medium text-body-sm text-ink",children:"How it runs"}),t.jsxs(Ut,{"aria-labelledby":"integration-add-transport-label",children:[t.jsx(Ke,{value:"command","data-integration-transport":"command",children:"Local command"}),t.jsx(Ke,{value:"url","data-integration-transport":"url",children:"Remote URL"})]}),t.jsx("p",{className:"text-ink-dim text-meta",children:nc}),t.jsxs(zt,{value:"command",className:"mt-0 flex flex-col gap-4",children:[t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsx(we,{htmlFor:"integration-add-command",children:"Command"}),t.jsx(ye,{ref:P,id:"integration-add-command",value:g,placeholder:"e.g. npx",autoComplete:"off",className:"font-mono","aria-invalid":!!(ee&&D("command")),"aria-describedby":ee&&D("command")?"integration-add-command-error":void 0,onChange:O=>x(O.target.value),onBlur:()=>V(O=>({...O,command:!0}))}),U("integration-add-command-error",ee,"command")]}),t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsxs(we,{htmlFor:"integration-add-args",children:["Arguments"," ",t.jsx("span",{className:"font-normal text-ink-dim",children:"(one per line)"})]}),t.jsx(Je,{id:"integration-add-args",value:y,rows:2,className:"font-mono",onChange:O=>f(O.target.value)})]})]}),t.jsx(zt,{value:"url",className:"mt-0 flex flex-col gap-4",children:t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsx(we,{htmlFor:"integration-add-url",children:"URL"}),t.jsx(ye,{ref:w,id:"integration-add-url",type:"url",value:k,placeholder:"https://mcp.example.com/mcp",autoComplete:"off",className:"font-mono","aria-invalid":!!(W&&D("url")),"aria-describedby":W&&D("url")?"integration-add-url-error":"integration-add-url-help",onChange:O=>E(O.target.value),onBlur:()=>V(O=>({...O,url:!0}))}),U("integration-add-url-error",W,"url")??t.jsx("p",{id:"integration-add-url-help",className:"text-ink-dim text-meta",children:"If it needs a sign-in or a key, you'll be asked after it's added."})]})})]}),n?t.jsxs(Dt,{value:R,onValueChange:O=>K(O==="project"?"project":"global"),className:"flex flex-col gap-1.5",children:[t.jsx("span",{id:"integration-add-scope-label",className:"font-medium text-body-sm text-ink",children:"Available in"}),t.jsxs(Ut,{"aria-labelledby":"integration-add-scope-label",children:[t.jsx(Ke,{value:"global","data-integration-scope":"global",children:"All chats"}),t.jsx(Ke,{value:"project","data-integration-scope":"project",children:"This project"})]}),a?t.jsx("p",{className:"text-ink-dim text-meta",children:R==="project"?`Only chats working in ${a}.`:"Every chat, in any folder."}):null]}):null,L?t.jsx("p",{className:"text-body-sm text-danger",role:"alert",children:L}):null,t.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[t.jsx("p",{className:se("text-body-sm text-ink-dim"),children:tc}),t.jsxs("div",{className:"flex gap-2",children:[t.jsx($,{type:"button",variant:"ghost",size:"md",onMouseDown:ce,onClick:o,children:"Cancel"}),t.jsxs($,{type:"submit",variant:"primary",size:"md",disabled:T,onMouseDown:ce,children:[T?t.jsx(ue,{size:"xs"}):null,"Add integration"]})]})]})]})},sc=4;function oc(e){return e.rowMoving?e.now+e.windowMs:Math.max(e.hold.until,e.lastMovingAt+e.windowMs)}function rc(e){return e.now>e.hold.until||e.hold.reanchors>=sc?"drop":e.hold.landedOn.isConnected&&(!e.candidate||e.candidate===e.hold.landedOn)?"settled":e.active&&e.active!==e.body&&e.active!==e.hold.landedOn?"drop":e.candidate?.isConnected?"restore":"drop"}function ic(e){const n=oc({hold:e.hold,now:e.now,windowMs:e.windowMs,rowMoving:e.rowMoving,lastMovingAt:e.lastMovingAt});if(e.now>n)return{hold:null,land:null};const a=e.hold.landedOn??null,s=e.candidate;if(!s)return{hold:{until:n,reanchors:e.hold.reanchors,landedOn:a},land:null};if(!a)return{hold:{until:n,reanchors:e.hold.reanchors,landedOn:s},land:s};const o=rc({hold:{until:n,reanchors:e.hold.reanchors,landedOn:a},candidate:s,active:e.active,body:e.body,now:e.now});if(o==="settled")return{hold:{until:n,reanchors:e.hold.reanchors,landedOn:a},land:null};if(o==="drop")return{hold:null,land:null};const r=!a.isConnected;return{hold:{until:r?e.now+e.windowMs:n,reanchors:r?e.hold.reanchors+1:e.hold.reanchors,landedOn:s},land:s}}function cc(e){const{row:n,target:a}=e;return!n||!a||typeof a.nodeType!="number"?!1:!n.contains(a)}const Zt=250;function Qt(e){return e?!e.disabled:!1}function lc(e){return Qt(e.primary)?e.primary??null:Qt(e.overflow)?e.overflow??null:null}function dc(e){return e.verdict==="finished"?null:e.watchMs}const Fn="key";function uc(e){const{name:n,keyless:a,freeName:s,names:o,values:r,replace:l,canReplace:d}=e;if(a){const c=ft(n,s);return{values:{[c]:(r[Fn]??"").trim()},confirmedReplace:l&&d?[c]:[],header:s.trim()}}return{values:Object.fromEntries(o.map(c=>[c,(r[c]??"").trim()])),confirmedReplace:l&&d?o:[],header:void 0}}function ft(e,n){const a=Jt(e),s=Jt(n);if(!s)return"";const o=[a,s].filter(Boolean).join("_"),r=/^[A-Za-z_]/.test(o)?o:`K_${o}`;if(r.length<=rt)return r;const l=mc(a),d=rt-s.length-l.length-2,c=[a.slice(0,Math.max(d,0)),l,s].filter(Boolean).join("_");return c.length<=rt?c:c.slice(-128)}const rt=128,Jt=e=>e.trim().toUpperCase().replace(/[^A-Z0-9]+/g,"_").replace(/^_+|_+$/g,""),mc=e=>{let n=2166136261;for(let a=0;a<e.length;a+=1)n^=e.charCodeAt(a),n=Math.imul(n,16777619)>>>0;return n.toString(36).toUpperCase().slice(0,5)},hc=({name:e,keyNames:n,keyless:a=!1,savedKeys:s=[],saving:o,failure:r,onSave:l,onClose:d})=>{const[c,u]=i.useState({}),[g,x]=i.useState(!1),[y,f]=i.useState(""),k=a?[ft(e,y)]:[...n],E=a?[Fn]:k,R=(a?ft(e,y).length>0:!0)&&E.every(_=>(c[_]??"").trim()),K=k.some(_=>s.includes(_));return t.jsx(hn,{open:!0,onClose:d,maxWidth:"xs",title:a||n.length===1?`Add the key for ${e}`:`Add keys for ${e}`,actions:t.jsxs(t.Fragment,{children:[t.jsx(ct,{onClick:d,children:"Cancel"}),t.jsx(lt,{disabled:!R||o,onClick:()=>{const _=uc({name:e,keyless:a,freeName:y,names:k,values:c,replace:g,canReplace:K});l(_.values,_.confirmedReplace,_.header)},children:o?"Saving…":"Save and test"})]}),children:t.jsxs("div",{className:"flex flex-col gap-3 p-1.5 text-body text-ink-muted",children:[t.jsx("p",{className:"-mx-1.5",children:a?"Keys are saved encrypted on this computer. This one is stored under a name derived from this integration, so no other server shares it.":"Keys are saved encrypted on this computer. Other integrations that use the same key name share it."}),a?t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsx(we,{htmlFor:"integration-key-name",children:"The header this server wants the key in"}),t.jsx(ye,{id:"integration-key-name",autoComplete:"off",placeholder:"e.g. Authorization or X-Api-Key",value:y,onChange:_=>f(_.target.value)}),t.jsx("p",{className:"-mx-1.5 text-ink-dim text-meta",children:"This server declares no key of its own, so Local Operator adds one to its config for you."})]}):null,E.filter(_=>a!==!0||_.trim().length>0).map(_=>t.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.jsx(we,{htmlFor:`integration-key-${_}`,className:"font-mono",children:a?"Key":_}),t.jsx(ye,{id:`integration-key-${_}`,type:"password",autoComplete:"off",value:c[_]??"",onChange:V=>u(z=>({...z,[_]:V.target.value}))})]},_)),K?t.jsxs("div",{className:"flex items-center gap-2 text-body-sm",children:[t.jsx(Qa,{id:"integration-key-replace",checked:g,onCheckedChange:_=>x(_===!0)}),t.jsx(we,{htmlFor:"integration-key-replace",className:"font-normal",children:An(k.length)})]}):null,r?t.jsx("p",{className:"-mx-1.5 text-body-sm text-danger",role:"alert",children:r}):null]})})},pc={success:"bg-success",warning:"bg-warning",danger:"bg-danger",info:"bg-info",neutral:"bg-ink-dim"},fc={success:"text-ink-muted",warning:"text-warning",danger:"text-danger",info:"text-ink-muted",neutral:"text-ink-dim"},Xt={Ready:Oi,"Not connected":Ii},gc=({row:e,operations:n,memories:a,now:s,projectScopeAvailable:o,highlighted:r=!1,rowRef:l,primaryRef:d,overflowRef:c,pending:u,failure:g,confirm:x,onPrimary:y,onOverflow:f,onConfirm:k,onCancelConfirm:E})=>{const R=Ri(e,n,a,s),K=r&&R.tone==="danger"?"text-ink":fc[R.tone],_=jt(e,n,a),V=$i(e,n,a),z=Fi(e,o),I=V.findIndex(T=>T.kind==="remove"||T.kind==="remove_elsewhere");return t.jsxs("li",{ref:l,"data-integration":e.name,"data-status":e.status,className:se("flex min-h-14 flex-col justify-center gap-1 px-4 py-2.5",r&&"bg-row-selected"),onKeyDown:T=>{!x||T.key!=="Escape"||(T.stopPropagation(),E())},children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("span",{className:"flex size-4 shrink-0 items-center justify-center",children:R.busy?t.jsx(ue,{size:"xs"}):t.jsx("span",{"aria-hidden":"true","data-tone":R.tone,className:se("size-2 rounded-full",pc[R.tone])})}),t.jsxs("div",{className:"flex min-w-0 flex-1 flex-col",children:[t.jsx("span",{className:"truncate font-medium text-body text-ink",title:e.name,children:e.name}),t.jsx("span",{className:"truncate text-ink-dim text-meta",children:z.map((T,Z)=>t.jsxs("span",{children:[Z>0?" · ":null,T.startsWith("Imported from")&&e.source.path?t.jsx($e,{content:ca(e.source.path),children:t.jsx("span",{className:"underline decoration-dotted underline-offset-2",children:T})}):T]},T))})]}),Xt[R.label]?t.jsx($e,{content:Xt[R.label],children:t.jsx("span",{className:se("shrink-0 text-body-sm",K),children:R.label})}):t.jsx("span",{className:se("shrink-0 text-body-sm",K),children:R.label}),_?t.jsxs($,{ref:d,variant:_.variant??"secondary",size:"sm","aria-label":`${_.label} ${e.name}`,disabled:u,"data-integration-action":_.kind,onClick:()=>y(_),children:[u?t.jsx(ue,{size:"xs"}):null,_.label]}):null,t.jsxs(Ja,{children:[t.jsx(Xa,{asChild:!0,children:t.jsx($,{ref:c,variant:"ghost",size:"icon-sm","aria-label":`More actions for ${e.name}`,disabled:u,children:t.jsx(la,{"aria-hidden":"true"})})}),t.jsx(es,{align:"end",className:"min-w-48",children:V.map((T,Z)=>t.jsx(xc,{item:T,separated:Z===I&&Z>0,onSelect:()=>f(T)},T.kind))})]})]}),R.detail?t.jsx("p",{className:se("pl-7 text-body-sm",R.tone==="danger"?"text-ink-muted":"text-ink-dim"),children:R.detail}):null,g?t.jsx("p",{className:se("pl-7 text-body-sm",r?"text-ink":"text-danger"),role:"alert",children:g}):null,x?t.jsxs("div",{className:"flex flex-wrap items-center gap-2 pl-7",children:[t.jsx("span",{className:"text-body-sm text-ink",children:x.kind==="remove"?`Remove ${e.name}?`:`Sign out of ${e.name}?`}),t.jsx("span",{className:"text-body-sm text-ink-muted",children:x.kind==="remove"?`Agents in every chat lose access to ${e.name}.`:e.auth.kind==="oauth"?"The saved sign-in is removed too.":"Its saved credential is removed too."}),t.jsx($,{variant:"danger",size:"sm",onClick:k,"data-integration-confirm":x.kind,children:x.kind==="remove"?"Remove":"Sign out"}),t.jsx($,{variant:"ghost",size:"sm",onClick:E,children:"Keep"})]}):null]})},xc=({item:e,separated:n,onSelect:a})=>t.jsxs(t.Fragment,{children:[n?t.jsx(ts,{}):null,e.kind==="remove_elsewhere"?t.jsxs(Pt,{disabled:!0,className:"flex-col items-start gap-0.5",children:[t.jsx("span",{children:e.label}),t.jsx("span",{className:"text-meta text-ink-dim",children:e.hint})]}):t.jsx(Pt,{destructive:e.kind==="remove",onSelect:a,"data-integration-menu":e.kind,children:e.label})]});function yc(e,n,a){return!n||n.status==="running"?n?.browser_opened===!0?{message:`Your browser opened. Approve access to ${e} there, then come back here.`,tone:"progress",link:n.authorization_url??null}:n?.browser_opened===!1?{message:n.authorization_url?"Your browser didn't open. Open this link to approve access:":"Your browser didn't open, and no link was provided. Cancel and try again.",tone:"progress",link:n.authorization_url??null}:{message:`Waiting for you to approve access to ${e}…`,tone:"progress",link:n?.authorization_url??null}:n.status==="complete"?{message:`Signed in to ${e}. Agents can use it now.`,tone:"success",link:null}:n.status==="cancelled"?{message:"Sign-in cancelled.",tone:"failure",link:null,reason:null,nextStep:"Press Try again when you are ready."}:{message:"Sign-in didn't finish.",tone:"failure",link:null,reason:Ei(n.message,a)??"The server didn't say why.",nextStep:vc(n.message??null,a)}}function vc(e,n){const a=(e??"").toLowerCase();return a.includes("redirect")?n?"This server may not accept sign-ins from Local Operator. Check the server's settings, or add a key instead.":"This server may not accept sign-ins from Local Operator. Check the server's settings, then try again.":a.includes("no oauth")||a.includes("authorization server")?n?"This server doesn't publish a browser sign-in. Add its key instead.":"This server doesn't publish a browser sign-in. Check the server's settings, then try again.":a.includes("network")||a.includes("connect")?"Check the server's URL and your network, then try again.":"Check the server's settings, then try again."}function kc(e,n){return e.kind==="ready"?"ready":e.kind==="running"&&n&&n.tone!=="progress"?n.tone==="success"?"success":"failure":"running"}const bc=({name:e,action:n,keyRoute:a,phase:s,onStart:o,onCancel:r,onOpenLink:l,onClose:d})=>{const c=s.kind==="running"?s.operation:null,u=s.kind==="running"?yc(e,c,a):null,g=s.kind==="starting"||s.kind==="running"&&u?.tone==="progress",x=u&&u.tone!=="progress",y=i.useRef(null),f=i.useRef(!1),k=kc(s,u);i.useEffect(()=>{if(!f.current){f.current=!0;return}k&&y.current?.focus()},[k]);const E=()=>d(u?.tone==="success"?"signed-in":"dismissed");return t.jsx(hn,{open:!0,onClose:E,maxWidth:"xs",fullWidth:!0,title:`Sign in to ${e}`,dialogProps:{onOpenAutoFocus:R=>{R.preventDefault(),y.current?.focus()}},actions:t.jsxs(t.Fragment,{children:[g&&c?t.jsx(ct,{ref:y,onClick:()=>r(c.id),children:"Cancel sign-in"}):t.jsx(ct,{ref:s.kind==="ready"?void 0:y,onClick:E,children:u?.tone==="success"?"Done":"Close"}),s.kind==="ready"?t.jsx(lt,{ref:y,onClick:o,children:"Continue in browser"}):null,s.kind==="refused"||u?.tone==="failure"?t.jsx(lt,{ref:u?.tone==="failure"?y:void 0,onClick:o,children:"Try again"}):null]}),children:t.jsxs("div",{className:"flex flex-col gap-3 p-1.5 text-body text-ink-muted","aria-live":"polite",children:[s.kind==="ready"?t.jsxs("p",{className:"-mx-1.5",children:["Local Operator opens your browser so you can approve access to"," ",e,".",n==="reauth"?" This replaces the sign-in it has now.":""]}):null,s.kind==="starting"?t.jsxs("p",{className:"-mx-1.5 flex items-center gap-2",children:[t.jsx(ue,{size:"xs"}),"Starting sign-in…"]}):null,u?t.jsxs("div",{className:"flex flex-col gap-1",role:x?"status":void 0,children:[t.jsxs("p",{className:(u.tone==="success","-mx-1.5 flex items-start gap-2 text-ink"),children:[u.tone==="progress"?t.jsx(ue,{size:"xs",className:"mt-0.5"}):null,u.tone==="failure"?t.jsx(ns,{"aria-hidden":"true",className:"mt-0.5 size-4 shrink-0 text-danger"}):null,t.jsx("span",{children:u.message})]}),u.reason?t.jsx("p",{className:"-mx-1.5 text-ink-muted",children:u.reason}):null,u.nextStep?t.jsx("p",{className:"-mx-1.5 text-ink-muted",children:u.nextStep}):null]}):null,u?.link&&u.tone==="progress"?t.jsxs("div",{className:"flex flex-col items-start gap-1",children:[t.jsxs("div",{className:"flex w-full min-w-0 items-center gap-1",children:[t.jsx("span",{className:"min-w-0 flex-1 truncate font-mono text-ink-dim text-mono-sm",title:u.link,children:u.link}),t.jsx($,{variant:"ghost",size:"icon-sm","aria-label":"Copy the sign-in link",title:"Copy the sign-in link",onClick:()=>{navigator.clipboard.writeText(u.link??"").then(()=>dt("Sign-in link copied.")).catch(()=>{})},children:t.jsx(da,{"aria-hidden":"true"})})]}),t.jsx($,{variant:"link",size:"sm",onClick:()=>l(u.link??""),children:"Open the sign-in page"})]}):null,s.kind==="refused"?t.jsx("p",{className:"text-danger",role:"alert",children:s.message}):null]})})},wc={catalog:(e,n)=>["desktop","mcp-catalog",e??"",n??""],all:["desktop","mcp-catalog"]},_c=async(e,n)=>(await fe({op:"mcp.catalog",...e?{cwd:e}:{},...n?{sessionId:n}:{}})).data,jc=async(e,n)=>(await fe({op:"mcp.catalog.control",...e?{cwd:e}:{},control:n})).data,Nc=async(e,n,a,s,o)=>(await fe({op:"mcp.catalog.credentials",...e?{cwd:e}:{},name:n,values:a,confirmedReplace:s,...o?{header:o}:{}})).data,Sc=e=>e.reduce((n,a)=>n?(a.updated_at??0)>(n.updated_at??0)?a:n:a,null),Cc=/^[A-Za-z]:[\\/]/,Ze=e=>{const n=e?.trim();return n&&(n.startsWith("/")||Cc.test(n))?n:null};function Mc(e){const o=e?.payload?.frontend?.snapshot?.cwd;return typeof o=="string"&&o.trim()?o:null}const De="local-operator.settings.integrations.last-cwd";function Ac(e,n,a=typeof localStorage>"u"?null:localStorage){const s=Ze(n);if(!(!e||!s||!a))try{const o=a.getItem(De),r=o?JSON.parse(o):{};if(r[e]===s)return;a.setItem(De,JSON.stringify({...r,[e]:s}))}catch{}}const $n=()=>typeof localStorage>"u"?null:localStorage;function Dn(e=$n()){if(!e)return{};try{const n=e.getItem(ht);if(!n)return{};const a=JSON.parse(n);return!a||typeof a!="object"||Array.isArray(a)?{}:a}catch{return{}}}const en=256;function Rc(e,n=$n()){if(n)try{const a={...Dn(n),...e},s=Object.keys(a);if(s.length>en){const o={};for(const r of s.slice(-en))o[r]=a[r];n.setItem(ht,JSON.stringify(o));return}n.setItem(ht,JSON.stringify(a))}catch{}}function tn(e,n,a){return e==="saved"?null:e==="replace_confirmation_required"?`A saved value already exists for this key. Tick “${An(Object.keys(a).length)}” to overwrite it.`:e==="invalid_target"?"That header can't carry this key. It may already be set on the server, or belong to the transport - try a different header name. Nothing was saved.":`Not saved: ${(n.length?n:Object.keys(a)).join(", ")}. The encrypted store may be locked.`}function Tc(e,n=typeof localStorage>"u"?null:localStorage){if(!(!e||!n))try{const a=n.getItem(De);if(!a)return;const s=JSON.parse(a);if(!(e in s))return;const o={...s};delete o[e],n.setItem(De,JSON.stringify(o))}catch{}}const Ec=e=>!!(e&&typeof e=="object"&&"code"in e&&e.code==="invalid_cwd"),Oc=(e,n)=>n!==null&&e===n?null:e;function Ic(e,n=typeof localStorage>"u"?null:localStorage){if(!e||!n)return null;try{const a=n.getItem(De);if(!a)return null;const o=JSON.parse(a)[e];return typeof o=="string"?o:null}catch{return null}}const Lc=e=>e.action==="disconnect"?"disconnected":"connected";function Fc(e){switch(e.action){case"cancel":return{action:"cancel",operation_id:e.operationId};case"connect":case"disconnect":case"reload":return null;case"test":return{action:"test",name:e.name};default:return{...e,confirmed:!0}}}function $c(e){switch(e.action){case"cancel":return{action:"cancel",operation_id:e.operationId};case"test":case"connect":return{action:"connect",name:e.name};case"reload":return{action:"reload",name:e.name};case"add":return e;case"remove":return{...e,confirmed:!0};default:return{action:e.action,name:e.name,confirmed:!0}}}function Dc({sessionId:e}){const n=yt(),a=Fe(n.data,"mcp_catalog"),s=Fe(n.data,"mcp"),o=a?"catalog":s?"session":null,[r,l]=i.useState(null),d=rn(),c=qe(p=>p.sessions),u=qe(p=>p.fetchSessions),g=qe(p=>p.loading),x=i.useMemo(()=>c.find(p=>p.session_id===e)??null,[c,e]),y=i.useMemo(()=>o==="session"&&!e?Sc(c):null,[o,e,c]),f=o==="session"?e??y?.session_id??null:null;i.useEffect(()=>{o!=="session"||e||c.length>0||u(ua)},[o,e,c.length,u]);const k=o==="catalog"?Ze(x?.cwd):null,E=o==="catalog"&&!!e&&k===null,R=_e({queryKey:["desktop","session-cwd",e??""],queryFn:()=>fe({op:"sessions.get",sessionId:e??""}),enabled:E,staleTime:Number.POSITIVE_INFINITY,retry:!1}),K=E&&!R.isFetched,_=k??Ze(Mc(R.data))??(R.isFetched?Ze(Ic(e)):null),V=Oc(_,r),z=o==="catalog"?V:null,I=o==="catalog"?e??null:null,T=wc.catalog(z,I);i.useEffect(()=>{o!=="catalog"||!e||!z||Ac(e,z)},[o,e,z]);const Z=i.useRef(0),[L,X]=i.useState(0),Q=i.useRef(null),P=i.useCallback((p,M)=>{const S=Date.now()+Yt;Z.current=S,Q.current={name:p,expect:M},X(S)},[]),w=i.useCallback(p=>Date.now()<Z.current?Ln:Vi(p),[]),q=_e({queryKey:T,queryFn:()=>_c(z,I),enabled:o==="catalog"&&!K,staleTime:1e4,refetchInterval:p=>w(p.state.data)}),ee=Ec(q.error);i.useEffect(()=>{!ee||!_||r===_||(l(_),Tc(e))},[ee,_,r,e]);const W=_e({queryKey:ut.list(f??""),queryFn:()=>ma(f??""),enabled:o==="session"&&!!f,staleTime:1e4,refetchInterval:p=>w(p.state.data?pt(p.state.data,f??""):void 0)}),D=i.useMemo(()=>{if(o==="catalog")return q.data;if(o==="session"&&W.data&&f)return pt(W.data,f)},[o,q.data,W.data,f]),ne=i.useCallback(()=>Uc({queryClient:d,route:o,catalogKey:T,sessionId:f}),[o,T,d,f]);i.useEffect(()=>{if(!L)return;const p=Q.current;if(!p)return;const M=D?.servers.find(Y=>Y.name===p.name);!M||!(p.expect==="connected"?M.status==="connected":M.status_basis==="live"&&M.status!=="connected")||(Z.current=0,Q.current=null,X(0))},[D,L]);const U=i.useRef({}),[ce,O]=i.useState(0),ae=i.useMemo(()=>(U.current=zi(Hi(U.current,D,Dn()),D),U.current),[D,ce]),oe=i.useRef("");i.useEffect(()=>{const p=Bi(ae,D);if(!Object.keys(p).length)return;const M=JSON.stringify(p);M!==oe.current&&(oe.current=M,Rc(p))},[ae,D]);const re=i.useCallback(p=>{const M=Ae(U.current,p);M.needsKey||(U.current={...U.current,[p]:{...M,needsKey:!0}},O(S=>S+1))},[]),te=i.useCallback(p=>{if(p.action!=="disconnect"&&p.action!=="connect"&&p.action!=="reload")return;const M=Ae(U.current,p.name),S=Date.now()+Yt,Y=p.action==="disconnect"?{...M,connectedAt:null,disconnectedAt:Date.now(),holdUntil:S}:{...M,disconnectedAt:null,holdUntil:S};U.current={...U.current,[p.name]:Y},P(p.name,Lc(p)),O(B=>B+1)},[P]),J=i.useCallback(async p=>{if(o==="catalog"){const M=Fc(p);if(!M)return null;try{const S=await jc(z,M);return d.setQueryData(T,S),te(p),S.operation?.id??null}catch(S){throw S instanceof vt&&S.status===409&&d.invalidateQueries({queryKey:T}),S}}if(o==="session"&&f){const M=await fe({op:"mcp.control",sessionId:f,control:$c(p)});te(p);const S=ut.list(f),Y=M?.data;return Y&&"servers"in Y&&Array.isArray(Y.servers)?(d.setQueryData(S,Y),null):(d.invalidateQueries({queryKey:S}),Y&&"id"in Y&&typeof Y.id=="string"?Y.id:null)}return null},[o,z,T,d,f,te]),ie=i.useCallback(async p=>{if(o==="catalog"&&I&&(p.action==="connect"||p.action==="disconnect"||p.action==="reload")){try{await fe({op:"mcp.control",sessionId:I,control:{action:p.action,name:p.name,...p.action==="disconnect"?{confirmed:!0}:{}}})}catch(M){throw d.invalidateQueries({queryKey:T}),M}return te(p),await d.invalidateQueries({queryKey:T}),null}return J(p)},[o,I,d,T,J,te]),ve=i.useCallback(async(p,M,S,Y)=>{if(o==="catalog"){const B=await Nc(z,p,M,S,Y);if(B.catalog&&d.setQueryData(T,B.catalog),B.code!=="saved")return{saved:!1,message:tn(B.code,B.failed_ids,M)};try{await J({action:"test",name:p})}catch{}return{saved:!0,message:null}}if(o==="session"&&f){const B=await fe({op:"mcp.credentials.store",sessionId:f,name:p,values:M,confirmedReplace:S});if(B.data?.code!=="saved")return{saved:!1,message:tn(B.data?.code,B.data?.failed_ids??[],M)};try{await J({action:"connect",name:p})}catch{}return{saved:!0,message:null}}return{saved:!1,message:null}},[o,z,T,d,J,f]),me=o==="catalog"?q:W,ge=i.useCallback(()=>{me.refetch()},[me]);return{enabled:o!==null,route:o,sessionId:o==="catalog"?I:f,borrowed:y,noConversation:o==="session"&&!f&&!g,document:D,isLoading:n.isLoading||o==="catalog"&&(K||q.isLoading)||o==="session"&&(f?W.isLoading:g),isError:me.isError,folderUnavailable:Pi(r,_),refetch:ge,readDocument:ne,control:ie,storeKeys:ve,memories:ae,markNeedsKey:re}}function Uc(e){if(e.route==="catalog")return e.queryClient.getQueryData(e.catalogKey);if(e.route==="session"&&e.sessionId){const n=e.queryClient.getQueryData(ut.list(e.sessionId));return n?pt(n,e.sessionId):void 0}}const zc=(e,n)=>{const a=e?.trim();if(!a)return null;const s=fa(a,n);return s.kind==="auth"?{kind:"matched",name:s.name,unresolved:null}:{kind:"miss",asked:a}},Pc=6,it="Integrations",Bc="Let agents use your tools and accounts, like Notion, Linear or GitHub.",Hc={test:"test",connect:"reconnect",disconnect:"disconnect",reload:"reload",remove:"remove",sign_out:"disconnect",cancel:"cancel",login:"grant",reauth:"grant"},Kc=({sessionId:e,sectionRef:n,highlightServer:a})=>{const s=Dc({sessionId:e}),{document:o,control:r,readDocument:l}=s,d=ha(),c=o?.servers??[],u=o?.operations??[],g=o?.project_scope_available??!1,[x,y]=i.useState(!1),[f,k]=i.useState(""),[E,R]=i.useState(null),[K,_]=i.useState({}),[V,z]=i.useState(null),[I,T]=i.useState(null),[Z,L]=i.useState({kind:"ready"}),[X,Q]=i.useState(null),[P,w]=i.useState(null),[q,ee]=i.useState(!1),W=i.useRef({}),D=i.useRef({}),ne=i.useRef({}),U=i.useRef(0),ce=i.useRef(null),O=i.useRef(null),ae=i.useRef(null),[oe,re]=i.useState(null),[te,J]=i.useState(null),[ie,ve]=i.useState(null),me=i.useCallback(()=>{const h=ae.current;ae.current=null,T(null),Q(null),window.setTimeout(()=>{h?.isConnected&&h.focus()},0)},[]),ge=i.useCallback(h=>{const v=window.document.activeElement;ae.current=v instanceof HTMLElement?v:null,T(h)},[]),p=i.useCallback((h,v)=>{J({name:h,waitForSignIn:v==="signed-in",until:Date.now()+Ie,reanchors:0}),me()},[me]),M=i.useMemo(()=>zc(a,c.map(h=>h.name)),[a,c]),S=M?.kind==="matched"?M.name:null,Y=i.useRef(null),B=i.useRef(null),le=f.trim().toLowerCase(),m=i.useMemo(()=>le?c.filter(h=>h.name.toLowerCase().includes(le)):c,[c,le]),b=i.useMemo(()=>Ui(m,u,s.memories),[m,u,s.memories]),N=I?.kind==="sign_in"?c.find(h=>h.name===I.name)??null:null;i.useEffect(()=>{!S||B.current===S||!f||k("")},[S,f]),i.useEffect(()=>{!S||B.current===S||m.some(h=>h.name===S)&&(B.current=S,Y.current?.scrollIntoView({block:"center",behavior:"smooth"}))},[S,m]),i.useEffect(()=>{if(!X)return;const h=u.find(v=>v.id===X)??null;L({kind:"running",operation:h})},[u,X]);const C=u.some(h=>h.status==="running"),G=h=>{const v=window.document.activeElement;v&&v!==window.document.body&&v.isConnected||J({name:h,waitForSignIn:!1,until:Date.now()+Ie,reanchors:0})},F=async(h,v,A)=>{R(h),_(({[h]:Ne,...Se})=>Se);let H=null,xe=!1;try{H=await A()}catch(Ne){xe=!0,_(Se=>({...Se,[h]:Ge(Hc[v]??"status",Ne,C)}))}finally{R(null),v!=="sign_out"&&(v!=="remove"||xe)&&G(h)}return{operationId:H,failed:xe}},ke=h=>c.find(v=>v.name===h),je=h=>{h.source.path&&ga(h.source.path)},tt=async(h,v)=>{L({kind:"starting"}),Q(null);try{const A=await r({action:v,name:h});A?Q(A):L({kind:"running",operation:null})}catch(A){A instanceof vt&&A.code==="oauth_unsupported"&&s.markNeedsKey(h),L({kind:"refused",message:Ge("grant",A,C)})}},Pe=(h,v)=>{switch(v.kind){case"sign_in":case"reauth":{const A=u.find(H=>H.name===h.name&&H.status==="running");A&&ze(A)?(L({kind:"running",operation:A}),Q(A.id)):(L({kind:"ready"}),Q(null)),ge({kind:"sign_in",name:h.name,action:v.kind==="reauth"?"reauth":"login"});return}case"set_key":w(null),ge({kind:"key",name:h.name,keyNames:h.auth.secret_refs.map(A=>A.id)});return;case"fix":je(h);return;case"sign_out":z({name:h.name,kind:"sign_out"});return;default:{const A=v.kind;F(h.name,A,()=>r({action:A,name:h.name}))}}},Ct=(h,v)=>{switch(v.kind){case"remove":case"sign_out":z({name:h.name,kind:v.kind});return;case"sign_in":case"reauth":case"set_key":Pe(h,{kind:v.kind,label:v.label});return;case"open_config":je(h);return;case"copy_setup":navigator.clipboard.writeText(h.setup_prompt??"").then(()=>dt("Setup steps copied. Paste them into a chat.")).catch(()=>{});return;case"cancel":{const A=u.find(H=>H.name===h.name&&H.status==="running");A&&F(h.name,"cancel",()=>r({action:"cancel",operationId:A.id}));return}case"test":case"connect":case"disconnect":case"reload":{const A=v.kind;F(h.name,A,()=>r({action:A,name:h.name}));return}default:return}},Be=(h,v)=>{if(z(null),v==="remove"){const A=h.source.owned_scope;if(!A)return;const H=m.findIndex(xe=>xe.name===h.name);F(h.name,"remove",()=>r({action:"remove",name:h.name,scope:A})).then(({operationId:xe,failed:Ne})=>{Ne||xe!==null||(dt(`Removed ${h.name}.`),H>=0&&ve({index:H}))});return}F(h.name,"sign_out",()=>r({action:"logout",name:h.name})).then(()=>{J({name:h.name,waitForSignIn:!1,until:Date.now()+Ie,reanchors:0})})},He=async h=>{try{return await r({action:"add",name:h.name,scope:h.scope,...h.mode==="command"?{command:h.command,args:h.args}:{url:h.url}}),y(!1),re(h.name),null}catch(v){return Ge("add",v,!1)}},Mt=t.jsxs("div",{className:"flex items-start justify-between gap-4",children:[t.jsxs("div",{className:"min-w-0",children:[t.jsx("h2",{className:"text-heading text-ink",children:it}),t.jsx("p",{className:"mt-1 max-w-2xl text-body-sm text-ink-muted",children:Bc})]}),s.enabled&&c.length>0&&!x?t.jsxs($,{ref:ce,variant:"secondary",size:"sm",onClick:()=>y(!0),"data-tour-tag":"mcp-add-server",children:[t.jsx(Lt,{"aria-hidden":"true"}),"Add integration"]}):null]});if(!s.enabled&&!s.isLoading)return t.jsx(he,{title:it,titleComponent:Mt,sectionRef:n,children:t.jsx(de,{variant:"warning",children:"Integrations need a newer Local Operator backend. Update it and restart the app to manage them here."})});const At=t.jsx(ac,{existingNames:c.map(h=>h.name),projectScopeAvailable:g,projectLabel:o?.cwd?qc(o.cwd):null,onSubmit:He,onCancel:()=>{y(!1),window.setTimeout(()=>ce.current?.focus(),0)}}),Rt=I?ke(I.name):void 0,Un=Object.entries(K).filter(([h])=>!c.some(v=>v.name===h)),zn=h=>_(({[h]:v,...A})=>A);i.useEffect(()=>{if(!oe)return;const h=W.current[oe];if(!h){c.some(v=>v.name===oe)&&(D.current[oe]?.focus(),re(null));return}h.focus(),re(null)},[oe,c]),i.useEffect(()=>{if(!ie)return;const v=m[Math.min(ie.index,m.length-1)]??m.at(-1);if(v){const A=W.current[v.name]??D.current[v.name];if(!A)return;A.focus()}else ce.current?.focus();ve(null)},[ie,m]);const nt=i.useCallback((h,v)=>{const A=l()??o,H=A?.servers.find(Pn=>Pn.name===h.name),xe=A?.operations??[],Ne=H?H.status==="connecting"||Oe(H.name,xe)!==null:!1;Ne&&H&&(U.current=v);const Se=H?jt(H,xe,s.memories):null;if(H&&h.waitForSignIn&&(Se?.kind==="sign_in"||Se?.kind==="reauth"))return"kept";const Re=ic({hold:h,now:v,windowMs:Ie,rowMoving:Ne,lastMovingAt:U.current,candidate:H?lc({primary:Se?W.current[H.name]:null,overflow:D.current[H.name]}):void 0,active:window.document.activeElement,body:window.document.body});if(!Re.hold)return J(null),"finished";if(!Re.land)return"kept";J({name:h.name,waitForSignIn:!1,until:Re.hold.until,landedOn:Re.land,reanchors:Re.hold.reanchors});const Tt=Re.land;return window.setTimeout(()=>{Tt.isConnected&&Tt.focus()},0),"landed"},[l,o,s.memories]);return i.useEffect(()=>{if(!te)return;nt(te,Date.now());let h=0,v=!1;const A=()=>{if(v)return;const H=dc({verdict:nt(te,Date.now()),watchMs:Zt});H!==null&&(h=window.setTimeout(A,H))};return h=window.setTimeout(A,Zt),()=>{v=!0,window.clearTimeout(h)}},[te,nt]),i.useEffect(()=>{if(!te)return;const h=v=>{cc({target:v.target,row:ne.current[te.name]})&&J(null)};return window.document.addEventListener("pointerdown",h,!0),()=>{window.document.removeEventListener("pointerdown",h,!0)}},[te]),t.jsxs(he,{title:it,titleComponent:Mt,sectionRef:n,children:[t.jsxs("div",{className:"flex flex-col gap-4",children:[s.route==="session"&&s.borrowed?t.jsxs("p",{className:"text-body-sm text-ink-muted",children:["Showing the integrations for"," ",s.borrowed.title?.trim()||s.borrowed.session_id.slice(0,6),", your most recent chat."]}):null,s.noConversation?t.jsxs("div",{className:"flex flex-col items-start gap-2",children:[t.jsx("p",{className:"text-body-sm text-ink-muted",children:"Integrations can be managed here once a chat has started."}),t.jsx($,{variant:"primary",size:"sm",onClick:()=>d("/chat"),children:"Start a chat"}),t.jsx("p",{className:"text-ink-dim text-meta",children:"Updating Local Operator removes this step."})]}):null,s.isLoading?t.jsx("div",{className:"flex h-24 items-center justify-center",children:t.jsx(ue,{size:"lg",label:"Loading integrations"})}):null,s.folderUnavailable?t.jsx(de,{variant:"warning",children:t.jsx("span",{children:"This chat's folder no longer exists, so only global integrations are shown."})}):null,s.isError?t.jsx(de,{variant:"warning",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsx("span",{children:"Integrations couldn't be loaded."}),t.jsx($,{variant:"secondary",size:"sm",onClick:s.refetch,children:"Retry"})]})}):null,Un.map(([h,v])=>t.jsx(de,{variant:"warning",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsx("span",{children:v}),t.jsx($,{variant:"ghost",size:"sm",onClick:()=>zn(h),children:"Dismiss"})]})},h)),x&&c.length>0?At:null,c.length>=Pc?t.jsxs("div",{className:"relative",children:[t.jsx(un,{"aria-hidden":"true",className:"pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-ink-dim"}),t.jsx(ye,{ref:O,value:f,onChange:h=>k(h.target.value),onKeyDown:h=>{h.key!=="Escape"||!f||(h.preventDefault(),k(""))},placeholder:`Search ${ki(c.length)}`,"aria-label":"Search integrations",className:"pl-9"})]}):null,M?.kind==="miss"&&c.length>0?t.jsx("p",{className:"text-body-sm text-ink-muted",children:`No integration matches "${M.asked}".`}):null,M?.kind==="matched"&&M.unresolved?t.jsx("p",{className:"text-body-sm text-ink-muted",children:`Showing "${M.name}" — "${M.unresolved}" is not one of your integrations.`}):null,o&&c.length===0&&!s.isLoading?x?At:t.jsxs("div",{className:"flex flex-col items-start gap-3 rounded-lg bg-surface p-6",children:[t.jsx(pn,{"aria-hidden":"true",className:"size-5 text-ink-muted"}),t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("h3",{className:"text-heading text-ink",children:"No integrations yet"}),t.jsx("p",{className:"max-w-xl text-body-sm text-ink-muted",children:"Integrations let agents read and act in your other tools, like Notion or Linear. Add one with a command that runs on this computer, or a server's URL."})]}),t.jsxs($,{variant:"primary",size:"md",onClick:()=>y(!0),"data-tour-tag":"mcp-add-server",children:[t.jsx(Lt,{"aria-hidden":"true"}),"Add integration"]})]}):null,c.length>0&&m.length===0?t.jsxs("div",{className:"flex flex-col items-start gap-2",children:[t.jsx("p",{className:"text-body-sm text-ink-muted",children:"No integrations match this search."}),t.jsx($,{variant:"secondary",size:"sm",onClick:()=>{k(""),window.setTimeout(()=>{(O.current??ce.current)?.focus()},0)},children:"Clear search"})]}):null,b.map(h=>t.jsxs("section",{"aria-labelledby":`integrations-group-${h.id}`,className:"flex flex-col gap-1.5",children:[t.jsxs("h3",{id:`integrations-group-${h.id}`,className:"px-1 text-ink-dim text-meta",children:[h.title," · ",h.rows.length]}),t.jsx("ul",{className:"flex flex-col divide-y divide-hairline overflow-hidden rounded-lg bg-surface",children:h.rows.map(v=>t.jsx(gc,{row:v,operations:u,memories:s.memories,projectScopeAvailable:g,highlighted:v.name===S,rowRef:A=>{ne.current[v.name]=A,v.name===S&&(Y.current=A)},primaryRef:A=>{W.current[v.name]=A},overflowRef:A=>{D.current[v.name]=A},pending:E===v.name,failure:K[v.name]??null,confirm:V?.name===v.name?{kind:V.kind}:null,onPrimary:A=>Pe(v,A),onOverflow:A=>Ct(v,A),onConfirm:()=>V&&Be(v,V.kind),onCancelConfirm:()=>{z(null),window.setTimeout(()=>{D.current[v.name]?.focus()},0)}},v.id))})]},h.id))]}),I?.kind==="sign_in"?t.jsx(bc,{name:I.name,action:I.action,keyRoute:N?Xe(N):!1,phase:Z,onStart:()=>void tt(I.name,I.action),onCancel:h=>void r({action:"cancel",operationId:h}).catch(()=>{}),onOpenLink:h=>void pa(h),onClose:h=>p(I.name,h)}):null,I?.kind==="key"?t.jsx(hc,{name:I.name,keyNames:I.keyNames.length?I.keyNames:Rt?.auth.secret_refs.map(h=>h.id)??[],keyless:I.keyNames.length===0,savedKeys:Rt?.auth.secret_refs.filter(h=>h.state==="encrypted").map(h=>h.id),saving:q,failure:P,onClose:me,onSave:(h,v,A)=>{ee(!0),w(null),s.storeKeys(I.name,h,v,A).then(H=>{if(!H.saved){w(H.message);return}T(null),J({name:I.name,waitForSignIn:!1,until:Date.now()+Ie,reanchors:0})}).catch(H=>w(Ge("key",H,!1))).finally(()=>ee(!1))}}):null]})},Ie=4e3,Gc=/^\/(?:Users|home)\/[^/]+(?=\/|$)/,qc=e=>e.replace(Gc,"~"),Vc=e=>typeof e!="number"||!Number.isFinite(e)?"your free credits":`$${e.toFixed(2)} in free credits`,Yc="https://console.radienthq.com/dashboard/verification",Wc=(e,n)=>e==="pending"?{sentence:`Verify your email to claim ${n}. Check your inbox for the link Radient sent.`,action:"Open verification page"}:e==="expired"?{sentence:`The link to claim ${n} has expired. Request a new one from the verification page.`,action:"Request a new link"}:{sentence:"No signup grant is attached to this account. Open the verification page to check the account.",action:"Open verification page"},Zc=({verification:e})=>{const{prices:n}=va(),a=e.grant_amount??n?.default_new_credits,{sentence:s,action:o}=Wc(e.signup_grant,Vc(a)),r=e.claim_url||Yc;return t.jsxs("div",{className:"mt-8 flex items-start gap-3 rounded-sm border border-hairline bg-surface p-3",children:[t.jsx(Qe,{className:"mt-0.5 size-4 shrink-0 text-ink-muted","aria-hidden":"true"}),t.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-2",children:[t.jsx("p",{className:"text-body-sm text-ink",children:s}),t.jsx($,{variant:"secondary",size:"sm",onClick:()=>{window.api?.openExternal?window.api.openExternal(r):window.open(r,"_blank")},children:o})]})]})},Qc=({onAfterCredentialUpdate:e})=>{const{isAuthenticated:n,user:a,isLoading:s,accountRead:o,signOut:r}=xa(),l=fn(x=>x.isSigningOut),d=i.useCallback(async()=>{try{await r()}catch(x){console.error("Error signing out:",x)}},[r]),c=i.useMemo(()=>{if(!n||!a?.radientUser)return null;const{account:x,identity:y,verification:f}=a.radientUser,k=f!=null&&!f.email_verified&&f.signup_grant!=="claimed";return t.jsxs(t.Fragment,{children:[t.jsxs(kt,{children:[t.jsx(pe,{label:"Status",value:t.jsxs("span",{className:"inline-flex items-center gap-2",children:["Connected",t.jsx(kn,{variant:"success",className:"capitalize",children:x.status})]})}),t.jsx(pe,{label:"Name",value:x.name||"Not provided"}),t.jsx(pe,{label:"Email",value:x.email}),t.jsx(pe,{label:"Account ID",value:t.jsx("span",{className:"text-mono-sm",children:x.id})}),t.jsx(pe,{label:"Tenant ID",value:t.jsx("span",{className:"text-mono-sm",children:x.tenant_id})}),t.jsx(pe,{label:"Provider",value:t.jsx("span",{className:"capitalize",children:y.provider})}),t.jsx(pe,{label:"Created",value:gn(x.created_at)})]}),k&&f?t.jsx(Zc,{verification:f}):null,t.jsxs("div",{className:"mt-8",children:[t.jsx("p",{className:"text-body-sm text-ink-muted",children:"Need to sign out or switch accounts?"}),t.jsxs($,{variant:"danger",className:"mt-3",onClick:d,children:[t.jsx(ya,{}),"Sign out from Radient"]})]})]})},[n,a?.radientUser,d]),u=i.useMemo(()=>o==="refused"?"Radient refused the sign-in this app is holding, so your account details could not be read. Signing in again below replaces it.":xn(o)?"Your Radient account could not be read, so this app cannot show your account details.":"You are not currently signed in to Radient.",[o]),g=i.useMemo(()=>n&&a?null:t.jsxs("div",{children:[t.jsxs("p",{className:"text-body-sm text-ink-muted",children:[u," Sign in to access your account details or sign up to get free credits and unified access to models, tools, and more with Radient Pass. Radient's automatic model router will automatically select the best model for your agents to balance cost and performance. It is often cheaper to use Radient Pass than to use single AI providers due to automatic cost optimization."]}),t.jsx("div",{className:"mt-6",children:t.jsx(os,{titleText:"",onAfterCredentialUpdate:e,descriptionText:"",onSignInSuccess:()=>{}})})]}),[n,a,u,e]);return s||l?t.jsxs("div",{className:"flex min-h-36 flex-col items-center justify-center gap-3",children:[t.jsx(ue,{size:"lg",label:"Loading account"}),!l&&t.jsx("p",{className:"text-meta text-ink-dim",children:"Loading your Radient account details…"})]}):n&&a?.radientUser?c:t.jsx("div",{className:"flex flex-col gap-4",children:g})};function Jc({metric:e,data:n}){return t.jsx(ka,{title:"",heightClassName:"h-62",yAxisWidth:48,unit:e==="credits"?"credits":"tokens",srSummary:`${e==="credits"?"Credits consumed":"Tokens used"} over the last 30 days, plotted per day across ${n.length} days.`,xTickFormatter:a=>a,yTickFormatter:a=>e==="credits"?`$${a.toFixed(2)}`:ba(a),children:t.jsx(Mr,{data:n,children:t.jsx(cn,{type:"monotone",dataKey:"value",strokeWidth:2,dot:!1,activeDot:{r:4,strokeWidth:0},name:e==="credits"?"Credits consumed":"Tokens used"})})})}const Xc=()=>{const{data:e,isLoading:n,error:a,refetch:s}=Nr(),o=Sr(),[r,l]=i.useState(""),[d,c]=i.useState(!1);i.useEffect(()=>{l(e?.content??""),c(!1)},[e]);const u=k=>{const E=k.target.value;l(E),c(E!==(e?.content??""))},g=async()=>{if(!(!d||o.isPending))try{const k={content:r};await o.mutateAsync(k),await s(),c(!1)}catch(k){console.error("Error updating system prompt:",k)}},x=()=>{l(e?.content??""),c(!1)},y=o.isPending,f=()=>t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsxs("div",{className:"flex flex-col gap-2",children:[t.jsx(we,{htmlFor:"app-system-prompt",children:"Instructions"}),t.jsx(Je,{id:"app-system-prompt",name:"systemPrompt",value:r,onChange:u,placeholder:"Enter instructions for how all agents should behave and respond to your requests...",className:"min-h-50"})]}),t.jsxs("div",{className:"flex gap-3",children:[t.jsxs($,{variant:"primary",onClick:g,disabled:!d||y,children:[y?t.jsx(ue,{size:"sm"}):t.jsx(wa,{}),y?"Saving...":"Save changes"]}),t.jsx($,{onClick:x,disabled:!d||y,children:"Cancel"})]}),e?.last_modified&&t.jsxs("p",{className:"text-ink-dim text-meta",children:["Last modified:"," ",t.jsx("span",{className:"font-mono text-mono-sm",children:yn(e.last_modified)})]})]});return t.jsx(he,{title:"System prompt",icon:rs,description:"Every Local Operator agent receives this prompt in addition to its own instructions, so it is the place for baseline expectations and for details you want every agent to know about you, such as your name, location, or preferences. It is sent to your selected hosting provider.",children:n?t.jsx("div",{className:"flex min-h-50 items-center justify-center",children:t.jsx(ue,{size:"lg",label:"Loading system prompt"})}):a?t.jsxs(de,{variant:"danger",children:["Failed to load system prompt:"," ",a instanceof Error?a.message:"Unknown error"]}):f()})},el=["ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Home","End"],tl=e=>el.includes(e),nl=e=>{const n=[];let a=0;for(const s of e){const o=Math.max(0,Math.floor(s.count)),r=Math.max(1,Math.floor(s.columns));for(let l=0;l<o;l+=r)n.push({start:a+l,count:Math.min(r,o-l)});a+=o}return n},al=({index:e,key:n,groups:a})=>{const s=nl(a),o=s.reduce((r,l)=>r+l.count,0);if(!Number.isInteger(e)||e<0||e>=o)return e;switch(n){case"Home":return 0;case"End":return o-1;case"ArrowLeft":return Math.max(0,e-1);case"ArrowRight":return Math.min(o-1,e+1);case"ArrowUp":case"ArrowDown":{const r=s.findIndex(c=>e>=c.start&&e<c.start+c.count),l=s[r+(n==="ArrowDown"?1:-1)];if(!l)return e;const d=e-s[r].start;return l.start+Math.min(d,l.count-1)}default:return e}},sl={localOperatorDark:To,localOperatorLight:Qo,dracula:Ho,dune:so,sage:_o,monokai:Na,tokyoNight:Lo,iceberg:Go,radient:xo,neon:_r,obsidian:_n,synth:xs,catppuccinMocha:Hs,catppuccinLatte:Co,tokyoNightStorm:Ls,gruvbox:Ns,nord:br,oneDark:fs,solarizedDark:Wo,rosePine:co,rosePineMoon:Ao,rosePineDawn:Ps,alucard:uo,gruvboxLight:Zs,tokyoNightDay:Oo,oneLight:No,catppuccinFrappe:Ys,catppuccinMacchiato:vo,palenight:ja,everforest:ur,everforestLight:lr,kanagawaWave:xr,kanagawaLotus:ro,ayuDark:Js,ayuMirage:eo,ayuLight:Uo,nightfox:$s,duskfox:tr,synthwave:$o,matrix:vs,tron:Os,cyberpunk:_a,vaporwave:ir,outrun:_s,neonNoir:hr,arcade:bo,forest:or,ocean:no,desert:ar,autumn:vr,lavender:Vo,arctic:Us,rosewood:fo,solarizedLight:Xo,githubLight:ho,paper:is,linen:Po,highContrastLight:hs,mintLight:bs},nn="bg-[color-mix(in_srgb,var(--color-accent)_8%,var(--color-accent-wash))]",ol=({id:e})=>t.jsxs("div",{"data-theme":e,"aria-hidden":"true",className:"flex h-full bg-canvas",children:[t.jsxs("div",{className:"flex w-1/4 flex-col gap-1 bg-sunken p-1",children:[t.jsx("span",{className:"flex h-2.5 items-center rounded-xs bg-accent-wash px-1",children:t.jsx("span",{className:"h-1 w-full rounded-xs bg-accent"})}),t.jsx("span",{className:"mx-1 h-1 w-2/3 rounded-xs bg-ink-dim"}),t.jsx("span",{className:"mx-1 h-1 w-1/2 rounded-xs bg-ink-dim"})]}),t.jsxs("div",{className:"flex flex-1 flex-col justify-between p-1",children:[t.jsxs("div",{className:"flex flex-col gap-1 rounded-xs bg-surface p-1",children:[t.jsx("span",{className:"h-1 w-3/5 rounded-xs bg-ink"}),t.jsx("span",{className:"h-1 w-full rounded-xs bg-ink-dim"})]}),t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"h-2.5 w-6 rounded-xs bg-elevated"}),t.jsx("span",{className:"h-2.5 w-5 rounded-xs bg-accent"}),t.jsx("span",{className:"h-2.5 w-4 rounded-xs bg-accent-alt"}),t.jsx("span",{className:"h-2.5 w-4 rounded-xs border border-control"})]})]})]}),rl=({id:e,name:n,description:a,isSelected:s,isTabStop:o,onSelect:r,onFocusTile:l})=>{const d=sl[e];return t.jsx($e,{side:"bottom",align:"start",content:a,children:t.jsxs("button",{type:"button","data-theme-tile":e,"aria-pressed":s,tabIndex:o?0:-1,onFocus:l,onClick:r,className:se("relative flex flex-col gap-1.5 rounded-md p-1 text-left transition-colors duration-fast ease-out-quart",s?nn:"hover:bg-surface"),children:[t.jsxs("span",{className:se("relative block h-10 overflow-hidden rounded-sm border transition-colors duration-fast ease-out-quart",s?"border-accent":"border-hairline"),children:[t.jsx(ol,{id:e}),s&&t.jsx("span",{className:se("pointer-events-none absolute top-0.5 right-0.5 flex h-4 w-4 items-center justify-center rounded-full",nn),children:t.jsx(ss,{size:12,className:"text-accent","aria-hidden":"true"})})]}),t.jsxs("span",{className:"flex items-center gap-1.5",children:[t.jsx(d,{size:12,className:"shrink-0 text-ink-dim","aria-hidden":"true"}),t.jsx("span",{className:"min-w-0 flex-1 truncate text-meta text-ink",children:n})]})]})})},il=e=>[...e.querySelectorAll("[data-theme-grid]")].map(n=>{const a=[...n.querySelectorAll("[data-theme-tile]")],s=a[0]?.getBoundingClientRect().top??0;return{count:a.length,columns:Math.max(1,a.filter(o=>Math.abs(o.getBoundingClientRect().top-s)<1).length)}}),cl=()=>{const{themeName:e,setTheme:n}=mt(),a=i.useMemo(()=>{const d=Object.values(Bn);return[{label:"Dark",items:d.filter(c=>c.theme.palette.mode==="dark")},{label:"Light",items:d.filter(c=>c.theme.palette.mode==="light")}].filter(c=>c.items.length>0)},[]),[s,o]=i.useState(null),r=i.useMemo(()=>{const d=a.flatMap(c=>c.items.map(u=>u.id));return s&&d.includes(s)?s:d.includes(e)?e:d[0]},[a,s,e]),l=d=>{if(!tl(d.key))return;const c=[...d.currentTarget.querySelectorAll("[data-theme-tile]")],u=c.indexOf(d.target);if(u<0)return;d.preventDefault();const g=al({index:u,key:d.key,groups:il(d.currentTarget)});g!==u&&c[g]?.focus()};return t.jsx(as,{children:t.jsx("div",{onKeyDown:l,className:"flex flex-col gap-6",children:a.map(d=>t.jsxs("div",{children:[t.jsx("h3",{className:"px-1 pb-2 text-meta text-ink-dim",children:d.label}),t.jsx("div",{"data-theme-grid":d.label,className:"grid grid-cols-[repeat(auto-fill,minmax(160px,1fr))] gap-2",children:d.items.map(({id:c,name:u,description:g})=>t.jsx(rl,{id:c,name:u,description:g,isSelected:c===e,isTabStop:c===r,onSelect:()=>n(c),onFocusTile:()=>o(c)},c))})]},d.label))})})},ll=()=>{const{data:e,isLoading:n,error:a}=Tr({enabled:!0});return t.jsxs("div",{children:[t.jsxs("h3",{className:"mb-3 flex items-center gap-2 text-heading text-ink",children:[t.jsx(qs,{size:16,className:"shrink-0 text-ink-dim"}),"Radient Pass"]}),n&&t.jsx(bn,{className:"h-6 w-36"}),a&&t.jsxs(de,{variant:"warning",children:["Could not load your credit balance. ",a.message]}),e&&!n&&!a&&t.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center",children:[t.jsxs("p",{className:"flex-1 text-body-sm text-ink-muted",children:["Available credits"," ",t.jsx("span",{className:"font-medium text-ink",children:e.balance.toFixed(2)})]}),t.jsx($,{variant:"secondary",size:"sm",asChild:!0,children:t.jsxs("a",{href:"https://console.radienthq.com/dashboard/billing",target:"_blank",rel:"noopener noreferrer",children:[t.jsx(Ts,{}),"Add credits"]})})]})]})},dl=[{id:"credits",label:"Credits"},{id:"tokens",label:"Tokens"}],ul=()=>{const[e,n]=i.useState("credits"),a=i.useMemo(()=>{const d=new Date,c=Ar(d);return{start_date:Bt(c),end_date:Bt(d),rollup:"daily"}},[]),{data:s,isLoading:o,error:r}=Or(a,{enabled:!0}),l=i.useMemo(()=>s?.data_points?[...s.data_points].sort((c,u)=>at(c.timestamp).getTime()-at(u.timestamp).getTime()).map(c=>({bucket:za(ds(at(c.timestamp),"yyyy-MM-dd")),value:e==="credits"?Number.parseFloat(c.total_cost.toFixed(2)):c.total_tokens})):[],[s,e]);return t.jsxs("div",{children:[t.jsxs("div",{className:"mb-5 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[t.jsxs("h3",{className:"flex items-center gap-2 text-heading text-ink",children:[t.jsx(Cs,{size:16,className:"shrink-0 text-ink-dim"}),"Usage (last 30 days)"]}),t.jsxs("fieldset",{className:"m-0 w-fit border-0 p-0",children:[t.jsx("legend",{className:"sr-only",children:"Usage metric"}),t.jsx("div",{className:"flex gap-0.5 rounded-md bg-sunken p-0.5",children:dl.map(({id:d,label:c})=>t.jsx($,{variant:"ghost",size:"sm","aria-pressed":e===d,onClick:()=>n(d),className:se(e===d&&"bg-surface text-ink hover:bg-surface"),children:c},d))})]})]}),o&&t.jsx(bn,{className:"h-62 w-full"}),r&&t.jsxs(de,{variant:"warning",children:["Could not load your usage data. ",r.message]}),!o&&!r&&s&&l.length>0&&t.jsx(Jc,{metric:e,data:l}),!o&&!r&&(!s||l.length===0)&&t.jsx("p",{className:"text-body-sm text-ink-muted",children:"No usage recorded in the last 30 days."})]})},ml=()=>t.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[t.jsxs("h2",{className:"flex items-center gap-2 text-heading text-ink",children:[t.jsx(Pa,{size:16,className:"shrink-0 text-ink-dim"}),"Radient account"]}),t.jsx($,{variant:"secondary",size:"sm",className:"self-start sm:self-center",asChild:!0,children:t.jsxs("a",{href:"https://console.radienthq.com",target:"_blank",rel:"noopener noreferrer",children:["Go to Radient console",t.jsx(Ba,{})]})})]}),_l=()=>{const e=Sa(),n=mt(p=>p.showAgentReasoning),a=mt(p=>p.setShowAgentReasoning),{data:s,isLoading:o,isFetching:r,error:l,refetch:d}=Ca(),c=wn(),{sentence:u,remedy:g}=mn(c,"Your settings could not be loaded.",l),x=Ma(),[y,f]=i.useState(null),k=fn(),{isAuthenticated:E,accountRead:R,isFetching:K,isRefreshing:_,refreshUser:V}=xt(),z=qe(p=>p.activeSessionId),[I,T]=i.useState("general"),[Z,L]=i.useState(!1),X=i.useRef(null),Q=i.useRef(null),{startTour:P}=Aa(),w=Ra(),{data:q,refetch:ee}=Ta(),{refreshModels:W}=Ea(),D=i.useMemo(()=>q?.keys?[...q.keys].sort():[],[q?.keys]),ne=i.useRef({keys:"",hosting:void 0});i.useEffect(()=>{const p=D.join(","),M=s?.values?.hosting;(ne.current.keys!==p||ne.current.hosting!==M)&&(ne.current={keys:p,hosting:M},W().catch(S=>{console.error("Failed to refresh models after credentials or hosting change:",S)}))},[D,s?.values?.hosting,W]);const U=i.useRef({general:i.useRef(null),radient:i.useRef(null),integrations:i.useRef(null),appearance:i.useRef(null),providers:i.useRef(null),backend:i.useRef(null),updates:i.useRef(null)}).current,ce=i.useMemo(()=>new URLSearchParams(w.search).get("setting"),[w.search]),O=i.useMemo(()=>new URLSearchParams(w.search).get("filter")??"",[w.search]),ae=i.useMemo(()=>new URLSearchParams(w.search).get("mcp")??void 0,[w.search]),oe=i.useMemo(()=>new URLSearchParams(w.search).get("provider"),[w.search]),re=i.useCallback(p=>{T(p),L(!0);const M=U[p],S=Q.current;if(M?.current&&S){const B=M.current.getBoundingClientRect().top-S.getBoundingClientRect().top;S.scrollHeight>S.clientHeight?S.scrollTo({top:Math.max(0,S.scrollTop+B-80),behavior:"smooth"}):window.scrollTo({top:Math.max(0,M.current.getBoundingClientRect().top+window.scrollY-80),behavior:"smooth"}),clearTimeout(X.current??void 0),X.current=setTimeout(()=>{L(!1),X.current=null},800)}else L(!1)},[U]);i.useEffect(()=>{const p=setTimeout(()=>{const M=Q.current;if(!M)return;const S=()=>{if(Z)return;const Y=M.getBoundingClientRect(),B=Y.height;let le="",m=0;for(const[b,N]of Object.entries(U))if(N.current){const C=N.current.getBoundingClientRect(),G=Y.top,F=C.top-G,ke=C.bottom-G,je=C.height,tt=Math.max(0,F),Pe=Math.min(B,ke),Be=Math.max(0,Pe-tt)/je,He=Be+(F<B*.3?.1:0);He>m&&Be>.1&&(m=He,le=b)}le&&le!==I&&T(le)};return S(),M.addEventListener("scroll",S,{passive:!0}),()=>{M.removeEventListener("scroll",S),clearTimeout(X.current??void 0)}},100);return()=>clearTimeout(p)},[U,I,Z]),i.useEffect(()=>{const p=new URLSearchParams(w.search),M=p.get("section"),S=p.get("setting")?"backend":M,Y=S?U[S]:void 0;if(!S||!Y)return;let B=!1,le=Number.NaN,m=0;const b=window.setTimeout(()=>{B||(B=!0,C.disconnect(),re(S))},2e3),N=()=>{if(B)return;const G=Y.current;if(!G){m=requestAnimationFrame(N);return}const F=Math.round(G.getBoundingClientRect().top+window.scrollY);if(F===le&&F>0){B=!0,C.disconnect(),window.clearTimeout(b),re(S);return}le=F,m=requestAnimationFrame(N)},C=new ResizeObserver(()=>{B||(cancelAnimationFrame(m),m=requestAnimationFrame(N))});return Q.current&&C.observe(Q.current),m=requestAnimationFrame(N),()=>{B=!0,cancelAnimationFrame(m),C.disconnect(),window.clearTimeout(b)}},[w.search,U,re]);const te=async(p,M)=>{f(p);try{await x.mutateAsync({[p]:M}),await d()}catch(S){console.error(`Error updating ${p}:`,S)}finally{f(null)}},J=o,ie=R==="checking",ve=xn(R),me=R==="ready"||R==="checking"||K,ge=an(J,4e3);return l?t.jsx("div",{className:"flex h-full w-full items-center justify-center bg-canvas p-6",children:t.jsx(de,{variant:"warning",className:"w-full max-w-xl",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsx("span",{children:u}),g&&t.jsx($,{variant:"secondary",size:"sm",className:"shrink-0",onClick:()=>void d(),disabled:r,children:r?"Retrying":"Retry"})]})})}):J?t.jsxs("div",{role:"status",className:"flex h-full w-full flex-col items-center justify-center gap-3 bg-canvas",children:[t.jsx(ue,{size:"lg",label:ge?void 0:"Loading settings"}),ge&&t.jsx("p",{className:"max-w-sm text-center text-body-sm text-ink-muted",children:"The Local Operator server is taking longer than usual to answer. If it does not respond, you will be able to retry from here."})]}):s?t.jsxs("div",{className:"flex h-full w-full overflow-hidden bg-canvas",children:[t.jsx("div",{ref:e,className:"w-12 shrink-0 overflow-y-auto border-r border-hairline min-[1040px]:w-55",children:t.jsx(Oa,{activeSection:I,onSelectSection:re,sections:Ia})}),t.jsx("div",{ref:Q,"data-settings-content":!0,"data-tour-tag":"settings-general-section",className:"flex-1 overflow-y-auto overflow-x-hidden p-4 sm:p-6 md:p-8",children:t.jsxs("div",{className:"mx-auto flex w-full max-w-4xl flex-col gap-8 pb-8",children:[t.jsx(Ha,{title:"Settings",icon:Ft}),t.jsxs("div",{className:"flex flex-col gap-8",children:[t.jsxs("div",{ref:U.general,className:"flex flex-col gap-8",children:[t.jsxs(he,{title:"User profile",icon:La,description:`Your user profile information displayed in the application. This information is not provided to the agents. ${E?"These details are provided through your Radient account.":""}`,children:[ie&&t.jsx("p",{className:"text-meta text-ink-dim",children:"Checking your Radient account…"}),ve&&t.jsx(de,{variant:"warning",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsxs("span",{children:["Your Radient account could not be read, so the name and email below are placeholders rather than your account details.",R==="refused"?" Retry, or sign in to Radient again.":" Retry."]}),t.jsx($,{variant:"secondary",size:"sm",className:"shrink-0",onClick:()=>V(),disabled:_,children:_?"Retrying":"Retry"})]})}),t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsx($t,{value:k.profile.name,label:"Display name",placeholder:"Enter your name...",isSaving:y==="user_name",onSave:async p=>{f("user_name");try{k.updateName(p)}finally{f(null)}},readOnly:me}),t.jsx($t,{value:k.profile.email,label:"Email address",placeholder:"Enter your email...",isSaving:y==="user_email",onSave:async p=>{f("user_email");try{k.updateEmail(p)}finally{f(null)}},readOnly:me})]})]}),t.jsx(he,{title:"Application tour",description:"Missed the application onboarding tour or want a refresher? Start it again here.",children:t.jsxs($,{variant:"secondary",onClick:()=>{P({forceModalCompleted:!0})},children:[t.jsx(As,{}),"Take the tour"]})}),t.jsx(he,{id:"model-settings",title:"Model settings",icon:Fa,description:"Configure the default AI model and hosting providers used for generating responses. This will be used for all agents that don't have a specific model or hosting provider configured. You can override these settings for individual agents in the agent settings.",children:t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsx($a,{value:s.values.hosting,isSaving:y==="hosting",onSave:p=>te("hosting",p),filterByCredentials:!0,allowCustom:!0,allowDefault:!1,emptyHelperText:"No hosting providers available. Sign in to a provider, or add a provider's API key below, under Providers."}),t.jsx(Da,{value:s.values.model_name,hostingId:s.values.hosting,isSaving:y==="model_name",onSave:p=>te("model_name",p),allowCustom:!0,allowDefault:!1}),t.jsx(de,{variant:"neutral",icon:t.jsx(Qe,{className:"size-4","aria-hidden":"true"}),children:"You need a Radient account or your own API keys to reach cloud providers. If you don't see more hosting providers and models here, sign in to Radient, or add a provider's API key below, under Providers."})]})}),t.jsx(Xc,{}),t.jsx(he,{title:"Configuration information",icon:Qe,description:"System information about the current configuration.",children:t.jsxs(kt,{children:[t.jsx(pe,{label:"Version",value:t.jsx("span",{className:"text-mono-sm",children:s.version})}),t.jsx(pe,{label:"Created",value:gn(s.metadata.created_at)}),t.jsx(pe,{label:"Last modified",value:yn(s.metadata.last_modified)}),t.jsx(pe,{label:"Description",value:s.metadata.description||"No description available"})]})})]}),t.jsx(he,{title:"Appearance",icon:_n,description:"Customize the look and feel of Local Operator",sectionRef:U.appearance,dataTourTag:"settings-appearance-section",children:t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsx(cl,{}),t.jsx(Cr,{value:n,label:"Show agent reasoning",description:"Adds the agent's Reasoning and Thinking rows to conversations. They stay closed until you open one.",onChange:async p=>a(p)})]})}),t.jsx(he,{title:"Model providers",icon:pn,description:"Sign in to the services your agents think with. New chats use your default model.",sectionRef:U.providers,children:t.jsx(Ua,{initialProviderId:oe,onChangeModel:()=>re("general")})}),t.jsx(Kc,{sessionId:z??void 0,sectionRef:U.integrations,highlightServer:ae}),t.jsx(he,{title:"Radient account",titleComponent:t.jsx(ml,{}),description:"Your Radient account, Radient Pass details and credits. To use Radient models, sign in under Model providers.",sectionRef:U.radient,dataTourTag:"settings-radient-account-section",children:t.jsxs("div",{className:"flex flex-col gap-8",children:[t.jsx(Qc,{onAfterCredentialUpdate:()=>{W(),ee()}}),E&&t.jsxs(t.Fragment,{children:[t.jsx(ll,{}),t.jsx(ul,{})]})]})}),t.jsx(he,{title:"Backend settings",icon:Ft,description:"Every setting the backend registry owns, searchable, with typed editors and scopes.",sectionRef:U.backend,children:t.jsx(yi,{focusKey:ce,initialFilter:O})}),t.jsx("div",{ref:U.updates,children:t.jsx(Fr,{})})]})]})})]}):t.jsx("div",{className:"flex h-full w-full items-center justify-center bg-canvas p-6",children:t.jsx(de,{variant:"warning",className:"w-full max-w-xl",children:"Your settings could not be loaded."})})};export{_l as SettingsPage};
|