tmex-cli 0.6.8 → 0.7.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.
@@ -0,0 +1,12 @@
1
+ import{c as U,y as N,w as j,ah as G,ab as se,aa as ae,ai as M,v as e,M as Z,G as w,U as W,a0 as te,a1 as ie,a2 as ne,as as re,T as Y,a3 as ce,a4 as oe,a5 as de,a6 as le,a7 as he,H as me,t as v,J as pe,N as ue,O as xe,P as I,Q as ve,R as ye,I as O,at as je,ac as fe,au as ge,av as we,V as Ne,W as De,Y as Ce,Z as be,aw as Se,_ as x,aj as z,ak as Q,al as B,am as _,an as f,af as Ee,$ as Me}from"./index-BhWcb9L_.js";import{C as S,c as E,a as Pe,b as ke,d as Ke}from"./card-BHK15lCp.js";/**
2
+ * @license lucide-react v0.564.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const Ie=[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]],$e=U("ellipsis",Ie);/**
7
+ * @license lucide-react v0.564.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */const Ae=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],Te=U("zap",Ae);function p(s){const c=s.trim();return c||void 0}function Fe(s){return s?{name:s.name,type:s.type,host:s.host??"",port:s.port??22,username:s.username??"",sshConfigRef:s.sshConfigRef??"",session:s.session??"tmex",authMode:s.type==="local"?"auto":s.authMode,password:"",privateKey:"",privateKeyPassphrase:""}:{name:"",type:"local",host:"",port:22,username:"",sshConfigRef:"",session:"tmex",authMode:"auto",password:"",privateKey:"",privateKeyPassphrase:""}}function He(s){if(s.type==="local")return{name:s.name.trim(),type:"local",session:p(s.session)??"tmex",authMode:"auto"};const c={name:s.name.trim(),type:"ssh",host:p(s.host),port:s.port,username:p(s.username),sshConfigRef:p(s.sshConfigRef),session:p(s.session)??"tmex",authMode:s.authMode};return s.authMode==="password"&&(c.password=s.password),s.authMode==="key"&&(c.privateKey=s.privateKey,c.privateKeyPassphrase=s.privateKeyPassphrase||void 0),c}function Le(s){if(s.type==="local")return{name:s.name.trim(),session:p(s.session)??"tmex",authMode:"auto"};const c={name:s.name.trim(),host:p(s.host),port:s.port,username:p(s.username),sshConfigRef:p(s.sshConfigRef),session:p(s.session)??"tmex",authMode:s.authMode};return s.authMode==="password"&&s.password&&(c.password=s.password),s.authMode==="key"&&s.privateKey&&(c.privateKey=s.privateKey,c.privateKeyPassphrase=s.privateKeyPassphrase||void 0),c}async function V(s,c){try{return(await s.json()).error??c}catch{return c}}function ze(){const{t:s}=N(),[c,h]=j.useState(!1),[a,y]=j.useState(null),[n,o]=j.useState(null),l=G();j.useEffect(()=>{const r=()=>h(!0);return window.addEventListener("tmex:open-add-device",r),()=>window.removeEventListener("tmex:open-add-device",r)},[]);const{data:d,isLoading:u,isError:P}=se({queryKey:["devices"],queryFn:async()=>{const r=await fetch("/api/devices");if(!r.ok)throw new Error(s("device.loadFailed"));return r.json()},throwOnError:!1}),D=ae(r=>r.hydrateDeviceErrors);j.useEffect(()=>{d!=null&&d.devices&&D(d.devices.map(r=>({deviceId:r.id,lastError:r.lastError??null,lastErrorType:r.lastErrorType??null})))},[d,D]);const C=M({mutationFn:async r=>{if(!(await fetch(`/api/devices/${r}`,{method:"DELETE"})).ok)throw new Error(s("device.deleteFailed"))},onSuccess:()=>{l.invalidateQueries({queryKey:["devices"]}),v.success(s("common.success"))},onError:r=>{v.error(r instanceof Error?r.message:s("common.error"))}}),b=(d==null?void 0:d.devices)??[];return e.jsxs("div",{className:"mx-auto flex w-full max-w-6xl flex-col gap-3 p-3 pb-[calc(1rem+env(safe-area-inset-bottom))] sm:gap-4 sm:p-5","data-testid":"devices-page",children:[u?e.jsx(S,{children:e.jsx(E,{className:"py-16 text-center text-sm text-muted-foreground",children:s("common.loading")})}):P?e.jsx(S,{children:e.jsx(E,{className:"py-16 text-center text-sm text-destructive",children:s("device.loadFailed")})}):b.length===0?e.jsx(S,{children:e.jsxs(E,{className:"space-y-4 py-14 text-center",children:[e.jsx("div",{className:"mx-auto flex h-12 w-12 items-center justify-center rounded-xl border border-border bg-muted",children:e.jsx(Z,{className:"h-6 w-6 text-muted-foreground"})}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("h2",{className:"text-lg font-medium",children:s("device.noDevices")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s("device.addDevice")})]}),e.jsxs(w,{variant:"default","data-testid":"devices-add-empty",onClick:()=>h(!0),children:[e.jsx(W,{className:"h-4 w-4"}),s("device.addDevice")]})]})}):e.jsx("div",{className:"grid gap-3 lg:grid-cols-2",children:b.map(r=>e.jsx(Re,{device:r,onEdit:()=>y(r),onDelete:()=>o(r)},r.id))}),c&&e.jsx(J,{mode:"create",onClose:()=>h(!1)}),a&&e.jsx(J,{mode:"edit",device:a,onClose:()=>y(null)}),e.jsx(te,{open:n!==null,onOpenChange:r=>!r&&o(null),children:e.jsxs(ie,{children:[e.jsxs(ne,{children:[e.jsx(re,{className:"bg-destructive/10",children:e.jsx(Y,{className:"h-5 w-5 text-destructive"})}),e.jsx(ce,{children:s("device.deleteConfirm")}),e.jsx(oe,{children:s("device.deleteDescription",{name:(n==null?void 0:n.name)??""})})]}),e.jsxs(de,{children:[e.jsx(le,{children:s("common.cancel")}),e.jsx(he,{variant:"destructive",disabled:!n||C.isPending,onClick:()=>{n&&(C.mutate(n.id),o(null))},children:s("common.delete")})]})]})})]})}function Re({device:s,onEdit:c,onDelete:h}){const{t:a}=N(),y=s.type==="local"?e.jsx(Z,{className:"h-4 w-4"}):e.jsx(me,{className:"h-4 w-4"}),n=s.type==="local"?a("device.typeLocal"):`${s.username??"-"}@${s.host??"-"}:${s.port??22}`,o=M({mutationFn:async()=>{const l=await fetch(`/api/devices/${s.id}/test-connection`,{method:"POST"});let d=null;try{d=await l.json()}catch{d=null}if(!l.ok){const u=d;throw new Error((u==null?void 0:u.error)??a("common.error"))}return d},onSuccess:l=>{v.success(l.message??a("common.success"))},onError:l=>{v.error(l instanceof Error?l.message:a("common.error"))}});return e.jsxs(S,{"data-testid":"device-card","data-device-id":s.id,"data-device-name":s.name,className:"overflow-hidden",children:[e.jsxs(Pe,{className:"space-y-2 pb-2",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2.5",children:[e.jsx("div",{className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border bg-muted text-muted-foreground",children:y}),e.jsxs("div",{className:"min-w-0 space-y-0.5",children:[e.jsx(ke,{className:"line-clamp-1 text-sm",title:s.name,children:s.name}),e.jsx(Ke,{className:"line-clamp-1 text-xs",children:n})]})]}),e.jsx("div",{className:"flex shrink-0 items-center gap-1",children:e.jsxs(pe,{children:[e.jsx(ue,{render:e.jsx(w,{variant:"ghost",size:"icon-sm","data-testid":`device-card-actions-${s.id}`,"aria-label":a("common.edit"),title:a("common.edit")}),children:e.jsx($e,{className:"h-4 w-4"})}),e.jsxs(xe,{align:"end",children:[e.jsxs(I,{"data-testid":`device-card-edit-${s.id}`,onClick:c,children:[e.jsx(ve,{className:"h-4 w-4"}),a("common.edit")]}),s.type==="ssh"&&e.jsxs(I,{"data-testid":`device-card-test-${s.id}`,onClick:()=>o.mutate(),disabled:o.isPending,children:[e.jsx(Te,{className:"h-4 w-4"}),a("common.test")]}),e.jsx(ye,{}),e.jsxs(I,{"data-testid":`device-card-delete-${s.id}`,variant:"destructive",onClick:h,children:[e.jsx(Y,{className:"h-4 w-4"}),a("common.delete")]})]})]})})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[e.jsx(O,{variant:"outline",className:"text-[11px] font-normal",children:s.type==="local"?a("device.typeLocal"):a("device.typeSSHBadge")}),s.session&&e.jsx(O,{variant:"outline",className:"text-[11px] font-normal",children:s.session}),e.jsx(je,{deviceId:s.id})]})]}),e.jsxs(E,{className:"pt-0",children:[e.jsx(fe,{className:"mb-2"}),e.jsx("div",{className:"flex items-center justify-end",children:e.jsx(ge,{to:`/devices/${s.id}`,"data-testid":`device-card-connect-${s.id}`,className:we({variant:"default",size:"sm"}),children:a("device.connect")})})]})]})}function J({mode:s,device:c,onClose:h}){const{t:a}=N(),y=G(),[n,o]=j.useState(Fe(c)),[l,d]=j.useState(!1),u=s==="edit",P=n.type==="ssh",D=M({mutationFn:async t=>{const i=await fetch("/api/devices",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!i.ok)throw new Error(await V(i,a("device.createFailed")));return i.json()},onSuccess:()=>{y.invalidateQueries({queryKey:["devices"]}),v.success(a("common.success")),h()},onError:t=>{v.error(t instanceof Error?t.message:a("common.error"))}}),C=M({mutationFn:async t=>{if(!c)throw new Error(a("apiError.deviceNotFound"));const i=await fetch(`/api/devices/${c.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!i.ok)throw new Error(await V(i,a("device.updateFailed")));return i.json()},onSuccess:()=>{y.invalidateQueries({queryKey:["devices"]}),v.success(a("common.success")),h()},onError:t=>{v.error(t instanceof Error?t.message:a("common.error"))}}),b=async t=>{t.preventDefault(),d(!0);try{s==="create"?await D.mutateAsync(He(n)):await C.mutateAsync(Le(n))}catch{}finally{d(!1)}},r=`${s}-device-name`,k=`${s}-device-type`,$=`${s}-device-host`,A=`${s}-device-port`,T=`${s}-device-username`,F=`${s}-device-session`,H=`${s}-device-auth-mode`,L=`${s}-device-password`,R=`${s}-device-private-key`,q=`${s}-device-private-key-passphrase`,X={local:a("device.typeLocal"),ssh:a("device.typeSSH")},ee={password:a("device.authPassword"),key:a("device.authKey"),agent:a("device.authAgent"),configRef:"SSH Config"},K=t=>e.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-muted-foreground",children:t}),m=(t,i,g)=>e.jsxs("label",{className:"block text-xs font-medium text-foreground",htmlFor:t,children:[i,g&&e.jsx("span",{className:"ml-0.5 text-destructive",children:"*"})]});return e.jsx(Ne,{open:!0,onOpenChange:t=>!t&&h(),children:e.jsxs(De,{"data-testid":"device-dialog",className:"w-full max-w-2xl",children:[e.jsxs(Ce,{children:[e.jsx(be,{children:a(u?"device.editDevice":"device.addDevice")}),e.jsx(Se,{children:a(u?"device.editDeviceDescription":"device.addDeviceDescription")})]}),e.jsxs("form",{onSubmit:b,className:"space-y-4",children:[e.jsxs("div",{className:"-mr-2 max-h-[min(70vh,720px)] space-y-5 overflow-y-auto pr-2",children:[e.jsxs("section",{className:"space-y-2.5",children:[K(a("device.sectionBasic")),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{className:"space-y-1.5 sm:col-span-2",children:[m(r,a("device.name"),!0),e.jsx(x,{id:r,"data-testid":"device-name-input",type:"text",value:n.name,onChange:t=>o(i=>({...i,name:t.target.value})),placeholder:a("device.namePlaceholder"),required:!0})]}),e.jsxs("div",{className:"space-y-1.5",children:[m(k,a("device.type")),e.jsxs(z,{value:n.type,onValueChange:t=>{if(!t)return;const i=t;o(g=>({...g,type:i,authMode:i==="local"?"auto":g.authMode==="auto"?"password":g.authMode}))},disabled:u,children:[e.jsx(Q,{id:k,"data-testid":"device-type-select",className:"w-full",children:e.jsx(B,{placeholder:a("device.type"),children:t=>X[t]??""})}),e.jsxs(_,{children:[e.jsx(f,{value:"local",children:a("device.typeLocal")}),e.jsx(f,{value:"ssh",children:a("device.typeSSH")})]})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[m(F,a("device.session")),e.jsx(x,{id:F,"data-testid":"device-session-input",type:"text",value:n.session,onChange:t=>o(i=>({...i,session:t.target.value})),placeholder:a("device.sessionPlaceholder")})]})]})]}),P&&e.jsxs(e.Fragment,{children:[e.jsxs("section",{className:"space-y-2.5",children:[K(a("device.sectionConnection")),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-3",children:[e.jsxs("div",{className:"space-y-1.5 sm:col-span-2",children:[m($,a("device.host")),e.jsx(x,{id:$,type:"text",value:n.host,onChange:t=>o(i=>({...i,host:t.target.value})),placeholder:a("device.hostPlaceholder")})]}),e.jsxs("div",{className:"space-y-1.5",children:[m(A,a("device.port")),e.jsx(x,{id:A,type:"number",value:n.port,onChange:t=>o(i=>({...i,port:Number.parseInt(t.target.value||"22",10)})),min:1,max:65535})]}),e.jsxs("div",{className:"space-y-1.5 sm:col-span-2",children:[m(T,a("device.username")),e.jsx(x,{id:T,type:"text",value:n.username,onChange:t=>o(i=>({...i,username:t.target.value})),placeholder:a("device.usernamePlaceholder")})]}),e.jsxs("div",{className:"space-y-1.5",children:[m(`${s}-device-ssh-config-ref`,"SSH Config"),e.jsx(x,{id:`${s}-device-ssh-config-ref`,type:"text",value:n.sshConfigRef,onChange:t=>o(i=>({...i,sshConfigRef:t.target.value})),placeholder:"~/.ssh/config"})]})]})]}),e.jsxs("section",{className:"space-y-2.5",children:[K(a("device.sectionAuth")),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[m(H,a("device.authMode")),e.jsxs(z,{value:n.authMode,onValueChange:t=>{t&&o(i=>({...i,authMode:t}))},children:[e.jsx(Q,{id:H,className:"w-full",children:e.jsx(B,{placeholder:a("device.authMode"),children:t=>ee[t]??""})}),e.jsxs(_,{children:[e.jsx(f,{value:"password",children:a("device.authPassword")}),e.jsx(f,{value:"key",children:a("device.authKey")}),e.jsx(f,{value:"agent",children:a("device.authAgent")}),e.jsx(f,{value:"configRef",children:"SSH Config"})]})]})]}),n.authMode==="password"&&e.jsxs("div",{className:"space-y-1.5",children:[m(L,a("device.password")),e.jsx(x,{id:L,type:"password",value:n.password,onChange:t=>o(i=>({...i,password:t.target.value}))})]}),n.authMode==="key"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1.5",children:[m(R,a("device.privateKey")),e.jsx(Ee,{id:R,value:n.privateKey,onChange:t=>o(i=>({...i,privateKey:t.target.value})),className:"h-28 font-mono text-xs",placeholder:a("device.privateKeyPlaceholder")})]}),e.jsxs("div",{className:"space-y-1.5",children:[m(q,a("device.passphrase")),e.jsx(x,{id:q,type:"password",value:n.privateKeyPassphrase,onChange:t=>o(i=>({...i,privateKeyPassphrase:t.target.value}))})]})]})]})]})]})]}),e.jsxs(Me,{children:[e.jsx(w,{type:"button",variant:"outline",onClick:h,children:a("common.cancel")}),e.jsx(w,{type:"submit",variant:"default","data-testid":"device-dialog-save",disabled:l,children:a(l?"common.saving":"common.save")})]})]})]})})}function Qe(){const{t:s}=N();return e.jsx(e.Fragment,{children:s("sidebar.manageDevices")})}function Be(){const{t:s}=N(),c=()=>{window.dispatchEvent(new CustomEvent("tmex:open-add-device"))};return e.jsx(w,{variant:"ghost",size:"icon-sm","data-testid":"devices-add",onClick:c,"aria-label":s("sidebar.addDevice"),title:s("sidebar.addDevice"),children:e.jsx(W,{className:"h-4 w-4"})})}export{Be as PageActions,Qe as PageTitle,ze as default};
12
+ //# sourceMappingURL=DevicesPage-_lgEXguX.js.map
@@ -0,0 +1,17 @@
1
+ import{c as de,y as A,ah as Q,w as r,ab as I,ai as S,t as m,v as e,_ as v,aj as z,ak as H,al as V,am as J,an as U,G as x,L as D,ae as $,T as G,a0 as me,a1 as he,a2 as ue,a3 as ge,a4 as xe,a5 as pe,a6 as fe,a7 as je,ao as Ue,ap as Re,aq as Ie,ar as Qe,s as Ze}from"./index-BhWcb9L_.js";import{C as M,a as q,b as _,c as R}from"./card-BHK15lCp.js";import{R as es}from"./refresh-cw-DfNqpalN.js";import{S as ss}from"./send-XA81w52-.js";/**
2
+ * @license lucide-react v0.564.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const ts=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],as=de("rotate-ccw",ts);/**
7
+ * @license lucide-react v0.564.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */const ns=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],B=de("save",ns);/**
12
+ * @license lucide-react v0.564.0 - ISC
13
+ *
14
+ * This source code is licensed under the ISC license.
15
+ * See the LICENSE file in the root directory of this source tree.
16
+ */const is=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]],Oe=de("shield",is),ze=["openai-chat","openai-responses"];async function O(s,a){try{return(await s.json()).error??a}catch{return a}}function ls(){var b;const{t:s}=A(),a=Q(),[h,n]=r.useState(""),[d,p]=r.useState(""),[w,f]=r.useState("openai-chat"),[u,y]=r.useState(""),N=I({queryKey:["llm-providers"],queryFn:async()=>{const c=await fetch("/api/llm/providers");if(!c.ok)throw new Error(await O(c,s("settings.llm.loadFailed")));return await c.json()}}),g=S({mutationFn:async()=>{const c={name:h.trim(),protocol:w,baseUrl:d.trim(),apiKey:u.trim(),enabled:!0},E=await fetch("/api/llm/providers",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});if(!E.ok)throw new Error(await O(E,s("settings.llm.createFailed")));return await E.json()},onSuccess:async c=>{n(""),p(""),f("openai-chat"),y(""),await a.invalidateQueries({queryKey:["llm-providers"]}),c.modelsError?m.warning(s("settings.llm.modelsFetchFailed",{error:c.modelsError})):m.success(s("common.success"))},onError:c=>{m.error(c instanceof Error?c.message:s("common.error"))}}),j=((b=N.data)==null?void 0:b.providers)??[];return e.jsxs(e.Fragment,{children:[e.jsxs(M,{className:"border-0 ring-0","data-testid":"llm-providers-section",children:[e.jsx(q,{children:e.jsx(_,{children:s("settings.llm.title")})}),e.jsxs(R,{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end",children:[e.jsxs("div",{className:"md:col-span-3 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"new-llm-provider-name",children:s("settings.llm.name")}),e.jsx(v,{id:"new-llm-provider-name","data-testid":"llm-provider-name-input",value:h,onChange:c=>n(c.target.value),placeholder:s("settings.llm.namePlaceholder"),className:"min-h-10"})]}),e.jsxs("div",{className:"md:col-span-4 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"new-llm-provider-baseurl",children:s("settings.llm.baseUrl")}),e.jsx(v,{id:"new-llm-provider-baseurl","data-testid":"llm-provider-baseurl-input",value:d,onChange:c=>p(c.target.value),placeholder:s("settings.llm.baseUrlPlaceholder"),className:"min-h-10"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s("settings.llm.baseUrlHint")})]}),e.jsxs("div",{className:"md:col-span-2 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"new-llm-provider-protocol",children:s("settings.llm.protocol")}),e.jsxs(z,{value:w,onValueChange:c=>{c&&f(c)},children:[e.jsx(H,{id:"new-llm-provider-protocol","data-testid":"llm-provider-protocol-select",className:"w-full min-h-10",children:e.jsx(V,{})}),e.jsx(J,{children:ze.map(c=>e.jsx(U,{value:c,children:c},c))})]})]}),e.jsxs("div",{className:"md:col-span-3 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"new-llm-provider-apikey",children:s("settings.llm.apiKey")}),e.jsx(v,{id:"new-llm-provider-apikey","data-testid":"llm-provider-apikey-input",type:"password",value:u,onChange:c=>y(c.target.value),placeholder:s("settings.llm.apiKeyPlaceholder"),className:"min-h-10"})]})]}),e.jsx("div",{className:"flex justify-end",children:e.jsxs(x,{variant:"default","data-testid":"llm-provider-add",onClick:()=>g.mutate(),disabled:g.isPending||!h.trim()||!d.trim()||!u.trim(),className:"w-full sm:w-auto",children:[g.isPending?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(B,{className:"h-4 w-4"}),s("settings.llm.addProvider")]})}),e.jsxs("div",{className:"space-y-3",children:[N.isLoading&&e.jsx("div",{className:"text-sm text-muted-foreground",children:s("common.loading")}),!N.isLoading&&j.length===0&&e.jsx("div",{className:"text-sm text-muted-foreground","data-testid":"llm-providers-empty",children:s("settings.llm.empty")}),j.map(c=>e.jsx(rs,{provider:c},c.id))]})]})]}),e.jsx(os,{providers:j})]})}function rs({provider:s}){const{t:a}=A(),h=Q(),[n,d]=r.useState(s.name),[p,w]=r.useState(s.baseUrl),[f,u]=r.useState(s.protocol),[y,N]=r.useState(""),[g,j]=r.useState(s.enabled),[b,c]=r.useState(!1),[E,F]=r.useState(!1);r.useEffect(()=>{d(s.name),w(s.baseUrl),u(s.protocol),j(s.enabled)},[s.name,s.baseUrl,s.protocol,s.enabled]);const i=S({mutationFn:async()=>{const o={name:n.trim(),baseUrl:p.trim(),protocol:f,enabled:g};y.trim()&&(o.apiKey=y.trim());const l=await fetch(`/api/llm/providers/${s.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!l.ok)throw new Error(await O(l,a("settings.llm.updateFailed")));return await l.json()},onSuccess:async o=>{N(""),await h.invalidateQueries({queryKey:["llm-providers"]}),o.modelsError?m.warning(a("settings.llm.modelsFetchFailed",{error:o.modelsError})):m.success(a("common.success"))},onError:o=>{m.error(o instanceof Error?o.message:a("common.error"))}}),P=S({mutationFn:async()=>{const o=await fetch(`/api/llm/providers/${s.id}`,{method:"DELETE"});if(!o.ok)throw new Error(await O(o,a("settings.llm.deleteFailed")))},onSuccess:async()=>{await h.invalidateQueries({queryKey:["llm-providers"]}),await h.invalidateQueries({queryKey:["llm-settings"]}),m.success(a("common.success"))},onError:o=>{m.error(o instanceof Error?o.message:a("common.error"))}}),K=S({mutationFn:async()=>{const o=await fetch(`/api/llm/providers/${s.id}/refresh-models`,{method:"POST"});if(!o.ok)throw new Error(await O(o,a("settings.llm.refreshModelsFailed")))},onSuccess:async()=>{await h.invalidateQueries({queryKey:["llm-providers"]}),m.success(a("common.success"))},onError:o=>{m.error(o instanceof Error?o.message:a("common.error"))}});return e.jsxs("div",{className:"space-y-4 rounded-md border-0 bg-card p-4","data-testid":`llm-provider-card-${s.id}`,"data-provider-name":s.name,children:[e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end",children:[e.jsxs("div",{className:"md:col-span-3 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:`llm-provider-name-${s.id}`,children:a("settings.llm.name")}),e.jsx(v,{id:`llm-provider-name-${s.id}`,value:n,onChange:o=>d(o.target.value),className:"min-h-10"})]}),e.jsxs("div",{className:"md:col-span-4 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:`llm-provider-baseurl-${s.id}`,children:a("settings.llm.baseUrl")}),e.jsx(v,{id:`llm-provider-baseurl-${s.id}`,value:p,onChange:o=>w(o.target.value),className:"min-h-10"})]}),e.jsxs("div",{className:"md:col-span-2 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:`llm-provider-protocol-${s.id}`,children:a("settings.llm.protocol")}),e.jsxs(z,{value:f,onValueChange:o=>{o&&u(o)},children:[e.jsx(H,{id:`llm-provider-protocol-${s.id}`,className:"w-full min-h-10",children:e.jsx(V,{})}),e.jsx(J,{children:ze.map(o=>e.jsx(U,{value:o,children:o},o))})]})]}),e.jsxs("div",{className:"md:col-span-3 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:`llm-provider-apikey-${s.id}`,children:a("settings.llm.apiKey")}),e.jsx(v,{id:`llm-provider-apikey-${s.id}`,"data-testid":`llm-provider-apikey-${s.id}`,"data-key-set":s.hasApiKey?"true":"false",type:"password",value:y,onChange:o=>N(o.target.value),placeholder:s.hasApiKey?a("settings.llm.apiKeySetPlaceholder"):a("settings.llm.apiKeyPlaceholder"),className:"min-h-10"})]})]}),e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("div",{className:"flex min-h-10 items-center gap-3 rounded-lg border border-border bg-background px-3 py-2",children:[e.jsx("span",{className:"text-sm font-medium",children:a("common.enabled")}),e.jsx($,{checked:g,onCheckedChange:o=>j(!!o),"data-testid":`llm-provider-enabled-${s.id}`})]}),e.jsxs(x,{variant:"outline",size:"sm","data-testid":`llm-provider-refresh-models-${s.id}`,onClick:()=>K.mutate(),disabled:K.isPending,children:[K.isPending?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(es,{className:"h-4 w-4"}),a("settings.llm.refreshModels")]}),e.jsx(x,{variant:"ghost",size:"sm","data-testid":`llm-provider-toggle-models-${s.id}`,onClick:()=>c(o=>!o),children:s.models.length>0?a("settings.llm.modelsCount",{total:s.models.length}):a("settings.llm.modelsNotFetched")})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(x,{variant:"destructive",size:"sm","data-testid":`llm-provider-delete-${s.id}`,onClick:()=>F(!0),disabled:P.isPending,children:[e.jsx(G,{className:"h-4 w-4"}),a("common.delete")]}),e.jsxs(x,{variant:"default",size:"sm","data-testid":`llm-provider-save-${s.id}`,onClick:()=>i.mutate(),disabled:i.isPending||!n.trim()||!p.trim(),children:[i.isPending?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(B,{className:"h-4 w-4"}),a("common.save")]})]})]}),b&&s.models.length>0&&e.jsx("div",{className:"max-h-48 overflow-y-auto rounded-lg border border-border bg-background p-3","data-testid":`llm-provider-models-${s.id}`,children:e.jsx("ul",{className:"space-y-1",children:s.models.map(o=>e.jsx("li",{className:"font-mono text-xs text-muted-foreground",children:o},o))})}),e.jsx(me,{open:E,onOpenChange:F,children:e.jsxs(he,{children:[e.jsxs(ue,{children:[e.jsx(ge,{children:a("settings.llm.deleteProvider")}),e.jsx(xe,{children:a("settings.llm.deleteConfirm",{name:s.name})})]}),e.jsxs(pe,{children:[e.jsx(fe,{onClick:()=>F(!1),children:a("common.cancel")}),e.jsx(je,{variant:"destructive","data-testid":`llm-provider-delete-confirm-${s.id}`,onClick:()=>{P.mutate(),F(!1)},children:a("common.confirm")})]})]})})]})}const re="__none__";function os({providers:s}){var E,F;const{t:a}=A(),h=Q(),[n,d]=r.useState(null),[p,w]=r.useState(""),f=I({queryKey:["llm-settings"],queryFn:async()=>{const i=await fetch("/api/llm/settings");if(!i.ok)throw new Error(await O(i,a("settings.llm.settingsLoadFailed")));return await i.json()}}),u=((E=f.data)==null?void 0:E.settings.defaultProviderId)??null,y=((F=f.data)==null?void 0:F.settings.defaultModelId)??"",N=!!f.data;r.useEffect(()=>{N&&(d(u),w(y))},[N,u,y]);const g=S({mutationFn:async()=>{const i={defaultProviderId:n,defaultModelId:p.trim()||null},P=await fetch("/api/llm/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!P.ok)throw new Error(await O(P,a("settings.llm.settingsSaveFailed")))},onSuccess:async()=>{await h.invalidateQueries({queryKey:["llm-settings"]}),m.success(a("common.success"))},onError:i=>{m.error(i instanceof Error?i.message:a("common.error"))}}),j=s.filter(i=>i.enabled),b=s.find(i=>i.id===n),c=(b==null?void 0:b.models)??[];return e.jsxs(M,{className:"border-0 ring-0","data-testid":"llm-defaults-section",children:[e.jsx(q,{children:e.jsx(_,{children:a("settings.llm.defaults")})}),e.jsxs(R,{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"llm-default-provider-select",children:a("settings.llm.defaultProvider")}),e.jsxs(z,{value:n??re,onValueChange:i=>{i&&d(i===re?null:i)},children:[e.jsx(H,{id:"llm-default-provider-select","data-testid":"llm-default-provider-select",className:"w-full min-h-10",children:e.jsx(V,{children:(b==null?void 0:b.name)??a("settings.llm.defaultProviderNone")})}),e.jsxs(J,{children:[e.jsx(U,{value:re,children:a("settings.llm.defaultProviderNone")}),j.map(i=>e.jsx(U,{value:i.id,children:i.name},i.id))]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"llm-default-model-input",children:a("settings.llm.defaultModel")}),e.jsx(v,{id:"llm-default-model-input","data-testid":"llm-default-model-input",list:"llm-default-model-options",value:p,onChange:i=>w(i.target.value),placeholder:a("settings.llm.defaultModelPlaceholder"),className:"min-h-10"}),e.jsx("datalist",{id:"llm-default-model-options",children:c.map(i=>e.jsx("option",{value:i},i))})]})]}),e.jsx("div",{className:"flex justify-end",children:e.jsxs(x,{variant:"default","data-testid":"llm-defaults-save",onClick:()=>g.mutate(),disabled:g.isPending||f.isLoading,className:"w-full sm:w-auto",children:[g.isPending?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(B,{className:"h-4 w-4"}),a("settings.llm.saveDefaults")]})})]})]})}const cs=["none","tavily","brave"];async function oe(s,a){try{return(await s.json()).error??a}catch{return a}}function ds(){var F;const{t:s}=A(),a=Q(),[h,n]=r.useState("none"),[d,p]=r.useState(""),[w,f]=r.useState(""),[u,y]=r.useState(null),N=I({queryKey:["llm-settings"],queryFn:async()=>{const i=await fetch("/api/llm/settings");if(!i.ok)throw new Error(await oe(i,s("settings.search.loadFailed")));return await i.json()}}),g=(F=N.data)==null?void 0:F.settings,j=g==null?void 0:g.searchProvider;r.useEffect(()=>{j&&n(j)},[j]);const b=S({mutationFn:async()=>{const i={searchProvider:h};d.trim()&&(i.tavilyApiKey=d.trim()),w.trim()&&(i.braveApiKey=w.trim());const P=await fetch("/api/llm/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!P.ok)throw new Error(await oe(P,s("settings.search.saveFailed")))},onSuccess:async()=>{p(""),f(""),await a.invalidateQueries({queryKey:["llm-settings"]}),m.success(s("common.success"))},onError:i=>{m.error(i instanceof Error?i.message:s("common.error"))}}),c=S({mutationFn:async i=>{const P={[i]:""},K=await fetch("/api/llm/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(P)});if(!K.ok)throw new Error(await oe(K,s("settings.search.saveFailed")))},onSuccess:async()=>{await a.invalidateQueries({queryKey:["llm-settings"]}),m.success(s("common.success"))},onError:i=>{m.error(i instanceof Error?i.message:s("common.error"))}}),E=i=>i==="none"?s("settings.search.providerNone"):i==="tavily"?"Tavily":"Brave";return e.jsxs(M,{className:"border-0 ring-0","data-testid":"settings-search-section",children:[e.jsx(q,{children:e.jsx(_,{children:s("settings.search.title")})}),e.jsxs(R,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"search-provider-select",children:s("settings.search.provider")}),e.jsxs(z,{value:h,onValueChange:i=>{i&&n(i)},children:[e.jsx(H,{id:"search-provider-select","data-testid":"settings-search-provider-select",className:"w-full min-h-10",children:e.jsx(V,{children:E(h)})}),e.jsx(J,{children:cs.map(i=>e.jsx(U,{value:i,children:E(i)},i))})]})]}),e.jsx(De,{id:"search-tavily-key-input",testId:"settings-search-tavily",label:s("settings.search.tavilyApiKey"),value:d,hasKey:(g==null?void 0:g.hasTavilyApiKey)??!1,onChange:p,onClear:()=>y("tavilyApiKey"),clearing:c.isPending&&c.variables==="tavilyApiKey"}),e.jsx(De,{id:"search-brave-key-input",testId:"settings-search-brave",label:s("settings.search.braveApiKey"),value:w,hasKey:(g==null?void 0:g.hasBraveApiKey)??!1,onChange:f,onClear:()=>y("braveApiKey"),clearing:c.isPending&&c.variables==="braveApiKey"}),e.jsx(me,{open:u!==null,onOpenChange:i=>{i||y(null)},children:e.jsxs(he,{children:[e.jsxs(ue,{children:[e.jsx(ge,{children:s("settings.search.clearKey")}),e.jsx(xe,{children:s("settings.search.clearKeyConfirm")})]}),e.jsxs(pe,{children:[e.jsx(fe,{children:s("common.cancel")}),e.jsx(je,{"data-testid":"settings-search-clear-confirm",onClick:()=>{u&&c.mutate(u),y(null)},children:s("settings.search.clearKey")})]})]})}),e.jsx("div",{className:"flex justify-end",children:e.jsxs(x,{variant:"default","data-testid":"settings-search-save",onClick:()=>b.mutate(),disabled:b.isPending||N.isLoading,className:"w-full sm:w-auto",children:[b.isPending?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(B,{className:"h-4 w-4"}),s("common.save")]})})]})]})}function De({id:s,testId:a,label:h,value:n,hasKey:d,onChange:p,onClear:w,clearing:f}){const{t:u}=A();return e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:s,children:h}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(v,{id:s,"data-testid":`${a}-input`,"data-key-set":d?"true":"false",type:"password",value:n,onChange:y=>p(y.target.value),placeholder:u(d?"settings.search.keySetPlaceholder":"settings.search.keyPlaceholder"),className:"min-h-10"}),d&&e.jsxs(x,{variant:"outline",size:"sm","data-testid":`${a}-clear`,onClick:w,disabled:f,className:"shrink-0",children:[e.jsx(G,{className:"h-4 w-4"}),u("settings.search.clearKey")]})]})]})}const ce=["terminal_bell","terminal_notification","tmux_window_close","tmux_pane_close","device_tmux_missing","device_disconnect","session_created","session_closed","agent_confirmation_pending","agent_turn_finished","agent_error","watch_triggered","watch_model_unavailable","watch_rule_error"];async function T(s,a){try{return(await s.json()).error??a}catch{return a}}function ps(){var Be,Me,qe,_e;const{t:s}=A(),a=Q(),{refreshSettings:h}=Ue(),[n,d]=r.useState("site"),p=Re(t=>t.theme),w=Re(t=>t.setTheme),f=p==="dark",[u,y]=r.useState("tmex"),[N,g]=r.useState(window.location.origin),[j,b]=r.useState("en_US"),[c,E]=r.useState(6),[F,i]=r.useState(3),[P,K]=r.useState(!0),[o,l]=r.useState(!0),[C,L]=r.useState(!0),[ye,be]=r.useState(!0),[we,ve]=r.useState(2),[Ne,ke]=r.useState(10),[He,Ve]=r.useState(!1),[X,Ce]=r.useState(""),[Y,Se]=r.useState(""),[Je,We]=r.useState(null),[Z,Ee]=r.useState(""),[ee,Pe]=r.useState(""),[se,Fe]=r.useState(ce),Ge=t=>{const k=t?"dark":"light";w(k),document.documentElement.classList.toggle("dark",k==="dark")},te=I({queryKey:["site-settings"],queryFn:async()=>{const t=await fetch("/api/settings/site");if(!t.ok)throw new Error(await T(t,s("settings.loadFailed")));return await t.json()}}),ae=I({queryKey:["telegram-bots"],queryFn:async()=>{const t=await fetch("/api/settings/telegram/bots");if(!t.ok)throw new Error(await T(t,s("telegram.loadBotsFailed")));return await t.json()}});r.useEffect(()=>{var k;const t=(k=te.data)==null?void 0:k.settings;t&&(y(t.siteName),g(t.siteUrl),b(t.language??"en_US"),E(t.bellThrottleSeconds),i(t.notificationThrottleSeconds??3),K(t.enableBrowserBellToast??!0),l(t.enableBrowserNotificationToast??!0),L(t.enableTelegramBellPush??!0),be(t.enableTelegramNotificationPush??!0),ve(t.sshReconnectMaxRetries),ke(t.sshReconnectDelaySeconds))},[(Be=te.data)==null?void 0:Be.settings]);const Te=S({mutationFn:async()=>{const k=await fetch("/api/settings/site",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({siteName:u,siteUrl:N,language:j,bellThrottleSeconds:c,notificationThrottleSeconds:F,enableBrowserBellToast:P,enableBrowserNotificationToast:o,enableTelegramBellPush:C,enableTelegramNotificationPush:ye,sshReconnectMaxRetries:we,sshReconnectDelaySeconds:Ne})});if(!k.ok)throw new Error(await T(k,s("settings.saveFailed")))},onSuccess:async()=>{var t,k;await Promise.all([a.invalidateQueries({queryKey:["site-settings"]}),h()]),m.success(s("settings.settingsSaved")),((k=(t=te.data)==null?void 0:t.settings)==null?void 0:k.language)!==j&&(Ze.changeLanguage(j),Ve(!0))},onError:t=>{m.error(t instanceof Error?t.message:s("common.error"))}}),ne=S({mutationFn:async()=>{const t=await fetch("/api/settings/telegram/bots",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:X,token:Y,enabled:!0,allowAuthRequests:!0})});if(!t.ok)throw new Error(await T(t,s("telegram.createFailed")))},onSuccess:async()=>{Ce(""),Se(""),await a.invalidateQueries({queryKey:["telegram-bots"]}),m.success(s("common.success"))},onError:t=>{m.error(t instanceof Error?t.message:s("common.error"))}}),Ke=((Me=ae.data)==null?void 0:Me.bots)??[],ie=I({queryKey:["webhooks"],queryFn:async()=>{const t=await fetch("/api/webhooks");if(!t.ok)throw new Error(await T(t,s("webhook.loadFailed")));return await t.json()}}),le=S({mutationFn:async()=>{const t=await fetch("/api/webhooks",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:Z,secret:ee,eventMask:se})});if(!t.ok)throw new Error(await T(t,s("webhook.createFailed")))},onSuccess:async()=>{Ee(""),Pe(""),Fe(ce),await a.invalidateQueries({queryKey:["webhooks"]}),m.success(s("common.success"))},onError:t=>{m.error(t instanceof Error?t.message:s("common.error"))}}),Ae=S({mutationFn:async t=>{const k=await fetch(`/api/webhooks/${t}`,{method:"DELETE"});if(!k.ok)throw new Error(await T(k,s("webhook.deleteFailed")))},onSuccess:async()=>{await a.invalidateQueries({queryKey:["webhooks"]}),m.success(s("common.success"))},onError:t=>{m.error(t instanceof Error?t.message:s("common.error"))}}),$e=((qe=ie.data)==null?void 0:qe.webhooks)??[];return e.jsxs("div",{className:"mx-auto flex w-full max-w-6xl flex-col gap-4 p-3 pb-[calc(2rem+env(safe-area-inset-bottom))] sm:gap-6 sm:p-5","data-testid":"settings-page",children:[e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(x,{type:"button",size:"sm",variant:n==="site"?"default":"outline","data-testid":"settings-tab-site",onClick:()=>d("site"),children:s("settings.siteSettings")}),e.jsx(x,{type:"button",size:"sm",variant:n==="notifications"?"default":"outline","data-testid":"settings-tab-notifications",onClick:()=>d("notifications"),children:s("settings.notificationsTab")}),e.jsx(x,{type:"button",size:"sm",variant:n==="telegram"?"default":"outline","data-testid":"settings-tab-telegram",onClick:()=>d("telegram"),children:s("telegram.title")}),e.jsx(x,{type:"button",size:"sm",variant:n==="webhooks"?"default":"outline","data-testid":"settings-tab-webhooks",onClick:()=>d("webhooks"),children:s("webhook.title")}),e.jsx(x,{type:"button",size:"sm",variant:n==="llm"?"default":"outline","data-testid":"settings-tab-llm",onClick:()=>d("llm"),children:s("settings.llm.title")}),e.jsx(x,{type:"button",size:"sm",variant:n==="search"?"default":"outline","data-testid":"settings-tab-search",onClick:()=>d("search"),children:s("settings.search.title")})]}),n==="site"&&e.jsxs(M,{className:"border-0 ring-0",children:[e.jsx(q,{children:e.jsx(_,{children:s("settings.siteSettings")})}),e.jsxs(R,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"site-name-input",children:s("settings.siteName")}),e.jsx(v,{id:"site-name-input",value:u,onChange:t=>y(t.target.value),placeholder:s("settings.siteNamePlaceholder"),className:"min-h-10"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"site-url-input",children:s("settings.siteUrl")}),e.jsx(v,{id:"site-url-input",value:N,onChange:t=>g(t.target.value),placeholder:s("settings.siteUrlPlaceholder"),className:"min-h-10"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"language-select",children:s("settings.language")}),e.jsxs(z,{value:j,onValueChange:t=>{t&&b(t)},children:[e.jsx(H,{id:"language-select","data-testid":"settings-language-select",className:"w-full min-h-10",children:e.jsx(V,{placeholder:s("settings.language"),children:((_e=Ie.locales.find(t=>t.code===j))==null?void 0:_e.nativeName)??j})}),e.jsx(J,{className:"max-h-[var(--tmex-viewport-height)]",children:Ie.locales.map(t=>e.jsx(U,{value:t.code,children:t.nativeName},t.code))})]}),He&&e.jsx("p",{className:"mt-1 text-xs text-primary","data-testid":"settings-refresh-notice",children:s("settings.refreshToApply")})]}),e.jsx("div",{className:"space-y-3",children:e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsx("div",{className:"min-w-0 pr-2",children:e.jsx("div",{className:"text-sm font-medium",children:s("settings.theme")})}),e.jsx($,{checked:f,onCheckedChange:t=>Ge(!!t),"data-testid":"settings-theme-toggle"})]})})]})]}),n==="notifications"&&e.jsxs(M,{className:"border-0 ring-0",children:[e.jsx(q,{children:e.jsx(_,{children:s("settings.notificationsTab")})}),e.jsxs(R,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsx("div",{className:"min-w-0 pr-2",children:e.jsx("div",{className:"text-sm font-medium",children:s("settings.enableBrowserBellToast")})}),e.jsx($,{checked:P,onCheckedChange:t=>K(!!t),"data-testid":"settings-enable-browser-bell-toast"})]}),e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsx("div",{className:"min-w-0 pr-2",children:e.jsx("div",{className:"text-sm font-medium",children:s("settings.enableTelegramBellPush")})}),e.jsx($,{checked:C,onCheckedChange:t=>L(!!t),"data-testid":"settings-enable-telegram-bell-push"})]}),e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsx("div",{className:"min-w-0 pr-2",children:e.jsx("div",{className:"text-sm font-medium",children:s("settings.enableBrowserNotificationToast")})}),e.jsx($,{checked:o,onCheckedChange:t=>l(!!t),"data-testid":"settings-enable-browser-notification-toast"})]}),e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsx("div",{className:"min-w-0 pr-2",children:e.jsx("div",{className:"text-sm font-medium",children:s("settings.enableTelegramNotificationPush")})}),e.jsx($,{checked:ye,onCheckedChange:t=>be(!!t),"data-testid":"settings-enable-telegram-notification-push"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-4 sm:grid-cols-3",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"bell-throttle-input",children:s("settings.bellThrottle")}),e.jsx(v,{id:"bell-throttle-input",type:"number",value:c,min:0,max:300,onChange:t=>E(Number(t.target.value)),className:"min-h-10"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"notification-throttle-input",children:s("settings.notificationThrottle")}),e.jsx(v,{id:"notification-throttle-input",type:"number",value:F,min:0,max:300,onChange:t=>i(Number(t.target.value)),className:"min-h-10"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"ssh-reconnect-retries-input",children:s("settings.sshReconnectMaxRetries")}),e.jsx(v,{id:"ssh-reconnect-retries-input",type:"number",value:we,min:0,max:20,onChange:t=>ve(Number(t.target.value)),className:"min-h-10"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"ssh-reconnect-delay-input",children:s("settings.sshReconnectDelay")}),e.jsx(v,{id:"ssh-reconnect-delay-input",type:"number",value:Ne,min:1,max:300,onChange:t=>ke(Number(t.target.value)),className:"min-h-10"})]})]})]})]}),n==="telegram"&&e.jsxs(M,{className:"border-0 ring-0",children:[e.jsx(q,{children:e.jsx(_,{children:s("telegram.title")})}),e.jsxs(R,{className:"space-y-6",children:[e.jsx("div",{className:"space-y-4",children:e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end",children:[e.jsxs("div",{className:"md:col-span-4 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"new-bot-name",children:s("telegram.botName")}),e.jsx(v,{id:"new-bot-name",value:X,onChange:t=>Ce(t.target.value),placeholder:s("telegram.botNamePlaceholder"),className:"min-h-10"})]}),e.jsxs("div",{className:"md:col-span-6 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"new-bot-token",children:s("telegram.botToken")}),e.jsx(v,{id:"new-bot-token",type:"password",value:Y,onChange:t=>Se(t.target.value),placeholder:s("telegram.botTokenPlaceholder"),className:"min-h-10"})]}),e.jsx("div",{className:"md:col-span-2",children:e.jsxs(x,{variant:"default",className:"w-full md:w-auto","data-testid":"telegram-add-bot",onClick:()=>ne.mutate(),disabled:ne.isPending||!X.trim()||!Y.trim(),children:[ne.isPending?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(B,{className:"h-4 w-4"}),s("telegram.addBot")]})})]})}),e.jsxs("div",{className:"space-y-3",children:[ae.isLoading&&e.jsx("div",{className:"text-sm text-muted-foreground",children:s("common.loading")}),!ae.isLoading&&Ke.length===0&&e.jsx("div",{className:"text-sm text-muted-foreground",children:s("telegram.addBot")}),Ke.map(t=>e.jsx(ms,{bot:t,expanded:Je===t.id,onToggleExpand:()=>{We(k=>k===t.id?null:t.id)}},t.id))]})]})]}),n==="webhooks"&&e.jsxs(M,{className:"border-0 ring-0",children:[e.jsx(q,{children:e.jsx(_,{children:s("webhook.title")})}),e.jsxs(R,{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end",children:[e.jsxs("div",{className:"md:col-span-6 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"webhook-url-input",children:s("webhook.url")}),e.jsx(v,{id:"webhook-url-input","data-testid":"webhook-url-input",value:Z,onChange:t=>Ee(t.target.value),placeholder:"https://example.com/webhook",className:"min-h-10"})]}),e.jsxs("div",{className:"md:col-span-4 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"webhook-secret-input",children:s("webhook.secret")}),e.jsx(v,{id:"webhook-secret-input","data-testid":"webhook-secret-input",value:ee,onChange:t=>Pe(t.target.value),placeholder:s("webhook.secretPlaceholder"),className:"min-h-10"})]}),e.jsx("div",{className:"md:col-span-2",children:e.jsxs(x,{variant:"default",className:"w-full md:w-auto","data-testid":"webhook-add",onClick:()=>le.mutate(),disabled:le.isPending||!Z.trim()||!ee.trim()||se.length===0,children:[le.isPending?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(B,{className:"h-4 w-4"}),s("webhook.add")]})})]}),e.jsxs("div",{className:"space-y-3 rounded-lg border border-border bg-card px-4 py-3",children:[e.jsx("div",{className:"text-sm font-medium",children:s("webhook.eventMask")}),e.jsx("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2",children:ce.map(t=>{const k=se.includes(t);return e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-background px-3 py-2",children:[e.jsx("div",{className:"min-w-0 pr-2 text-sm font-medium",children:s(`notification.eventType.${t}`)}),e.jsx($,{checked:k,"data-testid":`webhook-event-${t}`,onCheckedChange:Xe=>{Fe(W=>Xe?W.includes(t)?W:[...W,t]:W.filter(Ye=>Ye!==t))}})]},t)})})]}),e.jsxs("div",{className:"space-y-2",children:[ie.isLoading&&e.jsx("div",{className:"text-sm text-muted-foreground",children:s("common.loading")}),!ie.isLoading&&$e.length===0&&e.jsx("div",{className:"text-sm text-muted-foreground",children:s("webhook.empty")}),$e.map(t=>e.jsxs("div",{"data-testid":"webhook-item","data-webhook-url":t.url,className:"flex items-center justify-between gap-3 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-sm font-medium",children:t.url}),e.jsx("div",{className:"text-xs text-muted-foreground",children:new Date(t.createdAt).toLocaleString(Qe(j))})]}),e.jsx(x,{variant:"ghost",size:"icon-sm","data-testid":"webhook-delete",onClick:()=>Ae.mutate(t.id),disabled:Ae.isPending,"aria-label":s("common.delete"),title:s("common.delete"),children:e.jsx(G,{className:"h-4 w-4"})})]},t.id))]})]})]}),n==="llm"&&e.jsx(ls,{}),n==="search"&&e.jsx(ds,{}),(n==="site"||n==="notifications")&&e.jsx("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end",children:e.jsxs(x,{variant:"default","data-testid":"settings-save",onClick:()=>Te.mutate(),disabled:Te.isPending,className:"w-full sm:w-auto",children:[e.jsx(B,{className:"h-4 w-4"}),s("common.save")]})})]})}function ms({bot:s,expanded:a,onToggleExpand:h}){var o;const{t:n}=A(),d=Q(),[p,w]=r.useState(s.name),[f,u]=r.useState(""),[y,N]=r.useState(s.enabled),[g,j]=r.useState(s.allowAuthRequests);r.useEffect(()=>{w(s.name),N(s.enabled),j(s.allowAuthRequests)},[s.allowAuthRequests,s.enabled,s.name]);const b=I({queryKey:["telegram-bot-chats",s.id],enabled:a,queryFn:async()=>{const l=await fetch(`/api/settings/telegram/bots/${s.id}/chats`);if(!l.ok)throw new Error(await T(l,n("telegram.loadChatsFailed")));return await l.json()}}),c=r.useMemo(()=>{var C;const l=((C=b.data)==null?void 0:C.chats)??[];return{pending:l.filter(L=>L.status==="pending"),authorized:l.filter(L=>L.status==="authorized")}},[(o=b.data)==null?void 0:o.chats]),E=S({mutationFn:async()=>{const l={name:p,enabled:y,allowAuthRequests:g};f.trim()&&(l.token=f.trim());const C=await fetch(`/api/settings/telegram/bots/${s.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)});if(!C.ok)throw new Error(await T(C,n("telegram.updateFailed")))},onSuccess:async()=>{u(""),await d.invalidateQueries({queryKey:["telegram-bots"]}),m.success(n("common.success"))},onError:l=>{m.error(l instanceof Error?l.message:n("common.error"))}}),F=S({mutationFn:async()=>{const l=await fetch(`/api/settings/telegram/bots/${s.id}`,{method:"DELETE"});if(!l.ok)throw new Error(await T(l,n("telegram.deleteFailed")))},onSuccess:async()=>{await d.invalidateQueries({queryKey:["telegram-bots"]}),m.success(n("common.success"))},onError:l=>{m.error(l instanceof Error?l.message:n("common.error"))}}),i=S({mutationFn:async l=>{const C=await fetch(`/api/settings/telegram/bots/${s.id}/chats/${encodeURIComponent(l)}/approve`,{method:"POST"});if(!C.ok)throw new Error(await T(C,n("telegram.approveFailed")))},onSuccess:async()=>{await Promise.all([d.invalidateQueries({queryKey:["telegram-bots"]}),d.invalidateQueries({queryKey:["telegram-bot-chats",s.id]})]),m.success(n("common.success"))},onError:l=>{m.error(l instanceof Error?l.message:n("common.error"))}}),P=S({mutationFn:async l=>{const C=await fetch(`/api/settings/telegram/bots/${s.id}/chats/${encodeURIComponent(l)}`,{method:"DELETE"});if(!C.ok)throw new Error(await T(C,n("telegram.removeFailed")))},onSuccess:async()=>{await Promise.all([d.invalidateQueries({queryKey:["telegram-bots"]}),d.invalidateQueries({queryKey:["telegram-bot-chats",s.id]})]),m.success(n("common.success"))},onError:l=>{m.error(l instanceof Error?l.message:n("common.error"))}}),K=S({mutationFn:async l=>{const C=await fetch(`/api/settings/telegram/bots/${s.id}/chats/${encodeURIComponent(l)}/test`,{method:"POST"});if(!C.ok)throw new Error(await T(C,n("telegram.testMessageFailed")))},onSuccess:()=>{m.success(n("common.success"))},onError:l=>{m.error(l instanceof Error?l.message:n("common.error"))}});return e.jsxs("div",{className:"space-y-4 rounded-md border-0 bg-card p-4","data-testid":`telegram-bot-card-${s.id}`,"data-bot-name":s.name,children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:s.name}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[s.authorizedCount," / ",s.pendingCount]})]}),e.jsx(x,{variant:"ghost","data-testid":`telegram-bot-toggle-${s.id}`,onClick:h,children:n(a?"common.collapse":"common.expand")})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end",children:[e.jsxs("div",{className:"md:col-span-3 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:`bot-name-${s.id}`,children:n("telegram.botName")}),e.jsx(v,{id:`bot-name-${s.id}`,value:p,onChange:l=>w(l.target.value),className:"min-h-10"})]}),e.jsxs("div",{className:"md:col-span-4 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:`bot-token-${s.id}`,children:n("telegram.botToken")}),e.jsx(v,{id:`bot-token-${s.id}`,type:"password",value:f,onChange:l=>u(l.target.value),placeholder:n("telegram.tokenPlaceholder"),className:"min-h-10"})]}),e.jsx("div",{className:"md:col-span-2",children:e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-3 rounded-lg border border-border bg-background px-3 py-2.5",children:[e.jsx("span",{className:"text-sm font-medium",children:n("common.enabled")}),e.jsx($,{checked:y,onCheckedChange:l=>N(!!l)})]})}),e.jsx("div",{className:"md:col-span-3",children:e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-3 rounded-lg border border-border bg-background px-3 py-2.5",children:[e.jsx("span",{className:"text-sm font-medium",children:n("telegram.allowAuthRequests")}),e.jsx($,{checked:g,onCheckedChange:l=>j(!!l)})]})})]}),e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end",children:[e.jsxs(x,{variant:"destructive","data-testid":`telegram-bot-delete-${s.id}`,onClick:()=>F.mutate(),className:"w-full sm:w-auto",children:[e.jsx(G,{className:"h-4 w-4"}),n("telegram.deleteBot")]}),e.jsxs(x,{variant:"default","data-testid":`telegram-bot-save-${s.id}`,onClick:()=>E.mutate(),className:"w-full sm:w-auto",children:[e.jsx(B,{className:"h-4 w-4"}),n("common.save")]})]}),a&&e.jsxs("div",{className:"grid grid-cols-1 gap-4 border-t border-border pt-4 lg:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("h3",{className:"text-sm font-semibold flex items-center gap-1",children:[e.jsx(Oe,{className:"h-4 w-4"}),n("telegram.pendingChats")]}),c.pending.length===0&&e.jsx("div",{className:"text-xs text-muted-foreground",children:"-"}),c.pending.map(l=>e.jsx(Le,{chat:l,pending:!0,onApprove:()=>i.mutate(l.chatId),onDelete:()=>P.mutate(l.chatId)},`${l.botId}-${l.chatId}`))]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("h3",{className:"text-sm font-semibold flex items-center gap-1",children:[e.jsx(Oe,{className:"h-4 w-4"}),n("telegram.chats")]}),c.authorized.length===0&&e.jsx("div",{className:"text-xs text-muted-foreground",children:"-"}),c.authorized.map(l=>e.jsx(Le,{chat:l,pending:!1,onTest:()=>K.mutate(l.chatId),onDelete:()=>P.mutate(l.chatId)},`${l.botId}-${l.chatId}`))]}),b.isLoading&&e.jsx("div",{className:"lg:col-span-2 text-xs text-muted-foreground",children:n("common.loading")})]})]})}function Le({chat:s,pending:a,onApprove:h,onDelete:n,onTest:d}){const{t:p}=A(),w=Ue(f=>{var u;return((u=f.settings)==null?void 0:u.language)??"en_US"});return e.jsxs("div",{className:"space-y-2 rounded border-0 bg-background p-3",children:[e.jsx("div",{className:"text-sm font-medium truncate",title:s.displayName,children:s.displayName}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[p("telegram.chatId"),":",s.chatId]}),e.jsx("div",{className:"text-xs text-muted-foreground",children:new Date(s.appliedAt).toLocaleString(Qe(w))}),e.jsx("div",{className:"flex items-center justify-end gap-2 pt-1",children:a?e.jsxs(e.Fragment,{children:[e.jsx(x,{variant:"outline",size:"sm",onClick:n,children:p("telegram.reject")}),e.jsx(x,{variant:"default",size:"sm",onClick:h,children:p("telegram.authorize")})]}):e.jsxs(e.Fragment,{children:[e.jsxs(x,{variant:"secondary",size:"sm",onClick:d,children:[e.jsx(ss,{className:"h-3.5 w-3.5"}),p("telegram.sendTestMessage")]}),e.jsx(x,{variant:"destructive",size:"sm",onClick:n,children:p("common.delete")})]})})]})}function fs(){const{t:s}=A();return e.jsx(e.Fragment,{children:s("sidebar.settings")})}function js(){const{t:s}=A(),[a,h]=r.useState(!1),n=S({mutationFn:async()=>{const d=await fetch("/api/settings/restart",{method:"POST"});if(!d.ok)throw new Error(await T(d,s("settings.restartFailed")))},onSuccess:()=>{m.success(s("settings.restartScheduled"))},onError:d=>{m.error(d instanceof Error?d.message:s("common.error"))}});return e.jsxs(e.Fragment,{children:[e.jsx(x,{variant:"ghost",size:"icon-sm",onClick:()=>h(!0),disabled:n.isPending,"aria-label":s("settings.restartGateway"),title:s("settings.restartGateway"),className:"text-destructive hover:text-destructive hover:bg-destructive/10",children:e.jsx(as,{className:"h-4 w-4"})}),e.jsx(me,{open:a,onOpenChange:h,children:e.jsxs(he,{children:[e.jsxs(ue,{children:[e.jsx(ge,{children:s("settings.restartGateway")}),e.jsx(xe,{children:s("settings.restartConfirm")})]}),e.jsxs(pe,{children:[e.jsx(fe,{onClick:()=>h(!1),children:s("common.cancel")}),e.jsx(je,{variant:"destructive",onClick:()=>{n.mutate(),h(!1)},children:s("common.confirm")})]})]})})]})}export{js as PageActions,fs as PageTitle,ps as default};
17
+ //# sourceMappingURL=SettingsPage-D2jiLXqU.js.map
@@ -0,0 +1,2 @@
1
+ import{v as r,x as d}from"./index-BhWcb9L_.js";function o({className:a,size:t="default",...s}){return r.jsx("div",{"data-slot":"card","data-size":t,className:d("ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-xl py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col",a),...s})}function i({className:a,...t}){return r.jsx("div",{"data-slot":"card-header",className:d("gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]",a),...t})}function c({className:a,...t}){return r.jsx("div",{"data-slot":"card-title",className:d("text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",a),...t})}function n({className:a,...t}){return r.jsx("div",{"data-slot":"card-description",className:d("text-muted-foreground text-sm",a),...t})}function u({className:a,...t}){return r.jsx("div",{"data-slot":"card-content",className:d("px-4 group-data-[size=sm]/card:px-3",a),...t})}export{o as C,i as a,c as b,u as c,n as d};
2
+ //# sourceMappingURL=card-BHK15lCp.js.map