@cuongtran001/kanna 1.83.2 → 1.84.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/assets/{BoardsPage-mm_dy-6I.js → BoardsPage-DjXjDuRd.js} +1 -1
- package/dist/client/assets/{BoardsRoutePage-B7dJA_QL.js → BoardsRoutePage-BZzJC4M6.js} +1 -1
- package/dist/client/assets/{ChatPage-Bw4peAkb.js → ChatPage-hEXrvtW-.js} +3 -3
- package/dist/client/assets/{CronJobRow-DKW6LnKe.js → CronJobRow-BLAAn194.js} +1 -1
- package/dist/client/assets/{CronJobsPage-CBxttYFH.js → CronJobsPage-W6GlW2Uy.js} +1 -1
- package/dist/client/assets/{CronRunMessage-B4x7mzzh.js → CronRunMessage-D0Qoy3uj.js} +1 -1
- package/dist/client/assets/{FilePreviewSheet-iaBNZ_R0.js → FilePreviewSheet-04ZguH1k.js} +1 -1
- package/dist/client/assets/{FlowSurface-B3kKtCHA.js → FlowSurface-Bs2DOgfu.js} +1 -1
- package/dist/client/assets/{GenUIBlock-CMM23p8L.js → GenUIBlock-CHl_B-Nm.js} +2 -2
- package/dist/client/assets/{InboxPage-C_QKGmlx.js → InboxPage-DW8ljScO.js} +1 -1
- package/dist/client/assets/{KannaSocketProvider-Clv949La.js → KannaSocketProvider-Bw4DvDDN.js} +1 -1
- package/dist/client/assets/{LocalProjectsPage-BLF1dYUW.js → LocalProjectsPage-DUp1SEg-.js} +1 -1
- package/dist/client/assets/{SettingsPage-CITPPDfV.js → SettingsPage-BiXGmGWw.js} +4 -4
- package/dist/client/assets/{StackBoardsRoutePage-BX-fo655.js → StackBoardsRoutePage-DUe7ECRH.js} +1 -1
- package/dist/client/assets/{ToolCallMessage-BbLzqXn7.js → ToolCallMessage-1gGAiUVa.js} +1 -1
- package/dist/client/assets/{VChartSurface-D9jlaiQA.js → VChartSurface-D5E7i7Qk.js} +1 -1
- package/dist/client/assets/WebhooksPage-Dc_dYxqW.js +4 -0
- package/dist/client/assets/{WorkflowsPage-ndxOqUWo.js → WorkflowsPage-Dt_YJIYD.js} +1 -1
- package/dist/client/assets/{WorkflowsSection-DgbttKnk.js → WorkflowsSection-Dn5NLie_.js} +1 -1
- package/dist/client/assets/{appSettingsStore-CDBkjKuH.js → appSettingsStore-BBfwETzX.js} +1 -1
- package/dist/client/assets/{arrow-left-DOANYNxC.js → arrow-left-CfIaqB4b.js} +1 -1
- package/dist/client/assets/{chart-renderer-Cw-dI71U.js → chart-renderer-DFgyTjFH.js} +1 -1
- package/dist/client/assets/{chatSounds-Cjf1Ow1m.js → chatSounds-DnB6LG-Z.js} +1 -1
- package/dist/client/assets/chevron-down-C3wqMsmk.js +1 -0
- package/dist/client/assets/chevron-left-D3epb-3S.js +1 -0
- package/dist/client/assets/{clipboard.adapter-BCxT7Qli.js → clipboard.adapter-hbKWYB9v.js} +1 -1
- package/dist/client/assets/{columnStyle-aXeR3SrA.js → columnStyle-C7KkAG5L.js} +1 -1
- package/dist/client/assets/{contextWindow-I-trSDu4.js → contextWindow-DXZRM56M.js} +1 -1
- package/dist/client/assets/{copyFeedbackStore-BW6Vjufv.js → copyFeedbackStore-D3VJJOPQ.js} +1 -1
- package/dist/client/assets/{createScopedStore-D1trFyJw.js → createScopedStore-BOB83agV.js} +1 -1
- package/dist/client/assets/{cronJobsStore-CndqKrjB.js → cronJobsStore-Bmd92Wdu.js} +1 -1
- package/dist/client/assets/{ellipsis-CFHwUFtG.js → ellipsis-CjyUt6mM.js} +1 -1
- package/dist/client/assets/{external-link-9xEpmM2n.js → external-link-DIOTFxAO.js} +1 -1
- package/dist/client/assets/{flow-kinds-DnUaQXgl.js → flow-kinds-CVdBVMES.js} +1 -1
- package/dist/client/assets/{folder-Bg7BAFNU.js → folder-CZMcdIZq.js} +1 -1
- package/dist/client/assets/{genui-jdDJe0VI.js → genui-Dwk7MqBN.js} +1 -1
- package/dist/client/assets/{globe-CeniwLw3.js → globe-BGOCLzBK.js} +1 -1
- package/dist/client/assets/{host-BNDj5_aa.js → host-Bn7kXks2.js} +1 -1
- package/dist/client/assets/{inbox-C62UubNn.js → inbox-OLNazs7P.js} +1 -1
- package/dist/client/assets/{inboxStore-Bks9mpiK.js → inboxStore-DkhqWd7E.js} +1 -1
- package/dist/client/assets/{index-Dp3JEZQ3.js → index-B1Wsyw2i.js} +3 -3
- package/dist/client/assets/{info-BMdKmB36.js → info-BUS8wzM_.js} +1 -1
- package/dist/client/assets/{input-CS1DBeNV.js → input-CvrFJg7l.js} +1 -1
- package/dist/client/assets/{lexicalToReact-CkI42EHr.js → lexicalToReact-TD2k-lRz.js} +3 -3
- package/dist/client/assets/{log-3sQ-5rrS.js → log-DeYiYzru.js} +1 -1
- package/dist/client/assets/{monitor-_V-BjQpD.js → monitor-BiV6DsHv.js} +1 -1
- package/dist/client/assets/{pencil-BTeN1rO_.js → pencil-D4taLrpW.js} +1 -1
- package/dist/client/assets/{pendingActionsStore-C9wopHr4.js → pendingActionsStore-2LSejcqM.js} +1 -1
- package/dist/client/assets/{play-C_g7W9ao.js → play-C_RZ57yb.js} +1 -1
- package/dist/client/assets/{plus-D0uUa5kJ.js → plus-Dt1R6Ec0.js} +1 -1
- package/dist/client/assets/{popover-CA332KD1.js → popover-Byr25LbG.js} +1 -1
- package/dist/client/assets/runDetached-CZb0BmgP.js +1 -0
- package/dist/client/assets/{search-48C1GM_8.js → search-DLUiqdl3.js} +1 -1
- package/dist/client/assets/{searchable-select-C2LG0o1C.js → searchable-select-0lGC5Dbu.js} +1 -1
- package/dist/client/assets/{segmented-control-DbmDSdKy.js → segmented-control-A3JAN-14.js} +1 -1
- package/dist/client/assets/{select-BKHnGLKS.js → select-k2e8CCUh.js} +1 -1
- package/dist/client/assets/{settings-header-button-D4w0LZ-R.js → settings-header-button-Ba-h5PgF.js} +1 -1
- package/dist/client/assets/{sidebarPendingActions-BQ059yIu.js → sidebarPendingActions-Dp77KdwI.js} +1 -1
- package/dist/client/assets/{square-pen-C5BA26g7.js → square-pen-DkAUPV7D.js} +1 -1
- package/dist/client/assets/{state-mark-DNAt8L4c.js → state-mark-BoEXhyKA.js} +1 -1
- package/dist/client/assets/{terminal-DDMsYlkg.js → terminal-Be54a8lM.js} +1 -1
- package/dist/client/assets/{timer.adapter-Di4tkt37.js → timer.adapter-xKYiziSz.js} +1 -1
- package/dist/client/assets/{tools-CeacgJBu.js → tools-C_pxctuN.js} +1 -1
- package/dist/client/assets/{triangle-alert-B6T8mkaG.js → triangle-alert-CWM6skP7.js} +1 -1
- package/dist/client/assets/{useAppGlobalState-C6_aikPC.js → useAppGlobalState-DgWkgOn7.js} +1 -1
- package/dist/client/assets/{useKannaState-BESpYf4x.js → useKannaState-C_NyiDTL.js} +2 -2
- package/dist/client/assets/{useTheme-V_0ZRiiP.js → useTheme-C-9wxUOa.js} +1 -1
- package/dist/client/assets/{webhook-_4KNokhW.js → webhook-CE6utUYg.js} +1 -1
- package/dist/client/assets/{webhookCommands-ClSc7rRQ.js → webhookCommands-Cxvl4R_Z.js} +1 -1
- package/dist/client/assets/{webhooksStore-DmkDHteX.js → webhooksStore-BZKAEqao.js} +3 -3
- package/dist/client/index.html +41 -41
- package/package.json +4 -1
- package/src/server/webhooks/webhook-filter.ts +162 -0
- package/src/server/webhooks/webhook-http-routes.test.ts +68 -1
- package/src/server/webhooks/webhook-http-routes.ts +14 -1
- package/src/server/webhooks/webhook-registry.test.ts +67 -0
- package/src/server/webhooks/webhook-registry.ts +62 -4
- package/src/server/webhooks/webhook-store.adapter.test.ts +13 -0
- package/src/server/webhooks/webhook-store.adapter.ts +8 -0
- package/src/server/ws-router-webhooks.ts +12 -0
- package/src/shared/webhooks/types.ts +8 -3
- package/src/shared/webhooks/validate.ts +4 -0
- package/dist/client/assets/WebhooksPage-DGi5OTMt.js +0 -1
- package/dist/client/assets/chevron-down-Coo9PgPJ.js +0 -1
- package/dist/client/assets/chevron-left-n1tLJKrp.js +0 -1
- package/dist/client/assets/runDetached-BBRv1zoc.js +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{o as e}from"./rolldown-runtime-C0FnF6B9.js";import{t}from"./react-eq8zrF0J.js";import{l as n,u as r}from"./chunk-OB3PAWPO-bMwGZcTr.js";import{t as i}from"./jsx-runtime-BdxMnOeJ.js";import{B as a,Ct as o,D as s,Ft as c,It as l,Lt as u,M as d,Nt as f,T as p,b as m,bt as h,d as g,f as _,ft as v,j as y,k as b,l as x,n as ee,o as te,u as ne,vt as S,wt as re,x as C,xt as ie}from"./useAppGlobalState-C6_aikPC.js";import{a as ae,c as w,d as oe,f as T,p as se,s as ce}from"./log-3sQ-5rrS.js";import{a as E,c as D,d as O,f as k,n as A,o as j,r as M,s as N,t as P}from"./pendingActionsStore-C9wopHr4.js";import{C as le,S as ue,_ as de,a as fe,b as pe,d as me,g as he,h as ge,i as _e,m as ve,n as ye,t as be,v as xe,y as Se}from"./copyFeedbackStore-BW6Vjufv.js";import{t as Ce,zt as we}from"./lexicalToReact-CkI42EHr.js";import{n as Te,r as Ee,t as De}from"./clipboard.adapter-BCxT7Qli.js";import{t as Oe}from"./chevron-down-Coo9PgPJ.js";import{a as ke,i as F,n as Ae,o as je,r as Me,t as Ne}from"./select-BKHnGLKS.js";import{t as Pe}from"./external-link-9xEpmM2n.js";import{t as Fe}from"./info-BMdKmB36.js";import{t as Ie}from"./monitor-_V-BjQpD.js";import{t as Le}from"./pencil-BTeN1rO_.js";import{t as Re}from"./plus-D0uUa5kJ.js";import{n as ze,t as Be}from"./search-48C1GM_8.js";import{a as Ve,g as He,i as Ue,l as We,n as I,r as Ge,u as Ke}from"./webhooksStore-DmkDHteX.js";import{g as qe,i as Je,n as Ye,o as Xe,r as Ze,t as Qe,u as $e}from"./timer.adapter-Di4tkt37.js";import{a as et,c as tt,o as nt,s as rt,t as L}from"./segmented-control-DbmDSdKy.js";import{t as R}from"./input-CS1DBeNV.js";import{C as it,S as at,_ as z,a as ot,c as st,d as ct,f as lt,g as ut,h as dt,i as ft,l as pt,m as mt,n as ht,o as gt,p as _t,r as vt,s as yt,t as bt,u as xt,x as St,y as Ct}from"./appSettingsStore-CDBkjKuH.js";import{t as wt}from"./runDetached-BBRv1zoc.js";import{t as Tt}from"./chatSounds-Cjf1Ow1m.js";import{c as Et,l as Dt,o as Ot,r as kt}from"./contextWindow-I-trSDu4.js";import{C as At,D as jt,E as Mt,O as Nt,T as Pt,_ as Ft,a as It,b as Lt,c as Rt,d as zt,f as Bt,g as Vt,h as Ht,i as Ut,l as Wt,m as Gt,n as Kt,o as qt,p as Jt,r as Yt,s as Xt,t as Zt,u as Qt,v as $t,w as B,x as en,y as tn}from"./types-C-hQn4rL.js";import{c as nn,h as rn,i as an,m as on,n as sn,o as cn,p as ln,r as un,s as dn,u as fn}from"./KannaSocketProvider-Clv949La.js";import{r as pn}from"./formatters-BGORekd-.js";import{n as V,t as mn}from"./formatDuration-BbWTR_M_.js";import{n as hn}from"./state-mark-DNAt8L4c.js";import{n as gn,r as _n,t as vn}from"./popover-CA332KD1.js";import{n as yn}from"./cronJobsStore-CndqKrjB.js";import{r as bn}from"./useTheme-V_0ZRiiP.js";import{a as xn,i as Sn,o as Cn,r as wn}from"./webhookCommands-ClSc7rRQ.js";import{a as H,n as U,o as Tn,s as En,t as Dn}from"./searchable-select-C2LG0o1C.js";import{t as On}from"./settings-header-button-D4w0LZ-R.js";var kn={name:`antenna`,size:24,node:[[`path`,{d:`M2 12 7 2`,key:`117k30`}],[`path`,{d:`m7 12 5-10`,key:`1tvx22`}],[`path`,{d:`m12 12 5-10`,key:`ev1o1a`}],[`path`,{d:`m17 12 5-10`,key:`1e4ti3`}],[`path`,{d:`M4.5 7h15`,key:`vlsxkz`}],[`path`,{d:`M12 16v6`,key:`c8a4gj`}]]};kn.node;var An=k(kn),jn={name:`book-text`,size:24,node:[[`path`,{d:`M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20`,key:`k3hazp`}],[`path`,{d:`M8 11h8`,key:`vwpz6n`}],[`path`,{d:`M8 7h6`,key:`1f0q6e`}]]};jn.node;var Mn=k(jn),Nn={name:`circle-arrow-up`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m16 12-4-4-4 4`,key:`177agl`}],[`path`,{d:`M12 16V8`,key:`1sbj14`}]],aliases:[`arrow-up-circle`]};Nn.node;var Pn=k(Nn),Fn={name:`cloud-download`,size:24,node:[[`path`,{d:`M12 13v8l-4-4`,key:`1f5nwf`}],[`path`,{d:`m12 21 4-4`,key:`1lfcce`}],[`path`,{d:`M4.393 15.269A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.436 8.284`,key:`ui1hmy`}]],aliases:[`download-cloud`]};Fn.node;var In=k(Fn),Ln={name:`command`,size:24,node:[[`path`,{d:`M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3`,key:`11bfej`}]]};Ln.node;var Rn=k(Ln),zn={name:`cpu`,size:24,node:[[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M17 20v2`,key:`1rnc9c`}],[`path`,{d:`M17 2v2`,key:`11trls`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M2 17h2`,key:`7oei6x`}],[`path`,{d:`M2 7h2`,key:`asdhe0`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`M20 17h2`,key:`1fpfkl`}],[`path`,{d:`M20 7h2`,key:`1o8tra`}],[`path`,{d:`M7 20v2`,key:`4gnj0m`}],[`path`,{d:`M7 2v2`,key:`1i4yhu`}],[`rect`,{x:`4`,y:`4`,width:`16`,height:`16`,rx:`2`,key:`1vbyd7`}],[`rect`,{x:`8`,y:`8`,width:`8`,height:`8`,rx:`1`,key:`z9xiuo`}]]};zn.node;var Bn=k(zn),Vn={name:`flask-conical`,size:24,node:[[`path`,{d:`M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2`,key:`18mbvz`}],[`path`,{d:`M6.453 15h11.094`,key:`3shlmq`}],[`path`,{d:`M8.5 2h7`,key:`csnxdl`}]]};Vn.node;var Hn=k(Vn),Un={name:`log-out`,size:24,node:[[`path`,{d:`m16 17 5-5-5-5`,key:`1bji2h`}],[`path`,{d:`M21 12H9`,key:`dn1m92`}],[`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`,key:`1uf3rs`}]]};Un.node;var Wn=k(Un),Gn={name:`message-square-quote`,size:24,node:[[`path`,{d:`M14 14a2 2 0 0 0 2-2V8h-2`,key:`1r06pg`}],[`path`,{d:`M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z`,key:`18887p`}],[`path`,{d:`M8 14a2 2 0 0 0 2-2V8H8`,key:`1jzu5j`}]]};Gn.node;var Kn=k(Gn),qn={name:`moon`,size:24,node:[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]};qn.node;var Jn=k(qn),Yn={name:`network`,size:24,node:[[`rect`,{x:`16`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`4q2zg0`}],[`rect`,{x:`2`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`8cvhb9`}],[`rect`,{x:`9`,y:`2`,width:`6`,height:`6`,rx:`1`,key:`1egb70`}],[`path`,{d:`M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3`,key:`1jsf9p`}],[`path`,{d:`M12 12V8`,key:`2874zd`}]]};Yn.node;var Xn=k(Yn),Zn={name:`plug`,size:24,node:[[`path`,{d:`M12 22v-5`,key:`1ega77`}],[`path`,{d:`M15 8V2`,key:`18g5xt`}],[`path`,{d:`M17 8a1 1 0 0 1 1 1v4a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1z`,key:`1xoxul`}],[`path`,{d:`M9 8V2`,key:`14iosj`}]]};Zn.node;var Qn=k(Zn),$n={name:`power-off`,size:24,node:[[`path`,{d:`M18.36 6.64A9 9 0 0 1 20.77 15`,key:`dxknvb`}],[`path`,{d:`M6.16 6.16a9 9 0 1 0 12.68 12.68`,key:`1x7qb5`}],[`path`,{d:`M12 2v4`,key:`3427ic`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]};$n.node;var er=k($n),tr={name:`power`,size:24,node:[[`path`,{d:`M12 2v10`,key:`mnfbl`}],[`path`,{d:`M18.4 6.6a9 9 0 1 1-12.77.04`,key:`obofu9`}]]};tr.node;var nr=k(tr),rr={name:`sun`,size:24,node:[[`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`}]]};rr.node;var ir=k(rr),ar={name:`type`,size:24,node:[[`path`,{d:`M12 4v16`,key:`1654pz`}],[`path`,{d:`M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2`,key:`e0r10z`}],[`path`,{d:`M9 20h6`,key:`s66wpe`}]]};ar.node;var or=k(ar),sr={name:`waypoints`,size:24,node:[[`path`,{d:`m10.586 5.414-5.172 5.172`,key:`4mc350`}],[`path`,{d:`m18.586 13.414-5.172 5.172`,key:`8c96vv`}],[`path`,{d:`M6 12h12`,key:`8npq4p`}],[`circle`,{cx:`12`,cy:`20`,r:`2`,key:`144qzu`}],[`circle`,{cx:`12`,cy:`4`,r:`2`,key:`muu5ef`}],[`circle`,{cx:`20`,cy:`12`,r:`2`,key:`1xzzfp`}],[`circle`,{cx:`4`,cy:`12`,r:`2`,key:`1hvhnz`}]]};sr.node;var cr=k(sr),lr=`gpt-5.4-mini`;function ur(e){return e===`previous-assistant-reply`||e===`full-transcript`}function dr(e){return e===`auto`||e===`manual`}var fr={enabled:!1,cloudflaredPath:`cloudflared`,mode:`always-ask`},W=e(t(),1),G=e(i(),1);function pr(e){let t=e.trim();if(t.startsWith(`https://`))try{let e=new URL(t);if(e.protocol!==`https:`)return!1;let n=e.hostname.toLowerCase();return!(n===`localhost`||!n.includes(`.`)||n.startsWith(`.`)||n.endsWith(`.`))}catch{return!1}if(t.startsWith(`mailto:`)){let e=t.slice(7),n=/^[^\s@]+@([^\s@]+)$/.exec(e);if(!n)return!1;let r=n[1].toLowerCase();return!(r===`localhost`||!r.includes(`.`)||r.startsWith(`.`)||r.endsWith(`.`))}return!1}var mr={maxFileSizeMb:2048},hr=51200,gr=[`app_launch`,`project_opened`,`project_created`,`project_removed`,`project_deleted`,`chat_created`,`chat_deleted`,`message_sent`,`update_checked`,`update_installed`,`update_failed`,`analytics_enabled`,`analytics_disabled`],_r=[`current_version`,`environment`,`latest_version`,`custom_port_enabled`,`no_open_enabled`,`password_enabled`,`strict_port_enabled`,`remote_enabled`,`host_enabled`,`share_quick_enabled`,`share_token_enabled`];function vr(){return{name:``,provider:`claude`,model:At(`claude`).defaultModel,modelOptions:{...Ft},systemPrompt:``,contextScope:`previous-assistant-reply`,triggerMode:`auto`}}function yr(){return{draft:vr(),error:null,pending:!1,confirmDelete:!1}}var br=w()(e=>({editing:{kind:`list`},form:yr(),timeoutDraft:``,loopError:null,setEditing:t=>e({editing:t}),resetForm:t=>e({form:{draft:t,error:null,pending:!1,confirmDelete:!1}}),patchForm:t=>e(e=>({form:{...e.form,...t}})),patchFormDraft:t=>e(e=>({form:{...e.form,draft:{...e.form.draft,...t}}})),setTimeoutDraft:t=>e({timeoutDraft:t}),setLoopError:t=>e({loopError:t})}));function K(e){return(0,G.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,G.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:e.label}),e.children,e.hint?(0,G.jsx)(`span`,{className:D(`text-xs`,e.hintTone===`destructive`?`text-destructive`:`text-muted-foreground`),children:e.hint}):null]})}function xr(e){let{draft:t,patchDraft:n}=e;return(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(K,{label:`Working directory`,hint:`Optional. Relative to the parent chat cwd. Restricts the subagent's filesystem access to this subtree.`,children:(0,G.jsx)(R,{"data-testid":`subagent-form-working-dir`,value:t.workingDir??``,onChange:e=>{let t=e.target.value;n({workingDir:t.length>0?t:void 0})},placeholder:`docs`})}),(0,G.jsx)(K,{label:`Allowed paths`,hint:`Optional. Newline-separated, relative to the parent chat cwd. When set, file tools can only read/write inside these roots.`,children:(0,G.jsx)(ln,{"data-testid":`subagent-form-allowed-paths`,value:(t.allowedPaths??[]).join(`
|
|
1
|
+
import{o as e}from"./rolldown-runtime-C0FnF6B9.js";import{t}from"./react-eq8zrF0J.js";import{l as n,u as r}from"./chunk-OB3PAWPO-bMwGZcTr.js";import{t as i}from"./jsx-runtime-BdxMnOeJ.js";import{B as a,Ct as o,D as s,Ft as c,It as l,Lt as u,M as d,Nt as f,T as p,b as m,bt as h,d as g,f as _,ft as v,j as y,k as b,l as x,n as ee,o as te,u as ne,vt as S,wt as re,x as C,xt as ie}from"./useAppGlobalState-DgWkgOn7.js";import{a as ae,c as w,d as oe,f as T,p as se,s as ce}from"./log-DeYiYzru.js";import{a as E,c as D,d as O,f as k,n as A,o as j,r as M,s as N,t as P}from"./pendingActionsStore-2LSejcqM.js";import{C as le,S as ue,_ as de,a as fe,b as pe,d as me,g as he,h as ge,i as _e,m as ve,n as ye,t as be,v as xe,y as Se}from"./copyFeedbackStore-D3VJJOPQ.js";import{t as Ce,zt as we}from"./lexicalToReact-TD2k-lRz.js";import{n as Te,r as Ee,t as De}from"./clipboard.adapter-hbKWYB9v.js";import{t as Oe}from"./chevron-down-C3wqMsmk.js";import{a as ke,i as F,n as Ae,o as je,r as Me,t as Ne}from"./select-k2e8CCUh.js";import{t as Pe}from"./external-link-DIOTFxAO.js";import{t as Fe}from"./info-BUS8wzM_.js";import{t as Ie}from"./monitor-BiV6DsHv.js";import{t as Le}from"./pencil-D4taLrpW.js";import{t as Re}from"./plus-Dt1R6Ec0.js";import{n as ze,t as Be}from"./search-DLUiqdl3.js";import{_ as Ve,a as He,i as Ue,l as We,n as I,r as Ge,u as Ke}from"./webhooksStore-BZKAEqao.js";import{g as qe,i as Je,n as Ye,o as Xe,r as Ze,t as Qe,u as $e}from"./timer.adapter-xKYiziSz.js";import{a as et,c as tt,o as nt,s as rt,t as L}from"./segmented-control-A3JAN-14.js";import{t as R}from"./input-CvrFJg7l.js";import{C as it,S as at,_ as z,a as ot,c as st,d as ct,f as lt,g as ut,h as dt,i as ft,l as pt,m as mt,n as ht,o as gt,p as _t,r as vt,s as yt,t as bt,u as xt,x as St,y as Ct}from"./appSettingsStore-BBfwETzX.js";import{t as wt}from"./runDetached-CZb0BmgP.js";import{t as Tt}from"./chatSounds-DnB6LG-Z.js";import{c as Et,l as Dt,o as Ot,r as kt}from"./contextWindow-DXZRM56M.js";import{C as At,D as jt,E as Mt,O as Nt,T as Pt,_ as Ft,a as It,b as Lt,c as Rt,d as zt,f as Bt,g as Vt,h as Ht,i as Ut,l as Wt,m as Gt,n as Kt,o as qt,p as Jt,r as Yt,s as Xt,t as Zt,u as Qt,v as $t,w as B,x as en,y as tn}from"./types-C-hQn4rL.js";import{c as nn,h as rn,i as an,m as on,n as sn,o as cn,p as ln,r as un,s as dn,u as fn}from"./KannaSocketProvider-Bw4DvDDN.js";import{r as pn}from"./formatters-BGORekd-.js";import{n as V,t as mn}from"./formatDuration-BbWTR_M_.js";import{n as hn}from"./state-mark-BoEXhyKA.js";import{n as gn,r as _n,t as vn}from"./popover-Byr25LbG.js";import{n as yn}from"./cronJobsStore-Bmd92Wdu.js";import{r as bn}from"./useTheme-C-9wxUOa.js";import{a as xn,i as Sn,o as Cn,r as wn}from"./webhookCommands-Cxvl4R_Z.js";import{a as H,n as U,o as Tn,s as En,t as Dn}from"./searchable-select-0lGC5Dbu.js";import{t as On}from"./settings-header-button-Ba-h5PgF.js";var kn={name:`antenna`,size:24,node:[[`path`,{d:`M2 12 7 2`,key:`117k30`}],[`path`,{d:`m7 12 5-10`,key:`1tvx22`}],[`path`,{d:`m12 12 5-10`,key:`ev1o1a`}],[`path`,{d:`m17 12 5-10`,key:`1e4ti3`}],[`path`,{d:`M4.5 7h15`,key:`vlsxkz`}],[`path`,{d:`M12 16v6`,key:`c8a4gj`}]]};kn.node;var An=k(kn),jn={name:`book-text`,size:24,node:[[`path`,{d:`M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20`,key:`k3hazp`}],[`path`,{d:`M8 11h8`,key:`vwpz6n`}],[`path`,{d:`M8 7h6`,key:`1f0q6e`}]]};jn.node;var Mn=k(jn),Nn={name:`circle-arrow-up`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m16 12-4-4-4 4`,key:`177agl`}],[`path`,{d:`M12 16V8`,key:`1sbj14`}]],aliases:[`arrow-up-circle`]};Nn.node;var Pn=k(Nn),Fn={name:`cloud-download`,size:24,node:[[`path`,{d:`M12 13v8l-4-4`,key:`1f5nwf`}],[`path`,{d:`m12 21 4-4`,key:`1lfcce`}],[`path`,{d:`M4.393 15.269A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.436 8.284`,key:`ui1hmy`}]],aliases:[`download-cloud`]};Fn.node;var In=k(Fn),Ln={name:`command`,size:24,node:[[`path`,{d:`M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3`,key:`11bfej`}]]};Ln.node;var Rn=k(Ln),zn={name:`cpu`,size:24,node:[[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M17 20v2`,key:`1rnc9c`}],[`path`,{d:`M17 2v2`,key:`11trls`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M2 17h2`,key:`7oei6x`}],[`path`,{d:`M2 7h2`,key:`asdhe0`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`M20 17h2`,key:`1fpfkl`}],[`path`,{d:`M20 7h2`,key:`1o8tra`}],[`path`,{d:`M7 20v2`,key:`4gnj0m`}],[`path`,{d:`M7 2v2`,key:`1i4yhu`}],[`rect`,{x:`4`,y:`4`,width:`16`,height:`16`,rx:`2`,key:`1vbyd7`}],[`rect`,{x:`8`,y:`8`,width:`8`,height:`8`,rx:`1`,key:`z9xiuo`}]]};zn.node;var Bn=k(zn),Vn={name:`flask-conical`,size:24,node:[[`path`,{d:`M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2`,key:`18mbvz`}],[`path`,{d:`M6.453 15h11.094`,key:`3shlmq`}],[`path`,{d:`M8.5 2h7`,key:`csnxdl`}]]};Vn.node;var Hn=k(Vn),Un={name:`log-out`,size:24,node:[[`path`,{d:`m16 17 5-5-5-5`,key:`1bji2h`}],[`path`,{d:`M21 12H9`,key:`dn1m92`}],[`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`,key:`1uf3rs`}]]};Un.node;var Wn=k(Un),Gn={name:`message-square-quote`,size:24,node:[[`path`,{d:`M14 14a2 2 0 0 0 2-2V8h-2`,key:`1r06pg`}],[`path`,{d:`M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z`,key:`18887p`}],[`path`,{d:`M8 14a2 2 0 0 0 2-2V8H8`,key:`1jzu5j`}]]};Gn.node;var Kn=k(Gn),qn={name:`moon`,size:24,node:[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]};qn.node;var Jn=k(qn),Yn={name:`network`,size:24,node:[[`rect`,{x:`16`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`4q2zg0`}],[`rect`,{x:`2`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`8cvhb9`}],[`rect`,{x:`9`,y:`2`,width:`6`,height:`6`,rx:`1`,key:`1egb70`}],[`path`,{d:`M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3`,key:`1jsf9p`}],[`path`,{d:`M12 12V8`,key:`2874zd`}]]};Yn.node;var Xn=k(Yn),Zn={name:`plug`,size:24,node:[[`path`,{d:`M12 22v-5`,key:`1ega77`}],[`path`,{d:`M15 8V2`,key:`18g5xt`}],[`path`,{d:`M17 8a1 1 0 0 1 1 1v4a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1z`,key:`1xoxul`}],[`path`,{d:`M9 8V2`,key:`14iosj`}]]};Zn.node;var Qn=k(Zn),$n={name:`power-off`,size:24,node:[[`path`,{d:`M18.36 6.64A9 9 0 0 1 20.77 15`,key:`dxknvb`}],[`path`,{d:`M6.16 6.16a9 9 0 1 0 12.68 12.68`,key:`1x7qb5`}],[`path`,{d:`M12 2v4`,key:`3427ic`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]};$n.node;var er=k($n),tr={name:`power`,size:24,node:[[`path`,{d:`M12 2v10`,key:`mnfbl`}],[`path`,{d:`M18.4 6.6a9 9 0 1 1-12.77.04`,key:`obofu9`}]]};tr.node;var nr=k(tr),rr={name:`sun`,size:24,node:[[`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`}]]};rr.node;var ir=k(rr),ar={name:`type`,size:24,node:[[`path`,{d:`M12 4v16`,key:`1654pz`}],[`path`,{d:`M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2`,key:`e0r10z`}],[`path`,{d:`M9 20h6`,key:`s66wpe`}]]};ar.node;var or=k(ar),sr={name:`waypoints`,size:24,node:[[`path`,{d:`m10.586 5.414-5.172 5.172`,key:`4mc350`}],[`path`,{d:`m18.586 13.414-5.172 5.172`,key:`8c96vv`}],[`path`,{d:`M6 12h12`,key:`8npq4p`}],[`circle`,{cx:`12`,cy:`20`,r:`2`,key:`144qzu`}],[`circle`,{cx:`12`,cy:`4`,r:`2`,key:`muu5ef`}],[`circle`,{cx:`20`,cy:`12`,r:`2`,key:`1xzzfp`}],[`circle`,{cx:`4`,cy:`12`,r:`2`,key:`1hvhnz`}]]};sr.node;var cr=k(sr),lr=`gpt-5.4-mini`;function ur(e){return e===`previous-assistant-reply`||e===`full-transcript`}function dr(e){return e===`auto`||e===`manual`}var fr={enabled:!1,cloudflaredPath:`cloudflared`,mode:`always-ask`},W=e(t(),1),G=e(i(),1);function pr(e){let t=e.trim();if(t.startsWith(`https://`))try{let e=new URL(t);if(e.protocol!==`https:`)return!1;let n=e.hostname.toLowerCase();return!(n===`localhost`||!n.includes(`.`)||n.startsWith(`.`)||n.endsWith(`.`))}catch{return!1}if(t.startsWith(`mailto:`)){let e=t.slice(7),n=/^[^\s@]+@([^\s@]+)$/.exec(e);if(!n)return!1;let r=n[1].toLowerCase();return!(r===`localhost`||!r.includes(`.`)||r.startsWith(`.`)||r.endsWith(`.`))}return!1}var mr={maxFileSizeMb:2048},hr=51200,gr=[`app_launch`,`project_opened`,`project_created`,`project_removed`,`project_deleted`,`chat_created`,`chat_deleted`,`message_sent`,`update_checked`,`update_installed`,`update_failed`,`analytics_enabled`,`analytics_disabled`],_r=[`current_version`,`environment`,`latest_version`,`custom_port_enabled`,`no_open_enabled`,`password_enabled`,`strict_port_enabled`,`remote_enabled`,`host_enabled`,`share_quick_enabled`,`share_token_enabled`];function vr(){return{name:``,provider:`claude`,model:At(`claude`).defaultModel,modelOptions:{...Ft},systemPrompt:``,contextScope:`previous-assistant-reply`,triggerMode:`auto`}}function yr(){return{draft:vr(),error:null,pending:!1,confirmDelete:!1}}var br=w()(e=>({editing:{kind:`list`},form:yr(),timeoutDraft:``,loopError:null,setEditing:t=>e({editing:t}),resetForm:t=>e({form:{draft:t,error:null,pending:!1,confirmDelete:!1}}),patchForm:t=>e(e=>({form:{...e.form,...t}})),patchFormDraft:t=>e(e=>({form:{...e.form,draft:{...e.form.draft,...t}}})),setTimeoutDraft:t=>e({timeoutDraft:t}),setLoopError:t=>e({loopError:t})}));function K(e){return(0,G.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,G.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:e.label}),e.children,e.hint?(0,G.jsx)(`span`,{className:D(`text-xs`,e.hintTone===`destructive`?`text-destructive`:`text-muted-foreground`),children:e.hint}):null]})}function xr(e){let{draft:t,patchDraft:n}=e;return(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(K,{label:`Working directory`,hint:`Optional. Relative to the parent chat cwd. Restricts the subagent's filesystem access to this subtree.`,children:(0,G.jsx)(R,{"data-testid":`subagent-form-working-dir`,value:t.workingDir??``,onChange:e=>{let t=e.target.value;n({workingDir:t.length>0?t:void 0})},placeholder:`docs`})}),(0,G.jsx)(K,{label:`Allowed paths`,hint:`Optional. Newline-separated, relative to the parent chat cwd. When set, file tools can only read/write inside these roots.`,children:(0,G.jsx)(ln,{"data-testid":`subagent-form-allowed-paths`,value:(t.allowedPaths??[]).join(`
|
|
2
2
|
`),onChange:e=>{let t=e.target.value.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0);n({allowedPaths:t.length>0?t:void 0})},placeholder:`docs
|
|
3
|
-
wiki`,rows:3})}),(0,G.jsx)(K,{label:`Beacon tools`,hint:`Off by default. When on, this subagent can run commands and read files on your paired machines. Each call still asks for your approval.`,children:(0,G.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-sm text-foreground`,children:[(0,G.jsx)(`input`,{type:`checkbox`,"data-testid":`subagent-form-allow-beacon-tools`,checked:t.allowBeaconTools===!0,onChange:e=>{n({allowBeaconTools:e.target.checked})}}),(0,G.jsx)(`span`,{children:`Allow this subagent to use beacon tools (run on your paired machines)`})]})})]})}function Sr(e){return`contextWindow`in e}function Cr(e){return`fastMode`in e}function wr(e){let t=e.editing,n=(0,W.useMemo)(()=>t.kind===`edit`?e.subagents.find(e=>e.id===t.id)??null:null,[t,e.subagents]),r=t.kind,i=r!==`list`,a=e.subagents.length===0;return a&&!i?(0,G.jsx)(Tr,{onStartCreate:e.onStartCreate}):(0,G.jsxs)(`div`,{className:`flex flex-col gap-6 md:flex-row md:items-start md:gap-8`,children:[a?null:(0,G.jsx)(Dr,{subagents:e.subagents,editing:e.editing,onSelect:e.onSelect,onStartCreate:e.onStartCreate}),i?(0,G.jsx)(Pr,{mode:r,subject:r===`edit`?n:null,providerDefaults:e.providerDefaults,availableProviders:e.availableProviders,handlers:e.handlers,onCancelEditing:e.onCancelEditing},r===`edit`?n?.id??`edit`:`create`):(0,G.jsx)(Er,{})]})}function Tr(e){return(0,G.jsxs)(`div`,{className:`flex w-full flex-col items-center gap-4 rounded-lg border border-dashed border-border px-6 py-14 text-center`,"data-testid":`subagent-empty`,children:[(0,G.jsx)(`div`,{className:`flex size-10 items-center justify-center rounded-full bg-muted text-muted-foreground`,children:(0,G.jsx)(le,{className:`size-5`,"aria-hidden":!0})}),(0,G.jsx)(`p`,{className:`text-sm font-medium text-foreground`,children:`No subagents yet`}),(0,G.jsxs)(E,{variant:`default`,size:`sm`,onClick:e.onStartCreate,children:[(0,G.jsx)(Re,{className:`mr-1.5 size-4`}),` Create subagent`]})]})}function Er(){return(0,G.jsx)(`div`,{className:`hidden flex-1 items-center justify-center rounded-lg border border-dashed border-border px-6 py-12 text-center text-sm text-muted-foreground md:flex`,children:`Select a subagent to edit, or create a new one.`})}function Dr(e){let t=e.editing.kind===`edit`?e.editing.id:null;return(0,G.jsxs)(`aside`,{className:`flex w-full flex-col gap-2 md:w-64 md:flex-shrink-0`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,G.jsxs)(`span`,{className:`text-xs font-medium tracking-wide text-muted-foreground`,style:{fontVariantNumeric:`tabular-nums`},children:[e.subagents.length,` `,e.subagents.length===1?`agent`:`agents`]}),(0,G.jsxs)(E,{variant:`ghost`,size:`sm`,onClick:e.onStartCreate,"data-testid":`subagent-create`,children:[(0,G.jsx)(Re,{className:`size-4`}),(0,G.jsx)(`span`,{className:`sr-only`,children:`Create subagent`})]})]}),(0,G.jsx)(`ul`,{className:`flex flex-col gap-0.5`,children:e.subagents.map(n=>{let r=n.description?.trim()||(n.contextScope===`previous-assistant-reply`?`Last reply`:`Full transcript`);return(0,G.jsx)(`li`,{children:(0,G.jsxs)(`button`,{type:`button`,"data-testid":`subagent-row:${n.id}`,onClick:()=>e.onSelect(n.id),className:D(`flex w-full flex-col items-start gap-0.5 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-muted`,t===n.id&&`bg-muted`),children:[(0,G.jsxs)(`span`,{className:`flex w-full items-center justify-between gap-2`,children:[(0,G.jsx)(`span`,{className:`truncate text-sm font-medium text-foreground`,children:n.name}),(0,G.jsx)(Or,{provider:n.provider})]}),(0,G.jsx)(`span`,{className:`w-full truncate text-xs text-muted-foreground`,children:r})]})},n.id)})})]})}function Or({provider:e}){let t=At(e).label;return(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1 rounded border border-border bg-card px-1.5 py-0.5 text-xs font-medium tracking-wide text-muted-foreground`,children:[(0,G.jsx)(le,{className:`size-3`}),` `,t]})}var kr=[{value:`claude`,label:`Claude`},{value:`codex`,label:`Codex`},{value:`openrouter`,label:`OpenRouter`}],Ar=[...kr,{value:`custom`,label:`Custom endpoints`}];function jr(e,t){return t.length===0?e:e.map(e=>e.id===`openrouter`?{...e,models:t.map(e=>({id:e.id,label:e.label}))}:e)}var Mr=[{value:`previous-assistant-reply`,label:`Last reply`},{value:`full-transcript`,label:`Full transcript`}],Nr=[{value:`auto`,label:`Auto`},{value:`manual`,label:`Manual`}];function Pr(e){let t=(0,W.useMemo)(()=>e.mode===`edit`&&e.subject?Gr(e.subject):Wr(`claude`,e.providerDefaults,e.availableProviders),[e.mode,e.subject,e.providerDefaults,e.availableProviders]),n=br(e=>e.resetForm),r=br(e=>e.form),i=br(e=>e.patchFormDraft),a=br(e=>e.patchForm);(0,W.useEffect)(()=>{n(t)},[]);let{draft:o,error:s,pending:c,confirmDelete:l}=r,u=o.provider===`custom`||e.availableProviders.some(e=>e.id===`custom`)?Ar:kr,d=s?.field===`name`?s.message:null,f=s?.field===`general`?s.message:null,p=qr(o,t),m=o.name.trim().length>0&&(e.mode===`create`||p);function h(e){i(e),s?.field===`name`&&`name`in e&&a({error:null})}function g(t){if(t===o.provider)return;let n=Wr(t,e.providerDefaults,e.availableProviders);i({provider:t,model:n.model,modelOptions:n.modelOptions})}function _(e){if(o.provider!==`claude`)return;let t=Sr(o.modelOptions)?o.modelOptions:Ft;i({modelOptions:{...Ft,...t,reasoningEffort:e}})}function v(e){if(o.provider!==`claude`)return;let t=Sr(o.modelOptions)?o.modelOptions:Ft;i({modelOptions:{...Ft,...t,contextWindow:e}})}function y(e){if(o.provider!==`codex`)return;let t=Cr(o.modelOptions)?o.modelOptions:$t;i({modelOptions:{...$t,...t,reasoningEffort:e}})}async function b(){if(m&&!c){a({pending:!0,error:null,confirmDelete:!1});try{let t=e.mode===`create`?await e.handlers.onCreate(o):await e.handlers.onUpdate(e.subject.id,o);t.ok||a({error:Yr(t.error)})}catch(e){a({error:{field:`general`,message:T(e)}})}finally{a({pending:!1})}}}async function x(){if(e.mode===`edit`&&e.subject){if(!l){a({confirmDelete:!0});return}a({pending:!0,error:null});try{await e.handlers.onDelete(e.subject.id)}catch(e){a({error:{field:`general`,message:T(e)}})}finally{a({pending:!1,confirmDelete:!1})}}}let ee=o.provider===`claude`?{...Ft,...Sr(o.modelOptions)?o.modelOptions:{}}:null,te=o.provider===`codex`?{...$t,...Cr(o.modelOptions)?o.modelOptions:{}}:null,ne=e.availableProviders.find(e=>e.id===o.provider)??At(o.provider);return(0,G.jsxs)(`section`,{className:`flex w-full flex-1 flex-col gap-4`,children:[(0,G.jsxs)(`header`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`h3`,{className:`text-base font-medium text-foreground`,children:e.mode===`create`?`New subagent`:o.name||`Subagent`}),(0,G.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[`Mention with `,(0,G.jsxs)(`code`,{className:`rounded bg-muted px-1 py-0.5 font-mono text-xs`,children:[`@agent/`,o.name||`<name>`]}),` in chat.`]})]}),f?(0,G.jsx)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm text-destructive`,children:f}):null,(0,G.jsx)(K,{label:`Name`,hint:d,hintTone:d?`destructive`:`muted`,children:(0,G.jsx)(R,{"data-testid":`subagent-form-name`,value:o.name,onChange:e=>h({name:Xr(e.target.value)}),maxLength:64,placeholder:`reviewer`,className:`font-mono`})}),(0,G.jsx)(K,{label:`Description`,hint:`Optional. Shown next to the name.`,children:(0,G.jsx)(R,{"data-testid":`subagent-form-description`,value:o.description??``,onChange:e=>h({description:e.target.value}),placeholder:`Reviews diffs against the repo style`})}),(0,G.jsx)(K,{label:`Provider`,children:(0,G.jsx)(L,{value:o.provider,onValueChange:e=>{Zt(e)&&g(e)},options:u,size:`sm`})}),(0,G.jsx)(K,{label:`Model`,children:(0,G.jsxs)(Ne,{value:o.model,onValueChange:e=>h({model:e}),children:[(0,G.jsx)(ke,{"data-testid":`subagent-form-model`,className:`w-full md:w-72`,children:(0,G.jsx)(je,{placeholder:`Select a model`})}),(0,G.jsx)(Ae,{children:ne.models.map(e=>(0,G.jsx)(F,{value:e.id,children:e.label},e.id))})]})}),ee?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(K,{label:`Reasoning effort`,children:(0,G.jsx)(L,{value:ee.reasoningEffort,onValueChange:e=>{Pt(e)&&_(e)},options:Ht.map(e=>({value:e.id,label:e.label})),size:`sm`})}),(0,G.jsx)(K,{label:`Context window`,children:(0,G.jsx)(L,{value:ee.contextWindow,onValueChange:e=>{B(e)&&v(e)},options:Gt.map(e=>({value:e.id,label:e.label})),size:`sm`})})]}):null,te?(0,G.jsx)(K,{label:`Reasoning effort`,children:(0,G.jsx)(L,{value:te.reasoningEffort,onValueChange:e=>{Mt(e)&&y(e)},options:Vt.map(e=>({value:e.id,label:e.label})),size:`sm`})}):null,(0,G.jsx)(K,{label:`Context scope`,children:(0,G.jsx)(L,{value:o.contextScope,onValueChange:e=>{ur(e)&&h({contextScope:e})},options:Mr,size:`sm`})}),(0,G.jsx)(K,{label:`Trigger`,hint:`Auto: the main agent may delegate on its own. Manual: only runs when you @-mention it.`,children:(0,G.jsx)(L,{value:o.triggerMode??`auto`,onValueChange:e=>{dr(e)&&h({triggerMode:e})},options:Nr,size:`sm`})}),(0,G.jsx)(K,{label:`System prompt`,hint:`What this persona should focus on. Plain text.`,children:(0,G.jsx)(ln,{"data-testid":`subagent-form-system-prompt`,value:o.systemPrompt,onChange:e=>h({systemPrompt:e.target.value}),placeholder:`You are a careful code reviewer...`,rows:6,className:`min-h-32`})}),(0,G.jsx)(K,{label:`Max turns`,hint:`Optional. Caps the agentic turns per run (like Claude Code's per-agent maxTurns). Empty = unbounded. Claude SDK runs stop gracefully at the limit; Codex runs are aborted.`,children:(0,G.jsx)(R,{"data-testid":`subagent-form-max-turns`,type:`number`,min:1,step:1,value:o.maxTurns?.toString()??``,onChange:e=>{let t=Number.parseInt(e.target.value,10);h({maxTurns:Number.isInteger(t)&&t>0?t:void 0})},placeholder:`unbounded`,className:`w-36`})}),o.provider===`claude`?(0,G.jsx)(xr,{draft:o,patchDraft:h}):null,(0,G.jsxs)(`footer`,{className:`flex flex-wrap items-center justify-end gap-2 pt-2`,children:[(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:e.onCancelEditing,children:`Cancel`}),e.mode===`edit`?(0,G.jsx)(E,{variant:`destructive`,size:`sm`,"data-testid":`subagent-form-delete`,disabled:c,pending:c&&l,onClick:()=>{A(P(`subagent.delete`,e.subject?.id??``),x)},children:l?`Confirm delete`:`Delete`}):null,(0,G.jsx)(E,{variant:`default`,size:`sm`,"data-testid":`subagent-form-save`,disabled:!m||c,pending:c&&!l,onClick:()=>{A(P(`subagent.save`,e.subject?.id??`new`),b)},children:c?`Saving…`:`Save`})]})]})}var Fr=[],Ir={claude:{model:At(`claude`).defaultModel,modelOptions:{...Ft},planMode:!1},codex:{model:At(`codex`).defaultModel,modelOptions:{...$t},planMode:!1},openrouter:{model:tn,modelOptions:{},planMode:!1},custom:{model:``,modelOptions:{},planMode:!1}};function Lr(e){let t=z(e=>e.settings?.subagents??Fr),n=z(e=>e.settings?.providerDefaults??Ir),r=z(ot),i=z(gt),a=m(Et(e=>e.models)),o=(0,W.useMemo)(()=>jr(Ve(Nt([...Lt],r),i),a),[r,i,a]),s=br(e=>e.editing),c=br(e=>e.setEditing),l=(0,W.useMemo)(()=>({onCreate:async t=>{let n=await e.state.socket.command({type:`subagent.create`,input:t});return n.ok&&c({kind:`edit`,id:n.subagent.id}),n},onUpdate:async(t,n)=>await e.state.socket.command({type:`subagent.update`,id:t,patch:{...n,maxTurns:n.maxTurns??null}}),onDelete:async t=>{await e.state.socket.command({type:`subagent.delete`,id:t}),c({kind:`list`})}}),[e.state.socket,c]),u=(0,W.useCallback)(e=>{c({kind:`edit`,id:e})},[c]),d=(0,W.useCallback)(()=>{c({kind:`create`})},[c]),f=(0,W.useCallback)(()=>{c({kind:`list`})},[c]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-6 px-6 py-6`,children:[(0,G.jsx)(Hr,{subagents:t,handleWriteAppSettings:e.state.handleWriteAppSettings}),(0,G.jsx)(wr,{subagents:t,providerDefaults:n,availableProviders:o,editing:s,onSelect:u,onStartCreate:d,onCancelEditing:f,handlers:l})]})}var Rr=`__none__`,zr=30,Br=86400,Vr=600;function Hr(e){let t=z(e=>e.settings?.subagentRuntime),n=t?Math.round(t.runTimeoutMs/1e3):Vr,r=t?.defaultLoopSubagentId??null,i=br(e=>e.timeoutDraft),a=br(e=>e.setTimeoutDraft),o=br(e=>e.loopError),s=br(e=>e.setLoopError);(0,W.useEffect)(()=>{a(String(n))},[n]);function c(){let t=Number(i);if(!Number.isInteger(t)||t<zr||t>Br){a(String(n)),s(`Timeout must be a whole number of seconds between ${zr} and ${Br}.`);return}s(null),t!==n&&e.handleWriteAppSettings({subagentRuntime:{runTimeoutMs:t*1e3}}).catch(e=>s(e instanceof Error?e.message:`Unable to save subagent runtime settings.`))}function l(t){s(null);let n=t===Rr?null:t;e.handleWriteAppSettings({subagentRuntime:{defaultLoopSubagentId:n}}).catch(e=>s(e instanceof Error?e.message:`Unable to save default loop subagent.`))}return(0,G.jsxs)(`section`,{className:`flex flex-col gap-4 rounded-lg border border-border/60 bg-card/40 p-4`,children:[(0,G.jsxs)(`header`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`h3`,{className:`text-sm font-medium text-foreground`,children:`Loop & runtime`}),(0,G.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Applies to background subagent runs and the autonomous `,(0,G.jsx)(`code`,{className:`rounded bg-muted px-1 py-0.5 font-mono`,children:`/loop`}),`.`]})]}),o?(0,G.jsx)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive`,children:o}):null,(0,G.jsx)(K,{label:`Stall timeout (seconds)`,hint:`A subagent run is aborted only after this long with no streamed activity — not a total wall-clock cap. A steadily-working run is never killed.`,children:(0,G.jsx)(R,{type:`number`,inputMode:`numeric`,min:zr,max:Br,value:i,onChange:e=>a(e.target.value),onBlur:c,onKeyDown:e=>{e.key===`Enter`&&(c(),e.currentTarget.blur())},className:`w-full md:w-48 tabular-nums`})}),(0,G.jsx)(K,{label:`Default loop subagent`,hint:`The subagent setup_loop delegates each chunk to when no explicit id is given.`,children:(0,G.jsxs)(Ne,{value:r??Rr,onValueChange:l,children:[(0,G.jsx)(ke,{className:`w-full md:w-72`,children:(0,G.jsx)(je,{placeholder:`None`})}),(0,G.jsxs)(Ae,{children:[(0,G.jsx)(F,{value:Rr,children:`None (require explicit id)`}),e.subagents.map(e=>(0,G.jsx)(F,{value:e.id,children:e.name},e.id))]})]})})]})}var Ur=new Set([`EMPTY_NAME`,`INVALID_CHAR`,`RESERVED_NAME`,`DUPLICATE_NAME`,`TOO_LONG`]);function Wr(e,t,n){if(e===`claude`){let r=t?.claude;return{name:``,provider:e,model:r?.model??n?.find(e=>e.id===`claude`)?.defaultModel??At(`claude`).defaultModel,modelOptions:{...r?.modelOptions??{...Ft}},systemPrompt:``,contextScope:`previous-assistant-reply`,triggerMode:`auto`}}if(jt(e))return{name:``,provider:e,model:t?.[e]?.model||n?.find(t=>t.id===e)?.defaultModel||At(e).defaultModel,modelOptions:{},systemPrompt:``,contextScope:`previous-assistant-reply`,triggerMode:`auto`};let r=t?.codex;return{name:``,provider:e,model:r?.model??n?.find(e=>e.id===`codex`)?.defaultModel??At(`codex`).defaultModel,modelOptions:{...r?.modelOptions??{...$t}},systemPrompt:``,contextScope:`previous-assistant-reply`,triggerMode:`auto`}}function Gr(e){return{name:e.name,description:e.description,provider:e.provider,model:e.model,modelOptions:e.modelOptions,systemPrompt:e.systemPrompt,contextScope:e.contextScope,triggerMode:e.triggerMode,workingDir:e.workingDir,allowedPaths:e.allowedPaths,maxTurns:e.maxTurns,allowBeaconTools:e.allowBeaconTools}}var Kr=(e,t)=>{if(e===t)return!0;if(!e||!t||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0};function qr(e,t){return e.name!==t.name||(e.description??``)!==(t.description??``)||e.provider!==t.provider||e.model!==t.model||e.systemPrompt!==t.systemPrompt||e.contextScope!==t.contextScope||(e.triggerMode??`auto`)!==(t.triggerMode??`auto`)||(e.workingDir??``)!==(t.workingDir??``)||!Kr(e.allowedPaths,t.allowedPaths)||(e.maxTurns??null)!==(t.maxTurns??null)||(e.allowBeaconTools??!1)!==(t.allowBeaconTools??!1)||!Jr(e.modelOptions,t.modelOptions)}function Jr(e,t){if(!se(e)||!se(t))return!1;let n=new Set([...Object.keys(e),...Object.keys(t)]);for(let r of n)if(e[r]!==t[r])return!1;return!0}function Yr(e){return Ur.has(e.code)?{field:`name`,message:e.message}:{field:`general`,message:e.message}}function Xr(e){return e.toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).slice(0,64)}function q({title:e,description:t,children:n,bordered:r=!0,alignStart:i=!1}){return(0,G.jsx)(`div`,{className:r?`border-t border-border`:void 0,children:(0,G.jsxs)(`div`,{className:D(`flex flex-col gap-4 py-5 md:flex-row md:justify-between md:gap-8`,i?`md:items-start`:`md:items-center`),children:[(0,G.jsxs)(`div`,{className:`min-w-0 max-w-xl`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:e}),(0,G.jsx)(`div`,{className:`mt-1 text-13 text-muted-foreground`,children:t})]}),(0,G.jsx)(`div`,{className:`flex items-center justify-start md:shrink-0 md:justify-end`,children:n})]})})}function Zr({icon:e,message:t}){return(0,G.jsxs)(`div`,{className:`flex flex-col items-center justify-center rounded-md border border-dashed px-6 py-10 text-center`,children:[(0,G.jsx)(e,{className:`mb-3 h-8 w-8 text-muted-foreground`,"aria-hidden":!0}),(0,G.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:t})]})}function Qr({children:e}){return(0,G.jsx)(`ul`,{className:`flex flex-col divide-y rounded-md border`,children:e})}function $r({label:e,onEdit:t,onDelete:n,deletePending:r=!1}){return(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:t,"aria-label":`Edit ${e}`,children:(0,G.jsx)(Le,{className:`h-4 w-4`})}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:n,pending:r,"aria-label":`Delete ${e}`,children:(0,G.jsx)(He,{className:`h-4 w-4`})})]})}var ei=new Set;function ti(e){return{name:e?.name??``,transport:e?.transport??`stdio`,command:e?.transport===`stdio`?e.command:``,argsText:e?.transport===`stdio`?e.args.join(`
|
|
3
|
+
wiki`,rows:3})}),(0,G.jsx)(K,{label:`Beacon tools`,hint:`Off by default. When on, this subagent can run commands and read files on your paired machines. Each call still asks for your approval.`,children:(0,G.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-sm text-foreground`,children:[(0,G.jsx)(`input`,{type:`checkbox`,"data-testid":`subagent-form-allow-beacon-tools`,checked:t.allowBeaconTools===!0,onChange:e=>{n({allowBeaconTools:e.target.checked})}}),(0,G.jsx)(`span`,{children:`Allow this subagent to use beacon tools (run on your paired machines)`})]})})]})}function Sr(e){return`contextWindow`in e}function Cr(e){return`fastMode`in e}function wr(e){let t=e.editing,n=(0,W.useMemo)(()=>t.kind===`edit`?e.subagents.find(e=>e.id===t.id)??null:null,[t,e.subagents]),r=t.kind,i=r!==`list`,a=e.subagents.length===0;return a&&!i?(0,G.jsx)(Tr,{onStartCreate:e.onStartCreate}):(0,G.jsxs)(`div`,{className:`flex flex-col gap-6 md:flex-row md:items-start md:gap-8`,children:[a?null:(0,G.jsx)(Dr,{subagents:e.subagents,editing:e.editing,onSelect:e.onSelect,onStartCreate:e.onStartCreate}),i?(0,G.jsx)(Pr,{mode:r,subject:r===`edit`?n:null,providerDefaults:e.providerDefaults,availableProviders:e.availableProviders,handlers:e.handlers,onCancelEditing:e.onCancelEditing},r===`edit`?n?.id??`edit`:`create`):(0,G.jsx)(Er,{})]})}function Tr(e){return(0,G.jsxs)(`div`,{className:`flex w-full flex-col items-center gap-4 rounded-lg border border-dashed border-border px-6 py-14 text-center`,"data-testid":`subagent-empty`,children:[(0,G.jsx)(`div`,{className:`flex size-10 items-center justify-center rounded-full bg-muted text-muted-foreground`,children:(0,G.jsx)(le,{className:`size-5`,"aria-hidden":!0})}),(0,G.jsx)(`p`,{className:`text-sm font-medium text-foreground`,children:`No subagents yet`}),(0,G.jsxs)(E,{variant:`default`,size:`sm`,onClick:e.onStartCreate,children:[(0,G.jsx)(Re,{className:`mr-1.5 size-4`}),` Create subagent`]})]})}function Er(){return(0,G.jsx)(`div`,{className:`hidden flex-1 items-center justify-center rounded-lg border border-dashed border-border px-6 py-12 text-center text-sm text-muted-foreground md:flex`,children:`Select a subagent to edit, or create a new one.`})}function Dr(e){let t=e.editing.kind===`edit`?e.editing.id:null;return(0,G.jsxs)(`aside`,{className:`flex w-full flex-col gap-2 md:w-64 md:flex-shrink-0`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,G.jsxs)(`span`,{className:`text-xs font-medium tracking-wide text-muted-foreground`,style:{fontVariantNumeric:`tabular-nums`},children:[e.subagents.length,` `,e.subagents.length===1?`agent`:`agents`]}),(0,G.jsxs)(E,{variant:`ghost`,size:`sm`,onClick:e.onStartCreate,"data-testid":`subagent-create`,children:[(0,G.jsx)(Re,{className:`size-4`}),(0,G.jsx)(`span`,{className:`sr-only`,children:`Create subagent`})]})]}),(0,G.jsx)(`ul`,{className:`flex flex-col gap-0.5`,children:e.subagents.map(n=>{let r=n.description?.trim()||(n.contextScope===`previous-assistant-reply`?`Last reply`:`Full transcript`);return(0,G.jsx)(`li`,{children:(0,G.jsxs)(`button`,{type:`button`,"data-testid":`subagent-row:${n.id}`,onClick:()=>e.onSelect(n.id),className:D(`flex w-full flex-col items-start gap-0.5 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-muted`,t===n.id&&`bg-muted`),children:[(0,G.jsxs)(`span`,{className:`flex w-full items-center justify-between gap-2`,children:[(0,G.jsx)(`span`,{className:`truncate text-sm font-medium text-foreground`,children:n.name}),(0,G.jsx)(Or,{provider:n.provider})]}),(0,G.jsx)(`span`,{className:`w-full truncate text-xs text-muted-foreground`,children:r})]})},n.id)})})]})}function Or({provider:e}){let t=At(e).label;return(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1 rounded border border-border bg-card px-1.5 py-0.5 text-xs font-medium tracking-wide text-muted-foreground`,children:[(0,G.jsx)(le,{className:`size-3`}),` `,t]})}var kr=[{value:`claude`,label:`Claude`},{value:`codex`,label:`Codex`},{value:`openrouter`,label:`OpenRouter`}],Ar=[...kr,{value:`custom`,label:`Custom endpoints`}];function jr(e,t){return t.length===0?e:e.map(e=>e.id===`openrouter`?{...e,models:t.map(e=>({id:e.id,label:e.label}))}:e)}var Mr=[{value:`previous-assistant-reply`,label:`Last reply`},{value:`full-transcript`,label:`Full transcript`}],Nr=[{value:`auto`,label:`Auto`},{value:`manual`,label:`Manual`}];function Pr(e){let t=(0,W.useMemo)(()=>e.mode===`edit`&&e.subject?Gr(e.subject):Wr(`claude`,e.providerDefaults,e.availableProviders),[e.mode,e.subject,e.providerDefaults,e.availableProviders]),n=br(e=>e.resetForm),r=br(e=>e.form),i=br(e=>e.patchFormDraft),a=br(e=>e.patchForm);(0,W.useEffect)(()=>{n(t)},[]);let{draft:o,error:s,pending:c,confirmDelete:l}=r,u=o.provider===`custom`||e.availableProviders.some(e=>e.id===`custom`)?Ar:kr,d=s?.field===`name`?s.message:null,f=s?.field===`general`?s.message:null,p=qr(o,t),m=o.name.trim().length>0&&(e.mode===`create`||p);function h(e){i(e),s?.field===`name`&&`name`in e&&a({error:null})}function g(t){if(t===o.provider)return;let n=Wr(t,e.providerDefaults,e.availableProviders);i({provider:t,model:n.model,modelOptions:n.modelOptions})}function _(e){if(o.provider!==`claude`)return;let t=Sr(o.modelOptions)?o.modelOptions:Ft;i({modelOptions:{...Ft,...t,reasoningEffort:e}})}function v(e){if(o.provider!==`claude`)return;let t=Sr(o.modelOptions)?o.modelOptions:Ft;i({modelOptions:{...Ft,...t,contextWindow:e}})}function y(e){if(o.provider!==`codex`)return;let t=Cr(o.modelOptions)?o.modelOptions:$t;i({modelOptions:{...$t,...t,reasoningEffort:e}})}async function b(){if(m&&!c){a({pending:!0,error:null,confirmDelete:!1});try{let t=e.mode===`create`?await e.handlers.onCreate(o):await e.handlers.onUpdate(e.subject.id,o);t.ok||a({error:Yr(t.error)})}catch(e){a({error:{field:`general`,message:T(e)}})}finally{a({pending:!1})}}}async function x(){if(e.mode===`edit`&&e.subject){if(!l){a({confirmDelete:!0});return}a({pending:!0,error:null});try{await e.handlers.onDelete(e.subject.id)}catch(e){a({error:{field:`general`,message:T(e)}})}finally{a({pending:!1,confirmDelete:!1})}}}let ee=o.provider===`claude`?{...Ft,...Sr(o.modelOptions)?o.modelOptions:{}}:null,te=o.provider===`codex`?{...$t,...Cr(o.modelOptions)?o.modelOptions:{}}:null,ne=e.availableProviders.find(e=>e.id===o.provider)??At(o.provider);return(0,G.jsxs)(`section`,{className:`flex w-full flex-1 flex-col gap-4`,children:[(0,G.jsxs)(`header`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`h3`,{className:`text-base font-medium text-foreground`,children:e.mode===`create`?`New subagent`:o.name||`Subagent`}),(0,G.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[`Mention with `,(0,G.jsxs)(`code`,{className:`rounded bg-muted px-1 py-0.5 font-mono text-xs`,children:[`@agent/`,o.name||`<name>`]}),` in chat.`]})]}),f?(0,G.jsx)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm text-destructive`,children:f}):null,(0,G.jsx)(K,{label:`Name`,hint:d,hintTone:d?`destructive`:`muted`,children:(0,G.jsx)(R,{"data-testid":`subagent-form-name`,value:o.name,onChange:e=>h({name:Xr(e.target.value)}),maxLength:64,placeholder:`reviewer`,className:`font-mono`})}),(0,G.jsx)(K,{label:`Description`,hint:`Optional. Shown next to the name.`,children:(0,G.jsx)(R,{"data-testid":`subagent-form-description`,value:o.description??``,onChange:e=>h({description:e.target.value}),placeholder:`Reviews diffs against the repo style`})}),(0,G.jsx)(K,{label:`Provider`,children:(0,G.jsx)(L,{value:o.provider,onValueChange:e=>{Zt(e)&&g(e)},options:u,size:`sm`})}),(0,G.jsx)(K,{label:`Model`,children:(0,G.jsxs)(Ne,{value:o.model,onValueChange:e=>h({model:e}),children:[(0,G.jsx)(ke,{"data-testid":`subagent-form-model`,className:`w-full md:w-72`,children:(0,G.jsx)(je,{placeholder:`Select a model`})}),(0,G.jsx)(Ae,{children:ne.models.map(e=>(0,G.jsx)(F,{value:e.id,children:e.label},e.id))})]})}),ee?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(K,{label:`Reasoning effort`,children:(0,G.jsx)(L,{value:ee.reasoningEffort,onValueChange:e=>{Pt(e)&&_(e)},options:Ht.map(e=>({value:e.id,label:e.label})),size:`sm`})}),(0,G.jsx)(K,{label:`Context window`,children:(0,G.jsx)(L,{value:ee.contextWindow,onValueChange:e=>{B(e)&&v(e)},options:Gt.map(e=>({value:e.id,label:e.label})),size:`sm`})})]}):null,te?(0,G.jsx)(K,{label:`Reasoning effort`,children:(0,G.jsx)(L,{value:te.reasoningEffort,onValueChange:e=>{Mt(e)&&y(e)},options:Vt.map(e=>({value:e.id,label:e.label})),size:`sm`})}):null,(0,G.jsx)(K,{label:`Context scope`,children:(0,G.jsx)(L,{value:o.contextScope,onValueChange:e=>{ur(e)&&h({contextScope:e})},options:Mr,size:`sm`})}),(0,G.jsx)(K,{label:`Trigger`,hint:`Auto: the main agent may delegate on its own. Manual: only runs when you @-mention it.`,children:(0,G.jsx)(L,{value:o.triggerMode??`auto`,onValueChange:e=>{dr(e)&&h({triggerMode:e})},options:Nr,size:`sm`})}),(0,G.jsx)(K,{label:`System prompt`,hint:`What this persona should focus on. Plain text.`,children:(0,G.jsx)(ln,{"data-testid":`subagent-form-system-prompt`,value:o.systemPrompt,onChange:e=>h({systemPrompt:e.target.value}),placeholder:`You are a careful code reviewer...`,rows:6,className:`min-h-32`})}),(0,G.jsx)(K,{label:`Max turns`,hint:`Optional. Caps the agentic turns per run (like Claude Code's per-agent maxTurns). Empty = unbounded. Claude SDK runs stop gracefully at the limit; Codex runs are aborted.`,children:(0,G.jsx)(R,{"data-testid":`subagent-form-max-turns`,type:`number`,min:1,step:1,value:o.maxTurns?.toString()??``,onChange:e=>{let t=Number.parseInt(e.target.value,10);h({maxTurns:Number.isInteger(t)&&t>0?t:void 0})},placeholder:`unbounded`,className:`w-36`})}),o.provider===`claude`?(0,G.jsx)(xr,{draft:o,patchDraft:h}):null,(0,G.jsxs)(`footer`,{className:`flex flex-wrap items-center justify-end gap-2 pt-2`,children:[(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:e.onCancelEditing,children:`Cancel`}),e.mode===`edit`?(0,G.jsx)(E,{variant:`destructive`,size:`sm`,"data-testid":`subagent-form-delete`,disabled:c,pending:c&&l,onClick:()=>{A(P(`subagent.delete`,e.subject?.id??``),x)},children:l?`Confirm delete`:`Delete`}):null,(0,G.jsx)(E,{variant:`default`,size:`sm`,"data-testid":`subagent-form-save`,disabled:!m||c,pending:c&&!l,onClick:()=>{A(P(`subagent.save`,e.subject?.id??`new`),b)},children:c?`Saving…`:`Save`})]})]})}var Fr=[],Ir={claude:{model:At(`claude`).defaultModel,modelOptions:{...Ft},planMode:!1},codex:{model:At(`codex`).defaultModel,modelOptions:{...$t},planMode:!1},openrouter:{model:tn,modelOptions:{},planMode:!1},custom:{model:``,modelOptions:{},planMode:!1}};function Lr(e){let t=z(e=>e.settings?.subagents??Fr),n=z(e=>e.settings?.providerDefaults??Ir),r=z(ot),i=z(gt),a=m(Et(e=>e.models)),o=(0,W.useMemo)(()=>jr(He(Nt([...Lt],r),i),a),[r,i,a]),s=br(e=>e.editing),c=br(e=>e.setEditing),l=(0,W.useMemo)(()=>({onCreate:async t=>{let n=await e.state.socket.command({type:`subagent.create`,input:t});return n.ok&&c({kind:`edit`,id:n.subagent.id}),n},onUpdate:async(t,n)=>await e.state.socket.command({type:`subagent.update`,id:t,patch:{...n,maxTurns:n.maxTurns??null}}),onDelete:async t=>{await e.state.socket.command({type:`subagent.delete`,id:t}),c({kind:`list`})}}),[e.state.socket,c]),u=(0,W.useCallback)(e=>{c({kind:`edit`,id:e})},[c]),d=(0,W.useCallback)(()=>{c({kind:`create`})},[c]),f=(0,W.useCallback)(()=>{c({kind:`list`})},[c]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-6 px-6 py-6`,children:[(0,G.jsx)(Hr,{subagents:t,handleWriteAppSettings:e.state.handleWriteAppSettings}),(0,G.jsx)(wr,{subagents:t,providerDefaults:n,availableProviders:o,editing:s,onSelect:u,onStartCreate:d,onCancelEditing:f,handlers:l})]})}var Rr=`__none__`,zr=30,Br=86400,Vr=600;function Hr(e){let t=z(e=>e.settings?.subagentRuntime),n=t?Math.round(t.runTimeoutMs/1e3):Vr,r=t?.defaultLoopSubagentId??null,i=br(e=>e.timeoutDraft),a=br(e=>e.setTimeoutDraft),o=br(e=>e.loopError),s=br(e=>e.setLoopError);(0,W.useEffect)(()=>{a(String(n))},[n]);function c(){let t=Number(i);if(!Number.isInteger(t)||t<zr||t>Br){a(String(n)),s(`Timeout must be a whole number of seconds between ${zr} and ${Br}.`);return}s(null),t!==n&&e.handleWriteAppSettings({subagentRuntime:{runTimeoutMs:t*1e3}}).catch(e=>s(e instanceof Error?e.message:`Unable to save subagent runtime settings.`))}function l(t){s(null);let n=t===Rr?null:t;e.handleWriteAppSettings({subagentRuntime:{defaultLoopSubagentId:n}}).catch(e=>s(e instanceof Error?e.message:`Unable to save default loop subagent.`))}return(0,G.jsxs)(`section`,{className:`flex flex-col gap-4 rounded-lg border border-border/60 bg-card/40 p-4`,children:[(0,G.jsxs)(`header`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`h3`,{className:`text-sm font-medium text-foreground`,children:`Loop & runtime`}),(0,G.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Applies to background subagent runs and the autonomous `,(0,G.jsx)(`code`,{className:`rounded bg-muted px-1 py-0.5 font-mono`,children:`/loop`}),`.`]})]}),o?(0,G.jsx)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive`,children:o}):null,(0,G.jsx)(K,{label:`Stall timeout (seconds)`,hint:`A subagent run is aborted only after this long with no streamed activity — not a total wall-clock cap. A steadily-working run is never killed.`,children:(0,G.jsx)(R,{type:`number`,inputMode:`numeric`,min:zr,max:Br,value:i,onChange:e=>a(e.target.value),onBlur:c,onKeyDown:e=>{e.key===`Enter`&&(c(),e.currentTarget.blur())},className:`w-full md:w-48 tabular-nums`})}),(0,G.jsx)(K,{label:`Default loop subagent`,hint:`The subagent setup_loop delegates each chunk to when no explicit id is given.`,children:(0,G.jsxs)(Ne,{value:r??Rr,onValueChange:l,children:[(0,G.jsx)(ke,{className:`w-full md:w-72`,children:(0,G.jsx)(je,{placeholder:`None`})}),(0,G.jsxs)(Ae,{children:[(0,G.jsx)(F,{value:Rr,children:`None (require explicit id)`}),e.subagents.map(e=>(0,G.jsx)(F,{value:e.id,children:e.name},e.id))]})]})})]})}var Ur=new Set([`EMPTY_NAME`,`INVALID_CHAR`,`RESERVED_NAME`,`DUPLICATE_NAME`,`TOO_LONG`]);function Wr(e,t,n){if(e===`claude`){let r=t?.claude;return{name:``,provider:e,model:r?.model??n?.find(e=>e.id===`claude`)?.defaultModel??At(`claude`).defaultModel,modelOptions:{...r?.modelOptions??{...Ft}},systemPrompt:``,contextScope:`previous-assistant-reply`,triggerMode:`auto`}}if(jt(e))return{name:``,provider:e,model:t?.[e]?.model||n?.find(t=>t.id===e)?.defaultModel||At(e).defaultModel,modelOptions:{},systemPrompt:``,contextScope:`previous-assistant-reply`,triggerMode:`auto`};let r=t?.codex;return{name:``,provider:e,model:r?.model??n?.find(e=>e.id===`codex`)?.defaultModel??At(`codex`).defaultModel,modelOptions:{...r?.modelOptions??{...$t}},systemPrompt:``,contextScope:`previous-assistant-reply`,triggerMode:`auto`}}function Gr(e){return{name:e.name,description:e.description,provider:e.provider,model:e.model,modelOptions:e.modelOptions,systemPrompt:e.systemPrompt,contextScope:e.contextScope,triggerMode:e.triggerMode,workingDir:e.workingDir,allowedPaths:e.allowedPaths,maxTurns:e.maxTurns,allowBeaconTools:e.allowBeaconTools}}var Kr=(e,t)=>{if(e===t)return!0;if(!e||!t||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0};function qr(e,t){return e.name!==t.name||(e.description??``)!==(t.description??``)||e.provider!==t.provider||e.model!==t.model||e.systemPrompt!==t.systemPrompt||e.contextScope!==t.contextScope||(e.triggerMode??`auto`)!==(t.triggerMode??`auto`)||(e.workingDir??``)!==(t.workingDir??``)||!Kr(e.allowedPaths,t.allowedPaths)||(e.maxTurns??null)!==(t.maxTurns??null)||(e.allowBeaconTools??!1)!==(t.allowBeaconTools??!1)||!Jr(e.modelOptions,t.modelOptions)}function Jr(e,t){if(!se(e)||!se(t))return!1;let n=new Set([...Object.keys(e),...Object.keys(t)]);for(let r of n)if(e[r]!==t[r])return!1;return!0}function Yr(e){return Ur.has(e.code)?{field:`name`,message:e.message}:{field:`general`,message:e.message}}function Xr(e){return e.toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).slice(0,64)}function q({title:e,description:t,children:n,bordered:r=!0,alignStart:i=!1}){return(0,G.jsx)(`div`,{className:r?`border-t border-border`:void 0,children:(0,G.jsxs)(`div`,{className:D(`flex flex-col gap-4 py-5 md:flex-row md:justify-between md:gap-8`,i?`md:items-start`:`md:items-center`),children:[(0,G.jsxs)(`div`,{className:`min-w-0 max-w-xl`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:e}),(0,G.jsx)(`div`,{className:`mt-1 text-13 text-muted-foreground`,children:t})]}),(0,G.jsx)(`div`,{className:`flex items-center justify-start md:shrink-0 md:justify-end`,children:n})]})})}function Zr({icon:e,message:t}){return(0,G.jsxs)(`div`,{className:`flex flex-col items-center justify-center rounded-md border border-dashed px-6 py-10 text-center`,children:[(0,G.jsx)(e,{className:`mb-3 h-8 w-8 text-muted-foreground`,"aria-hidden":!0}),(0,G.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:t})]})}function Qr({children:e}){return(0,G.jsx)(`ul`,{className:`flex flex-col divide-y rounded-md border`,children:e})}function $r({label:e,onEdit:t,onDelete:n,deletePending:r=!1}){return(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:t,"aria-label":`Edit ${e}`,children:(0,G.jsx)(Le,{className:`h-4 w-4`})}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:n,pending:r,"aria-label":`Delete ${e}`,children:(0,G.jsx)(Ve,{className:`h-4 w-4`})})]})}var ei=new Set;function ti(e){return{name:e?.name??``,transport:e?.transport??`stdio`,command:e?.transport===`stdio`?e.command:``,argsText:e?.transport===`stdio`?e.args.join(`
|
|
4
4
|
`):``,envText:e?.transport===`stdio`?Object.entries(e.env).map(([e,t])=>`${e}=${t}`).join(`
|
|
5
5
|
`):``,cwd:e?.transport===`stdio`?e.cwd??``:``,url:e!==null&&e.transport!==`stdio`?e.url:``,headersText:e!==null&&e.transport!==`stdio`?Object.entries(e.headers).map(([e,t])=>`${e}: ${t}`).join(`
|
|
6
6
|
`):``,error:null,submitting:!1,oauthEnabled:e!==null&&e.transport!==`stdio`?e.oauth?.enabled??!1:!1,authFlowUrl:null,callbackInput:``,oauthError:null,authenticating:!1,completing:!1}}var ni=w()(e=>({editing:{kind:`list`},testingServerIds:ei,editorForm:ti(null),setEditing:t=>e({editing:t}),setServerTesting:(t,n)=>e(e=>{let r=new Set(e.testingServerIds);return n?r.add(t):r.delete(t),{testingServerIds:r.size===0?ei:r}}),resetEditorForm:t=>e({editorForm:ti(t)}),patchEditorForm:t=>e(e=>({editorForm:{...e.editorForm,...t}}))}));function ri(e,t){return(0,W.useMemo)(()=>({onCreate:async n=>{await t.handleWriteAppSettings(e({create:n}))},onUpdate:async(n,r)=>{await t.handleWriteAppSettings(e({update:{id:n,patch:r}}))},onDelete:async n=>{await t.handleWriteAppSettings(e({delete:{id:n}}))}}),[e,t])}async function ii(e){e.patch({submitting:!0,error:null});try{await e.save(),e.onDone()}catch(t){e.patch({error:t instanceof Error?t.message:e.fallbackMessage})}finally{e.patch({submitting:!1})}}function ai(e){return e.submitting?`Saving…`:e.isEdit?`Save changes`:e.addLabel}function oi({server:e,handlers:t,onEdit:n,dom:r=oe}){let i=ni(t=>t.testingServerIds.has(e.id)),a=ni(e=>e.setServerTesting),o=(0,W.useCallback)(async()=>{a(e.id,!0);try{await t.onTest(e.id)}finally{a(e.id,!1)}},[t,e.id,a]),s=P(`mcpServers.delete`,e.id),c=M(s),l=P(`mcpServers.setEnabled`,e.id),u=M(l),d=P(`settings.testMcpServer`,e.id),f=(0,W.useCallback)(()=>{r.confirmDialog(`Delete MCP server "${e.name}"?`)&&A(s,()=>t.onDelete(e.id))},[s,r,t,e.id,e.name]),p=(0,W.useCallback)(n=>{let r=n.target.checked;A(l,()=>t.onSetEnabled(e.id,r))},[t,e.id,l]),m=(0,W.useCallback)(()=>{A(d,o)},[o,d]);return(0,G.jsxs)(`li`,{className:`flex items-center gap-3 px-4 py-3`,"aria-busy":c||void 0,children:[(0,G.jsxs)(`div`,{className:`flex flex-col`,children:[(0,G.jsx)(`span`,{className:`font-medium`,children:e.name}),(0,G.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[(0,G.jsx)(si,{transport:e.transport}),(0,G.jsx)(`span`,{className:`ml-2`,children:e.transport===`stdio`?e.command:e.url})]})]}),(0,G.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,G.jsx)(ci,{result:e.lastTest,pending:i}),e.transport!==`stdio`&&(0,G.jsx)(li,{oauth:e.oauth}),(0,G.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-1 text-xs text-muted-foreground`,children:[u?(0,G.jsx)(N,{}):null,(0,G.jsx)(`input`,{type:`checkbox`,checked:e.enabled,disabled:u,"aria-busy":u||void 0,onChange:p,"aria-label":`Enabled`}),(0,G.jsx)(`span`,{children:`On`})]}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:m,disabled:i,"aria-busy":i||void 0,title:`Test connection`,children:(0,G.jsx)(ze,{className:D(`h-4 w-4`,i&&`animate-spin`)})}),(0,G.jsx)($r,{label:e.name,onEdit:n,onDelete:f,deletePending:c})]})]})}function si({transport:e}){return(0,G.jsx)(`span`,{className:`rounded bg-muted px-1.5 py-0.5 text-xs`,children:e})}function ci({result:e,pending:t}){if(t||e.status===`pending`)return(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Testing…`});switch(e.status){case`ok`:return(0,G.jsxs)(`span`,{className:`text-xs text-green-600`,children:[`OK · `,e.toolCount,` tools`]});case`error`:return(0,G.jsx)(on,{label:e.message,children:(0,G.jsx)(`span`,{className:`text-xs text-red-600`,children:`Failed`})});default:return(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Untested`})}}function li({oauth:e}){if(!e?.enabled)return null;switch(e.status){case`authenticated`:return(0,G.jsx)(`span`,{className:`text-xs text-green-600`,children:`OAuth ✓`});case`error`:return(0,G.jsx)(on,{label:e.errorMessage,children:(0,G.jsx)(`span`,{className:`text-xs text-red-600`,children:`OAuth error`})});default:return(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`OAuth: unauth`})}}var ui=new Set([`stdio`,`http`,`sse`,`ws`]);function di(e){return ui.has(e)}var fi=`new`;function pi({pending:e,copied:t}){return e?(0,G.jsx)(N,{className:`size-3`}):t?(0,G.jsx)(Ee,{className:`h-3 w-3 text-success-text`}):(0,G.jsx)(Te,{className:`h-3 w-3`})}var mi=e=>({customMcpServers:e});function hi(e){return e.editing.kind===`list`?e.servers.length===0?(0,G.jsxs)(`div`,{className:`flex flex-col items-center justify-center px-6 py-16 text-center`,children:[(0,G.jsx)(Qn,{className:`mb-4 h-10 w-10 text-muted-foreground`,"aria-hidden":!0}),(0,G.jsx)(`h2`,{className:`text-lg font-medium`,children:`No custom MCP servers`}),(0,G.jsx)(`p`,{className:`mt-2 max-w-md text-sm text-muted-foreground`,children:`Install MCP servers to extend the model's tool surface. Supports stdio, http, sse, and ws transports.`}),(0,G.jsxs)(E,{className:`mt-6`,onClick:e.onStartCreate,children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add server`]})]}):(0,G.jsxs)(`div`,{className:`flex flex-col gap-3 px-6 py-6`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:`Custom MCP servers`}),(0,G.jsxs)(E,{size:`sm`,onClick:e.onStartCreate,children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add server`]})]}),(0,G.jsx)(Qr,{children:e.servers.map(t=>(0,G.jsx)(oi,{server:t,handlers:e.handlers,onEdit:()=>e.onSelect(t.id)},t.id))})]}):(0,G.jsx)(gi,{initial:e.editing.kind===`edit`?e.servers.find(t=>e.editing.kind===`edit`&&t.id===e.editing.id)??null:null,existingNames:e.servers.map(e=>({id:e.id,name:e.name})),onCancel:e.onCancelEditing,handlers:e.handlers})}function gi({initial:e,existingNames:t,onCancel:n,handlers:r,clipboard:i=De}){let a=ni(e=>e.editorForm),o=ni(e=>e.resetEditorForm),s=ni(e=>e.patchEditorForm),c=(0,W.useCallback)(e=>{di(e)&&s({transport:e})},[s]),{name:l,transport:u,command:d,argsText:f,envText:p,cwd:m,url:h,headersText:g,error:_,submitting:v,oauthEnabled:y,authFlowUrl:b,callbackInput:x,oauthError:ee,authenticating:te,completing:ne}=a,S=(0,W.useRef)(e);(0,W.useEffect)(()=>{o(S.current)},[o]);let re=e!==null&&e.transport!==`stdio`?e.oauth:void 0,C=e?.id??fi,ie=P(`mcpServers.toggleOAuth`,C),ae=M(ie),w=P(`mcpServers.copyAuthUrl`,C),oe=M(w),T=ye(w),se=(0,W.useCallback)(async t=>{s(t?{oauthEnabled:!0}:{oauthEnabled:!1,authFlowUrl:null,callbackInput:``,oauthError:null}),e&&await r.onUpdate(e.id,{oauth:{...re??{status:`unauthenticated`},enabled:t}})},[e,re,r,s]),ce=(0,W.useCallback)(async()=>{if(e){s({authenticating:!0,oauthError:null});try{let t=await r.onStartMcpOAuth(e.id);t.ok&&t.authorizationUrl?s({authFlowUrl:t.authorizationUrl}):t.ok&&t.alreadyAuthenticated?s({authFlowUrl:null}):s({oauthError:t.error??`Failed to start OAuth flow`})}finally{s({authenticating:!1})}}},[e,r,s]),D=(0,W.useCallback)(async()=>{if(e){s({completing:!0,oauthError:null});try{let t=await r.onCompleteMcpOAuth(e.id,x);t.ok?s({authFlowUrl:null,callbackInput:``}):s({oauthError:t.error??`Failed to complete OAuth flow`})}finally{s({completing:!1})}}},[e,x,r,s]),O=(0,W.useCallback)(e=>{let t=e.target.checked;A(ie,()=>se(t))},[se,ie]),k=(0,W.useCallback)(()=>{A(P(`settings.startMcpOAuth`,C),ce)},[C,ce]),j=(0,W.useCallback)(()=>{A(P(`settings.completeMcpOAuth`,C),D)},[D,C]),le=(0,W.useCallback)(()=>{b&&A(w,()=>be(w,()=>i.writeText(b)))},[b,i,w]),de=(0,W.useMemo)(()=>l.length===0?null:/^[a-zA-Z][a-zA-Z0-9_-]{0,31}$/.test(l)?l===`kanna`?`'kanna' is reserved.`:t.find(t=>t.name===l&&t.id!==e?.id)?`Name already taken.`:null:`Name must start with a letter and contain only letters, digits, '_' or '-' (max 32 chars).`,[l,t,e?.id]),fe=(0,W.useCallback)(async()=>{de||await ii({patch:s,save:async()=>{let t=f.split(`
|
|
@@ -8,10 +8,10 @@ wiki`,rows:3})}),(0,G.jsx)(K,{label:`Beacon tools`,hint:`Off by default. When on
|
|
|
8
8
|
`)){let t=e.indexOf(`=`);t>0&&(n[e.slice(0,t).trim()]=e.slice(t+1))}let i={};for(let e of g.split(`
|
|
9
9
|
`)){let t=e.indexOf(`:`);t>0&&(i[e.slice(0,t).trim()]=e.slice(t+1).trim())}if(e){let a=u===`stdio`?{name:l,transport:u,command:d,args:t,env:n,cwd:m||void 0}:{name:l,transport:u,url:h,headers:i};await r.onUpdate(e.id,a)}else{let e=u===`stdio`?{name:l,transport:`stdio`,command:d,args:t,env:n,cwd:m||void 0}:{name:l,transport:u,url:h,headers:i};await r.onCreate(e)}},onDone:n,fallbackMessage:`Failed to save MCP server`})},[f,d,m,p,r,g,e,l,de,n,u,h,s]),pe=(0,W.useCallback)(()=>{A(P(`mcpServers.save`,C),fe)},[C,fe]),me=ai({submitting:v,isEdit:e!==null,addLabel:`Add server`});return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 px-6 py-6 max-w-2xl`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:e?`Edit MCP server`:`Add MCP server`}),(0,G.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,G.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`Name`}),(0,G.jsx)(R,{value:l,onChange:e=>s({name:e.target.value}),placeholder:`fs`}),de&&(0,G.jsx)(`p`,{className:`text-xs text-red-600`,children:de})]}),(0,G.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,G.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`Transport`}),(0,G.jsxs)(Ne,{value:u,onValueChange:c,children:[(0,G.jsx)(ke,{children:(0,G.jsx)(je,{})}),(0,G.jsxs)(Ae,{children:[(0,G.jsx)(F,{value:`stdio`,children:`stdio (spawn local command)`}),(0,G.jsx)(F,{value:`http`,children:`http (Streamable HTTP)`}),(0,G.jsx)(F,{value:`sse`,children:`sse (Server-Sent Events)`}),(0,G.jsx)(F,{value:`ws`,children:`ws (WebSocket)`})]})]})]}),u===`stdio`?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,G.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`Command`}),(0,G.jsx)(R,{value:d,onChange:e=>s({command:e.target.value}),placeholder:`/usr/local/bin/mcp-filesystem`})]}),(0,G.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,G.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`Args (one per line)`}),(0,G.jsx)(ln,{value:f,onChange:e=>s({argsText:e.target.value}),rows:3,className:`font-mono text-sm`})]}),(0,G.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,G.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`Env (KEY=value, one per line)`}),(0,G.jsx)(ln,{value:p,onChange:e=>s({envText:e.target.value}),rows:3,className:`font-mono text-sm`})]}),(0,G.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,G.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`cwd (optional)`}),(0,G.jsx)(R,{value:m,onChange:e=>s({cwd:e.target.value}),placeholder:`/optional/working/dir`})]})]}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,G.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`URL`}),(0,G.jsx)(R,{value:h,onChange:e=>s({url:e.target.value}),placeholder:u===`ws`?`wss://example.com/mcp`:`https://example.com/mcp`})]}),u===`ws`?(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Headers are not supported on the ws transport.`}):(0,G.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,G.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`Headers (Key: value, one per line)`}),(0,G.jsx)(ln,{value:g,onChange:e=>s({headersText:e.target.value}),rows:3,className:`font-mono text-sm`,disabled:y}),y&&(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Authorization header is managed by OAuth when enabled.`})]}),(u===`http`||u===`sse`)&&(0,G.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-md border p-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(ue,{className:`h-4 w-4 text-muted-foreground`,"aria-hidden":!0}),(0,G.jsx)(`span`,{className:`text-xs font-medium`,children:`OAuth 2.1`}),(0,G.jsxs)(`label`,{className:`ml-auto flex cursor-pointer items-center gap-1 text-xs text-muted-foreground`,children:[ae?(0,G.jsx)(N,{}):null,(0,G.jsx)(`input`,{type:`checkbox`,checked:y,disabled:ae,"aria-busy":ae||void 0,onChange:O,"aria-label":`Enable OAuth`}),(0,G.jsx)(`span`,{children:`Enable`})]})]}),y&&!e&&(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Save the server first, then authenticate.`}),y&&e&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(li,{oauth:re}),re?.status===`authenticated`&&(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:k,pending:te,children:`Re-authenticate`})]}),(re?.status!==`authenticated`||b)&&(b?(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,G.jsxs)(`a`,{href:b,target:`_blank`,rel:`noopener noreferrer`,className:`flex items-center gap-1 text-xs text-blue-600 underline`,children:[`Open authorization URL`,(0,G.jsx)(Pe,{className:`h-3 w-3`})]}),(0,G.jsx)(on,{label:T?`Copied`:`Copy URL`,children:(0,G.jsx)(`button`,{type:`button`,onClick:le,disabled:oe,"aria-busy":oe||void 0,className:`ml-1 text-muted-foreground hover:text-foreground`,"aria-label":T?`Copied`:`Copy authorization URL`,children:(0,G.jsx)(pi,{pending:oe,copied:T})})})]}),(0,G.jsxs)(`div`,{className:`grid gap-1`,children:[(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`After authorizing, paste the callback URL here:`}),(0,G.jsx)(R,{value:x,onChange:e=>s({callbackInput:e.target.value}),placeholder:`http://localhost:…/callback?code=…`,className:`font-mono text-xs`})]}),(0,G.jsx)(E,{variant:`outline`,size:`sm`,className:`w-fit`,onClick:j,pending:ne,disabled:x.length===0,children:ne?`Completing…`:`Complete`})]}):(0,G.jsx)(E,{variant:`outline`,size:`sm`,className:`w-fit`,onClick:k,pending:te,children:te?`Starting…`:`Authenticate`})),ee&&(0,G.jsx)(`p`,{className:`text-xs text-red-600`,children:ee})]})]})]}),_&&(0,G.jsx)(`p`,{className:`text-xs text-red-600`,children:_}),(0,G.jsxs)(`div`,{className:`flex justify-end gap-2 pt-2`,children:[(0,G.jsx)(E,{variant:`ghost`,onClick:n,disabled:v,children:`Cancel`}),(0,G.jsx)(E,{onClick:pe,pending:v,disabled:!!de||l.length===0,children:me})]})]})}function _i(e){let t=z(ft),n=ni(e=>e.editing),r=ni(e=>e.setEditing),i=ri(mi,e.state),a=(0,W.useMemo)(()=>({...i,onDelete:async e=>{await i.onDelete(e),r({kind:`list`})},onSetEnabled:async(t,n)=>{await e.state.handleWriteAppSettings({customMcpServers:{setEnabled:{id:t,enabled:n}}})},onTest:async t=>{await e.state.handleTestMcpServer(t)},onStartMcpOAuth:async t=>e.state.handleStartMcpOAuth(t),onCompleteMcpOAuth:async(t,n)=>e.state.handleCompleteMcpOAuth(t,n)}),[i,e.state,r]);return(0,G.jsx)(hi,{servers:t,editing:n,onSelect:e=>r({kind:`edit`,id:e}),onStartCreate:()=>r({kind:`create`}),onCancelEditing:()=>r({kind:`list`}),handlers:a})}var vi={disabled:`Disabled`,connecting:`Connecting`,listening:`Listening`,polling:`Polling`,backoff:`Retrying`,error:`Error`},yi={disabled:`muted`,connecting:`attention`,listening:`muted`,polling:`muted`,backoff:`attention`,error:`destructive`},bi={subscribe:`Subscribe`,poll:`Poll`},xi={subscribe:`Kanna listens for change notifications on the resources you name and reads each one that changes.`,poll:`Kanna calls a tool on an interval and remembers a cursor, so each message is delivered once.`};function Si(e){return vi[e]}function Ci(e){return yi[e]}function wi(e){return bi[e]}function Ti(e){return xi[e]}var Ei={zalo:{label:`Zalo`,mode:`poll`,tool:`zalo_get_messages`,args:{limit:50},cursorArg:`since`,cursorPath:`cursor`,itemsPath:`messages`,itemKeyPath:`messageId`,threadKeyPath:`threadId`,senderPath:`senderName`,intervalMs:15e3,handler:{mode:`spawn`,template:`A new Zalo message arrived in a conversation. Read it, decide whether the user needs to act, and draft a reply in the same language the sender used.`,replyHint:`Send the reply with zalo_send_message using threadId {{threadId}} and threadType {{threadType}} (0 for a direct message, 1 for a group).`,pushEnabled:!0}}},Di=[`subscribe`,`poll`],Oi=5e3,ki=8e3,Ai=2e3;function ji(e){return Di.some(t=>t===e)}function Mi(e){return e.trim().length>0}function Ni(e){let t=Cn(e.handler),n=e.handler.template.trim();return n.length===0&&t.push(`Template is required`),n.length>8e3&&t.push(`Template must be at most ${ki} characters`),e.handler.replyHint.length>2e3&&t.push(`Reply hint must be at most ${Ai} characters`),t}function Pi(e){if(e.mode===`subscribe`)return e.resourceUris.some(Mi)?[]:[`At least one resource URI is required`];let t=[],n=[[`Tool`,e.tool],[`Cursor argument`,e.cursorArg],[`Cursor path`,e.cursorPath],[`Items path`,e.itemsPath]];for(let[e,r]of n)Mi(r)||t.push(`${e} is required`);return St(e.args)||t.push(`Arguments must be a JSON object`),t}function Fi(e){let t=[],n=e.name.trim();return n.length===0&&t.push(`Name is required`),n.length>80&&t.push(`Name must be at most 80 characters`),Mi(e.serverId)||t.push(`An MCP server is required`),ji(e.mode)?t.push(...Pi(e)):t.push(`Mode must be subscribe or poll`),[e.threadKeyPath,e.senderPath].some(e=>e.length>200)&&t.push(`Paths must be at most 200 characters`),t.push(...Ni(e)),t}function Ii(e){let t=e.trim();if(t.length===0)return{args:{}};let n=at(t);return n!==null&&St(n)?{args:n}:{error:`Arguments must be a JSON object`}}var Li=`A new message arrived. Read it, decide whether the user needs to act, and draft a reply if one is appropriate.`,Ri=`30`;function zi(){return{name:``,serverId:``,mode:`subscribe`,resourceUris:``,tool:``,argsText:`{}`,cursorArg:``,cursorPath:``,itemsPath:``,itemKeyPath:``,intervalSeconds:Ri,threadKeyPath:``,senderPath:``,handlerMode:`spawn`,chatId:``,projectId:``,modelValue:``,template:Li,replyHint:``,pushEnabled:!0}}function Bi(e){return{handlerMode:e.mode,chatId:e.chatId??``,projectId:e.projectId??``,modelValue:e.provider&&e.model?H(e.provider,e.model):``,template:e.template,replyHint:e.replyHint,pushEnabled:e.pushEnabled}}function Vi(e){let t={...zi(),name:e.name,serverId:e.serverId,mode:e.mode,threadKeyPath:e.threadKeyPath,senderPath:e.senderPath,...Bi(e.handler)};return e.mode===`subscribe`?{...t,resourceUris:e.resourceUris.join(`
|
|
10
10
|
`)}:{...t,tool:e.tool,argsText:JSON.stringify(e.args,null,2),cursorArg:e.cursorArg,cursorPath:e.cursorPath,itemsPath:e.itemsPath,itemKeyPath:e.itemKeyPath??``,intervalSeconds:String(Math.round(e.intervalMs/1e3))}}function Hi(e){let t=Ei.zalo;return{...e,name:e.name.trim().length>0?e.name:t.label,mode:t.mode,tool:t.tool,argsText:JSON.stringify(t.args,null,2),cursorArg:t.cursorArg,cursorPath:t.cursorPath,itemsPath:t.itemsPath,itemKeyPath:t.itemKeyPath,intervalSeconds:String(Math.round(t.intervalMs/1e3)),threadKeyPath:t.threadKeyPath,senderPath:t.senderPath,...Bi({...t.handler,projectId:e.projectId||void 0})}}function Ui(e){return e.handlerMode===`spawn`?e.projectId?{projectId:e.projectId}:{}:e.chatId?{chatId:e.chatId}:{}}function Wi(e){let t=e.handlerMode===`notify`?null:U(e.modelValue);return{mode:e.handlerMode,template:e.template,replyHint:e.replyHint,pushEnabled:e.pushEnabled,...Ui(e),...t?{provider:t.provider,model:t.model}:{}}}function Gi(e){let t={name:e.name.trim(),serverId:e.serverId,threadKeyPath:e.threadKeyPath.trim(),senderPath:e.senderPath.trim(),handler:Wi(e)};if(e.mode===`subscribe`){let n={...t,mode:`subscribe`,resourceUris:e.resourceUris.split(`
|
|
11
|
-
`).map(e=>e.trim()).filter(e=>e.length>0)},r=Fi(n);return r.length>0?{ok:!1,errors:r}:{ok:!0,input:n}}let n=Ii(e.argsText),r=Number(e.intervalSeconds),i={...t,mode:`poll`,tool:e.tool.trim(),args:`args`in n?n.args:{},cursorArg:e.cursorArg.trim(),cursorPath:e.cursorPath.trim(),itemsPath:e.itemsPath.trim(),itemKeyPath:e.itemKeyPath.trim()||null,intervalMs:Number.isFinite(r)?Math.round(r*1e3):Oi},a=[...`error`in n?[n.error]:[],...Number.isFinite(r)&&r>0?[]:[`Interval must be a number of seconds`],...Fi(i)];return a.length>0?{ok:!1,errors:a}:{ok:!0,input:i}}function Ki(e){let{enabled:t,...n}=e;return n}var qi=w()(e=>({editing:{kind:`list`},draft:zi(),error:null,confirmingDeleteId:null,startCreate:()=>e({editing:{kind:`create`},draft:zi(),error:null}),startEdit:t=>e({editing:{kind:`edit`,id:t.id},draft:Vi(t),error:null}),closeEditor:()=>e({editing:{kind:`list`},error:null}),patchDraft:t=>e(e=>({draft:{...e.draft,...t}})),applyZaloPreset:()=>e(e=>({draft:Hi(e.draft)})),setError:t=>e({error:t}),askDelete:t=>e({confirmingDeleteId:t}),cancelDelete:()=>e({confirmingDeleteId:null})})),Ji=[`subscribe`,`poll`].map(e=>({value:e,label:wi(e)})),Yi=[`notify`,`inline`,`spawn`].map(e=>({value:e,label:Ke(e)}));function J({id:e,label:t,hint:n,children:r}){return(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(`label`,{htmlFor:e,className:`block text-sm font-medium text-foreground`,children:t}),r,n?(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:n}):null]})}function Xi(e,t){let n=e.filter(e=>e.transport!==`ws`&&(e.enabled||e.id===t)),r=n.filter(e=>e.transport!==`stdio`),i=n.filter(e=>e.transport===`stdio`);return[...r,...i].map(e=>({value:e.id,label:e.name,hint:e.transport}))}function Zi({draft:e,onChange:t}){return(0,G.jsx)(J,{id:`mcp-source-uris`,label:`Resource URIs`,hint:`One URI per line. Kanna subscribes to each and reads it whenever the server says it changed.`,children:(0,G.jsx)(ln,{id:`mcp-source-uris`,rows:3,className:`font-mono`,value:e.resourceUris,onChange:e=>t({resourceUris:e.target.value})})})}function Qi({draft:e,onChange:t}){return(0,G.jsxs)(`div`,{className:`space-y-4`,children:[(0,G.jsx)(J,{id:`mcp-source-tool`,label:`List tool`,hint:`The tool Kanna calls on every poll.`,children:(0,G.jsx)(R,{id:`mcp-source-tool`,className:`font-mono`,value:e.tool,onChange:e=>t({tool:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-args`,label:`Arguments`,hint:`A JSON object sent with every call. The cursor is added under the cursor argument.`,children:(0,G.jsx)(ln,{id:`mcp-source-args`,rows:3,className:`font-mono`,value:e.argsText,onChange:e=>t({argsText:e.target.value})})}),(0,G.jsxs)(`div`,{className:`grid grid-cols-1 gap-4 sm:grid-cols-2`,children:[(0,G.jsx)(J,{id:`mcp-source-cursor-arg`,label:`Cursor argument`,children:(0,G.jsx)(R,{id:`mcp-source-cursor-arg`,className:`font-mono`,value:e.cursorArg,onChange:e=>t({cursorArg:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-cursor-path`,label:`Cursor path`,hint:`Where the next cursor sits in the result.`,children:(0,G.jsx)(R,{id:`mcp-source-cursor-path`,className:`font-mono`,value:e.cursorPath,onChange:e=>t({cursorPath:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-items-path`,label:`Items path`,hint:`Where the array of messages sits in the result.`,children:(0,G.jsx)(R,{id:`mcp-source-items-path`,className:`font-mono`,value:e.itemsPath,onChange:e=>t({itemsPath:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-item-key`,label:`Item key path`,hint:`A field that is unique per message. Leave empty to hash the whole item.`,children:(0,G.jsx)(R,{id:`mcp-source-item-key`,className:`font-mono`,value:e.itemKeyPath,onChange:e=>t({itemKeyPath:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-interval`,label:`Interval (seconds)`,hint:`Between 5 and 3600.`,children:(0,G.jsx)(R,{id:`mcp-source-interval`,inputMode:`numeric`,className:`tabular-nums`,value:e.intervalSeconds,onChange:e=>t({intervalSeconds:e.target.value})})})]})]})}function $i({editing:e,servers:t,sidebarData:n,handlers:r}){let i=Sn(),a=qi(e=>e.draft),o=qi(e=>e.error),s=qi(e=>e.patchDraft),c=qi(e=>e.applyZaloPreset),l=qi(e=>e.closeEditor),u=qi(e=>e.setError),d=P(`mcpSources.save`,e?.id??`new`),f=M(d),p=(0,W.useMemo)(()=>En(n),[n]),m=(0,W.useMemo)(()=>Tn(i),[i]),h=(0,W.useMemo)(()=>Xi(t,a.serverId),[t,a.serverId]),g=(0,W.useMemo)(()=>Gi(a),[a]),_=a.handlerMode!==`notify`,v=(0,W.useCallback)(e=>s({name:e.target.value}),[s]),y=(0,W.useCallback)(()=>{g.ok&&A(d,async()=>{u(null);try{e?await r.onUpdate(e.id,Ki(g.input)):await r.onCreate(g.input),l()}catch(e){u(e instanceof Error?e.message:`Failed to save the MCP source`)}})},[l,e,r,g,d,u]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-5 px-6 py-6`,children:[(0,G.jsxs)(`div`,{className:`flex items-start justify-between gap-4`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:e?`Edit MCP source`:`Add MCP source`}),(0,G.jsx)(E,{variant:`secondary`,size:`sm`,onClick:c,children:`Zalo preset`})]}),(0,G.jsx)(J,{id:`mcp-source-name`,label:`Name`,children:(0,G.jsx)(R,{id:`mcp-source-name`,value:a.name,onChange:v,placeholder:`Zalo`,autoFocus:!0})}),(0,G.jsx)(J,{id:`mcp-source-server`,label:`MCP server`,hint:`A stdio server started here is a separate process from the one your chats use — prefer http or sse.`,children:(0,G.jsx)(Dn,{id:`mcp-source-server`,value:a.serverId,options:h,placeholder:`Choose an MCP server`,searchPlaceholder:`Search servers...`,emptyMessage:`Add an MCP server first`,onValueChange:e=>s({serverId:e})})}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(`span`,{className:`block text-sm font-medium text-foreground`,children:`How messages arrive`}),(0,G.jsx)(L,{value:a.mode,onValueChange:e=>s({mode:e}),options:Ji,size:`sm`}),(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:Ti(a.mode)})]}),a.mode===`subscribe`?(0,G.jsx)(Zi,{draft:a,onChange:s}):(0,G.jsx)(Qi,{draft:a,onChange:s}),(0,G.jsxs)(`div`,{className:`grid grid-cols-1 gap-4 sm:grid-cols-2`,children:[(0,G.jsx)(J,{id:`mcp-source-thread-key`,label:`Thread key path`,hint:`Messages with the same value share one Inbox thread.`,children:(0,G.jsx)(R,{id:`mcp-source-thread-key`,className:`font-mono`,value:a.threadKeyPath,onChange:e=>s({threadKeyPath:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-sender`,label:`Sender path`,hint:`Shown as the sender of the thread.`,children:(0,G.jsx)(R,{id:`mcp-source-sender`,className:`font-mono`,value:a.senderPath,onChange:e=>s({senderPath:e.target.value})})})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(`span`,{className:`block text-sm font-medium text-foreground`,children:`Action`}),(0,G.jsx)(L,{value:a.handlerMode,onValueChange:e=>s({handlerMode:e}),options:Yi,size:`sm`}),(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:We(a.handlerMode)})]}),(0,G.jsx)(J,{id:`mcp-source-target`,label:a.handlerMode===`spawn`?`Project`:`Chat`,children:a.handlerMode===`spawn`?(0,G.jsx)(xn,{id:`mcp-source-target`,value:a.projectId,options:p.projects,placeholder:`Choose a project`,searchPlaceholder:`Search projects...`,onValueChange:e=>s({projectId:e})}):(0,G.jsx)(xn,{id:`mcp-source-target`,value:a.chatId,options:p.chats,placeholder:`Choose a chat`,searchPlaceholder:`Search chats...`,onValueChange:e=>s({chatId:e})})}),_?(0,G.jsx)(J,{id:`mcp-source-model`,label:`Model`,hint:`The model the turn started by each message runs with.`,children:(0,G.jsx)(Dn,{id:`mcp-source-model`,value:a.modelValue,options:m,placeholder:`Choose a model`,searchPlaceholder:`Search models...`,onValueChange:e=>s({modelValue:e})})}):null,(0,G.jsx)(J,{id:`mcp-source-template`,label:`Instruction template`,hint:(0,G.jsxs)(G.Fragment,{children:[`Insert fields from the message with `,(0,G.jsx)(`code`,{className:`font-mono`,children:`{{senderName}}`}),`. The message is appended as untrusted data.`]}),children:(0,G.jsx)(ln,{id:`mcp-source-template`,rows:4,value:a.template,onChange:e=>s({template:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-reply-hint`,label:`Reply hint`,hint:`Tells the agent how to send a reply through the server's tools when you answer from the Inbox.`,children:(0,G.jsx)(ln,{id:`mcp-source-reply-hint`,rows:3,value:a.replyHint,onChange:e=>s({replyHint:e.target.value})})}),(0,G.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-3 text-sm`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:a.pushEnabled,onChange:e=>s({pushEnabled:e.target.checked}),className:`h-4 w-4 shrink-0 rounded border-border accent-foreground`}),`Send a push notification for new messages`]}),!g.ok&&a.name.length>0?(0,G.jsx)(`p`,{className:`text-xs text-destructive-text`,children:g.errors[0]}):null,o?(0,G.jsx)(`p`,{className:`text-xs text-destructive-text`,children:o}):null,(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(E,{onClick:y,pending:f,disabled:!g.ok,children:e?`Save changes`:`Add source`}),(0,G.jsx)(E,{variant:`ghost`,onClick:l,disabled:f,children:`Cancel`})]})]})}var ea=e=>({mcpSources:e});function ta({source:e,serverName:t,status:n,now:r,confirmingDelete:i,handlers:a}){let o=qi(e=>e.startEdit),s=qi(e=>e.askDelete),c=qi(e=>e.cancelDelete),l=P(`mcpSources.setEnabled`,e.id),u=P(`mcpSources.delete`,e.id),d=M(l),f=M(u),p=n?.state??(e.enabled?`connecting`:`disabled`),m=pn(n?.lastItemAt??void 0,r),h=(0,W.useCallback)(()=>{A(l,()=>a.onSetEnabled(e.id,!e.enabled))},[l,a,e.enabled,e.id]),g=(0,W.useCallback)(()=>o(e),[e,o]),_=(0,W.useCallback)(()=>s(e.id),[s,e.id]),v=(0,W.useCallback)(()=>{A(u,async()=>{await a.onDelete(e.id),c()})},[c,u,a,e.id]);return(0,G.jsxs)(`li`,{className:`flex flex-wrap items-center gap-x-4 gap-y-2 px-4 py-3`,"aria-busy":d||f||void 0,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-0.5`,children:[(0,G.jsx)(`span`,{className:`truncate text-sm font-medium`,children:e.name}),(0,G.jsxs)(`span`,{className:`truncate text-xs text-muted-foreground`,children:[t,` · `,wi(e.mode)]}),n?.lastError?(0,G.jsx)(`span`,{className:`text-xs text-destructive-text`,children:n.lastError}):null]}),(0,G.jsxs)(`div`,{className:`ml-auto flex flex-wrap items-center gap-3 text-xs text-muted-foreground`,children:[(0,G.jsx)(hn,{tone:Ci(p),label:Si(p)}),(0,G.jsx)(`span`,{className:`tabular-nums`,children:m?`last ${m}`:`no items yet`}),(0,G.jsxs)(`span`,{className:`tabular-nums`,children:[n?.itemCount??0,` items`]}),(0,G.jsx)(E,{variant:`secondary`,size:`sm`,onClick:h,pending:d,children:e.enabled?`Disable`:`Enable`}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:g,"aria-label":`Edit ${e.name}`,children:`Edit`}),i?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(E,{variant:`destructive`,size:`sm`,onClick:v,pending:f,children:[`Delete `,e.name,`?`]}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:c,disabled:f,children:`Keep`})]}):(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:_,"aria-label":`Delete ${e.name}`,children:`Delete`})]})]})}function na({sources:e,statuses:t,servers:n,sidebarData:r,handlers:i}){let a=qi(e=>e.editing),o=qi(e=>e.confirmingDeleteId),s=qi(e=>e.startCreate),c=yn(3e4);if(a.kind!==`list`){let t=a.kind===`edit`?e.find(e=>e.id===a.id)??null:null;return(0,G.jsx)($i,{editing:t,servers:n,sidebarData:r,handlers:i})}return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 px-6 py-6`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:`MCP sources`}),(0,G.jsx)(`p`,{className:`max-w-[65ch] text-sm text-muted-foreground`,children:`Let Kanna listen to an MCP server you already added, such as a Zalo or mail server, and put what arrives into the Inbox. Replies go back out through the same server.`})]}),(0,G.jsxs)(E,{size:`sm`,onClick:s,children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add source`]})]}),e.length===0?(0,G.jsx)(Zr,{icon:An,message:`No MCP sources yet. Add one to bring a server's messages into the Inbox.`}):(0,G.jsx)(Qr,{children:e.map(e=>(0,G.jsx)(ta,{source:e,serverName:n.find(t=>t.id===e.serverId)?.name??`Missing server`,status:t.find(t=>t.id===e.id),now:c,confirmingDelete:o===e.id,handlers:i},e.id))})]})}function ra({state:e}){let t=z(xt),n=z(ft),r=_(e=>e.statuses),i=ri(ea,e),{handleWriteAppSettings:a}=e,o=(0,W.useMemo)(()=>({...i,onSetEnabled:async(e,t)=>{await a({mcpSources:{setEnabled:{id:e,enabled:t}}})}}),[i,a]);return(0,G.jsx)(na,{sources:t,statuses:r,servers:n,sidebarData:e.sidebarData,handlers:o})}var ia=new Set([`checking`,`downloading`,`installing`,`restarting`]);function aa(e){return e!==null&&ia.has(e.state)}function oa(e){switch(e.state){case`checking`:return`Checking ${e.version}…`;case`downloading`:return`Downloading ${e.version}…`;case`installing`:return`Installing ${e.version}…`;case`restarting`:return`Restarting…`;case`current`:return`Up to date`;case`failed`:return e.message===void 0?`Update failed`:`Update failed: ${e.message}`}}function sa(e){switch(e.state){case`failed`:return`destructive`;case`current`:return`muted`;case`checking`:case`downloading`:case`installing`:case`restarting`:return`active`}}var ca={},la={},ua={},da={};function fa(e,t){return`${e}:${t}`}function pa(e,t,n){let r=Object.fromEntries(Object.entries(e).filter(([e])=>e!==t));return Object.keys(r).length>0?r:n}var Y=w()(e=>({pairing:null,expandedId:null,drafts:ca,updateErrors:la,aliasErrors:ua,openExplanations:da,setPairing:t=>e({pairing:t}),toggleExpanded:t=>e(e=>({expandedId:e.expandedId===t?null:t})),setDraft:(t,n)=>e(e=>({drafts:{...e.drafts,[t]:n}})),clearDraft:t=>e(e=>({drafts:pa(e.drafts,t,ca)})),setUpdateError:(t,n)=>e(e=>n===null?{updateErrors:pa(e.updateErrors,t,la)}:{updateErrors:{...e.updateErrors,[t]:n}}),beginAliasEdit:(t,n)=>e(e=>({drafts:{...e.drafts,[fa(t,`alias`)]:n}})),endAliasEdit:t=>e(e=>({drafts:pa(e.drafts,fa(t,`alias`),ca),aliasErrors:pa(e.aliasErrors,t,ua)})),setAliasError:(t,n)=>e(e=>n===null?{aliasErrors:pa(e.aliasErrors,t,ua)}:{aliasErrors:{...e.aliasErrors,[t]:n}}),toggleExplanation:t=>e(e=>({openExplanations:t in e.openExplanations?pa(e.openExplanations,t,da):{...e.openExplanations,[t]:!0}}))})),ma=`kanna-beacon`,ha=`ABCDEFGHJKLMNPQRSTUVWXYZ23456789`,ga=`https://github.com/cuongtranba/kanna/releases/latest`;RegExp(`^[${ha}]{8}$`);function _a(e){return`${ma}://pair?url=${encodeURIComponent(e.kannaUrl)}&code=${encodeURIComponent(e.code)}`}function va(e){return e.replace(/^v/,``).split(`-`)[0].split(`.`).map(e=>Number.parseInt(e,10))}function ya(e,t){if(e===t)return!1;let n=va(e),r=va(t),i=Math.max(n.length,r.length);for(let a=0;a<i;a+=1){let i=n[a]??0,o=r[a]??0;if(Number.isNaN(i)||Number.isNaN(o))return e<t;if(i!==o)return i<o}return!1}var ba={outdated:`border-warning/40 text-warning-text bg-warning/10`,partial:`border-warning/40 text-warning-text bg-warning/10`,unknown:`border-border text-muted-foreground bg-muted/40`};function xa({beaconId:e,alias:t,displayName:n}){let r=Y(e=>e.beginAliasEdit),i=(0,W.useCallback)(()=>{r(e,t??``)},[t,e,r]);return(0,G.jsx)(on,{label:`Set a short name`,children:(0,G.jsx)(E,{variant:`ghost`,size:`icon-sm`,onClick:i,"aria-label":`Set a short name for ${n}`,children:(0,G.jsx)(Le,{className:`h-3.5 w-3.5`})})})}function Sa({beaconId:e,alias:t,displayName:n,onSetAlias:r}){let i=fa(e,`alias`),a=Y(e=>e.drafts[i]),o=Y(t=>t.aliasErrors[e]??null),s=Y(e=>e.setDraft),c=Y(e=>e.setAliasError),l=Y(e=>e.endAliasEdit),u=P(`beacons.setAlias`,e),d=M(u),f=a??``,p=f.length===0?null:ve(f),m=f.length>0&&p===null&&f!==t,h=p??o,g=(0,W.useCallback)(t=>{s(i,t.target.value.toLowerCase()),c(e,null)},[e,i,c,s]),_=(0,W.useCallback)(t=>{A(u,async()=>{try{await r(e,t),l(e)}catch(t){c(e,T(t))}})},[e,l,r,u,c]),v=(0,W.useCallback)(()=>{_(f)},[_,f]),y=(0,W.useCallback)(()=>{_(null)},[_]),b=(0,W.useCallback)(()=>{l(e)},[e,l]);return a===void 0?null:(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,G.jsx)(R,{value:f,onChange:g,placeholder:`office-mac`,disabled:d,"aria-label":`Short name for ${n}`,"aria-invalid":h!==null||void 0,className:`w-48`}),(0,G.jsx)(E,{size:`sm`,onClick:v,pending:d,disabled:!m,children:`Save`}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:b,disabled:d,children:`Cancel`}),t!==null&&(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:y,disabled:d,children:`Clear alias`})]}),(0,G.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Type `,(0,G.jsxs)(`span`,{className:`font-mono`,children:[`@beacon/`,f.length>0?f:`name`]}),` in a message to refer to this machine.`]}),h!==null&&(0,G.jsx)(`p`,{role:`alert`,className:`text-xs text-destructive-text`,children:h})]})}var Ca=`Lets the agent run commands and scripts on this machine. Off means every command and script is refused, and the agent can only read and copy files inside the folders below. When on, each command still waits for your approval unless it is on the always-run list or you switch on running without asking.`,wa=`Skips the approval prompt. Reads and writes inside the folders below, and every command and script, run immediately. Leave it off to review each action before it runs on this machine.`,Ta=`The agent can list, search, read and copy files off this machine only inside these folders and their subfolders. Anything outside is refused. With none listed it cannot read from this machine at all. Each read waits for your approval unless running without asking is on.`,Ea=`The agent can copy files onto this machine only inside these folders and their subfolders. Leave empty and it cannot write to this machine at all. Each write waits for your approval unless running without asking is on.`,Da=`Command names, such as git, that run immediately once running commands is allowed. Matching uses the command name only, so git covers every git subcommand. Anything not listed asks you first.`;function Oa(e){return`beacon-explain-${e}`}function ka({explanationKey:e,subject:t}){let n=Y(t=>e in t.openExplanations),r=Y(e=>e.toggleExplanation),i=(0,W.useCallback)(()=>{r(e)},[e,r]);return(0,G.jsx)(on,{label:`What does this do?`,children:(0,G.jsx)(E,{variant:`ghost`,size:`icon-sm`,onClick:i,"aria-expanded":n,"aria-controls":Oa(e),"aria-label":`What does "${t}" do?`,children:(0,G.jsx)(Fe,{className:`h-4 w-4`})})})}function Aa({explanationKey:e,text:t}){let n=Y(t=>e in t.openExplanations);return(0,G.jsx)(`p`,{id:Oa(e),hidden:!n,className:`text-13 text-muted-foreground`,children:t})}function ja({beaconId:e,scope:t,onSetScope:n}){let r=P(`beacons.setScope`,e),i=M(r),a=(0,W.useCallback)(t=>{A(r,()=>n(e,t))},[e,n,r]),o=(0,W.useCallback)(e=>{a({...t,exec:e.target.checked})},[a,t]),s=(0,W.useCallback)(e=>{a({...t,autoRunScripts:e.target.checked})},[a,t]),c=(0,W.useCallback)(e=>{a({...t,readRoots:e})},[a,t]),l=(0,W.useCallback)(e=>{a({...t,writeRoots:e})},[a,t]),u=(0,W.useCallback)(e=>{a({...t,execAllowlist:e})},[a,t]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 border-t border-border bg-muted/40 px-4 py-4`,"aria-busy":i||void 0,children:[(0,G.jsx)(Ma,{explanationKey:fa(e,`exec`),checked:t.exec,disabled:i,onChange:o,title:`Allow running commands`,explanation:Ca}),(0,G.jsx)(Ma,{explanationKey:fa(e,`autoRunScripts`),checked:t.autoRunScripts,disabled:i,onChange:s,title:`Run commands and scripts from this chat without asking each time`,explanation:wa}),(0,G.jsx)(Na,{label:`Folders the agent may read`,explanation:Ta,placeholder:`/Users/me/projects`,draftKey:fa(e,`readRoots`),items:t.readRoots,disabled:i,onChange:c}),(0,G.jsx)(Na,{label:`Folders the agent may write to`,explanation:Ea,placeholder:`/Users/me/inbox`,draftKey:fa(e,`writeRoots`),items:t.writeRoots,disabled:i,onChange:l}),(0,G.jsx)(Na,{label:`Commands that always run without asking`,explanation:Da,placeholder:`git`,draftKey:fa(e,`execAllowlist`),items:t.execAllowlist,disabled:i,onChange:u})]})}function Ma({explanationKey:e,checked:t,disabled:n,onChange:r,title:i,explanation:a}){return(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,G.jsxs)(`label`,{className:`flex min-w-0 cursor-pointer items-center gap-3`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:t,disabled:n,onChange:r}),(0,G.jsx)(`span`,{className:`text-sm font-medium text-foreground`,children:i})]}),(0,G.jsx)(ka,{explanationKey:e,subject:i})]}),(0,G.jsx)(`div`,{className:`pl-7`,children:(0,G.jsx)(Aa,{explanationKey:e,text:a})})]})}function Na({label:e,explanation:t,placeholder:n,draftKey:r,items:i,disabled:a,onChange:o}){let s=Y(e=>e.drafts[r]??``),c=Y(e=>e.setDraft),l=Y(e=>e.clearDraft),u=s.trim(),d=u.length>0&&!i.includes(u),f=(0,W.useCallback)(e=>{c(r,e.target.value)},[r,c]),p=(0,W.useCallback)(()=>{o([...i,u]),l(r)},[l,r,i,o,u]),m=(0,W.useCallback)(e=>{o(i.filter(t=>t!==e))},[i,o]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium text-foreground`,children:e}),(0,G.jsx)(ka,{explanationKey:r,subject:e})]}),(0,G.jsx)(Aa,{explanationKey:r,text:t}),i.length===0?(0,G.jsx)(`span`,{className:`text-13 text-muted-foreground`,children:`None`}):(0,G.jsx)(`ul`,{className:`flex flex-col gap-1`,children:i.map(e=>(0,G.jsx)(Pa,{item:e,disabled:a,onRemove:m},e))}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(R,{value:s,onChange:f,placeholder:n,disabled:a,"aria-label":e}),(0,G.jsx)(E,{variant:`secondary`,size:`sm`,onClick:p,disabled:a||!d,children:`Add`})]})]})}function Pa({item:e,disabled:t,onRemove:n}){let r=(0,W.useCallback)(()=>{n(e)},[e,n]);return(0,G.jsxs)(`li`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`code`,{className:`min-w-0 flex-1 break-all rounded-md border border-border bg-muted px-2 py-1 font-mono text-13`,children:e}),(0,G.jsx)(E,{variant:`ghost`,size:`icon-sm`,onClick:r,disabled:t,"aria-label":`Remove ${e}`,children:(0,G.jsx)(qe,{className:`h-4 w-4`})})]})}var Fa=ae.split(`/`)[1],Ia=P(`beacons.mintPairingCode`);function La(e,t){let n=new Map(e.map(e=>[e.id,e]));return t.map(e=>{let t=n.get(e.id);return{id:e.id,label:e.label,alias:e.alias??null,os:e.os,enabled:e.enabled,online:t?.online??!1,lastSeenAt:t?.lastSeenAt??null,beaconVersion:t?.beaconVersion??null,canSelfUpdate:t?.canSelfUpdate??!1,update:t?.update??null}})}function Ra({rows:e,configs:t,handlers:n,serverVersion:r,dom:i=oe,clipboard:a=De,timer:o=Qe}){let s=yn(1e3),c=(0,W.useMemo)(()=>La(e,t),[e,t]),l=(0,W.useMemo)(()=>new Map(t.map(e=>[e.id,e])),[t]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 px-6 py-6`,children:[(0,G.jsx)(za,{now:s,handlers:n,dom:i,clipboard:a,timer:o}),c.length===0?(0,G.jsx)(Zr,{icon:pe,message:`No machines paired yet. Pair a machine to let the agent read files and run approved commands there.`}):(0,G.jsx)(Qr,{children:c.map(e=>(0,G.jsx)(Ga,{row:e,scope:l.get(e.id)?.scope??null,now:s,serverVersion:r,handlers:n,dom:i},e.id))})]})}function za({now:e,handlers:t,dom:n,clipboard:r,timer:i}){let a=Y(e=>e.pairing),o=Y(e=>e.setPairing),s=M(Ia),c=(0,W.useCallback)(()=>{A(Ia,async()=>{o(await t.onMint())})},[t,o]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-lg border border-border bg-card p-4`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:`Beacons`}),(0,G.jsx)(`p`,{className:`mt-1 text-13 text-muted-foreground`,children:`A beacon is a small program on your own machine. Once paired, the agent can read files and run commands there, only within the scope you grant below.`})]}),(0,G.jsxs)(E,{size:`sm`,variant:a?.ok===!0?`secondary`:`default`,onClick:c,pending:s,children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Pair a machine`]})]}),a?.ok===!1&&(0,G.jsx)(`p`,{role:`alert`,className:`text-sm text-destructive-text`,children:a.error}),a?.ok===!0&&(0,G.jsx)(Ba,{code:a.code,expiresAt:a.expiresAt,now:e,dom:n,clipboard:r,timer:i})]})}function Ba({code:e,expiresAt:t,now:n,dom:r,clipboard:i,timer:a}){let o=t-n,s=r.getOrigin(),c=`kanna-beacon pair ${s} ${e}`,l=_a({kannaUrl:s,code:e}),u=P(`beacons.copyPairCommand`,e),d=M(u),f=ye(u),p=(0,W.useCallback)(()=>{A(u,()=>be(u,()=>i.writeText(c),a))},[i,c,u,a]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-2 border-t border-border pt-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-baseline gap-3`,children:[(0,G.jsx)(`span`,{className:`font-mono text-2xl font-medium tabular-nums tracking-widest`,children:e}),(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground tabular-nums`,children:o>0?`Expires in ${V(o)}`:`Expired. Pair again for a new code.`})]}),(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-2`,children:[(0,G.jsxs)(`a`,{href:l,className:j({size:`sm`}),children:[(0,G.jsx)(Pe,{className:`mr-1 h-4 w-4`}),`Open in Kanna Beacon`]}),(0,G.jsx)(`a`,{href:ga,target:`_blank`,rel:`noreferrer`,className:`text-13 text-muted-foreground underline underline-offset-2 hover:text-foreground`,children:`Download Kanna Beacon`})]}),(0,G.jsx)(`p`,{className:`text-13 text-muted-foreground`,children:`Or run this on the machine you want to pair:`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`code`,{className:`min-w-0 flex-1 break-all rounded-md border border-border bg-muted px-3 py-2 font-mono text-13`,children:c}),(0,G.jsx)(on,{label:f?`Copied`:`Copy command`,children:(0,G.jsx)(E,{variant:`ghost`,size:`icon`,onClick:p,pending:d,"aria-label":f?`Copied`:`Copy pairing command`,children:f?(0,G.jsx)(Ee,{className:`h-4 w-4 text-success-text`}):(0,G.jsx)(Te,{className:`h-4 w-4`})})})]})]})}function Va(e,t){return e.lastSeenAt===null?`Never connected`:`Last seen ${mn(t-e.lastSeenAt)} ago`}var Ha=`This beacon is too old to update itself. Reinstall it once from the download page; after that, updates are one click.`;function Ua({canSelfUpdate:e}){let t=D(`rounded-full border px-2 py-0.5 text-xs`,ba.outdated);return e?(0,G.jsx)(`span`,{className:t,children:`Update available`}):(0,G.jsx)(on,{label:Ha,children:(0,G.jsx)(`a`,{href:ga,target:`_blank`,rel:`noreferrer`,className:t,children:`Update available`})})}function Wa({row:e,updateAvailable:t,handlers:n}){let r=P(`beacons.update`,e.id),i=M(r),a=Y(t=>t.updateErrors[e.id]??null),o=Y(e=>e.setUpdateError),s=t&&e.online&&e.canSelfUpdate&&!aa(e.update),c=(0,W.useCallback)(()=>{A(r,async()=>{let t=await n.onUpdate(e.id);o(e.id,t.ok?null:t.error)})},[n,e.id,o,r]);return(0,G.jsxs)(G.Fragment,{children:[e.update!==null&&(0,G.jsx)(hn,{tone:sa(e.update),label:oa(e.update)}),s&&(0,G.jsxs)(E,{variant:`secondary`,size:`sm`,onClick:c,pending:i,"aria-label":`Update ${me(e)} now`,children:[(0,G.jsx)(Pn,{className:`mr-1 h-4 w-4`}),`Update now`]}),a!==null&&(0,G.jsx)(`span`,{role:`alert`,className:`text-destructive-text`,children:a})]})}function Ga({row:e,scope:t,now:n,serverVersion:r,handlers:i,dom:a}){let o=Y(t=>t.expandedId===e.id),s=Y(e=>e.toggleExpanded),c=P(`beacons.setEnabled`,e.id),l=M(c),u=P(`beacons.delete`,e.id),d=M(u),f=me(e),p=e.beaconVersion!==null&&r!==void 0&&ya(e.beaconVersion,r),m=(0,W.useCallback)(t=>{let n=t.target.checked;A(c,()=>i.onSetEnabled(e.id,n))},[c,i,e.id]),h=(0,W.useCallback)(()=>{a.confirmDialog(`Revoke "${f}"? The agent will lose access to this machine until you pair it again.`)&&A(u,()=>i.onDelete(e.id))},[u,f,a,i,e.id]),g=(0,W.useCallback)(()=>{s(e.id)},[e.id,s]);return(0,G.jsxs)(`li`,{className:`flex flex-col`,"aria-busy":d||void 0,children:[(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 px-4 py-3`,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-1`,children:[(0,G.jsxs)(`span`,{className:`flex min-w-0 items-center gap-1`,children:[(0,G.jsx)(`span`,{className:`truncate font-medium`,children:f}),(0,G.jsx)(xa,{beaconId:e.id,alias:e.alias,displayName:f})]}),e.alias!==null&&(0,G.jsxs)(`span`,{className:`flex flex-wrap items-center gap-x-3 text-xs text-muted-foreground`,children:[(0,G.jsx)(`span`,{className:`font-mono`,children:e.label}),(0,G.jsxs)(`span`,{className:`font-mono`,children:[`@beacon/`,e.alias]})]}),(0,G.jsx)(Sa,{beaconId:e.id,alias:e.alias,displayName:f,onSetAlias:i.onSetAlias}),(0,G.jsxs)(`span`,{className:`flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground`,children:[(0,G.jsx)(hn,{tone:e.online?`active`:`muted`,label:e.online?`Online`:`Offline`}),(0,G.jsx)(`span`,{className:`tabular-nums`,children:Va(e,n)}),e.beaconVersion!==null&&(0,G.jsxs)(`span`,{className:`font-mono tabular-nums`,children:[`v`,e.beaconVersion]}),p&&(0,G.jsx)(Ua,{canSelfUpdate:e.canSelfUpdate}),(0,G.jsx)(Wa,{row:e,updateAvailable:p,handlers:i}),(0,G.jsx)(`span`,{children:e.os})]})]}),(0,G.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,G.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-1 text-xs text-muted-foreground`,children:[l?(0,G.jsx)(N,{}):null,(0,G.jsx)(`input`,{type:`checkbox`,checked:e.enabled,disabled:l,"aria-busy":l||void 0,onChange:m,"aria-label":`Enable ${f}`}),(0,G.jsx)(`span`,{children:e.enabled?`Enabled`:`Disabled`})]}),t!==null&&(0,G.jsxs)(E,{variant:`ghost`,size:`sm`,onClick:g,"aria-expanded":o,children:[`Scope`,(0,G.jsx)(Oe,{className:D(`ml-1 h-4 w-4 transition-transform`,o&&`rotate-180`)})]}),(0,G.jsx)(on,{label:`Revoke this machine`,children:(0,G.jsx)(E,{variant:`ghost`,size:`icon`,onClick:h,pending:d,"aria-label":`Revoke ${f}`,children:(0,G.jsx)(He,{className:`h-4 w-4`})})})]})]}),o&&t!==null&&(0,G.jsx)(ja,{beaconId:e.id,scope:t,onSetScope:i.onSetScope})]})}function Ka(e){let t=d(y),n=z(vt),{handleWriteAppSettings:r,handleMintBeaconPairingCode:i,handleUpdateBeacon:a}=e.state,o=(0,W.useMemo)(()=>({onMint:i,onSetEnabled:async(e,t)=>{await r({customBeacons:{setEnabled:{id:e,enabled:t}}})},onSetScope:async(e,t)=>{await r({customBeacons:{setScope:{id:e,scope:t}}})},onSetAlias:async(e,t)=>{await r({customBeacons:{update:{id:e,patch:{alias:t}}}})},onDelete:async e=>{await r({customBeacons:{delete:{id:e}}})},onUpdate:a}),[r,i,a]);return(0,G.jsx)(Ra,{rows:t,configs:n,handlers:o,serverVersion:Fa})}var qa={id:``,label:``,modelProvider:`claude`,supportedEfforts:[],offersOneMillionContext:!1};function Ja(e){return{...e,submitting:!1,error:null}}var Ya=w()(e=>({editing:{kind:`list`},editorForm:Ja(qa),setEditing:t=>e({editing:t}),resetEditorForm:t=>e({editorForm:Ja(t)}),patchEditorForm:t=>e(e=>({editorForm:{...e.editorForm,...t}})),toggleSupportedEffort:t=>e(e=>{let n=e.editorForm.supportedEfforts,r=n.includes(t)?n.filter(e=>e!==t):[...n,t];return{editorForm:{...e.editorForm,supportedEfforts:r}}}),toggleOneMillionContext:()=>e(e=>({editorForm:{...e.editorForm,offersOneMillionContext:!e.editorForm.offersOneMillionContext}}))})),Xa=e=>({customModels:e}),Za=new Set([`claude`,`codex`]);function Qa(e){return Za.has(e)}var $a={claude:`Claude`,codex:`Codex`};function eo({models:e,handlers:t,dom:n=oe}){let r=Ya(e=>e.editing),i=Ya(e=>e.setEditing),a=Ya(e=>e.resetEditorForm);function o(t){if(t.kind===`create`)a({id:``,label:``,modelProvider:t.provider,supportedEfforts:[],offersOneMillionContext:!1});else if(t.kind===`edit`){let n=e.find(e=>e.id===t.id)??null;n&&a({id:n.id,label:n.label,modelProvider:n.provider,supportedEfforts:n.supportedEfforts??[],offersOneMillionContext:en(n.provider,n.id,n.contextWindowOptions).some(e=>e.id===`1m`)})}i(t)}if(r.kind!==`list`){let n=r.kind===`edit`?e.find(e=>e.id===r.id)??null:null;return(0,G.jsx)(no,{initial:n,existing:e.map(e=>({id:e.id,provider:e.provider})),handlers:t,onDone:()=>i({kind:`list`})})}return(0,G.jsx)(`div`,{className:`flex flex-col gap-6 px-6 py-6`,children:[`claude`,`codex`].map(r=>{let i=e.filter(e=>e.provider===r);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsxs)(`h2`,{className:`text-base font-medium`,children:[$a[r],` models`]}),(0,G.jsxs)(E,{size:`sm`,onClick:()=>o({kind:`create`,provider:r}),children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add model`]})]}),i.length===0?(0,G.jsx)(Zr,{icon:Bn,message:`No ${$a[r]} models configured.`}):(0,G.jsx)(Qr,{children:i.map(e=>(0,G.jsx)(to,{model:e,onEdit:()=>o({kind:`edit`,id:e.id}),onDelete:t.onDelete,dom:n},e.id))})]},r)})})}function to({model:e,onEdit:t,onDelete:n,dom:r}){let i=P(`models.delete`,e.provider,e.id),a=M(i),o=(0,W.useCallback)(()=>{r.confirmDialog(`Delete model "${e.label}"?`)&&A(i,()=>n(e.id))},[i,r,e.id,e.label,n]);return(0,G.jsxs)(`li`,{className:`flex items-center gap-3 px-4 py-3`,"aria-busy":a||void 0,children:[(0,G.jsxs)(`div`,{className:`flex flex-col`,children:[(0,G.jsx)(`span`,{className:`font-medium`,children:e.label}),(0,G.jsx)(`span`,{className:`font-mono text-xs text-muted-foreground`,children:e.id})]}),(0,G.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(e.supportedEfforts?.length??0)>0&&(0,G.jsx)(`span`,{className:`rounded bg-muted px-1.5 py-0.5 text-xs`,children:`effort`}),e.supportedEfforts?.includes(`max`)&&(0,G.jsx)(`span`,{className:`rounded bg-muted px-1.5 py-0.5 text-xs`,children:`max`}),(0,G.jsx)($r,{label:e.label,onEdit:t,onDelete:o,deletePending:a})]})]})}function no({initial:e,existing:t,handlers:n,onDone:r}){let i=Ya(e=>e.editorForm),a=Ya(e=>e.patchEditorForm),o=Ya(e=>e.toggleSupportedEffort),s=Ya(e=>e.toggleOneMillionContext),c=(0,W.useCallback)(e=>{Qa(e)&&a({modelProvider:e})},[a]),{id:l,label:u,modelProvider:d,supportedEfforts:f,offersOneMillionContext:p,submitting:m,error:h}=i,g=p?Gt:Gt.filter(e=>e.id===`200k`),_=e!==null,v=(0,W.useMemo)(()=>!_&&t.some(e=>e.id===l.trim()&&e.provider===d),[t,l,_,d]),y=l.trim().length>0&&u.trim().length>0&&!v&&!m,b=()=>ii({patch:a,save:async()=>{_&&e?await n.onUpdate(e.id,{label:u.trim(),supportedEfforts:f.length>0?f:null,...d===`claude`?{contextWindowOptions:g}:{}}):await n.onCreate({id:l.trim(),label:u.trim(),provider:d,...f.length>0?{supportedEfforts:f}:{},...d===`claude`?{contextWindowOptions:g}:{}})},onDone:r,fallbackMessage:`Failed to save model`}),x=ai({submitting:m,isEdit:_,addLabel:`Add model`});return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 px-6 py-6`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:_?`Edit model`:`Add model`}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Provider`}),(0,G.jsxs)(Ne,{value:d,onValueChange:c,disabled:_,children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsxs)(Ae,{children:[(0,G.jsx)(F,{value:`claude`,children:`Claude`}),(0,G.jsx)(F,{value:`codex`,children:`Codex`})]})]})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Model ID`}),(0,G.jsx)(R,{value:l,onChange:e=>a({id:e.target.value}),placeholder:`claude-opus-4-9`,disabled:_,className:`font-mono`}),v&&(0,G.jsx)(`span`,{className:`text-xs text-red-600`,children:`A model with this id already exists.`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Label`}),(0,G.jsx)(R,{value:u,onChange:e=>a({label:e.target.value}),placeholder:`Opus 4.9`})]}),d===`claude`&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Supported effort levels`}),Ht.map(e=>(0,G.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-2 text-sm`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:f.includes(e.id),onChange:()=>o(e.id)}),(0,G.jsx)(`span`,{children:e.label})]},e.id))]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Context window`}),(0,G.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-2 text-sm`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:p,onChange:s}),(0,G.jsx)(`span`,{children:`Offer the 1M context window`})]}),(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Off means every turn on this model runs on the 200k window.`})]})]}),h&&(0,G.jsx)(`span`,{className:`text-xs text-red-600`,children:h}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(E,{onClick:()=>{A(P(`models.save`,e?.id??`new`),b)},pending:m,disabled:!y,children:x}),(0,G.jsx)(E,{variant:`ghost`,onClick:r,disabled:m,children:`Cancel`})]})]})}function ro(e){let t=z(ot),n=ri(Xa,e.state);return(0,G.jsx)(eo,{models:t,handlers:n})}var io=32,ao=`-`;function oo(){return{id:``,idTouched:!1,label:``,baseUrl:``,apiKey:``,models:[so()],contextWindow:``,hint:null}}function so(){return{id:``,label:``}}function co(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^[^a-z]+/,``).replace(/-+$/,``).slice(0,io).replace(/-+$/,``)}function lo(e,t){if(e.length===0||!t.includes(e))return e;for(let n=2;;n+=1){let r=`-${n}`,i=`${e.slice(0,io-r.length)}${r}`;if(!t.includes(i))return i}}function uo(e,t){return{id:lo(e.id,t),idTouched:!0,label:e.label,baseUrl:e.baseUrl,apiKey:e.defaultApiKey??``,models:e.models.length>0?e.models.map(e=>({...e})):[so()],contextWindow:e.contextWindow===void 0?``:String(e.contextWindow),hint:e.hint??null}}function fo(e){return{id:e.id,idTouched:!0,label:e.label,baseUrl:e.baseUrl,apiKey:``,models:e.models.map(e=>({...e})),contextWindow:e.contextWindow===void 0?``:String(e.contextWindow),hint:null}}function po(e,t){return lo(co(e),t)}function mo(e){return e.map(e=>({id:e.id.trim(),label:e.label.trim()})).filter(e=>e.id.length>0||e.label.length>0)}function ho(e){let t=e.replace(/[\s,_]/g,``);return t.length===0?void 0:Number(t)}function go(e){let t=ho(e.contextWindow);return{id:e.id.trim(),label:e.label.trim(),baseUrl:e.baseUrl.trim(),apiKey:e.apiKey.trim(),models:mo(e.models),...t===void 0?{}:{contextWindow:t}}}function _o(e){let t=e.apiKey.trim();return{label:e.label.trim(),baseUrl:e.baseUrl.trim(),models:mo(e.models),contextWindow:ho(e.contextWindow)??null,...t.length>0?{apiKey:t}:{}}}function vo(e,t,n){let r=go(e),i=Ue({...r,apiKey:t===`edit`&&r.apiKey.length===0?ao:r.apiKey},n);return i===null?null:i.code===`INVALID_ID`?`Id must be lowercase letters, digits or dashes, start with a letter, and be at most ${io} characters (${Ge}).`:i.message}function yo(e){return`${e<1e6&&e%1024==0?`${e/1024}k`:kt(e)} context`}function bo(e){return e===null?`Key set`:`Key ••••${e}`}function xo(e,t){return e===`create`?`API key`:t===null?`Leave blank to keep the saved key`:`Leave blank to keep ••••${t}`}function So(e){return{...e,submitting:!1,error:null}}var X=w()(e=>({editing:{kind:`list`},menuOpen:!1,listError:null,editorForm:So(oo()),setMenuOpen:t=>e({menuOpen:t}),setListError:t=>e({listError:t}),startEditing:(t,n)=>e({editing:t,menuOpen:!1,listError:null,editorForm:So(n)}),discardEditor:()=>e({editing:{kind:`list`},menuOpen:!1,editorForm:So(oo())}),patchEditorForm:t=>e(e=>({editorForm:{...e.editorForm,...t}})),setLabel:(t,n)=>e(e=>({editorForm:{...e.editorForm,label:t,id:e.editorForm.idTouched?e.editorForm.id:po(t,n)}})),setId:t=>e(e=>({editorForm:{...e.editorForm,id:t.toLowerCase(),idTouched:!0}})),setModelField:(t,n,r)=>e(e=>({editorForm:{...e.editorForm,models:e.editorForm.models.map((e,i)=>i===t?{...e,[n]:r}:e)}})),addModelRow:()=>e(e=>({editorForm:{...e.editorForm,models:[...e.editorForm.models,{id:``,label:``}]}})),removeModelRow:t=>e(e=>({editorForm:{...e.editorForm,models:e.editorForm.models.filter((e,n)=>n!==t)}}))})),Co=[{id:`glm`,label:`GLM (Z.AI)`,baseUrl:`https://api.z.ai/api/anthropic`,models:[{id:`glm-5.3`,label:`GLM-5.3`},{id:`glm-5.3-flash`,label:`GLM-5.3 Flash`}]},{id:`qwen`,label:`Qwen (Alibaba Model Studio)`,baseUrl:`https://coding-intl.dashscope.aliyuncs.com/apps/anthropic`,models:[{id:`qwen3.7-plus`,label:`Qwen3.7 Plus`},{id:`qwen3.7-max`,label:`Qwen3.7 Max`}],hint:`Coding Plan endpoint. Pay-as-you-go uses https://{WorkspaceId}.<region>.maas.aliyuncs.com/apps/anthropic.`},{id:`kimi`,label:`Kimi (Moonshot)`,baseUrl:`https://api.moonshot.ai/anthropic`,models:[{id:`kimi-k3`,label:`Kimi K3`},{id:`kimi-k2.7-code`,label:`Kimi K2.7 Code`}]},{id:`deepseek`,label:`DeepSeek`,baseUrl:`https://api.deepseek.com/anthropic`,models:[{id:`deepseek-v4-pro`,label:`DeepSeek V4 Pro`},{id:`deepseek-flash`,label:`DeepSeek Flash`}]},{id:`minimax`,label:`MiniMax`,baseUrl:`https://api.minimax.io/anthropic`,models:[{id:`MiniMax-M3.1`,label:`MiniMax M3.1`}],hint:`Mainland China: https://api.minimaxi.com/anthropic`},{id:`ollama`,label:`Ollama (local)`,baseUrl:`http://localhost:11434`,models:[],contextWindow:65536,defaultApiKey:`ollama`,hint:"Runs on this machine. Ollama ignores the API key, so any value works. Add the exact model names from `ollama list`, and set Context window to your OLLAMA_CONTEXT_LENGTH."}],wo=e=>({customProviders:e}),To=`Anthropic-compatible endpoints such as GLM, Qwen, Kimi, DeepSeek or MiniMax. They run through the Claude agent, so tools, skills and MCP work as usual. Pick them in the chat composer under Custom endpoints.`;function Eo(e){return`${e} ${e===1?`model`:`models`}`}function Do({providers:e,handlers:t,dom:n=oe}){let r=X(e=>e.editing),i=X(e=>e.discardEditor);return(0,W.useEffect)(()=>{i()},[i]),(0,G.jsxs)(`div`,{className:`border-t border-border pb-5`,children:[(0,G.jsx)(q,{title:`Custom endpoints`,description:To,bordered:!1,alignStart:!0,children:r.kind===`list`?(0,G.jsx)(Oo,{providers:e}):null}),r.kind===`list`?(0,G.jsx)(ko,{providers:e,onDelete:t.onDelete,dom:n}):(0,G.jsx)(jo,{providers:e,editingId:r.kind===`edit`?r.id:null,handlers:t})]})}function Oo({providers:e}){let t=X(e=>e.menuOpen),n=X(e=>e.setMenuOpen),r=X(e=>e.startEditing),i=(0,W.useMemo)(()=>e.map(e=>e.id),[e]),a=(0,W.useCallback)(e=>{r({kind:`create`},uo(e,i))},[r,i]),o=(0,W.useCallback)(()=>{r({kind:`create`},oo())},[r]);return(0,G.jsxs)(vn,{open:t,onOpenChange:n,children:[(0,G.jsx)(_n,{asChild:!0,children:(0,G.jsxs)(E,{size:`sm`,children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add endpoint`]})}),(0,G.jsx)(gn,{align:`end`,className:`w-64 p-1`,children:(0,G.jsxs)(`div`,{className:`space-y-1`,children:[Co.map(e=>(0,G.jsx)(he,{onClick:()=>a(e),selected:!1,icon:(0,G.jsx)(Se,{className:`h-4 w-4 text-muted-foreground`}),label:e.label},e.id)),(0,G.jsx)(he,{onClick:o,selected:!1,icon:(0,G.jsx)(Re,{className:`h-4 w-4 text-muted-foreground`}),label:`Custom…`,description:`Any Anthropic-compatible URL`})]})})]})}function ko({providers:e,onDelete:t,dom:n}){let r=X(e=>e.listError);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[r?(0,G.jsx)(`div`,{role:`alert`,className:`rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm text-destructive`,children:r}):null,e.length===0?(0,G.jsx)(Zr,{icon:Se,message:`No custom endpoints yet.`}):(0,G.jsx)(Qr,{children:e.map(e=>(0,G.jsx)(Ao,{provider:e,onDelete:t,dom:n},e.id))})]})}function Ao({provider:e,onDelete:t,dom:n}){let r=X(e=>e.startEditing),i=X(e=>e.setListError),a=P(`settings.customProviders.delete`,e.id),o=M(a),s=(0,W.useCallback)(()=>{r({kind:`edit`,id:e.id},fo(e))},[e,r]),c=(0,W.useCallback)(()=>{n.confirmDialog(`Delete endpoint "${e.label}"?`)&&A(a,async()=>{i(null);try{await t(e.id)}catch(e){i(T(e))}})},[a,n,t,e.id,e.label,i]);return(0,G.jsxs)(`li`,{className:`flex items-center gap-3 px-4 py-3`,"aria-busy":o||void 0,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-0.5`,children:[(0,G.jsx)(`span`,{className:`truncate font-medium`,children:e.label}),(0,G.jsx)(rn,{tooltip:e.baseUrl,className:`font-mono text-xs text-muted-foreground`,children:e.baseUrl})]}),(0,G.jsxs)(`div`,{className:`flex shrink-0 flex-col items-end gap-0.5 text-xs text-muted-foreground`,children:[(0,G.jsx)(`span`,{className:`tabular-nums`,children:Eo(e.models.length)}),e.contextWindow===void 0?null:(0,G.jsx)(`span`,{className:`tabular-nums`,children:yo(e.contextWindow)}),(0,G.jsx)(`span`,{children:bo(e.apiKeyHint)})]}),(0,G.jsx)(`div`,{className:`flex shrink-0 items-center gap-1`,children:(0,G.jsx)($r,{label:e.label,onEdit:s,onDelete:c,deletePending:o})})]})}function jo({providers:e,editingId:t,handlers:n}){let r=X(e=>e.editorForm),i=X(e=>e.patchEditorForm),a=X(e=>e.setLabel),o=X(e=>e.setId),s=X(e=>e.setModelField),c=X(e=>e.addModelRow),l=X(e=>e.removeModelRow),u=X(e=>e.discardEditor),d=t!==null,f=d?`edit`:`create`,p=(0,W.useMemo)(()=>e.find(e=>e.id===t)??null,[e,t]),m=(0,W.useMemo)(()=>e.filter(e=>e.id!==t).map(e=>e.id),[e,t]),h=P(`settings.customProviders`,t??(r.id||`new`)),g=M(h),_=(0,W.useCallback)(e=>{a(e,m)},[m,a]),v=(0,W.useCallback)(()=>{let e=vo(r,f,m);if(e!==null){i({error:e});return}A(h,()=>ii({patch:i,save:async()=>{t===null?await n.onCreate(go(r)):await n.onUpdate(t,_o(r))},onDone:u,fallbackMessage:`Failed to save endpoint`}))},[u,t,r,n,f,m,i,h]),y=r.submitting||g;return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 rounded-md border border-border px-4 py-4`,children:[(0,G.jsx)(`h3`,{className:`text-sm font-medium`,children:d?`Edit ${p?.label??t}`:`Add endpoint`}),r.hint?(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r.hint}):null,(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Label`}),(0,G.jsx)(R,{value:r.label,onChange:e=>_(e.target.value),maxLength:64,placeholder:`GLM (Z.AI)`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Id`}),(0,G.jsx)(R,{value:r.id,onChange:e=>o(e.target.value),disabled:d,placeholder:`glm`,className:`font-mono`}),(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Part of every model id, so it cannot change after the endpoint is created.`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Base URL`}),(0,G.jsx)(R,{value:r.baseUrl,onChange:e=>i({baseUrl:e.target.value}),placeholder:`https://api.example.com/anthropic`,className:`font-mono`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`API key`}),(0,G.jsx)(R,{type:`password`,autoComplete:`off`,value:r.apiKey,onChange:e=>i({apiKey:e.target.value}),maxLength:I,placeholder:xo(f,p?.apiKeyHint??null),className:`font-mono`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Context window (tokens)`}),(0,G.jsx)(R,{inputMode:`numeric`,value:r.contextWindow,onChange:e=>i({contextWindow:e.target.value}),placeholder:`200000`,className:`font-mono tabular-nums`}),(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`The model's real context window. The agent compacts the conversation before reaching it. Leave empty to assume 200,000. For Ollama use your OLLAMA_CONTEXT_LENGTH.`})]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Models`}),r.models.map((e,t)=>(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(R,{value:e.id,onChange:e=>s(t,`id`,e.target.value),maxLength:128,placeholder:`Model id`,"aria-label":`Model ${t+1} id`,className:`font-mono`}),(0,G.jsx)(R,{value:e.label,onChange:e=>s(t,`label`,e.target.value),maxLength:64,placeholder:`Label (optional)`,"aria-label":`Model ${t+1} label`}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:()=>l(t),"aria-label":`Remove model ${t+1}`,children:(0,G.jsx)(qe,{className:`h-4 w-4`})})]},t)),(0,G.jsx)(`div`,{children:(0,G.jsxs)(E,{variant:`ghost`,size:`sm`,onClick:c,children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add model`]})})]}),r.error?(0,G.jsx)(`div`,{role:`alert`,className:`rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm text-destructive`,children:r.error}):null,(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(E,{onClick:v,pending:y,children:ai({submitting:y,isEdit:d,addLabel:`Add endpoint`})}),(0,G.jsx)(E,{variant:`ghost`,onClick:u,disabled:y,children:`Cancel`})]})]})}function Mo(e){let t=z(gt),n=ri(wo,e.state);return(0,G.jsx)(Do,{providers:t,handlers:n})}function No(e,t){return{shortcut:e,expansion:t,submitting:!1,error:null}}var Po=w()(e=>({editing:{kind:`list`},editorForm:No(``,``),setEditing:t=>e({editing:t}),resetEditorForm:(t,n)=>e({editorForm:No(t,n)}),patchEditorForm:t=>e(e=>({editorForm:{...e.editorForm,...t}}))})),Fo=e=>({textSnippets:e}),Io=/^\S{1,32}$/;function Lo({snippets:e,handlers:t,dom:n=oe}){let r=Po(e=>e.editing),i=Po(e=>e.setEditing),a=Po(e=>e.resetEditorForm);function o(t){if(t.kind===`create`)a(``,``);else if(t.kind===`edit`){let n=e.find(e=>e.id===t.id)??null;n&&a(n.shortcut,n.expansion)}i(t)}if(r.kind!==`list`){let n=r.kind===`edit`?e.find(e=>e.id===r.id)??null:null;return(0,G.jsx)(zo,{initial:n,existing:e.map(e=>({id:e.id,shortcut:e.shortcut})),handlers:t,onDone:()=>i({kind:`list`})})}return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 px-6 py-6`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:`Text snippets`}),(0,G.jsx)(`p`,{className:`max-w-[65ch] text-sm text-muted-foreground`,children:`Type a shortcut in the chat composer and press Tab to expand it into the full text. Handy for prompts you send often.`})]}),(0,G.jsxs)(E,{size:`sm`,onClick:()=>o({kind:`create`}),children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add snippet`]})]}),e.length===0?(0,G.jsx)(Zr,{icon:or,message:`No snippets yet. Add one to expand a shortcut with Tab.`}):(0,G.jsx)(Qr,{children:e.map(e=>(0,G.jsx)(Ro,{snippet:e,onEdit:()=>o({kind:`edit`,id:e.id}),onDelete:t.onDelete,dom:n},e.id))})]})}function Ro({snippet:e,onEdit:t,onDelete:n,dom:r}){let i=P(`textSnippets.delete`,e.id),a=M(i),o=(0,W.useCallback)(()=>{r.confirmDialog(`Delete snippet "${e.shortcut}"?`)&&A(i,()=>n(e.id))},[i,r,n,e.id,e.shortcut]);return(0,G.jsxs)(`li`,{className:`flex items-center gap-3 px-4 py-3`,"aria-busy":a||void 0,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-0.5`,children:[(0,G.jsx)(`span`,{className:`font-mono text-sm`,children:e.shortcut}),(0,G.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,children:e.expansion})]}),(0,G.jsx)(`div`,{className:`ml-auto flex items-center gap-2`,children:(0,G.jsx)($r,{label:e.shortcut,onEdit:t,onDelete:o,deletePending:a})})]})}function zo({initial:e,existing:t,handlers:n,onDone:r}){let i=Po(e=>e.editorForm),a=Po(e=>e.patchEditorForm),{shortcut:o,expansion:s,submitting:c,error:l}=i,u=e!==null,d=o.trim(),f=Io.test(d),p=(0,W.useMemo)(()=>t.some(t=>t.shortcut===d&&t.id!==e?.id),[t,d,e?.id]),m=f&&!p&&s.length>0&&!c,h=()=>ii({patch:a,save:async()=>{u&&e?await n.onUpdate(e.id,{shortcut:d,expansion:s}):await n.onCreate({shortcut:d,expansion:s})},onDone:r,fallbackMessage:`Failed to save snippet`}),g=ai({submitting:c,isEdit:u,addLabel:`Add snippet`});return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 px-6 py-6`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:u?`Edit snippet`:`Add snippet`}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Shortcut`}),(0,G.jsx)(R,{value:o,onChange:e=>a({shortcut:e.target.value}),placeholder:`pgm`,className:`font-mono`,autoFocus:!0}),o.length>0&&!f&&(0,G.jsx)(`span`,{className:`text-xs text-destructive`,children:`Shortcut must be 1-32 characters with no spaces.`}),p&&(0,G.jsx)(`span`,{className:`text-xs text-destructive`,children:`A snippet with this shortcut already exists.`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Expands to`}),(0,G.jsx)(ln,{value:s,onChange:e=>a({expansion:e.target.value}),placeholder:`pull request green then merge`,rows:4})]}),l&&(0,G.jsx)(`span`,{className:`text-xs text-destructive`,children:l}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(E,{onClick:()=>{A(P(`textSnippets.save`,e?.id??`new`),h)},pending:c,disabled:!m,children:g}),(0,G.jsx)(E,{variant:`ghost`,onClick:r,disabled:c,children:`Cancel`})]})]})}function Bo(e){let t=z(ut),n=ri(Fo,e.state);return(0,G.jsx)(Lo,{snippets:t,handlers:n})}function Vo(e){if(!e)return`—`;let t=e.trim();if(!t)return`—`;let n=t.slice(-4);return`${t.startsWith(`sk-ant-`)?`sk-ant-`:``}…${n}`}var Z=w()(e=>({addLabel:``,addToken:``,addBaseUrl:``,addSubmitting:!1,tokenRowStates:{},baseUrlDrafts:{},setAddLabel:t=>e({addLabel:t}),setAddToken:t=>e({addToken:t}),setAddBaseUrl:t=>e({addBaseUrl:t}),setAddSubmitting:t=>e({addSubmitting:t}),resetAddForm:()=>e({addLabel:``,addToken:``,addBaseUrl:``}),setTokenRowTesting:(t,n)=>e(e=>({tokenRowStates:{...e.tokenRowStates,[t]:{...e.tokenRowStates[t]??{testResult:null,testing:!1},testing:n}}})),setTokenRowTestResult:(t,n)=>e(e=>({tokenRowStates:{...e.tokenRowStates,[t]:{...e.tokenRowStates[t]??{testResult:null,testing:!1},testResult:n}}})),clearTokenRowState:t=>e(e=>{let{[t]:n,...r}=e.tokenRowStates;return{tokenRowStates:r}}),setBaseUrlDraft:(t,n)=>e(e=>({baseUrlDrafts:{...e.baseUrlDrafts,[t]:n}})),clearBaseUrlDraft:t=>e(e=>{let{[t]:n,...r}=e.baseUrlDrafts;return{baseUrlDrafts:r}})}));function Ho(e){if(e<=0)return`reset now`;let t=Math.ceil(e/1e3),n=Math.floor(t/60),r=t%60;return n<60?`reset in ${n}m ${r.toString().padStart(2,`0`)}s`:`reset in ${Math.floor(n/60)}h ${(n%60).toString().padStart(2,`00`)}m`}function Uo({entry:e,now:t}){if(e.status===`active`)return(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,G.jsx)(`span`,{className:`size-1.5 rounded-full bg-muted-foreground/50`,"aria-hidden":`true`}),`Active`]});if(e.status===`limited`){let n=e.limitedUntil===null?null:Ho(e.limitedUntil-t);return(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-xs text-amber-600 dark:text-amber-400`,children:[(0,G.jsx)(`span`,{className:`size-1.5 rounded-full bg-amber-500`,"aria-hidden":`true`}),`Limited`,n!==null&&(0,G.jsxs)(G.Fragment,{children:[` `,`(`,(0,G.jsx)(`span`,{className:`tabular-nums`,children:n}),`)`]})]})}if(e.status===`disabled`)return(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-xs text-muted-foreground/60`,children:[(0,G.jsx)(`span`,{className:`size-1.5 rounded-full bg-muted-foreground/30`,"aria-hidden":`true`}),`Disabled`]});let n=e.lastErrorMessage??`Unknown error`;return(0,G.jsx)(rt,{children:(0,G.jsxs)(et,{children:[(0,G.jsx)(tt,{asChild:!0,children:(0,G.jsxs)(`span`,{className:`inline-flex cursor-default items-center gap-1.5 text-xs text-destructive`,children:[(0,G.jsx)(`span`,{className:`size-1.5 rounded-full bg-destructive`,"aria-hidden":`true`}),`Error`,(0,G.jsx)(`span`,{className:`sr-only`,children:n})]})}),(0,G.jsx)(nt,{"aria-hidden":`true`,children:n})]})})}function Wo({entry:e,now:t,isCurrent:n,concurrencyDefault:r,onRemove:i,onToggleDisabled:a,onTest:o,onChangeMaxConcurrent:s,onChangeBaseUrl:c,ports:l}){let u=l?.timer??Qe,d=Z(e=>e.tokenRowStates),f=Z(e=>e.setTokenRowTesting),p=Z(e=>e.setTokenRowTestResult),m=Z(e=>e.baseUrlDrafts),h=Z(e=>e.setBaseUrlDraft),g=d[e.id],_=g?.testResult??null,v=g?.testing??!1,y=m[e.id]??e.baseUrl??``,b=y.trim().length>0&&Jt(y)===null,x=P(`oauthPool.remove`,e.id),ee=P(`oauthPool.toggle`,e.id),te=P(`oauthPool.concurrency`,e.id),ne=P(`oauthPool.baseUrl`,e.id),S=P(`oauthPool.test`,e.id),re=M(x),C=M(ee),ie=M(te),ae=M(ne),w=()=>A(ne,()=>c(e.id,y)),oe=e=>{e.key===`Enter`&&e.currentTarget.blur()},T=async()=>{f(e.id,!0),p(e.id,null);try{let t=await o(e.token,e.baseUrl),n=t.ok?`OK`:t.error??`Error`;p(e.id,n),u.setTimeout(()=>p(e.id,null),3e3)}catch{p(e.id,`Error`),u.setTimeout(()=>p(e.id,null),3e3)}finally{f(e.id,!1)}},se=e.status===`disabled`,ce=se?nr:er,E=e.maxConcurrent??r;return(0,G.jsxs)(`div`,{className:`border-t border-border py-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,G.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium ${se?`text-muted-foreground/60`:`text-foreground`}`,children:e.label}),(0,G.jsx)(`code`,{className:`text-xs font-mono text-muted-foreground`,children:Vo(e.token)}),n&&(0,G.jsx)(`span`,{className:`inline-flex shrink-0 items-center whitespace-nowrap rounded-full border border-primary/40 bg-primary/10 px-1.5 py-0.5 text-xs font-medium tracking-wide text-primary`,children:`In use`})]}),(0,G.jsx)(`div`,{className:`mt-0.5`,children:(0,G.jsx)(Uo,{entry:e,now:t})})]}),(0,G.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[(0,G.jsx)(on,{label:`Maximum concurrent chats sharing this OAuth token. Higher = risks Anthropic rate limits.`,children:(0,G.jsxs)(`label`,{className:`inline-flex items-center gap-1 text-xs text-muted-foreground`,children:[(0,G.jsx)(`span`,{children:`Concurrent`}),ie?(0,G.jsx)(N,{className:`size-3`}):null,(0,G.jsx)(R,{type:`number`,value:E,readOnly:ie,"aria-busy":ie||void 0,onChange:t=>A(te,()=>s(e.id,Rt(Number(t.target.value)))),min:1,"aria-label":`Max concurrent chats`,className:`h-7 w-14 text-xs`,disabled:se})]})}),_!==null&&(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:_}),(0,G.jsxs)(`button`,{type:`button`,"aria-label":`Test`,onClick:()=>A(S,T),disabled:v||se,"aria-busy":v||void 0,className:`inline-flex items-center gap-1 rounded px-2 py-1 text-xs text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50`,children:[v?(0,G.jsx)(N,{className:`size-3`}):(0,G.jsx)(Hn,{className:`size-3`,"aria-hidden":`true`}),`Test`]}),(0,G.jsx)(rt,{children:(0,G.jsxs)(et,{children:[(0,G.jsx)(tt,{asChild:!0,children:(0,G.jsxs)(`button`,{type:`button`,"aria-label":se?`Enable`:`Disable`,onClick:()=>A(ee,a),disabled:C,"aria-busy":C||void 0,className:`rounded p-1 text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-default`,children:[C?(0,G.jsx)(N,{}):(0,G.jsx)(ce,{"aria-hidden":`true`,className:`size-3.5`}),(0,G.jsx)(`span`,{className:`sr-only`,children:se?`Enable`:`Disable`})]})}),(0,G.jsx)(nt,{children:se?`Enable`:`Disable`})]})}),(0,G.jsxs)(`button`,{type:`button`,"aria-label":`Remove`,onClick:()=>A(x,i),disabled:re,"aria-busy":re||void 0,className:`rounded p-1 text-muted-foreground transition-colors hover:text-destructive focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-default`,children:[re?(0,G.jsx)(N,{}):(0,G.jsx)(He,{className:`size-3.5`,"aria-hidden":`true`}),(0,G.jsx)(`span`,{className:`sr-only`,children:`Remove`})]})]})]}),(0,G.jsx)(on,{label:`Anthropic API endpoint this token authenticates against. Leave empty for the default api.anthropic.com; set it to route this credential through a proxy.`,children:(0,G.jsxs)(`label`,{className:`mt-2 flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,G.jsx)(`span`,{className:`shrink-0`,children:`Base URL`}),ae?(0,G.jsx)(N,{className:`size-3`}):null,(0,G.jsx)(R,{value:y,readOnly:ae,"aria-busy":ae||void 0,onChange:t=>h(e.id,t.target.value),onBlur:w,onKeyDown:oe,placeholder:`(default)`,maxLength:512,"aria-label":`Anthropic base URL for ${e.label}`,className:`h-7 flex-1 text-xs font-mono`,disabled:se})]})}),b&&(0,G.jsx)(`div`,{className:`mt-1 text-xs text-destructive`,children:`Must start with http:// or https://`})]})}function Go({tokens:e,onWrite:t}){let n=Z(e=>e.addLabel),r=Z(e=>e.addToken),i=Z(e=>e.addBaseUrl),a=Z(e=>e.addSubmitting),o=Z(e=>e.setAddLabel),s=Z(e=>e.setAddToken),c=Z(e=>e.setAddBaseUrl),l=Z(e=>e.setAddSubmitting),u=Z(e=>e.resetAddForm),d=Jt(i),f=i.trim().length>0&&d===null,p=n.trim().length>0&&r.trim().length>0&&!f&&!a,m=async()=>{if(p){l(!0);try{let i={id:crypto.randomUUID(),label:n.trim(),token:r.trim(),status:`active`,limitedUntil:null,lastUsedAt:null,lastErrorAt:null,lastErrorMessage:null,addedAt:Date.now(),...d===null?{}:{baseUrl:d}};await t({tokens:[...e,i]}),u()}finally{l(!1)}}};return(0,G.jsxs)(`div`,{className:`border-t border-border pt-4`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-2 sm:flex-row sm:items-end sm:gap-3`,children:[(0,G.jsx)(`div`,{className:`flex-1`,children:(0,G.jsx)(R,{value:n,onChange:e=>o(e.target.value),placeholder:`e.g. personal`,maxLength:64,className:`text-sm`,"aria-label":`Token label`})}),(0,G.jsx)(`div`,{className:`flex-[2]`,children:(0,G.jsx)(R,{value:r,onChange:e=>s(e.target.value),type:`password`,placeholder:`sk-ant-...`,maxLength:1024,className:`text-sm font-mono`,"aria-label":`OAuth token`})}),(0,G.jsxs)(`button`,{type:`button`,onClick:()=>A(`oauthPool.add`,m),disabled:!p,"aria-busy":a||void 0,className:`inline-flex shrink-0 items-center gap-1.5 rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50`,children:[a?(0,G.jsx)(N,{}):null,`Add token`]})]}),(0,G.jsxs)(`div`,{className:`mt-2`,children:[(0,G.jsx)(R,{value:i,onChange:e=>c(e.target.value),placeholder:`Base URL — leave empty for api.anthropic.com`,maxLength:512,className:`text-sm font-mono`,"aria-label":`Anthropic base URL`}),f&&(0,G.jsx)(`div`,{className:`mt-1 text-xs text-destructive`,children:`Must start with http:// or https://`})]})]})}function Ko({tokens:e,concurrencyDefault:t,onWrite:n,onTest:r,now:i,ports:a}){let o=i??Date.now(),s=Z(e=>e.clearBaseUrlDraft),c=e.reduce((e,t)=>t.lastUsedAt!==null&&(e===null||t.lastUsedAt>(e.lastUsedAt??0))?t:e,null)?.id??null,l=t=>n({tokens:e.filter(e=>e.id!==t)}),u=t=>n({tokens:e.map(e=>e.id===t?{...e,status:e.status===`disabled`?`active`:`disabled`}:e)}),d=(t,r)=>n({tokens:e.map(e=>e.id===t?{...e,maxConcurrent:r}:e)}),f=async(t,r)=>{let i=e.find(e=>e.id===t);if(!i)return;let a=Jt(r);a===null&&r.trim().length>0||(s(t),a!==(i.baseUrl??null)&&await n({tokens:e.map(e=>{if(e.id!==t)return e;let{baseUrl:n,...r}=e;return a===null?r:{...e,baseUrl:a}})}))},p=M(`oauthPool.concurrencyDefault`),m=e=>{A(`oauthPool.concurrencyDefault`,()=>n({concurrencyDefault:Rt(e)}))};return(0,G.jsxs)(`div`,{children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-3 pb-3`,children:[(0,G.jsx)(on,{label:`Default concurrent-chat cap applied to any OAuth token whose row does not override it. Sharing across N chats burns Anthropic quota and risks 429s.`,children:(0,G.jsxs)(`label`,{className:`flex flex-col gap-0.5 text-sm`,children:[(0,G.jsx)(`span`,{className:`font-medium text-foreground`,children:`Default concurrency per token`}),(0,G.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`Cap for tokens without an explicit per-row override. Minimum `,1,`, no upper limit.`]})]})}),p?(0,G.jsx)(N,{className:`ml-auto text-muted-foreground`}):null,(0,G.jsx)(R,{type:`number`,value:t,readOnly:p,"aria-busy":p||void 0,onChange:e=>m(Number(e.target.value)),min:1,"aria-label":`Default concurrency per token`,className:`h-8 w-16 text-sm`})]}),e.map(e=>(0,G.jsx)(Wo,{entry:e,now:o,isCurrent:e.id===c,concurrencyDefault:t,onRemove:()=>l(e.id),onToggleDisabled:()=>u(e.id),onTest:r,onChangeMaxConcurrent:d,onChangeBaseUrl:f,ports:a},e.id)),(0,G.jsx)(Go,{tokens:e,onWrite:n})]})}function qo(e,t){e.key===`Enter`&&(t(),e.currentTarget.blur())}function Jo(e){let t={};for(let n of Xt)t[n]=ie(e[n]??``);return{...It,...t}}function Yo(e){return P(`settings.writeKeybindings`,e)}function Xo({action:e,currentValue:t,bordered:n,onDraftChange:r,onCommit:i,onRestoreDefault:a}){let o=Yo(e),s=M(o),c=S(It[e]),l=t!==c,u=()=>{A(o,i)};return(0,G.jsx)(q,{title:v[e],description:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`span`,{children:`Comma-separated shortcuts.`}),l?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`span`,{children:` `}),(0,G.jsxs)(`button`,{type:`button`,disabled:s,"aria-busy":s||void 0,onClick:()=>{A(o,()=>a(e))},className:`inline rounded text-foreground hover:text-foreground/80 disabled:opacity-60`,children:[`Restore: `,c]})]}):null]}),bordered:n,children:(0,G.jsxs)(`div`,{className:`flex min-w-0 max-w-[420px] flex-1 items-center gap-2`,children:[(0,G.jsx)(R,{type:`text`,value:t,"aria-busy":s||void 0,onChange:t=>r(e,t.target.value),onBlur:u,onKeyDown:e=>qo(e,u),className:`font-mono`}),s?(0,G.jsx)(N,{}):null]})})}function Zo({state:e}){let t=x(e=>e.keybindingDrafts),n=x(e=>e.setKeybindingDrafts),r=x(e=>e.setKeybindingDraft),i=x(e=>e.keybindingsError),a=x(e=>e.setKeybindingsError),o=(0,W.useMemo)(()=>h(e.keybindings),[e.keybindings]);(0,W.useEffect)(()=>{n(Object.fromEntries(Xt.map(e=>[e,S(o.bindings[e])])))},[o,n]);async function s(t){try{a(null),await e.socket.command({type:`settings.writeKeybindings`,bindings:Jo(t)})}catch(e){a(e instanceof Error?e.message:`Unable to save keybindings.`)}}async function c(){await s(t)}async function l(e){let r={...t,[e]:S(It[e])};n(r),await s(r)}return(0,G.jsxs)(`div`,{className:`border-b border-border`,children:[i?(0,G.jsx)(`div`,{className:`mb-4 rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:i}):null,o.warning?(0,G.jsx)(`div`,{className:`mb-4 rounded-lg border border-border bg-card/30 px-4 py-3 text-sm text-muted-foreground`,children:o.warning}):null,Xt.map((e,n)=>(0,G.jsx)(Xo,{action:e,currentValue:t[e]??``,bordered:n!==0,onDraftChange:r,onCommit:c,onRestoreDefault:l},e))]})}var Qo=`always`,$o=`funk`,es=[{value:`blow`,label:`Blow`},{value:`bottle`,label:`Bottle`},{value:`frog`,label:`Frog`},{value:`funk`,label:`Funk`},{value:`glass`,label:`Glass`},{value:`ping`,label:`Ping`},{value:`pop`,label:`Pop`},{value:`purr`,label:`Purr`},{value:`tink`,label:`Tink`}];function ts(e){switch(e){case`never`:case`unfocused`:case`always`:return e;default:return Qo}}function ns(e){switch(e){case`blow`:case`bottle`:case`frog`:case`funk`:case`glass`:case`ping`:case`pop`:case`purr`:case`tink`:return e;default:return $o}}var rs=w()(e=>({chatSoundPreference:Qo,chatSoundId:$o,setChatSoundPreference:t=>e({chatSoundPreference:ts(t)}),setChatSoundId:t=>e({chatSoundId:ns(t)})})),is=`inline-flex items-center justify-center rounded-lg border border-border bg-background px-3 py-1.5 text-sm font-medium text-foreground transition-colors hover:bg-muted`,as=`inline-flex items-center justify-center rounded-lg bg-foreground px-3 py-1.5 text-sm font-medium text-background transition-colors hover:bg-foreground/90`,os=`rounded bg-muted px-1 py-0.5 font-mono text-12 text-foreground`,ss=`text-xs font-medium tracking-wide text-muted-foreground`,cs=`gap-1.5 disabled:cursor-default disabled:opacity-60`,ls=`push.enable`,us=`push.test`,ds=`push.disable`,fs=`push.contactSubject`;async function ps(e){try{await e(),x.getState().setPushError(null)}catch(e){x.getState().setPushError(T(e))}}function ms(e,t){A(e,()=>ps(t))}function hs(){let e=x(e=>e.pushError);return e?(0,G.jsx)(`p`,{role:`alert`,className:`rounded-lg border border-destructive/20 bg-destructive/10 px-3 py-2 text-sm text-destructive-text`,children:e}):null}function gs({pendingKey:e,onRun:t,className:n,label:r,children:i}){let a=M(e);return(0,G.jsxs)(`button`,{type:`button`,onClick:()=>ms(e,t),disabled:a,"aria-busy":a||void 0,"aria-label":r,className:D(n,cs),children:[a?(0,G.jsx)(N,{}):null,i]})}function _s({localPath:e,muted:t,onMuteToggle:n}){let r=P(`push.setProjectMute`,e),i=M(r);return(0,G.jsxs)(`label`,{"aria-busy":i||void 0,className:`flex cursor-pointer items-center gap-3 rounded-md px-2 py-1.5 transition-colors hover:bg-muted/50`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:!t,disabled:i,onChange:t=>ms(r,()=>n(e,!t.target.checked)),className:`h-4 w-4 shrink-0 rounded border-border accent-foreground`}),(0,G.jsx)(rn,{inline:!0,className:`min-w-0 flex-1 font-mono text-12 text-foreground`,tooltip:e,children:e}),i?(0,G.jsx)(N,{className:`text-muted-foreground`}):null]})}function vs(e){let{permissionState:t}=e,n=M(fs);if(t===`unsupported`)return(0,G.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Push notifications are not supported in this browser.`});if(t===`insecure-context`)return(0,G.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[`Push requires HTTPS. Run `,(0,G.jsx)(`code`,{className:os,children:`kanna --share`}),` or open Kanna over a tunnel, then enable on this device.`]});if(t===`denied`)return(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`You blocked notifications for this site. Re-enable them in your browser settings, then reload.`}),(0,G.jsx)(hs,{})]});if(!(t===`granted`&&e.config.devices.some(t=>t.id===e.currentDeviceId)))return(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-start gap-2 md:w-[440px]`,children:[(0,G.jsx)(gs,{pendingKey:ls,onRun:e.onEnable,className:as,children:`Enable on this device`}),(0,G.jsx)(hs,{})]});let r=new Set(e.config.preferences.mutedProjectPaths),i=e.contactSubjectDraft.trim(),a=pr(i),o=i!==e.contactSubject,s=()=>{a&&o&&ms(fs,()=>e.onContactSubjectSave(i))};return(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col gap-5 md:w-[440px]`,children:[(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-2 rounded-full border border-border bg-card/40 px-3 py-1 text-xs font-medium text-foreground`,children:[(0,G.jsx)(`span`,{className:`h-1.5 w-1.5 rounded-full bg-emerald-500`,"aria-hidden":!0}),`Enabled on this device`]}),(0,G.jsx)(gs,{pendingKey:us,onRun:e.onTest,className:is,children:`Send test`}),(0,G.jsx)(gs,{pendingKey:ds,onRun:e.onDisable,className:is,children:`Disable`})]}),(0,G.jsx)(hs,{}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`div`,{className:D(ss,`flex items-center gap-1.5`),children:[`Contact for delivery`,n?(0,G.jsx)(N,{}):null]}),(0,G.jsx)(R,{type:`text`,inputMode:`email`,spellCheck:!1,autoCapitalize:`none`,value:e.contactSubjectDraft,readOnly:n,"aria-busy":n||void 0,onChange:t=>e.onContactSubjectDraftChange(t.target.value),onBlur:s,onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),s())},placeholder:`mailto:you@example.com`,"aria-label":`Push contact subject`,"aria-invalid":i!==``&&!a,className:D(`font-mono`,i!==``&&!a&&`border-destructive`)}),i!==``&&!a?(0,G.jsxs)(`p`,{className:`text-xs text-destructive`,children:[`Must be a `,(0,G.jsx)(`code`,{className:os,children:`mailto:`}),` address or`,` `,(0,G.jsx)(`code`,{className:os,children:`https:`}),` URL with a routable domain (not localhost).`]}):(0,G.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Push services require a contact `,(0,G.jsx)(`code`,{className:os,children:`mailto:`}),` or`,` `,(0,G.jsx)(`code`,{className:os,children:`https:`}),` URL to sign notifications. Set your own so delivery isn’t rejected.`]})]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsx)(`div`,{className:ss,children:`Devices`}),(0,G.jsx)(`ul`,{className:`flex flex-col gap-1.5`,children:e.config.devices.map(t=>(0,G.jsxs)(`li`,{className:`flex items-start justify-between gap-3 rounded-lg border border-border bg-card/40 px-3 py-2`,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-0.5`,children:[(0,G.jsx)(`span`,{className:`truncate text-sm font-medium text-foreground`,children:t.label}),(0,G.jsx)(`span`,{className:`line-clamp-2 break-all text-xs leading-snug text-muted-foreground`,children:t.userAgent})]}),!t.isCurrentDevice&&(0,G.jsx)(gs,{pendingKey:P(`push.unsubscribe`,t.id),onRun:()=>e.onRemoveDevice(t.id),label:`Remove ${t.label}`,className:`inline-flex shrink-0 items-center rounded-md border border-border bg-background px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,children:`Remove`})]},t.id))})]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsx)(`div`,{className:ss,children:`Per-project`}),(0,G.jsx)(`ul`,{className:`flex flex-col`,children:e.projects.map(t=>(0,G.jsx)(`li`,{children:(0,G.jsx)(_s,{localPath:t.localPath,muted:r.has(t.localPath),onMuteToggle:e.onMuteToggle})},t.localPath))})]}),(0,G.jsxs)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:[`Phone setup: this page must be reachable over HTTPS. Run`,` `,(0,G.jsx)(`code`,{className:os,children:`kanna --share`}),` or open Kanna over your tunnel on the phone, then enable on that device.`]})]})}var ys=P(`packages.checkUpdates`);function bs(e){return P(`packages.update`,e)}async function xs(e,t){try{await e.command(t),fn.getState().setCommandError(null)}catch(e){throw fn.getState().setCommandError(T(e)),e}}var Ss=[],Cs=[],ws=[],Ts=[];function Es(e){return typeof e==`object`&&!!e&&`packages`in e&&`errors`in e}var Ds={up_to_date:`Up to date`,outdated:`Outdated`,partial:`Partial`,unknown:`Unknown`};function Os({pkg:e,packageEntry:t,applying:n,onUpdate:r}){let i=M(bs(e.id)),a=n||i,o=t?.update.availability,s=e.versionLabel??e.version??e.revision?.slice(0,7)??null,c=o&&o!==`up_to_date`?ba[o]:null;return(0,G.jsxs)(`div`,{className:`flex min-w-0 items-start justify-between gap-3 rounded-lg border border-border bg-card/30 p-3`,children:[(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`div`,{className:`truncate text-sm font-medium text-foreground`,children:e.name}),s?(0,G.jsx)(`div`,{className:`font-mono tabular-nums text-xs text-muted-foreground/70`,children:s}):null]}),(0,G.jsxs)(`div`,{className:`flex shrink-0 flex-wrap items-center justify-end gap-2`,children:[c?(0,G.jsx)(`span`,{className:D(`rounded-full border px-2 py-0.5 text-xs font-medium`,c),children:Ds[o]}):null,o===`outdated`||o===`partial`?(0,G.jsxs)(E,{type:`button`,size:`sm`,variant:`secondary`,disabled:a,"aria-busy":a||void 0,onClick:r,className:`h-6 rounded-full px-2 text-xs`,children:[a?(0,G.jsx)(O,{className:`mr-1 h-3 w-3 animate-spin`}):null,`Update`]}):null,e.sourceUrl?(0,G.jsx)(`a`,{href:e.sourceUrl,target:`_blank`,rel:`noreferrer`,"aria-label":`View ${e.name} source`,className:`touch-manipulation inline-flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,children:(0,G.jsx)(Pe,{className:`h-4 w-4`})}):null]})]})}function ks({source:e,packages:t,updateEntries:n,applying:r,isChecking:i,onCheckUpdates:a,onUpdate:o}){return(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,G.jsx)(`div`,{className:`text-xs font-medium tracking-wide text-muted-foreground`,children:e}),(0,G.jsxs)(E,{size:`sm`,variant:`ghost`,className:`h-6 rounded-full px-2 text-xs`,disabled:i,"aria-busy":i||void 0,onClick:a,children:[i?(0,G.jsx)(O,{className:`mr-1 h-3 w-3 animate-spin`}):(0,G.jsx)(ze,{className:`mr-1 h-3 w-3`}),`Refresh`]})]}),(0,G.jsx)(`div`,{className:`grid gap-2 md:grid-cols-2`,children:t.map(e=>{let t=n.find(t=>t.id===e.id)??null;return(0,G.jsx)(Os,{pkg:e,packageEntry:t,applying:r.includes(e.id),onUpdate:()=>o(e.id)},e.id)})})]})}function As({label:e,kind:t,packages:n,errors:r,updateEntries:i,applying:a,isChecking:o,onCheckUpdates:s,onUpdate:c}){let l=r.find(e=>e.kind===t),u=n.filter(e=>e.kind===t),d=new Map;for(let e of u){let t=e.source||`Unknown`,n=d.get(t);n?n.push(e):d.set(t,[e])}let f=t===`claude-plugin`?`Claude Code CLI`:`Codex CLI`,p;return p=l?(0,G.jsxs)(`div`,{className:`rounded-lg border border-border bg-card/30 p-3 text-sm text-muted-foreground`,children:[f,` not found — install it to manage `,e,` plugins.`]}):u.length===0?(0,G.jsxs)(`div`,{className:`rounded-lg border border-border bg-card/30 p-3 text-sm text-muted-foreground`,children:[`No `,e,` plugins installed.`]}):(0,G.jsx)(`div`,{className:`flex flex-col gap-4`,children:[...d.entries()].map(([e,t])=>(0,G.jsx)(ks,{source:e,packages:t,updateEntries:i,applying:a,isChecking:o,onCheckUpdates:s,onUpdate:c},e))}),(0,G.jsxs)(`section`,{className:`flex flex-col gap-3`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:e}),p]})}function js({state:e}){let{socket:t,connectionStatus:n}=e,r=x(e=>e.pluginInventory),i=x(e=>e.pluginInventoryLoading),a=x(e=>e.pluginInventoryError),o=x(e=>e.setPluginInventory),s=x(e=>e.setPluginInventoryLoading),c=x(e=>e.setPluginInventoryError),l=x(e=>e.packageUpdateSnapshot),u=(0,W.useCallback)(async()=>{if(n!==`connected`){o(null),c(null),s(!1);return}try{s(!0),c(null);let e=await t.command({type:`packages.listInstalled`});if(!Es(e))throw Error(`packages.listInstalled: unexpected response`);o(e)}catch(e){c(e instanceof Error?e.message:`Unable to load plugins.`)}finally{s(!1)}},[n,t,o,s,c]);(0,W.useEffect)(()=>{wt(`packages.listInstalled`,u())},[u]);let d=(0,W.useCallback)(()=>{A(ys,()=>xs(t,{type:`packages.checkUpdates`}))},[t]),f=(0,W.useCallback)(e=>{A(bs(e),()=>xs(t,{type:`packages.update`,id:e}))},[t]),p=M(ys),m=l?.status===`checking`||p,h=l?.applying??Ts,g=l?.packages.filter(e=>e.kind===`claude-plugin`||e.kind===`codex-plugin`)??ws,_=r?.packages??Ss,v=r?.errors??Cs;return a?(0,G.jsx)(`div`,{className:`rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:a}):i&&!r?(0,G.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:[(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}),`Loading…`]}):(0,G.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,G.jsx)(As,{label:`Claude Code`,kind:`claude-plugin`,packages:_,errors:v,updateEntries:g,applying:h,isChecking:m,onCheckUpdates:d,onUpdate:f}),(0,G.jsx)(As,{label:`Codex`,kind:`codex-plugin`,packages:_,errors:v,updateEntries:g,applying:h,isChecking:m,onCheckUpdates:d,onUpdate:f})]})}function Ms(e){return e.map(e=>({...e,disabled:!0}))}function Ns({pendingKey:e,value:t,onValueChange:n,options:r,size:i}){let a=M(e);return(0,G.jsxs)(`div`,{className:`inline-flex items-center gap-2`,"aria-busy":a||void 0,children:[a?(0,G.jsx)(N,{className:`text-muted-foreground`}):null,(0,G.jsx)(L,{value:t,onValueChange:t=>A(e,()=>n(t)),options:a?Ms(r):r,size:i})]})}var Ps=w()(e=>({publicUrlDraft:null,copiedSnippetId:null,error:null,setPublicUrlDraft:t=>e({publicUrlDraft:t}),setCopiedSnippetId:t=>e({copiedSnippetId:t}),setError:t=>e({error:t})})),Fs=`<your Kanna password>`,Is=`Start Kanna with --password first; the remote MCP server is off without it. `,Ls=`The URL must be https and reachable from the internet (a Cloudflare tunnel or --share).`;function Rs(e){return`${e}/mcp`}function zs({publicOrigin:e,passwordConfigured:t}){let n=Rs(e??`https://<your-public-kanna-url>`),r=t?``:Is;return[{id:`claude-code`,client:`claude-code`,title:`Claude Code`,instructions:`${r}Add the server with your Kanna password as a bearer header, or add it without one and sign in through OAuth.`,snippet:[`claude mcp add --transport http kanna ${n} --header "Authorization: Bearer ${Fs}"`,``,`claude mcp add --transport http kanna ${n}`,`# then run /mcp inside Claude Code and choose Authenticate to sign in with OAuth`].join(`
|
|
11
|
+
`).map(e=>e.trim()).filter(e=>e.length>0)},r=Fi(n);return r.length>0?{ok:!1,errors:r}:{ok:!0,input:n}}let n=Ii(e.argsText),r=Number(e.intervalSeconds),i={...t,mode:`poll`,tool:e.tool.trim(),args:`args`in n?n.args:{},cursorArg:e.cursorArg.trim(),cursorPath:e.cursorPath.trim(),itemsPath:e.itemsPath.trim(),itemKeyPath:e.itemKeyPath.trim()||null,intervalMs:Number.isFinite(r)?Math.round(r*1e3):Oi},a=[...`error`in n?[n.error]:[],...Number.isFinite(r)&&r>0?[]:[`Interval must be a number of seconds`],...Fi(i)];return a.length>0?{ok:!1,errors:a}:{ok:!0,input:i}}function Ki(e){let{enabled:t,...n}=e;return n}var qi=w()(e=>({editing:{kind:`list`},draft:zi(),error:null,confirmingDeleteId:null,startCreate:()=>e({editing:{kind:`create`},draft:zi(),error:null}),startEdit:t=>e({editing:{kind:`edit`,id:t.id},draft:Vi(t),error:null}),closeEditor:()=>e({editing:{kind:`list`},error:null}),patchDraft:t=>e(e=>({draft:{...e.draft,...t}})),applyZaloPreset:()=>e(e=>({draft:Hi(e.draft)})),setError:t=>e({error:t}),askDelete:t=>e({confirmingDeleteId:t}),cancelDelete:()=>e({confirmingDeleteId:null})})),Ji=[`subscribe`,`poll`].map(e=>({value:e,label:wi(e)})),Yi=[`notify`,`inline`,`spawn`].map(e=>({value:e,label:Ke(e)}));function J({id:e,label:t,hint:n,children:r}){return(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(`label`,{htmlFor:e,className:`block text-sm font-medium text-foreground`,children:t}),r,n?(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:n}):null]})}function Xi(e,t){let n=e.filter(e=>e.transport!==`ws`&&(e.enabled||e.id===t)),r=n.filter(e=>e.transport!==`stdio`),i=n.filter(e=>e.transport===`stdio`);return[...r,...i].map(e=>({value:e.id,label:e.name,hint:e.transport}))}function Zi({draft:e,onChange:t}){return(0,G.jsx)(J,{id:`mcp-source-uris`,label:`Resource URIs`,hint:`One URI per line. Kanna subscribes to each and reads it whenever the server says it changed.`,children:(0,G.jsx)(ln,{id:`mcp-source-uris`,rows:3,className:`font-mono`,value:e.resourceUris,onChange:e=>t({resourceUris:e.target.value})})})}function Qi({draft:e,onChange:t}){return(0,G.jsxs)(`div`,{className:`space-y-4`,children:[(0,G.jsx)(J,{id:`mcp-source-tool`,label:`List tool`,hint:`The tool Kanna calls on every poll.`,children:(0,G.jsx)(R,{id:`mcp-source-tool`,className:`font-mono`,value:e.tool,onChange:e=>t({tool:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-args`,label:`Arguments`,hint:`A JSON object sent with every call. The cursor is added under the cursor argument.`,children:(0,G.jsx)(ln,{id:`mcp-source-args`,rows:3,className:`font-mono`,value:e.argsText,onChange:e=>t({argsText:e.target.value})})}),(0,G.jsxs)(`div`,{className:`grid grid-cols-1 gap-4 sm:grid-cols-2`,children:[(0,G.jsx)(J,{id:`mcp-source-cursor-arg`,label:`Cursor argument`,children:(0,G.jsx)(R,{id:`mcp-source-cursor-arg`,className:`font-mono`,value:e.cursorArg,onChange:e=>t({cursorArg:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-cursor-path`,label:`Cursor path`,hint:`Where the next cursor sits in the result.`,children:(0,G.jsx)(R,{id:`mcp-source-cursor-path`,className:`font-mono`,value:e.cursorPath,onChange:e=>t({cursorPath:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-items-path`,label:`Items path`,hint:`Where the array of messages sits in the result.`,children:(0,G.jsx)(R,{id:`mcp-source-items-path`,className:`font-mono`,value:e.itemsPath,onChange:e=>t({itemsPath:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-item-key`,label:`Item key path`,hint:`A field that is unique per message. Leave empty to hash the whole item.`,children:(0,G.jsx)(R,{id:`mcp-source-item-key`,className:`font-mono`,value:e.itemKeyPath,onChange:e=>t({itemKeyPath:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-interval`,label:`Interval (seconds)`,hint:`Between 5 and 3600.`,children:(0,G.jsx)(R,{id:`mcp-source-interval`,inputMode:`numeric`,className:`tabular-nums`,value:e.intervalSeconds,onChange:e=>t({intervalSeconds:e.target.value})})})]})]})}function $i({editing:e,servers:t,sidebarData:n,handlers:r}){let i=Sn(),a=qi(e=>e.draft),o=qi(e=>e.error),s=qi(e=>e.patchDraft),c=qi(e=>e.applyZaloPreset),l=qi(e=>e.closeEditor),u=qi(e=>e.setError),d=P(`mcpSources.save`,e?.id??`new`),f=M(d),p=(0,W.useMemo)(()=>En(n),[n]),m=(0,W.useMemo)(()=>Tn(i),[i]),h=(0,W.useMemo)(()=>Xi(t,a.serverId),[t,a.serverId]),g=(0,W.useMemo)(()=>Gi(a),[a]),_=a.handlerMode!==`notify`,v=(0,W.useCallback)(e=>s({name:e.target.value}),[s]),y=(0,W.useCallback)(()=>{g.ok&&A(d,async()=>{u(null);try{e?await r.onUpdate(e.id,Ki(g.input)):await r.onCreate(g.input),l()}catch(e){u(e instanceof Error?e.message:`Failed to save the MCP source`)}})},[l,e,r,g,d,u]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-5 px-6 py-6`,children:[(0,G.jsxs)(`div`,{className:`flex items-start justify-between gap-4`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:e?`Edit MCP source`:`Add MCP source`}),(0,G.jsx)(E,{variant:`secondary`,size:`sm`,onClick:c,children:`Zalo preset`})]}),(0,G.jsx)(J,{id:`mcp-source-name`,label:`Name`,children:(0,G.jsx)(R,{id:`mcp-source-name`,value:a.name,onChange:v,placeholder:`Zalo`,autoFocus:!0})}),(0,G.jsx)(J,{id:`mcp-source-server`,label:`MCP server`,hint:`A stdio server started here is a separate process from the one your chats use — prefer http or sse.`,children:(0,G.jsx)(Dn,{id:`mcp-source-server`,value:a.serverId,options:h,placeholder:`Choose an MCP server`,searchPlaceholder:`Search servers...`,emptyMessage:`Add an MCP server first`,onValueChange:e=>s({serverId:e})})}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(`span`,{className:`block text-sm font-medium text-foreground`,children:`How messages arrive`}),(0,G.jsx)(L,{value:a.mode,onValueChange:e=>s({mode:e}),options:Ji,size:`sm`}),(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:Ti(a.mode)})]}),a.mode===`subscribe`?(0,G.jsx)(Zi,{draft:a,onChange:s}):(0,G.jsx)(Qi,{draft:a,onChange:s}),(0,G.jsxs)(`div`,{className:`grid grid-cols-1 gap-4 sm:grid-cols-2`,children:[(0,G.jsx)(J,{id:`mcp-source-thread-key`,label:`Thread key path`,hint:`Messages with the same value share one Inbox thread.`,children:(0,G.jsx)(R,{id:`mcp-source-thread-key`,className:`font-mono`,value:a.threadKeyPath,onChange:e=>s({threadKeyPath:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-sender`,label:`Sender path`,hint:`Shown as the sender of the thread.`,children:(0,G.jsx)(R,{id:`mcp-source-sender`,className:`font-mono`,value:a.senderPath,onChange:e=>s({senderPath:e.target.value})})})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(`span`,{className:`block text-sm font-medium text-foreground`,children:`Action`}),(0,G.jsx)(L,{value:a.handlerMode,onValueChange:e=>s({handlerMode:e}),options:Yi,size:`sm`}),(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:We(a.handlerMode)})]}),(0,G.jsx)(J,{id:`mcp-source-target`,label:a.handlerMode===`spawn`?`Project`:`Chat`,children:a.handlerMode===`spawn`?(0,G.jsx)(xn,{id:`mcp-source-target`,value:a.projectId,options:p.projects,placeholder:`Choose a project`,searchPlaceholder:`Search projects...`,onValueChange:e=>s({projectId:e})}):(0,G.jsx)(xn,{id:`mcp-source-target`,value:a.chatId,options:p.chats,placeholder:`Choose a chat`,searchPlaceholder:`Search chats...`,onValueChange:e=>s({chatId:e})})}),_?(0,G.jsx)(J,{id:`mcp-source-model`,label:`Model`,hint:`The model the turn started by each message runs with.`,children:(0,G.jsx)(Dn,{id:`mcp-source-model`,value:a.modelValue,options:m,placeholder:`Choose a model`,searchPlaceholder:`Search models...`,onValueChange:e=>s({modelValue:e})})}):null,(0,G.jsx)(J,{id:`mcp-source-template`,label:`Instruction template`,hint:(0,G.jsxs)(G.Fragment,{children:[`Insert fields from the message with `,(0,G.jsx)(`code`,{className:`font-mono`,children:`{{senderName}}`}),`. The message is appended as untrusted data.`]}),children:(0,G.jsx)(ln,{id:`mcp-source-template`,rows:4,value:a.template,onChange:e=>s({template:e.target.value})})}),(0,G.jsx)(J,{id:`mcp-source-reply-hint`,label:`Reply hint`,hint:`Tells the agent how to send a reply through the server's tools when you answer from the Inbox.`,children:(0,G.jsx)(ln,{id:`mcp-source-reply-hint`,rows:3,value:a.replyHint,onChange:e=>s({replyHint:e.target.value})})}),(0,G.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-3 text-sm`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:a.pushEnabled,onChange:e=>s({pushEnabled:e.target.checked}),className:`h-4 w-4 shrink-0 rounded border-border accent-foreground`}),`Send a push notification for new messages`]}),!g.ok&&a.name.length>0?(0,G.jsx)(`p`,{className:`text-xs text-destructive-text`,children:g.errors[0]}):null,o?(0,G.jsx)(`p`,{className:`text-xs text-destructive-text`,children:o}):null,(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(E,{onClick:y,pending:f,disabled:!g.ok,children:e?`Save changes`:`Add source`}),(0,G.jsx)(E,{variant:`ghost`,onClick:l,disabled:f,children:`Cancel`})]})]})}var ea=e=>({mcpSources:e});function ta({source:e,serverName:t,status:n,now:r,confirmingDelete:i,handlers:a}){let o=qi(e=>e.startEdit),s=qi(e=>e.askDelete),c=qi(e=>e.cancelDelete),l=P(`mcpSources.setEnabled`,e.id),u=P(`mcpSources.delete`,e.id),d=M(l),f=M(u),p=n?.state??(e.enabled?`connecting`:`disabled`),m=pn(n?.lastItemAt??void 0,r),h=(0,W.useCallback)(()=>{A(l,()=>a.onSetEnabled(e.id,!e.enabled))},[l,a,e.enabled,e.id]),g=(0,W.useCallback)(()=>o(e),[e,o]),_=(0,W.useCallback)(()=>s(e.id),[s,e.id]),v=(0,W.useCallback)(()=>{A(u,async()=>{await a.onDelete(e.id),c()})},[c,u,a,e.id]);return(0,G.jsxs)(`li`,{className:`flex flex-wrap items-center gap-x-4 gap-y-2 px-4 py-3`,"aria-busy":d||f||void 0,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-0.5`,children:[(0,G.jsx)(`span`,{className:`truncate text-sm font-medium`,children:e.name}),(0,G.jsxs)(`span`,{className:`truncate text-xs text-muted-foreground`,children:[t,` · `,wi(e.mode)]}),n?.lastError?(0,G.jsx)(`span`,{className:`text-xs text-destructive-text`,children:n.lastError}):null]}),(0,G.jsxs)(`div`,{className:`ml-auto flex flex-wrap items-center gap-3 text-xs text-muted-foreground`,children:[(0,G.jsx)(hn,{tone:Ci(p),label:Si(p)}),(0,G.jsx)(`span`,{className:`tabular-nums`,children:m?`last ${m}`:`no items yet`}),(0,G.jsxs)(`span`,{className:`tabular-nums`,children:[n?.itemCount??0,` items`]}),(0,G.jsx)(E,{variant:`secondary`,size:`sm`,onClick:h,pending:d,children:e.enabled?`Disable`:`Enable`}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:g,"aria-label":`Edit ${e.name}`,children:`Edit`}),i?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(E,{variant:`destructive`,size:`sm`,onClick:v,pending:f,children:[`Delete `,e.name,`?`]}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:c,disabled:f,children:`Keep`})]}):(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:_,"aria-label":`Delete ${e.name}`,children:`Delete`})]})]})}function na({sources:e,statuses:t,servers:n,sidebarData:r,handlers:i}){let a=qi(e=>e.editing),o=qi(e=>e.confirmingDeleteId),s=qi(e=>e.startCreate),c=yn(3e4);if(a.kind!==`list`){let t=a.kind===`edit`?e.find(e=>e.id===a.id)??null:null;return(0,G.jsx)($i,{editing:t,servers:n,sidebarData:r,handlers:i})}return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 px-6 py-6`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:`MCP sources`}),(0,G.jsx)(`p`,{className:`max-w-[65ch] text-sm text-muted-foreground`,children:`Let Kanna listen to an MCP server you already added, such as a Zalo or mail server, and put what arrives into the Inbox. Replies go back out through the same server.`})]}),(0,G.jsxs)(E,{size:`sm`,onClick:s,children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add source`]})]}),e.length===0?(0,G.jsx)(Zr,{icon:An,message:`No MCP sources yet. Add one to bring a server's messages into the Inbox.`}):(0,G.jsx)(Qr,{children:e.map(e=>(0,G.jsx)(ta,{source:e,serverName:n.find(t=>t.id===e.serverId)?.name??`Missing server`,status:t.find(t=>t.id===e.id),now:c,confirmingDelete:o===e.id,handlers:i},e.id))})]})}function ra({state:e}){let t=z(xt),n=z(ft),r=_(e=>e.statuses),i=ri(ea,e),{handleWriteAppSettings:a}=e,o=(0,W.useMemo)(()=>({...i,onSetEnabled:async(e,t)=>{await a({mcpSources:{setEnabled:{id:e,enabled:t}}})}}),[i,a]);return(0,G.jsx)(na,{sources:t,statuses:r,servers:n,sidebarData:e.sidebarData,handlers:o})}var ia=new Set([`checking`,`downloading`,`installing`,`restarting`]);function aa(e){return e!==null&&ia.has(e.state)}function oa(e){switch(e.state){case`checking`:return`Checking ${e.version}…`;case`downloading`:return`Downloading ${e.version}…`;case`installing`:return`Installing ${e.version}…`;case`restarting`:return`Restarting…`;case`current`:return`Up to date`;case`failed`:return e.message===void 0?`Update failed`:`Update failed: ${e.message}`}}function sa(e){switch(e.state){case`failed`:return`destructive`;case`current`:return`muted`;case`checking`:case`downloading`:case`installing`:case`restarting`:return`active`}}var ca={},la={},ua={},da={};function fa(e,t){return`${e}:${t}`}function pa(e,t,n){let r=Object.fromEntries(Object.entries(e).filter(([e])=>e!==t));return Object.keys(r).length>0?r:n}var Y=w()(e=>({pairing:null,expandedId:null,drafts:ca,updateErrors:la,aliasErrors:ua,openExplanations:da,setPairing:t=>e({pairing:t}),toggleExpanded:t=>e(e=>({expandedId:e.expandedId===t?null:t})),setDraft:(t,n)=>e(e=>({drafts:{...e.drafts,[t]:n}})),clearDraft:t=>e(e=>({drafts:pa(e.drafts,t,ca)})),setUpdateError:(t,n)=>e(e=>n===null?{updateErrors:pa(e.updateErrors,t,la)}:{updateErrors:{...e.updateErrors,[t]:n}}),beginAliasEdit:(t,n)=>e(e=>({drafts:{...e.drafts,[fa(t,`alias`)]:n}})),endAliasEdit:t=>e(e=>({drafts:pa(e.drafts,fa(t,`alias`),ca),aliasErrors:pa(e.aliasErrors,t,ua)})),setAliasError:(t,n)=>e(e=>n===null?{aliasErrors:pa(e.aliasErrors,t,ua)}:{aliasErrors:{...e.aliasErrors,[t]:n}}),toggleExplanation:t=>e(e=>({openExplanations:t in e.openExplanations?pa(e.openExplanations,t,da):{...e.openExplanations,[t]:!0}}))})),ma=`kanna-beacon`,ha=`ABCDEFGHJKLMNPQRSTUVWXYZ23456789`,ga=`https://github.com/cuongtranba/kanna/releases/latest`;RegExp(`^[${ha}]{8}$`);function _a(e){return`${ma}://pair?url=${encodeURIComponent(e.kannaUrl)}&code=${encodeURIComponent(e.code)}`}function va(e){return e.replace(/^v/,``).split(`-`)[0].split(`.`).map(e=>Number.parseInt(e,10))}function ya(e,t){if(e===t)return!1;let n=va(e),r=va(t),i=Math.max(n.length,r.length);for(let a=0;a<i;a+=1){let i=n[a]??0,o=r[a]??0;if(Number.isNaN(i)||Number.isNaN(o))return e<t;if(i!==o)return i<o}return!1}var ba={outdated:`border-warning/40 text-warning-text bg-warning/10`,partial:`border-warning/40 text-warning-text bg-warning/10`,unknown:`border-border text-muted-foreground bg-muted/40`};function xa({beaconId:e,alias:t,displayName:n}){let r=Y(e=>e.beginAliasEdit),i=(0,W.useCallback)(()=>{r(e,t??``)},[t,e,r]);return(0,G.jsx)(on,{label:`Set a short name`,children:(0,G.jsx)(E,{variant:`ghost`,size:`icon-sm`,onClick:i,"aria-label":`Set a short name for ${n}`,children:(0,G.jsx)(Le,{className:`h-3.5 w-3.5`})})})}function Sa({beaconId:e,alias:t,displayName:n,onSetAlias:r}){let i=fa(e,`alias`),a=Y(e=>e.drafts[i]),o=Y(t=>t.aliasErrors[e]??null),s=Y(e=>e.setDraft),c=Y(e=>e.setAliasError),l=Y(e=>e.endAliasEdit),u=P(`beacons.setAlias`,e),d=M(u),f=a??``,p=f.length===0?null:ve(f),m=f.length>0&&p===null&&f!==t,h=p??o,g=(0,W.useCallback)(t=>{s(i,t.target.value.toLowerCase()),c(e,null)},[e,i,c,s]),_=(0,W.useCallback)(t=>{A(u,async()=>{try{await r(e,t),l(e)}catch(t){c(e,T(t))}})},[e,l,r,u,c]),v=(0,W.useCallback)(()=>{_(f)},[_,f]),y=(0,W.useCallback)(()=>{_(null)},[_]),b=(0,W.useCallback)(()=>{l(e)},[e,l]);return a===void 0?null:(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,G.jsx)(R,{value:f,onChange:g,placeholder:`office-mac`,disabled:d,"aria-label":`Short name for ${n}`,"aria-invalid":h!==null||void 0,className:`w-48`}),(0,G.jsx)(E,{size:`sm`,onClick:v,pending:d,disabled:!m,children:`Save`}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:b,disabled:d,children:`Cancel`}),t!==null&&(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:y,disabled:d,children:`Clear alias`})]}),(0,G.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Type `,(0,G.jsxs)(`span`,{className:`font-mono`,children:[`@beacon/`,f.length>0?f:`name`]}),` in a message to refer to this machine.`]}),h!==null&&(0,G.jsx)(`p`,{role:`alert`,className:`text-xs text-destructive-text`,children:h})]})}var Ca=`Lets the agent run commands and scripts on this machine. Off means every command and script is refused, and the agent can only read and copy files inside the folders below. When on, each command still waits for your approval unless it is on the always-run list or you switch on running without asking.`,wa=`Skips the approval prompt. Reads and writes inside the folders below, and every command and script, run immediately. Leave it off to review each action before it runs on this machine.`,Ta=`The agent can list, search, read and copy files off this machine only inside these folders and their subfolders. Anything outside is refused. With none listed it cannot read from this machine at all. Each read waits for your approval unless running without asking is on.`,Ea=`The agent can copy files onto this machine only inside these folders and their subfolders. Leave empty and it cannot write to this machine at all. Each write waits for your approval unless running without asking is on.`,Da=`Command names, such as git, that run immediately once running commands is allowed. Matching uses the command name only, so git covers every git subcommand. Anything not listed asks you first.`;function Oa(e){return`beacon-explain-${e}`}function ka({explanationKey:e,subject:t}){let n=Y(t=>e in t.openExplanations),r=Y(e=>e.toggleExplanation),i=(0,W.useCallback)(()=>{r(e)},[e,r]);return(0,G.jsx)(on,{label:`What does this do?`,children:(0,G.jsx)(E,{variant:`ghost`,size:`icon-sm`,onClick:i,"aria-expanded":n,"aria-controls":Oa(e),"aria-label":`What does "${t}" do?`,children:(0,G.jsx)(Fe,{className:`h-4 w-4`})})})}function Aa({explanationKey:e,text:t}){let n=Y(t=>e in t.openExplanations);return(0,G.jsx)(`p`,{id:Oa(e),hidden:!n,className:`text-13 text-muted-foreground`,children:t})}function ja({beaconId:e,scope:t,onSetScope:n}){let r=P(`beacons.setScope`,e),i=M(r),a=(0,W.useCallback)(t=>{A(r,()=>n(e,t))},[e,n,r]),o=(0,W.useCallback)(e=>{a({...t,exec:e.target.checked})},[a,t]),s=(0,W.useCallback)(e=>{a({...t,autoRunScripts:e.target.checked})},[a,t]),c=(0,W.useCallback)(e=>{a({...t,readRoots:e})},[a,t]),l=(0,W.useCallback)(e=>{a({...t,writeRoots:e})},[a,t]),u=(0,W.useCallback)(e=>{a({...t,execAllowlist:e})},[a,t]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 border-t border-border bg-muted/40 px-4 py-4`,"aria-busy":i||void 0,children:[(0,G.jsx)(Ma,{explanationKey:fa(e,`exec`),checked:t.exec,disabled:i,onChange:o,title:`Allow running commands`,explanation:Ca}),(0,G.jsx)(Ma,{explanationKey:fa(e,`autoRunScripts`),checked:t.autoRunScripts,disabled:i,onChange:s,title:`Run commands and scripts from this chat without asking each time`,explanation:wa}),(0,G.jsx)(Na,{label:`Folders the agent may read`,explanation:Ta,placeholder:`/Users/me/projects`,draftKey:fa(e,`readRoots`),items:t.readRoots,disabled:i,onChange:c}),(0,G.jsx)(Na,{label:`Folders the agent may write to`,explanation:Ea,placeholder:`/Users/me/inbox`,draftKey:fa(e,`writeRoots`),items:t.writeRoots,disabled:i,onChange:l}),(0,G.jsx)(Na,{label:`Commands that always run without asking`,explanation:Da,placeholder:`git`,draftKey:fa(e,`execAllowlist`),items:t.execAllowlist,disabled:i,onChange:u})]})}function Ma({explanationKey:e,checked:t,disabled:n,onChange:r,title:i,explanation:a}){return(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,G.jsxs)(`label`,{className:`flex min-w-0 cursor-pointer items-center gap-3`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:t,disabled:n,onChange:r}),(0,G.jsx)(`span`,{className:`text-sm font-medium text-foreground`,children:i})]}),(0,G.jsx)(ka,{explanationKey:e,subject:i})]}),(0,G.jsx)(`div`,{className:`pl-7`,children:(0,G.jsx)(Aa,{explanationKey:e,text:a})})]})}function Na({label:e,explanation:t,placeholder:n,draftKey:r,items:i,disabled:a,onChange:o}){let s=Y(e=>e.drafts[r]??``),c=Y(e=>e.setDraft),l=Y(e=>e.clearDraft),u=s.trim(),d=u.length>0&&!i.includes(u),f=(0,W.useCallback)(e=>{c(r,e.target.value)},[r,c]),p=(0,W.useCallback)(()=>{o([...i,u]),l(r)},[l,r,i,o,u]),m=(0,W.useCallback)(e=>{o(i.filter(t=>t!==e))},[i,o]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium text-foreground`,children:e}),(0,G.jsx)(ka,{explanationKey:r,subject:e})]}),(0,G.jsx)(Aa,{explanationKey:r,text:t}),i.length===0?(0,G.jsx)(`span`,{className:`text-13 text-muted-foreground`,children:`None`}):(0,G.jsx)(`ul`,{className:`flex flex-col gap-1`,children:i.map(e=>(0,G.jsx)(Pa,{item:e,disabled:a,onRemove:m},e))}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(R,{value:s,onChange:f,placeholder:n,disabled:a,"aria-label":e}),(0,G.jsx)(E,{variant:`secondary`,size:`sm`,onClick:p,disabled:a||!d,children:`Add`})]})]})}function Pa({item:e,disabled:t,onRemove:n}){let r=(0,W.useCallback)(()=>{n(e)},[e,n]);return(0,G.jsxs)(`li`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`code`,{className:`min-w-0 flex-1 break-all rounded-md border border-border bg-muted px-2 py-1 font-mono text-13`,children:e}),(0,G.jsx)(E,{variant:`ghost`,size:`icon-sm`,onClick:r,disabled:t,"aria-label":`Remove ${e}`,children:(0,G.jsx)(qe,{className:`h-4 w-4`})})]})}var Fa=ae.split(`/`)[1],Ia=P(`beacons.mintPairingCode`);function La(e,t){let n=new Map(e.map(e=>[e.id,e]));return t.map(e=>{let t=n.get(e.id);return{id:e.id,label:e.label,alias:e.alias??null,os:e.os,enabled:e.enabled,online:t?.online??!1,lastSeenAt:t?.lastSeenAt??null,beaconVersion:t?.beaconVersion??null,canSelfUpdate:t?.canSelfUpdate??!1,update:t?.update??null}})}function Ra({rows:e,configs:t,handlers:n,serverVersion:r,dom:i=oe,clipboard:a=De,timer:o=Qe}){let s=yn(1e3),c=(0,W.useMemo)(()=>La(e,t),[e,t]),l=(0,W.useMemo)(()=>new Map(t.map(e=>[e.id,e])),[t]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 px-6 py-6`,children:[(0,G.jsx)(za,{now:s,handlers:n,dom:i,clipboard:a,timer:o}),c.length===0?(0,G.jsx)(Zr,{icon:pe,message:`No machines paired yet. Pair a machine to let the agent read files and run approved commands there.`}):(0,G.jsx)(Qr,{children:c.map(e=>(0,G.jsx)(Ga,{row:e,scope:l.get(e.id)?.scope??null,now:s,serverVersion:r,handlers:n,dom:i},e.id))})]})}function za({now:e,handlers:t,dom:n,clipboard:r,timer:i}){let a=Y(e=>e.pairing),o=Y(e=>e.setPairing),s=M(Ia),c=(0,W.useCallback)(()=>{A(Ia,async()=>{o(await t.onMint())})},[t,o]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-lg border border-border bg-card p-4`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:`Beacons`}),(0,G.jsx)(`p`,{className:`mt-1 text-13 text-muted-foreground`,children:`A beacon is a small program on your own machine. Once paired, the agent can read files and run commands there, only within the scope you grant below.`})]}),(0,G.jsxs)(E,{size:`sm`,variant:a?.ok===!0?`secondary`:`default`,onClick:c,pending:s,children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Pair a machine`]})]}),a?.ok===!1&&(0,G.jsx)(`p`,{role:`alert`,className:`text-sm text-destructive-text`,children:a.error}),a?.ok===!0&&(0,G.jsx)(Ba,{code:a.code,expiresAt:a.expiresAt,now:e,dom:n,clipboard:r,timer:i})]})}function Ba({code:e,expiresAt:t,now:n,dom:r,clipboard:i,timer:a}){let o=t-n,s=r.getOrigin(),c=`kanna-beacon pair ${s} ${e}`,l=_a({kannaUrl:s,code:e}),u=P(`beacons.copyPairCommand`,e),d=M(u),f=ye(u),p=(0,W.useCallback)(()=>{A(u,()=>be(u,()=>i.writeText(c),a))},[i,c,u,a]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-2 border-t border-border pt-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-baseline gap-3`,children:[(0,G.jsx)(`span`,{className:`font-mono text-2xl font-medium tabular-nums tracking-widest`,children:e}),(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground tabular-nums`,children:o>0?`Expires in ${V(o)}`:`Expired. Pair again for a new code.`})]}),(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-2`,children:[(0,G.jsxs)(`a`,{href:l,className:j({size:`sm`}),children:[(0,G.jsx)(Pe,{className:`mr-1 h-4 w-4`}),`Open in Kanna Beacon`]}),(0,G.jsx)(`a`,{href:ga,target:`_blank`,rel:`noreferrer`,className:`text-13 text-muted-foreground underline underline-offset-2 hover:text-foreground`,children:`Download Kanna Beacon`})]}),(0,G.jsx)(`p`,{className:`text-13 text-muted-foreground`,children:`Or run this on the machine you want to pair:`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`code`,{className:`min-w-0 flex-1 break-all rounded-md border border-border bg-muted px-3 py-2 font-mono text-13`,children:c}),(0,G.jsx)(on,{label:f?`Copied`:`Copy command`,children:(0,G.jsx)(E,{variant:`ghost`,size:`icon`,onClick:p,pending:d,"aria-label":f?`Copied`:`Copy pairing command`,children:f?(0,G.jsx)(Ee,{className:`h-4 w-4 text-success-text`}):(0,G.jsx)(Te,{className:`h-4 w-4`})})})]})]})}function Va(e,t){return e.lastSeenAt===null?`Never connected`:`Last seen ${mn(t-e.lastSeenAt)} ago`}var Ha=`This beacon is too old to update itself. Reinstall it once from the download page; after that, updates are one click.`;function Ua({canSelfUpdate:e}){let t=D(`rounded-full border px-2 py-0.5 text-xs`,ba.outdated);return e?(0,G.jsx)(`span`,{className:t,children:`Update available`}):(0,G.jsx)(on,{label:Ha,children:(0,G.jsx)(`a`,{href:ga,target:`_blank`,rel:`noreferrer`,className:t,children:`Update available`})})}function Wa({row:e,updateAvailable:t,handlers:n}){let r=P(`beacons.update`,e.id),i=M(r),a=Y(t=>t.updateErrors[e.id]??null),o=Y(e=>e.setUpdateError),s=t&&e.online&&e.canSelfUpdate&&!aa(e.update),c=(0,W.useCallback)(()=>{A(r,async()=>{let t=await n.onUpdate(e.id);o(e.id,t.ok?null:t.error)})},[n,e.id,o,r]);return(0,G.jsxs)(G.Fragment,{children:[e.update!==null&&(0,G.jsx)(hn,{tone:sa(e.update),label:oa(e.update)}),s&&(0,G.jsxs)(E,{variant:`secondary`,size:`sm`,onClick:c,pending:i,"aria-label":`Update ${me(e)} now`,children:[(0,G.jsx)(Pn,{className:`mr-1 h-4 w-4`}),`Update now`]}),a!==null&&(0,G.jsx)(`span`,{role:`alert`,className:`text-destructive-text`,children:a})]})}function Ga({row:e,scope:t,now:n,serverVersion:r,handlers:i,dom:a}){let o=Y(t=>t.expandedId===e.id),s=Y(e=>e.toggleExpanded),c=P(`beacons.setEnabled`,e.id),l=M(c),u=P(`beacons.delete`,e.id),d=M(u),f=me(e),p=e.beaconVersion!==null&&r!==void 0&&ya(e.beaconVersion,r),m=(0,W.useCallback)(t=>{let n=t.target.checked;A(c,()=>i.onSetEnabled(e.id,n))},[c,i,e.id]),h=(0,W.useCallback)(()=>{a.confirmDialog(`Revoke "${f}"? The agent will lose access to this machine until you pair it again.`)&&A(u,()=>i.onDelete(e.id))},[u,f,a,i,e.id]),g=(0,W.useCallback)(()=>{s(e.id)},[e.id,s]);return(0,G.jsxs)(`li`,{className:`flex flex-col`,"aria-busy":d||void 0,children:[(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 px-4 py-3`,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-1`,children:[(0,G.jsxs)(`span`,{className:`flex min-w-0 items-center gap-1`,children:[(0,G.jsx)(`span`,{className:`truncate font-medium`,children:f}),(0,G.jsx)(xa,{beaconId:e.id,alias:e.alias,displayName:f})]}),e.alias!==null&&(0,G.jsxs)(`span`,{className:`flex flex-wrap items-center gap-x-3 text-xs text-muted-foreground`,children:[(0,G.jsx)(`span`,{className:`font-mono`,children:e.label}),(0,G.jsxs)(`span`,{className:`font-mono`,children:[`@beacon/`,e.alias]})]}),(0,G.jsx)(Sa,{beaconId:e.id,alias:e.alias,displayName:f,onSetAlias:i.onSetAlias}),(0,G.jsxs)(`span`,{className:`flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground`,children:[(0,G.jsx)(hn,{tone:e.online?`active`:`muted`,label:e.online?`Online`:`Offline`}),(0,G.jsx)(`span`,{className:`tabular-nums`,children:Va(e,n)}),e.beaconVersion!==null&&(0,G.jsxs)(`span`,{className:`font-mono tabular-nums`,children:[`v`,e.beaconVersion]}),p&&(0,G.jsx)(Ua,{canSelfUpdate:e.canSelfUpdate}),(0,G.jsx)(Wa,{row:e,updateAvailable:p,handlers:i}),(0,G.jsx)(`span`,{children:e.os})]})]}),(0,G.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,G.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-1 text-xs text-muted-foreground`,children:[l?(0,G.jsx)(N,{}):null,(0,G.jsx)(`input`,{type:`checkbox`,checked:e.enabled,disabled:l,"aria-busy":l||void 0,onChange:m,"aria-label":`Enable ${f}`}),(0,G.jsx)(`span`,{children:e.enabled?`Enabled`:`Disabled`})]}),t!==null&&(0,G.jsxs)(E,{variant:`ghost`,size:`sm`,onClick:g,"aria-expanded":o,children:[`Scope`,(0,G.jsx)(Oe,{className:D(`ml-1 h-4 w-4 transition-transform`,o&&`rotate-180`)})]}),(0,G.jsx)(on,{label:`Revoke this machine`,children:(0,G.jsx)(E,{variant:`ghost`,size:`icon`,onClick:h,pending:d,"aria-label":`Revoke ${f}`,children:(0,G.jsx)(Ve,{className:`h-4 w-4`})})})]})]}),o&&t!==null&&(0,G.jsx)(ja,{beaconId:e.id,scope:t,onSetScope:i.onSetScope})]})}function Ka(e){let t=d(y),n=z(vt),{handleWriteAppSettings:r,handleMintBeaconPairingCode:i,handleUpdateBeacon:a}=e.state,o=(0,W.useMemo)(()=>({onMint:i,onSetEnabled:async(e,t)=>{await r({customBeacons:{setEnabled:{id:e,enabled:t}}})},onSetScope:async(e,t)=>{await r({customBeacons:{setScope:{id:e,scope:t}}})},onSetAlias:async(e,t)=>{await r({customBeacons:{update:{id:e,patch:{alias:t}}}})},onDelete:async e=>{await r({customBeacons:{delete:{id:e}}})},onUpdate:a}),[r,i,a]);return(0,G.jsx)(Ra,{rows:t,configs:n,handlers:o,serverVersion:Fa})}var qa={id:``,label:``,modelProvider:`claude`,supportedEfforts:[],offersOneMillionContext:!1};function Ja(e){return{...e,submitting:!1,error:null}}var Ya=w()(e=>({editing:{kind:`list`},editorForm:Ja(qa),setEditing:t=>e({editing:t}),resetEditorForm:t=>e({editorForm:Ja(t)}),patchEditorForm:t=>e(e=>({editorForm:{...e.editorForm,...t}})),toggleSupportedEffort:t=>e(e=>{let n=e.editorForm.supportedEfforts,r=n.includes(t)?n.filter(e=>e!==t):[...n,t];return{editorForm:{...e.editorForm,supportedEfforts:r}}}),toggleOneMillionContext:()=>e(e=>({editorForm:{...e.editorForm,offersOneMillionContext:!e.editorForm.offersOneMillionContext}}))})),Xa=e=>({customModels:e}),Za=new Set([`claude`,`codex`]);function Qa(e){return Za.has(e)}var $a={claude:`Claude`,codex:`Codex`};function eo({models:e,handlers:t,dom:n=oe}){let r=Ya(e=>e.editing),i=Ya(e=>e.setEditing),a=Ya(e=>e.resetEditorForm);function o(t){if(t.kind===`create`)a({id:``,label:``,modelProvider:t.provider,supportedEfforts:[],offersOneMillionContext:!1});else if(t.kind===`edit`){let n=e.find(e=>e.id===t.id)??null;n&&a({id:n.id,label:n.label,modelProvider:n.provider,supportedEfforts:n.supportedEfforts??[],offersOneMillionContext:en(n.provider,n.id,n.contextWindowOptions).some(e=>e.id===`1m`)})}i(t)}if(r.kind!==`list`){let n=r.kind===`edit`?e.find(e=>e.id===r.id)??null:null;return(0,G.jsx)(no,{initial:n,existing:e.map(e=>({id:e.id,provider:e.provider})),handlers:t,onDone:()=>i({kind:`list`})})}return(0,G.jsx)(`div`,{className:`flex flex-col gap-6 px-6 py-6`,children:[`claude`,`codex`].map(r=>{let i=e.filter(e=>e.provider===r);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsxs)(`h2`,{className:`text-base font-medium`,children:[$a[r],` models`]}),(0,G.jsxs)(E,{size:`sm`,onClick:()=>o({kind:`create`,provider:r}),children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add model`]})]}),i.length===0?(0,G.jsx)(Zr,{icon:Bn,message:`No ${$a[r]} models configured.`}):(0,G.jsx)(Qr,{children:i.map(e=>(0,G.jsx)(to,{model:e,onEdit:()=>o({kind:`edit`,id:e.id}),onDelete:t.onDelete,dom:n},e.id))})]},r)})})}function to({model:e,onEdit:t,onDelete:n,dom:r}){let i=P(`models.delete`,e.provider,e.id),a=M(i),o=(0,W.useCallback)(()=>{r.confirmDialog(`Delete model "${e.label}"?`)&&A(i,()=>n(e.id))},[i,r,e.id,e.label,n]);return(0,G.jsxs)(`li`,{className:`flex items-center gap-3 px-4 py-3`,"aria-busy":a||void 0,children:[(0,G.jsxs)(`div`,{className:`flex flex-col`,children:[(0,G.jsx)(`span`,{className:`font-medium`,children:e.label}),(0,G.jsx)(`span`,{className:`font-mono text-xs text-muted-foreground`,children:e.id})]}),(0,G.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(e.supportedEfforts?.length??0)>0&&(0,G.jsx)(`span`,{className:`rounded bg-muted px-1.5 py-0.5 text-xs`,children:`effort`}),e.supportedEfforts?.includes(`max`)&&(0,G.jsx)(`span`,{className:`rounded bg-muted px-1.5 py-0.5 text-xs`,children:`max`}),(0,G.jsx)($r,{label:e.label,onEdit:t,onDelete:o,deletePending:a})]})]})}function no({initial:e,existing:t,handlers:n,onDone:r}){let i=Ya(e=>e.editorForm),a=Ya(e=>e.patchEditorForm),o=Ya(e=>e.toggleSupportedEffort),s=Ya(e=>e.toggleOneMillionContext),c=(0,W.useCallback)(e=>{Qa(e)&&a({modelProvider:e})},[a]),{id:l,label:u,modelProvider:d,supportedEfforts:f,offersOneMillionContext:p,submitting:m,error:h}=i,g=p?Gt:Gt.filter(e=>e.id===`200k`),_=e!==null,v=(0,W.useMemo)(()=>!_&&t.some(e=>e.id===l.trim()&&e.provider===d),[t,l,_,d]),y=l.trim().length>0&&u.trim().length>0&&!v&&!m,b=()=>ii({patch:a,save:async()=>{_&&e?await n.onUpdate(e.id,{label:u.trim(),supportedEfforts:f.length>0?f:null,...d===`claude`?{contextWindowOptions:g}:{}}):await n.onCreate({id:l.trim(),label:u.trim(),provider:d,...f.length>0?{supportedEfforts:f}:{},...d===`claude`?{contextWindowOptions:g}:{}})},onDone:r,fallbackMessage:`Failed to save model`}),x=ai({submitting:m,isEdit:_,addLabel:`Add model`});return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 px-6 py-6`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:_?`Edit model`:`Add model`}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Provider`}),(0,G.jsxs)(Ne,{value:d,onValueChange:c,disabled:_,children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsxs)(Ae,{children:[(0,G.jsx)(F,{value:`claude`,children:`Claude`}),(0,G.jsx)(F,{value:`codex`,children:`Codex`})]})]})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Model ID`}),(0,G.jsx)(R,{value:l,onChange:e=>a({id:e.target.value}),placeholder:`claude-opus-4-9`,disabled:_,className:`font-mono`}),v&&(0,G.jsx)(`span`,{className:`text-xs text-red-600`,children:`A model with this id already exists.`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Label`}),(0,G.jsx)(R,{value:u,onChange:e=>a({label:e.target.value}),placeholder:`Opus 4.9`})]}),d===`claude`&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Supported effort levels`}),Ht.map(e=>(0,G.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-2 text-sm`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:f.includes(e.id),onChange:()=>o(e.id)}),(0,G.jsx)(`span`,{children:e.label})]},e.id))]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Context window`}),(0,G.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-2 text-sm`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:p,onChange:s}),(0,G.jsx)(`span`,{children:`Offer the 1M context window`})]}),(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Off means every turn on this model runs on the 200k window.`})]})]}),h&&(0,G.jsx)(`span`,{className:`text-xs text-red-600`,children:h}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(E,{onClick:()=>{A(P(`models.save`,e?.id??`new`),b)},pending:m,disabled:!y,children:x}),(0,G.jsx)(E,{variant:`ghost`,onClick:r,disabled:m,children:`Cancel`})]})]})}function ro(e){let t=z(ot),n=ri(Xa,e.state);return(0,G.jsx)(eo,{models:t,handlers:n})}var io=32,ao=`-`;function oo(){return{id:``,idTouched:!1,label:``,baseUrl:``,apiKey:``,models:[so()],contextWindow:``,hint:null}}function so(){return{id:``,label:``}}function co(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^[^a-z]+/,``).replace(/-+$/,``).slice(0,io).replace(/-+$/,``)}function lo(e,t){if(e.length===0||!t.includes(e))return e;for(let n=2;;n+=1){let r=`-${n}`,i=`${e.slice(0,io-r.length)}${r}`;if(!t.includes(i))return i}}function uo(e,t){return{id:lo(e.id,t),idTouched:!0,label:e.label,baseUrl:e.baseUrl,apiKey:e.defaultApiKey??``,models:e.models.length>0?e.models.map(e=>({...e})):[so()],contextWindow:e.contextWindow===void 0?``:String(e.contextWindow),hint:e.hint??null}}function fo(e){return{id:e.id,idTouched:!0,label:e.label,baseUrl:e.baseUrl,apiKey:``,models:e.models.map(e=>({...e})),contextWindow:e.contextWindow===void 0?``:String(e.contextWindow),hint:null}}function po(e,t){return lo(co(e),t)}function mo(e){return e.map(e=>({id:e.id.trim(),label:e.label.trim()})).filter(e=>e.id.length>0||e.label.length>0)}function ho(e){let t=e.replace(/[\s,_]/g,``);return t.length===0?void 0:Number(t)}function go(e){let t=ho(e.contextWindow);return{id:e.id.trim(),label:e.label.trim(),baseUrl:e.baseUrl.trim(),apiKey:e.apiKey.trim(),models:mo(e.models),...t===void 0?{}:{contextWindow:t}}}function _o(e){let t=e.apiKey.trim();return{label:e.label.trim(),baseUrl:e.baseUrl.trim(),models:mo(e.models),contextWindow:ho(e.contextWindow)??null,...t.length>0?{apiKey:t}:{}}}function vo(e,t,n){let r=go(e),i=Ue({...r,apiKey:t===`edit`&&r.apiKey.length===0?ao:r.apiKey},n);return i===null?null:i.code===`INVALID_ID`?`Id must be lowercase letters, digits or dashes, start with a letter, and be at most ${io} characters (${Ge}).`:i.message}function yo(e){return`${e<1e6&&e%1024==0?`${e/1024}k`:kt(e)} context`}function bo(e){return e===null?`Key set`:`Key ••••${e}`}function xo(e,t){return e===`create`?`API key`:t===null?`Leave blank to keep the saved key`:`Leave blank to keep ••••${t}`}function So(e){return{...e,submitting:!1,error:null}}var X=w()(e=>({editing:{kind:`list`},menuOpen:!1,listError:null,editorForm:So(oo()),setMenuOpen:t=>e({menuOpen:t}),setListError:t=>e({listError:t}),startEditing:(t,n)=>e({editing:t,menuOpen:!1,listError:null,editorForm:So(n)}),discardEditor:()=>e({editing:{kind:`list`},menuOpen:!1,editorForm:So(oo())}),patchEditorForm:t=>e(e=>({editorForm:{...e.editorForm,...t}})),setLabel:(t,n)=>e(e=>({editorForm:{...e.editorForm,label:t,id:e.editorForm.idTouched?e.editorForm.id:po(t,n)}})),setId:t=>e(e=>({editorForm:{...e.editorForm,id:t.toLowerCase(),idTouched:!0}})),setModelField:(t,n,r)=>e(e=>({editorForm:{...e.editorForm,models:e.editorForm.models.map((e,i)=>i===t?{...e,[n]:r}:e)}})),addModelRow:()=>e(e=>({editorForm:{...e.editorForm,models:[...e.editorForm.models,{id:``,label:``}]}})),removeModelRow:t=>e(e=>({editorForm:{...e.editorForm,models:e.editorForm.models.filter((e,n)=>n!==t)}}))})),Co=[{id:`glm`,label:`GLM (Z.AI)`,baseUrl:`https://api.z.ai/api/anthropic`,models:[{id:`glm-5.3`,label:`GLM-5.3`},{id:`glm-5.3-flash`,label:`GLM-5.3 Flash`}]},{id:`qwen`,label:`Qwen (Alibaba Model Studio)`,baseUrl:`https://coding-intl.dashscope.aliyuncs.com/apps/anthropic`,models:[{id:`qwen3.7-plus`,label:`Qwen3.7 Plus`},{id:`qwen3.7-max`,label:`Qwen3.7 Max`}],hint:`Coding Plan endpoint. Pay-as-you-go uses https://{WorkspaceId}.<region>.maas.aliyuncs.com/apps/anthropic.`},{id:`kimi`,label:`Kimi (Moonshot)`,baseUrl:`https://api.moonshot.ai/anthropic`,models:[{id:`kimi-k3`,label:`Kimi K3`},{id:`kimi-k2.7-code`,label:`Kimi K2.7 Code`}]},{id:`deepseek`,label:`DeepSeek`,baseUrl:`https://api.deepseek.com/anthropic`,models:[{id:`deepseek-v4-pro`,label:`DeepSeek V4 Pro`},{id:`deepseek-flash`,label:`DeepSeek Flash`}]},{id:`minimax`,label:`MiniMax`,baseUrl:`https://api.minimax.io/anthropic`,models:[{id:`MiniMax-M3.1`,label:`MiniMax M3.1`}],hint:`Mainland China: https://api.minimaxi.com/anthropic`},{id:`ollama`,label:`Ollama (local)`,baseUrl:`http://localhost:11434`,models:[],contextWindow:65536,defaultApiKey:`ollama`,hint:"Runs on this machine. Ollama ignores the API key, so any value works. Add the exact model names from `ollama list`, and set Context window to your OLLAMA_CONTEXT_LENGTH."}],wo=e=>({customProviders:e}),To=`Anthropic-compatible endpoints such as GLM, Qwen, Kimi, DeepSeek or MiniMax. They run through the Claude agent, so tools, skills and MCP work as usual. Pick them in the chat composer under Custom endpoints.`;function Eo(e){return`${e} ${e===1?`model`:`models`}`}function Do({providers:e,handlers:t,dom:n=oe}){let r=X(e=>e.editing),i=X(e=>e.discardEditor);return(0,W.useEffect)(()=>{i()},[i]),(0,G.jsxs)(`div`,{className:`border-t border-border pb-5`,children:[(0,G.jsx)(q,{title:`Custom endpoints`,description:To,bordered:!1,alignStart:!0,children:r.kind===`list`?(0,G.jsx)(Oo,{providers:e}):null}),r.kind===`list`?(0,G.jsx)(ko,{providers:e,onDelete:t.onDelete,dom:n}):(0,G.jsx)(jo,{providers:e,editingId:r.kind===`edit`?r.id:null,handlers:t})]})}function Oo({providers:e}){let t=X(e=>e.menuOpen),n=X(e=>e.setMenuOpen),r=X(e=>e.startEditing),i=(0,W.useMemo)(()=>e.map(e=>e.id),[e]),a=(0,W.useCallback)(e=>{r({kind:`create`},uo(e,i))},[r,i]),o=(0,W.useCallback)(()=>{r({kind:`create`},oo())},[r]);return(0,G.jsxs)(vn,{open:t,onOpenChange:n,children:[(0,G.jsx)(_n,{asChild:!0,children:(0,G.jsxs)(E,{size:`sm`,children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add endpoint`]})}),(0,G.jsx)(gn,{align:`end`,className:`w-64 p-1`,children:(0,G.jsxs)(`div`,{className:`space-y-1`,children:[Co.map(e=>(0,G.jsx)(he,{onClick:()=>a(e),selected:!1,icon:(0,G.jsx)(Se,{className:`h-4 w-4 text-muted-foreground`}),label:e.label},e.id)),(0,G.jsx)(he,{onClick:o,selected:!1,icon:(0,G.jsx)(Re,{className:`h-4 w-4 text-muted-foreground`}),label:`Custom…`,description:`Any Anthropic-compatible URL`})]})})]})}function ko({providers:e,onDelete:t,dom:n}){let r=X(e=>e.listError);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[r?(0,G.jsx)(`div`,{role:`alert`,className:`rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm text-destructive`,children:r}):null,e.length===0?(0,G.jsx)(Zr,{icon:Se,message:`No custom endpoints yet.`}):(0,G.jsx)(Qr,{children:e.map(e=>(0,G.jsx)(Ao,{provider:e,onDelete:t,dom:n},e.id))})]})}function Ao({provider:e,onDelete:t,dom:n}){let r=X(e=>e.startEditing),i=X(e=>e.setListError),a=P(`settings.customProviders.delete`,e.id),o=M(a),s=(0,W.useCallback)(()=>{r({kind:`edit`,id:e.id},fo(e))},[e,r]),c=(0,W.useCallback)(()=>{n.confirmDialog(`Delete endpoint "${e.label}"?`)&&A(a,async()=>{i(null);try{await t(e.id)}catch(e){i(T(e))}})},[a,n,t,e.id,e.label,i]);return(0,G.jsxs)(`li`,{className:`flex items-center gap-3 px-4 py-3`,"aria-busy":o||void 0,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-0.5`,children:[(0,G.jsx)(`span`,{className:`truncate font-medium`,children:e.label}),(0,G.jsx)(rn,{tooltip:e.baseUrl,className:`font-mono text-xs text-muted-foreground`,children:e.baseUrl})]}),(0,G.jsxs)(`div`,{className:`flex shrink-0 flex-col items-end gap-0.5 text-xs text-muted-foreground`,children:[(0,G.jsx)(`span`,{className:`tabular-nums`,children:Eo(e.models.length)}),e.contextWindow===void 0?null:(0,G.jsx)(`span`,{className:`tabular-nums`,children:yo(e.contextWindow)}),(0,G.jsx)(`span`,{children:bo(e.apiKeyHint)})]}),(0,G.jsx)(`div`,{className:`flex shrink-0 items-center gap-1`,children:(0,G.jsx)($r,{label:e.label,onEdit:s,onDelete:c,deletePending:o})})]})}function jo({providers:e,editingId:t,handlers:n}){let r=X(e=>e.editorForm),i=X(e=>e.patchEditorForm),a=X(e=>e.setLabel),o=X(e=>e.setId),s=X(e=>e.setModelField),c=X(e=>e.addModelRow),l=X(e=>e.removeModelRow),u=X(e=>e.discardEditor),d=t!==null,f=d?`edit`:`create`,p=(0,W.useMemo)(()=>e.find(e=>e.id===t)??null,[e,t]),m=(0,W.useMemo)(()=>e.filter(e=>e.id!==t).map(e=>e.id),[e,t]),h=P(`settings.customProviders`,t??(r.id||`new`)),g=M(h),_=(0,W.useCallback)(e=>{a(e,m)},[m,a]),v=(0,W.useCallback)(()=>{let e=vo(r,f,m);if(e!==null){i({error:e});return}A(h,()=>ii({patch:i,save:async()=>{t===null?await n.onCreate(go(r)):await n.onUpdate(t,_o(r))},onDone:u,fallbackMessage:`Failed to save endpoint`}))},[u,t,r,n,f,m,i,h]),y=r.submitting||g;return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 rounded-md border border-border px-4 py-4`,children:[(0,G.jsx)(`h3`,{className:`text-sm font-medium`,children:d?`Edit ${p?.label??t}`:`Add endpoint`}),r.hint?(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r.hint}):null,(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Label`}),(0,G.jsx)(R,{value:r.label,onChange:e=>_(e.target.value),maxLength:64,placeholder:`GLM (Z.AI)`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Id`}),(0,G.jsx)(R,{value:r.id,onChange:e=>o(e.target.value),disabled:d,placeholder:`glm`,className:`font-mono`}),(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Part of every model id, so it cannot change after the endpoint is created.`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Base URL`}),(0,G.jsx)(R,{value:r.baseUrl,onChange:e=>i({baseUrl:e.target.value}),placeholder:`https://api.example.com/anthropic`,className:`font-mono`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`API key`}),(0,G.jsx)(R,{type:`password`,autoComplete:`off`,value:r.apiKey,onChange:e=>i({apiKey:e.target.value}),maxLength:I,placeholder:xo(f,p?.apiKeyHint??null),className:`font-mono`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Context window (tokens)`}),(0,G.jsx)(R,{inputMode:`numeric`,value:r.contextWindow,onChange:e=>i({contextWindow:e.target.value}),placeholder:`200000`,className:`font-mono tabular-nums`}),(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`The model's real context window. The agent compacts the conversation before reaching it. Leave empty to assume 200,000. For Ollama use your OLLAMA_CONTEXT_LENGTH.`})]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Models`}),r.models.map((e,t)=>(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(R,{value:e.id,onChange:e=>s(t,`id`,e.target.value),maxLength:128,placeholder:`Model id`,"aria-label":`Model ${t+1} id`,className:`font-mono`}),(0,G.jsx)(R,{value:e.label,onChange:e=>s(t,`label`,e.target.value),maxLength:64,placeholder:`Label (optional)`,"aria-label":`Model ${t+1} label`}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,onClick:()=>l(t),"aria-label":`Remove model ${t+1}`,children:(0,G.jsx)(qe,{className:`h-4 w-4`})})]},t)),(0,G.jsx)(`div`,{children:(0,G.jsxs)(E,{variant:`ghost`,size:`sm`,onClick:c,children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add model`]})})]}),r.error?(0,G.jsx)(`div`,{role:`alert`,className:`rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm text-destructive`,children:r.error}):null,(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(E,{onClick:v,pending:y,children:ai({submitting:y,isEdit:d,addLabel:`Add endpoint`})}),(0,G.jsx)(E,{variant:`ghost`,onClick:u,disabled:y,children:`Cancel`})]})]})}function Mo(e){let t=z(gt),n=ri(wo,e.state);return(0,G.jsx)(Do,{providers:t,handlers:n})}function No(e,t){return{shortcut:e,expansion:t,submitting:!1,error:null}}var Po=w()(e=>({editing:{kind:`list`},editorForm:No(``,``),setEditing:t=>e({editing:t}),resetEditorForm:(t,n)=>e({editorForm:No(t,n)}),patchEditorForm:t=>e(e=>({editorForm:{...e.editorForm,...t}}))})),Fo=e=>({textSnippets:e}),Io=/^\S{1,32}$/;function Lo({snippets:e,handlers:t,dom:n=oe}){let r=Po(e=>e.editing),i=Po(e=>e.setEditing),a=Po(e=>e.resetEditorForm);function o(t){if(t.kind===`create`)a(``,``);else if(t.kind===`edit`){let n=e.find(e=>e.id===t.id)??null;n&&a(n.shortcut,n.expansion)}i(t)}if(r.kind!==`list`){let n=r.kind===`edit`?e.find(e=>e.id===r.id)??null:null;return(0,G.jsx)(zo,{initial:n,existing:e.map(e=>({id:e.id,shortcut:e.shortcut})),handlers:t,onDone:()=>i({kind:`list`})})}return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 px-6 py-6`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:`Text snippets`}),(0,G.jsx)(`p`,{className:`max-w-[65ch] text-sm text-muted-foreground`,children:`Type a shortcut in the chat composer and press Tab to expand it into the full text. Handy for prompts you send often.`})]}),(0,G.jsxs)(E,{size:`sm`,onClick:()=>o({kind:`create`}),children:[(0,G.jsx)(Re,{className:`mr-1 h-4 w-4`}),`Add snippet`]})]}),e.length===0?(0,G.jsx)(Zr,{icon:or,message:`No snippets yet. Add one to expand a shortcut with Tab.`}):(0,G.jsx)(Qr,{children:e.map(e=>(0,G.jsx)(Ro,{snippet:e,onEdit:()=>o({kind:`edit`,id:e.id}),onDelete:t.onDelete,dom:n},e.id))})]})}function Ro({snippet:e,onEdit:t,onDelete:n,dom:r}){let i=P(`textSnippets.delete`,e.id),a=M(i),o=(0,W.useCallback)(()=>{r.confirmDialog(`Delete snippet "${e.shortcut}"?`)&&A(i,()=>n(e.id))},[i,r,n,e.id,e.shortcut]);return(0,G.jsxs)(`li`,{className:`flex items-center gap-3 px-4 py-3`,"aria-busy":a||void 0,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-0.5`,children:[(0,G.jsx)(`span`,{className:`font-mono text-sm`,children:e.shortcut}),(0,G.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,children:e.expansion})]}),(0,G.jsx)(`div`,{className:`ml-auto flex items-center gap-2`,children:(0,G.jsx)($r,{label:e.shortcut,onEdit:t,onDelete:o,deletePending:a})})]})}function zo({initial:e,existing:t,handlers:n,onDone:r}){let i=Po(e=>e.editorForm),a=Po(e=>e.patchEditorForm),{shortcut:o,expansion:s,submitting:c,error:l}=i,u=e!==null,d=o.trim(),f=Io.test(d),p=(0,W.useMemo)(()=>t.some(t=>t.shortcut===d&&t.id!==e?.id),[t,d,e?.id]),m=f&&!p&&s.length>0&&!c,h=()=>ii({patch:a,save:async()=>{u&&e?await n.onUpdate(e.id,{shortcut:d,expansion:s}):await n.onCreate({shortcut:d,expansion:s})},onDone:r,fallbackMessage:`Failed to save snippet`}),g=ai({submitting:c,isEdit:u,addLabel:`Add snippet`});return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 px-6 py-6`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:u?`Edit snippet`:`Add snippet`}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Shortcut`}),(0,G.jsx)(R,{value:o,onChange:e=>a({shortcut:e.target.value}),placeholder:`pgm`,className:`font-mono`,autoFocus:!0}),o.length>0&&!f&&(0,G.jsx)(`span`,{className:`text-xs text-destructive`,children:`Shortcut must be 1-32 characters with no spaces.`}),p&&(0,G.jsx)(`span`,{className:`text-xs text-destructive`,children:`A snippet with this shortcut already exists.`})]}),(0,G.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:`Expands to`}),(0,G.jsx)(ln,{value:s,onChange:e=>a({expansion:e.target.value}),placeholder:`pull request green then merge`,rows:4})]}),l&&(0,G.jsx)(`span`,{className:`text-xs text-destructive`,children:l}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(E,{onClick:()=>{A(P(`textSnippets.save`,e?.id??`new`),h)},pending:c,disabled:!m,children:g}),(0,G.jsx)(E,{variant:`ghost`,onClick:r,disabled:c,children:`Cancel`})]})]})}function Bo(e){let t=z(ut),n=ri(Fo,e.state);return(0,G.jsx)(Lo,{snippets:t,handlers:n})}function Vo(e){if(!e)return`—`;let t=e.trim();if(!t)return`—`;let n=t.slice(-4);return`${t.startsWith(`sk-ant-`)?`sk-ant-`:``}…${n}`}var Z=w()(e=>({addLabel:``,addToken:``,addBaseUrl:``,addSubmitting:!1,tokenRowStates:{},baseUrlDrafts:{},setAddLabel:t=>e({addLabel:t}),setAddToken:t=>e({addToken:t}),setAddBaseUrl:t=>e({addBaseUrl:t}),setAddSubmitting:t=>e({addSubmitting:t}),resetAddForm:()=>e({addLabel:``,addToken:``,addBaseUrl:``}),setTokenRowTesting:(t,n)=>e(e=>({tokenRowStates:{...e.tokenRowStates,[t]:{...e.tokenRowStates[t]??{testResult:null,testing:!1},testing:n}}})),setTokenRowTestResult:(t,n)=>e(e=>({tokenRowStates:{...e.tokenRowStates,[t]:{...e.tokenRowStates[t]??{testResult:null,testing:!1},testResult:n}}})),clearTokenRowState:t=>e(e=>{let{[t]:n,...r}=e.tokenRowStates;return{tokenRowStates:r}}),setBaseUrlDraft:(t,n)=>e(e=>({baseUrlDrafts:{...e.baseUrlDrafts,[t]:n}})),clearBaseUrlDraft:t=>e(e=>{let{[t]:n,...r}=e.baseUrlDrafts;return{baseUrlDrafts:r}})}));function Ho(e){if(e<=0)return`reset now`;let t=Math.ceil(e/1e3),n=Math.floor(t/60),r=t%60;return n<60?`reset in ${n}m ${r.toString().padStart(2,`0`)}s`:`reset in ${Math.floor(n/60)}h ${(n%60).toString().padStart(2,`00`)}m`}function Uo({entry:e,now:t}){if(e.status===`active`)return(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,G.jsx)(`span`,{className:`size-1.5 rounded-full bg-muted-foreground/50`,"aria-hidden":`true`}),`Active`]});if(e.status===`limited`){let n=e.limitedUntil===null?null:Ho(e.limitedUntil-t);return(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-xs text-amber-600 dark:text-amber-400`,children:[(0,G.jsx)(`span`,{className:`size-1.5 rounded-full bg-amber-500`,"aria-hidden":`true`}),`Limited`,n!==null&&(0,G.jsxs)(G.Fragment,{children:[` `,`(`,(0,G.jsx)(`span`,{className:`tabular-nums`,children:n}),`)`]})]})}if(e.status===`disabled`)return(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-xs text-muted-foreground/60`,children:[(0,G.jsx)(`span`,{className:`size-1.5 rounded-full bg-muted-foreground/30`,"aria-hidden":`true`}),`Disabled`]});let n=e.lastErrorMessage??`Unknown error`;return(0,G.jsx)(rt,{children:(0,G.jsxs)(et,{children:[(0,G.jsx)(tt,{asChild:!0,children:(0,G.jsxs)(`span`,{className:`inline-flex cursor-default items-center gap-1.5 text-xs text-destructive`,children:[(0,G.jsx)(`span`,{className:`size-1.5 rounded-full bg-destructive`,"aria-hidden":`true`}),`Error`,(0,G.jsx)(`span`,{className:`sr-only`,children:n})]})}),(0,G.jsx)(nt,{"aria-hidden":`true`,children:n})]})})}function Wo({entry:e,now:t,isCurrent:n,concurrencyDefault:r,onRemove:i,onToggleDisabled:a,onTest:o,onChangeMaxConcurrent:s,onChangeBaseUrl:c,ports:l}){let u=l?.timer??Qe,d=Z(e=>e.tokenRowStates),f=Z(e=>e.setTokenRowTesting),p=Z(e=>e.setTokenRowTestResult),m=Z(e=>e.baseUrlDrafts),h=Z(e=>e.setBaseUrlDraft),g=d[e.id],_=g?.testResult??null,v=g?.testing??!1,y=m[e.id]??e.baseUrl??``,b=y.trim().length>0&&Jt(y)===null,x=P(`oauthPool.remove`,e.id),ee=P(`oauthPool.toggle`,e.id),te=P(`oauthPool.concurrency`,e.id),ne=P(`oauthPool.baseUrl`,e.id),S=P(`oauthPool.test`,e.id),re=M(x),C=M(ee),ie=M(te),ae=M(ne),w=()=>A(ne,()=>c(e.id,y)),oe=e=>{e.key===`Enter`&&e.currentTarget.blur()},T=async()=>{f(e.id,!0),p(e.id,null);try{let t=await o(e.token,e.baseUrl),n=t.ok?`OK`:t.error??`Error`;p(e.id,n),u.setTimeout(()=>p(e.id,null),3e3)}catch{p(e.id,`Error`),u.setTimeout(()=>p(e.id,null),3e3)}finally{f(e.id,!1)}},se=e.status===`disabled`,ce=se?nr:er,E=e.maxConcurrent??r;return(0,G.jsxs)(`div`,{className:`border-t border-border py-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,G.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium ${se?`text-muted-foreground/60`:`text-foreground`}`,children:e.label}),(0,G.jsx)(`code`,{className:`text-xs font-mono text-muted-foreground`,children:Vo(e.token)}),n&&(0,G.jsx)(`span`,{className:`inline-flex shrink-0 items-center whitespace-nowrap rounded-full border border-primary/40 bg-primary/10 px-1.5 py-0.5 text-xs font-medium tracking-wide text-primary`,children:`In use`})]}),(0,G.jsx)(`div`,{className:`mt-0.5`,children:(0,G.jsx)(Uo,{entry:e,now:t})})]}),(0,G.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[(0,G.jsx)(on,{label:`Maximum concurrent chats sharing this OAuth token. Higher = risks Anthropic rate limits.`,children:(0,G.jsxs)(`label`,{className:`inline-flex items-center gap-1 text-xs text-muted-foreground`,children:[(0,G.jsx)(`span`,{children:`Concurrent`}),ie?(0,G.jsx)(N,{className:`size-3`}):null,(0,G.jsx)(R,{type:`number`,value:E,readOnly:ie,"aria-busy":ie||void 0,onChange:t=>A(te,()=>s(e.id,Rt(Number(t.target.value)))),min:1,"aria-label":`Max concurrent chats`,className:`h-7 w-14 text-xs`,disabled:se})]})}),_!==null&&(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:_}),(0,G.jsxs)(`button`,{type:`button`,"aria-label":`Test`,onClick:()=>A(S,T),disabled:v||se,"aria-busy":v||void 0,className:`inline-flex items-center gap-1 rounded px-2 py-1 text-xs text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50`,children:[v?(0,G.jsx)(N,{className:`size-3`}):(0,G.jsx)(Hn,{className:`size-3`,"aria-hidden":`true`}),`Test`]}),(0,G.jsx)(rt,{children:(0,G.jsxs)(et,{children:[(0,G.jsx)(tt,{asChild:!0,children:(0,G.jsxs)(`button`,{type:`button`,"aria-label":se?`Enable`:`Disable`,onClick:()=>A(ee,a),disabled:C,"aria-busy":C||void 0,className:`rounded p-1 text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-default`,children:[C?(0,G.jsx)(N,{}):(0,G.jsx)(ce,{"aria-hidden":`true`,className:`size-3.5`}),(0,G.jsx)(`span`,{className:`sr-only`,children:se?`Enable`:`Disable`})]})}),(0,G.jsx)(nt,{children:se?`Enable`:`Disable`})]})}),(0,G.jsxs)(`button`,{type:`button`,"aria-label":`Remove`,onClick:()=>A(x,i),disabled:re,"aria-busy":re||void 0,className:`rounded p-1 text-muted-foreground transition-colors hover:text-destructive focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-default`,children:[re?(0,G.jsx)(N,{}):(0,G.jsx)(Ve,{className:`size-3.5`,"aria-hidden":`true`}),(0,G.jsx)(`span`,{className:`sr-only`,children:`Remove`})]})]})]}),(0,G.jsx)(on,{label:`Anthropic API endpoint this token authenticates against. Leave empty for the default api.anthropic.com; set it to route this credential through a proxy.`,children:(0,G.jsxs)(`label`,{className:`mt-2 flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,G.jsx)(`span`,{className:`shrink-0`,children:`Base URL`}),ae?(0,G.jsx)(N,{className:`size-3`}):null,(0,G.jsx)(R,{value:y,readOnly:ae,"aria-busy":ae||void 0,onChange:t=>h(e.id,t.target.value),onBlur:w,onKeyDown:oe,placeholder:`(default)`,maxLength:512,"aria-label":`Anthropic base URL for ${e.label}`,className:`h-7 flex-1 text-xs font-mono`,disabled:se})]})}),b&&(0,G.jsx)(`div`,{className:`mt-1 text-xs text-destructive`,children:`Must start with http:// or https://`})]})}function Go({tokens:e,onWrite:t}){let n=Z(e=>e.addLabel),r=Z(e=>e.addToken),i=Z(e=>e.addBaseUrl),a=Z(e=>e.addSubmitting),o=Z(e=>e.setAddLabel),s=Z(e=>e.setAddToken),c=Z(e=>e.setAddBaseUrl),l=Z(e=>e.setAddSubmitting),u=Z(e=>e.resetAddForm),d=Jt(i),f=i.trim().length>0&&d===null,p=n.trim().length>0&&r.trim().length>0&&!f&&!a,m=async()=>{if(p){l(!0);try{let i={id:crypto.randomUUID(),label:n.trim(),token:r.trim(),status:`active`,limitedUntil:null,lastUsedAt:null,lastErrorAt:null,lastErrorMessage:null,addedAt:Date.now(),...d===null?{}:{baseUrl:d}};await t({tokens:[...e,i]}),u()}finally{l(!1)}}};return(0,G.jsxs)(`div`,{className:`border-t border-border pt-4`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-2 sm:flex-row sm:items-end sm:gap-3`,children:[(0,G.jsx)(`div`,{className:`flex-1`,children:(0,G.jsx)(R,{value:n,onChange:e=>o(e.target.value),placeholder:`e.g. personal`,maxLength:64,className:`text-sm`,"aria-label":`Token label`})}),(0,G.jsx)(`div`,{className:`flex-[2]`,children:(0,G.jsx)(R,{value:r,onChange:e=>s(e.target.value),type:`password`,placeholder:`sk-ant-...`,maxLength:1024,className:`text-sm font-mono`,"aria-label":`OAuth token`})}),(0,G.jsxs)(`button`,{type:`button`,onClick:()=>A(`oauthPool.add`,m),disabled:!p,"aria-busy":a||void 0,className:`inline-flex shrink-0 items-center gap-1.5 rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50`,children:[a?(0,G.jsx)(N,{}):null,`Add token`]})]}),(0,G.jsxs)(`div`,{className:`mt-2`,children:[(0,G.jsx)(R,{value:i,onChange:e=>c(e.target.value),placeholder:`Base URL — leave empty for api.anthropic.com`,maxLength:512,className:`text-sm font-mono`,"aria-label":`Anthropic base URL`}),f&&(0,G.jsx)(`div`,{className:`mt-1 text-xs text-destructive`,children:`Must start with http:// or https://`})]})]})}function Ko({tokens:e,concurrencyDefault:t,onWrite:n,onTest:r,now:i,ports:a}){let o=i??Date.now(),s=Z(e=>e.clearBaseUrlDraft),c=e.reduce((e,t)=>t.lastUsedAt!==null&&(e===null||t.lastUsedAt>(e.lastUsedAt??0))?t:e,null)?.id??null,l=t=>n({tokens:e.filter(e=>e.id!==t)}),u=t=>n({tokens:e.map(e=>e.id===t?{...e,status:e.status===`disabled`?`active`:`disabled`}:e)}),d=(t,r)=>n({tokens:e.map(e=>e.id===t?{...e,maxConcurrent:r}:e)}),f=async(t,r)=>{let i=e.find(e=>e.id===t);if(!i)return;let a=Jt(r);a===null&&r.trim().length>0||(s(t),a!==(i.baseUrl??null)&&await n({tokens:e.map(e=>{if(e.id!==t)return e;let{baseUrl:n,...r}=e;return a===null?r:{...e,baseUrl:a}})}))},p=M(`oauthPool.concurrencyDefault`),m=e=>{A(`oauthPool.concurrencyDefault`,()=>n({concurrencyDefault:Rt(e)}))};return(0,G.jsxs)(`div`,{children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-3 pb-3`,children:[(0,G.jsx)(on,{label:`Default concurrent-chat cap applied to any OAuth token whose row does not override it. Sharing across N chats burns Anthropic quota and risks 429s.`,children:(0,G.jsxs)(`label`,{className:`flex flex-col gap-0.5 text-sm`,children:[(0,G.jsx)(`span`,{className:`font-medium text-foreground`,children:`Default concurrency per token`}),(0,G.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`Cap for tokens without an explicit per-row override. Minimum `,1,`, no upper limit.`]})]})}),p?(0,G.jsx)(N,{className:`ml-auto text-muted-foreground`}):null,(0,G.jsx)(R,{type:`number`,value:t,readOnly:p,"aria-busy":p||void 0,onChange:e=>m(Number(e.target.value)),min:1,"aria-label":`Default concurrency per token`,className:`h-8 w-16 text-sm`})]}),e.map(e=>(0,G.jsx)(Wo,{entry:e,now:o,isCurrent:e.id===c,concurrencyDefault:t,onRemove:()=>l(e.id),onToggleDisabled:()=>u(e.id),onTest:r,onChangeMaxConcurrent:d,onChangeBaseUrl:f,ports:a},e.id)),(0,G.jsx)(Go,{tokens:e,onWrite:n})]})}function qo(e,t){e.key===`Enter`&&(t(),e.currentTarget.blur())}function Jo(e){let t={};for(let n of Xt)t[n]=ie(e[n]??``);return{...It,...t}}function Yo(e){return P(`settings.writeKeybindings`,e)}function Xo({action:e,currentValue:t,bordered:n,onDraftChange:r,onCommit:i,onRestoreDefault:a}){let o=Yo(e),s=M(o),c=S(It[e]),l=t!==c,u=()=>{A(o,i)};return(0,G.jsx)(q,{title:v[e],description:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`span`,{children:`Comma-separated shortcuts.`}),l?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`span`,{children:` `}),(0,G.jsxs)(`button`,{type:`button`,disabled:s,"aria-busy":s||void 0,onClick:()=>{A(o,()=>a(e))},className:`inline rounded text-foreground hover:text-foreground/80 disabled:opacity-60`,children:[`Restore: `,c]})]}):null]}),bordered:n,children:(0,G.jsxs)(`div`,{className:`flex min-w-0 max-w-[420px] flex-1 items-center gap-2`,children:[(0,G.jsx)(R,{type:`text`,value:t,"aria-busy":s||void 0,onChange:t=>r(e,t.target.value),onBlur:u,onKeyDown:e=>qo(e,u),className:`font-mono`}),s?(0,G.jsx)(N,{}):null]})})}function Zo({state:e}){let t=x(e=>e.keybindingDrafts),n=x(e=>e.setKeybindingDrafts),r=x(e=>e.setKeybindingDraft),i=x(e=>e.keybindingsError),a=x(e=>e.setKeybindingsError),o=(0,W.useMemo)(()=>h(e.keybindings),[e.keybindings]);(0,W.useEffect)(()=>{n(Object.fromEntries(Xt.map(e=>[e,S(o.bindings[e])])))},[o,n]);async function s(t){try{a(null),await e.socket.command({type:`settings.writeKeybindings`,bindings:Jo(t)})}catch(e){a(e instanceof Error?e.message:`Unable to save keybindings.`)}}async function c(){await s(t)}async function l(e){let r={...t,[e]:S(It[e])};n(r),await s(r)}return(0,G.jsxs)(`div`,{className:`border-b border-border`,children:[i?(0,G.jsx)(`div`,{className:`mb-4 rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:i}):null,o.warning?(0,G.jsx)(`div`,{className:`mb-4 rounded-lg border border-border bg-card/30 px-4 py-3 text-sm text-muted-foreground`,children:o.warning}):null,Xt.map((e,n)=>(0,G.jsx)(Xo,{action:e,currentValue:t[e]??``,bordered:n!==0,onDraftChange:r,onCommit:c,onRestoreDefault:l},e))]})}var Qo=`always`,$o=`funk`,es=[{value:`blow`,label:`Blow`},{value:`bottle`,label:`Bottle`},{value:`frog`,label:`Frog`},{value:`funk`,label:`Funk`},{value:`glass`,label:`Glass`},{value:`ping`,label:`Ping`},{value:`pop`,label:`Pop`},{value:`purr`,label:`Purr`},{value:`tink`,label:`Tink`}];function ts(e){switch(e){case`never`:case`unfocused`:case`always`:return e;default:return Qo}}function ns(e){switch(e){case`blow`:case`bottle`:case`frog`:case`funk`:case`glass`:case`ping`:case`pop`:case`purr`:case`tink`:return e;default:return $o}}var rs=w()(e=>({chatSoundPreference:Qo,chatSoundId:$o,setChatSoundPreference:t=>e({chatSoundPreference:ts(t)}),setChatSoundId:t=>e({chatSoundId:ns(t)})})),is=`inline-flex items-center justify-center rounded-lg border border-border bg-background px-3 py-1.5 text-sm font-medium text-foreground transition-colors hover:bg-muted`,as=`inline-flex items-center justify-center rounded-lg bg-foreground px-3 py-1.5 text-sm font-medium text-background transition-colors hover:bg-foreground/90`,os=`rounded bg-muted px-1 py-0.5 font-mono text-12 text-foreground`,ss=`text-xs font-medium tracking-wide text-muted-foreground`,cs=`gap-1.5 disabled:cursor-default disabled:opacity-60`,ls=`push.enable`,us=`push.test`,ds=`push.disable`,fs=`push.contactSubject`;async function ps(e){try{await e(),x.getState().setPushError(null)}catch(e){x.getState().setPushError(T(e))}}function ms(e,t){A(e,()=>ps(t))}function hs(){let e=x(e=>e.pushError);return e?(0,G.jsx)(`p`,{role:`alert`,className:`rounded-lg border border-destructive/20 bg-destructive/10 px-3 py-2 text-sm text-destructive-text`,children:e}):null}function gs({pendingKey:e,onRun:t,className:n,label:r,children:i}){let a=M(e);return(0,G.jsxs)(`button`,{type:`button`,onClick:()=>ms(e,t),disabled:a,"aria-busy":a||void 0,"aria-label":r,className:D(n,cs),children:[a?(0,G.jsx)(N,{}):null,i]})}function _s({localPath:e,muted:t,onMuteToggle:n}){let r=P(`push.setProjectMute`,e),i=M(r);return(0,G.jsxs)(`label`,{"aria-busy":i||void 0,className:`flex cursor-pointer items-center gap-3 rounded-md px-2 py-1.5 transition-colors hover:bg-muted/50`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:!t,disabled:i,onChange:t=>ms(r,()=>n(e,!t.target.checked)),className:`h-4 w-4 shrink-0 rounded border-border accent-foreground`}),(0,G.jsx)(rn,{inline:!0,className:`min-w-0 flex-1 font-mono text-12 text-foreground`,tooltip:e,children:e}),i?(0,G.jsx)(N,{className:`text-muted-foreground`}):null]})}function vs(e){let{permissionState:t}=e,n=M(fs);if(t===`unsupported`)return(0,G.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Push notifications are not supported in this browser.`});if(t===`insecure-context`)return(0,G.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[`Push requires HTTPS. Run `,(0,G.jsx)(`code`,{className:os,children:`kanna --share`}),` or open Kanna over a tunnel, then enable on this device.`]});if(t===`denied`)return(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`You blocked notifications for this site. Re-enable them in your browser settings, then reload.`}),(0,G.jsx)(hs,{})]});if(!(t===`granted`&&e.config.devices.some(t=>t.id===e.currentDeviceId)))return(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-start gap-2 md:w-[440px]`,children:[(0,G.jsx)(gs,{pendingKey:ls,onRun:e.onEnable,className:as,children:`Enable on this device`}),(0,G.jsx)(hs,{})]});let r=new Set(e.config.preferences.mutedProjectPaths),i=e.contactSubjectDraft.trim(),a=pr(i),o=i!==e.contactSubject,s=()=>{a&&o&&ms(fs,()=>e.onContactSubjectSave(i))};return(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col gap-5 md:w-[440px]`,children:[(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-2 rounded-full border border-border bg-card/40 px-3 py-1 text-xs font-medium text-foreground`,children:[(0,G.jsx)(`span`,{className:`h-1.5 w-1.5 rounded-full bg-emerald-500`,"aria-hidden":!0}),`Enabled on this device`]}),(0,G.jsx)(gs,{pendingKey:us,onRun:e.onTest,className:is,children:`Send test`}),(0,G.jsx)(gs,{pendingKey:ds,onRun:e.onDisable,className:is,children:`Disable`})]}),(0,G.jsx)(hs,{}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`div`,{className:D(ss,`flex items-center gap-1.5`),children:[`Contact for delivery`,n?(0,G.jsx)(N,{}):null]}),(0,G.jsx)(R,{type:`text`,inputMode:`email`,spellCheck:!1,autoCapitalize:`none`,value:e.contactSubjectDraft,readOnly:n,"aria-busy":n||void 0,onChange:t=>e.onContactSubjectDraftChange(t.target.value),onBlur:s,onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),s())},placeholder:`mailto:you@example.com`,"aria-label":`Push contact subject`,"aria-invalid":i!==``&&!a,className:D(`font-mono`,i!==``&&!a&&`border-destructive`)}),i!==``&&!a?(0,G.jsxs)(`p`,{className:`text-xs text-destructive`,children:[`Must be a `,(0,G.jsx)(`code`,{className:os,children:`mailto:`}),` address or`,` `,(0,G.jsx)(`code`,{className:os,children:`https:`}),` URL with a routable domain (not localhost).`]}):(0,G.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Push services require a contact `,(0,G.jsx)(`code`,{className:os,children:`mailto:`}),` or`,` `,(0,G.jsx)(`code`,{className:os,children:`https:`}),` URL to sign notifications. Set your own so delivery isn’t rejected.`]})]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsx)(`div`,{className:ss,children:`Devices`}),(0,G.jsx)(`ul`,{className:`flex flex-col gap-1.5`,children:e.config.devices.map(t=>(0,G.jsxs)(`li`,{className:`flex items-start justify-between gap-3 rounded-lg border border-border bg-card/40 px-3 py-2`,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-0.5`,children:[(0,G.jsx)(`span`,{className:`truncate text-sm font-medium text-foreground`,children:t.label}),(0,G.jsx)(`span`,{className:`line-clamp-2 break-all text-xs leading-snug text-muted-foreground`,children:t.userAgent})]}),!t.isCurrentDevice&&(0,G.jsx)(gs,{pendingKey:P(`push.unsubscribe`,t.id),onRun:()=>e.onRemoveDevice(t.id),label:`Remove ${t.label}`,className:`inline-flex shrink-0 items-center rounded-md border border-border bg-background px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,children:`Remove`})]},t.id))})]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsx)(`div`,{className:ss,children:`Per-project`}),(0,G.jsx)(`ul`,{className:`flex flex-col`,children:e.projects.map(t=>(0,G.jsx)(`li`,{children:(0,G.jsx)(_s,{localPath:t.localPath,muted:r.has(t.localPath),onMuteToggle:e.onMuteToggle})},t.localPath))})]}),(0,G.jsxs)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:[`Phone setup: this page must be reachable over HTTPS. Run`,` `,(0,G.jsx)(`code`,{className:os,children:`kanna --share`}),` or open Kanna over your tunnel on the phone, then enable on that device.`]})]})}var ys=P(`packages.checkUpdates`);function bs(e){return P(`packages.update`,e)}async function xs(e,t){try{await e.command(t),fn.getState().setCommandError(null)}catch(e){throw fn.getState().setCommandError(T(e)),e}}var Ss=[],Cs=[],ws=[],Ts=[];function Es(e){return typeof e==`object`&&!!e&&`packages`in e&&`errors`in e}var Ds={up_to_date:`Up to date`,outdated:`Outdated`,partial:`Partial`,unknown:`Unknown`};function Os({pkg:e,packageEntry:t,applying:n,onUpdate:r}){let i=M(bs(e.id)),a=n||i,o=t?.update.availability,s=e.versionLabel??e.version??e.revision?.slice(0,7)??null,c=o&&o!==`up_to_date`?ba[o]:null;return(0,G.jsxs)(`div`,{className:`flex min-w-0 items-start justify-between gap-3 rounded-lg border border-border bg-card/30 p-3`,children:[(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`div`,{className:`truncate text-sm font-medium text-foreground`,children:e.name}),s?(0,G.jsx)(`div`,{className:`font-mono tabular-nums text-xs text-muted-foreground/70`,children:s}):null]}),(0,G.jsxs)(`div`,{className:`flex shrink-0 flex-wrap items-center justify-end gap-2`,children:[c?(0,G.jsx)(`span`,{className:D(`rounded-full border px-2 py-0.5 text-xs font-medium`,c),children:Ds[o]}):null,o===`outdated`||o===`partial`?(0,G.jsxs)(E,{type:`button`,size:`sm`,variant:`secondary`,disabled:a,"aria-busy":a||void 0,onClick:r,className:`h-6 rounded-full px-2 text-xs`,children:[a?(0,G.jsx)(O,{className:`mr-1 h-3 w-3 animate-spin`}):null,`Update`]}):null,e.sourceUrl?(0,G.jsx)(`a`,{href:e.sourceUrl,target:`_blank`,rel:`noreferrer`,"aria-label":`View ${e.name} source`,className:`touch-manipulation inline-flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,children:(0,G.jsx)(Pe,{className:`h-4 w-4`})}):null]})]})}function ks({source:e,packages:t,updateEntries:n,applying:r,isChecking:i,onCheckUpdates:a,onUpdate:o}){return(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,G.jsx)(`div`,{className:`text-xs font-medium tracking-wide text-muted-foreground`,children:e}),(0,G.jsxs)(E,{size:`sm`,variant:`ghost`,className:`h-6 rounded-full px-2 text-xs`,disabled:i,"aria-busy":i||void 0,onClick:a,children:[i?(0,G.jsx)(O,{className:`mr-1 h-3 w-3 animate-spin`}):(0,G.jsx)(ze,{className:`mr-1 h-3 w-3`}),`Refresh`]})]}),(0,G.jsx)(`div`,{className:`grid gap-2 md:grid-cols-2`,children:t.map(e=>{let t=n.find(t=>t.id===e.id)??null;return(0,G.jsx)(Os,{pkg:e,packageEntry:t,applying:r.includes(e.id),onUpdate:()=>o(e.id)},e.id)})})]})}function As({label:e,kind:t,packages:n,errors:r,updateEntries:i,applying:a,isChecking:o,onCheckUpdates:s,onUpdate:c}){let l=r.find(e=>e.kind===t),u=n.filter(e=>e.kind===t),d=new Map;for(let e of u){let t=e.source||`Unknown`,n=d.get(t);n?n.push(e):d.set(t,[e])}let f=t===`claude-plugin`?`Claude Code CLI`:`Codex CLI`,p;return p=l?(0,G.jsxs)(`div`,{className:`rounded-lg border border-border bg-card/30 p-3 text-sm text-muted-foreground`,children:[f,` not found — install it to manage `,e,` plugins.`]}):u.length===0?(0,G.jsxs)(`div`,{className:`rounded-lg border border-border bg-card/30 p-3 text-sm text-muted-foreground`,children:[`No `,e,` plugins installed.`]}):(0,G.jsx)(`div`,{className:`flex flex-col gap-4`,children:[...d.entries()].map(([e,t])=>(0,G.jsx)(ks,{source:e,packages:t,updateEntries:i,applying:a,isChecking:o,onCheckUpdates:s,onUpdate:c},e))}),(0,G.jsxs)(`section`,{className:`flex flex-col gap-3`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:e}),p]})}function js({state:e}){let{socket:t,connectionStatus:n}=e,r=x(e=>e.pluginInventory),i=x(e=>e.pluginInventoryLoading),a=x(e=>e.pluginInventoryError),o=x(e=>e.setPluginInventory),s=x(e=>e.setPluginInventoryLoading),c=x(e=>e.setPluginInventoryError),l=x(e=>e.packageUpdateSnapshot),u=(0,W.useCallback)(async()=>{if(n!==`connected`){o(null),c(null),s(!1);return}try{s(!0),c(null);let e=await t.command({type:`packages.listInstalled`});if(!Es(e))throw Error(`packages.listInstalled: unexpected response`);o(e)}catch(e){c(e instanceof Error?e.message:`Unable to load plugins.`)}finally{s(!1)}},[n,t,o,s,c]);(0,W.useEffect)(()=>{wt(`packages.listInstalled`,u())},[u]);let d=(0,W.useCallback)(()=>{A(ys,()=>xs(t,{type:`packages.checkUpdates`}))},[t]),f=(0,W.useCallback)(e=>{A(bs(e),()=>xs(t,{type:`packages.update`,id:e}))},[t]),p=M(ys),m=l?.status===`checking`||p,h=l?.applying??Ts,g=l?.packages.filter(e=>e.kind===`claude-plugin`||e.kind===`codex-plugin`)??ws,_=r?.packages??Ss,v=r?.errors??Cs;return a?(0,G.jsx)(`div`,{className:`rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:a}):i&&!r?(0,G.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:[(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}),`Loading…`]}):(0,G.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,G.jsx)(As,{label:`Claude Code`,kind:`claude-plugin`,packages:_,errors:v,updateEntries:g,applying:h,isChecking:m,onCheckUpdates:d,onUpdate:f}),(0,G.jsx)(As,{label:`Codex`,kind:`codex-plugin`,packages:_,errors:v,updateEntries:g,applying:h,isChecking:m,onCheckUpdates:d,onUpdate:f})]})}function Ms(e){return e.map(e=>({...e,disabled:!0}))}function Ns({pendingKey:e,value:t,onValueChange:n,options:r,size:i}){let a=M(e);return(0,G.jsxs)(`div`,{className:`inline-flex items-center gap-2`,"aria-busy":a||void 0,children:[a?(0,G.jsx)(N,{className:`text-muted-foreground`}):null,(0,G.jsx)(L,{value:t,onValueChange:t=>A(e,()=>n(t)),options:a?Ms(r):r,size:i})]})}var Ps=w()(e=>({publicUrlDraft:null,copiedSnippetId:null,error:null,setPublicUrlDraft:t=>e({publicUrlDraft:t}),setCopiedSnippetId:t=>e({copiedSnippetId:t}),setError:t=>e({error:t})})),Fs=`<your Kanna password>`,Is=`Start Kanna with --password first; the remote MCP server is off without it. `,Ls=`The URL must be https and reachable from the internet (a Cloudflare tunnel or --share).`;function Rs(e){return`${e}/mcp`}function zs({publicOrigin:e,passwordConfigured:t}){let n=Rs(e??`https://<your-public-kanna-url>`),r=t?``:Is;return[{id:`claude-code`,client:`claude-code`,title:`Claude Code`,instructions:`${r}Add the server with your Kanna password as a bearer header, or add it without one and sign in through OAuth.`,snippet:[`claude mcp add --transport http kanna ${n} --header "Authorization: Bearer ${Fs}"`,``,`claude mcp add --transport http kanna ${n}`,`# then run /mcp inside Claude Code and choose Authenticate to sign in with OAuth`].join(`
|
|
12
12
|
`)},{id:`codex`,client:`codex`,title:`Codex`,instructions:`${r}Put the block in ~/.codex/config.toml and export your Kanna password as KANNA_PASSWORD, or sign in through OAuth instead.`,snippet:[`[mcp_servers.kanna]`,`url = "${n}"`,`bearer_token_env_var = "KANNA_PASSWORD"`,``,`# OAuth alternative: drop bearer_token_env_var and run`,`codex mcp login kanna`].join(`
|
|
13
13
|
`)},{id:`claude-desktop`,client:`claude-desktop`,title:`Claude Desktop and claude.ai`,instructions:`${r}Open Settings, Connectors, Add custom connector and enter the URL. Add the request header below, or leave it empty to sign in through OAuth. ${Ls}`,snippet:[`URL: ${n}`,`Header: Authorization: Bearer ${Fs}`].join(`
|
|
14
14
|
`)},{id:`chatgpt`,client:`chatgpt`,title:`ChatGPT`,instructions:`${r}Open chatgpt.com/plugins, select the plus button, then Add custom MCP server; enter the URL and choose OAuth as the authentication. ${Ls}`,snippet:[`URL: ${n}`,`Authentication: OAuth`].join(`
|
|
15
15
|
`)}]}var Bs=P(`settings.remoteMcp`,`enabled`),Vs=P(`settings.remoteMcp`,`publicUrl`),Hs=2e3,Us=[{value:`enabled`,label:`Enabled`},{value:`disabled`,label:`Disabled`}];function Ws(e){try{return new URL(e).origin}catch{return``}}function Gs({snippet:e}){let t=Ps(t=>t.copiedSnippetId===e.id),n=Ps(e=>e.setCopiedSnippetId),r=(0,W.useCallback)(async()=>{await De.writeText(e.snippet),n(e.id),Qe.setTimeout(()=>n(null),Hs)},[e.id,e.snippet,n]);return(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-2 rounded-lg border border-border bg-card/30 p-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:e.title}),(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`icon-mobile`,"aria-label":t?`Copied ${e.title} setup`:`Copy ${e.title} setup`,className:`text-muted-foreground hover:text-foreground`,onClick:()=>wt(`copy remote MCP setup`,r()),children:t?(0,G.jsx)(Ee,{className:`h-4 w-4 text-success-text`}):(0,G.jsx)(Te,{className:`h-4 w-4`})})]}),(0,G.jsx)(`p`,{className:`text-13 text-muted-foreground`,children:e.instructions}),(0,G.jsx)(`pre`,{className:`max-h-64 overflow-auto whitespace-pre-wrap break-all rounded-md border border-border bg-muted p-2 font-mono text-xs text-foreground`,children:e.snippet})]})}function Ks({state:e,dom:t=oe}){let n=z(_t),r=x(e=>e.authEnabled),i=Ps(e=>e.publicUrlDraft),a=Ps(e=>e.setPublicUrlDraft),o=Ps(e=>e.error),s=Ps(e=>e.setError),c=M(Vs),l=i??n.publicUrl??``,u=l.trim(),d=u!==``&&it(u)===null,f=u!==(n.publicUrl??``),p=n.publicUrl??it(Ws(t.getHref())),m=zs({publicOrigin:p,passwordConfigured:r}),h=(0,W.useCallback)(t=>e.handleWriteAppSettings({remoteMcp:{enabled:t===`enabled`}}),[e]),g=(0,W.useCallback)(async()=>{s(null);try{await e.handleWriteAppSettings({remoteMcp:{publicUrl:u===``?null:u}}),a(null)}catch(e){s(T(e))}},[e,u,a,s]);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-1 pb-2`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:`Remote MCP`}),(0,G.jsx)(`p`,{className:`max-w-[65ch] text-sm text-muted-foreground`,children:`Let other agents and apps drive Kanna over the Model Context Protocol: Claude Code, Codex, Claude Desktop and ChatGPT can list projects, run chats, move board cards and more.`})]}),r?null:(0,G.jsx)(`div`,{className:`rounded-lg border border-border bg-card/30 px-4 py-3 text-sm text-muted-foreground`,children:`Set --password when starting Kanna to enable the remote MCP server`}),(0,G.jsxs)(`div`,{className:`border-b border-border`,children:[(0,G.jsx)(q,{title:`Remote MCP server`,description:`Serves the /mcp endpoint and the OAuth sign-in pages. Turn it off to answer 404 on all of them.`,children:(0,G.jsx)(Ns,{pendingKey:Bs,value:n.enabled?`enabled`:`disabled`,onValueChange:h,options:Us,size:`sm`})}),(0,G.jsx)(q,{title:`Public URL`,description:`https URL, or http on localhost; the OAuth issuer and resource are derived from it. Leave empty to use this machine's loopback address.`,alignStart:!0,children:(0,G.jsxs)(`div`,{className:`flex w-full flex-col gap-2 md:w-[420px]`,children:[(0,G.jsx)(R,{value:l,onChange:e=>a(e.target.value),placeholder:`https://kanna.example.com`,"aria-label":`Public URL`,"aria-invalid":d||void 0,spellCheck:!1}),(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2 text-xs`,children:[(0,G.jsx)(`span`,{className:d?`text-destructive-text`:`text-muted-foreground`,children:d?`Enter an https URL, or an http URL on localhost`:`Path, query and trailing slash are dropped`}),(0,G.jsx)(E,{type:`button`,size:`sm`,disabled:!f||d,onClick:()=>A(Vs,g),pending:c,children:`Save`})]}),o?(0,G.jsx)(`div`,{className:`text-xs text-destructive-text`,children:o}):null]})}),(0,G.jsx)(q,{title:`Endpoint`,description:`Give this URL to your MCP client.`,bordered:!0,children:p?(0,G.jsxs)(`code`,{className:`break-all rounded-md border border-border bg-muted px-2 py-1 font-mono text-xs`,children:[p,`/mcp`]}):(0,G.jsx)(`span`,{className:`text-13 text-muted-foreground`,children:`Set a public URL to see the endpoint`})})]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-3 pt-4`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`Connect a client`}),(0,G.jsx)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:m.map(e=>(0,G.jsx)(Gs,{snippet:e},e.id))})]})]})}var qs={disabled:`Disabled`,installing:`Installing`,starting:`Starting`,connecting:`Connecting`,connected:`Connected`,reconnecting:`Reconnecting`,restarting:`Restarting`,error:`Error`},Js={disabled:`muted`,installing:`attention`,starting:`attention`,connecting:`attention`,connected:`muted`,reconnecting:`attention`,restarting:`attention`,error:`destructive`};function Ys(e){return qs[e]}function Xs(e){return Js[e]}var Zs=[`B`,`KB`,`MB`,`GB`,`TB`];function Qs(e){let t=e,n=0;for(;t>=1024&&n<Zs.length-1;)t/=1024,n+=1;let r=n===0||t>=100?0:1;return`${t.toFixed(r)} ${Zs[n]}`}var Q=w()(e=>({connection:null,stream:null,embedded:null,consumerEditor:null,resetConfirm:!1,error:null,editConnection:(t,n)=>e(e=>({connection:{...e.connection??t,...n}})),discardConnection:()=>e({connection:null}),editStream:(t,n)=>e(e=>({stream:{...e.stream??t,...n}})),discardStream:()=>e({stream:null}),editEmbedded:(t,n)=>e(e=>({embedded:{...e.embedded??t,...n}})),discardEmbedded:()=>e({embedded:null}),openConsumerEditor:(t,n)=>e({consumerEditor:{target:t,draft:n}}),editConsumer:t=>e(e=>e.consumerEditor===null?e:{consumerEditor:{...e.consumerEditor,draft:{...e.consumerEditor.draft,...t}}}),closeConsumerEditor:()=>e({consumerEditor:null}),askResetConfirm:()=>e({resetConfirm:!0}),cancelResetConfirm:()=>e({resetConfirm:!1}),setError:t=>e({error:t})})),$s=`auto`;function ec(e){return{name:e.name,subjectPrefix:e.subjectPrefix,extraSubjects:e.extraSubjects.join(`
|
|
16
16
|
`),retention:e.retention,storage:e.storage,maxAgeDays:String(e.maxAgeDays),maxBytesMb:String(e.maxBytesMb),maxMsgs:String(e.maxMsgs),discard:e.discard,duplicateWindowSec:String(e.duplicateWindowSec),replicas:String(e.replicas)}}function tc(e){return e.trim()===``?NaN:Number(e)}function nc(e){return{name:e.name.trim(),subjectPrefix:e.subjectPrefix.trim(),extraSubjects:e.extraSubjects.split(`
|
|
17
|
-
`).map(e=>e.trim()).filter(e=>e.length>0),retention:e.retention,storage:e.storage,maxAgeDays:tc(e.maxAgeDays),maxBytesMb:tc(e.maxBytesMb),maxMsgs:tc(e.maxMsgs),discard:e.discard,duplicateWindowSec:tc(e.duplicateWindowSec),replicas:tc(e.replicas)}}function rc(e){return{durableName:e.durableName,filterSubject:e.filterSubject,ackPolicy:e.ackPolicy,deliverPolicy:e.deliverPolicy,maxAckPending:String(e.maxAckPending),ackWaitSec:String(e.ackWaitSec)}}function ic(e){return{durableName:``,filterSubject:`${e}.>`,ackPolicy:`explicit`,deliverPolicy:`all`,maxAckPending:`1000`,ackWaitSec:`30`}}function ac(e){return{durableName:e.durableName.trim(),filterSubject:e.filterSubject.trim(),ackPolicy:e.ackPolicy,deliverPolicy:e.deliverPolicy,maxAckPending:tc(e.maxAckPending),ackWaitSec:tc(e.ackWaitSec)}}function oc(e){return{maxMemoryStoreMb:String(e.maxMemoryStoreMb),maxFileStoreMb:String(e.maxFileStoreMb),port:String(e.port),logLevel:e.logLevel}}function sc(e){let t=e.port.trim().toLowerCase()===`auto`?$s:tc(e.port);return{maxMemoryStoreMb:tc(e.maxMemoryStoreMb),maxFileStoreMb:tc(e.maxFileStoreMb),port:t,logLevel:e.logLevel}}function cc(e,t){return Ct({...e,...t})}function lc(e,t){let n=[];return e.retention!==t.retention&&n.push(`retention`),e.storage!==t.storage&&n.push(`storage`),e.replicas!==t.replicas&&n.push(`replicas`),n}function uc(e,t){return t.maxAgeDays<e.maxAgeDays||t.maxBytesMb<e.maxBytesMb}function dc(e,t){return JSON.stringify(ec(e))===JSON.stringify(t)}function $({label:e,note:t,warn:n=!1,children:r}){return(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-1.5`,children:[(0,G.jsx)(`div`,{className:`text-13 font-medium text-foreground`,children:e}),r,t?(0,G.jsx)(`div`,{className:D(`text-xs`,n?`text-warning-text`:`text-muted-foreground`),children:t}):null]})}function fc({label:e,value:t}){return(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col`,children:[(0,G.jsx)(`dt`,{className:`text-xs text-muted-foreground`,children:e}),(0,G.jsx)(`dd`,{className:`font-mono text-13 tabular-nums text-foreground`,children:t})]})}function pc({problems:e}){return e.length===0?null:(0,G.jsx)(`ul`,{className:`flex flex-col gap-0.5 text-xs text-destructive-text`,role:`alert`,children:e.map(e=>(0,G.jsx)(`li`,{children:e},e))})}var mc=P(`settings.serviceBus`,`consumers`),hc=[{value:`explicit`,label:`Explicit`},{value:`all`,label:`All`},{value:`none`,label:`None`}],gc=[{value:`all`,label:`All`},{value:`new`,label:`New`},{value:`last`,label:`Last`}];function _c({consumer:e,onEdit:t,onRemove:n}){let r=g(t=>t.status.consumers.find(t=>t.name===e.durableName)),i=M(P(`settings.serviceBus`,`consumer`,e.durableName));return(0,G.jsxs)(`li`,{className:`flex flex-col gap-1 px-4 py-3 md:flex-row md:items-center md:justify-between`,children:[(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`div`,{className:`truncate text-sm font-medium text-foreground`,children:e.durableName}),(0,G.jsxs)(`div`,{className:`truncate font-mono text-xs text-muted-foreground`,children:[e.filterSubject||`all subjects`,` · ack `,e.ackPolicy,` · deliver `,e.deliverPolicy]})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsx)(`span`,{className:`font-mono text-xs tabular-nums text-muted-foreground`,children:r?`${String(r.pending)} pending · ${String(r.ackPending)} ack pending`:`not reported yet`}),(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`icon-sm`,"aria-label":`Edit ${e.durableName}`,onClick:t,children:(0,G.jsx)(Le,{className:`h-4 w-4`})}),(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`icon-sm`,"aria-label":`Remove ${e.durableName}`,pending:i,onClick:n,children:(0,G.jsx)(He,{className:`h-4 w-4`})})]})]})}function vc({state:e}){let t=z(dt);g(ne);let n=Q(e=>e.consumerEditor),r=Q(e=>e.openConsumerEditor),i=Q(e=>e.editConsumer),a=Q(e=>e.closeConsumerEditor),o=Q(e=>e.setError),s=M(mc),c=(0,W.useCallback)(async t=>{o(null);try{await e.handleWriteAppSettings({serviceBus:{consumers:t}}),a()}catch(e){o(T(e))}},[e,a,o]),l=n?ac(n.draft):null,u=n?.target.kind===`edit`?n.target.durableName:null,d=t.consumers.filter(e=>e.durableName!==u),f=l?cc(t,{consumers:[...d,l]}):[],p=(0,W.useCallback)(async()=>{if(l===null)return;let e=t.consumers.map(e=>e.durableName===u?l:e);await c(u===null?[...t.consumers,l]:e)},[l,u,t.consumers,c]);return(0,G.jsxs)(`details`,{className:`rounded-lg border border-border`,children:[(0,G.jsxs)(`summary`,{className:`cursor-pointer px-4 py-3 text-sm font-medium text-foreground`,children:[`Consumers `,(0,G.jsx)(`span`,{className:`font-mono text-xs tabular-nums text-muted-foreground`,children:t.consumers.length})]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-3 border-t border-border py-3`,children:[(0,G.jsx)(`p`,{className:`px-4 text-13 text-muted-foreground`,children:`Durable pull consumers Kanna creates on the stream. Kanna removes only the ones it created, and never touches consumers you add elsewhere.`}),t.consumers.length===0?(0,G.jsx)(`div`,{className:`px-4 text-13 text-muted-foreground`,children:`No consumers configured`}):(0,G.jsx)(`ul`,{className:`flex flex-col divide-y divide-border border-y border-border`,children:t.consumers.map(e=>(0,G.jsx)(_c,{consumer:e,onEdit:()=>r({kind:`edit`,durableName:e.durableName},rc(e)),onRemove:()=>A(P(`settings.serviceBus`,`consumer`,e.durableName),()=>c(t.consumers.filter(t=>t.durableName!==e.durableName)))},e.durableName))}),n?(0,G.jsxs)(`div`,{className:`mx-4 flex flex-col gap-4 rounded-lg border border-border p-4`,children:[(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-2`,children:[(0,G.jsx)($,{label:`Durable name`,children:(0,G.jsx)(R,{"aria-label":`Durable name`,value:n.draft.durableName,disabled:u!==null,onChange:e=>i({durableName:e.target.value}),spellCheck:!1})}),(0,G.jsx)($,{label:`Filter subject`,note:`Leave empty for every subject in the stream`,children:(0,G.jsx)(R,{"aria-label":`Filter subject`,value:n.draft.filterSubject,onChange:e=>i({filterSubject:e.target.value}),spellCheck:!1})})]}),(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-2`,children:[(0,G.jsx)($,{label:`Acknowledgement`,note:u===null?void 0:`Cannot change on an existing consumer; remove and add it again`,children:(0,G.jsx)(L,{size:`sm`,value:n.draft.ackPolicy,onValueChange:e=>i({ackPolicy:e}),options:hc})}),(0,G.jsx)($,{label:`Deliver`,children:(0,G.jsx)(L,{size:`sm`,value:n.draft.deliverPolicy,onValueChange:e=>i({deliverPolicy:e}),options:gc})}),(0,G.jsx)($,{label:`Max ack pending`,children:(0,G.jsx)(R,{"aria-label":`Max ack pending`,inputMode:`numeric`,className:`tabular-nums`,value:n.draft.maxAckPending,onChange:e=>i({maxAckPending:e.target.value})})}),(0,G.jsx)($,{label:`Ack wait (s)`,children:(0,G.jsx)(R,{"aria-label":`Ack wait in seconds`,inputMode:`numeric`,className:`tabular-nums`,value:n.draft.ackWaitSec,onChange:e=>i({ackWaitSec:e.target.value})})})]}),(0,G.jsx)(pc,{problems:f}),(0,G.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`sm`,disabled:s,onClick:a,children:`Cancel`}),(0,G.jsx)(E,{type:`button`,size:`sm`,disabled:f.length>0,pending:s,onClick:()=>A(mc,p),children:`Save consumer`})]})]}):(0,G.jsx)(`div`,{className:`px-4`,children:(0,G.jsxs)(E,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>r({kind:`new`},ic(t.stream.subjectPrefix)),children:[(0,G.jsx)(Re,{className:`mr-1.5 h-4 w-4`}),`Add consumer`]})})]})]})}var yc=P(`settings.serviceBus`,`embedded`),bc=P(`serviceBus.resetStore`),xc=[{value:`info`,label:`Info`},{value:`debug`,label:`Debug`}];function Sc({state:e}){let t=sn(),n=z(dt),r=oc(n.embedded),i=Q(e=>e.embedded)??r,a=Q(e=>e.editEmbedded),o=Q(e=>e.discardEmbedded),s=Q(e=>e.resetConfirm),c=Q(e=>e.askResetConfirm),l=Q(e=>e.cancelResetConfirm),u=Q(e=>e.setError),d=M(yc),f=M(bc),p=cc(n,{embedded:sc(i)}),m=JSON.stringify(r)!==JSON.stringify(i),h=e=>a(r,e),g=(0,W.useCallback)(async()=>{u(null);try{await e.handleWriteAppSettings({serviceBus:{embedded:sc(i)}}),o()}catch(e){u(T(e))}},[e,i,o,u]),_=(0,W.useCallback)(async()=>{u(null);try{await wn(t,{type:`serviceBus.resetStore`})}catch(e){u(T(e))}finally{l()}},[t,l,u]);return(0,G.jsxs)(`details`,{className:`rounded-lg border border-border`,children:[(0,G.jsx)(`summary`,{className:`cursor-pointer px-4 py-3 text-sm font-medium text-foreground`,children:`Embedded server`}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 border-t border-border px-4 py-4`,children:[(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-3`,children:[(0,G.jsx)($,{label:`Memory store (MB)`,children:(0,G.jsx)(R,{"aria-label":`Memory store in megabytes`,inputMode:`numeric`,className:`tabular-nums`,value:i.maxMemoryStoreMb,onChange:e=>h({maxMemoryStoreMb:e.target.value})})}),(0,G.jsx)($,{label:`File store (MB)`,children:(0,G.jsx)(R,{"aria-label":`File store in megabytes`,inputMode:`numeric`,className:`tabular-nums`,value:i.maxFileStoreMb,onChange:e=>h({maxFileStoreMb:e.target.value})})}),(0,G.jsx)($,{label:`Port`,note:`auto picks a free loopback port`,children:(0,G.jsx)(R,{"aria-label":`Port`,inputMode:`numeric`,className:`tabular-nums`,value:i.port,onChange:e=>h({port:e.target.value})})})]}),(0,G.jsx)($,{label:`Server log level`,children:(0,G.jsx)(L,{size:`sm`,value:i.logLevel,onValueChange:e=>h({logLevel:e}),options:xc})}),(0,G.jsx)(pc,{problems:p}),(0,G.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`sm`,disabled:!m||d,onClick:o,children:`Revert`}),(0,G.jsx)(E,{type:`button`,size:`sm`,disabled:!m||p.length>0,pending:d,onClick:()=>A(yc,g),children:`Save server`})]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-2 border-t border-border pt-4`,children:[(0,G.jsx)(`div`,{className:`text-13 font-medium text-foreground`,children:`Reset store`}),(0,G.jsx)(`p`,{className:`text-13 text-muted-foreground`,children:`Stops the embedded server, deletes every message it holds and starts it again. Kanna's own history is not touched.`}),s?(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(E,{type:`button`,variant:`destructive`,size:`sm`,pending:f,onClick:()=>A(bc,_),children:`Delete the store`}),(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`sm`,disabled:f,onClick:l,children:`Cancel`})]}):(0,G.jsx)(`div`,{children:(0,G.jsx)(E,{type:`button`,variant:`outline`,size:`sm`,onClick:c,children:`Reset store`})})]})]})]})}var Cc=P(`settings.serviceBus`,`stream`),wc=`Changing this requires recreating the stream`,Tc=`Lowering this drops older messages`,Ec=[{value:`limits`,label:`Limits`},{value:`interest`,label:`Interest`},{value:`workqueue`,label:`Work queue`}],Dc=[{value:`file`,label:`File`},{value:`memory`,label:`Memory`}],Oc=[{value:`old`,label:`Oldest`},{value:`new`,label:`Newest`}];function kc({state:e}){let t=z(dt),n=ec(t.stream),r=Q(e=>e.stream)??n,i=Q(e=>e.editStream),a=Q(e=>e.discardStream),o=Q(e=>e.setError),s=M(Cc),c=nc(r),l=cc(t,{stream:c}),u=!dc(t.stream,r),d=lc(t.stream,c),f=uc(t.stream,c),p=e=>i(n,e),m=(0,W.useCallback)(async()=>{o(null);try{await e.handleWriteAppSettings({serviceBus:{stream:nc(r)}}),a()}catch(e){o(T(e))}},[e,r,a,o]);return(0,G.jsxs)(`details`,{className:`rounded-lg border border-border`,children:[(0,G.jsx)(`summary`,{className:`cursor-pointer px-4 py-3 text-sm font-medium text-foreground`,children:`Stream`}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 border-t border-border px-4 py-4`,children:[(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-2`,children:[(0,G.jsx)($,{label:`Stream name`,children:(0,G.jsx)(R,{"aria-label":`Stream name`,value:r.name,onChange:e=>p({name:e.target.value}),spellCheck:!1})}),(0,G.jsx)($,{label:`Subject prefix`,note:`Kanna publishes under ${r.subjectPrefix||`…`}.>`,children:(0,G.jsx)(R,{"aria-label":`Subject prefix`,value:r.subjectPrefix,onChange:e=>p({subjectPrefix:e.target.value}),spellCheck:!1})})]}),(0,G.jsx)($,{label:`Extra subjects`,note:`One per line; the stream also captures these`,children:(0,G.jsx)(ln,{"aria-label":`Extra subjects`,rows:2,value:r.extraSubjects,onChange:e=>p({extraSubjects:e.target.value}),spellCheck:!1})}),(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-3`,children:[(0,G.jsx)($,{label:`Retention`,note:wc,warn:d.includes(`retention`),children:(0,G.jsx)(L,{size:`sm`,value:r.retention,onValueChange:e=>p({retention:e}),options:Ec})}),(0,G.jsx)($,{label:`Storage`,note:wc,warn:d.includes(`storage`),children:(0,G.jsx)(L,{size:`sm`,value:r.storage,onValueChange:e=>p({storage:e}),options:Dc})}),(0,G.jsx)($,{label:`Replicas`,note:wc,warn:d.includes(`replicas`),children:(0,G.jsx)(R,{"aria-label":`Replicas`,inputMode:`numeric`,className:`tabular-nums`,value:r.replicas,onChange:e=>p({replicas:e.target.value})})})]}),(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-3`,children:[(0,G.jsx)($,{label:`Max age (days)`,note:Tc,warn:f,children:(0,G.jsx)(R,{"aria-label":`Max age in days`,inputMode:`numeric`,className:`tabular-nums`,value:r.maxAgeDays,onChange:e=>p({maxAgeDays:e.target.value})})}),(0,G.jsx)($,{label:`Max bytes (MB)`,note:Tc,warn:f,children:(0,G.jsx)(R,{"aria-label":`Max bytes in megabytes`,inputMode:`numeric`,className:`tabular-nums`,value:r.maxBytesMb,onChange:e=>p({maxBytesMb:e.target.value})})}),(0,G.jsx)($,{label:`Max messages`,note:`-1 means unlimited`,children:(0,G.jsx)(R,{"aria-label":`Max messages`,inputMode:`numeric`,className:`tabular-nums`,value:r.maxMsgs,onChange:e=>p({maxMsgs:e.target.value})})})]}),(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-3`,children:[(0,G.jsx)($,{label:`When full, discard`,children:(0,G.jsx)(L,{size:`sm`,value:r.discard,onValueChange:e=>p({discard:e}),options:Oc})}),(0,G.jsx)($,{label:`Duplicate window (s)`,note:`Messages with the same id inside this window are stored once`,children:(0,G.jsx)(R,{"aria-label":`Duplicate window in seconds`,inputMode:`numeric`,className:`tabular-nums`,value:r.duplicateWindowSec,onChange:e=>p({duplicateWindowSec:e.target.value})})})]}),(0,G.jsx)(pc,{problems:l}),(0,G.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`sm`,disabled:!u||s,onClick:a,children:`Revert`}),(0,G.jsx)(E,{type:`button`,size:`sm`,disabled:!u||l.length>0,pending:s,onClick:()=>A(Cc,m),children:`Save stream`})]})]})]})}var Ac=P(`settings.serviceBus`,`enabled`),jc=P(`settings.serviceBus`,`mode`),Mc=P(`settings.serviceBus`,`start`),Nc=P(`settings.serviceBus`,`connection`),Pc=P(`settings.serviceBus`,`token`),Fc=[{value:`enabled`,label:`Enabled`},{value:`disabled`,label:`Disabled`}],Ic=[{value:`embedded`,label:`Embedded`},{value:`external`,label:`External`}];function Lc(){let e=g(ne),t=e=>e.toLocaleString(`en-US`);return(0,G.jsxs)(`dl`,{className:`grid grid-cols-2 gap-x-6 gap-y-3 md:grid-cols-4`,children:[e.stream?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(fc,{label:`Messages`,value:t(e.stream.messages)}),(0,G.jsx)(fc,{label:`Size`,value:Qs(e.stream.bytes)}),(0,G.jsx)(fc,{label:`First seq`,value:t(e.stream.firstSeq)}),(0,G.jsx)(fc,{label:`Last seq`,value:t(e.stream.lastSeq)})]}):null,(0,G.jsx)(fc,{label:`Published`,value:t(e.published)}),(0,G.jsx)(fc,{label:`Dropped`,value:t(e.dropped)}),(0,G.jsx)(fc,{label:`Queued`,value:t(e.queued)}),e.serverVersion?(0,G.jsx)(fc,{label:`Server`,value:`v${e.serverVersion}${e.port?` · :${String(e.port)}`:``}`}):null]})}function Rc({state:e}){let t=z(dt),n=Q(e=>e.connection)??{url:t.url,token:``},r=Q(e=>e.editConnection),i=Q(e=>e.discardConnection),a=Q(e=>e.setError),o=M(Nc),s=M(Pc),c=n.url.trim(),l=cc({...t,mode:`external`},{url:c}),u=c!==t.url,d=(0,W.useCallback)(async()=>{a(null);try{await e.handleWriteAppSettings({serviceBus:{url:c}}),i()}catch(e){a(T(e))}},[e,c,i,a]),f=(0,W.useCallback)(async t=>{a(null);try{await e.handleWriteAppSettings({serviceBus:{token:t}}),i()}catch(e){a(T(e))}},[e,i,a]),p={url:t.url,token:``};return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 border-t border-border py-5`,children:[(0,G.jsx)($,{label:`Server URL`,note:`Where your own nats-server listens, for example nats://nats.internal:4222`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(R,{"aria-label":`Server URL`,value:n.url,onChange:e=>r(p,{url:e.target.value}),spellCheck:!1}),(0,G.jsx)(E,{type:`button`,size:`sm`,disabled:!u||l.length>0,pending:o,onClick:()=>A(Nc,d),children:`Save`})]})}),(0,G.jsx)($,{label:`Token`,note:t.tokenHint?`A token ending in ${t.tokenHint} is stored. Kanna never shows it again.`:`No token stored`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(R,{"aria-label":`Token`,type:`password`,autoComplete:`off`,value:n.token,placeholder:t.tokenHint?`Enter a new token to replace it`:`Token`,onChange:e=>r(p,{token:e.target.value})}),(0,G.jsx)(E,{type:`button`,size:`sm`,disabled:n.token.trim()===``,pending:s,onClick:()=>A(Pc,()=>f(n.token.trim())),children:`Replace token`}),(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`sm`,disabled:t.tokenHint===null,onClick:()=>A(Pc,()=>f(null)),children:`Clear`})]})}),(0,G.jsx)(pc,{problems:l})]})}function zc({state:e}){let t=z(dt),n=g(ne),r=Q(e=>e.error),i=Q(e=>e.setError),a=M(Mc),o=(0,W.useCallback)(async t=>{i(null);try{await e.handleWriteAppSettings({serviceBus:t})}catch(e){i(T(e))}},[e,i]),s=(0,W.useCallback)(e=>o({enabled:e===`enabled`}),[o]),c=(0,W.useCallback)(e=>o({mode:e}),[o]),l=(0,W.useCallback)(async()=>{t.enabled&&await o({enabled:!1}),await o({enabled:!0})},[t.enabled,o]),u=t.mode===`embedded`,d=u&&(!t.enabled||n.state===`error`);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-1 pb-2`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:`Service bus`}),(0,G.jsx)(`p`,{className:`max-w-[65ch] text-sm text-muted-foreground`,children:`Mirror every durable event Kanna records into a NATS JetStream stream, so other programs can read them with the nats CLI or any NATS client. Kanna's own history is not affected, and a bus outage never blocks a chat.`}),(0,G.jsx)(`p`,{className:`max-w-[65ch] text-13 text-muted-foreground`,children:`Embedded mode downloads nats-server v2.15.1 (~7 MB) from GitHub on first start and runs it on loopback with a private token.`})]}),(0,G.jsxs)(`div`,{className:`border-b border-border`,children:[(0,G.jsx)(q,{title:`Mirror to NATS`,description:`When off, nothing is downloaded, started or published.`,children:(0,G.jsx)(Ns,{pendingKey:Ac,value:t.enabled?`enabled`:`disabled`,onValueChange:s,options:Fc,size:`sm`})}),(0,G.jsx)(q,{title:`Server`,description:`Embedded runs a nats-server that Kanna manages. External connects to one you run.`,children:(0,G.jsx)(Ns,{pendingKey:jc,value:t.mode,onValueChange:c,options:Ic,size:`sm`})}),(0,G.jsx)(q,{title:`Status`,description:n.lastError?(0,G.jsx)(`span`,{className:`text-destructive-text`,children:n.lastError}):`Live state of the mirror.`,alignStart:!0,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsx)(hn,{tone:Xs(n.state),label:Ys(n.state)}),d?(0,G.jsx)(E,{type:`button`,size:`sm`,pending:a,onClick:()=>A(Mc,l),children:t.enabled?`Retry`:`Install & start`}):null]})})]}),r?(0,G.jsx)(`div`,{className:`text-xs text-destructive-text`,role:`alert`,children:r}):null,t.enabled||n.state!==`disabled`?(0,G.jsx)(`div`,{className:`py-3`,children:(0,G.jsx)(Lc,{})}):null,u?null:(0,G.jsx)(Rc,{state:e}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-3 pt-2`,children:[(0,G.jsx)(kc,{state:e}),(0,G.jsx)(vc,{state:e}),u?(0,G.jsx)(Sc,{state:e}):null]})]})}function Bc(e){let{pushConfig:t,socket:n}=e,r=x(e=>e.pushDeviceId),i=x(e=>e.setPushDeviceId),a=x(e=>e.setPushPermissionState);return{handleEnablePush:(0,W.useCallback)(async()=>{if(t)try{let e=await dn({vapidPublicKey:t.vapidPublicKey,sendToServer:async e=>{let t=await n.command({type:`push.subscribe`,subscription:e.subscription,label:e.label,userAgent:e.userAgent});return cn(t.id),{id:t.id}}});i(e)}finally{a(an().state)}},[t,n,i,a]),handleDisablePush:(0,W.useCallback)(async()=>{r&&(await nn({pushDeviceId:r,sendToServer:async e=>{await n.command({type:`push.unsubscribe`,pushDeviceId:e})}}),un(),i(null))},[r,n,i])}}function Vc(e){return e===`openai`?lr:e===`openrouter`?tn:``}function Hc(e,t){return{...e,provider:t,model:Vc(t),baseUrl:t===`custom`?e.baseUrl:``}}function Uc(e,t){if(!e.pinnedRef)return null;let n=t.latestVersion;return!n||n===e.pinnedRef?null:n}var Wc={up_to_date:`Up to date`,outdated:`Outdated`,partial:`Partial`,unknown:`Unknown`};function Gc(e){if(!e)return null;let t=Uc(e,e.update);if(t)return`Re-pin to ${t}`;if(e.pinnedRef)return null;let n=e.update.availability;return n===`outdated`||n===`partial`?`Update`:null}function Kc({skill:e,packageEntry:t,uninstalling:n,applying:r,onUninstall:i,onUpdate:a}){let o=e.source?`https://skills.sh/${e.source}/${e.name}`:null,s=t?.update.availability,c=t?.versionLabel??t?.revision?.slice(0,7)??t?.updatedAt??null,l=s&&s!==`up_to_date`?ba[s]:null,u=t?.pinnedRef??null,d=Gc(t);return(0,G.jsxs)(`div`,{className:`flex min-w-0 items-start justify-between gap-3 rounded-lg border border-border bg-card/30 p-3`,children:[(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`div`,{className:`truncate text-sm font-medium text-foreground`,children:e.name}),(0,G.jsx)(`div`,{className:`truncate text-xs text-muted-foreground`,children:e.source||`Unknown source`}),c?(0,G.jsx)(`div`,{className:`font-mono tabular-nums text-xs text-muted-foreground/70`,children:c}):null,u?(0,G.jsxs)(`div`,{className:`truncate font-mono tabular-nums text-xs text-muted-foreground/70`,children:[`Pinned `,u]}):null]}),(0,G.jsxs)(`div`,{className:`flex shrink-0 flex-wrap items-center justify-end gap-2`,children:[l?(0,G.jsx)(`span`,{className:D(`rounded-full border px-2 py-0.5 text-xs font-medium`,l),children:Wc[s]}):null,d?(0,G.jsxs)(E,{type:`button`,size:`sm`,variant:`secondary`,disabled:r,onClick:a,className:`h-6 rounded-full px-2 text-xs`,children:[r?(0,G.jsx)(O,{className:`mr-1 h-3 w-3 animate-spin`}):null,d]}):null,o?(0,G.jsx)(`a`,{href:o,target:`_blank`,rel:`noreferrer`,"aria-label":`View ${e.name} on skills.sh`,className:`touch-manipulation inline-flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,children:(0,G.jsx)(Pe,{className:`h-4 w-4`})}):null,(0,G.jsx)(`button`,{type:`button`,"aria-label":`Uninstall ${e.name}`,disabled:n,onClick:i,className:`touch-manipulation inline-flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none disabled:opacity-50`,children:n?(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}):(0,G.jsx)(He,{className:`h-4 w-4`})})]})]})}function qc(e){return!e||e<=0?`0 installs`:e>=1e6?`${(e/1e6).toFixed(1).replace(/\.0$/,``)}M installs`:e>=1e3?`${(e/1e3).toFixed(1).replace(/\.0$/,``)}K installs`:`${e} install${e===1?``:`s`}`}var Jc=P(`packages.checkUpdates`),Yc=P(`packages.updateAll`,`skill`);function Xc(e){return`skill:${e}`}function Zc({skill:e,packageEntry:t,uninstalling:n,applying:r,onUninstall:i,onUpdate:a}){let o=Xc(e.name),s=M(P(`packages.update`,o)),c=M(P(`skills.uninstall`,e.name));return(0,G.jsx)(Kc,{skill:e,packageEntry:t,uninstalling:n||c,applying:r||s,onUninstall:()=>i(e),onUpdate:()=>a(o)})}function Qc({message:e}){return(0,G.jsx)(`pre`,{className:`max-w-full overflow-x-auto whitespace-pre-wrap rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-xs text-destructive`,children:e})}function $c({skill:e,installing:t,installed:n,message:r,onInstall:i}){let a;return a=n?`Installed`:t?`Installing`:`Get`,(0,G.jsxs)(`div`,{className:`flex min-w-0 items-center justify-between gap-3 rounded-lg border border-border bg-card/30 p-3`,children:[(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`div`,{className:`truncate text-sm font-medium text-foreground`,children:e.name}),(0,G.jsxs)(`div`,{className:`truncate text-xs text-muted-foreground`,children:[e.source,` · `,qc(e.installs)]}),n&&r?(0,G.jsx)(`div`,{className:`mt-1 truncate text-xs text-emerald-500`,children:r}):null]}),(0,G.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[(0,G.jsx)(`a`,{href:`https://skills.sh/${e.id}`,target:`_blank`,rel:`noreferrer`,"aria-label":`View ${e.name} on skills.sh`,className:`touch-manipulation inline-flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,children:(0,G.jsx)(Pe,{className:`h-4 w-4`})}),(0,G.jsxs)(E,{type:`button`,size:`sm`,variant:n?`secondary`:`default`,disabled:t||n,onClick:i,className:`h-6 rounded-full px-2 text-xs`,children:[t?(0,G.jsx)(O,{className:`mr-1.5 h-3.5 w-3.5 animate-spin`}):null,a]})]})]})}function el({state:e,ports:t}){let n=t?.timer??Qe,r=e.socket,i=e.connectionStatus,a=x(e=>e.skillQuery),o=x(e=>e.setSkillQuery),s=x(e=>e.skillResults),c=x(e=>e.setSkillResults),l=x(e=>e.skillSearchLoading),u=x(e=>e.setSkillSearchLoading),d=x(e=>e.skillSearchError),f=x(e=>e.setSkillSearchError),p=x(e=>e.installedSkills),m=x(e=>e.setInstalledSkills),h=x(e=>e.installedSkillIds),g=x(e=>e.setInstalledSkillIds),_=x(e=>e.addInstalledSkillId),v=x(e=>e.removeInstalledSkillId),y=x(e=>e.installedLoading),b=x(e=>e.setInstalledLoading),ee=x(e=>e.installedError),te=x(e=>e.setInstalledError),ne=x(e=>e.skillOperationError),S=x(e=>e.setSkillOperationError),re=x(e=>e.installingSkillId),C=x(e=>e.setInstallingSkillId),ie=x(e=>e.uninstallingSkillId),ae=x(e=>e.setUninstallingSkillId),w=x(e=>e.installMessages),oe=x(e=>e.setInstallMessage),se=x(e=>e.clearInstallMessage),ce=x(e=>e.clearInstallMessagesForSkill),D=x(e=>e.packageUpdateSnapshot),k=D?.status===`checking`,j=D?.packages.filter(e=>e.kind===`skill`&&!e.pinnedRef).filter(e=>e.update.availability===`outdated`||e.update.availability===`partial`).map(e=>e.id)??[],N=j.length,le=D?.lastCheckedAt?new Date(D.lastCheckedAt).toLocaleTimeString():null,ue=M(Jc),de=M(Yc),fe=k||ue;async function pe(e){try{S(null),await r.command(e)}catch(e){throw S(T(e)),e}}function me(){A(Jc,()=>pe({type:`packages.checkUpdates`}))}function he(e){A(P(`packages.update`,e),()=>pe({type:`packages.update`,id:e}))}function ge(){j.length!==0&&A(Yc,()=>pe({type:`packages.updateAll`,ids:j}))}function _e(e){A(P(`skills.install`,e.id),()=>be(e))}function ve(e){A(P(`skills.uninstall`,e.name),()=>xe(e))}let ye=(0,W.useCallback)(async()=>{if(i!==`connected`){m([]),g(new Set),te(null),b(!1);return}try{b(!0),te(null);let e=await r.command({type:`skills.listInstalled`});m(e.skills),g(new Set(e.skills.map(e=>e.name)))}catch(e){m([]),g(new Set),te(e instanceof Error?e.message:`Unable to read installed skills.`)}finally{b(!1)}},[i,r,m,g,te,b]);(0,W.useEffect)(()=>{wt(`skills.listInstalled`,ye())},[i,ye,r]),(0,W.useEffect)(()=>{let e=a.trim();if(e.length<2){c([]),f(null),u(!1);return}if(i!==`connected`){c([]),u(!1),f(`Backend connection required.`);return}let t=!1;u(!0),f(null);let o=n.setTimeout(()=>{r.command({type:`skills.search`,query:e,limit:100}).then(e=>{t||c(e.skills)}).catch(e=>{t||(c([]),f(e instanceof Error?e.message:`Unable to search skills.`))}).finally(()=>{t||u(!1)})},250);return()=>{t=!0,n.clearTimeout(o)}},[i,a,r,c,f,u,n]);async function be(e){if(i!==`connected`){S(`Backend connection required.`);return}try{C(e.id),S(null),se(e.id),await r.command({type:`skills.install`,source:e.source,skillId:e.skillId}),_(e.skillId),oe(e.id,`Installed globally`),wt(`skills.listInstalled`,ye())}catch(e){S(e instanceof Error?e.message:`Install failed.`)}finally{C(null)}}async function xe(e){if(i!==`connected`){S(`Backend connection required.`);return}try{ae(e.name),S(null),await r.command({type:`skills.uninstall`,skillId:e.name}),m(p.filter(t=>t.name!==e.name)),v(e.name),ce(e.name),wt(`skills.listInstalled`,ye())}catch(e){S(e instanceof Error?e.message:`Uninstall failed.`)}finally{ae(null)}}let Se;return Se=p.length>0?(0,G.jsx)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:p.map(e=>(0,G.jsx)(Zc,{skill:e,packageEntry:D?.packages.find(t=>t.kind===`skill`&&t.name===e.name)??null,uninstalling:ie===e.name,applying:D?.applying.includes(Xc(e.name))??!1,onUninstall:ve,onUpdate:he},`${e.source}/${e.name}`))}):y?null:(0,G.jsx)(`div`,{className:`rounded-lg border border-border bg-card/30 p-3 text-sm text-muted-foreground`,children:`No global skills installed.`}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[ne?(0,G.jsx)(Qc,{message:ne}):null,(0,G.jsxs)(`section`,{className:`flex flex-col gap-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`Installed`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[le?(0,G.jsxs)(`span`,{className:`tabular-nums text-xs text-muted-foreground`,children:[`Checked `,le]}):null,N>0?(0,G.jsxs)(E,{size:`sm`,variant:`secondary`,className:`h-6 rounded-full px-2 text-xs`,pending:de,onClick:ge,children:[`Update all (`,N,`)`]}):null,(0,G.jsxs)(E,{size:`sm`,variant:`ghost`,className:`h-6 rounded-full px-2 text-xs`,disabled:fe,"aria-busy":fe||void 0,onClick:me,children:[fe?(0,G.jsx)(O,{className:`mr-1 h-3 w-3 animate-spin`}):null,`Check`]}),y?(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin text-muted-foreground`}):null]})]}),ee?(0,G.jsx)(`div`,{className:`text-xs text-destructive`,children:ee}):null,Se]}),(0,G.jsxs)(`section`,{className:`flex flex-col gap-3`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`Discover`}),(0,G.jsxs)(`div`,{className:`flex h-10 items-center gap-2 rounded-lg border border-border bg-card/30 px-3`,children:[(0,G.jsx)(Be,{className:`h-4 w-4 shrink-0 text-muted-foreground`}),(0,G.jsx)(`input`,{type:`text`,role:`searchbox`,value:a,onChange:e=>o(e.target.value),placeholder:`Search skills`,className:`min-w-0 flex-1 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground`}),a?(0,G.jsx)(`button`,{type:`button`,"aria-label":`Clear skills search`,onClick:()=>o(``),className:`touch-manipulation inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,children:(0,G.jsx)(qe,{className:`h-3.5 w-3.5`})}):null,l?(0,G.jsx)(O,{className:`h-4 w-4 shrink-0 animate-spin text-muted-foreground`}):null]}),d?(0,G.jsx)(`div`,{className:`text-xs text-destructive`,children:d}):null,(0,G.jsx)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:s.map(e=>(0,G.jsx)($c,{skill:e,installing:re===e.id,installed:h.has(e.skillId),message:w[e.id],onInstall:()=>{_e(e)}},e.id))}),!l&&!d&&a.trim().length>=2&&s.length===0?(0,G.jsx)(`div`,{className:`rounded-lg border border-border bg-card/30 p-3 text-sm text-muted-foreground`,children:`No skills found.`}):null]})]})}function tl(e){return{async onReload(t){if(!(await e(`/api/plugins/${t}/reload`,{})).ok)throw Error(`Failed to reload plugin ${t}`)}}}function nl({plugins:e,handlers:t}){return e.length===0?(0,G.jsx)(Zr,{icon:l,message:`No plugins installed yet.`}):(0,G.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,G.jsx)(`h2`,{className:`text-sm font-medium text-foreground`,children:`Plugins`}),(0,G.jsx)(Qr,{children:e.map(e=>(0,G.jsx)(rl,{plugin:e,onReload:t.onReload},e.id))})]})}function rl({plugin:e,onReload:t}){let n=P(`plugins.reload`,e.id),r=M(n),i=(0,W.useCallback)(()=>{A(n,async()=>{try{await t(e.id),fn.getState().setCommandError(null)}catch(e){throw fn.getState().setCommandError(T(e)),e}})},[t,e.id,n]);return(0,G.jsxs)(`li`,{className:`flex items-center justify-between gap-3 px-4 py-3`,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-0.5`,children:[(0,G.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`span`,{className:`truncate text-sm font-medium text-foreground`,children:e.id}),(0,G.jsx)(Ot,{tone:e.enabled?`active`:`muted`,label:e.enabled?`Enabled`:`Disabled`})]}),(0,G.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,children:e.sourceDir})]}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,"data-testid":`plugin-reload:${e.id}`,pending:r,onClick:i,children:`Reload`})]})}async function il(e,t){return{ok:(await we.postJsonBody(e,t)).ok}}var al=tl(il);function ol(){let e=z(pt);return(0,G.jsx)(nl,{plugins:e,handlers:al})}var sl=[{id:`general`,label:`General`,icon:xe,subtitle:`Manage appearance, editor behavior, and embedded terminal defaults.`},{id:`skills`,label:`Skills`,icon:Mn,subtitle:`Manage globally installed agent skills from the active skill lock file.`},{id:`plugins`,label:`Plugins`,icon:Qn,subtitle:`View and update globally installed Claude Code and Codex plugins.`},{id:`kanna-plugins`,label:`Kanna plugins`,icon:l,subtitle:`Install local Kanna plugins that contribute UI surfaces and daemon behavior.`},{id:`providers`,label:`Providers`,icon:Kn,subtitle:`Manage the default chat provider and saved model defaults for Claude Code and Codex.`},{id:`models`,label:`Models`,icon:Bn,subtitle:`Add, edit, and remove Claude and Codex models available in the model picker.`},{id:`subagents`,label:`Subagents`,icon:le,subtitle:`Define reusable agent personas. Mention them in chat with @agent/<name>.`},{id:`mcp-servers`,label:`MCP servers`,icon:Qn,subtitle:`Install custom MCP servers (stdio, http, sse, ws) and connect-test them.`},{id:`mcp-sources`,label:`MCP sources`,icon:An,subtitle:`Bring messages from an MCP server, such as Zalo, into the Inbox by subscription or polling.`},{id:`remote-mcp`,label:`Remote MCP`,icon:Xn,subtitle:`Let Claude, Codex and ChatGPT drive Kanna over MCP, with setup snippets for each client.`},{id:`service-bus`,label:`Service bus`,icon:cr,subtitle:`Mirror Kanna's events into NATS JetStream, with an embedded or your own server.`},{id:`beacons`,label:`Beacons`,icon:pe,subtitle:`Pair your own machines so the agent can read files and run approved commands there.`},{id:`snippets`,label:`Text snippets`,icon:or,subtitle:`Define shortcuts that expand to full text in the chat composer with Tab.`},{id:`instructions`,label:`Instructions`,icon:Kn,subtitle:`Global instructions appended to every Claude and Codex turn (main + subagents).`},{id:`keybindings`,label:`Keybindings`,icon:Rn,subtitle:`Edit global app shortcuts stored in the active keybindings file.`},{id:`changelog`,label:`Changelog`,icon:Mn,subtitle:`Release notes pulled from the public GitHub releases feed.`}],cl={"mcp-servers":_i,"mcp-sources":ra,"remote-mcp":Ks,"service-bus":zc,beacons:Ka};function ll(e){return e?sl.find(t=>t.id===e)?.id??null:null}function ul(e){return e?sl:sl.filter(e=>e.id!==`kanna-plugins`)}var dl=[{value:`light`,label:`Light`,icon:ir},{value:`dark`,label:`Dark`,icon:Jn},{value:`system`,label:`System`,icon:Ie}],fl=[{value:`sm`,label:`Small`},{value:`md`,label:`Default`},{value:`lg`,label:`Large`},{value:`xl`,label:`Extra Large`},{value:`xxl`,label:`XX-Large`}],pl=[{value:`never`,label:`Never`},{value:`unfocused`,label:`When Unfocused`},{value:`always`,label:`Always`}],ml=[{value:`disabled`,label:`Off`},{value:`enabled`,label:`On`}],hl=[{value:`disabled`,label:`Off`},{value:`enabled`,label:`On`}],gl=[{value:`always-ask`,label:`Always ask`},{value:`auto-expose`,label:`Auto-expose`}],_l=[{value:`openai`,label:`OpenAI`},{value:`openrouter`,label:`OpenRouter`},{value:`custom`,label:`Custom`}],vl=3e5,yl=null;function bl(e){return`Edit global app shortcuts stored in ${e}.`}function xl(e,t){return e!==t}function Sl(){return yl?Date.now()>=yl.expiresAt?(yl=null,null):yl.releases:null}function Cl(e){yl={releases:e,expiresAt:Date.now()+vl}}async function wl(e,t){let n=t?.force?null:Sl();if(n)return n;let r=await e();return Cl(r),r}function Tl(e,t){let n=e=>e.trim().replace(/^v/i,``).split(`-`)[0].split(`.`).map(e=>Number.parseInt(e,10)).filter(e=>Number.isFinite(e)),r=n(e),i=n(t),a=Math.max(r.length,i.length);for(let e=0;e<a;e+=1){let t=r[e]??0,n=i[e]??0;if(t!==n)return t<n?-1:1}return 0}function El(e){if(!e)return`Unpublished`;let t=new Date(e);return Number.isNaN(t.getTime())?`Unknown date`:new Intl.DateTimeFormat(void 0,{month:`short`,day:`numeric`,year:`numeric`}).format(t)}var Dl=`__redeploy__`,Ol=`settings.writeLlmProvider`,kl=`appSettings.setCloudflareTunnel`,Al=P(kl,`cloudflaredPath`);function jl({status:e,releases:t,error:n,onRetry:r,updateSnapshot:i,currentVersion:a,onInstallUpdate:o,onCheckForUpdates:s,onForceReload:c}){let l=M(`update.check`),u=x(e=>e.changelogPendingAction),d=x(e=>e.setChangelogPendingAction),f=i?.latestVersion??t[0]?.tag_name??`Unknown`,p=i?.currentVersion??a,m=i?.status===`checking`||l,h=i?.status===`updating`||i?.status===`restart_pending`,g=h||u!==null,_=i?.updateAvailable===!0,v=f.replace(/^v/i,``),y=p.replace(/^v/i,``),b=(0,W.useCallback)(async e=>{d(e);try{await o(e)}finally{d(null)}},[o,d]),ee=(0,W.useCallback)(async()=>{d(Dl);try{await c()}finally{d(null)}},[c,d]),te=u===Dl||h;return(0,G.jsxs)(`div`,{className:`space-y-4`,children:[e===`loading`||e===`idle`?(0,G.jsx)(`div`,{className:`flex min-h-[180px] items-center justify-center rounded-2xl border border-border bg-card/40 px-6 py-8 text-sm text-muted-foreground`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),(0,G.jsx)(`span`,{children:`Loading release notes…`})]})}):null,e===`error`?(0,G.jsx)(`div`,{className:`rounded-lg border border-destructive/20 bg-destructive/5 px-6 py-5`,children:(0,G.jsxs)(`div`,{className:`flex items-start justify-between gap-4`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`Could not load changelog`}),(0,G.jsx)(`div`,{className:`mt-1 text-sm text-muted-foreground`,children:n??`Unable to load changelog.`})]}),(0,G.jsx)(`button`,{type:`button`,onClick:r,className:`rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground transition-colors hover:bg-muted`,children:`Retry`})]})}):null,e===`success`&&t.length===0?(0,G.jsxs)(`div`,{className:`rounded-lg border border-border bg-card/30 px-6 py-8`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`No releases yet`}),(0,G.jsx)(`div`,{className:`mt-2 text-sm text-muted-foreground`,children:`GitHub did not return any published releases for this repository.`})]}):null,e===`success`?(0,G.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,G.jsx)(On,{variant:`outline`,onClick:()=>A(`update.redeploy`,ee),disabled:g,children:te?(0,G.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}),`Re-deploying…`]}):`Re-deploy`}),(0,G.jsx)(On,{variant:`outline`,onClick:()=>A(`update.check`,s),disabled:m||g,children:m?(0,G.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}),`Checking…`]}):`Check for updates`})]}):null,e===`success`&&t.length>0?t.map(e=>{let t=e.tag_name.replace(/^v/i,``),n=t===v,r=t===y;return(0,G.jsxs)(`article`,{className:D(`rounded-xl border bg-card/30 pl-6 pr-4 py-4`,n?`border-border bg-muted`:`border-border`),children:[(0,G.jsxs)(`div`,{className:`flex flex-row items-center min-w-0 flex-1 gap-3 `,children:[(0,G.jsxs)(`div`,{className:`flex flex-row items-center min-w-0 flex-1 gap-2 `,children:[(0,G.jsx)(`div`,{className:`text-lg font-semibold tracking-[-0.2px] text-foreground`,children:e.name?.trim()||e.tag_name}),(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2 text-sm text-muted-foreground`,children:[(0,G.jsx)(`span`,{children:El(e.published_at)}),e.prerelease?(0,G.jsx)(`span`,{className:`rounded-full border border-border px-2.5 py-1 tracking-wide`,children:`Prerelease`}):null]})]}),(0,G.jsxs)(`div`,{className:`flex flex-row items-center justify-end min-w-0 flex-1 gap-2 `,children:[(0,G.jsx)(`a`,{href:e.html_url,target:`_blank`,rel:`noopener noreferrer`,"aria-label":`View release on GitHub`,className:D(j({variant:`ghost`,size:`icon-sm`}),`h-11 w-11 md:h-8 md:w-8 shrink-0 rounded-md hover:!bg-transparent hover:border-border/0`),children:(0,G.jsx)(Ml,{className:`h-4 w-4`})}),r?(0,G.jsx)(`span`,{className:D(`bg-transparent border border-border text-secondary-foreground`,`h-9 rounded-full px-3 text-sm`,`h-auto gap-1.5 px-3 py-1.5`),children:`Current`}):null,n&&_||!n&&!r?(()=>{let r=u===e.tag_name||h&&u===null,i;i=n?`Update`:Tl(t,y)<0?`Rollback`:`Install`;let a;return a=n?`Updating…`:Tl(t,y)<0?`Rolling back…`:`Installing…`,(0,G.jsx)(On,{variant:`default`,className:``,onClick:()=>A(P(`update.install`,e.tag_name),()=>b(e.tag_name)),disabled:g,children:(0,G.jsxs)(`div`,{className:`flex flex-row items-center justify-center gap-2`,children:[r?(0,G.jsx)(O,{className:`size-4 animate-spin`}):(0,G.jsx)(In,{className:`size-4`}),r?a:i]})})})():null]})]}),e.body?.trim()?(0,G.jsx)(`div`,{className:`prose prose-sm mt-5 max-w-none text-foreground dark:prose-invert`,children:Ce(e.body)}):(0,G.jsx)(`div`,{className:`mt-5 text-sm text-muted-foreground`,children:`No release notes were provided.`})]},e.id)}):null]})}function Ml({className:e}){return(0,G.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`currentColor`,"aria-hidden":`true`,className:e,children:(0,G.jsx)(`path`,{d:`M12 .5C5.649.5.5 5.649.5 12A11.5 11.5 0 0 0 8.36 22.04c.575.106.785-.25.785-.556 0-.274-.01-1-.015-1.962-3.181.691-3.853-1.532-3.853-1.532-.52-1.322-1.27-1.674-1.27-1.674-1.038-.71.08-.695.08-.695 1.148.08 1.752 1.178 1.752 1.178 1.02 1.748 2.676 1.243 3.328.95.103-.738.399-1.243.725-1.53-2.54-.289-5.211-1.27-5.211-5.65 0-1.248.446-2.27 1.177-3.07-.118-.288-.51-1.45.112-3.024 0 0 .96-.307 3.145 1.173A10.91 10.91 0 0 1 12 6.03c.973.004 1.954.132 2.87.387 2.182-1.48 3.14-1.173 3.14-1.173.625 1.573.233 2.736.115 3.024.734.8 1.175 1.822 1.175 3.07 0 4.39-2.676 5.358-5.224 5.642.41.353.776 1.05.776 2.117 0 1.528-.014 2.761-.014 3.136 0 .309.207.668.79.555A11.502 11.502 0 0 0 23.5 12C23.5 5.649 18.351.5 12 .5Z`})})}function Nl({checked:e,onChange:t}){return(0,G.jsxs)(`label`,{className:`inline-flex items-center gap-2`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:e,onChange:e=>t(e.target.checked)}),`Enabled`]})}function Pl({state:e}){let t=z(e=>e.settings?.globalPromptAppend??``),n=x(e=>e.globalInstructionsDraft),r=x(e=>e.setGlobalInstructionsDraft),i=x(e=>e.globalInstructionsPersistedAtMount),a=x(e=>e.globalInstructionsSaving),o=x(e=>e.setGlobalInstructionsSaving),s=x(e=>e.globalInstructionsError),c=x(e=>e.setGlobalInstructionsError);(0,W.useEffect)(()=>{t!==i&&x.setState({globalInstructionsPersistedAtMount:t,globalInstructionsDraft:t})},[t,i]);let l=n.replace(/\s+$/u,``),u=l.length>qt,d=l!==t,f=a||u||!d,p=(0,W.useCallback)(async()=>{if(!f){c(null),o(!0);try{await e.handleWriteAppSettings({globalPromptAppend:l})}catch(e){c(e instanceof Error?e.message:String(e))}finally{o(!1)}}},[f,e,l,c,o]),m;return m=a?`Saving…`:d?`Save`:`Saved`,(0,G.jsx)(`div`,{className:`border-b border-border`,children:(0,G.jsx)(q,{title:`Global Instructions`,description:`Appended to every Claude and Codex turn — including subagent turns — as “Workspace instructions”. Kanna does not read CLAUDE.md or AGENTS.md from disk; paste your global instructions here. For rules that apply to one project only, use “Edit instructions” in that project's sidebar menu. Leave blank to disable.`,bordered:!1,alignStart:!0,children:(0,G.jsxs)(`div`,{className:`flex w-full flex-col gap-2 md:w-[420px]`,children:[(0,G.jsx)(`textarea`,{value:n,onChange:e=>r(e.target.value),placeholder:`e.g. Always write tests before implementation. Prefer Tailwind classes over inline styles.`,rows:8,"aria-label":`Global instructions`,className:D(`min-h-[160px] w-full resize-y rounded-md border bg-background px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50`,u?`border-destructive`:`border-input`),disabled:a}),(0,G.jsxs)(`div`,{className:`flex items-center justify-between text-xs`,children:[(0,G.jsxs)(`span`,{className:u?`text-destructive`:`text-muted-foreground`,children:[l.length,` / `,qt,` characters`,u?` — over limit`:``]}),(0,G.jsx)(E,{type:`button`,size:`sm`,onClick:()=>A(`settings.globalInstructions`,p),disabled:f,pending:a,children:m})]}),s?(0,G.jsx)(`div`,{className:`text-xs text-destructive`,children:s}):null]})})})}function Fl({ports:e,sectionId:t}={}){let i=e?.dom??oe,l=n(),d=r(),{theme:m,setTheme:g}=bn(),_=x(e=>e.changelogStatus),v=x(e=>e.setChangelogStatus),y=x(e=>e.signingOut),ne=x(e=>e.setSigningOut),S=x(e=>e.authEnabled),ie=x(e=>e.setAuthEnabled),w=x(e=>e.releases),T=x(e=>e.setReleases),se=x(e=>e.changelogError),k=x(e=>e.setChangelogError),j=ll(t)??`general`,le=cl[j],ue=z(e=>e.hydrationStatus===`loading`&&e.settings===null),pe=d.connectionStatus===`connecting`||!d.localProjectsReady||ue,me=M(Ol),he=M(ee),ve=me||he,ye=M(Al),be=M(`keybindings.openEditor`),xe=M(`settings.chatSoundPreference`),Se=M(`settings.chatSoundId`),Ce=d.localProjects?.machine.displayName??`Unavailable`,we=d.localProjects?.projects.length??0,Te=ae.split(`/`)[1]??`unknown`,Ee=z(mt),De=z(ct),Oe=z(st),Pe=z(yt),Ie=s(e=>e.setScrollbackLines),Le=s(e=>e.setMinColumnWidth),Re=s(e=>e.setEditorPreset),ze=s(e=>e.setEditorCommandTemplate),Be=z(ht),Ve=z(bt),He=rs(e=>e.setChatSoundPreference),Ue=rs(e=>e.setChatSoundId),We=d.keybindings,I=z(e=>e.settings),Ge=d.llmProvider,Ke=C(e=>e.autoResumeOnRateLimit),qe=C(e=>e.setAutoResumeOnRateLimit),Qe=C(e=>e.typographyOverride),et=C(e=>e.clearTypographyOverride),tt=z(e=>e.settings?.typography.scale),nt=re(Qe,tt),rt=b(e=>e.defaultProvider),it=b(e=>e.providerDefaults),at=b(e=>e.setDefaultProvider),ot=b(e=>e.setProviderDefaultModel),ut=b(e=>e.setProviderDefaultModelOptions),dt=b(e=>e.setProviderDefaultPlanMode),ft=z(lt),pt=Sn(),gt=(0,W.useMemo)(()=>h(We),[We]).filePathDisplay||ce(),_t=x(e=>e.pushPermissionState),vt=x(e=>e.setPushPermissionState),xt=x(e=>e.pushDeviceId),{handleEnablePush:St,handleDisablePush:Ct}=Bc(d),Et=x(e=>e.scrollbackDraft),Ot=x(e=>e.setScrollbackDraft),kt=x(e=>e.minColumnWidthDraft),At=x(e=>e.tabMinWidthDraft),jt=x(e=>e.setMinColumnWidthDraft),Mt=x(e=>e.setTabMinWidthDraft),Nt=I?.panes.tabMinWidth??60,Pt=I?.uploads.maxFileSizeMb??mr.maxFileSizeMb,Ft=x(e=>e.uploadMaxFileSizeDraft),It=x(e=>e.setUploadMaxFileSizeDraft),Lt=Math.round((I?.claudeDriver.lifecycle.idleTimeoutMs??Ut.idleTimeoutMs)/6e4),Rt=I?.claudeDriver.lifecycle.maxConcurrent??Ut.maxConcurrent,Vt=x(e=>e.claudeIdleMinutesDraft),Ht=x(e=>e.setClaudeIdleMinutesDraft),Gt=x(e=>e.claudeMaxConcurrentDraft),qt=x(e=>e.setClaudeMaxConcurrentDraft),Jt=x(e=>e.editorCommandDraft),Xt=x(e=>e.setEditorCommandDraft),$t=x(e=>e.appSettingsError),B=x(e=>e.setAppSettingsError),en=x(e=>e.analyticsDialogOpen),tn=x(e=>e.setAnalyticsDialogOpen),nn=x(e=>e.tunnelError),rn=x(e=>e.setTunnelError),sn=x(e=>e.cloudflaredPathDraft),cn=x(e=>e.setCloudflaredPathDraft),ln=x(e=>e.pushContactSubjectDraft),un=x(e=>e.setPushContactSubjectDraft),dn=I?.shareDefaultTtlHours??24,fn=x(e=>e.shareDefaultTtlDraft),pn=x(e=>e.setShareDefaultTtlDraft),V=x(e=>e.llmProviderDraft),mn=x(e=>e.setLlmProviderDraft),hn=x(e=>e.llmProviderError),gn=x(e=>e.setLlmProviderError),_n=x(e=>e.llmValidationStatus),vn=x(e=>e.setLlmValidationStatus),yn=x(e=>e.llmValidationError),xn=x(e=>e.setLlmValidationError),Cn=x(e=>e.llmValidationDialogOpen),wn=x(e=>e.setLlmValidationDialogOpen),H=d.updateSnapshot,U=d.handleWriteAppSettings,Tn=d.handleWriteCloudflareTunnel,En=d.handleWriteClaudeAuth,Dn=d.handleTestOAuthToken,kn=d.handleReadLlmProvider,An=d.handleWriteLlmProvider,jn=d.handleValidateLlmProvider,Mn;Mn=H?.status===`checking`?`Checking for updates…`:H?.status===`updating`?`Installing update…`:H?.status===`restart_pending`?`Restarting Kanna…`:H?.status===`available`?`Update available${H.latestVersion?`: ${H.latestVersion}`:``}`:H?.status===`up_to_date`?`Up to date`:H?.status===`error`?`Update check failed`:`Not checked yet`,(0,W.useEffect)(()=>{Ot(String(Ee))},[Ee,Ot]),(0,W.useEffect)(()=>{jt(String(De))},[De,jt]),(0,W.useEffect)(()=>{Mt(String(Nt))},[Nt,Mt]),(0,W.useEffect)(()=>{It(String(Pt))},[Pt,It]),(0,W.useEffect)(()=>{Ht(String(Lt))},[Lt,Ht]),(0,W.useEffect)(()=>{qt(String(Rt))},[Rt,qt]),(0,W.useEffect)(()=>i.addWindowListener(`focus`,()=>vt(an().state)),[i,vt]),(0,W.useEffect)(()=>{Xt(Pe)},[Pe,Xt]),(0,W.useEffect)(()=>{Ge&&mn({provider:Ge.provider,apiKey:Ge.apiKey,model:Ge.model,baseUrl:Ge.baseUrl})},[Ge,mn]),(0,W.useEffect)(()=>{vn(`idle`),xn(null)},[V.provider,V.apiKey,V.model,V.baseUrl,vn,xn]),(0,W.useEffect)(()=>{t&&(ll(t)||l(`/settings/general`,{replace:!0}))},[l,t]),(0,W.useEffect)(()=>{I&&cn(I.cloudflareTunnel.cloudflaredPath)},[I,cn]),(0,W.useEffect)(()=>{I&&un(I.push.contactSubject)},[I,un]),(0,W.useEffect)(()=>{let e=!1;return te().then(t=>{e||ie(t.enabled===!0)}).catch(()=>{e||ie(!1)}),()=>{e=!0}},[ie]),(0,W.useEffect)(()=>{j!==`providers`||pe||A(ee,kn)},[kn,pe,j]);let Nn=(0,W.useCallback)(()=>d.socket.command({type:`settings.getChangelog`}),[d.socket]);(0,W.useEffect)(()=>{if(j!==`changelog`||pe)return;let e=!1;return v(`loading`),k(null),wl(Nn).then(t=>{e||(T(t),v(`success`))}).catch(t=>{e||(k(t instanceof Error?t.message:`Unable to load changelog.`),v(`error`))}),()=>{e=!0}},[pe,j,v,k,T,Nn]);function Fn(){let e=Number(Et);if(!Number.isFinite(e)){Ot(String(Ee));return}Ie(e),U({terminal:{scrollbackLines:e}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save terminal settings.`)})}function In(){let e=Number(kt);if(!Number.isFinite(e)){jt(String(De));return}Le(e),U({terminal:{minColumnWidth:e}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save terminal settings.`)})}function Ln(){let e=Number(At);if(!Number.isFinite(e)){Mt(String(Nt));return}U({panes:{tabMinWidth:de(e)}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save pane settings.`)})}function Rn(){let e=Number(Ft);if(!Number.isFinite(e)||e<1||e>51200){It(String(Pt)),B(`Max file size must be between 1 and ${hr} MB.`);return}if(Math.round(e)===Pt){It(String(Pt));return}U({uploads:{maxFileSizeMb:Math.round(e)}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save upload settings.`)})}function zn(){let e=Number(Vt),t=Math.round(Yt/6e4),n=Math.round(Kt/6e4);if(!Number.isFinite(e)||e<t||e>n){Ht(String(Lt)),B(`Idle timeout must be between ${t} and ${n} minutes.`);return}if(Math.round(e)===Lt){Ht(String(Lt));return}U({claudeDriver:{lifecycle:{idleTimeoutMs:Math.round(e)*6e4}}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save Claude lifecycle settings.`)})}function Bn(){let e=Number(Gt);if(!Number.isFinite(e)||e<1||e>16){qt(String(Rt)),B(`Max concurrent sessions must be between 1 and 16.`);return}if(Math.round(e)===Rt){qt(String(Rt));return}U({claudeDriver:{lifecycle:{maxConcurrent:Math.round(e)}}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save Claude lifecycle settings.`)})}function Vn(){let e=Number(fn);if(!Number.isInteger(e)||e<1){pn(String(dn)),B(`Default share link expiry must be a whole number of hours >= 1.`);return}if(e===dn){pn(String(dn));return}U({shareDefaultTtlHours:e}).catch(e=>{B(e instanceof Error?e.message:`Unable to save share settings.`)})}function Hn(e,t){e.key===`Enter`&&(t(),e.currentTarget.blur())}function Un(){ze(Jt),U({editor:{commandTemplate:Jt}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save editor settings.`)})}function Gn(e){g(e),U({theme:e}).catch(e=>{B(e instanceof Error?e.message:`Unable to save theme settings.`)})}function Kn(e){U({typography:{scale:e}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save typography settings.`)})}function qn(e){Re(e);let t=e===`custom`?Pe:p(e);U({editor:{preset:e,commandTemplate:t}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save editor settings.`)})}function Jn(e){xl(Be,e)&&(He(e),A(`settings.chatSoundPreference`,()=>U({chatSoundPreference:e}).catch(e=>{B(e instanceof Error?e.message:`Unable to save chat sound settings.`)})),wt(`chat sound preview`,Tt(Ve,1)))}function Yn(e){xl(Ve,e)&&(Ue(e),A(`settings.chatSoundId`,()=>U({chatSoundId:e}).catch(e=>{B(e instanceof Error?e.message:`Unable to save chat sound settings.`)})),wt(`chat sound preview`,Tt(e,1)))}async function Xn(e){try{B(null),await U({analyticsEnabled:e===`enabled`})}catch(e){B(e instanceof Error?e.message:`Unable to save analytics settings.`)}}async function Zn(e){try{B(null),await U({telemetry:{enabled:e===`enabled`}})}catch(e){B(e instanceof Error?e.message:`Unable to save telemetry settings.`)}}async function Qn(e){try{rn(null),await Tn(e)}catch(e){rn(e instanceof Error?e.message:`Unable to save Cloudflare Tunnel settings.`)}}function $n(e){at(e),U({defaultProvider:e}).catch(e=>{B(e instanceof Error?e.message:`Unable to save provider settings.`)})}function er(e,t){ot(e,t),U({providerDefaults:{[e]:{model:t}}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save provider settings.`)})}function tr(e,t){ut(e,t),U({providerDefaults:{[e]:{modelOptions:t}}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save provider settings.`)})}function nr(e,t){dt(e,t),U({providerDefaults:{[e]:{planMode:t}}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save provider settings.`)})}async function rr(e=V){try{gn(null),await An(e);let t=await jn(e);vn(t.ok?`valid`:`invalid`),xn(t.error)}catch(e){let t=e instanceof Error?{name:e.name,message:e.message}:Dt(e);vn(`invalid`),xn(t),gn(e instanceof Error?e.message:`Unable to save quick response provider settings.`)}}function ir(e){let t=Hc(V,e);mn(t),ar(t)}function ar(e=V){A(Ol,()=>rr(e))}function or(){yl=null,v(`loading`),k(null),wl(Nn,{force:!0}).then(e=>{T(e),v(`success`)}).catch(e=>{k(e instanceof Error?e.message:`Unable to load changelog.`),v(`error`)})}let sr=Jt.replaceAll(`{path}`,`/Users/jake/Projects/kanna/src/client/app/App.tsx`).replaceAll(`{line}`,`12`).replaceAll(`{column}`,`1`),cr=gr,lr=I?.analyticsEnabled===!1?`disabled`:`enabled`,ur=I?.telemetry?.enabled===!1?`disabled`:`enabled`,dr=I?.cloudflareTunnel??fr,pr=dr.enabled?`enabled`:`disabled`,vr=sl.find(e=>e.id===j)??sl[0],yr=(0,W.useMemo)(()=>ul(ft),[ft]),br=j===`keybindings`?bl(gt):vr.subtitle,K=!pe,xr=yn?JSON.stringify(yn,null,2):``,Sr;Sr=ve?`inline-flex items-center gap-1.5 text-muted-foreground`:_n===`valid`?`text-success-text`:_n===`invalid`?`text-destructive`:`hidden`;let Cr;Cr=ve?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(N,{}),me?`Saving…`:`Loading…`]}):_n===`valid`?`Credentials valid & saved`:_n===`invalid`?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`span`,{children:`Credentials invalid.`}),yn?(0,G.jsxs)(G.Fragment,{children:[` `,(0,G.jsx)(`button`,{type:`button`,onClick:()=>wn(!0),className:`underline underline-offset-2`,children:`See error`})]}):null]}):null;let wr=(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`span`,{children:[`Use an OpenAI-compatible API for title and commit message generation before Claude and Codex. Stored in `,Ge?.filePathDisplay??`the active llm-provider.json file`,`.`]}),(0,G.jsx)(`span`,{className:D(`mt-2 block text-sm font-medium`,Sr),children:Cr})]});async function Tr(){if(!y){ne(!0);try{await d.handleSignOut()}finally{ne(!1)}}}return(0,G.jsxs)(`div`,{className:`relative flex h-full flex-1 min-w-0 bg-background`,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-1`,children:[(0,G.jsx)(`aside`,{className:`hidden w-[200px] shrink-0 md:block ${K?`pb-[89px]`:``}`,children:(0,G.jsxs)(`div`,{className:`flex flex-col gap-1 px-4 py-6`,children:[(0,G.jsx)(`div`,{className:`px-3 pb-5 text-22 font-extrabold tracking-[-0.5px] text-foreground`,children:`Settings`}),yr.map(e=>{let t=e.id===`changelog`&&H?.updateAvailable===!0;return(0,G.jsxs)(`button`,{type:`button`,onClick:()=>{l(`/settings/${e.id}`)},className:`relative cursor-pointer rounded-lg px-3 py-2 text-sm ${e.id===j?`font-medium text-foreground`:`text-muted-foreground hover:bg-muted/50 hover:text-foreground`}`,children:[e.id===j?(0,G.jsx)(u.span,{layoutId:`settings-nav-indicator`,className:`absolute inset-0 rounded-lg bg-muted`,transition:{type:`spring`,...a.indicator}}):null,(0,G.jsxs)(`div`,{className:`relative flex items-center gap-2.5`,children:[(0,G.jsx)(e.icon,{className:`h-4 w-4 shrink-0`}),(0,G.jsx)(`span`,{className:`min-w-0 truncate`,children:e.label}),t?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(Pn,{className:`ml-auto size-3.5 shrink-0 text-warning-text`,"aria-hidden":`true`}),(0,G.jsx)(`span`,{className:`sr-only`,children:`Update available`})]}):null]})]},e.label)}),S?(0,G.jsx)(`button`,{type:`button`,onClick:()=>A(`auth.signOut`,Tr),disabled:y,className:`cursor-pointer rounded-lg px-3 py-2 text-sm text-muted-foreground hover:bg-muted/50 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-2.5`,children:[y?(0,G.jsx)(N,{className:`h-4 w-4`}):(0,G.jsx)(Wn,{className:`h-4 w-4 shrink-0`}),(0,G.jsx)(`span`,{children:y?`Signing out...`:`Sign out`})]})}):null]})}),(0,G.jsxs)(`div`,{className:`min-w-0 flex-1 overflow-y-auto`,children:[(0,G.jsx)(`div`,{className:`sticky top-0 z-20 border-b border-border bg-background px-2 py-2 md:hidden`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(on,{label:`Open sidebar`,children:(0,G.jsx)(`button`,{type:`button`,onClick:d.openSidebar,className:`flex size-11 shrink-0 items-center justify-center rounded-md text-sm text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground`,"aria-label":`Open sidebar`,children:(0,G.jsx)(f,{className:`h-4 w-4 shrink-0`})})}),(0,G.jsxs)(Ne,{value:j,onValueChange:e=>{l(`/settings/${e}`)},children:[(0,G.jsx)(ke,{className:`h-11 min-w-0 flex-1`,"aria-label":`Settings section`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:yr.map(e=>(0,G.jsx)(F,{value:e.id,children:e.label},e.id))})})]}),S?(0,G.jsxs)(`button`,{type:`button`,onClick:()=>A(`auth.signOut`,Tr),disabled:y,className:`flex min-h-11 shrink-0 items-center gap-2 rounded-md border border-border bg-background px-3 py-2 text-sm text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50`,children:[y?(0,G.jsx)(N,{className:`h-4 w-4`}):(0,G.jsx)(Wn,{className:`h-4 w-4 shrink-0`}),(0,G.jsx)(`span`,{className:`sr-only`,children:y?`Signing out...`:`Sign out`})]}):null]})}),(0,G.jsxs)(`div`,{className:`w-full px-4 pb-32 pt-8 md:px-6 md:pt-16`,children:[pe?(0,G.jsx)(`div`,{className:`flex min-h-[240px] items-center justify-center rounded-2xl border border-border bg-card/40 px-4 py-6 text-sm text-muted-foreground`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),(0,G.jsx)(`span`,{children:`Loading machine settings…`})]})}):(0,G.jsxs)(`div`,{className:`mx-auto max-w-4xl kanna-settings-section-in`,children:[(0,G.jsxs)(`div`,{className:`pb-6`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-4 min-h-[34px]`,children:[(0,G.jsx)(`div`,{className:`text-lg font-semibold tracking-[-0.2px] text-foreground`,children:vr.label}),j===`general`?(0,G.jsx)(On,{variant:`outline`,onClick:()=>{l(`/settings/changelog`)},children:`Check for updates`}):null,j===`keybindings`?(0,G.jsxs)(On,{onClick:()=>A(`keybindings.openEditor`,()=>d.handleOpenExternalPath(`open_editor`,gt)),disabled:be,"aria-busy":be||void 0,icon:be?(0,G.jsx)(N,{className:`h-4 w-4`}):(0,G.jsx)(c,{className:`h-4 w-4`}),children:[`Open in `,d.editorLabel]}):null]}),(0,G.jsx)(`div`,{className:`mt-1 text-sm text-muted-foreground`,children:br})]}),j===`general`&&(0,G.jsxs)(G.Fragment,{children:[$t?(0,G.jsx)(`div`,{className:`mb-4 rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:$t}):null,(0,G.jsxs)(`div`,{className:`border-b border-border`,children:[(0,G.jsx)(q,{title:`Application Update`,description:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`span`,{children:[Mn,`.`]}),H?.lastCheckedAt?(0,G.jsxs)(`span`,{children:[` Last checked `,new Intl.DateTimeFormat(void 0,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`}).format(H.lastCheckedAt),`.`]}):null,H?.error?(0,G.jsxs)(`span`,{children:[` `,H.error]}):null]}),bordered:!1,children:(0,G.jsxs)(`div`,{className:`text-right text-sm text-foreground`,children:[(0,G.jsxs)(`div`,{children:[`Current: `,H?.currentVersion??Te]}),(0,G.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`Latest: `,H?.latestVersion??`Unknown`]})]})}),(0,G.jsx)(q,{title:`Theme`,description:`Choose between light, dark, or system appearance`,children:(0,G.jsx)(L,{value:m,onValueChange:Gn,options:dl,size:`sm`})}),(0,G.jsx)(q,{title:`Typography Scale`,description:Qe?`This device uses its own text size instead of the account default.`:`Choose how large text and UI elements appear across the app.`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsxs)(Ne,{value:nt,onValueChange:e=>{o(e)&&Kn(e)},children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:fl.map(e=>(0,G.jsx)(F,{value:e.value,children:e.label},e.value))})})]}),Qe?(0,G.jsx)(E,{type:`button`,variant:`link`,size:`sm`,onClick:et,children:`Use account default`}):null]})}),(0,G.jsx)(q,{title:`Chat Sounds`,description:`Play a pop when a chat starts waiting on you or the unread chat count increases`,children:(0,G.jsxs)(Ne,{disabled:xe,value:Be,onValueChange:e=>{Qt(e)&&Jn(e)},children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:pl.map(e=>(0,G.jsx)(F,{value:e.value,children:e.label},e.value))})})]})}),(0,G.jsx)(q,{title:`Chat Sound`,description:`The bundled sound used for chat notification playback and previews`,children:(0,G.jsxs)(Ne,{disabled:Se,value:Ve,onValueChange:e=>{Wt(e)&&Yn(e)},children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:es.map(e=>(0,G.jsx)(F,{value:e.value,children:e.label},e.value))})})]})}),(0,G.jsx)(q,{title:`Default Editor`,description:`Used when opening transcript links or files from the git diff menu`,alignStart:!0,children:(0,G.jsxs)(Ne,{value:Oe,onValueChange:e=>{zt(e)&&qn(e)},children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:_e.map(e=>(0,G.jsx)(F,{value:e.value,children:(0,G.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(fe,{preset:e.value,className:`h-4 w-4 shrink-0`}),(0,G.jsx)(`span`,{children:e.label})]})},e.value))})})]})}),Oe===`custom`?(0,G.jsx)(`div`,{className:`border-t border-border`,children:(0,G.jsxs)(`div`,{className:`flex justify-between gap-8 py-5 pl-6`,children:[(0,G.jsxs)(`div`,{className:`min-w-0 max-w-xl`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`Command Template`}),(0,G.jsxs)(`div`,{className:`mt-1 text-13 text-muted-foreground`,children:[`Include `,`{path}`,` and optionally `,`{line}`,` and `,`{column}`,` in your command.`]})]}),(0,G.jsxs)(`div`,{className:`flex min-w-0 max-w-[420px] flex-1 flex-col items-stretch gap-2`,children:[(0,G.jsx)(R,{type:`text`,value:Jt,onChange:e=>Xt(e.target.value),onBlur:Un,onKeyDown:e=>qo(e,Un),className:`font-mono`}),(0,G.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`Preview: `,(0,G.jsx)(`span`,{className:`font-mono`,children:sr})]})]})]})}):null,(0,G.jsx)(q,{title:`Terminal Scrollback`,description:`Lines retained for embedded terminal history`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsx)(R,{type:`number`,min:500,max:5e3,step:100,value:Et,onChange:e=>Ot(e.target.value),onBlur:Fn,onKeyDown:e=>Hn(e,Fn),className:`hide-number-steppers w-full text-left font-mono md:w-28 md:text-right`}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground md:text-right`,children:[500,`-`,5e3,` lines`,Ee===1e3?` (default)`:``]})]})}),(0,G.jsx)(q,{title:`Terminal Min Column Width`,description:`Minimum width for each terminal pane`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsx)(R,{type:`number`,min:250,max:900,step:10,value:kt,onChange:e=>jt(e.target.value),onBlur:In,onKeyDown:e=>Hn(e,In),className:`hide-number-steppers w-full text-left font-mono md:w-28 md:text-right`}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground md:text-right`,children:[250,`-`,900,` px`,De===450?` (default)`:``]})]})}),(0,G.jsx)(q,{title:`Tab Minimum Width`,description:`How narrow a pane tab may get before the strip scrolls instead of shrinking`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsx)(R,{type:`number`,min:60,max:200,step:10,value:At,onChange:e=>Mt(e.target.value),onBlur:Ln,onKeyDown:e=>Hn(e,Ln),className:`hide-number-steppers w-full text-left font-mono md:w-28 md:text-right`}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground md:text-right`,children:[60,`-`,200,` px`,Nt===60?` (default)`:``]})]})}),(0,G.jsx)(q,{title:`Max upload file size`,description:`Largest single file the chat upload endpoint accepts.`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-1.5 md:w-auto md:items-end`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2 md:justify-end`,children:[(0,G.jsx)(R,{type:`number`,min:1,max:51200,step:1,value:Ft,onChange:e=>It(e.target.value),onBlur:Rn,onKeyDown:e=>Hn(e,Rn),className:`hide-number-steppers w-full text-left font-mono tabular-nums md:w-24 md:text-right`,"aria-label":`Max upload file size in megabytes`}),(0,G.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:`MB`})]}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground tabular-nums md:text-right`,children:[1,`–`,51200,` MB · default `,mr.maxFileSizeMb]})]})}),(0,G.jsx)(q,{title:`Auto-resume on rate limit`,description:`When you hit a rate limit, automatically schedule "continue" at the reset time instead of asking. You can still cancel each one from the chat.`,children:(0,G.jsx)(Nl,{checked:Ke,onChange:qe})}),d.pushConfig?(0,G.jsx)(q,{title:`Push notifications`,description:`Get notified when a chat is waiting for you, finishes, or fails. Works on iPhone (after Add to Home Screen), Android, and desktop browsers.`,bordered:!1,alignStart:!0,children:(0,G.jsx)(vs,{permissionState:_t,config:d.pushConfig,projects:d.localProjects?.projects??[],currentDeviceId:xt,contactSubject:I?.push.contactSubject??``,contactSubjectDraft:ln,onContactSubjectDraftChange:un,onContactSubjectSave:async e=>{await d.socket.command({type:`settings.writeAppSettingsPatch`,patch:{push:{contactSubject:e}}})},onEnable:St,onDisable:Ct,onTest:async()=>{await d.socket.command({type:`push.test`})},onMuteToggle:async(e,t)=>{await d.socket.command({type:`push.setProjectMute`,localPath:e,muted:t})},onRemoveDevice:async e=>{await d.socket.command({type:`push.unsubscribe`,pushDeviceId:e})}})}):null,(0,G.jsx)(q,{title:`Anonymous Analytics`,description:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`span`,{children:`Help improve Kanna with anonymous product analytics. Kanna sends tracked event names plus a small set of event properties like current version, environment, update version info, and launch flags. No message content, prompts, file paths, or provider credentials are sent.`}),(0,G.jsxs)(`span`,{className:`mt-1 block`,children:[`Stored in `,I?.filePathDisplay??`~/.kanna/data/settings.json`,`.`,` `,(0,G.jsx)(`button`,{type:`button`,onClick:()=>tn(!0),className:`underline underline-offset-2 text-foreground hover:text-foreground/80`,children:`View tracked events`})]}),I?.warning?(0,G.jsx)(`span`,{className:`mt-1 block`,children:I.warning}):null]}),children:(0,G.jsx)(Ns,{pendingKey:`settings.analytics`,value:lr,onValueChange:Xn,options:ml,size:`sm`})}),(0,G.jsx)(q,{title:`Telemetry Tracing`,description:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`span`,{children:`Export OpenTelemetry traces and metrics (turn timings, subagent runs, process memory) to Kanna's observability collector so each install can be monitored. This machine reports under its computer name. Turning it off stops the export immediately.`}),(0,G.jsxs)(`span`,{className:`mt-1 block`,children:[`Collector: `,I?.telemetry?.endpoint??`not configured`,`. Stored in `,I?.filePathDisplay??`~/.kanna/data/settings.json`,`.`]})]}),children:(0,G.jsx)(Ns,{pendingKey:`settings.telemetry`,value:ur,onValueChange:Zn,options:ml,size:`sm`})})]}),(0,G.jsxs)(`div`,{className:`border-b border-border`,children:[nn?(0,G.jsx)(`div`,{className:`mb-4 rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:nn}):null,(0,G.jsx)(q,{title:`Cloudflare Tunnel`,description:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`span`,{children:[`When enabled, Claude can call the `,(0,G.jsx)(`code`,{className:`rounded bg-muted px-1 py-0.5 font-mono text-xs`,children:`expose_port`}),` tool to expose a local port via Cloudflare Tunnel. The mode below controls whether each call requires your approval or is exposed automatically. Requires`,` `,(0,G.jsx)(`code`,{className:`rounded bg-muted px-1 py-0.5 font-mono text-xs`,children:`cloudflared`}),` `,`to be installed.`]}),(0,G.jsxs)(`span`,{className:`mt-1 block`,children:[`Stored in `,I?.filePathDisplay??`~/.kanna/data/settings.json`,`.`]})]}),bordered:!1,children:(0,G.jsx)(Ns,{pendingKey:P(kl,`enabled`),value:pr,onValueChange:e=>Qn({enabled:e===`enabled`}),options:hl,size:`sm`})}),dr.enabled&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(q,{title:`Tool mode`,description:`Always ask: each expose_port call shows an accept card. Auto-expose: expose_port calls spawn cloudflared immediately without prompting.`,children:(0,G.jsx)(Ns,{pendingKey:P(kl,`mode`),value:dr.mode,onValueChange:e=>Qn({mode:e}),options:gl,size:`sm`})}),(0,G.jsx)(q,{title:`cloudflared path`,description:`Path to the cloudflared binary. Defaults to the one found on $PATH.`,children:(0,G.jsx)(R,{value:sn,onChange:e=>cn(e.target.value),onBlur:()=>A(Al,()=>Qn({cloudflaredPath:sn})),readOnly:ye,"aria-busy":ye||void 0,placeholder:`cloudflared`,className:`w-full font-mono md:w-64`})})]})]}),(0,G.jsx)(`div`,{className:`border-b border-border`,children:(0,G.jsx)(q,{title:`Public share links`,description:`Default expiry for read-only chat share links. Owners can revoke any link manually at any time.`,bordered:!1,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2 md:justify-end`,children:[(0,G.jsx)(R,{type:`number`,min:1,step:1,value:fn,onChange:e=>pn(e.target.value),onBlur:Vn,onKeyDown:e=>Hn(e,Vn),className:`hide-number-steppers w-full text-left font-mono tabular-nums md:w-24 md:text-right`,"aria-label":`Default share link expiry in hours`}),(0,G.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:`hours`})]}),(0,G.jsx)(`div`,{className:`text-left text-xs text-muted-foreground tabular-nums md:text-right`,children:`Minimum 1 hour · default 24`})]})})})]}),j===`providers`&&(0,G.jsxs)(`div`,{className:`border-b border-border`,children:[(0,G.jsx)(q,{title:`Claude OAuth tokens`,description:`Manage multiple Claude OAuth tokens. Kanna switches automatically when one hits its rate limit.`,bordered:!1,alignStart:!0,children:(0,G.jsx)(`div`,{className:`w-full md:w-[420px]`,children:(0,G.jsx)(Ko,{tokens:I?.claudeAuth.tokens??[],concurrencyDefault:I?.claudeAuth.concurrencyDefault??1,onWrite:En,onTest:Dn})})}),(0,G.jsx)(q,{title:`Claude session idle timeout`,description:`Stop a Claude session after this many minutes without user activity. Lower values free memory sooner; higher values keep cold-start latency low.`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsx)(R,{type:`number`,min:1,max:60,step:1,value:Vt,onChange:e=>Ht(e.target.value),onBlur:zn,onKeyDown:e=>Hn(e,zn),className:`hide-number-steppers w-full text-left font-mono md:w-28 md:text-right`}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground md:text-right`,children:[1,`–`,60,` min · default `,Math.round(Ut.idleTimeoutMs/6e4)]})]})}),(0,G.jsx)(q,{title:`Max concurrent Claude sessions`,description:`Hard cap on resident Claude processes. Excess sessions are evicted LRU; their next activation cold-starts.`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsx)(R,{type:`number`,min:1,max:16,step:1,value:Gt,onChange:e=>qt(e.target.value),onBlur:Bn,onKeyDown:e=>Hn(e,Bn),className:`hide-number-steppers w-full text-left font-mono md:w-28 md:text-right`}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground md:text-right`,children:[1,`–`,16,` · default `,Ut.maxConcurrent]})]})}),(0,G.jsx)(q,{title:`Default Provider`,description:`The default harness used for new chats before a provider is locked by an existing session.`,children:(0,G.jsxs)(Ne,{value:rt,onValueChange:e=>{(e===`last_used`||Zt(e))&&$n(e)},children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsxs)(Me,{children:[(0,G.jsx)(F,{value:`last_used`,children:`Last Used`}),pt.map(e=>(0,G.jsx)(F,{value:e.id,children:e.label},e.id))]})})]})}),(0,G.jsx)(Mo,{state:d}),(0,G.jsx)(q,{title:`Claude Code Defaults`,description:`Saved defaults when using Claude Code.`,alignStart:!0,children:(0,G.jsx)(`div`,{className:`max-w-[420px]`,children:(0,G.jsx)(ge,{availableProviders:pt,selectedProvider:`claude`,showProviderPicker:!1,model:it.claude.model,modelOptions:it.claude.modelOptions,onModelChange:(e,t)=>{er(`claude`,t)},onModelOptionChange:e=>{e.type===`claudeReasoningEffort`?tr(`claude`,{reasoningEffort:e.effort}):e.type===`contextWindow`&&tr(`claude`,{contextWindow:e.contextWindow})},planMode:it.claude.planMode,onPlanModeChange:e=>nr(`claude`,e),includePlanMode:!0,className:`justify-start flex-wrap`})})}),(0,G.jsx)(q,{title:`Codex Defaults`,description:`Saved defaults when using Codex.`,alignStart:!0,children:(0,G.jsx)(`div`,{className:`max-w-[420px]`,children:(0,G.jsx)(ge,{availableProviders:pt,selectedProvider:`codex`,showProviderPicker:!1,model:it.codex.model,modelOptions:it.codex.modelOptions,onModelChange:(e,t)=>{er(`codex`,t)},onModelOptionChange:e=>{e.type===`codexReasoningEffort`?tr(`codex`,{reasoningEffort:e.effort}):e.type===`fastMode`&&tr(`codex`,{fastMode:e.fastMode})},planMode:it.codex.planMode,onPlanModeChange:e=>nr(`codex`,e),includePlanMode:!0,className:`justify-start flex-wrap`})})}),(0,G.jsx)(q,{title:`Quick Response SDK`,description:wr,alignStart:!0,children:(0,G.jsxs)(`div`,{className:`flex w-full max-w-[420px] flex-col gap-3`,children:[hn?(0,G.jsx)(`div`,{className:`rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:hn}):null,Ge?.warning?(0,G.jsx)(`div`,{className:`rounded-lg border border-border bg-card/30 px-4 py-3 text-sm text-muted-foreground`,children:Ge.warning}):null,(0,G.jsxs)(Ne,{value:V.provider,disabled:ve,onValueChange:e=>{Bt(e)&&ir(e)},children:[(0,G.jsx)(ke,{className:`w-full`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:_l.map(e=>(0,G.jsx)(F,{value:e.value,children:e.label},e.value))})})]}),V.provider===`custom`?(0,G.jsx)(R,{value:V.baseUrl,onChange:e=>mn({...V,baseUrl:e.target.value}),onBlur:()=>ar(),onKeyDown:e=>qo(e,ar),readOnly:ve,placeholder:`https://your-provider.example/v1`}):null,(0,G.jsx)(R,{type:`password`,value:V.apiKey,onChange:e=>mn({...V,apiKey:e.target.value}),onBlur:()=>ar(),onKeyDown:e=>qo(e,ar),readOnly:ve,placeholder:`API key`}),(0,G.jsx)(R,{value:V.model,onChange:e=>mn({...V,model:e.target.value}),onBlur:()=>ar(),onKeyDown:e=>qo(e,ar),readOnly:ve,placeholder:`Model id`})]})})]}),j===`keybindings`&&(0,G.jsx)(Zo,{state:d}),j===`skills`&&(0,G.jsx)(el,{state:d}),j===`plugins`&&(0,G.jsx)(js,{state:d}),j===`kanna-plugins`&&ft&&(0,G.jsx)(ol,{}),j===`subagents`&&(0,G.jsx)(Lr,{state:d}),j===`models`&&(0,G.jsx)(ro,{state:d}),le&&(0,G.jsx)(le,{state:d}),j===`snippets`&&(0,G.jsx)(Bo,{state:d}),j===`instructions`&&(0,G.jsx)(Pl,{state:d}),![`general`,`providers`,`keybindings`,`skills`,`plugins`,`subagents`,`models`,`mcp-servers`,`mcp-sources`,`remote-mcp`,`service-bus`,`beacons`,`snippets`,`instructions`].includes(j)&&(0,G.jsx)(jl,{status:_,releases:w,error:se,onRetry:or,updateSnapshot:H,currentVersion:Te,onInstallUpdate:e=>d.handleInstallUpdate(e),onCheckForUpdates:()=>d.handleCheckForUpdates({force:!0}),onForceReload:()=>d.handleForceReload()})]},j),d.commandError?(0,G.jsxs)(`div`,{className:`mx-auto mt-4 flex max-w-4xl items-start gap-3 rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:[(0,G.jsx)(Fe,{className:`mt-0.5 h-4 w-4 flex-shrink-0`}),(0,G.jsx)(`span`,{children:d.commandError})]}):null]})]})]}),K?(0,G.jsx)(`div`,{className:`absolute bottom-0 left-0 right-0 border-t border-border bg-background`,children:(0,G.jsx)(`div`,{className:`px-6 py-[14.25px]`,children:(0,G.jsxs)(`div`,{className:`grid gap-3 text-xs text-muted-foreground grid-cols-2 lg:grid-cols-4`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`mb-1 tracking-wide text-xs text-muted-foreground/80`,children:`Machine`}),(0,G.jsx)(`div`,{className:`text-foreground/80`,children:Ce})]}),(0,G.jsxs)(`div`,{className:`hidden md:block`,children:[(0,G.jsx)(`div`,{className:`mb-1 tracking-wide text-xs text-muted-foreground/80`,children:`Connection`}),(0,G.jsx)(`div`,{className:`text-foreground/80`,children:d.connectionStatus})]}),(0,G.jsxs)(`div`,{className:`hidden md:block`,children:[(0,G.jsx)(`div`,{className:`mb-1 tracking-wide text-xs text-muted-foreground/80`,children:`Projects Indexed`}),(0,G.jsx)(`div`,{className:`text-foreground/80`,children:we})]}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`mb-1 tracking-wide text-xs text-muted-foreground/80`,children:`App Version`}),(0,G.jsx)(`div`,{className:`text-foreground/80`,children:Te})]})]})})}):null,(0,G.jsx)(Ye,{open:en,onOpenChange:tn,children:(0,G.jsxs)(Je,{size:`lg`,children:[(0,G.jsxs)(Ze,{className:`space-y-4`,children:[(0,G.jsx)($e,{children:`Tracked Events`}),(0,G.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:`Kanna sends these event names plus the limited property keys below, depending on the event type.`}),(0,G.jsxs)(`div`,{className:`max-h-[60vh] overflow-auto rounded-lg border border-border bg-muted/40 p-3`,children:[(0,G.jsx)(`div`,{className:`text-xs font-medium tracking-wide text-muted-foreground`,children:`Event Names`}),(0,G.jsx)(`ul`,{className:`mt-3 space-y-2 text-sm`,children:cr.map(e=>(0,G.jsx)(`li`,{className:`font-mono text-foreground`,children:e},e))}),(0,G.jsx)(`div`,{className:`mt-6 text-xs font-medium tracking-wide text-muted-foreground`,children:`Property Keys`}),(0,G.jsx)(`ul`,{className:`mt-3 space-y-2 text-sm`,children:_r.map(e=>(0,G.jsx)(`li`,{className:`font-mono text-foreground`,children:e},e))})]})]}),(0,G.jsx)(Xe,{children:(0,G.jsx)(E,{variant:`secondary`,size:`sm`,onClick:()=>tn(!1),children:`Close`})})]})}),(0,G.jsx)(Ye,{open:Cn,onOpenChange:wn,children:(0,G.jsxs)(Je,{size:`lg`,children:[(0,G.jsxs)(Ze,{className:`space-y-4`,children:[(0,G.jsx)($e,{children:`Validation Error`}),(0,G.jsx)(`pre`,{className:`max-h-[60vh] overflow-auto rounded-lg border border-border bg-muted p-3 text-xs font-mono whitespace-pre-wrap break-words`,children:xr})]}),(0,G.jsx)(Xe,{children:(0,G.jsx)(E,{variant:`secondary`,size:`sm`,onClick:()=>wn(!1),children:`Close`})})]})})]})}export{Fl as SettingsPage};
|
|
17
|
+
`).map(e=>e.trim()).filter(e=>e.length>0),retention:e.retention,storage:e.storage,maxAgeDays:tc(e.maxAgeDays),maxBytesMb:tc(e.maxBytesMb),maxMsgs:tc(e.maxMsgs),discard:e.discard,duplicateWindowSec:tc(e.duplicateWindowSec),replicas:tc(e.replicas)}}function rc(e){return{durableName:e.durableName,filterSubject:e.filterSubject,ackPolicy:e.ackPolicy,deliverPolicy:e.deliverPolicy,maxAckPending:String(e.maxAckPending),ackWaitSec:String(e.ackWaitSec)}}function ic(e){return{durableName:``,filterSubject:`${e}.>`,ackPolicy:`explicit`,deliverPolicy:`all`,maxAckPending:`1000`,ackWaitSec:`30`}}function ac(e){return{durableName:e.durableName.trim(),filterSubject:e.filterSubject.trim(),ackPolicy:e.ackPolicy,deliverPolicy:e.deliverPolicy,maxAckPending:tc(e.maxAckPending),ackWaitSec:tc(e.ackWaitSec)}}function oc(e){return{maxMemoryStoreMb:String(e.maxMemoryStoreMb),maxFileStoreMb:String(e.maxFileStoreMb),port:String(e.port),logLevel:e.logLevel}}function sc(e){let t=e.port.trim().toLowerCase()===`auto`?$s:tc(e.port);return{maxMemoryStoreMb:tc(e.maxMemoryStoreMb),maxFileStoreMb:tc(e.maxFileStoreMb),port:t,logLevel:e.logLevel}}function cc(e,t){return Ct({...e,...t})}function lc(e,t){let n=[];return e.retention!==t.retention&&n.push(`retention`),e.storage!==t.storage&&n.push(`storage`),e.replicas!==t.replicas&&n.push(`replicas`),n}function uc(e,t){return t.maxAgeDays<e.maxAgeDays||t.maxBytesMb<e.maxBytesMb}function dc(e,t){return JSON.stringify(ec(e))===JSON.stringify(t)}function $({label:e,note:t,warn:n=!1,children:r}){return(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-1.5`,children:[(0,G.jsx)(`div`,{className:`text-13 font-medium text-foreground`,children:e}),r,t?(0,G.jsx)(`div`,{className:D(`text-xs`,n?`text-warning-text`:`text-muted-foreground`),children:t}):null]})}function fc({label:e,value:t}){return(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col`,children:[(0,G.jsx)(`dt`,{className:`text-xs text-muted-foreground`,children:e}),(0,G.jsx)(`dd`,{className:`font-mono text-13 tabular-nums text-foreground`,children:t})]})}function pc({problems:e}){return e.length===0?null:(0,G.jsx)(`ul`,{className:`flex flex-col gap-0.5 text-xs text-destructive-text`,role:`alert`,children:e.map(e=>(0,G.jsx)(`li`,{children:e},e))})}var mc=P(`settings.serviceBus`,`consumers`),hc=[{value:`explicit`,label:`Explicit`},{value:`all`,label:`All`},{value:`none`,label:`None`}],gc=[{value:`all`,label:`All`},{value:`new`,label:`New`},{value:`last`,label:`Last`}];function _c({consumer:e,onEdit:t,onRemove:n}){let r=g(t=>t.status.consumers.find(t=>t.name===e.durableName)),i=M(P(`settings.serviceBus`,`consumer`,e.durableName));return(0,G.jsxs)(`li`,{className:`flex flex-col gap-1 px-4 py-3 md:flex-row md:items-center md:justify-between`,children:[(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`div`,{className:`truncate text-sm font-medium text-foreground`,children:e.durableName}),(0,G.jsxs)(`div`,{className:`truncate font-mono text-xs text-muted-foreground`,children:[e.filterSubject||`all subjects`,` · ack `,e.ackPolicy,` · deliver `,e.deliverPolicy]})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsx)(`span`,{className:`font-mono text-xs tabular-nums text-muted-foreground`,children:r?`${String(r.pending)} pending · ${String(r.ackPending)} ack pending`:`not reported yet`}),(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`icon-sm`,"aria-label":`Edit ${e.durableName}`,onClick:t,children:(0,G.jsx)(Le,{className:`h-4 w-4`})}),(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`icon-sm`,"aria-label":`Remove ${e.durableName}`,pending:i,onClick:n,children:(0,G.jsx)(Ve,{className:`h-4 w-4`})})]})]})}function vc({state:e}){let t=z(dt);g(ne);let n=Q(e=>e.consumerEditor),r=Q(e=>e.openConsumerEditor),i=Q(e=>e.editConsumer),a=Q(e=>e.closeConsumerEditor),o=Q(e=>e.setError),s=M(mc),c=(0,W.useCallback)(async t=>{o(null);try{await e.handleWriteAppSettings({serviceBus:{consumers:t}}),a()}catch(e){o(T(e))}},[e,a,o]),l=n?ac(n.draft):null,u=n?.target.kind===`edit`?n.target.durableName:null,d=t.consumers.filter(e=>e.durableName!==u),f=l?cc(t,{consumers:[...d,l]}):[],p=(0,W.useCallback)(async()=>{if(l===null)return;let e=t.consumers.map(e=>e.durableName===u?l:e);await c(u===null?[...t.consumers,l]:e)},[l,u,t.consumers,c]);return(0,G.jsxs)(`details`,{className:`rounded-lg border border-border`,children:[(0,G.jsxs)(`summary`,{className:`cursor-pointer px-4 py-3 text-sm font-medium text-foreground`,children:[`Consumers `,(0,G.jsx)(`span`,{className:`font-mono text-xs tabular-nums text-muted-foreground`,children:t.consumers.length})]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-3 border-t border-border py-3`,children:[(0,G.jsx)(`p`,{className:`px-4 text-13 text-muted-foreground`,children:`Durable pull consumers Kanna creates on the stream. Kanna removes only the ones it created, and never touches consumers you add elsewhere.`}),t.consumers.length===0?(0,G.jsx)(`div`,{className:`px-4 text-13 text-muted-foreground`,children:`No consumers configured`}):(0,G.jsx)(`ul`,{className:`flex flex-col divide-y divide-border border-y border-border`,children:t.consumers.map(e=>(0,G.jsx)(_c,{consumer:e,onEdit:()=>r({kind:`edit`,durableName:e.durableName},rc(e)),onRemove:()=>A(P(`settings.serviceBus`,`consumer`,e.durableName),()=>c(t.consumers.filter(t=>t.durableName!==e.durableName)))},e.durableName))}),n?(0,G.jsxs)(`div`,{className:`mx-4 flex flex-col gap-4 rounded-lg border border-border p-4`,children:[(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-2`,children:[(0,G.jsx)($,{label:`Durable name`,children:(0,G.jsx)(R,{"aria-label":`Durable name`,value:n.draft.durableName,disabled:u!==null,onChange:e=>i({durableName:e.target.value}),spellCheck:!1})}),(0,G.jsx)($,{label:`Filter subject`,note:`Leave empty for every subject in the stream`,children:(0,G.jsx)(R,{"aria-label":`Filter subject`,value:n.draft.filterSubject,onChange:e=>i({filterSubject:e.target.value}),spellCheck:!1})})]}),(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-2`,children:[(0,G.jsx)($,{label:`Acknowledgement`,note:u===null?void 0:`Cannot change on an existing consumer; remove and add it again`,children:(0,G.jsx)(L,{size:`sm`,value:n.draft.ackPolicy,onValueChange:e=>i({ackPolicy:e}),options:hc})}),(0,G.jsx)($,{label:`Deliver`,children:(0,G.jsx)(L,{size:`sm`,value:n.draft.deliverPolicy,onValueChange:e=>i({deliverPolicy:e}),options:gc})}),(0,G.jsx)($,{label:`Max ack pending`,children:(0,G.jsx)(R,{"aria-label":`Max ack pending`,inputMode:`numeric`,className:`tabular-nums`,value:n.draft.maxAckPending,onChange:e=>i({maxAckPending:e.target.value})})}),(0,G.jsx)($,{label:`Ack wait (s)`,children:(0,G.jsx)(R,{"aria-label":`Ack wait in seconds`,inputMode:`numeric`,className:`tabular-nums`,value:n.draft.ackWaitSec,onChange:e=>i({ackWaitSec:e.target.value})})})]}),(0,G.jsx)(pc,{problems:f}),(0,G.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`sm`,disabled:s,onClick:a,children:`Cancel`}),(0,G.jsx)(E,{type:`button`,size:`sm`,disabled:f.length>0,pending:s,onClick:()=>A(mc,p),children:`Save consumer`})]})]}):(0,G.jsx)(`div`,{className:`px-4`,children:(0,G.jsxs)(E,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>r({kind:`new`},ic(t.stream.subjectPrefix)),children:[(0,G.jsx)(Re,{className:`mr-1.5 h-4 w-4`}),`Add consumer`]})})]})]})}var yc=P(`settings.serviceBus`,`embedded`),bc=P(`serviceBus.resetStore`),xc=[{value:`info`,label:`Info`},{value:`debug`,label:`Debug`}];function Sc({state:e}){let t=sn(),n=z(dt),r=oc(n.embedded),i=Q(e=>e.embedded)??r,a=Q(e=>e.editEmbedded),o=Q(e=>e.discardEmbedded),s=Q(e=>e.resetConfirm),c=Q(e=>e.askResetConfirm),l=Q(e=>e.cancelResetConfirm),u=Q(e=>e.setError),d=M(yc),f=M(bc),p=cc(n,{embedded:sc(i)}),m=JSON.stringify(r)!==JSON.stringify(i),h=e=>a(r,e),g=(0,W.useCallback)(async()=>{u(null);try{await e.handleWriteAppSettings({serviceBus:{embedded:sc(i)}}),o()}catch(e){u(T(e))}},[e,i,o,u]),_=(0,W.useCallback)(async()=>{u(null);try{await wn(t,{type:`serviceBus.resetStore`})}catch(e){u(T(e))}finally{l()}},[t,l,u]);return(0,G.jsxs)(`details`,{className:`rounded-lg border border-border`,children:[(0,G.jsx)(`summary`,{className:`cursor-pointer px-4 py-3 text-sm font-medium text-foreground`,children:`Embedded server`}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 border-t border-border px-4 py-4`,children:[(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-3`,children:[(0,G.jsx)($,{label:`Memory store (MB)`,children:(0,G.jsx)(R,{"aria-label":`Memory store in megabytes`,inputMode:`numeric`,className:`tabular-nums`,value:i.maxMemoryStoreMb,onChange:e=>h({maxMemoryStoreMb:e.target.value})})}),(0,G.jsx)($,{label:`File store (MB)`,children:(0,G.jsx)(R,{"aria-label":`File store in megabytes`,inputMode:`numeric`,className:`tabular-nums`,value:i.maxFileStoreMb,onChange:e=>h({maxFileStoreMb:e.target.value})})}),(0,G.jsx)($,{label:`Port`,note:`auto picks a free loopback port`,children:(0,G.jsx)(R,{"aria-label":`Port`,inputMode:`numeric`,className:`tabular-nums`,value:i.port,onChange:e=>h({port:e.target.value})})})]}),(0,G.jsx)($,{label:`Server log level`,children:(0,G.jsx)(L,{size:`sm`,value:i.logLevel,onValueChange:e=>h({logLevel:e}),options:xc})}),(0,G.jsx)(pc,{problems:p}),(0,G.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`sm`,disabled:!m||d,onClick:o,children:`Revert`}),(0,G.jsx)(E,{type:`button`,size:`sm`,disabled:!m||p.length>0,pending:d,onClick:()=>A(yc,g),children:`Save server`})]}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-2 border-t border-border pt-4`,children:[(0,G.jsx)(`div`,{className:`text-13 font-medium text-foreground`,children:`Reset store`}),(0,G.jsx)(`p`,{className:`text-13 text-muted-foreground`,children:`Stops the embedded server, deletes every message it holds and starts it again. Kanna's own history is not touched.`}),s?(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(E,{type:`button`,variant:`destructive`,size:`sm`,pending:f,onClick:()=>A(bc,_),children:`Delete the store`}),(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`sm`,disabled:f,onClick:l,children:`Cancel`})]}):(0,G.jsx)(`div`,{children:(0,G.jsx)(E,{type:`button`,variant:`outline`,size:`sm`,onClick:c,children:`Reset store`})})]})]})]})}var Cc=P(`settings.serviceBus`,`stream`),wc=`Changing this requires recreating the stream`,Tc=`Lowering this drops older messages`,Ec=[{value:`limits`,label:`Limits`},{value:`interest`,label:`Interest`},{value:`workqueue`,label:`Work queue`}],Dc=[{value:`file`,label:`File`},{value:`memory`,label:`Memory`}],Oc=[{value:`old`,label:`Oldest`},{value:`new`,label:`Newest`}];function kc({state:e}){let t=z(dt),n=ec(t.stream),r=Q(e=>e.stream)??n,i=Q(e=>e.editStream),a=Q(e=>e.discardStream),o=Q(e=>e.setError),s=M(Cc),c=nc(r),l=cc(t,{stream:c}),u=!dc(t.stream,r),d=lc(t.stream,c),f=uc(t.stream,c),p=e=>i(n,e),m=(0,W.useCallback)(async()=>{o(null);try{await e.handleWriteAppSettings({serviceBus:{stream:nc(r)}}),a()}catch(e){o(T(e))}},[e,r,a,o]);return(0,G.jsxs)(`details`,{className:`rounded-lg border border-border`,children:[(0,G.jsx)(`summary`,{className:`cursor-pointer px-4 py-3 text-sm font-medium text-foreground`,children:`Stream`}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 border-t border-border px-4 py-4`,children:[(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-2`,children:[(0,G.jsx)($,{label:`Stream name`,children:(0,G.jsx)(R,{"aria-label":`Stream name`,value:r.name,onChange:e=>p({name:e.target.value}),spellCheck:!1})}),(0,G.jsx)($,{label:`Subject prefix`,note:`Kanna publishes under ${r.subjectPrefix||`…`}.>`,children:(0,G.jsx)(R,{"aria-label":`Subject prefix`,value:r.subjectPrefix,onChange:e=>p({subjectPrefix:e.target.value}),spellCheck:!1})})]}),(0,G.jsx)($,{label:`Extra subjects`,note:`One per line; the stream also captures these`,children:(0,G.jsx)(ln,{"aria-label":`Extra subjects`,rows:2,value:r.extraSubjects,onChange:e=>p({extraSubjects:e.target.value}),spellCheck:!1})}),(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-3`,children:[(0,G.jsx)($,{label:`Retention`,note:wc,warn:d.includes(`retention`),children:(0,G.jsx)(L,{size:`sm`,value:r.retention,onValueChange:e=>p({retention:e}),options:Ec})}),(0,G.jsx)($,{label:`Storage`,note:wc,warn:d.includes(`storage`),children:(0,G.jsx)(L,{size:`sm`,value:r.storage,onValueChange:e=>p({storage:e}),options:Dc})}),(0,G.jsx)($,{label:`Replicas`,note:wc,warn:d.includes(`replicas`),children:(0,G.jsx)(R,{"aria-label":`Replicas`,inputMode:`numeric`,className:`tabular-nums`,value:r.replicas,onChange:e=>p({replicas:e.target.value})})})]}),(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-3`,children:[(0,G.jsx)($,{label:`Max age (days)`,note:Tc,warn:f,children:(0,G.jsx)(R,{"aria-label":`Max age in days`,inputMode:`numeric`,className:`tabular-nums`,value:r.maxAgeDays,onChange:e=>p({maxAgeDays:e.target.value})})}),(0,G.jsx)($,{label:`Max bytes (MB)`,note:Tc,warn:f,children:(0,G.jsx)(R,{"aria-label":`Max bytes in megabytes`,inputMode:`numeric`,className:`tabular-nums`,value:r.maxBytesMb,onChange:e=>p({maxBytesMb:e.target.value})})}),(0,G.jsx)($,{label:`Max messages`,note:`-1 means unlimited`,children:(0,G.jsx)(R,{"aria-label":`Max messages`,inputMode:`numeric`,className:`tabular-nums`,value:r.maxMsgs,onChange:e=>p({maxMsgs:e.target.value})})})]}),(0,G.jsxs)(`div`,{className:`grid gap-4 md:grid-cols-3`,children:[(0,G.jsx)($,{label:`When full, discard`,children:(0,G.jsx)(L,{size:`sm`,value:r.discard,onValueChange:e=>p({discard:e}),options:Oc})}),(0,G.jsx)($,{label:`Duplicate window (s)`,note:`Messages with the same id inside this window are stored once`,children:(0,G.jsx)(R,{"aria-label":`Duplicate window in seconds`,inputMode:`numeric`,className:`tabular-nums`,value:r.duplicateWindowSec,onChange:e=>p({duplicateWindowSec:e.target.value})})})]}),(0,G.jsx)(pc,{problems:l}),(0,G.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`sm`,disabled:!u||s,onClick:a,children:`Revert`}),(0,G.jsx)(E,{type:`button`,size:`sm`,disabled:!u||l.length>0,pending:s,onClick:()=>A(Cc,m),children:`Save stream`})]})]})]})}var Ac=P(`settings.serviceBus`,`enabled`),jc=P(`settings.serviceBus`,`mode`),Mc=P(`settings.serviceBus`,`start`),Nc=P(`settings.serviceBus`,`connection`),Pc=P(`settings.serviceBus`,`token`),Fc=[{value:`enabled`,label:`Enabled`},{value:`disabled`,label:`Disabled`}],Ic=[{value:`embedded`,label:`Embedded`},{value:`external`,label:`External`}];function Lc(){let e=g(ne),t=e=>e.toLocaleString(`en-US`);return(0,G.jsxs)(`dl`,{className:`grid grid-cols-2 gap-x-6 gap-y-3 md:grid-cols-4`,children:[e.stream?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(fc,{label:`Messages`,value:t(e.stream.messages)}),(0,G.jsx)(fc,{label:`Size`,value:Qs(e.stream.bytes)}),(0,G.jsx)(fc,{label:`First seq`,value:t(e.stream.firstSeq)}),(0,G.jsx)(fc,{label:`Last seq`,value:t(e.stream.lastSeq)})]}):null,(0,G.jsx)(fc,{label:`Published`,value:t(e.published)}),(0,G.jsx)(fc,{label:`Dropped`,value:t(e.dropped)}),(0,G.jsx)(fc,{label:`Queued`,value:t(e.queued)}),e.serverVersion?(0,G.jsx)(fc,{label:`Server`,value:`v${e.serverVersion}${e.port?` · :${String(e.port)}`:``}`}):null]})}function Rc({state:e}){let t=z(dt),n=Q(e=>e.connection)??{url:t.url,token:``},r=Q(e=>e.editConnection),i=Q(e=>e.discardConnection),a=Q(e=>e.setError),o=M(Nc),s=M(Pc),c=n.url.trim(),l=cc({...t,mode:`external`},{url:c}),u=c!==t.url,d=(0,W.useCallback)(async()=>{a(null);try{await e.handleWriteAppSettings({serviceBus:{url:c}}),i()}catch(e){a(T(e))}},[e,c,i,a]),f=(0,W.useCallback)(async t=>{a(null);try{await e.handleWriteAppSettings({serviceBus:{token:t}}),i()}catch(e){a(T(e))}},[e,i,a]),p={url:t.url,token:``};return(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 border-t border-border py-5`,children:[(0,G.jsx)($,{label:`Server URL`,note:`Where your own nats-server listens, for example nats://nats.internal:4222`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(R,{"aria-label":`Server URL`,value:n.url,onChange:e=>r(p,{url:e.target.value}),spellCheck:!1}),(0,G.jsx)(E,{type:`button`,size:`sm`,disabled:!u||l.length>0,pending:o,onClick:()=>A(Nc,d),children:`Save`})]})}),(0,G.jsx)($,{label:`Token`,note:t.tokenHint?`A token ending in ${t.tokenHint} is stored. Kanna never shows it again.`:`No token stored`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(R,{"aria-label":`Token`,type:`password`,autoComplete:`off`,value:n.token,placeholder:t.tokenHint?`Enter a new token to replace it`:`Token`,onChange:e=>r(p,{token:e.target.value})}),(0,G.jsx)(E,{type:`button`,size:`sm`,disabled:n.token.trim()===``,pending:s,onClick:()=>A(Pc,()=>f(n.token.trim())),children:`Replace token`}),(0,G.jsx)(E,{type:`button`,variant:`ghost`,size:`sm`,disabled:t.tokenHint===null,onClick:()=>A(Pc,()=>f(null)),children:`Clear`})]})}),(0,G.jsx)(pc,{problems:l})]})}function zc({state:e}){let t=z(dt),n=g(ne),r=Q(e=>e.error),i=Q(e=>e.setError),a=M(Mc),o=(0,W.useCallback)(async t=>{i(null);try{await e.handleWriteAppSettings({serviceBus:t})}catch(e){i(T(e))}},[e,i]),s=(0,W.useCallback)(e=>o({enabled:e===`enabled`}),[o]),c=(0,W.useCallback)(e=>o({mode:e}),[o]),l=(0,W.useCallback)(async()=>{t.enabled&&await o({enabled:!1}),await o({enabled:!0})},[t.enabled,o]),u=t.mode===`embedded`,d=u&&(!t.enabled||n.state===`error`);return(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-1 pb-2`,children:[(0,G.jsx)(`h2`,{className:`text-base font-medium`,children:`Service bus`}),(0,G.jsx)(`p`,{className:`max-w-[65ch] text-sm text-muted-foreground`,children:`Mirror every durable event Kanna records into a NATS JetStream stream, so other programs can read them with the nats CLI or any NATS client. Kanna's own history is not affected, and a bus outage never blocks a chat.`}),(0,G.jsx)(`p`,{className:`max-w-[65ch] text-13 text-muted-foreground`,children:`Embedded mode downloads nats-server v2.15.1 (~7 MB) from GitHub on first start and runs it on loopback with a private token.`})]}),(0,G.jsxs)(`div`,{className:`border-b border-border`,children:[(0,G.jsx)(q,{title:`Mirror to NATS`,description:`When off, nothing is downloaded, started or published.`,children:(0,G.jsx)(Ns,{pendingKey:Ac,value:t.enabled?`enabled`:`disabled`,onValueChange:s,options:Fc,size:`sm`})}),(0,G.jsx)(q,{title:`Server`,description:`Embedded runs a nats-server that Kanna manages. External connects to one you run.`,children:(0,G.jsx)(Ns,{pendingKey:jc,value:t.mode,onValueChange:c,options:Ic,size:`sm`})}),(0,G.jsx)(q,{title:`Status`,description:n.lastError?(0,G.jsx)(`span`,{className:`text-destructive-text`,children:n.lastError}):`Live state of the mirror.`,alignStart:!0,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsx)(hn,{tone:Xs(n.state),label:Ys(n.state)}),d?(0,G.jsx)(E,{type:`button`,size:`sm`,pending:a,onClick:()=>A(Mc,l),children:t.enabled?`Retry`:`Install & start`}):null]})})]}),r?(0,G.jsx)(`div`,{className:`text-xs text-destructive-text`,role:`alert`,children:r}):null,t.enabled||n.state!==`disabled`?(0,G.jsx)(`div`,{className:`py-3`,children:(0,G.jsx)(Lc,{})}):null,u?null:(0,G.jsx)(Rc,{state:e}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-3 pt-2`,children:[(0,G.jsx)(kc,{state:e}),(0,G.jsx)(vc,{state:e}),u?(0,G.jsx)(Sc,{state:e}):null]})]})}function Bc(e){let{pushConfig:t,socket:n}=e,r=x(e=>e.pushDeviceId),i=x(e=>e.setPushDeviceId),a=x(e=>e.setPushPermissionState);return{handleEnablePush:(0,W.useCallback)(async()=>{if(t)try{let e=await dn({vapidPublicKey:t.vapidPublicKey,sendToServer:async e=>{let t=await n.command({type:`push.subscribe`,subscription:e.subscription,label:e.label,userAgent:e.userAgent});return cn(t.id),{id:t.id}}});i(e)}finally{a(an().state)}},[t,n,i,a]),handleDisablePush:(0,W.useCallback)(async()=>{r&&(await nn({pushDeviceId:r,sendToServer:async e=>{await n.command({type:`push.unsubscribe`,pushDeviceId:e})}}),un(),i(null))},[r,n,i])}}function Vc(e){return e===`openai`?lr:e===`openrouter`?tn:``}function Hc(e,t){return{...e,provider:t,model:Vc(t),baseUrl:t===`custom`?e.baseUrl:``}}function Uc(e,t){if(!e.pinnedRef)return null;let n=t.latestVersion;return!n||n===e.pinnedRef?null:n}var Wc={up_to_date:`Up to date`,outdated:`Outdated`,partial:`Partial`,unknown:`Unknown`};function Gc(e){if(!e)return null;let t=Uc(e,e.update);if(t)return`Re-pin to ${t}`;if(e.pinnedRef)return null;let n=e.update.availability;return n===`outdated`||n===`partial`?`Update`:null}function Kc({skill:e,packageEntry:t,uninstalling:n,applying:r,onUninstall:i,onUpdate:a}){let o=e.source?`https://skills.sh/${e.source}/${e.name}`:null,s=t?.update.availability,c=t?.versionLabel??t?.revision?.slice(0,7)??t?.updatedAt??null,l=s&&s!==`up_to_date`?ba[s]:null,u=t?.pinnedRef??null,d=Gc(t);return(0,G.jsxs)(`div`,{className:`flex min-w-0 items-start justify-between gap-3 rounded-lg border border-border bg-card/30 p-3`,children:[(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`div`,{className:`truncate text-sm font-medium text-foreground`,children:e.name}),(0,G.jsx)(`div`,{className:`truncate text-xs text-muted-foreground`,children:e.source||`Unknown source`}),c?(0,G.jsx)(`div`,{className:`font-mono tabular-nums text-xs text-muted-foreground/70`,children:c}):null,u?(0,G.jsxs)(`div`,{className:`truncate font-mono tabular-nums text-xs text-muted-foreground/70`,children:[`Pinned `,u]}):null]}),(0,G.jsxs)(`div`,{className:`flex shrink-0 flex-wrap items-center justify-end gap-2`,children:[l?(0,G.jsx)(`span`,{className:D(`rounded-full border px-2 py-0.5 text-xs font-medium`,l),children:Wc[s]}):null,d?(0,G.jsxs)(E,{type:`button`,size:`sm`,variant:`secondary`,disabled:r,onClick:a,className:`h-6 rounded-full px-2 text-xs`,children:[r?(0,G.jsx)(O,{className:`mr-1 h-3 w-3 animate-spin`}):null,d]}):null,o?(0,G.jsx)(`a`,{href:o,target:`_blank`,rel:`noreferrer`,"aria-label":`View ${e.name} on skills.sh`,className:`touch-manipulation inline-flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,children:(0,G.jsx)(Pe,{className:`h-4 w-4`})}):null,(0,G.jsx)(`button`,{type:`button`,"aria-label":`Uninstall ${e.name}`,disabled:n,onClick:i,className:`touch-manipulation inline-flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none disabled:opacity-50`,children:n?(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}):(0,G.jsx)(Ve,{className:`h-4 w-4`})})]})]})}function qc(e){return!e||e<=0?`0 installs`:e>=1e6?`${(e/1e6).toFixed(1).replace(/\.0$/,``)}M installs`:e>=1e3?`${(e/1e3).toFixed(1).replace(/\.0$/,``)}K installs`:`${e} install${e===1?``:`s`}`}var Jc=P(`packages.checkUpdates`),Yc=P(`packages.updateAll`,`skill`);function Xc(e){return`skill:${e}`}function Zc({skill:e,packageEntry:t,uninstalling:n,applying:r,onUninstall:i,onUpdate:a}){let o=Xc(e.name),s=M(P(`packages.update`,o)),c=M(P(`skills.uninstall`,e.name));return(0,G.jsx)(Kc,{skill:e,packageEntry:t,uninstalling:n||c,applying:r||s,onUninstall:()=>i(e),onUpdate:()=>a(o)})}function Qc({message:e}){return(0,G.jsx)(`pre`,{className:`max-w-full overflow-x-auto whitespace-pre-wrap rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-xs text-destructive`,children:e})}function $c({skill:e,installing:t,installed:n,message:r,onInstall:i}){let a;return a=n?`Installed`:t?`Installing`:`Get`,(0,G.jsxs)(`div`,{className:`flex min-w-0 items-center justify-between gap-3 rounded-lg border border-border bg-card/30 p-3`,children:[(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`div`,{className:`truncate text-sm font-medium text-foreground`,children:e.name}),(0,G.jsxs)(`div`,{className:`truncate text-xs text-muted-foreground`,children:[e.source,` · `,qc(e.installs)]}),n&&r?(0,G.jsx)(`div`,{className:`mt-1 truncate text-xs text-emerald-500`,children:r}):null]}),(0,G.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[(0,G.jsx)(`a`,{href:`https://skills.sh/${e.id}`,target:`_blank`,rel:`noreferrer`,"aria-label":`View ${e.name} on skills.sh`,className:`touch-manipulation inline-flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,children:(0,G.jsx)(Pe,{className:`h-4 w-4`})}),(0,G.jsxs)(E,{type:`button`,size:`sm`,variant:n?`secondary`:`default`,disabled:t||n,onClick:i,className:`h-6 rounded-full px-2 text-xs`,children:[t?(0,G.jsx)(O,{className:`mr-1.5 h-3.5 w-3.5 animate-spin`}):null,a]})]})]})}function el({state:e,ports:t}){let n=t?.timer??Qe,r=e.socket,i=e.connectionStatus,a=x(e=>e.skillQuery),o=x(e=>e.setSkillQuery),s=x(e=>e.skillResults),c=x(e=>e.setSkillResults),l=x(e=>e.skillSearchLoading),u=x(e=>e.setSkillSearchLoading),d=x(e=>e.skillSearchError),f=x(e=>e.setSkillSearchError),p=x(e=>e.installedSkills),m=x(e=>e.setInstalledSkills),h=x(e=>e.installedSkillIds),g=x(e=>e.setInstalledSkillIds),_=x(e=>e.addInstalledSkillId),v=x(e=>e.removeInstalledSkillId),y=x(e=>e.installedLoading),b=x(e=>e.setInstalledLoading),ee=x(e=>e.installedError),te=x(e=>e.setInstalledError),ne=x(e=>e.skillOperationError),S=x(e=>e.setSkillOperationError),re=x(e=>e.installingSkillId),C=x(e=>e.setInstallingSkillId),ie=x(e=>e.uninstallingSkillId),ae=x(e=>e.setUninstallingSkillId),w=x(e=>e.installMessages),oe=x(e=>e.setInstallMessage),se=x(e=>e.clearInstallMessage),ce=x(e=>e.clearInstallMessagesForSkill),D=x(e=>e.packageUpdateSnapshot),k=D?.status===`checking`,j=D?.packages.filter(e=>e.kind===`skill`&&!e.pinnedRef).filter(e=>e.update.availability===`outdated`||e.update.availability===`partial`).map(e=>e.id)??[],N=j.length,le=D?.lastCheckedAt?new Date(D.lastCheckedAt).toLocaleTimeString():null,ue=M(Jc),de=M(Yc),fe=k||ue;async function pe(e){try{S(null),await r.command(e)}catch(e){throw S(T(e)),e}}function me(){A(Jc,()=>pe({type:`packages.checkUpdates`}))}function he(e){A(P(`packages.update`,e),()=>pe({type:`packages.update`,id:e}))}function ge(){j.length!==0&&A(Yc,()=>pe({type:`packages.updateAll`,ids:j}))}function _e(e){A(P(`skills.install`,e.id),()=>be(e))}function ve(e){A(P(`skills.uninstall`,e.name),()=>xe(e))}let ye=(0,W.useCallback)(async()=>{if(i!==`connected`){m([]),g(new Set),te(null),b(!1);return}try{b(!0),te(null);let e=await r.command({type:`skills.listInstalled`});m(e.skills),g(new Set(e.skills.map(e=>e.name)))}catch(e){m([]),g(new Set),te(e instanceof Error?e.message:`Unable to read installed skills.`)}finally{b(!1)}},[i,r,m,g,te,b]);(0,W.useEffect)(()=>{wt(`skills.listInstalled`,ye())},[i,ye,r]),(0,W.useEffect)(()=>{let e=a.trim();if(e.length<2){c([]),f(null),u(!1);return}if(i!==`connected`){c([]),u(!1),f(`Backend connection required.`);return}let t=!1;u(!0),f(null);let o=n.setTimeout(()=>{r.command({type:`skills.search`,query:e,limit:100}).then(e=>{t||c(e.skills)}).catch(e=>{t||(c([]),f(e instanceof Error?e.message:`Unable to search skills.`))}).finally(()=>{t||u(!1)})},250);return()=>{t=!0,n.clearTimeout(o)}},[i,a,r,c,f,u,n]);async function be(e){if(i!==`connected`){S(`Backend connection required.`);return}try{C(e.id),S(null),se(e.id),await r.command({type:`skills.install`,source:e.source,skillId:e.skillId}),_(e.skillId),oe(e.id,`Installed globally`),wt(`skills.listInstalled`,ye())}catch(e){S(e instanceof Error?e.message:`Install failed.`)}finally{C(null)}}async function xe(e){if(i!==`connected`){S(`Backend connection required.`);return}try{ae(e.name),S(null),await r.command({type:`skills.uninstall`,skillId:e.name}),m(p.filter(t=>t.name!==e.name)),v(e.name),ce(e.name),wt(`skills.listInstalled`,ye())}catch(e){S(e instanceof Error?e.message:`Uninstall failed.`)}finally{ae(null)}}let Se;return Se=p.length>0?(0,G.jsx)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:p.map(e=>(0,G.jsx)(Zc,{skill:e,packageEntry:D?.packages.find(t=>t.kind===`skill`&&t.name===e.name)??null,uninstalling:ie===e.name,applying:D?.applying.includes(Xc(e.name))??!1,onUninstall:ve,onUpdate:he},`${e.source}/${e.name}`))}):y?null:(0,G.jsx)(`div`,{className:`rounded-lg border border-border bg-card/30 p-3 text-sm text-muted-foreground`,children:`No global skills installed.`}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[ne?(0,G.jsx)(Qc,{message:ne}):null,(0,G.jsxs)(`section`,{className:`flex flex-col gap-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`Installed`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[le?(0,G.jsxs)(`span`,{className:`tabular-nums text-xs text-muted-foreground`,children:[`Checked `,le]}):null,N>0?(0,G.jsxs)(E,{size:`sm`,variant:`secondary`,className:`h-6 rounded-full px-2 text-xs`,pending:de,onClick:ge,children:[`Update all (`,N,`)`]}):null,(0,G.jsxs)(E,{size:`sm`,variant:`ghost`,className:`h-6 rounded-full px-2 text-xs`,disabled:fe,"aria-busy":fe||void 0,onClick:me,children:[fe?(0,G.jsx)(O,{className:`mr-1 h-3 w-3 animate-spin`}):null,`Check`]}),y?(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin text-muted-foreground`}):null]})]}),ee?(0,G.jsx)(`div`,{className:`text-xs text-destructive`,children:ee}):null,Se]}),(0,G.jsxs)(`section`,{className:`flex flex-col gap-3`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`Discover`}),(0,G.jsxs)(`div`,{className:`flex h-10 items-center gap-2 rounded-lg border border-border bg-card/30 px-3`,children:[(0,G.jsx)(Be,{className:`h-4 w-4 shrink-0 text-muted-foreground`}),(0,G.jsx)(`input`,{type:`text`,role:`searchbox`,value:a,onChange:e=>o(e.target.value),placeholder:`Search skills`,className:`min-w-0 flex-1 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground`}),a?(0,G.jsx)(`button`,{type:`button`,"aria-label":`Clear skills search`,onClick:()=>o(``),className:`touch-manipulation inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,children:(0,G.jsx)(qe,{className:`h-3.5 w-3.5`})}):null,l?(0,G.jsx)(O,{className:`h-4 w-4 shrink-0 animate-spin text-muted-foreground`}):null]}),d?(0,G.jsx)(`div`,{className:`text-xs text-destructive`,children:d}):null,(0,G.jsx)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:s.map(e=>(0,G.jsx)($c,{skill:e,installing:re===e.id,installed:h.has(e.skillId),message:w[e.id],onInstall:()=>{_e(e)}},e.id))}),!l&&!d&&a.trim().length>=2&&s.length===0?(0,G.jsx)(`div`,{className:`rounded-lg border border-border bg-card/30 p-3 text-sm text-muted-foreground`,children:`No skills found.`}):null]})]})}function tl(e){return{async onReload(t){if(!(await e(`/api/plugins/${t}/reload`,{})).ok)throw Error(`Failed to reload plugin ${t}`)}}}function nl({plugins:e,handlers:t}){return e.length===0?(0,G.jsx)(Zr,{icon:l,message:`No plugins installed yet.`}):(0,G.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,G.jsx)(`h2`,{className:`text-sm font-medium text-foreground`,children:`Plugins`}),(0,G.jsx)(Qr,{children:e.map(e=>(0,G.jsx)(rl,{plugin:e,onReload:t.onReload},e.id))})]})}function rl({plugin:e,onReload:t}){let n=P(`plugins.reload`,e.id),r=M(n),i=(0,W.useCallback)(()=>{A(n,async()=>{try{await t(e.id),fn.getState().setCommandError(null)}catch(e){throw fn.getState().setCommandError(T(e)),e}})},[t,e.id,n]);return(0,G.jsxs)(`li`,{className:`flex items-center justify-between gap-3 px-4 py-3`,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-0.5`,children:[(0,G.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`span`,{className:`truncate text-sm font-medium text-foreground`,children:e.id}),(0,G.jsx)(Ot,{tone:e.enabled?`active`:`muted`,label:e.enabled?`Enabled`:`Disabled`})]}),(0,G.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,children:e.sourceDir})]}),(0,G.jsx)(E,{variant:`ghost`,size:`sm`,"data-testid":`plugin-reload:${e.id}`,pending:r,onClick:i,children:`Reload`})]})}async function il(e,t){return{ok:(await we.postJsonBody(e,t)).ok}}var al=tl(il);function ol(){let e=z(pt);return(0,G.jsx)(nl,{plugins:e,handlers:al})}var sl=[{id:`general`,label:`General`,icon:xe,subtitle:`Manage appearance, editor behavior, and embedded terminal defaults.`},{id:`skills`,label:`Skills`,icon:Mn,subtitle:`Manage globally installed agent skills from the active skill lock file.`},{id:`plugins`,label:`Plugins`,icon:Qn,subtitle:`View and update globally installed Claude Code and Codex plugins.`},{id:`kanna-plugins`,label:`Kanna plugins`,icon:l,subtitle:`Install local Kanna plugins that contribute UI surfaces and daemon behavior.`},{id:`providers`,label:`Providers`,icon:Kn,subtitle:`Manage the default chat provider and saved model defaults for Claude Code and Codex.`},{id:`models`,label:`Models`,icon:Bn,subtitle:`Add, edit, and remove Claude and Codex models available in the model picker.`},{id:`subagents`,label:`Subagents`,icon:le,subtitle:`Define reusable agent personas. Mention them in chat with @agent/<name>.`},{id:`mcp-servers`,label:`MCP servers`,icon:Qn,subtitle:`Install custom MCP servers (stdio, http, sse, ws) and connect-test them.`},{id:`mcp-sources`,label:`MCP sources`,icon:An,subtitle:`Bring messages from an MCP server, such as Zalo, into the Inbox by subscription or polling.`},{id:`remote-mcp`,label:`Remote MCP`,icon:Xn,subtitle:`Let Claude, Codex and ChatGPT drive Kanna over MCP, with setup snippets for each client.`},{id:`service-bus`,label:`Service bus`,icon:cr,subtitle:`Mirror Kanna's events into NATS JetStream, with an embedded or your own server.`},{id:`beacons`,label:`Beacons`,icon:pe,subtitle:`Pair your own machines so the agent can read files and run approved commands there.`},{id:`snippets`,label:`Text snippets`,icon:or,subtitle:`Define shortcuts that expand to full text in the chat composer with Tab.`},{id:`instructions`,label:`Instructions`,icon:Kn,subtitle:`Global instructions appended to every Claude and Codex turn (main + subagents).`},{id:`keybindings`,label:`Keybindings`,icon:Rn,subtitle:`Edit global app shortcuts stored in the active keybindings file.`},{id:`changelog`,label:`Changelog`,icon:Mn,subtitle:`Release notes pulled from the public GitHub releases feed.`}],cl={"mcp-servers":_i,"mcp-sources":ra,"remote-mcp":Ks,"service-bus":zc,beacons:Ka};function ll(e){return e?sl.find(t=>t.id===e)?.id??null:null}function ul(e){return e?sl:sl.filter(e=>e.id!==`kanna-plugins`)}var dl=[{value:`light`,label:`Light`,icon:ir},{value:`dark`,label:`Dark`,icon:Jn},{value:`system`,label:`System`,icon:Ie}],fl=[{value:`sm`,label:`Small`},{value:`md`,label:`Default`},{value:`lg`,label:`Large`},{value:`xl`,label:`Extra Large`},{value:`xxl`,label:`XX-Large`}],pl=[{value:`never`,label:`Never`},{value:`unfocused`,label:`When Unfocused`},{value:`always`,label:`Always`}],ml=[{value:`disabled`,label:`Off`},{value:`enabled`,label:`On`}],hl=[{value:`disabled`,label:`Off`},{value:`enabled`,label:`On`}],gl=[{value:`always-ask`,label:`Always ask`},{value:`auto-expose`,label:`Auto-expose`}],_l=[{value:`openai`,label:`OpenAI`},{value:`openrouter`,label:`OpenRouter`},{value:`custom`,label:`Custom`}],vl=3e5,yl=null;function bl(e){return`Edit global app shortcuts stored in ${e}.`}function xl(e,t){return e!==t}function Sl(){return yl?Date.now()>=yl.expiresAt?(yl=null,null):yl.releases:null}function Cl(e){yl={releases:e,expiresAt:Date.now()+vl}}async function wl(e,t){let n=t?.force?null:Sl();if(n)return n;let r=await e();return Cl(r),r}function Tl(e,t){let n=e=>e.trim().replace(/^v/i,``).split(`-`)[0].split(`.`).map(e=>Number.parseInt(e,10)).filter(e=>Number.isFinite(e)),r=n(e),i=n(t),a=Math.max(r.length,i.length);for(let e=0;e<a;e+=1){let t=r[e]??0,n=i[e]??0;if(t!==n)return t<n?-1:1}return 0}function El(e){if(!e)return`Unpublished`;let t=new Date(e);return Number.isNaN(t.getTime())?`Unknown date`:new Intl.DateTimeFormat(void 0,{month:`short`,day:`numeric`,year:`numeric`}).format(t)}var Dl=`__redeploy__`,Ol=`settings.writeLlmProvider`,kl=`appSettings.setCloudflareTunnel`,Al=P(kl,`cloudflaredPath`);function jl({status:e,releases:t,error:n,onRetry:r,updateSnapshot:i,currentVersion:a,onInstallUpdate:o,onCheckForUpdates:s,onForceReload:c}){let l=M(`update.check`),u=x(e=>e.changelogPendingAction),d=x(e=>e.setChangelogPendingAction),f=i?.latestVersion??t[0]?.tag_name??`Unknown`,p=i?.currentVersion??a,m=i?.status===`checking`||l,h=i?.status===`updating`||i?.status===`restart_pending`,g=h||u!==null,_=i?.updateAvailable===!0,v=f.replace(/^v/i,``),y=p.replace(/^v/i,``),b=(0,W.useCallback)(async e=>{d(e);try{await o(e)}finally{d(null)}},[o,d]),ee=(0,W.useCallback)(async()=>{d(Dl);try{await c()}finally{d(null)}},[c,d]),te=u===Dl||h;return(0,G.jsxs)(`div`,{className:`space-y-4`,children:[e===`loading`||e===`idle`?(0,G.jsx)(`div`,{className:`flex min-h-[180px] items-center justify-center rounded-2xl border border-border bg-card/40 px-6 py-8 text-sm text-muted-foreground`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),(0,G.jsx)(`span`,{children:`Loading release notes…`})]})}):null,e===`error`?(0,G.jsx)(`div`,{className:`rounded-lg border border-destructive/20 bg-destructive/5 px-6 py-5`,children:(0,G.jsxs)(`div`,{className:`flex items-start justify-between gap-4`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`Could not load changelog`}),(0,G.jsx)(`div`,{className:`mt-1 text-sm text-muted-foreground`,children:n??`Unable to load changelog.`})]}),(0,G.jsx)(`button`,{type:`button`,onClick:r,className:`rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground transition-colors hover:bg-muted`,children:`Retry`})]})}):null,e===`success`&&t.length===0?(0,G.jsxs)(`div`,{className:`rounded-lg border border-border bg-card/30 px-6 py-8`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`No releases yet`}),(0,G.jsx)(`div`,{className:`mt-2 text-sm text-muted-foreground`,children:`GitHub did not return any published releases for this repository.`})]}):null,e===`success`?(0,G.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,G.jsx)(On,{variant:`outline`,onClick:()=>A(`update.redeploy`,ee),disabled:g,children:te?(0,G.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}),`Re-deploying…`]}):`Re-deploy`}),(0,G.jsx)(On,{variant:`outline`,onClick:()=>A(`update.check`,s),disabled:m||g,children:m?(0,G.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}),`Checking…`]}):`Check for updates`})]}):null,e===`success`&&t.length>0?t.map(e=>{let t=e.tag_name.replace(/^v/i,``),n=t===v,r=t===y;return(0,G.jsxs)(`article`,{className:D(`rounded-xl border bg-card/30 pl-6 pr-4 py-4`,n?`border-border bg-muted`:`border-border`),children:[(0,G.jsxs)(`div`,{className:`flex flex-row items-center min-w-0 flex-1 gap-3 `,children:[(0,G.jsxs)(`div`,{className:`flex flex-row items-center min-w-0 flex-1 gap-2 `,children:[(0,G.jsx)(`div`,{className:`text-lg font-semibold tracking-[-0.2px] text-foreground`,children:e.name?.trim()||e.tag_name}),(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2 text-sm text-muted-foreground`,children:[(0,G.jsx)(`span`,{children:El(e.published_at)}),e.prerelease?(0,G.jsx)(`span`,{className:`rounded-full border border-border px-2.5 py-1 tracking-wide`,children:`Prerelease`}):null]})]}),(0,G.jsxs)(`div`,{className:`flex flex-row items-center justify-end min-w-0 flex-1 gap-2 `,children:[(0,G.jsx)(`a`,{href:e.html_url,target:`_blank`,rel:`noopener noreferrer`,"aria-label":`View release on GitHub`,className:D(j({variant:`ghost`,size:`icon-sm`}),`h-11 w-11 md:h-8 md:w-8 shrink-0 rounded-md hover:!bg-transparent hover:border-border/0`),children:(0,G.jsx)(Ml,{className:`h-4 w-4`})}),r?(0,G.jsx)(`span`,{className:D(`bg-transparent border border-border text-secondary-foreground`,`h-9 rounded-full px-3 text-sm`,`h-auto gap-1.5 px-3 py-1.5`),children:`Current`}):null,n&&_||!n&&!r?(()=>{let r=u===e.tag_name||h&&u===null,i;i=n?`Update`:Tl(t,y)<0?`Rollback`:`Install`;let a;return a=n?`Updating…`:Tl(t,y)<0?`Rolling back…`:`Installing…`,(0,G.jsx)(On,{variant:`default`,className:``,onClick:()=>A(P(`update.install`,e.tag_name),()=>b(e.tag_name)),disabled:g,children:(0,G.jsxs)(`div`,{className:`flex flex-row items-center justify-center gap-2`,children:[r?(0,G.jsx)(O,{className:`size-4 animate-spin`}):(0,G.jsx)(In,{className:`size-4`}),r?a:i]})})})():null]})]}),e.body?.trim()?(0,G.jsx)(`div`,{className:`prose prose-sm mt-5 max-w-none text-foreground dark:prose-invert`,children:Ce(e.body)}):(0,G.jsx)(`div`,{className:`mt-5 text-sm text-muted-foreground`,children:`No release notes were provided.`})]},e.id)}):null]})}function Ml({className:e}){return(0,G.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`currentColor`,"aria-hidden":`true`,className:e,children:(0,G.jsx)(`path`,{d:`M12 .5C5.649.5.5 5.649.5 12A11.5 11.5 0 0 0 8.36 22.04c.575.106.785-.25.785-.556 0-.274-.01-1-.015-1.962-3.181.691-3.853-1.532-3.853-1.532-.52-1.322-1.27-1.674-1.27-1.674-1.038-.71.08-.695.08-.695 1.148.08 1.752 1.178 1.752 1.178 1.02 1.748 2.676 1.243 3.328.95.103-.738.399-1.243.725-1.53-2.54-.289-5.211-1.27-5.211-5.65 0-1.248.446-2.27 1.177-3.07-.118-.288-.51-1.45.112-3.024 0 0 .96-.307 3.145 1.173A10.91 10.91 0 0 1 12 6.03c.973.004 1.954.132 2.87.387 2.182-1.48 3.14-1.173 3.14-1.173.625 1.573.233 2.736.115 3.024.734.8 1.175 1.822 1.175 3.07 0 4.39-2.676 5.358-5.224 5.642.41.353.776 1.05.776 2.117 0 1.528-.014 2.761-.014 3.136 0 .309.207.668.79.555A11.502 11.502 0 0 0 23.5 12C23.5 5.649 18.351.5 12 .5Z`})})}function Nl({checked:e,onChange:t}){return(0,G.jsxs)(`label`,{className:`inline-flex items-center gap-2`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:e,onChange:e=>t(e.target.checked)}),`Enabled`]})}function Pl({state:e}){let t=z(e=>e.settings?.globalPromptAppend??``),n=x(e=>e.globalInstructionsDraft),r=x(e=>e.setGlobalInstructionsDraft),i=x(e=>e.globalInstructionsPersistedAtMount),a=x(e=>e.globalInstructionsSaving),o=x(e=>e.setGlobalInstructionsSaving),s=x(e=>e.globalInstructionsError),c=x(e=>e.setGlobalInstructionsError);(0,W.useEffect)(()=>{t!==i&&x.setState({globalInstructionsPersistedAtMount:t,globalInstructionsDraft:t})},[t,i]);let l=n.replace(/\s+$/u,``),u=l.length>qt,d=l!==t,f=a||u||!d,p=(0,W.useCallback)(async()=>{if(!f){c(null),o(!0);try{await e.handleWriteAppSettings({globalPromptAppend:l})}catch(e){c(e instanceof Error?e.message:String(e))}finally{o(!1)}}},[f,e,l,c,o]),m;return m=a?`Saving…`:d?`Save`:`Saved`,(0,G.jsx)(`div`,{className:`border-b border-border`,children:(0,G.jsx)(q,{title:`Global Instructions`,description:`Appended to every Claude and Codex turn — including subagent turns — as “Workspace instructions”. Kanna does not read CLAUDE.md or AGENTS.md from disk; paste your global instructions here. For rules that apply to one project only, use “Edit instructions” in that project's sidebar menu. Leave blank to disable.`,bordered:!1,alignStart:!0,children:(0,G.jsxs)(`div`,{className:`flex w-full flex-col gap-2 md:w-[420px]`,children:[(0,G.jsx)(`textarea`,{value:n,onChange:e=>r(e.target.value),placeholder:`e.g. Always write tests before implementation. Prefer Tailwind classes over inline styles.`,rows:8,"aria-label":`Global instructions`,className:D(`min-h-[160px] w-full resize-y rounded-md border bg-background px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50`,u?`border-destructive`:`border-input`),disabled:a}),(0,G.jsxs)(`div`,{className:`flex items-center justify-between text-xs`,children:[(0,G.jsxs)(`span`,{className:u?`text-destructive`:`text-muted-foreground`,children:[l.length,` / `,qt,` characters`,u?` — over limit`:``]}),(0,G.jsx)(E,{type:`button`,size:`sm`,onClick:()=>A(`settings.globalInstructions`,p),disabled:f,pending:a,children:m})]}),s?(0,G.jsx)(`div`,{className:`text-xs text-destructive`,children:s}):null]})})})}function Fl({ports:e,sectionId:t}={}){let i=e?.dom??oe,l=n(),d=r(),{theme:m,setTheme:g}=bn(),_=x(e=>e.changelogStatus),v=x(e=>e.setChangelogStatus),y=x(e=>e.signingOut),ne=x(e=>e.setSigningOut),S=x(e=>e.authEnabled),ie=x(e=>e.setAuthEnabled),w=x(e=>e.releases),T=x(e=>e.setReleases),se=x(e=>e.changelogError),k=x(e=>e.setChangelogError),j=ll(t)??`general`,le=cl[j],ue=z(e=>e.hydrationStatus===`loading`&&e.settings===null),pe=d.connectionStatus===`connecting`||!d.localProjectsReady||ue,me=M(Ol),he=M(ee),ve=me||he,ye=M(Al),be=M(`keybindings.openEditor`),xe=M(`settings.chatSoundPreference`),Se=M(`settings.chatSoundId`),Ce=d.localProjects?.machine.displayName??`Unavailable`,we=d.localProjects?.projects.length??0,Te=ae.split(`/`)[1]??`unknown`,Ee=z(mt),De=z(ct),Oe=z(st),Pe=z(yt),Ie=s(e=>e.setScrollbackLines),Le=s(e=>e.setMinColumnWidth),Re=s(e=>e.setEditorPreset),ze=s(e=>e.setEditorCommandTemplate),Be=z(ht),Ve=z(bt),He=rs(e=>e.setChatSoundPreference),Ue=rs(e=>e.setChatSoundId),We=d.keybindings,I=z(e=>e.settings),Ge=d.llmProvider,Ke=C(e=>e.autoResumeOnRateLimit),qe=C(e=>e.setAutoResumeOnRateLimit),Qe=C(e=>e.typographyOverride),et=C(e=>e.clearTypographyOverride),tt=z(e=>e.settings?.typography.scale),nt=re(Qe,tt),rt=b(e=>e.defaultProvider),it=b(e=>e.providerDefaults),at=b(e=>e.setDefaultProvider),ot=b(e=>e.setProviderDefaultModel),ut=b(e=>e.setProviderDefaultModelOptions),dt=b(e=>e.setProviderDefaultPlanMode),ft=z(lt),pt=Sn(),gt=(0,W.useMemo)(()=>h(We),[We]).filePathDisplay||ce(),_t=x(e=>e.pushPermissionState),vt=x(e=>e.setPushPermissionState),xt=x(e=>e.pushDeviceId),{handleEnablePush:St,handleDisablePush:Ct}=Bc(d),Et=x(e=>e.scrollbackDraft),Ot=x(e=>e.setScrollbackDraft),kt=x(e=>e.minColumnWidthDraft),At=x(e=>e.tabMinWidthDraft),jt=x(e=>e.setMinColumnWidthDraft),Mt=x(e=>e.setTabMinWidthDraft),Nt=I?.panes.tabMinWidth??60,Pt=I?.uploads.maxFileSizeMb??mr.maxFileSizeMb,Ft=x(e=>e.uploadMaxFileSizeDraft),It=x(e=>e.setUploadMaxFileSizeDraft),Lt=Math.round((I?.claudeDriver.lifecycle.idleTimeoutMs??Ut.idleTimeoutMs)/6e4),Rt=I?.claudeDriver.lifecycle.maxConcurrent??Ut.maxConcurrent,Vt=x(e=>e.claudeIdleMinutesDraft),Ht=x(e=>e.setClaudeIdleMinutesDraft),Gt=x(e=>e.claudeMaxConcurrentDraft),qt=x(e=>e.setClaudeMaxConcurrentDraft),Jt=x(e=>e.editorCommandDraft),Xt=x(e=>e.setEditorCommandDraft),$t=x(e=>e.appSettingsError),B=x(e=>e.setAppSettingsError),en=x(e=>e.analyticsDialogOpen),tn=x(e=>e.setAnalyticsDialogOpen),nn=x(e=>e.tunnelError),rn=x(e=>e.setTunnelError),sn=x(e=>e.cloudflaredPathDraft),cn=x(e=>e.setCloudflaredPathDraft),ln=x(e=>e.pushContactSubjectDraft),un=x(e=>e.setPushContactSubjectDraft),dn=I?.shareDefaultTtlHours??24,fn=x(e=>e.shareDefaultTtlDraft),pn=x(e=>e.setShareDefaultTtlDraft),V=x(e=>e.llmProviderDraft),mn=x(e=>e.setLlmProviderDraft),hn=x(e=>e.llmProviderError),gn=x(e=>e.setLlmProviderError),_n=x(e=>e.llmValidationStatus),vn=x(e=>e.setLlmValidationStatus),yn=x(e=>e.llmValidationError),xn=x(e=>e.setLlmValidationError),Cn=x(e=>e.llmValidationDialogOpen),wn=x(e=>e.setLlmValidationDialogOpen),H=d.updateSnapshot,U=d.handleWriteAppSettings,Tn=d.handleWriteCloudflareTunnel,En=d.handleWriteClaudeAuth,Dn=d.handleTestOAuthToken,kn=d.handleReadLlmProvider,An=d.handleWriteLlmProvider,jn=d.handleValidateLlmProvider,Mn;Mn=H?.status===`checking`?`Checking for updates…`:H?.status===`updating`?`Installing update…`:H?.status===`restart_pending`?`Restarting Kanna…`:H?.status===`available`?`Update available${H.latestVersion?`: ${H.latestVersion}`:``}`:H?.status===`up_to_date`?`Up to date`:H?.status===`error`?`Update check failed`:`Not checked yet`,(0,W.useEffect)(()=>{Ot(String(Ee))},[Ee,Ot]),(0,W.useEffect)(()=>{jt(String(De))},[De,jt]),(0,W.useEffect)(()=>{Mt(String(Nt))},[Nt,Mt]),(0,W.useEffect)(()=>{It(String(Pt))},[Pt,It]),(0,W.useEffect)(()=>{Ht(String(Lt))},[Lt,Ht]),(0,W.useEffect)(()=>{qt(String(Rt))},[Rt,qt]),(0,W.useEffect)(()=>i.addWindowListener(`focus`,()=>vt(an().state)),[i,vt]),(0,W.useEffect)(()=>{Xt(Pe)},[Pe,Xt]),(0,W.useEffect)(()=>{Ge&&mn({provider:Ge.provider,apiKey:Ge.apiKey,model:Ge.model,baseUrl:Ge.baseUrl})},[Ge,mn]),(0,W.useEffect)(()=>{vn(`idle`),xn(null)},[V.provider,V.apiKey,V.model,V.baseUrl,vn,xn]),(0,W.useEffect)(()=>{t&&(ll(t)||l(`/settings/general`,{replace:!0}))},[l,t]),(0,W.useEffect)(()=>{I&&cn(I.cloudflareTunnel.cloudflaredPath)},[I,cn]),(0,W.useEffect)(()=>{I&&un(I.push.contactSubject)},[I,un]),(0,W.useEffect)(()=>{let e=!1;return te().then(t=>{e||ie(t.enabled===!0)}).catch(()=>{e||ie(!1)}),()=>{e=!0}},[ie]),(0,W.useEffect)(()=>{j!==`providers`||pe||A(ee,kn)},[kn,pe,j]);let Nn=(0,W.useCallback)(()=>d.socket.command({type:`settings.getChangelog`}),[d.socket]);(0,W.useEffect)(()=>{if(j!==`changelog`||pe)return;let e=!1;return v(`loading`),k(null),wl(Nn).then(t=>{e||(T(t),v(`success`))}).catch(t=>{e||(k(t instanceof Error?t.message:`Unable to load changelog.`),v(`error`))}),()=>{e=!0}},[pe,j,v,k,T,Nn]);function Fn(){let e=Number(Et);if(!Number.isFinite(e)){Ot(String(Ee));return}Ie(e),U({terminal:{scrollbackLines:e}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save terminal settings.`)})}function In(){let e=Number(kt);if(!Number.isFinite(e)){jt(String(De));return}Le(e),U({terminal:{minColumnWidth:e}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save terminal settings.`)})}function Ln(){let e=Number(At);if(!Number.isFinite(e)){Mt(String(Nt));return}U({panes:{tabMinWidth:de(e)}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save pane settings.`)})}function Rn(){let e=Number(Ft);if(!Number.isFinite(e)||e<1||e>51200){It(String(Pt)),B(`Max file size must be between 1 and ${hr} MB.`);return}if(Math.round(e)===Pt){It(String(Pt));return}U({uploads:{maxFileSizeMb:Math.round(e)}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save upload settings.`)})}function zn(){let e=Number(Vt),t=Math.round(Yt/6e4),n=Math.round(Kt/6e4);if(!Number.isFinite(e)||e<t||e>n){Ht(String(Lt)),B(`Idle timeout must be between ${t} and ${n} minutes.`);return}if(Math.round(e)===Lt){Ht(String(Lt));return}U({claudeDriver:{lifecycle:{idleTimeoutMs:Math.round(e)*6e4}}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save Claude lifecycle settings.`)})}function Bn(){let e=Number(Gt);if(!Number.isFinite(e)||e<1||e>16){qt(String(Rt)),B(`Max concurrent sessions must be between 1 and 16.`);return}if(Math.round(e)===Rt){qt(String(Rt));return}U({claudeDriver:{lifecycle:{maxConcurrent:Math.round(e)}}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save Claude lifecycle settings.`)})}function Vn(){let e=Number(fn);if(!Number.isInteger(e)||e<1){pn(String(dn)),B(`Default share link expiry must be a whole number of hours >= 1.`);return}if(e===dn){pn(String(dn));return}U({shareDefaultTtlHours:e}).catch(e=>{B(e instanceof Error?e.message:`Unable to save share settings.`)})}function Hn(e,t){e.key===`Enter`&&(t(),e.currentTarget.blur())}function Un(){ze(Jt),U({editor:{commandTemplate:Jt}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save editor settings.`)})}function Gn(e){g(e),U({theme:e}).catch(e=>{B(e instanceof Error?e.message:`Unable to save theme settings.`)})}function Kn(e){U({typography:{scale:e}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save typography settings.`)})}function qn(e){Re(e);let t=e===`custom`?Pe:p(e);U({editor:{preset:e,commandTemplate:t}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save editor settings.`)})}function Jn(e){xl(Be,e)&&(He(e),A(`settings.chatSoundPreference`,()=>U({chatSoundPreference:e}).catch(e=>{B(e instanceof Error?e.message:`Unable to save chat sound settings.`)})),wt(`chat sound preview`,Tt(Ve,1)))}function Yn(e){xl(Ve,e)&&(Ue(e),A(`settings.chatSoundId`,()=>U({chatSoundId:e}).catch(e=>{B(e instanceof Error?e.message:`Unable to save chat sound settings.`)})),wt(`chat sound preview`,Tt(e,1)))}async function Xn(e){try{B(null),await U({analyticsEnabled:e===`enabled`})}catch(e){B(e instanceof Error?e.message:`Unable to save analytics settings.`)}}async function Zn(e){try{B(null),await U({telemetry:{enabled:e===`enabled`}})}catch(e){B(e instanceof Error?e.message:`Unable to save telemetry settings.`)}}async function Qn(e){try{rn(null),await Tn(e)}catch(e){rn(e instanceof Error?e.message:`Unable to save Cloudflare Tunnel settings.`)}}function $n(e){at(e),U({defaultProvider:e}).catch(e=>{B(e instanceof Error?e.message:`Unable to save provider settings.`)})}function er(e,t){ot(e,t),U({providerDefaults:{[e]:{model:t}}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save provider settings.`)})}function tr(e,t){ut(e,t),U({providerDefaults:{[e]:{modelOptions:t}}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save provider settings.`)})}function nr(e,t){dt(e,t),U({providerDefaults:{[e]:{planMode:t}}}).catch(e=>{B(e instanceof Error?e.message:`Unable to save provider settings.`)})}async function rr(e=V){try{gn(null),await An(e);let t=await jn(e);vn(t.ok?`valid`:`invalid`),xn(t.error)}catch(e){let t=e instanceof Error?{name:e.name,message:e.message}:Dt(e);vn(`invalid`),xn(t),gn(e instanceof Error?e.message:`Unable to save quick response provider settings.`)}}function ir(e){let t=Hc(V,e);mn(t),ar(t)}function ar(e=V){A(Ol,()=>rr(e))}function or(){yl=null,v(`loading`),k(null),wl(Nn,{force:!0}).then(e=>{T(e),v(`success`)}).catch(e=>{k(e instanceof Error?e.message:`Unable to load changelog.`),v(`error`)})}let sr=Jt.replaceAll(`{path}`,`/Users/jake/Projects/kanna/src/client/app/App.tsx`).replaceAll(`{line}`,`12`).replaceAll(`{column}`,`1`),cr=gr,lr=I?.analyticsEnabled===!1?`disabled`:`enabled`,ur=I?.telemetry?.enabled===!1?`disabled`:`enabled`,dr=I?.cloudflareTunnel??fr,pr=dr.enabled?`enabled`:`disabled`,vr=sl.find(e=>e.id===j)??sl[0],yr=(0,W.useMemo)(()=>ul(ft),[ft]),br=j===`keybindings`?bl(gt):vr.subtitle,K=!pe,xr=yn?JSON.stringify(yn,null,2):``,Sr;Sr=ve?`inline-flex items-center gap-1.5 text-muted-foreground`:_n===`valid`?`text-success-text`:_n===`invalid`?`text-destructive`:`hidden`;let Cr;Cr=ve?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(N,{}),me?`Saving…`:`Loading…`]}):_n===`valid`?`Credentials valid & saved`:_n===`invalid`?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`span`,{children:`Credentials invalid.`}),yn?(0,G.jsxs)(G.Fragment,{children:[` `,(0,G.jsx)(`button`,{type:`button`,onClick:()=>wn(!0),className:`underline underline-offset-2`,children:`See error`})]}):null]}):null;let wr=(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`span`,{children:[`Use an OpenAI-compatible API for title and commit message generation before Claude and Codex. Stored in `,Ge?.filePathDisplay??`the active llm-provider.json file`,`.`]}),(0,G.jsx)(`span`,{className:D(`mt-2 block text-sm font-medium`,Sr),children:Cr})]});async function Tr(){if(!y){ne(!0);try{await d.handleSignOut()}finally{ne(!1)}}}return(0,G.jsxs)(`div`,{className:`relative flex h-full flex-1 min-w-0 bg-background`,children:[(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-1`,children:[(0,G.jsx)(`aside`,{className:`hidden w-[200px] shrink-0 md:block ${K?`pb-[89px]`:``}`,children:(0,G.jsxs)(`div`,{className:`flex flex-col gap-1 px-4 py-6`,children:[(0,G.jsx)(`div`,{className:`px-3 pb-5 text-22 font-extrabold tracking-[-0.5px] text-foreground`,children:`Settings`}),yr.map(e=>{let t=e.id===`changelog`&&H?.updateAvailable===!0;return(0,G.jsxs)(`button`,{type:`button`,onClick:()=>{l(`/settings/${e.id}`)},className:`relative cursor-pointer rounded-lg px-3 py-2 text-sm ${e.id===j?`font-medium text-foreground`:`text-muted-foreground hover:bg-muted/50 hover:text-foreground`}`,children:[e.id===j?(0,G.jsx)(u.span,{layoutId:`settings-nav-indicator`,className:`absolute inset-0 rounded-lg bg-muted`,transition:{type:`spring`,...a.indicator}}):null,(0,G.jsxs)(`div`,{className:`relative flex items-center gap-2.5`,children:[(0,G.jsx)(e.icon,{className:`h-4 w-4 shrink-0`}),(0,G.jsx)(`span`,{className:`min-w-0 truncate`,children:e.label}),t?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(Pn,{className:`ml-auto size-3.5 shrink-0 text-warning-text`,"aria-hidden":`true`}),(0,G.jsx)(`span`,{className:`sr-only`,children:`Update available`})]}):null]})]},e.label)}),S?(0,G.jsx)(`button`,{type:`button`,onClick:()=>A(`auth.signOut`,Tr),disabled:y,className:`cursor-pointer rounded-lg px-3 py-2 text-sm text-muted-foreground hover:bg-muted/50 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-2.5`,children:[y?(0,G.jsx)(N,{className:`h-4 w-4`}):(0,G.jsx)(Wn,{className:`h-4 w-4 shrink-0`}),(0,G.jsx)(`span`,{children:y?`Signing out...`:`Sign out`})]})}):null]})}),(0,G.jsxs)(`div`,{className:`min-w-0 flex-1 overflow-y-auto`,children:[(0,G.jsx)(`div`,{className:`sticky top-0 z-20 border-b border-border bg-background px-2 py-2 md:hidden`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(on,{label:`Open sidebar`,children:(0,G.jsx)(`button`,{type:`button`,onClick:d.openSidebar,className:`flex size-11 shrink-0 items-center justify-center rounded-md text-sm text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground`,"aria-label":`Open sidebar`,children:(0,G.jsx)(f,{className:`h-4 w-4 shrink-0`})})}),(0,G.jsxs)(Ne,{value:j,onValueChange:e=>{l(`/settings/${e}`)},children:[(0,G.jsx)(ke,{className:`h-11 min-w-0 flex-1`,"aria-label":`Settings section`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:yr.map(e=>(0,G.jsx)(F,{value:e.id,children:e.label},e.id))})})]}),S?(0,G.jsxs)(`button`,{type:`button`,onClick:()=>A(`auth.signOut`,Tr),disabled:y,className:`flex min-h-11 shrink-0 items-center gap-2 rounded-md border border-border bg-background px-3 py-2 text-sm text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50`,children:[y?(0,G.jsx)(N,{className:`h-4 w-4`}):(0,G.jsx)(Wn,{className:`h-4 w-4 shrink-0`}),(0,G.jsx)(`span`,{className:`sr-only`,children:y?`Signing out...`:`Sign out`})]}):null]})}),(0,G.jsxs)(`div`,{className:`w-full px-4 pb-32 pt-8 md:px-6 md:pt-16`,children:[pe?(0,G.jsx)(`div`,{className:`flex min-h-[240px] items-center justify-center rounded-2xl border border-border bg-card/40 px-4 py-6 text-sm text-muted-foreground`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),(0,G.jsx)(`span`,{children:`Loading machine settings…`})]})}):(0,G.jsxs)(`div`,{className:`mx-auto max-w-4xl kanna-settings-section-in`,children:[(0,G.jsxs)(`div`,{className:`pb-6`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-4 min-h-[34px]`,children:[(0,G.jsx)(`div`,{className:`text-lg font-semibold tracking-[-0.2px] text-foreground`,children:vr.label}),j===`general`?(0,G.jsx)(On,{variant:`outline`,onClick:()=>{l(`/settings/changelog`)},children:`Check for updates`}):null,j===`keybindings`?(0,G.jsxs)(On,{onClick:()=>A(`keybindings.openEditor`,()=>d.handleOpenExternalPath(`open_editor`,gt)),disabled:be,"aria-busy":be||void 0,icon:be?(0,G.jsx)(N,{className:`h-4 w-4`}):(0,G.jsx)(c,{className:`h-4 w-4`}),children:[`Open in `,d.editorLabel]}):null]}),(0,G.jsx)(`div`,{className:`mt-1 text-sm text-muted-foreground`,children:br})]}),j===`general`&&(0,G.jsxs)(G.Fragment,{children:[$t?(0,G.jsx)(`div`,{className:`mb-4 rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:$t}):null,(0,G.jsxs)(`div`,{className:`border-b border-border`,children:[(0,G.jsx)(q,{title:`Application Update`,description:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`span`,{children:[Mn,`.`]}),H?.lastCheckedAt?(0,G.jsxs)(`span`,{children:[` Last checked `,new Intl.DateTimeFormat(void 0,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`}).format(H.lastCheckedAt),`.`]}):null,H?.error?(0,G.jsxs)(`span`,{children:[` `,H.error]}):null]}),bordered:!1,children:(0,G.jsxs)(`div`,{className:`text-right text-sm text-foreground`,children:[(0,G.jsxs)(`div`,{children:[`Current: `,H?.currentVersion??Te]}),(0,G.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`Latest: `,H?.latestVersion??`Unknown`]})]})}),(0,G.jsx)(q,{title:`Theme`,description:`Choose between light, dark, or system appearance`,children:(0,G.jsx)(L,{value:m,onValueChange:Gn,options:dl,size:`sm`})}),(0,G.jsx)(q,{title:`Typography Scale`,description:Qe?`This device uses its own text size instead of the account default.`:`Choose how large text and UI elements appear across the app.`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsxs)(Ne,{value:nt,onValueChange:e=>{o(e)&&Kn(e)},children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:fl.map(e=>(0,G.jsx)(F,{value:e.value,children:e.label},e.value))})})]}),Qe?(0,G.jsx)(E,{type:`button`,variant:`link`,size:`sm`,onClick:et,children:`Use account default`}):null]})}),(0,G.jsx)(q,{title:`Chat Sounds`,description:`Play a pop when a chat starts waiting on you or the unread chat count increases`,children:(0,G.jsxs)(Ne,{disabled:xe,value:Be,onValueChange:e=>{Qt(e)&&Jn(e)},children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:pl.map(e=>(0,G.jsx)(F,{value:e.value,children:e.label},e.value))})})]})}),(0,G.jsx)(q,{title:`Chat Sound`,description:`The bundled sound used for chat notification playback and previews`,children:(0,G.jsxs)(Ne,{disabled:Se,value:Ve,onValueChange:e=>{Wt(e)&&Yn(e)},children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:es.map(e=>(0,G.jsx)(F,{value:e.value,children:e.label},e.value))})})]})}),(0,G.jsx)(q,{title:`Default Editor`,description:`Used when opening transcript links or files from the git diff menu`,alignStart:!0,children:(0,G.jsxs)(Ne,{value:Oe,onValueChange:e=>{zt(e)&&qn(e)},children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:_e.map(e=>(0,G.jsx)(F,{value:e.value,children:(0,G.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(fe,{preset:e.value,className:`h-4 w-4 shrink-0`}),(0,G.jsx)(`span`,{children:e.label})]})},e.value))})})]})}),Oe===`custom`?(0,G.jsx)(`div`,{className:`border-t border-border`,children:(0,G.jsxs)(`div`,{className:`flex justify-between gap-8 py-5 pl-6`,children:[(0,G.jsxs)(`div`,{className:`min-w-0 max-w-xl`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`Command Template`}),(0,G.jsxs)(`div`,{className:`mt-1 text-13 text-muted-foreground`,children:[`Include `,`{path}`,` and optionally `,`{line}`,` and `,`{column}`,` in your command.`]})]}),(0,G.jsxs)(`div`,{className:`flex min-w-0 max-w-[420px] flex-1 flex-col items-stretch gap-2`,children:[(0,G.jsx)(R,{type:`text`,value:Jt,onChange:e=>Xt(e.target.value),onBlur:Un,onKeyDown:e=>qo(e,Un),className:`font-mono`}),(0,G.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`Preview: `,(0,G.jsx)(`span`,{className:`font-mono`,children:sr})]})]})]})}):null,(0,G.jsx)(q,{title:`Terminal Scrollback`,description:`Lines retained for embedded terminal history`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsx)(R,{type:`number`,min:500,max:5e3,step:100,value:Et,onChange:e=>Ot(e.target.value),onBlur:Fn,onKeyDown:e=>Hn(e,Fn),className:`hide-number-steppers w-full text-left font-mono md:w-28 md:text-right`}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground md:text-right`,children:[500,`-`,5e3,` lines`,Ee===1e3?` (default)`:``]})]})}),(0,G.jsx)(q,{title:`Terminal Min Column Width`,description:`Minimum width for each terminal pane`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsx)(R,{type:`number`,min:250,max:900,step:10,value:kt,onChange:e=>jt(e.target.value),onBlur:In,onKeyDown:e=>Hn(e,In),className:`hide-number-steppers w-full text-left font-mono md:w-28 md:text-right`}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground md:text-right`,children:[250,`-`,900,` px`,De===450?` (default)`:``]})]})}),(0,G.jsx)(q,{title:`Tab Minimum Width`,description:`How narrow a pane tab may get before the strip scrolls instead of shrinking`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsx)(R,{type:`number`,min:60,max:200,step:10,value:At,onChange:e=>Mt(e.target.value),onBlur:Ln,onKeyDown:e=>Hn(e,Ln),className:`hide-number-steppers w-full text-left font-mono md:w-28 md:text-right`}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground md:text-right`,children:[60,`-`,200,` px`,Nt===60?` (default)`:``]})]})}),(0,G.jsx)(q,{title:`Max upload file size`,description:`Largest single file the chat upload endpoint accepts.`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-1.5 md:w-auto md:items-end`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2 md:justify-end`,children:[(0,G.jsx)(R,{type:`number`,min:1,max:51200,step:1,value:Ft,onChange:e=>It(e.target.value),onBlur:Rn,onKeyDown:e=>Hn(e,Rn),className:`hide-number-steppers w-full text-left font-mono tabular-nums md:w-24 md:text-right`,"aria-label":`Max upload file size in megabytes`}),(0,G.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:`MB`})]}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground tabular-nums md:text-right`,children:[1,`–`,51200,` MB · default `,mr.maxFileSizeMb]})]})}),(0,G.jsx)(q,{title:`Auto-resume on rate limit`,description:`When you hit a rate limit, automatically schedule "continue" at the reset time instead of asking. You can still cancel each one from the chat.`,children:(0,G.jsx)(Nl,{checked:Ke,onChange:qe})}),d.pushConfig?(0,G.jsx)(q,{title:`Push notifications`,description:`Get notified when a chat is waiting for you, finishes, or fails. Works on iPhone (after Add to Home Screen), Android, and desktop browsers.`,bordered:!1,alignStart:!0,children:(0,G.jsx)(vs,{permissionState:_t,config:d.pushConfig,projects:d.localProjects?.projects??[],currentDeviceId:xt,contactSubject:I?.push.contactSubject??``,contactSubjectDraft:ln,onContactSubjectDraftChange:un,onContactSubjectSave:async e=>{await d.socket.command({type:`settings.writeAppSettingsPatch`,patch:{push:{contactSubject:e}}})},onEnable:St,onDisable:Ct,onTest:async()=>{await d.socket.command({type:`push.test`})},onMuteToggle:async(e,t)=>{await d.socket.command({type:`push.setProjectMute`,localPath:e,muted:t})},onRemoveDevice:async e=>{await d.socket.command({type:`push.unsubscribe`,pushDeviceId:e})}})}):null,(0,G.jsx)(q,{title:`Anonymous Analytics`,description:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`span`,{children:`Help improve Kanna with anonymous product analytics. Kanna sends tracked event names plus a small set of event properties like current version, environment, update version info, and launch flags. No message content, prompts, file paths, or provider credentials are sent.`}),(0,G.jsxs)(`span`,{className:`mt-1 block`,children:[`Stored in `,I?.filePathDisplay??`~/.kanna/data/settings.json`,`.`,` `,(0,G.jsx)(`button`,{type:`button`,onClick:()=>tn(!0),className:`underline underline-offset-2 text-foreground hover:text-foreground/80`,children:`View tracked events`})]}),I?.warning?(0,G.jsx)(`span`,{className:`mt-1 block`,children:I.warning}):null]}),children:(0,G.jsx)(Ns,{pendingKey:`settings.analytics`,value:lr,onValueChange:Xn,options:ml,size:`sm`})}),(0,G.jsx)(q,{title:`Telemetry Tracing`,description:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`span`,{children:`Export OpenTelemetry traces and metrics (turn timings, subagent runs, process memory) to Kanna's observability collector so each install can be monitored. This machine reports under its computer name. Turning it off stops the export immediately.`}),(0,G.jsxs)(`span`,{className:`mt-1 block`,children:[`Collector: `,I?.telemetry?.endpoint??`not configured`,`. Stored in `,I?.filePathDisplay??`~/.kanna/data/settings.json`,`.`]})]}),children:(0,G.jsx)(Ns,{pendingKey:`settings.telemetry`,value:ur,onValueChange:Zn,options:ml,size:`sm`})})]}),(0,G.jsxs)(`div`,{className:`border-b border-border`,children:[nn?(0,G.jsx)(`div`,{className:`mb-4 rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:nn}):null,(0,G.jsx)(q,{title:`Cloudflare Tunnel`,description:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`span`,{children:[`When enabled, Claude can call the `,(0,G.jsx)(`code`,{className:`rounded bg-muted px-1 py-0.5 font-mono text-xs`,children:`expose_port`}),` tool to expose a local port via Cloudflare Tunnel. The mode below controls whether each call requires your approval or is exposed automatically. Requires`,` `,(0,G.jsx)(`code`,{className:`rounded bg-muted px-1 py-0.5 font-mono text-xs`,children:`cloudflared`}),` `,`to be installed.`]}),(0,G.jsxs)(`span`,{className:`mt-1 block`,children:[`Stored in `,I?.filePathDisplay??`~/.kanna/data/settings.json`,`.`]})]}),bordered:!1,children:(0,G.jsx)(Ns,{pendingKey:P(kl,`enabled`),value:pr,onValueChange:e=>Qn({enabled:e===`enabled`}),options:hl,size:`sm`})}),dr.enabled&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(q,{title:`Tool mode`,description:`Always ask: each expose_port call shows an accept card. Auto-expose: expose_port calls spawn cloudflared immediately without prompting.`,children:(0,G.jsx)(Ns,{pendingKey:P(kl,`mode`),value:dr.mode,onValueChange:e=>Qn({mode:e}),options:gl,size:`sm`})}),(0,G.jsx)(q,{title:`cloudflared path`,description:`Path to the cloudflared binary. Defaults to the one found on $PATH.`,children:(0,G.jsx)(R,{value:sn,onChange:e=>cn(e.target.value),onBlur:()=>A(Al,()=>Qn({cloudflaredPath:sn})),readOnly:ye,"aria-busy":ye||void 0,placeholder:`cloudflared`,className:`w-full font-mono md:w-64`})})]})]}),(0,G.jsx)(`div`,{className:`border-b border-border`,children:(0,G.jsx)(q,{title:`Public share links`,description:`Default expiry for read-only chat share links. Owners can revoke any link manually at any time.`,bordered:!1,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2 md:justify-end`,children:[(0,G.jsx)(R,{type:`number`,min:1,step:1,value:fn,onChange:e=>pn(e.target.value),onBlur:Vn,onKeyDown:e=>Hn(e,Vn),className:`hide-number-steppers w-full text-left font-mono tabular-nums md:w-24 md:text-right`,"aria-label":`Default share link expiry in hours`}),(0,G.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:`hours`})]}),(0,G.jsx)(`div`,{className:`text-left text-xs text-muted-foreground tabular-nums md:text-right`,children:`Minimum 1 hour · default 24`})]})})})]}),j===`providers`&&(0,G.jsxs)(`div`,{className:`border-b border-border`,children:[(0,G.jsx)(q,{title:`Claude OAuth tokens`,description:`Manage multiple Claude OAuth tokens. Kanna switches automatically when one hits its rate limit.`,bordered:!1,alignStart:!0,children:(0,G.jsx)(`div`,{className:`w-full md:w-[420px]`,children:(0,G.jsx)(Ko,{tokens:I?.claudeAuth.tokens??[],concurrencyDefault:I?.claudeAuth.concurrencyDefault??1,onWrite:En,onTest:Dn})})}),(0,G.jsx)(q,{title:`Claude session idle timeout`,description:`Stop a Claude session after this many minutes without user activity. Lower values free memory sooner; higher values keep cold-start latency low.`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsx)(R,{type:`number`,min:1,max:60,step:1,value:Vt,onChange:e=>Ht(e.target.value),onBlur:zn,onKeyDown:e=>Hn(e,zn),className:`hide-number-steppers w-full text-left font-mono md:w-28 md:text-right`}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground md:text-right`,children:[1,`–`,60,` min · default `,Math.round(Ut.idleTimeoutMs/6e4)]})]})}),(0,G.jsx)(q,{title:`Max concurrent Claude sessions`,description:`Hard cap on resident Claude processes. Excess sessions are evicted LRU; their next activation cold-starts.`,children:(0,G.jsxs)(`div`,{className:`flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:items-end`,children:[(0,G.jsx)(R,{type:`number`,min:1,max:16,step:1,value:Gt,onChange:e=>qt(e.target.value),onBlur:Bn,onKeyDown:e=>Hn(e,Bn),className:`hide-number-steppers w-full text-left font-mono md:w-28 md:text-right`}),(0,G.jsxs)(`div`,{className:`text-left text-xs text-muted-foreground md:text-right`,children:[1,`–`,16,` · default `,Ut.maxConcurrent]})]})}),(0,G.jsx)(q,{title:`Default Provider`,description:`The default harness used for new chats before a provider is locked by an existing session.`,children:(0,G.jsxs)(Ne,{value:rt,onValueChange:e=>{(e===`last_used`||Zt(e))&&$n(e)},children:[(0,G.jsx)(ke,{className:`min-w-[180px]`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsxs)(Me,{children:[(0,G.jsx)(F,{value:`last_used`,children:`Last Used`}),pt.map(e=>(0,G.jsx)(F,{value:e.id,children:e.label},e.id))]})})]})}),(0,G.jsx)(Mo,{state:d}),(0,G.jsx)(q,{title:`Claude Code Defaults`,description:`Saved defaults when using Claude Code.`,alignStart:!0,children:(0,G.jsx)(`div`,{className:`max-w-[420px]`,children:(0,G.jsx)(ge,{availableProviders:pt,selectedProvider:`claude`,showProviderPicker:!1,model:it.claude.model,modelOptions:it.claude.modelOptions,onModelChange:(e,t)=>{er(`claude`,t)},onModelOptionChange:e=>{e.type===`claudeReasoningEffort`?tr(`claude`,{reasoningEffort:e.effort}):e.type===`contextWindow`&&tr(`claude`,{contextWindow:e.contextWindow})},planMode:it.claude.planMode,onPlanModeChange:e=>nr(`claude`,e),includePlanMode:!0,className:`justify-start flex-wrap`})})}),(0,G.jsx)(q,{title:`Codex Defaults`,description:`Saved defaults when using Codex.`,alignStart:!0,children:(0,G.jsx)(`div`,{className:`max-w-[420px]`,children:(0,G.jsx)(ge,{availableProviders:pt,selectedProvider:`codex`,showProviderPicker:!1,model:it.codex.model,modelOptions:it.codex.modelOptions,onModelChange:(e,t)=>{er(`codex`,t)},onModelOptionChange:e=>{e.type===`codexReasoningEffort`?tr(`codex`,{reasoningEffort:e.effort}):e.type===`fastMode`&&tr(`codex`,{fastMode:e.fastMode})},planMode:it.codex.planMode,onPlanModeChange:e=>nr(`codex`,e),includePlanMode:!0,className:`justify-start flex-wrap`})})}),(0,G.jsx)(q,{title:`Quick Response SDK`,description:wr,alignStart:!0,children:(0,G.jsxs)(`div`,{className:`flex w-full max-w-[420px] flex-col gap-3`,children:[hn?(0,G.jsx)(`div`,{className:`rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:hn}):null,Ge?.warning?(0,G.jsx)(`div`,{className:`rounded-lg border border-border bg-card/30 px-4 py-3 text-sm text-muted-foreground`,children:Ge.warning}):null,(0,G.jsxs)(Ne,{value:V.provider,disabled:ve,onValueChange:e=>{Bt(e)&&ir(e)},children:[(0,G.jsx)(ke,{className:`w-full`,children:(0,G.jsx)(je,{})}),(0,G.jsx)(Ae,{children:(0,G.jsx)(Me,{children:_l.map(e=>(0,G.jsx)(F,{value:e.value,children:e.label},e.value))})})]}),V.provider===`custom`?(0,G.jsx)(R,{value:V.baseUrl,onChange:e=>mn({...V,baseUrl:e.target.value}),onBlur:()=>ar(),onKeyDown:e=>qo(e,ar),readOnly:ve,placeholder:`https://your-provider.example/v1`}):null,(0,G.jsx)(R,{type:`password`,value:V.apiKey,onChange:e=>mn({...V,apiKey:e.target.value}),onBlur:()=>ar(),onKeyDown:e=>qo(e,ar),readOnly:ve,placeholder:`API key`}),(0,G.jsx)(R,{value:V.model,onChange:e=>mn({...V,model:e.target.value}),onBlur:()=>ar(),onKeyDown:e=>qo(e,ar),readOnly:ve,placeholder:`Model id`})]})})]}),j===`keybindings`&&(0,G.jsx)(Zo,{state:d}),j===`skills`&&(0,G.jsx)(el,{state:d}),j===`plugins`&&(0,G.jsx)(js,{state:d}),j===`kanna-plugins`&&ft&&(0,G.jsx)(ol,{}),j===`subagents`&&(0,G.jsx)(Lr,{state:d}),j===`models`&&(0,G.jsx)(ro,{state:d}),le&&(0,G.jsx)(le,{state:d}),j===`snippets`&&(0,G.jsx)(Bo,{state:d}),j===`instructions`&&(0,G.jsx)(Pl,{state:d}),![`general`,`providers`,`keybindings`,`skills`,`plugins`,`subagents`,`models`,`mcp-servers`,`mcp-sources`,`remote-mcp`,`service-bus`,`beacons`,`snippets`,`instructions`].includes(j)&&(0,G.jsx)(jl,{status:_,releases:w,error:se,onRetry:or,updateSnapshot:H,currentVersion:Te,onInstallUpdate:e=>d.handleInstallUpdate(e),onCheckForUpdates:()=>d.handleCheckForUpdates({force:!0}),onForceReload:()=>d.handleForceReload()})]},j),d.commandError?(0,G.jsxs)(`div`,{className:`mx-auto mt-4 flex max-w-4xl items-start gap-3 rounded-lg border border-destructive/20 bg-destructive/5 px-4 py-3 text-sm text-destructive`,children:[(0,G.jsx)(Fe,{className:`mt-0.5 h-4 w-4 flex-shrink-0`}),(0,G.jsx)(`span`,{children:d.commandError})]}):null]})]})]}),K?(0,G.jsx)(`div`,{className:`absolute bottom-0 left-0 right-0 border-t border-border bg-background`,children:(0,G.jsx)(`div`,{className:`px-6 py-[14.25px]`,children:(0,G.jsxs)(`div`,{className:`grid gap-3 text-xs text-muted-foreground grid-cols-2 lg:grid-cols-4`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`mb-1 tracking-wide text-xs text-muted-foreground/80`,children:`Machine`}),(0,G.jsx)(`div`,{className:`text-foreground/80`,children:Ce})]}),(0,G.jsxs)(`div`,{className:`hidden md:block`,children:[(0,G.jsx)(`div`,{className:`mb-1 tracking-wide text-xs text-muted-foreground/80`,children:`Connection`}),(0,G.jsx)(`div`,{className:`text-foreground/80`,children:d.connectionStatus})]}),(0,G.jsxs)(`div`,{className:`hidden md:block`,children:[(0,G.jsx)(`div`,{className:`mb-1 tracking-wide text-xs text-muted-foreground/80`,children:`Projects Indexed`}),(0,G.jsx)(`div`,{className:`text-foreground/80`,children:we})]}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`mb-1 tracking-wide text-xs text-muted-foreground/80`,children:`App Version`}),(0,G.jsx)(`div`,{className:`text-foreground/80`,children:Te})]})]})})}):null,(0,G.jsx)(Ye,{open:en,onOpenChange:tn,children:(0,G.jsxs)(Je,{size:`lg`,children:[(0,G.jsxs)(Ze,{className:`space-y-4`,children:[(0,G.jsx)($e,{children:`Tracked Events`}),(0,G.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:`Kanna sends these event names plus the limited property keys below, depending on the event type.`}),(0,G.jsxs)(`div`,{className:`max-h-[60vh] overflow-auto rounded-lg border border-border bg-muted/40 p-3`,children:[(0,G.jsx)(`div`,{className:`text-xs font-medium tracking-wide text-muted-foreground`,children:`Event Names`}),(0,G.jsx)(`ul`,{className:`mt-3 space-y-2 text-sm`,children:cr.map(e=>(0,G.jsx)(`li`,{className:`font-mono text-foreground`,children:e},e))}),(0,G.jsx)(`div`,{className:`mt-6 text-xs font-medium tracking-wide text-muted-foreground`,children:`Property Keys`}),(0,G.jsx)(`ul`,{className:`mt-3 space-y-2 text-sm`,children:_r.map(e=>(0,G.jsx)(`li`,{className:`font-mono text-foreground`,children:e},e))})]})]}),(0,G.jsx)(Xe,{children:(0,G.jsx)(E,{variant:`secondary`,size:`sm`,onClick:()=>tn(!1),children:`Close`})})]})}),(0,G.jsx)(Ye,{open:Cn,onOpenChange:wn,children:(0,G.jsxs)(Je,{size:`lg`,children:[(0,G.jsxs)(Ze,{className:`space-y-4`,children:[(0,G.jsx)($e,{children:`Validation Error`}),(0,G.jsx)(`pre`,{className:`max-h-[60vh] overflow-auto rounded-lg border border-border bg-muted p-3 text-xs font-mono whitespace-pre-wrap break-words`,children:xr})]}),(0,G.jsx)(Xe,{children:(0,G.jsx)(E,{variant:`secondary`,size:`sm`,onClick:()=>wn(!1),children:`Close`})})]})})]})}export{Fl as SettingsPage};
|