tmex-cli 0.16.1 → 0.16.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/CHANGELOG.md +10 -60
  2. package/dist/runtime/server.js +972 -330
  3. package/package.json +1 -1
  4. package/resources/fe-dist/assets/DevicePage-DtByPprm.js +24 -0
  5. package/resources/fe-dist/assets/{DevicesPage-sJHXbS_f.js → DevicesPage-WMW0FcaU.js} +1 -1
  6. package/resources/fe-dist/assets/{FilePage-7FFd1YcW.js → FilePage-C3yjgRDh.js} +1 -1
  7. package/resources/fe-dist/assets/SettingsPage-CKZEPwEq.js +39 -0
  8. package/resources/fe-dist/assets/agent-tab-B77EotmX.js +38 -0
  9. package/resources/fe-dist/assets/{api-DV7-9Pvt.js → api-DZDjPn8l.js} +1 -1
  10. package/resources/fe-dist/assets/{arc-PDHKfnGP.js → arc-DNrUdLWP.js} +1 -1
  11. package/resources/fe-dist/assets/{architectureDiagram-3BPJPVTR-BiPHTh1e.js → architectureDiagram-3BPJPVTR-B5DYf-5o.js} +1 -1
  12. package/resources/fe-dist/assets/{blockDiagram-GPEHLZMM-DP_BRHKg.js → blockDiagram-GPEHLZMM-DSgjcUbw.js} +1 -1
  13. package/resources/fe-dist/assets/{c4Diagram-AAUBKEIU-D16QYgyT.js → c4Diagram-AAUBKEIU-DKjqulHT.js} +1 -1
  14. package/resources/fe-dist/assets/{card-DmfNw0hd.js → card-DWQzPt-3.js} +1 -1
  15. package/resources/fe-dist/assets/channel-CpZANba-.js +1 -0
  16. package/resources/fe-dist/assets/{chunk-2J33WTMH-DOjtL7ww.js → chunk-2J33WTMH-DHQ_-AlN.js} +1 -1
  17. package/resources/fe-dist/assets/{chunk-4BX2VUAB-BbT67ZXa.js → chunk-4BX2VUAB-C7sszhBq.js} +1 -1
  18. package/resources/fe-dist/assets/{chunk-55IACEB6-CnnXwmY_.js → chunk-55IACEB6-BkPT2okv.js} +1 -1
  19. package/resources/fe-dist/assets/{chunk-727SXJPM-TyUdLEW5.js → chunk-727SXJPM-BsD5c54G.js} +1 -1
  20. package/resources/fe-dist/assets/{chunk-AQP2D5EJ-BMpK4dqa.js → chunk-AQP2D5EJ-Dx3mc4xO.js} +1 -1
  21. package/resources/fe-dist/assets/{chunk-FMBD7UC4-Dx0HVCZZ.js → chunk-FMBD7UC4-CyZO-UAp.js} +1 -1
  22. package/resources/fe-dist/assets/{chunk-ND2GUHAM-BQCoMEti.js → chunk-ND2GUHAM-DNxRBeA7.js} +1 -1
  23. package/resources/fe-dist/assets/{chunk-QZHKN3VN-ilmf5OgK.js → chunk-QZHKN3VN-DsPa138W.js} +1 -1
  24. package/resources/fe-dist/assets/classDiagram-4FO5ZUOK-BW09ep_0.js +1 -0
  25. package/resources/fe-dist/assets/classDiagram-v2-Q7XG4LA2-BW09ep_0.js +1 -0
  26. package/resources/fe-dist/assets/{copy-Ct5TNzGp.js → copy-DwXKDgGT.js} +1 -1
  27. package/resources/fe-dist/assets/{cose-bilkent-S5V4N54A-CpWhM7Za.js → cose-bilkent-S5V4N54A-C1d180_v.js} +1 -1
  28. package/resources/fe-dist/assets/{dagre-BM42HDAG-CWJttTzC.js → dagre-BM42HDAG-Bv8hvnH7.js} +1 -1
  29. package/resources/fe-dist/assets/{diagram-2AECGRRQ-BD8ny_Yg.js → diagram-2AECGRRQ-DfbJBHI6.js} +1 -1
  30. package/resources/fe-dist/assets/{diagram-5GNKFQAL-CeHcPWRz.js → diagram-5GNKFQAL-COnOrAiu.js} +1 -1
  31. package/resources/fe-dist/assets/{diagram-KO2AKTUF-tVlrBE8C.js → diagram-KO2AKTUF-BOtU5EdV.js} +1 -1
  32. package/resources/fe-dist/assets/{diagram-LMA3HP47-DGUn-oQn.js → diagram-LMA3HP47-B-WcT-Mc.js} +1 -1
  33. package/resources/fe-dist/assets/{diagram-OG6HWLK6-xKCd1kwA.js → diagram-OG6HWLK6-BptGbu0F.js} +1 -1
  34. package/resources/fe-dist/assets/en_US-BihUhDmr.js +1 -0
  35. package/resources/fe-dist/assets/{erDiagram-TEJ5UH35-C6M5qkGl.js → erDiagram-TEJ5UH35-H06uoCHU.js} +1 -1
  36. package/resources/fe-dist/assets/{files-tab-BWkYfaye.js → files-tab-C841Mmn_.js} +1 -1
  37. package/resources/fe-dist/assets/{flowDiagram-I6XJVG4X-D0MZDHnB.js → flowDiagram-I6XJVG4X-QOk_IVWN.js} +1 -1
  38. package/resources/fe-dist/assets/{ganttDiagram-6RSMTGT7-YeduSSa_.js → ganttDiagram-6RSMTGT7-Q7s2jHyi.js} +1 -1
  39. package/resources/fe-dist/assets/{gitGraphDiagram-PVQCEYII-Nem1Mvvg.js → gitGraphDiagram-PVQCEYII-Q7tAtx1u.js} +1 -1
  40. package/resources/fe-dist/assets/{index-iee3U_rD.js → index-C2v9tHtI.js} +1 -1
  41. package/resources/fe-dist/assets/{index-B3ddLSja.js → index-Dc3Fwpho.js} +63 -63
  42. package/resources/fe-dist/assets/index-j9kTGUS5.css +1 -0
  43. package/resources/fe-dist/assets/{infoDiagram-5YYISTIA-Bh6bbh_V.js → infoDiagram-5YYISTIA-B9n7MrtF.js} +1 -1
  44. package/resources/fe-dist/assets/{ishikawaDiagram-YF4QCWOH-CsZHu48j.js → ishikawaDiagram-YF4QCWOH-oZeau8IS.js} +1 -1
  45. package/resources/fe-dist/assets/ja_JP-f5sXmz8W.js +1 -0
  46. package/resources/fe-dist/assets/{journeyDiagram-JHISSGLW-CPgnovXt.js → journeyDiagram-JHISSGLW-ClXjUmc1.js} +1 -1
  47. package/resources/fe-dist/assets/{kanban-definition-UN3LZRKU-D4OAuDsS.js → kanban-definition-UN3LZRKU-Cwn4VzH2.js} +1 -1
  48. package/resources/fe-dist/assets/{linear-CcA4wV7f.js → linear-BNOQBDiB.js} +1 -1
  49. package/resources/fe-dist/assets/{markdown-preview-CBGlxpTs.js → markdown-preview-BsYVAcJ1.js} +3 -3
  50. package/resources/fe-dist/assets/{mermaid.core-D-CshtYr.js → mermaid.core-C3nmuA6R.js} +5 -5
  51. package/resources/fe-dist/assets/{mindmap-definition-RKZ34NQL-DBpI1nMC.js → mindmap-definition-RKZ34NQL-BKstxajf.js} +1 -1
  52. package/resources/fe-dist/assets/{pieDiagram-4H26LBE5-D4kh0_Y0.js → pieDiagram-4H26LBE5-D_2bHoC9.js} +1 -1
  53. package/resources/fe-dist/assets/{quadrantDiagram-W4KKPZXB-DNw3oGHQ.js → quadrantDiagram-W4KKPZXB-D6K_QmUy.js} +1 -1
  54. package/resources/fe-dist/assets/{requirementDiagram-4Y6WPE33-DqtMaND0.js → requirementDiagram-4Y6WPE33-B1SWUDkA.js} +1 -1
  55. package/resources/fe-dist/assets/{sankeyDiagram-5OEKKPKP-D-m9Pyie.js → sankeyDiagram-5OEKKPKP-DPmalO0b.js} +1 -1
  56. package/resources/fe-dist/assets/{send-DaOB9hLq.js → send-J45szXFM.js} +1 -1
  57. package/resources/fe-dist/assets/{sequenceDiagram-3UESZ5HK-CjrimNJf.js → sequenceDiagram-3UESZ5HK-C08DcZug.js} +1 -1
  58. package/resources/fe-dist/assets/{stateDiagram-AJRCARHV-BT5d8Z8W.js → stateDiagram-AJRCARHV-K9bVAVhg.js} +1 -1
  59. package/resources/fe-dist/assets/stateDiagram-v2-BHNVJYJU-DTGkSC6X.js +1 -0
  60. package/resources/fe-dist/assets/{terminal-settings-panel-DDhlnbRH.js → terminal-settings-panel-tZuaqdqz.js} +2 -2
  61. package/resources/fe-dist/assets/{timeline-definition-PNZ67QCA-BeocAFDX.js → timeline-definition-PNZ67QCA-DG0FtOvK.js} +1 -1
  62. package/resources/fe-dist/assets/{transfer-toast-DXl4RHsV.js → transfer-toast-D72q4082.js} +1 -1
  63. package/resources/fe-dist/assets/{triangle-alert-FQRTtbTP.js → triangle-alert-CagsqsWp.js} +1 -1
  64. package/resources/fe-dist/assets/{vennDiagram-CIIHVFJN-CYlmUB5_.js → vennDiagram-CIIHVFJN-CKBEKUkA.js} +1 -1
  65. package/resources/fe-dist/assets/{wardley-L42UT6IY-CTyaodt9.js → wardley-L42UT6IY-DTlpnptg.js} +1 -1
  66. package/resources/fe-dist/assets/{wardleyDiagram-YWT4CUSO-DNlEcEwQ.js → wardleyDiagram-YWT4CUSO-CnwEikRb.js} +1 -1
  67. package/resources/fe-dist/assets/{xychartDiagram-2RQKCTM6-7Zi-6P-I.js → xychartDiagram-2RQKCTM6-uaYRX4Ue.js} +1 -1
  68. package/resources/fe-dist/assets/{zap-BFIAXPXd.js → zap-DcJ8Gp1I.js} +1 -1
  69. package/resources/fe-dist/assets/zh_CN-CPdvelFW.js +1 -0
  70. package/resources/fe-dist/index.html +2 -2
  71. package/resources/gateway-drizzle/0012_naive_lizard.sql +8 -0
  72. package/resources/gateway-drizzle/0013_bored_blindfold.sql +1 -0
  73. package/resources/gateway-drizzle/0014_lucky_killraven.sql +1 -0
  74. package/resources/gateway-drizzle/meta/_journal.json +21 -0
  75. package/resources/fe-dist/assets/DevicePage-Ccz8gNji.js +0 -24
  76. package/resources/fe-dist/assets/SettingsPage-FrEtqZyI.js +0 -39
  77. package/resources/fe-dist/assets/agent-tab-9THUj7Cf.js +0 -38
  78. package/resources/fe-dist/assets/channel-Dzz9b4fW.js +0 -1
  79. package/resources/fe-dist/assets/classDiagram-4FO5ZUOK-BB9_4XLL.js +0 -1
  80. package/resources/fe-dist/assets/classDiagram-v2-Q7XG4LA2-BB9_4XLL.js +0 -1
  81. package/resources/fe-dist/assets/en_US-CjVU4anP.js +0 -1
  82. package/resources/fe-dist/assets/index-CuFTSN9i.css +0 -1
  83. package/resources/fe-dist/assets/ja_JP-Bq-BwOH_.js +0 -1
  84. package/resources/fe-dist/assets/stateDiagram-v2-BHNVJYJU-kSh9IuUW.js +0 -1
  85. package/resources/fe-dist/assets/zh_CN-BuxyXhCT.js +0 -1
@@ -1,39 +0,0 @@
1
- import{Y as ce,u as F,j as e,L as It,M as Ze,z as Lt,r as w,c as Q,B as k,P as ge,a as O,e as M,o as b,a2 as D,v as De,T as te,A as xe,f as fe,g as pe,h as $t,i as we,k as ye,l as je,m as ve,n as be,C as ae,F as ne,H as ie,I as re,J as Ne,N as Ce,O as Ee,Q as ke,R as Se,U as le,K as B,W as de,aq as U,G as Bt,x as xt,at as Dt,b as Oe,t as et,bs as $,X as ft,af as nt,bt as Ot,bu as _t,aB as zt,bv as qt,bw as Kt,bx as Qt,by as Ut,bz as it,Z as Ht}from"./index-B3ddLSja.js";import{C as H,b as G,c as J,d as pt,a as V}from"./card-DmfNw0hd.js";import{e as Vt,h as wt,F as We,i as Wt,j as Gt,D as Jt}from"./api-DV7-9Pvt.js";import{R as tt,T as Yt,b as Xt,d as Zt}from"./terminal-settings-panel-DDhlnbRH.js";import{S as yt}from"./send-DaOB9hLq.js";import{M as es}from"./markdown-preview-CBGlxpTs.js";import{T as jt}from"./triangle-alert-FQRTtbTP.js";import"./selection-clipboard-D3gUQQ7L.js";import"./index-iee3U_rD.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:"M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z",key:"lc1i9w"}],["path",{d:"m7 16.5-4.74-2.85",key:"1o9zyk"}],["path",{d:"m7 16.5 5-3",key:"va8pkn"}],["path",{d:"M7 16.5v5.17",key:"jnp8gn"}],["path",{d:"M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z",key:"8zsnat"}],["path",{d:"m17 16.5-5-3",key:"8arw3v"}],["path",{d:"m17 16.5 4.74-2.85",key:"8rfmw"}],["path",{d:"M17 16.5v5.17",key:"k6z78m"}],["path",{d:"M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z",key:"1xygjf"}],["path",{d:"M12 8 7.26 5.15",key:"1vbdud"}],["path",{d:"m12 8 4.74-2.85",key:"3rx089"}],["path",{d:"M12 13.5V8",key:"1io7kd"}]],ss=ce("boxes",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 as=[["rect",{width:"5",height:"5",x:"3",y:"3",rx:"1",key:"1tu5fj"}],["rect",{width:"5",height:"5",x:"16",y:"3",rx:"1",key:"1v8r4q"}],["rect",{width:"5",height:"5",x:"3",y:"16",rx:"1",key:"1x03jg"}],["path",{d:"M21 16h-3a2 2 0 0 0-2 2v3",key:"177gqh"}],["path",{d:"M21 21v.01",key:"ents32"}],["path",{d:"M12 7v3a2 2 0 0 1-2 2H7",key:"8crl2c"}],["path",{d:"M3 12h.01",key:"nlz23k"}],["path",{d:"M12 3h.01",key:"n36tog"}],["path",{d:"M12 16v.01",key:"133mhm"}],["path",{d:"M16 12h1",key:"1slzba"}],["path",{d:"M21 12v.01",key:"1lwtk9"}],["path",{d:"M12 21v-1",key:"1880an"}]],Ge=ce("qr-code",as);/**
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 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"}]],Z=ce("save",ns);/**
17
- * @license lucide-react v0.564.0 - ISC
18
- *
19
- * This source code is licensed under the ISC license.
20
- * See the LICENSE file in the root directory of this source tree.
21
- */const is=[["rect",{width:"20",height:"8",x:"2",y:"2",rx:"2",ry:"2",key:"ngkwjq"}],["rect",{width:"20",height:"8",x:"2",y:"14",rx:"2",ry:"2",key:"iecqi9"}],["line",{x1:"6",x2:"6.01",y1:"6",y2:"6",key:"16zg32"}],["line",{x1:"6",x2:"6.01",y1:"18",y2:"18",key:"nzw8ys"}]],rs=ce("server",is);/**
22
- * @license lucide-react v0.564.0 - ISC
23
- *
24
- * This source code is licensed under the ISC license.
25
- * See the LICENSE file in the root directory of this source tree.
26
- */const os=[["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"}]],rt=ce("shield",os);/**
27
- * @license lucide-react v0.564.0 - ISC
28
- *
29
- * This source code is licensed under the ISC license.
30
- * See the LICENSE file in the root directory of this source tree.
31
- */const ls=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744",key:"16gr8j"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}]],cs=ce("users",ls);function ds(){const{t}=F();return e.jsxs(H,{className:"border-0 ring-0",children:[e.jsxs(G,{children:[e.jsx(J,{children:t("settings.deviceManagement.title")}),e.jsx(pt,{children:t("settings.deviceManagement.description")})]}),e.jsx(V,{children:e.jsxs(It,{to:"/devices","data-testid":"settings-device-management-link",className:Lt({variant:"secondary"}),children:[e.jsx(Ze,{className:"h-4 w-4"}),t("settings.deviceManagement.openButton")]})})]})}function $e({type:t,className:o}){return t==="ssh"?e.jsx(Bt,{className:o}):e.jsx(Ze,{className:o})}function ms(){var r,m;const{t}=F(),[o,s]=w.useState(!1),[l,c]=w.useState(void 0),h=Q({queryKey:["files","roots"],queryFn:Vt}),p=Q({queryKey:["devices"],queryFn:async()=>{const d=await fetch("/api/devices");if(!d.ok)throw new Error(`HTTP ${d.status}`);return await d.json()},throwOnError:!1}),f=((r=h.data)==null?void 0:r.roots)??[],a=((m=p.data)==null?void 0:m.devices)??[],n=()=>{c(void 0),s(!0)},i=d=>{c(d),s(!0)};return e.jsxs(e.Fragment,{children:[e.jsxs(H,{className:"border-0 ring-0","data-testid":"settings-files-section",children:[e.jsxs(G,{className:"flex flex-row items-center justify-between gap-2",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(J,{children:t("settings.files.title")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:t("settings.files.description")})]}),e.jsxs(k,{variant:"secondary","data-testid":"settings-files-root-add",onClick:n,children:[e.jsx(ge,{className:"h-4 w-4"}),t("settings.files.addRoot")]})]}),e.jsxs(V,{className:"space-y-3",children:[h.isLoading&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("common.loading")}),!h.isLoading&&f.length===0&&e.jsx("div",{className:"text-sm text-muted-foreground","data-testid":"settings-files-empty",children:t("settings.files.empty")}),f.map(d=>e.jsx(us,{root:d,onEdit:i},d.id))]})]}),e.jsx(hs,{open:o,onOpenChange:s,root:l,devices:a})]})}function us({root:t,onEdit:o}){const{t:s}=F(),l=O(),[c,h]=w.useState(!1),p=M({mutationFn:({id:a,enabled:n})=>wt(a,{enabled:n}),onSuccess:async()=>{await l.invalidateQueries({queryKey:["files"]})},onError:()=>{b.error(s("settings.files.toggleFailed"))}}),f=M({mutationFn:a=>Wt(a),onSuccess:async()=>{await l.invalidateQueries({queryKey:["files"]}),b.success(s("common.success"))},onError:a=>{const n=a instanceof We?a.message:s("settings.files.deleteFailed");b.error(n)}});return e.jsxs("div",{className:"flex items-center gap-3 rounded-lg border border-border p-3","data-testid":`settings-files-root-${t.id}`,children:[e.jsx(D,{checked:t.enabled,disabled:p.isPending,onCheckedChange:a=>p.mutate({id:t.id,enabled:!!a}),"data-testid":`settings-files-root-enabled-${t.id}`}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-xs text-muted-foreground",children:[e.jsx($e,{type:t.deviceType,className:"h-3.5 w-3.5 shrink-0"}),t.deviceName===null?e.jsx("span",{className:"text-destructive",children:s("settings.files.missing")}):e.jsx("span",{className:"truncate",children:t.deviceName})]}),e.jsx("div",{className:"truncate font-mono text-xs",children:t.path}),e.jsx("div",{className:"truncate text-xs text-muted-foreground",children:t.name})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1",children:[e.jsx(k,{variant:"ghost",size:"icon-sm",title:s("common.edit"),"data-testid":`settings-files-root-edit-${t.id}`,onClick:()=>o(t),children:e.jsx(De,{className:"h-4 w-4"})}),e.jsx(k,{variant:"ghost",size:"icon-sm",title:s("common.delete"),"data-testid":`settings-files-root-delete-${t.id}`,onClick:()=>h(!0),disabled:f.isPending,children:e.jsx(te,{className:"h-4 w-4 text-destructive"})})]}),e.jsx(xe,{open:c,onOpenChange:h,children:e.jsxs(fe,{children:[e.jsxs(pe,{children:[e.jsx($t,{className:"bg-destructive/10",children:e.jsx(te,{className:"h-5 w-5 text-destructive"})}),e.jsx(we,{children:s("settings.files.deleteTitle")}),e.jsx(ye,{children:s("settings.files.deleteDesc",{path:t.path})})]}),e.jsxs(je,{children:[e.jsx(ve,{children:s("common.cancel")}),e.jsx(be,{variant:"destructive","data-testid":`settings-files-root-delete-confirm-${t.id}`,onClick:()=>{f.mutate(t.id),h(!1)},children:s("common.delete")})]})]})})]})}const ot="h-9 w-full";function hs({open:t,onOpenChange:o,root:s,devices:l}){const{t:c}=F(),h=O(),p=!!s,[f,a]=w.useState(""),[n,i]=w.useState(""),[r,m]=w.useState(!0);w.useEffect(()=>{t&&(a((s==null?void 0:s.deviceId)??""),i((s==null?void 0:s.path)??""),m((s==null?void 0:s.enabled)??!0))},[t,s]);const d=M({mutationFn:()=>{const E={deviceId:f,path:n.trim(),enabled:r};return Gt(E)},onSuccess:async()=>{await h.invalidateQueries({queryKey:["files"]}),b.success(c("common.success")),o(!1)},onError:E=>{const z=E instanceof We?E.message:c("settings.files.addFailed");b.error(z)}}),u=M({mutationFn:()=>{if(!s)throw new Error(c("settings.files.updateFailed"));const E={path:n.trim(),enabled:r};return wt(s.id,E)},onSuccess:async()=>{await h.invalidateQueries({queryKey:["files"]}),b.success(c("common.success")),o(!1)},onError:E=>{const z=E instanceof We?E.message:c("settings.files.updateFailed");b.error(z)}}),y=d.isPending||u.isPending,C=n.trim().startsWith("/")&&(p||f.length>0),x=()=>{!C||y||(p?u.mutate():d.mutate())},N=l.find(E=>E.id===f);return e.jsx(ae,{open:t,onOpenChange:o,children:e.jsxs(ne,{className:"sm:max-w-lg","data-testid":p?`settings-files-edit-modal-${s==null?void 0:s.id}`:"settings-files-add-modal",children:[e.jsxs(ie,{children:[e.jsx(re,{children:c(p?"settings.files.modalEditTitle":"settings.files.modalAddTitle")}),e.jsx(Ne,{children:c("settings.files.description")})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"files-form-device",children:c("settings.files.device")}),p?e.jsxs("div",{className:"flex h-9 items-center gap-1.5 rounded-lg border border-input bg-muted/30 px-2.5 text-sm",children:[e.jsx($e,{type:(s==null?void 0:s.deviceType)??null,className:"h-4 w-4 shrink-0"}),e.jsx("span",{className:"truncate",children:(s==null?void 0:s.deviceName)??c("settings.files.missing")})]}):e.jsxs(Ce,{value:f,onValueChange:E=>{E&&a(E)},children:[e.jsx(Ee,{id:"files-form-device","data-testid":"settings-files-device-select",className:ot,disabled:l.length===0,children:e.jsx(ke,{children:N?e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx($e,{type:N.type,className:"h-4 w-4 shrink-0"}),N.name]}):e.jsx("span",{className:"text-muted-foreground",children:c("settings.files.devicePlaceholder")})})}),e.jsx(Se,{children:l.map(E=>e.jsxs(le,{value:E.id,children:[e.jsx($e,{type:E.type,className:"h-4 w-4 shrink-0"}),E.name]},E.id))})]}),!p&&l.length===0&&e.jsx("p",{className:"text-xs text-destructive",children:c("settings.files.noDevices")})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"files-form-path",children:c("settings.files.path")}),e.jsx(B,{id:"files-form-path","data-testid":"settings-files-path-input",value:n,onChange:E=>i(E.target.value),placeholder:c("settings.files.pathPlaceholder"),className:`${ot} font-mono`}),e.jsx("p",{className:"text-xs text-muted-foreground",children:c("settings.files.pathHint")})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(D,{checked:r,onCheckedChange:E=>m(!!E),"data-testid":"settings-files-enabled-switch"}),e.jsx("label",{className:"text-sm font-medium",htmlFor:"settings-files-enabled-switch",children:c("settings.files.enabled")})]})]}),e.jsxs(de,{children:[e.jsx(k,{variant:"outline",onClick:()=>o(!1),disabled:y,children:c("common.cancel")}),e.jsxs(k,{variant:"secondary","data-testid":"settings-files-form-submit",onClick:x,disabled:!C||y,children:[y?e.jsx(U,{className:"h-4 w-4 animate-spin"}):e.jsx(Z,{className:"h-4 w-4"}),c("common.save")]})]})]})})}async function X(t,o){try{return(await t.json()).error??o}catch{return o}}const gs=["openai-chat","openai-responses"],Re="h-9 w-full";function xs({open:t,onOpenChange:o,provider:s}){const{t:l}=F(),c=O(),h=!!s,[p,f]=w.useState(""),[a,n]=w.useState(""),[i,r]=w.useState("openai-chat"),[m,d]=w.useState("");w.useEffect(()=>{t&&(f((s==null?void 0:s.name)??""),n((s==null?void 0:s.baseUrl)??""),r((s==null?void 0:s.protocol)??"openai-chat"),d(""))},[t,s]);const u=M({mutationFn:async()=>{const x={name:p.trim(),protocol:i,baseUrl:a.trim(),apiKey:m.trim(),enabled:!0},N=await fetch("/api/llm/providers",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(x)});if(!N.ok)throw new Error(await X(N,l("settings.llm.createFailed")));return await N.json()},onSuccess:async x=>{await c.invalidateQueries({queryKey:["llm-providers"]}),x.modelsError?b.warning(l("settings.llm.modelsFetchFailed",{error:x.modelsError})):b.success(l("common.success")),o(!1)},onError:x=>{b.error(x instanceof Error?x.message:l("common.error"))}}),y=M({mutationFn:async()=>{if(!s)throw new Error(l("settings.llm.updateFailed"));const x={name:p.trim(),baseUrl:a.trim(),protocol:i};m.trim()&&(x.apiKey=m.trim());const N=await fetch(`/api/llm/providers/${s.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(x)});if(!N.ok)throw new Error(await X(N,l("settings.llm.updateFailed")));return await N.json()},onSuccess:async x=>{await c.invalidateQueries({queryKey:["llm-providers"]}),x.modelsError?b.warning(l("settings.llm.modelsFetchFailed",{error:x.modelsError})):b.success(l("common.success")),o(!1)},onError:x=>{b.error(x instanceof Error?x.message:l("common.error"))}}),j=u.isPending||y.isPending,g=p.trim().length>0&&a.trim().length>0&&(h||m.trim().length>0),C=()=>{!g||j||(h?y.mutate():u.mutate())};return e.jsx(ae,{open:t,onOpenChange:o,children:e.jsxs(ne,{className:"sm:max-w-lg","data-testid":h?`llm-provider-edit-modal-${s==null?void 0:s.id}`:"llm-provider-add-modal",children:[e.jsxs(ie,{children:[e.jsx(re,{children:l(h?"settings.llm.editProvider":"settings.llm.addProvider")}),e.jsx(Ne,{children:l("settings.llm.formHint")})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"llm-form-name",children:l("settings.llm.name")}),e.jsx(B,{id:"llm-form-name","data-testid":"llm-provider-name-input",value:p,onChange:x=>f(x.target.value),placeholder:l("settings.llm.namePlaceholder"),className:Re})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"llm-form-baseurl",children:l("settings.llm.baseUrl")}),e.jsx(B,{id:"llm-form-baseurl","data-testid":"llm-provider-baseurl-input",value:a,onChange:x=>n(x.target.value),placeholder:l("settings.llm.baseUrlPlaceholder"),className:Re}),e.jsx("p",{className:"text-xs text-muted-foreground",children:l("settings.llm.baseUrlHint")})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"llm-form-protocol",children:l("settings.llm.protocol")}),e.jsxs(Ce,{value:i,onValueChange:x=>{x&&r(x)},children:[e.jsx(Ee,{id:"llm-form-protocol","data-testid":"llm-provider-protocol-select",className:Re,children:e.jsx(ke,{})}),e.jsx(Se,{children:gs.map(x=>e.jsx(le,{value:x,children:x},x))})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"llm-form-apikey",children:l("settings.llm.apiKey")}),e.jsx(B,{id:"llm-form-apikey","data-testid":"llm-provider-apikey-input","data-key-set":s!=null&&s.hasApiKey?"true":"false",type:"password",value:m,onChange:x=>d(x.target.value),placeholder:s!=null&&s.hasApiKey?l("settings.llm.apiKeySetPlaceholder"):l("settings.llm.apiKeyPlaceholder"),className:Re})]})]}),e.jsxs(de,{children:[e.jsx(k,{variant:"outline",onClick:()=>o(!1),disabled:j,children:l("common.cancel")}),e.jsxs(k,{variant:"secondary","data-testid":"llm-provider-form-submit",onClick:C,disabled:!g||j,children:[j?e.jsx(U,{className:"h-4 w-4 animate-spin"}):e.jsx(Z,{className:"h-4 w-4"}),l("common.save")]})]})]})})}function fs({models:t,onChange:o}){const{t:s}=F(),[l,c]=w.useState(""),h=(a,n)=>{o(t.map(i=>i.id===a?{...i,enabled:n}:i))},p=a=>{o(t.filter(n=>n.id!==a))},f=()=>{const a=l.trim();if(a){if(t.some(n=>n.id===a)){c("");return}o([...t,{id:a,source:"manual",enabled:!0}]),c("")}};return e.jsxs("div",{className:"space-y-3","data-testid":"llm-provider-models",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(B,{value:l,onChange:a=>c(a.target.value),onKeyDown:a=>{a.key==="Enter"&&(a.preventDefault(),f())},placeholder:s("settings.llm.addModelPlaceholder"),className:"h-9","data-testid":"llm-provider-add-model-input"}),e.jsxs(k,{type:"button",variant:"outline",size:"lg",onClick:f,disabled:!l.trim(),"data-testid":"llm-provider-add-model",children:[e.jsx(ge,{className:"h-4 w-4"}),s("common.add")]})]}),t.length===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:s("settings.llm.modelsNotFetched")}):e.jsx("ul",{className:"max-h-56 space-y-1 overflow-y-auto rounded-lg border border-border bg-background p-2",children:t.map(a=>e.jsxs("li",{className:"flex items-center justify-between gap-2 rounded-md px-2 py-1.5","data-testid":`llm-provider-model-${a.id}`,children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsx(D,{checked:a.enabled,onCheckedChange:n=>h(a.id,!!n),"data-testid":`llm-provider-model-toggle-${a.id}`}),e.jsx("span",{className:"truncate font-mono text-xs",children:a.id}),a.source==="manual"&&e.jsx(xt,{variant:"secondary",children:s("settings.llm.modelManual")})]}),a.source==="manual"&&e.jsx(k,{type:"button",variant:"ghost",size:"icon-sm",onClick:()=>p(a.id),"data-testid":`llm-provider-model-remove-${a.id}`,children:e.jsx(Dt,{className:"h-4 w-4"})})]},a.id))})]})}function ps(t){return t.modelDetails.map(o=>({id:o.id,source:o.source,enabled:o.enabled}))}function ws({open:t,onOpenChange:o,provider:s}){const{t:l}=F(),c=O(),[h,p]=w.useState([]);w.useEffect(()=>{t&&p(ps(s))},[t,s]);const f=M({mutationFn:async()=>{const a=h.filter(m=>m.source==="manual").map(m=>m.id),n=h.filter(m=>!m.enabled).map(m=>m.id),i={manualModels:a,disabledModels:n},r=await fetch(`/api/llm/providers/${s.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!r.ok)throw new Error(await X(r,l("settings.llm.updateFailed")));return await r.json()},onSuccess:async a=>{await c.invalidateQueries({queryKey:["llm-providers"]}),a.modelsError?b.warning(l("settings.llm.modelsFetchFailed",{error:a.modelsError})):b.success(l("common.success")),o(!1)},onError:a=>{b.error(a instanceof Error?a.message:l("common.error"))}});return e.jsx(ae,{open:t,onOpenChange:o,children:e.jsxs(ne,{className:"sm:max-w-lg","data-testid":`llm-provider-models-modal-${s.id}`,children:[e.jsxs(ie,{children:[e.jsx(re,{children:l("settings.llm.modelsTitle",{name:s.name})}),e.jsx(Ne,{children:l("settings.llm.modelsHint")})]}),e.jsx(fs,{models:h,onChange:p}),e.jsxs(de,{children:[e.jsx(k,{variant:"outline",onClick:()=>o(!1),disabled:f.isPending,children:l("common.cancel")}),e.jsxs(k,{variant:"secondary","data-testid":`llm-provider-models-save-${s.id}`,onClick:()=>f.mutate(),disabled:f.isPending,children:[f.isPending?e.jsx(U,{className:"h-4 w-4 animate-spin"}):e.jsx(Z,{className:"h-4 w-4"}),l("common.save")]})]})]})})}function ys(t){try{const o=new URL(t);return`${o.protocol}//${o.host}${o.pathname==="/"?"":o.pathname}`}catch{return t}}function js({provider:t,onEdit:o}){const{t:s}=F(),l=O(),[c,h]=w.useState(!1),[p,f]=w.useState(!1),a=M({mutationFn:async r=>{const m=await fetch(`/api/llm/providers/${t.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({enabled:r})});if(!m.ok)throw new Error(await X(m,s("settings.llm.updateFailed")))},onSuccess:async()=>{await l.invalidateQueries({queryKey:["llm-providers"]})},onError:r=>{b.error(r instanceof Error?r.message:s("common.error"))}}),n=M({mutationFn:async()=>{const r=await fetch(`/api/llm/providers/${t.id}/refresh-models`,{method:"POST"});if(!r.ok)throw new Error(await X(r,s("settings.llm.refreshModelsFailed")))},onSuccess:async()=>{await l.invalidateQueries({queryKey:["llm-providers"]}),b.success(s("common.success"))},onError:r=>{b.error(r instanceof Error?r.message:s("common.error"))}}),i=M({mutationFn:async()=>{const r=await fetch(`/api/llm/providers/${t.id}`,{method:"DELETE"});if(!r.ok)throw new Error(await X(r,s("settings.llm.deleteFailed")))},onSuccess:async()=>{await l.invalidateQueries({queryKey:["llm-providers"]}),await l.invalidateQueries({queryKey:["llm-settings"]}),b.success(s("common.success"))},onError:r=>{b.error(r instanceof Error?r.message:s("common.error"))}});return e.jsxs("div",{className:"flex flex-col gap-3 rounded-lg border border-border bg-card p-3 sm:flex-row sm:items-center sm:justify-between","data-testid":`llm-provider-row-${t.id}`,"data-provider-name":t.name,children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[e.jsx(D,{checked:t.enabled,disabled:a.isPending,onCheckedChange:r=>a.mutate(!!r),"data-testid":`llm-provider-enabled-${t.id}`}),e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"truncate font-medium",children:t.name}),e.jsx(xt,{variant:"outline",children:t.protocol})]}),e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsx("span",{className:"truncate font-mono",children:ys(t.baseUrl)}),e.jsx("span",{"aria-hidden":!0,children:"·"}),e.jsx("span",{className:"whitespace-nowrap",children:s("settings.llm.modelsCount",{total:t.models.length})})]})]})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1",children:[e.jsx(k,{variant:"ghost",size:"icon-sm",title:s("settings.llm.refreshModels"),"data-testid":`llm-provider-refresh-models-${t.id}`,onClick:()=>n.mutate(),disabled:n.isPending,children:n.isPending?e.jsx(U,{className:"h-4 w-4 animate-spin"}):e.jsx(tt,{className:"h-4 w-4"})}),e.jsx(k,{variant:"ghost",size:"icon-sm",title:s("settings.llm.models"),"data-testid":`llm-provider-models-${t.id}`,onClick:()=>f(!0),children:e.jsx(ss,{className:"h-4 w-4"})}),e.jsx(k,{variant:"ghost",size:"icon-sm",title:s("common.edit"),"data-testid":`llm-provider-edit-${t.id}`,onClick:()=>o(t),children:e.jsx(De,{className:"h-4 w-4"})}),e.jsx(k,{variant:"ghost",size:"icon-sm",title:s("common.delete"),"data-testid":`llm-provider-delete-${t.id}`,onClick:()=>h(!0),disabled:i.isPending,children:e.jsx(te,{className:"h-4 w-4 text-destructive"})})]}),e.jsx(ws,{open:p,onOpenChange:f,provider:t}),e.jsx(xe,{open:c,onOpenChange:h,children:e.jsxs(fe,{children:[e.jsxs(pe,{children:[e.jsx(we,{children:s("settings.llm.deleteProvider")}),e.jsx(ye,{children:s("settings.llm.deleteConfirm",{name:t.name})})]}),e.jsxs(je,{children:[e.jsx(ve,{onClick:()=>h(!1),children:s("common.cancel")}),e.jsx(be,{variant:"destructive","data-testid":`llm-provider-delete-confirm-${t.id}`,onClick:()=>{i.mutate(),h(!1)},children:s("common.confirm")})]})]})})]})}function vs(){var n;const{t}=F(),[o,s]=w.useState(!1),[l,c]=w.useState(void 0),h=Q({queryKey:["llm-providers"],queryFn:async()=>{const i=await fetch("/api/llm/providers");if(!i.ok)throw new Error(await X(i,t("settings.llm.loadFailed")));return await i.json()}}),p=((n=h.data)==null?void 0:n.providers)??[],f=()=>{c(void 0),s(!0)},a=i=>{c(i),s(!0)};return e.jsxs(e.Fragment,{children:[e.jsxs(H,{className:"border-0 ring-0","data-testid":"llm-providers-section",children:[e.jsxs(G,{className:"flex flex-row items-center justify-between gap-2",children:[e.jsx(J,{children:t("settings.llm.title")}),e.jsxs(k,{variant:"secondary","data-testid":"llm-provider-add",onClick:f,children:[e.jsx(ge,{className:"h-4 w-4"}),t("settings.llm.addProvider")]})]}),e.jsxs(V,{className:"space-y-3",children:[h.isLoading&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("common.loading")}),!h.isLoading&&p.length===0&&e.jsx("div",{className:"text-sm text-muted-foreground","data-testid":"llm-providers-empty",children:t("settings.llm.empty")}),p.map(i=>e.jsx(js,{provider:i,onEdit:a},i.id))]})]}),e.jsx(xs,{open:o,onOpenChange:s,provider:l}),e.jsx(bs,{providers:p})]})}const ze="__none__";function bs({providers:t}){var y,j;const{t:o}=F(),s=O(),[l,c]=w.useState(null),[h,p]=w.useState(""),f=Q({queryKey:["llm-settings"],queryFn:async()=>{const g=await fetch("/api/llm/settings");if(!g.ok)throw new Error(await X(g,o("settings.llm.settingsLoadFailed")));return await g.json()}}),a=((y=f.data)==null?void 0:y.settings.defaultProviderId)??null,n=((j=f.data)==null?void 0:j.settings.defaultModelId)??"",i=!!f.data;w.useEffect(()=>{i&&(c(a),p(n))},[i,a,n]);const r=M({mutationFn:async()=>{const g={defaultProviderId:l,defaultModelId:h.trim()||null},C=await fetch("/api/llm/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(g)});if(!C.ok)throw new Error(await X(C,o("settings.llm.settingsSaveFailed")))},onSuccess:async()=>{await s.invalidateQueries({queryKey:["llm-settings"]}),b.success(o("common.success"))},onError:g=>{b.error(g instanceof Error?g.message:o("common.error"))}}),m=t.filter(g=>g.enabled),d=t.find(g=>g.id===l),u=(d==null?void 0:d.models)??[];return e.jsxs(H,{className:"border-0 ring-0","data-testid":"llm-defaults-section",children:[e.jsx(G,{children:e.jsx(J,{children:o("settings.llm.defaults")})}),e.jsxs(V,{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:o("settings.llm.defaultProvider")}),e.jsxs(Ce,{value:l??ze,onValueChange:g=>{g&&c(g===ze?null:g)},children:[e.jsx(Ee,{id:"llm-default-provider-select","data-testid":"llm-default-provider-select",className:"h-9 w-full",children:e.jsx(ke,{children:(d==null?void 0:d.name)??o("settings.llm.defaultProviderNone")})}),e.jsxs(Se,{children:[e.jsx(le,{value:ze,children:o("settings.llm.defaultProviderNone")}),m.map(g=>e.jsx(le,{value:g.id,children:g.name},g.id))]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"llm-default-model-input",children:o("settings.llm.defaultModel")}),e.jsx(B,{id:"llm-default-model-input","data-testid":"llm-default-model-input",list:"llm-default-model-options",value:h,onChange:g=>p(g.target.value),placeholder:o("settings.llm.defaultModelPlaceholder"),className:"h-9"}),e.jsx("datalist",{id:"llm-default-model-options",children:u.map(g=>e.jsx("option",{value:g},g))})]})]}),e.jsx("div",{className:"flex justify-end",children:e.jsxs(k,{variant:"secondary","data-testid":"llm-defaults-save",onClick:()=>r.mutate(),disabled:r.isPending||f.isLoading,className:"w-full sm:w-auto",children:[r.isPending?e.jsx(U,{className:"h-4 w-4 animate-spin"}):e.jsx(Z,{className:"h-4 w-4"}),o("settings.llm.saveDefaults")]})})]})]})}const Ns=["none","tavily","brave"];async function qe(t,o){try{return(await t.json()).error??o}catch{return o}}function Cs(){var j;const{t}=F(),o=O(),[s,l]=w.useState("none"),[c,h]=w.useState(""),[p,f]=w.useState(""),[a,n]=w.useState(null),i=Q({queryKey:["llm-settings"],queryFn:async()=>{const g=await fetch("/api/llm/settings");if(!g.ok)throw new Error(await qe(g,t("settings.search.loadFailed")));return await g.json()}}),r=(j=i.data)==null?void 0:j.settings,m=r==null?void 0:r.searchProvider;w.useEffect(()=>{m&&l(m)},[m]);const d=M({mutationFn:async()=>{const g={searchProvider:s};c.trim()&&(g.tavilyApiKey=c.trim()),p.trim()&&(g.braveApiKey=p.trim());const C=await fetch("/api/llm/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(g)});if(!C.ok)throw new Error(await qe(C,t("settings.search.saveFailed")))},onSuccess:async()=>{h(""),f(""),await o.invalidateQueries({queryKey:["llm-settings"]}),b.success(t("common.success"))},onError:g=>{b.error(g instanceof Error?g.message:t("common.error"))}}),u=M({mutationFn:async g=>{const C={[g]:""},x=await fetch("/api/llm/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(C)});if(!x.ok)throw new Error(await qe(x,t("settings.search.saveFailed")))},onSuccess:async()=>{await o.invalidateQueries({queryKey:["llm-settings"]}),b.success(t("common.success"))},onError:g=>{b.error(g instanceof Error?g.message:t("common.error"))}}),y=g=>g==="none"?t("settings.search.providerNone"):g==="tavily"?"Tavily":"Brave";return e.jsxs(H,{className:"border-0 ring-0","data-testid":"settings-search-section",children:[e.jsx(G,{children:e.jsx(J,{children:t("settings.search.title")})}),e.jsxs(V,{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:t("settings.search.provider")}),e.jsxs(Ce,{value:s,onValueChange:g=>{g&&l(g)},children:[e.jsx(Ee,{id:"search-provider-select","data-testid":"settings-search-provider-select",className:"w-full min-h-10",children:e.jsx(ke,{children:y(s)})}),e.jsx(Se,{children:Ns.map(g=>e.jsx(le,{value:g,children:y(g)},g))})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:t("settings.search.responsesApiHint")})]}),e.jsx(lt,{id:"search-tavily-key-input",testId:"settings-search-tavily",label:t("settings.search.tavilyApiKey"),value:c,hasKey:(r==null?void 0:r.hasTavilyApiKey)??!1,onChange:h,onClear:()=>n("tavilyApiKey"),clearing:u.isPending&&u.variables==="tavilyApiKey"}),e.jsx(lt,{id:"search-brave-key-input",testId:"settings-search-brave",label:t("settings.search.braveApiKey"),value:p,hasKey:(r==null?void 0:r.hasBraveApiKey)??!1,onChange:f,onClear:()=>n("braveApiKey"),clearing:u.isPending&&u.variables==="braveApiKey"}),e.jsx(xe,{open:a!==null,onOpenChange:g=>{g||n(null)},children:e.jsxs(fe,{children:[e.jsxs(pe,{children:[e.jsx(we,{children:t("settings.search.clearKey")}),e.jsx(ye,{children:t("settings.search.clearKeyConfirm")})]}),e.jsxs(je,{children:[e.jsx(ve,{children:t("common.cancel")}),e.jsx(be,{"data-testid":"settings-search-clear-confirm",onClick:()=>{a&&u.mutate(a),n(null)},children:t("settings.search.clearKey")})]})]})}),e.jsx("div",{className:"flex justify-end",children:e.jsxs(k,{variant:"secondary","data-testid":"settings-search-save",onClick:()=>d.mutate(),disabled:d.isPending||i.isLoading,className:"w-full sm:w-auto",children:[d.isPending?e.jsx(U,{className:"h-4 w-4 animate-spin"}):e.jsx(Z,{className:"h-4 w-4"}),t("common.save")]})})]})]})}function lt({id:t,testId:o,label:s,value:l,hasKey:c,onChange:h,onClear:p,clearing:f}){const{t:a}=F();return e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:t,children:s}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(B,{id:t,"data-testid":`${o}-input`,"data-key-set":c?"true":"false",type:"password",value:l,onChange:n=>h(n.target.value),placeholder:a(c?"settings.search.keySetPlaceholder":"settings.search.keyPlaceholder"),className:"min-h-10"}),c&&e.jsxs(k,{variant:"outline",size:"sm","data-testid":`${o}-clear`,onClick:p,disabled:f,className:"shrink-0",children:[e.jsx(te,{className:"h-4 w-4"}),a("settings.search.clearKey")]})]})]})}const ct="min-h-10";async function dt(t,o){try{return(await t.json()).error??o}catch{return o}}function Es({open:t,onOpenChange:o,bot:s}){const{t:l}=F(),c=O(),h=!!s,[p,f]=w.useState(""),[a,n]=w.useState(""),[i,r]=w.useState(!0);w.useEffect(()=>{t&&(f((s==null?void 0:s.name)??""),n(""),r((s==null?void 0:s.allowAuthRequests)??!0))},[t,s]);const m=M({mutationFn:async()=>{const g=await fetch("/api/settings/telegram/bots",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:p.trim(),token:a.trim(),enabled:!0,allowAuthRequests:i})});if(!g.ok)throw new Error(await dt(g,l("telegram.createFailed")))},onSuccess:async()=>{await c.invalidateQueries({queryKey:["telegram-bots"]}),b.success(l("common.success")),o(!1)},onError:g=>{b.error(g instanceof Error?g.message:l("common.error"))}}),d=M({mutationFn:async()=>{if(!s)throw new Error(l("telegram.updateFailed"));const g={name:p.trim(),allowAuthRequests:i};a.trim()&&(g.token=a.trim());const C=await fetch(`/api/settings/telegram/bots/${s.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(g)});if(!C.ok)throw new Error(await dt(C,l("telegram.updateFailed")))},onSuccess:async()=>{await c.invalidateQueries({queryKey:["telegram-bots"]}),b.success(l("common.success")),o(!1)},onError:g=>{b.error(g instanceof Error?g.message:l("common.error"))}}),u=m.isPending||d.isPending,y=p.trim().length>0&&(h||a.trim().length>0),j=()=>{!y||u||(h?d.mutate():m.mutate())};return e.jsx(ae,{open:t,onOpenChange:o,children:e.jsxs(ne,{className:"sm:max-w-lg","data-testid":h?`telegram-bot-edit-modal-${s==null?void 0:s.id}`:"telegram-bot-add-modal",children:[e.jsx(ie,{children:e.jsx(re,{children:l(h?"telegram.editBot":"telegram.addBot")})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"telegram-bot-name",children:l("telegram.botName")}),e.jsx(B,{id:"telegram-bot-name","data-testid":"telegram-bot-name-input",value:p,onChange:g=>f(g.target.value),placeholder:l("telegram.botNamePlaceholder"),className:ct})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"telegram-bot-token",children:l("telegram.botToken")}),e.jsx(B,{id:"telegram-bot-token","data-testid":"telegram-bot-token-input",type:"password",value:a,onChange:g=>n(g.target.value),placeholder:l(h?"telegram.tokenPlaceholder":"telegram.botTokenPlaceholder"),className:ct})]}),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:l("telegram.allowAuthRequests")}),e.jsx(D,{checked:i,"data-testid":"telegram-bot-allow-auth",onCheckedChange:g=>r(!!g)})]})]}),e.jsxs(de,{children:[e.jsx(k,{variant:"outline",onClick:()=>o(!1),disabled:u,children:l("common.cancel")}),e.jsxs(k,{variant:"secondary","data-testid":"telegram-bot-form-submit",onClick:j,disabled:!y||u,children:[u?e.jsx(U,{className:"h-4 w-4 animate-spin"}):e.jsx(Z,{className:"h-4 w-4"}),l("common.save")]})]})]})})}async function Ie(t,o){try{return(await t.json()).error??o}catch{return o}}function ks({open:t,onOpenChange:o,botId:s,botName:l}){var m;const{t:c}=F(),h=O(),p=Q({queryKey:["telegram-bot-chats",s],enabled:t,queryFn:async()=>{const d=await fetch(`/api/settings/telegram/bots/${s}/chats`);if(!d.ok)throw new Error(await Ie(d,c("telegram.loadChatsFailed")));return await d.json()}}),f=w.useMemo(()=>{var u;const d=((u=p.data)==null?void 0:u.chats)??[];return{pending:d.filter(y=>y.status==="pending"),authorized:d.filter(y=>y.status==="authorized")}},[(m=p.data)==null?void 0:m.chats]),a=async()=>{await Promise.all([h.invalidateQueries({queryKey:["telegram-bots"]}),h.invalidateQueries({queryKey:["telegram-bot-chats",s]})])},n=M({mutationFn:async d=>{const u=await fetch(`/api/settings/telegram/bots/${s}/chats/${encodeURIComponent(d)}/approve`,{method:"POST"});if(!u.ok)throw new Error(await Ie(u,c("telegram.approveFailed")))},onSuccess:async()=>{await a(),b.success(c("common.success"))},onError:d=>{b.error(d instanceof Error?d.message:c("common.error"))}}),i=M({mutationFn:async d=>{const u=await fetch(`/api/settings/telegram/bots/${s}/chats/${encodeURIComponent(d)}`,{method:"DELETE"});if(!u.ok)throw new Error(await Ie(u,c("telegram.removeFailed")))},onSuccess:async()=>{await a(),b.success(c("common.success"))},onError:d=>{b.error(d instanceof Error?d.message:c("common.error"))}}),r=M({mutationFn:async d=>{const u=await fetch(`/api/settings/telegram/bots/${s}/chats/${encodeURIComponent(d)}/test`,{method:"POST"});if(!u.ok)throw new Error(await Ie(u,c("telegram.testMessageFailed")))},onSuccess:()=>{b.success(c("common.success"))},onError:d=>{b.error(d instanceof Error?d.message:c("common.error"))}});return e.jsx(ae,{open:t,onOpenChange:o,children:e.jsxs(ne,{className:"sm:max-w-2xl","data-testid":`telegram-bot-chats-modal-${s}`,children:[e.jsxs(ie,{children:[e.jsx(re,{children:c("telegram.chats")}),e.jsx(Ne,{children:l})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-4 lg:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("h3",{className:"flex items-center gap-1 text-sm font-semibold",children:[e.jsx(rt,{className:"h-4 w-4"}),c("telegram.pendingChats")]}),f.pending.length===0&&e.jsx("div",{className:"text-xs text-muted-foreground",children:c("telegram.noPendingChats")}),f.pending.map(d=>e.jsx(mt,{chat:d,pending:!0,onApprove:()=>n.mutate(d.chatId),onDelete:()=>i.mutate(d.chatId)},`${d.botId}-${d.chatId}`))]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("h3",{className:"flex items-center gap-1 text-sm font-semibold",children:[e.jsx(rt,{className:"h-4 w-4"}),c("telegram.chats")]}),f.authorized.length===0&&e.jsx("div",{className:"text-xs text-muted-foreground",children:c("telegram.noAuthorizedChats")}),f.authorized.map(d=>e.jsx(mt,{chat:d,pending:!1,onTest:()=>r.mutate(d.chatId),onDelete:()=>i.mutate(d.chatId)},`${d.botId}-${d.chatId}`))]}),p.isLoading&&e.jsx("div",{className:"text-xs text-muted-foreground lg:col-span-2",children:c("common.loading")})]})]})})}function mt({chat:t,pending:o,onApprove:s,onDelete:l,onTest:c}){const{t:h}=F(),p=Oe(f=>{var a;return((a=f.settings)==null?void 0:a.language)??"en_US"});return e.jsxs("div",{className:"space-y-2 rounded border-0 bg-background p-3",children:[e.jsx("div",{className:"truncate text-sm font-medium",title:t.displayName,children:t.displayName}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[h("telegram.chatId"),":",t.chatId]}),e.jsx("div",{className:"text-xs text-muted-foreground",children:new Date(t.appliedAt).toLocaleString(et(p))}),e.jsx("div",{className:"flex items-center justify-end gap-2 pt-1",children:o?e.jsxs(e.Fragment,{children:[e.jsx(k,{variant:"outline",size:"sm",onClick:l,children:h("telegram.reject")}),e.jsx(k,{variant:"secondary",size:"sm",onClick:s,children:h("telegram.authorize")})]}):e.jsxs(e.Fragment,{children:[e.jsxs(k,{variant:"secondary",size:"sm",onClick:c,children:[e.jsx(yt,{className:"h-3.5 w-3.5"}),h("telegram.sendTestMessage")]}),e.jsx(k,{variant:"destructive",size:"sm",onClick:l,children:h("common.delete")})]})})]})}async function ut(t,o){try{return(await t.json()).error??o}catch{return o}}function Ss({bot:t,onEdit:o}){const{t:s}=F(),l=O(),[c,h]=w.useState(!1),p=M({mutationFn:async a=>{const n=await fetch(`/api/settings/telegram/bots/${t.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({enabled:a})});if(!n.ok)throw new Error(await ut(n,s("telegram.updateFailed")))},onSuccess:async()=>{await l.invalidateQueries({queryKey:["telegram-bots"]})},onError:a=>{b.error(a instanceof Error?a.message:s("common.error"))}}),f=M({mutationFn:async()=>{const a=await fetch(`/api/settings/telegram/bots/${t.id}`,{method:"DELETE"});if(!a.ok)throw new Error(await ut(a,s("telegram.deleteFailed")))},onSuccess:async()=>{await l.invalidateQueries({queryKey:["telegram-bots"]}),b.success(s("common.success"))},onError:a=>{b.error(a instanceof Error?a.message:s("common.error"))}});return e.jsxs("div",{className:"flex flex-col gap-3 rounded-lg border border-border bg-card p-3 sm:flex-row sm:items-center sm:justify-between","data-testid":`telegram-bot-card-${t.id}`,"data-bot-name":t.name,children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[e.jsx(D,{checked:t.enabled,disabled:p.isPending,onCheckedChange:a=>p.mutate(!!a),"data-testid":`telegram-bot-enabled-${t.id}`}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate font-medium",children:t.name}),e.jsx("div",{className:"text-xs text-muted-foreground",children:s("telegram.authCount",{authorized:t.authorizedCount,pending:t.pendingCount})})]})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1",children:[e.jsx(k,{variant:"ghost",size:"icon-sm",title:s("telegram.chats"),"data-testid":`telegram-bot-chats-${t.id}`,onClick:()=>h(!0),children:e.jsx(cs,{className:"h-4 w-4"})}),e.jsx(k,{variant:"ghost",size:"icon-sm",title:s("common.edit"),"data-testid":`telegram-bot-edit-${t.id}`,onClick:()=>o(t),children:e.jsx(De,{className:"h-4 w-4"})}),e.jsx(k,{variant:"ghost",size:"icon-sm",title:s("telegram.deleteBot"),"data-testid":`telegram-bot-delete-${t.id}`,onClick:()=>f.mutate(),disabled:f.isPending,children:e.jsx(te,{className:"h-4 w-4 text-destructive"})})]}),e.jsx(ks,{open:c,onOpenChange:h,botId:t.id,botName:t.name})]})}async function Ms(t,o){try{return(await t.json()).error??o}catch{return o}}function Ps(){var n;const{t}=F(),[o,s]=w.useState(!1),[l,c]=w.useState(void 0),h=Q({queryKey:["telegram-bots"],queryFn:async()=>{const i=await fetch("/api/settings/telegram/bots");if(!i.ok)throw new Error(await Ms(i,t("telegram.loadBotsFailed")));return await i.json()}}),p=((n=h.data)==null?void 0:n.bots)??[],f=()=>{c(void 0),s(!0)},a=i=>{c(i),s(!0)};return e.jsxs(e.Fragment,{children:[e.jsxs(H,{className:"border-0 ring-0",children:[e.jsxs(G,{className:"flex flex-row items-center justify-between gap-2",children:[e.jsx(J,{children:t("telegram.title")}),e.jsxs(k,{variant:"secondary","data-testid":"telegram-add-bot",onClick:f,children:[e.jsx(ge,{className:"h-4 w-4"}),t("telegram.addBot")]})]}),e.jsxs(V,{className:"space-y-3",children:[h.isLoading&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("common.loading")}),!h.isLoading&&p.length===0&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("telegram.noBots")}),p.map(i=>e.jsx(Ss,{bot:i,onEdit:a},i.id))]})]}),e.jsx(Es,{open:o,onOpenChange:s,bot:l})]})}function Fs(){const{t}=F();return e.jsxs("div",{className:"space-y-4",children:[e.jsxs(H,{className:"border-0 ring-0",children:[e.jsx(G,{children:e.jsx(J,{children:t("settings.terminal.title")})}),e.jsx(V,{children:e.jsx(Yt,{showShortcuts:!1})})]}),e.jsxs(H,{className:"border-0 ring-0",children:[e.jsxs(G,{children:[e.jsx(J,{children:t("settings.terminal.shortcuts.title")}),e.jsx(pt,{children:t("settings.terminal.shortcuts.savedOnServer")})]}),e.jsx(V,{children:e.jsx(Xt,{})})]})]})}async function Ke(t,o){try{return(await t.json()).error??o}catch{return o}}function Qe({label:t,value:o}){return 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 text-sm font-medium",children:t}),e.jsx("div",{className:"min-w-0 truncate text-right text-sm text-muted-foreground",children:o})]})}function As(){const{t}=F(),o=O(),s=Oe(x=>{var N;return((N=x.settings)==null?void 0:N.language)??"en_US"}),[l,c]=w.useState(!1),[h,p]=w.useState(!1),f=w.useRef(!1),n=Q({queryKey:["system-info"],queryFn:async()=>{const x=await fetch("/api/system/info");if(!x.ok)throw new Error(await Ke(x,t("settings.loadFailed")));return await x.json()}}).data,i=Q({queryKey:["system-update-check"],enabled:!1,gcTime:0,queryFn:async()=>{const x=await fetch("/api/system/update-check");if(!x.ok)throw new Error(await Ke(x,t("settings.version.checkFailed")));return await x.json()}}),r=i.data,d=Q({queryKey:["system-upgrade-status"],enabled:h,refetchInterval:x=>{var E;const N=(E=x.state.data)==null?void 0:E.state;return h||N&&N!=="idle"?2e3:!1},retry:!0,queryFn:async()=>{const x=await fetch("/api/system/upgrade");if(!x.ok)throw new Error("status");return await x.json()}}).data;w.useEffect(()=>{if(!h)return;const x=d==null?void 0:d.state;x&&x!=="idle"?f.current=!0:x==="idle"&&(d!=null&&d.error)?(f.current=!1,p(!1),b.error(d.error)):x==="idle"&&f.current&&(f.current=!1,p(!1),o.invalidateQueries({queryKey:["system-info"]}),o.removeQueries({queryKey:["system-update-check"]}),b.success(t("common.success")))},[h,d,o,t]);const u=M({mutationFn:async x=>{const N=await fetch("/api/system/upgrade",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({version:x})});if(!N.ok)throw new Error(await Ke(N,t("common.error")));return await N.json()},onSuccess:x=>{f.current=!1,p(!0),o.setQueryData(["system-upgrade-status"],x),b.success(t("settings.version.upgradeStarted"))},onError:x=>{b.error(x instanceof Error?x.message:t("common.error"))}}),y=x=>t(x==="launchd"?"settings.version.deploymentLaunchd":x==="systemd"?"settings.version.deploymentSystemd":"settings.version.deploymentNone"),j=h&&(d==null?void 0:d.state)!==void 0,g=(d==null?void 0:d.state)==="downloading"?t("settings.version.stateDownloading"):(d==null?void 0:d.state)==="executing"?t("settings.version.stateExecuting"):null,C=n!=null&&n.canSelfUpdate?null:n!=null&&n.isProd?n!=null&&n.installedViaCli?null:t("settings.version.upgradeDisabledNonCli"):t("settings.version.upgradeDisabledDev");return e.jsxs(H,{className:"border-0 ring-0",children:[e.jsx(G,{children:e.jsx(J,{children:t("settings.version.title")})}),e.jsxs(V,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx(Qe,{label:t("settings.version.currentVersion"),value:e.jsx("span",{"data-testid":"settings-version-current",className:"font-mono",children:n?n.version:t("common.loading")})}),e.jsx(Qe,{label:t("settings.version.installMethod"),value:n?n.installedViaCli?t("settings.version.installMethodCli"):t("settings.version.installMethodNonCli"):"-"}),e.jsx(Qe,{label:t("settings.version.deployment"),value:n?y(n.deployment):"-"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs(k,{variant:"outline","data-testid":"settings-version-check",onClick:()=>i.refetch(),disabled:i.isFetching||j,children:[i.isFetching?e.jsx(U,{className:"h-4 w-4 animate-spin"}):e.jsx(tt,{className:"h-4 w-4"}),i.isFetching?t("settings.version.checking"):t("settings.version.checkUpdate")]}),r&&e.jsxs("span",{className:"text-sm text-muted-foreground","data-testid":"settings-version-latest",children:[r.hasUpdate&&r.latestVersion?t("settings.version.updateAvailable",{version:r.latestVersion}):t("settings.version.upToDate"),r.publishedAt?` · ${t("settings.version.publishedAt",{date:new Date(r.publishedAt).toLocaleDateString(et(s))})}`:""]})]}),i.isError&&e.jsx("div",{className:"text-sm text-destructive",children:t("settings.version.checkFailed")}),(r==null?void 0:r.hasUpdate)&&e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"text-sm font-semibold",children:t("settings.version.changelog")}),e.jsx("div",{className:"rounded-lg border border-border bg-card px-4 py-3",children:r.changelog?e.jsx(es,{source:r.changelog,basePath:"/"}):e.jsx("div",{className:"text-sm text-muted-foreground",children:t("settings.version.changelogUnavailable")})}),n!=null&&n.canSelfUpdate?e.jsxs(k,{variant:"secondary","data-testid":"settings-version-upgrade",disabled:j||u.isPending,onClick:()=>c(!0),children:[j?e.jsx(U,{className:"h-4 w-4 animate-spin"}):e.jsx(Jt,{className:"h-4 w-4"}),t("settings.version.upgrade")]}):e.jsxs("div",{className:"space-y-1",children:[C&&e.jsx("div",{className:"text-sm text-muted-foreground",children:C}),e.jsx("div",{className:"text-xs text-muted-foreground font-mono",children:t("settings.version.terminalHint")})]})]}),j&&g&&e.jsxs("div",{className:"flex items-start gap-2 rounded-lg border border-border bg-card px-4 py-3","data-testid":"settings-version-upgrade-status",children:[e.jsx(U,{className:"mt-0.5 h-4 w-4 shrink-0 animate-spin text-primary"}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"text-sm font-medium",children:g}),e.jsx("div",{className:"text-xs text-muted-foreground",children:t("settings.version.interruptNotice")})]})]})]}),e.jsx(xe,{open:l,onOpenChange:c,children:e.jsxs(fe,{children:[e.jsxs(pe,{children:[e.jsxs(we,{className:"flex items-center gap-2",children:[e.jsx(jt,{className:"h-5 w-5 text-destructive"}),t("settings.version.upgradeWarningTitle")]}),e.jsx(ye,{children:t("settings.version.upgradeWarningBody")})]}),e.jsxs(je,{children:[e.jsx(ve,{onClick:()=>c(!1),children:t("common.cancel")}),e.jsx(be,{variant:"destructive","data-testid":"settings-version-upgrade-confirm",onClick:()=>{c(!1),r!=null&&r.latestVersion&&u.mutate(r.latestVersion)},children:t("settings.version.upgrade")})]})]})})]})}const Ue=["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 He(t,o){try{return(await t.json()).error??o}catch{return o}}function Ts(){var d;const{t}=F(),o=O(),s=Oe(u=>{var y;return((y=u.settings)==null?void 0:y.language)??"en_US"}),[l,c]=w.useState(""),[h,p]=w.useState(""),[f,a]=w.useState(Ue),n=Q({queryKey:["webhooks"],queryFn:async()=>{const u=await fetch("/api/webhooks");if(!u.ok)throw new Error(await He(u,t("webhook.loadFailed")));return await u.json()}}),i=M({mutationFn:async()=>{const u=await fetch("/api/webhooks",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:l,secret:h,eventMask:f})});if(!u.ok)throw new Error(await He(u,t("webhook.createFailed")))},onSuccess:async()=>{c(""),p(""),a(Ue),await o.invalidateQueries({queryKey:["webhooks"]}),b.success(t("common.success"))},onError:u=>{b.error(u instanceof Error?u.message:t("common.error"))}}),r=M({mutationFn:async u=>{const y=await fetch(`/api/webhooks/${u}`,{method:"DELETE"});if(!y.ok)throw new Error(await He(y,t("webhook.deleteFailed")))},onSuccess:async()=>{await o.invalidateQueries({queryKey:["webhooks"]}),b.success(t("common.success"))},onError:u=>{b.error(u instanceof Error?u.message:t("common.error"))}}),m=((d=n.data)==null?void 0:d.webhooks)??[];return e.jsxs(H,{className:"border-0 ring-0",children:[e.jsx(G,{children:e.jsx(J,{children:t("webhook.title")})}),e.jsxs(V,{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:t("webhook.url")}),e.jsx(B,{id:"webhook-url-input","data-testid":"webhook-url-input",value:l,onChange:u=>c(u.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:t("webhook.secret")}),e.jsx(B,{id:"webhook-secret-input","data-testid":"webhook-secret-input",value:h,onChange:u=>p(u.target.value),placeholder:t("webhook.secretPlaceholder"),className:"min-h-10"})]}),e.jsx("div",{className:"md:col-span-2",children:e.jsxs(k,{variant:"secondary",className:"w-full md:w-auto","data-testid":"webhook-add",onClick:()=>i.mutate(),disabled:i.isPending||!l.trim()||!h.trim()||f.length===0,children:[i.isPending?e.jsx(U,{className:"h-4 w-4 animate-spin"}):e.jsx(Z,{className:"h-4 w-4"}),t("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:t("webhook.eventMask")}),e.jsx("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2",children:Ue.map(u=>{const y=f.includes(u);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:t(`notification.eventType.${u}`)}),e.jsx(D,{checked:y,"data-testid":`webhook-event-${u}`,onCheckedChange:j=>{a(g=>j?g.includes(u)?g:[...g,u]:g.filter(C=>C!==u))}})]},u)})})]}),e.jsxs("div",{className:"space-y-2",children:[n.isLoading&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("common.loading")}),!n.isLoading&&m.length===0&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("webhook.empty")}),m.map(u=>e.jsxs("div",{"data-testid":"webhook-item","data-webhook-url":u.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:u.url}),e.jsx("div",{className:"text-xs text-muted-foreground",children:new Date(u.createdAt).toLocaleString(et(s))})]}),e.jsx(k,{variant:"ghost",size:"icon-sm","data-testid":"webhook-delete",onClick:()=>r.mutate(u.id),disabled:r.isPending,"aria-label":t("common.delete"),title:t("common.delete"),children:e.jsx(te,{className:"h-4 w-4"})})]},u.id))]})]})]})}var Rs=Object.defineProperty,Be=Object.getOwnPropertySymbols,vt=Object.prototype.hasOwnProperty,bt=Object.prototype.propertyIsEnumerable,ht=(t,o,s)=>o in t?Rs(t,o,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[o]=s,Je=(t,o)=>{for(var s in o||(o={}))vt.call(o,s)&&ht(t,s,o[s]);if(Be)for(var s of Be(o))bt.call(o,s)&&ht(t,s,o[s]);return t},Ye=(t,o)=>{var s={};for(var l in t)vt.call(t,l)&&o.indexOf(l)<0&&(s[l]=t[l]);if(t!=null&&Be)for(var l of Be(t))o.indexOf(l)<0&&bt.call(t,l)&&(s[l]=t[l]);return s};/**
32
- * @license QR Code generator library (TypeScript)
33
- * Copyright (c) Project Nayuki.
34
- * SPDX-License-Identifier: MIT
35
- */var se;(t=>{const o=class S{constructor(a,n,i,r){if(this.version=a,this.errorCorrectionLevel=n,this.modules=[],this.isFunction=[],a<S.MIN_VERSION||a>S.MAX_VERSION)throw new RangeError("Version value out of range");if(r<-1||r>7)throw new RangeError("Mask value out of range");this.size=a*4+17;let m=[];for(let u=0;u<this.size;u++)m.push(!1);for(let u=0;u<this.size;u++)this.modules.push(m.slice()),this.isFunction.push(m.slice());this.drawFunctionPatterns();const d=this.addEccAndInterleave(i);if(this.drawCodewords(d),r==-1){let u=1e9;for(let y=0;y<8;y++){this.applyMask(y),this.drawFormatBits(y);const j=this.getPenaltyScore();j<u&&(r=y,u=j),this.applyMask(y)}}c(0<=r&&r<=7),this.mask=r,this.applyMask(r),this.drawFormatBits(r),this.isFunction=[]}static encodeText(a,n){const i=t.QrSegment.makeSegments(a);return S.encodeSegments(i,n)}static encodeBinary(a,n){const i=t.QrSegment.makeBytes(a);return S.encodeSegments([i],n)}static encodeSegments(a,n,i=1,r=40,m=-1,d=!0){if(!(S.MIN_VERSION<=i&&i<=r&&r<=S.MAX_VERSION)||m<-1||m>7)throw new RangeError("Invalid value");let u,y;for(u=i;;u++){const x=S.getNumDataCodewords(u,n)*8,N=p.getTotalBits(a,u);if(N<=x){y=N;break}if(u>=r)throw new RangeError("Data too long")}for(const x of[S.Ecc.MEDIUM,S.Ecc.QUARTILE,S.Ecc.HIGH])d&&y<=S.getNumDataCodewords(u,x)*8&&(n=x);let j=[];for(const x of a){s(x.mode.modeBits,4,j),s(x.numChars,x.mode.numCharCountBits(u),j);for(const N of x.getData())j.push(N)}c(j.length==y);const g=S.getNumDataCodewords(u,n)*8;c(j.length<=g),s(0,Math.min(4,g-j.length),j),s(0,(8-j.length%8)%8,j),c(j.length%8==0);for(let x=236;j.length<g;x^=253)s(x,8,j);let C=[];for(;C.length*8<j.length;)C.push(0);return j.forEach((x,N)=>C[N>>>3]|=x<<7-(N&7)),new S(u,n,C,m)}getModule(a,n){return 0<=a&&a<this.size&&0<=n&&n<this.size&&this.modules[n][a]}getModules(){return this.modules}drawFunctionPatterns(){for(let i=0;i<this.size;i++)this.setFunctionModule(6,i,i%2==0),this.setFunctionModule(i,6,i%2==0);this.drawFinderPattern(3,3),this.drawFinderPattern(this.size-4,3),this.drawFinderPattern(3,this.size-4);const a=this.getAlignmentPatternPositions(),n=a.length;for(let i=0;i<n;i++)for(let r=0;r<n;r++)i==0&&r==0||i==0&&r==n-1||i==n-1&&r==0||this.drawAlignmentPattern(a[i],a[r]);this.drawFormatBits(0),this.drawVersion()}drawFormatBits(a){const n=this.errorCorrectionLevel.formatBits<<3|a;let i=n;for(let m=0;m<10;m++)i=i<<1^(i>>>9)*1335;const r=(n<<10|i)^21522;c(r>>>15==0);for(let m=0;m<=5;m++)this.setFunctionModule(8,m,l(r,m));this.setFunctionModule(8,7,l(r,6)),this.setFunctionModule(8,8,l(r,7)),this.setFunctionModule(7,8,l(r,8));for(let m=9;m<15;m++)this.setFunctionModule(14-m,8,l(r,m));for(let m=0;m<8;m++)this.setFunctionModule(this.size-1-m,8,l(r,m));for(let m=8;m<15;m++)this.setFunctionModule(8,this.size-15+m,l(r,m));this.setFunctionModule(8,this.size-8,!0)}drawVersion(){if(this.version<7)return;let a=this.version;for(let i=0;i<12;i++)a=a<<1^(a>>>11)*7973;const n=this.version<<12|a;c(n>>>18==0);for(let i=0;i<18;i++){const r=l(n,i),m=this.size-11+i%3,d=Math.floor(i/3);this.setFunctionModule(m,d,r),this.setFunctionModule(d,m,r)}}drawFinderPattern(a,n){for(let i=-4;i<=4;i++)for(let r=-4;r<=4;r++){const m=Math.max(Math.abs(r),Math.abs(i)),d=a+r,u=n+i;0<=d&&d<this.size&&0<=u&&u<this.size&&this.setFunctionModule(d,u,m!=2&&m!=4)}}drawAlignmentPattern(a,n){for(let i=-2;i<=2;i++)for(let r=-2;r<=2;r++)this.setFunctionModule(a+r,n+i,Math.max(Math.abs(r),Math.abs(i))!=1)}setFunctionModule(a,n,i){this.modules[n][a]=i,this.isFunction[n][a]=!0}addEccAndInterleave(a){const n=this.version,i=this.errorCorrectionLevel;if(a.length!=S.getNumDataCodewords(n,i))throw new RangeError("Invalid argument");const r=S.NUM_ERROR_CORRECTION_BLOCKS[i.ordinal][n],m=S.ECC_CODEWORDS_PER_BLOCK[i.ordinal][n],d=Math.floor(S.getNumRawDataModules(n)/8),u=r-d%r,y=Math.floor(d/r);let j=[];const g=S.reedSolomonComputeDivisor(m);for(let x=0,N=0;x<r;x++){let E=a.slice(N,N+y-m+(x<u?0:1));N+=E.length;const z=S.reedSolomonComputeRemainder(E,g);x<u&&E.push(0),j.push(E.concat(z))}let C=[];for(let x=0;x<j[0].length;x++)j.forEach((N,E)=>{(x!=y-m||E>=u)&&C.push(N[x])});return c(C.length==d),C}drawCodewords(a){if(a.length!=Math.floor(S.getNumRawDataModules(this.version)/8))throw new RangeError("Invalid argument");let n=0;for(let i=this.size-1;i>=1;i-=2){i==6&&(i=5);for(let r=0;r<this.size;r++)for(let m=0;m<2;m++){const d=i-m,y=(i+1&2)==0?this.size-1-r:r;!this.isFunction[y][d]&&n<a.length*8&&(this.modules[y][d]=l(a[n>>>3],7-(n&7)),n++)}}c(n==a.length*8)}applyMask(a){if(a<0||a>7)throw new RangeError("Mask value out of range");for(let n=0;n<this.size;n++)for(let i=0;i<this.size;i++){let r;switch(a){case 0:r=(i+n)%2==0;break;case 1:r=n%2==0;break;case 2:r=i%3==0;break;case 3:r=(i+n)%3==0;break;case 4:r=(Math.floor(i/3)+Math.floor(n/2))%2==0;break;case 5:r=i*n%2+i*n%3==0;break;case 6:r=(i*n%2+i*n%3)%2==0;break;case 7:r=((i+n)%2+i*n%3)%2==0;break;default:throw new Error("Unreachable")}!this.isFunction[n][i]&&r&&(this.modules[n][i]=!this.modules[n][i])}}getPenaltyScore(){let a=0;for(let m=0;m<this.size;m++){let d=!1,u=0,y=[0,0,0,0,0,0,0];for(let j=0;j<this.size;j++)this.modules[m][j]==d?(u++,u==5?a+=S.PENALTY_N1:u>5&&a++):(this.finderPenaltyAddHistory(u,y),d||(a+=this.finderPenaltyCountPatterns(y)*S.PENALTY_N3),d=this.modules[m][j],u=1);a+=this.finderPenaltyTerminateAndCount(d,u,y)*S.PENALTY_N3}for(let m=0;m<this.size;m++){let d=!1,u=0,y=[0,0,0,0,0,0,0];for(let j=0;j<this.size;j++)this.modules[j][m]==d?(u++,u==5?a+=S.PENALTY_N1:u>5&&a++):(this.finderPenaltyAddHistory(u,y),d||(a+=this.finderPenaltyCountPatterns(y)*S.PENALTY_N3),d=this.modules[j][m],u=1);a+=this.finderPenaltyTerminateAndCount(d,u,y)*S.PENALTY_N3}for(let m=0;m<this.size-1;m++)for(let d=0;d<this.size-1;d++){const u=this.modules[m][d];u==this.modules[m][d+1]&&u==this.modules[m+1][d]&&u==this.modules[m+1][d+1]&&(a+=S.PENALTY_N2)}let n=0;for(const m of this.modules)n=m.reduce((d,u)=>d+(u?1:0),n);const i=this.size*this.size,r=Math.ceil(Math.abs(n*20-i*10)/i)-1;return c(0<=r&&r<=9),a+=r*S.PENALTY_N4,c(0<=a&&a<=2568888),a}getAlignmentPatternPositions(){if(this.version==1)return[];{const a=Math.floor(this.version/7)+2,n=this.version==32?26:Math.ceil((this.version*4+4)/(a*2-2))*2;let i=[6];for(let r=this.size-7;i.length<a;r-=n)i.splice(1,0,r);return i}}static getNumRawDataModules(a){if(a<S.MIN_VERSION||a>S.MAX_VERSION)throw new RangeError("Version number out of range");let n=(16*a+128)*a+64;if(a>=2){const i=Math.floor(a/7)+2;n-=(25*i-10)*i-55,a>=7&&(n-=36)}return c(208<=n&&n<=29648),n}static getNumDataCodewords(a,n){return Math.floor(S.getNumRawDataModules(a)/8)-S.ECC_CODEWORDS_PER_BLOCK[n.ordinal][a]*S.NUM_ERROR_CORRECTION_BLOCKS[n.ordinal][a]}static reedSolomonComputeDivisor(a){if(a<1||a>255)throw new RangeError("Degree out of range");let n=[];for(let r=0;r<a-1;r++)n.push(0);n.push(1);let i=1;for(let r=0;r<a;r++){for(let m=0;m<n.length;m++)n[m]=S.reedSolomonMultiply(n[m],i),m+1<n.length&&(n[m]^=n[m+1]);i=S.reedSolomonMultiply(i,2)}return n}static reedSolomonComputeRemainder(a,n){let i=n.map(r=>0);for(const r of a){const m=r^i.shift();i.push(0),n.forEach((d,u)=>i[u]^=S.reedSolomonMultiply(d,m))}return i}static reedSolomonMultiply(a,n){if(a>>>8||n>>>8)throw new RangeError("Byte out of range");let i=0;for(let r=7;r>=0;r--)i=i<<1^(i>>>7)*285,i^=(n>>>r&1)*a;return c(i>>>8==0),i}finderPenaltyCountPatterns(a){const n=a[1];c(n<=this.size*3);const i=n>0&&a[2]==n&&a[3]==n*3&&a[4]==n&&a[5]==n;return(i&&a[0]>=n*4&&a[6]>=n?1:0)+(i&&a[6]>=n*4&&a[0]>=n?1:0)}finderPenaltyTerminateAndCount(a,n,i){return a&&(this.finderPenaltyAddHistory(n,i),n=0),n+=this.size,this.finderPenaltyAddHistory(n,i),this.finderPenaltyCountPatterns(i)}finderPenaltyAddHistory(a,n){n[0]==0&&(a+=this.size),n.pop(),n.unshift(a)}};o.MIN_VERSION=1,o.MAX_VERSION=40,o.PENALTY_N1=3,o.PENALTY_N2=3,o.PENALTY_N3=40,o.PENALTY_N4=10,o.ECC_CODEWORDS_PER_BLOCK=[[-1,7,10,15,20,26,18,20,24,30,18,20,24,26,30,22,24,28,30,28,28,28,28,30,30,26,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,10,16,26,18,24,16,18,22,22,26,30,22,22,24,24,28,28,26,26,26,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28],[-1,13,22,18,26,18,24,18,22,20,24,28,26,24,20,30,24,28,28,26,30,28,30,30,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,17,28,22,16,22,28,26,26,24,28,24,28,22,24,24,30,28,28,26,28,30,24,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30]],o.NUM_ERROR_CORRECTION_BLOCKS=[[-1,1,1,1,1,1,2,2,2,2,4,4,4,4,4,6,6,6,6,7,8,8,9,9,10,12,12,12,13,14,15,16,17,18,19,19,20,21,22,24,25],[-1,1,1,1,2,2,4,4,4,5,5,5,8,9,9,10,10,11,13,14,16,17,17,18,20,21,23,25,26,28,29,31,33,35,37,38,40,43,45,47,49],[-1,1,1,2,2,4,4,6,6,8,8,8,10,12,16,12,17,16,18,21,20,23,23,25,27,29,34,34,35,38,40,43,45,48,51,53,56,59,62,65,68],[-1,1,1,2,4,4,4,5,6,8,8,11,11,16,16,18,16,19,21,25,25,25,34,30,32,35,37,40,42,45,48,51,54,57,60,63,66,70,74,77,81]],t.QrCode=o;function s(f,a,n){if(a<0||a>31||f>>>a)throw new RangeError("Value out of range");for(let i=a-1;i>=0;i--)n.push(f>>>i&1)}function l(f,a){return(f>>>a&1)!=0}function c(f){if(!f)throw new Error("Assertion error")}const h=class R{constructor(a,n,i){if(this.mode=a,this.numChars=n,this.bitData=i,n<0)throw new RangeError("Invalid argument");this.bitData=i.slice()}static makeBytes(a){let n=[];for(const i of a)s(i,8,n);return new R(R.Mode.BYTE,a.length,n)}static makeNumeric(a){if(!R.isNumeric(a))throw new RangeError("String contains non-numeric characters");let n=[];for(let i=0;i<a.length;){const r=Math.min(a.length-i,3);s(parseInt(a.substring(i,i+r),10),r*3+1,n),i+=r}return new R(R.Mode.NUMERIC,a.length,n)}static makeAlphanumeric(a){if(!R.isAlphanumeric(a))throw new RangeError("String contains unencodable characters in alphanumeric mode");let n=[],i;for(i=0;i+2<=a.length;i+=2){let r=R.ALPHANUMERIC_CHARSET.indexOf(a.charAt(i))*45;r+=R.ALPHANUMERIC_CHARSET.indexOf(a.charAt(i+1)),s(r,11,n)}return i<a.length&&s(R.ALPHANUMERIC_CHARSET.indexOf(a.charAt(i)),6,n),new R(R.Mode.ALPHANUMERIC,a.length,n)}static makeSegments(a){return a==""?[]:R.isNumeric(a)?[R.makeNumeric(a)]:R.isAlphanumeric(a)?[R.makeAlphanumeric(a)]:[R.makeBytes(R.toUtf8ByteArray(a))]}static makeEci(a){let n=[];if(a<0)throw new RangeError("ECI assignment value out of range");if(a<128)s(a,8,n);else if(a<16384)s(2,2,n),s(a,14,n);else if(a<1e6)s(6,3,n),s(a,21,n);else throw new RangeError("ECI assignment value out of range");return new R(R.Mode.ECI,0,n)}static isNumeric(a){return R.NUMERIC_REGEX.test(a)}static isAlphanumeric(a){return R.ALPHANUMERIC_REGEX.test(a)}getData(){return this.bitData.slice()}static getTotalBits(a,n){let i=0;for(const r of a){const m=r.mode.numCharCountBits(n);if(r.numChars>=1<<m)return 1/0;i+=4+m+r.bitData.length}return i}static toUtf8ByteArray(a){a=encodeURI(a);let n=[];for(let i=0;i<a.length;i++)a.charAt(i)!="%"?n.push(a.charCodeAt(i)):(n.push(parseInt(a.substring(i+1,i+3),16)),i+=2);return n}};h.NUMERIC_REGEX=/^[0-9]*$/,h.ALPHANUMERIC_REGEX=/^[A-Z0-9 $%*+.\/:-]*$/,h.ALPHANUMERIC_CHARSET="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";let p=h;t.QrSegment=h})(se||(se={}));(t=>{(o=>{const s=class{constructor(c,h){this.ordinal=c,this.formatBits=h}};s.LOW=new s(0,1),s.MEDIUM=new s(1,0),s.QUARTILE=new s(2,3),s.HIGH=new s(3,2),o.Ecc=s})(t.QrCode||(t.QrCode={}))})(se||(se={}));(t=>{(o=>{const s=class{constructor(c,h){this.modeBits=c,this.numBitsCharCount=h}numCharCountBits(c){return this.numBitsCharCount[Math.floor((c+7)/17)]}};s.NUMERIC=new s(1,[10,12,14]),s.ALPHANUMERIC=new s(2,[9,11,13]),s.BYTE=new s(4,[8,16,16]),s.KANJI=new s(8,[8,10,12]),s.ECI=new s(7,[0,0,0]),o.Mode=s})(t.QrSegment||(t.QrSegment={}))})(se||(se={}));var oe=se;/**
36
- * @license qrcode.react
37
- * Copyright (c) Paul O'Shannessy
38
- * SPDX-License-Identifier: ISC
39
- */var Is={L:oe.QrCode.Ecc.LOW,M:oe.QrCode.Ecc.MEDIUM,Q:oe.QrCode.Ecc.QUARTILE,H:oe.QrCode.Ecc.HIGH},Nt=128,Ct="L",Et="#FFFFFF",kt="#000000",St=!1,Mt=1,Ls=4,$s=0,Bs=.1;function Pt(t,o=0){const s=[];return t.forEach(function(l,c){let h=null;l.forEach(function(p,f){if(!p&&h!==null){s.push(`M${h+o} ${c+o}h${f-h}v1H${h+o}z`),h=null;return}if(f===l.length-1){if(!p)return;h===null?s.push(`M${f+o},${c+o} h1v1H${f+o}z`):s.push(`M${h+o},${c+o} h${f+1-h}v1H${h+o}z`);return}p&&h===null&&(h=f)})}),s.join("")}function Ft(t,o){return t.slice().map((s,l)=>l<o.y||l>=o.y+o.h?s:s.map((c,h)=>h<o.x||h>=o.x+o.w?c:!1))}function Ds(t,o,s,l){if(l==null)return null;const c=t.length+s*2,h=Math.floor(o*Bs),p=c/o,f=(l.width||h)*p,a=(l.height||h)*p,n=l.x==null?t.length/2-f/2:l.x*p,i=l.y==null?t.length/2-a/2:l.y*p,r=l.opacity==null?1:l.opacity;let m=null;if(l.excavate){let u=Math.floor(n),y=Math.floor(i),j=Math.ceil(f+n-u),g=Math.ceil(a+i-y);m={x:u,y,w:j,h:g}}const d=l.crossOrigin;return{x:n,y:i,h:a,w:f,excavation:m,opacity:r,crossOrigin:d}}function Os(t,o){return o!=null?Math.max(Math.floor(o),0):t?Ls:$s}function At({value:t,level:o,minVersion:s,includeMargin:l,marginSize:c,imageSettings:h,size:p,boostLevel:f}){let a=$.useMemo(()=>{const u=(Array.isArray(t)?t:[t]).reduce((y,j)=>(y.push(...oe.QrSegment.makeSegments(j)),y),[]);return oe.QrCode.encodeSegments(u,Is[o],s,void 0,void 0,f)},[t,o,s,f]);const{cells:n,margin:i,numCells:r,calculatedImageSettings:m}=$.useMemo(()=>{let d=a.getModules();const u=Os(l,c),y=d.length+u*2,j=Ds(d,p,u,h);return{cells:d,margin:u,numCells:y,calculatedImageSettings:j}},[a,p,h,l,c]);return{qrcode:a,margin:i,cells:n,numCells:r,calculatedImageSettings:m}}var _s=(function(){try{new Path2D().addPath(new Path2D)}catch{return!1}return!0})(),zs=$.forwardRef(function(o,s){const l=o,{value:c,size:h=Nt,level:p=Ct,bgColor:f=Et,fgColor:a=kt,includeMargin:n=St,minVersion:i=Mt,boostLevel:r,marginSize:m,imageSettings:d}=l,y=Ye(l,["value","size","level","bgColor","fgColor","includeMargin","minVersion","boostLevel","marginSize","imageSettings"]),{style:j}=y,g=Ye(y,["style"]),C=d==null?void 0:d.src,x=$.useRef(null),N=$.useRef(null),E=$.useCallback(q=>{x.current=q,typeof s=="function"?s(q):s&&(s.current=q)},[s]),[z,P]=$.useState(!1),{margin:A,cells:T,numCells:I,calculatedImageSettings:L}=At({value:c,level:p,minVersion:i,boostLevel:r,includeMargin:n,marginSize:m,imageSettings:d,size:h});$.useEffect(()=>{if(x.current!=null){const q=x.current,W=q.getContext("2d");if(!W)return;let me=T;const ee=N.current,Me=L!=null&&ee!==null&&ee.complete&&ee.naturalHeight!==0&&ee.naturalWidth!==0;Me&&L.excavation!=null&&(me=Ft(T,L.excavation));const Pe=window.devicePixelRatio||1;q.height=q.width=h*Pe;const Fe=h/I*Pe;W.scale(Fe,Fe),W.fillStyle=f,W.fillRect(0,0,I,I),W.fillStyle=a,_s?W.fill(new Path2D(Pt(me,A))):T.forEach(function(ue,Ae){ue.forEach(function(_e,Te){_e&&W.fillRect(Te+A,Ae+A,1,1)})}),L&&(W.globalAlpha=L.opacity),Me&&W.drawImage(ee,L.x+A,L.y+A,L.w,L.h)}}),$.useEffect(()=>{P(!1)},[C]);const Y=Je({height:h,width:h},j);let _=null;return C!=null&&(_=$.createElement("img",{src:C,key:C,style:{display:"none"},onLoad:()=>{P(!0)},ref:N,crossOrigin:L==null?void 0:L.crossOrigin})),$.createElement($.Fragment,null,$.createElement("canvas",Je({style:Y,height:h,width:h,ref:E,role:"img"},g)),_)});zs.displayName="QRCodeCanvas";var Tt=$.forwardRef(function(o,s){const l=o,{value:c,size:h=Nt,level:p=Ct,bgColor:f=Et,fgColor:a=kt,includeMargin:n=St,minVersion:i=Mt,boostLevel:r,title:m,marginSize:d,imageSettings:u}=l,y=Ye(l,["value","size","level","bgColor","fgColor","includeMargin","minVersion","boostLevel","title","marginSize","imageSettings"]),{margin:j,cells:g,numCells:C,calculatedImageSettings:x}=At({value:c,level:p,minVersion:i,boostLevel:r,includeMargin:n,marginSize:d,imageSettings:u,size:h});let N=g,E=null;u!=null&&x!=null&&(x.excavation!=null&&(N=Ft(g,x.excavation)),E=$.createElement("image",{href:u.src,height:x.h,width:x.w,x:x.x+j,y:x.y+j,preserveAspectRatio:"none",opacity:x.opacity,crossOrigin:x.crossOrigin}));const z=Pt(N,j);return $.createElement("svg",Je({height:h,width:h,viewBox:`0 0 ${C} ${C}`,ref:s,role:"img"},y),!!m&&$.createElement("title",null,m),$.createElement("path",{fill:f,d:`M0,0 h${C}v${C}H0z`,shapeRendering:"crispEdges"}),$.createElement("path",{fill:a,d:z,shapeRendering:"crispEdges"}),E)});Tt.displayName="QRCodeSVG";const Le=1500;async function he(t,o){try{return(await t.json()).error??o}catch{return o}}function Rt({open:t,onOpenChange:o,accountId:s,accountName:l}){const{t:c}=F(),h=O(),[p,f]=w.useState(null),[a,n]=w.useState("starting"),[i,r]=w.useState(null),m=w.useRef(null),d=w.useRef(0),u=w.useRef(null),y=w.useCallback(()=>{m.current!==null&&(clearTimeout(m.current),m.current=null)},[]),j=w.useCallback(()=>{var P;y(),(P=u.current)==null||P.abort(),u.current=null,d.current+=1},[y]),g=w.useCallback(async()=>{j(),await h.invalidateQueries({queryKey:["weixin-accounts"]}),b.success(c("weixin.bindSuccess")),o(!1)},[j,o,h,c]),C=w.useCallback(async(P,A,T)=>{try{const I=await fetch(`/api/settings/weixin/accounts/${s}/users`,{signal:A});if(d.current!==P)return;if(!I.ok)throw new Error(await he(I,c("weixin.loginFailed")));const L=await I.json();if(d.current!==P)return;const Y=L.users.find(_=>!T.has(_.userId)||_.lastInboundAt!==T.get(_.userId));if(Y){if(n("binding"),r(c("weixin.bindingInProgress")),Y.status==="pending"){const _=await fetch(`/api/settings/weixin/accounts/${s}/users/${encodeURIComponent(Y.userId)}/approve`,{method:"POST",signal:A});if(d.current!==P)return;if(!_.ok)throw new Error(await he(_,c("weixin.approveFailed")))}await g();return}m.current=setTimeout(()=>void C(P,A,T),Le)}catch(I){if(A.aborted||d.current!==P)return;n("error"),r(I instanceof Error?I.message:c("weixin.loginFailed"))}},[s,g,c]),x=w.useCallback(async(P,A)=>{try{const T=await fetch(`/api/settings/weixin/accounts/${s}/login/status`,{signal:A});if(d.current!==P)return;if(!T.ok)throw new Error(await he(T,c("weixin.loginFailed")));const I=await T.json();if(d.current!==P)return;if(I.status==="expired"){n("expired"),r(c("weixin.loginExpired"));return}if(I.status==="error"){n("error"),r(c("weixin.loginError",{message:I.message??""}));return}if(I.loggedIn||I.status==="confirmed"){const L=await fetch(`/api/settings/weixin/accounts/${s}/users`,{signal:A});if(d.current!==P)return;if(!L.ok)throw new Error(await he(L,c("weixin.loginFailed")));const Y=await L.json();if(d.current!==P)return;const _=new Map(Y.users.map(q=>[q.userId,q.lastInboundAt]));n("awaitMessage"),r(c("weixin.scanConfirmedSendHint")),m.current=setTimeout(()=>void C(P,A,_),Le);return}n("scanning"),r(c("weixin.scanQrcodeHint")),m.current=setTimeout(()=>void x(P,A),Le)}catch(T){if(A.aborted||d.current!==P)return;n("error"),r(T instanceof Error?T.message:c("weixin.loginFailed"))}},[s,C,c]),N=w.useCallback(async()=>{j();const P=d.current,A=new AbortController;u.current=A,n("starting"),r(null),f(null);try{const T=await fetch(`/api/settings/weixin/accounts/${s}/login/start`,{method:"POST",signal:A.signal});if(d.current!==P)return;if(!T.ok)throw new Error(await he(T,c("weixin.loginFailed")));const I=await T.json();if(d.current!==P)return;f(I.qrcodeUrl),n("scanning"),r(c("weixin.scanQrcodeHint")),m.current=setTimeout(()=>void x(P,A.signal),Le)}catch(T){if(A.signal.aborted||d.current!==P)return;n("error"),r(T instanceof Error?T.message:c("weixin.loginFailed"))}},[s,j,x,c]);w.useEffect(()=>{if(!t){j();return}return N(),j},[t,s]);const E=a==="starting",z=a==="expired"||a==="error";return e.jsx(ae,{open:t,onOpenChange:o,children:e.jsxs(ne,{className:"sm:max-w-sm","data-testid":`weixin-account-login-modal-${s}`,children:[e.jsxs(ie,{children:[e.jsx(re,{children:c("weixin.scanToLogin")}),e.jsx(Ne,{children:l})]}),e.jsxs("div",{className:"flex flex-col items-center gap-3 py-2",children:[e.jsxs("div",{className:"flex h-56 w-56 items-center justify-center rounded-lg border border-border bg-white",children:[E&&e.jsx(U,{className:"h-8 w-8 animate-spin text-muted-foreground"}),!E&&p&&e.jsx(Tt,{value:p,size:208,marginSize:3,"data-testid":`weixin-account-login-qrcode-${s}`}),!E&&!p&&e.jsx(Ge,{className:"h-10 w-10 text-muted-foreground"})]}),i&&e.jsx("p",{className:"text-center text-sm font-medium","data-testid":`weixin-account-login-status-${s}`,children:i})]}),e.jsxs(de,{children:[z&&e.jsxs(k,{variant:"secondary","data-testid":"weixin-account-login-refresh",onClick:()=>void N(),children:[e.jsx(tt,{className:"h-4 w-4"}),c("weixin.refreshQrcode")]}),e.jsx(k,{variant:"outline",onClick:()=>o(!1),children:c("weixin.closeLogin")})]})]})})}const qs="min-h-10";async function gt(t,o){try{return(await t.json()).error??o}catch{return o}}function Ks({open:t,onOpenChange:o,account:s}){const{t:l}=F(),c=O(),h=!!s,[p,f]=w.useState(""),[a,n]=w.useState(!0),[i,r]=w.useState(null);w.useEffect(()=>{t&&(f((s==null?void 0:s.name)??""),n((s==null?void 0:s.enabled)??!0))},[t,s]);const m=M({mutationFn:async()=>{const g=await fetch("/api/settings/weixin/accounts",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:p.trim(),enabled:a,allowAuthRequests:!0})});if(!g.ok)throw new Error(await gt(g,l("weixin.createFailed")));return await g.json()},onSuccess:async g=>{await c.invalidateQueries({queryKey:["weixin-accounts"]}),b.success(l("weixin.accountCreated")),o(!1),r({id:g.accountId,name:p.trim()})},onError:g=>{b.error(g instanceof Error?g.message:l("common.error"))}}),d=M({mutationFn:async()=>{if(!s)throw new Error(l("weixin.updateFailed"));const g=await fetch(`/api/settings/weixin/accounts/${s.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:p.trim(),enabled:a})});if(!g.ok)throw new Error(await gt(g,l("weixin.updateFailed")))},onSuccess:async()=>{await c.invalidateQueries({queryKey:["weixin-accounts"]}),b.success(l("weixin.accountUpdated")),o(!1)},onError:g=>{b.error(g instanceof Error?g.message:l("common.error"))}}),u=m.isPending||d.isPending,y=p.trim().length>0,j=()=>{!y||u||(h?d.mutate():m.mutate())};return e.jsxs(e.Fragment,{children:[e.jsx(ae,{open:t,onOpenChange:o,children:e.jsxs(ne,{className:"sm:max-w-lg","data-testid":h?`weixin-account-edit-modal-${s==null?void 0:s.id}`:"weixin-account-add-modal",children:[e.jsx(ie,{children:e.jsx(re,{children:l(h?"weixin.editAccount":"weixin.addAccount")})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"weixin-account-name",children:l("weixin.accountName")}),e.jsx(B,{id:"weixin-account-name","data-testid":"weixin-account-name-input",value:p,onChange:g=>f(g.target.value),placeholder:l("weixin.accountNamePlaceholder"),className:qs})]}),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:l("weixin.enableAccount")}),e.jsx(D,{checked:a,"data-testid":"weixin-account-enabled",onCheckedChange:g=>n(!!g)})]})]}),e.jsxs(de,{children:[e.jsx(k,{variant:"outline",onClick:()=>o(!1),disabled:u,children:l("common.cancel")}),e.jsxs(k,{variant:"secondary","data-testid":"weixin-account-form-submit",onClick:j,disabled:!y||u,children:[u?e.jsx(U,{className:"h-4 w-4 animate-spin"}):e.jsx(Z,{className:"h-4 w-4"}),l("common.save")]})]})]})}),i&&e.jsx(Rt,{open:!!i,onOpenChange:g=>{g||r(null)},accountId:i.id,accountName:i.name})]})}async function Ve(t,o){try{return(await t.json()).error??o}catch{return o}}function Qs({account:t,onEdit:o}){const{t:s}=F(),l=O(),[c,h]=w.useState(!1),p=t.loggedIn&&t.authorizedCount>0,f=M({mutationFn:async r=>{const m=await fetch(`/api/settings/weixin/accounts/${t.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({enabled:r})});if(!m.ok)throw new Error(await Ve(m,s("weixin.updateFailed")))},onSuccess:async()=>{await l.invalidateQueries({queryKey:["weixin-accounts"]})},onError:r=>{b.error(r instanceof Error?r.message:s("common.error"))}}),a=M({mutationFn:async()=>{const r=await fetch(`/api/settings/weixin/accounts/${t.id}/test`,{method:"POST"});if(!r.ok)throw new Error(await Ve(r,s("weixin.testMessageFailed")))},onSuccess:()=>{b.success(s("weixin.testMessageSent"))},onError:r=>{b.error(r instanceof Error?r.message:s("weixin.testMessageFailed"))}}),n=M({mutationFn:async()=>{const r=await fetch(`/api/settings/weixin/accounts/${t.id}`,{method:"DELETE"});if(!r.ok)throw new Error(await Ve(r,s("weixin.deleteFailed")))},onSuccess:async()=>{await l.invalidateQueries({queryKey:["weixin-accounts"]}),b.success(s("weixin.accountDeleted"))},onError:r=>{b.error(r instanceof Error?r.message:s("common.error"))}}),i=t.loggedIn?p?{label:s("weixin.bound"),tone:"success"}:{label:s("weixin.unbound"),tone:"muted"}:{label:s("weixin.notLoggedIn"),tone:"muted"};return e.jsxs("div",{className:"flex flex-col gap-3 rounded-lg border border-border bg-card p-3 sm:flex-row sm:items-center sm:justify-between","data-testid":`weixin-account-card-${t.id}`,"data-account-name":t.name,children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[e.jsx(D,{checked:t.enabled,disabled:f.isPending,onCheckedChange:r=>f.mutate(!!r),"data-testid":`weixin-account-enabled-${t.id}`}),e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"truncate font-medium",children:t.name}),e.jsx("span",{className:ft("shrink-0 rounded px-1.5 py-0.5 text-xs font-medium",i.tone==="success"?"bg-emerald-500/15 text-emerald-600 dark:text-emerald-400":"bg-muted text-muted-foreground"),"data-testid":`weixin-account-login-state-${t.id}`,children:i.label}),p&&t.needsReactivationCount>0&&e.jsxs("span",{className:"flex shrink-0 items-center gap-1 rounded bg-destructive/15 px-1.5 py-0.5 text-xs font-medium text-destructive",title:s("weixin.reactivationHint"),"data-testid":`weixin-account-needs-reactivation-${t.id}`,children:[e.jsx(jt,{className:"h-3.5 w-3.5"}),s("weixin.needsReactivation")]})]}),p&&t.needsReactivationCount>0&&e.jsx("div",{className:"mt-0.5 text-xs text-muted-foreground",children:s("weixin.reactivationHint")})]})]}),e.jsxs("div",{className:"flex shrink-0 flex-wrap items-center justify-end gap-1",children:[p?e.jsxs(e.Fragment,{children:[e.jsxs(k,{variant:"ghost",size:"sm","data-testid":`weixin-account-relogin-${t.id}`,onClick:()=>h(!0),children:[e.jsx(Ge,{className:"h-4 w-4"}),s("weixin.relogin")]}),e.jsxs(k,{variant:"ghost",size:"sm","data-testid":`weixin-account-test-${t.id}`,onClick:()=>a.mutate(),disabled:a.isPending,children:[e.jsx(yt,{className:"h-4 w-4"}),s("weixin.testMessage")]})]}):e.jsxs(k,{variant:"secondary",size:"sm","data-testid":`weixin-account-login-${t.id}`,onClick:()=>h(!0),children:[e.jsx(Ge,{className:"h-4 w-4"}),s("weixin.bindAction")]}),e.jsx(k,{variant:"ghost",size:"icon-sm",title:s("common.edit"),"data-testid":`weixin-account-edit-${t.id}`,onClick:()=>o(t),children:e.jsx(De,{className:"h-4 w-4"})}),e.jsx(k,{variant:"ghost",size:"icon-sm",title:s("weixin.deleteAccount"),"data-testid":`weixin-account-delete-${t.id}`,onClick:()=>n.mutate(),disabled:n.isPending,children:e.jsx(te,{className:"h-4 w-4 text-destructive"})})]}),e.jsx(Rt,{open:c,onOpenChange:h,accountId:t.id,accountName:t.name})]})}async function Us(t,o){try{return(await t.json()).error??o}catch{return o}}function Hs(){var n;const{t}=F(),[o,s]=w.useState(!1),[l,c]=w.useState(void 0),h=Q({queryKey:["weixin-accounts"],queryFn:async()=>{const i=await fetch("/api/settings/weixin/accounts");if(!i.ok)throw new Error(await Us(i,t("weixin.loadAccountsFailed")));return await i.json()}}),p=((n=h.data)==null?void 0:n.accounts)??[],f=()=>{c(void 0),s(!0)},a=i=>{c(i),s(!0)};return e.jsxs(e.Fragment,{children:[e.jsxs(H,{className:"border-0 ring-0",children:[e.jsxs(G,{className:"flex flex-row items-start justify-between gap-2",children:[e.jsxs("div",{className:"min-w-0 space-y-1",children:[e.jsx(J,{children:t("weixin.title")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:t("weixin.subtitle")})]}),e.jsxs(k,{variant:"secondary","data-testid":"weixin-add-account",onClick:f,children:[e.jsx(ge,{className:"h-4 w-4"}),t("weixin.addAccount")]})]}),e.jsxs(V,{className:"space-y-3",children:[e.jsx("p",{className:"rounded-lg border border-border bg-muted/40 p-3 text-xs text-muted-foreground",children:t("weixin.replyOnlyNotice")}),h.isLoading&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("common.loading")}),!h.isLoading&&p.length===0&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("weixin.noAccounts")}),p.map(i=>e.jsx(Qs,{account:i,onEdit:a},i.id))]})]}),e.jsx(Ks,{open:o,onOpenChange:s,account:l})]})}async function Xe(t,o){try{return(await t.json()).error??o}catch{return o}}function na(){var st,at;const{t}=F(),o=O(),{refreshSettings:s}=Oe(),[l,c]=w.useState("general"),h=nt(v=>v.theme),p=nt(v=>v.setTheme),f=h==="dark",[a,n]=w.useState("tmex"),[i,r]=w.useState(window.location.origin),[m,d]=w.useState("en_US"),[u,y]=w.useState(6),[j,g]=w.useState(3),[C,x]=w.useState(!0),[N,E]=w.useState(!0),[z,P]=w.useState(!0),[A,T]=w.useState(!0),[I,L]=w.useState(!1),[Y,_]=w.useState(!1),[q,W]=w.useState(2),[me,ee]=w.useState(10),[Me,Pe]=w.useState(!1),Fe=v=>{const K=v?"dark":"light";p(K),document.documentElement.classList.toggle("dark",K==="dark")},ue=Q({queryKey:["site-settings"],queryFn:async()=>{const v=await fetch("/api/settings/site");if(!v.ok)throw new Error(await Xe(v,t("settings.loadFailed")));return await v.json()}});w.useEffect(()=>{var K;const v=(K=ue.data)==null?void 0:K.settings;v&&(n(v.siteName),r(v.siteUrl),d(v.language??"en_US"),y(v.bellThrottleSeconds),g(v.notificationThrottleSeconds??3),x(v.enableBrowserBellToast??!0),E(v.enableBrowserNotificationToast??!0),P(v.enableTelegramBellPush??!0),T(v.enableTelegramNotificationPush??!0),L(v.enableWeixinBellPush??!1),_(v.enableWeixinNotificationPush??!1),W(v.sshReconnectMaxRetries),ee(v.sshReconnectDelaySeconds))},[(st=ue.data)==null?void 0:st.settings]);const Ae=M({mutationFn:async()=>{const K=await fetch("/api/settings/site",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({siteName:a,siteUrl:i,language:m,bellThrottleSeconds:u,notificationThrottleSeconds:j,enableBrowserBellToast:C,enableBrowserNotificationToast:N,enableTelegramBellPush:z,enableTelegramNotificationPush:A,enableWeixinBellPush:I,enableWeixinNotificationPush:Y,sshReconnectMaxRetries:q,sshReconnectDelaySeconds:me})});if(!K.ok)throw new Error(await Xe(K,t("settings.saveFailed")))},onSuccess:async()=>{var v,K;await Promise.all([o.invalidateQueries({queryKey:["site-settings"]}),s()]),b.success(t("settings.settingsSaved")),((K=(v=ue.data)==null?void 0:v.settings)==null?void 0:K.language)!==m&&(Ht.changeLanguage(m),Pe(!0))},onError:v=>{b.error(v instanceof Error?v.message:t("common.error"))}}),_e=[{value:"general",label:t("settings.tabGroup.general"),icon:Ot,testId:"settings-tab-general"},{value:"terminal",label:t("settings.tabGroup.terminal"),icon:Ze,testId:"settings-tab-terminal"},{value:"devicesAndFiles",label:t("settings.tabGroup.devicesAndFiles"),icon:rs,testId:"settings-tab-devicesAndFiles"},{value:"notifications",label:t("settings.tabGroup.notifications"),icon:_t,testId:"settings-tab-notifications"},{value:"ai",label:t("settings.tabGroup.ai"),icon:zt,testId:"settings-tab-ai"}],Te=e.jsx("div",{className:"flex justify-end pt-2",children:e.jsxs(k,{variant:"secondary","data-testid":"settings-save",onClick:()=>Ae.mutate(),disabled:Ae.isPending,className:"w-full sm:w-auto",children:[e.jsx(Z,{className:"h-4 w-4"}),t("common.save")]})});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.jsx(qt,{value:l,onValueChange:v=>c(v),children:e.jsx(Kt,{className:"w-full gap-1 !justify-start overflow-x-auto rounded-xl border border-border/60 p-1.5 group-data-horizontal/tabs:h-12 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",children:_e.map(v=>{const K=v.icon;return e.jsxs(Qt,{value:v.value,"data-testid":v.testId,className:ft(Ut,"min-w-max gap-2 px-3.5"),children:[e.jsx(K,{}),v.label]},v.value)})})}),l==="general"&&e.jsxs(e.Fragment,{children:[e.jsxs(H,{className:"border-0 ring-0",children:[e.jsx(G,{children:e.jsx(J,{children:t("settings.siteSettings")})}),e.jsxs(V,{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:t("settings.siteName")}),e.jsx(B,{id:"site-name-input",value:a,onChange:v=>n(v.target.value),placeholder:t("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:t("settings.siteUrl")}),e.jsx(B,{id:"site-url-input",value:i,onChange:v=>r(v.target.value),placeholder:t("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:t("settings.language")}),e.jsxs(Ce,{value:m,onValueChange:v=>{v&&d(v)},children:[e.jsx(Ee,{id:"language-select","data-testid":"settings-language-select",className:"w-full min-h-10",children:e.jsx(ke,{placeholder:t("settings.language"),children:((at=it.locales.find(v=>v.code===m))==null?void 0:at.nativeName)??m})}),e.jsx(Se,{className:"max-h-[var(--tmex-viewport-height)]",children:it.locales.map(v=>e.jsx(le,{value:v.code,children:v.nativeName},v.code))})]}),Me&&e.jsx("p",{className:"mt-1 text-xs text-primary","data-testid":"settings-refresh-notice",children:t("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:t("settings.theme")})}),e.jsx(D,{checked:f,onCheckedChange:v=>Fe(!!v),"data-testid":"settings-theme-toggle"})]})}),Te]})]}),e.jsx(As,{})]}),l==="devicesAndFiles"&&e.jsxs(e.Fragment,{children:[e.jsx(ds,{}),e.jsx(ms,{})]}),l==="notifications"&&e.jsxs(e.Fragment,{children:[e.jsx(H,{className:"border-0 ring-0",children:e.jsxs(V,{className:"space-y-6 pt-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:t("settings.enableBrowserBellToast")})}),e.jsx(D,{checked:C,onCheckedChange:v=>x(!!v),"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:t("settings.enableTelegramBellPush")})}),e.jsx(D,{checked:z,onCheckedChange:v=>P(!!v),"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:t("settings.enableBrowserNotificationToast")})}),e.jsx(D,{checked:N,onCheckedChange:v=>E(!!v),"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:t("settings.enableTelegramNotificationPush")})}),e.jsx(D,{checked:A,onCheckedChange:v=>T(!!v),"data-testid":"settings-enable-telegram-notification-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:t("settings.enableWeixinBellPush")})}),e.jsx(D,{checked:I,onCheckedChange:v=>L(!!v),"data-testid":"settings-enable-weixin-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:t("settings.enableWeixinNotificationPush")})}),e.jsx(D,{checked:Y,onCheckedChange:v=>_(!!v),"data-testid":"settings-enable-weixin-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:t("settings.bellThrottle")}),e.jsx(B,{id:"bell-throttle-input",type:"number",value:u,min:0,max:300,onChange:v=>y(Number(v.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:t("settings.notificationThrottle")}),e.jsx(B,{id:"notification-throttle-input",type:"number",value:j,min:0,max:300,onChange:v=>g(Number(v.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:t("settings.sshReconnectMaxRetries")}),e.jsx(B,{id:"ssh-reconnect-retries-input",type:"number",value:q,min:0,max:20,onChange:v=>W(Number(v.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:t("settings.sshReconnectDelay")}),e.jsx(B,{id:"ssh-reconnect-delay-input",type:"number",value:me,min:1,max:300,onChange:v=>ee(Number(v.target.value)),className:"min-h-10"})]})]}),Te]})}),e.jsx(Ps,{}),e.jsx(Hs,{}),e.jsx(Ts,{})]}),l==="ai"&&e.jsxs(e.Fragment,{children:[e.jsx(vs,{}),e.jsx(Cs,{})]}),l==="terminal"&&e.jsx(Fs,{})]})}function ia(){const{t}=F();return e.jsx(e.Fragment,{children:t("sidebar.settings")})}function ra(){const{t}=F(),[o,s]=w.useState(!1),l=M({mutationFn:async()=>{const c=await fetch("/api/settings/restart",{method:"POST"});if(!c.ok)throw new Error(await Xe(c,t("settings.restartFailed")))},onSuccess:()=>{b.success(t("settings.restartScheduled"))},onError:c=>{b.error(c instanceof Error?c.message:t("common.error"))}});return e.jsxs(e.Fragment,{children:[e.jsx(k,{variant:"ghost",size:"icon-sm",onClick:()=>s(!0),disabled:l.isPending,"aria-label":t("settings.restartGateway"),title:t("settings.restartGateway"),className:"text-destructive hover:text-destructive hover:bg-destructive/10",children:e.jsx(Zt,{className:"h-4 w-4"})}),e.jsx(xe,{open:o,onOpenChange:s,children:e.jsxs(fe,{children:[e.jsxs(pe,{children:[e.jsx(we,{children:t("settings.restartGateway")}),e.jsx(ye,{children:t("settings.restartConfirm")})]}),e.jsxs(je,{children:[e.jsx(ve,{onClick:()=>s(!1),children:t("common.cancel")}),e.jsx(be,{variant:"destructive",onClick:()=>{l.mutate(),s(!1)},children:t("common.confirm")})]})]})})]})}export{ra as PageActions,ia as PageTitle,na as default};
@@ -1,38 +0,0 @@
1
- import{Y as _,r as N,j as e,X as C,u as k,an as Y,ao as ee,ap as te,aq as se,ar as ne,am as F,as as B,at as H,B as y,G as be,M as ve,x as Ne,c as K,N as ye,O as ke,R as Ie,U as X,au as Ce,av as Se,V as re,v as Me,aw as _e,af as ze,ax as Te,ay as g,d as Ee,az as Be,aA as qe,P as $e,aB as Pe,a2 as Ae,aC as Re}from"./index-B3ddLSja.js";import{M as Fe,r as He}from"./index-iee3U_rD.js";import{K as Ke,S as Z}from"./send-DaOB9hLq.js";import{Z as ae}from"./zap-BFIAXPXd.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 Le=[["path",{d:"M12 5v14",key:"s699le"}],["path",{d:"m19 12-7 7-7-7",key:"1idqje"}]],Oe=_("arrow-down",Le);/**
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 We=[["path",{d:"M12 18V5",key:"adv99a"}],["path",{d:"M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4",key:"1e3is1"}],["path",{d:"M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5",key:"1gqd8o"}],["path",{d:"M17.997 5.125a4 4 0 0 1 2.526 5.77",key:"iwvgf7"}],["path",{d:"M18 18a4 4 0 0 0 2-7.464",key:"efp6ie"}],["path",{d:"M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517",key:"1gq6am"}],["path",{d:"M6 18a4 4 0 0 1-2-7.464",key:"k1g0md"}],["path",{d:"M6.003 5.125a4 4 0 0 0-2.526 5.77",key:"q97ue3"}]],Ge=_("brain",We);/**
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 Ue=[["path",{d:"M8 5h13",key:"1pao27"}],["path",{d:"M13 12h8",key:"h98zly"}],["path",{d:"M13 19h8",key:"c3s6r1"}],["path",{d:"M3 10a2 2 0 0 0 2 2h3",key:"1npucw"}],["path",{d:"M3 5v12a2 2 0 0 0 2 2h3",key:"x1gjn2"}]],Qe=_("list-tree",Ue);/**
17
- * @license lucide-react v0.564.0 - ISC
18
- *
19
- * This source code is licensed under the ISC license.
20
- * See the LICENSE file in the root directory of this source tree.
21
- */const Ve=[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]],Je=_("search",Ve);/**
22
- * @license lucide-react v0.564.0 - ISC
23
- *
24
- * This source code is licensed under the ISC license.
25
- * See the LICENSE file in the root directory of this source tree.
26
- */const Xe=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]],Ze=_("square",Xe);/**
27
- * @license lucide-react v0.564.0 - ISC
28
- *
29
- * This source code is licensed under the ISC license.
30
- * See the LICENSE file in the root directory of this source tree.
31
- */const De=[["path",{d:"M12 19h8",key:"baeox8"}],["path",{d:"m4 17 6-6-6-6",key:"1yngyt"}]],Ye=_("terminal",De);/**
32
- * @license lucide-react v0.564.0 - ISC
33
- *
34
- * This source code is licensed under the ISC license.
35
- * See the LICENSE file in the root directory of this source tree.
36
- */const et=[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z",key:"1ngwbx"}]],tt=_("wrench",et);function st(t){const s=t.split(`
37
- `),a=[];let d=[],o=!1;const i=()=>{const l=d.join(`
38
- `);l.trim()&&a.push(l),d=[]};for(const l of s){if(/^\s*(```|~~~)/.test(l)){o=!o,d.push(l);continue}if(!o&&l.trim()===""){i();continue}d.push(l)}return i(),a}const nt={a:({node:t,...s})=>e.jsx("a",{...s,target:"_blank",rel:"noopener noreferrer",className:"text-primary underline underline-offset-2 break-all"}),pre:({node:t,...s})=>e.jsx("pre",{...s,className:"bg-muted overflow-x-auto rounded-md p-2 font-mono text-xs leading-relaxed"}),code:({node:t,className:s,...a})=>e.jsx("code",{...a,className:C("bg-muted rounded px-1 font-mono text-xs",s)}),ul:({node:t,...s})=>e.jsx("ul",{...s,className:"list-disc pl-5"}),ol:({node:t,...s})=>e.jsx("ol",{...s,className:"list-decimal pl-5"}),blockquote:({node:t,...s})=>e.jsx("blockquote",{...s,className:"border-border text-muted-foreground border-l-2 pl-2"}),h1:({node:t,...s})=>e.jsx("h1",{...s,className:"text-base font-semibold"}),h2:({node:t,...s})=>e.jsx("h2",{...s,className:"text-sm font-semibold"}),h3:({node:t,...s})=>e.jsx("h3",{...s,className:"text-sm font-semibold"}),table:({node:t,...s})=>e.jsx("div",{className:"overflow-x-auto",children:e.jsx("table",{...s,className:"border-border w-full border-collapse border text-xs"})}),th:({node:t,...s})=>e.jsx("th",{...s,className:"border-border bg-muted border px-2 py-1 text-left"}),td:({node:t,...s})=>e.jsx("td",{...s,className:"border-border border px-2 py-1"})},rt=N.memo(function({content:s}){return e.jsx(Fe,{remarkPlugins:[He],components:nt,children:s})});function at({text:t,streaming:s=!1,className:a}){const d=N.useMemo(()=>st(t),[t]);return e.jsxs("div",{className:C("flex min-w-0 flex-col gap-2 text-sm leading-relaxed",a),children:[d.map((o,i)=>e.jsx(rt,{content:o},i)),s&&e.jsx("span",{"data-testid":"agent-streaming-cursor",className:"bg-foreground inline-block h-4 w-2 animate-pulse self-start"})]})}function ot({text:t,streaming:s=!1,className:a}){return e.jsx("div",{"data-testid":"agent-assistant-message",className:C("min-w-0 max-w-full self-start",a),children:e.jsx(at,{text:t,streaming:s})})}function it({text:t,streaming:s=!1,className:a}){const{t:d}=k();return e.jsxs(Y,{"data-testid":"agent-reasoning-block",className:C("min-w-0 max-w-full self-start",a),children:[e.jsxs(ee,{className:"text-muted-foreground hover:text-foreground group flex items-center gap-1 text-xs",children:[e.jsx(te,{className:"size-3 transition-transform group-data-[panel-open]:rotate-90"}),e.jsx(Ge,{className:"size-3"}),e.jsx("span",{children:d("agent.reasoning.title")}),s&&e.jsx(se,{className:"size-3 animate-spin"})]}),e.jsx(ne,{children:e.jsx("div",{className:"text-muted-foreground border-border mt-1 border-l-2 pl-2 text-xs whitespace-pre-wrap break-words",children:t})})]})}function M(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function L(t){if(typeof t=="string")return t;try{return JSON.stringify(t,null,2)}catch{return String(t)}}function dt(t){return M(t.output)&&typeof t.output.error=="string"?t.output.error:t.isError?L(t.output):null}function lt(t){switch(t){case"send_input":return e.jsx(Ke,{className:"size-3.5"});case"read_screen":return e.jsx(ve,{className:"size-3.5"});case"web_search":return e.jsx(Je,{className:"size-3.5"});case"fetch_url":return e.jsx(be,{className:"size-3.5"});default:return e.jsx(tt,{className:"size-3.5"})}}function E({label:t,text:s}){return e.jsxs(Y,{children:[e.jsxs(ee,{className:"text-muted-foreground hover:text-foreground group flex items-center gap-1 text-xs",children:[e.jsx(te,{className:"size-3 transition-transform group-data-[panel-open]:rotate-90"}),e.jsx("span",{children:t})]}),e.jsx(ne,{children:e.jsx("pre",{className:"bg-muted mt-1 max-h-64 overflow-auto rounded-md p-2 font-mono text-xs whitespace-pre-wrap break-all",children:s})})]})}function ct(t){if(typeof t!="string")return null;try{const s=JSON.parse(t);return Array.isArray(s)?s.filter(M).map(a=>({title:typeof a.title=="string"?a.title:"",url:typeof a.url=="string"?a.url:"",snippet:typeof a.snippet=="string"?a.snippet:""})).filter(a=>a.url):null}catch{return null}}function ut({call:t}){const{t:s}=k(),a=M(t.input)?t.input:{},d=typeof a.text=="string"?a.text:"",o=Array.isArray(a.keys)?a.keys.filter(u=>typeof u=="string"):[],i=M(t.output)?t.output:{},l=typeof i.screenTail=="string"?i.screenTail:"";return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[d&&e.jsx("pre",{className:"bg-muted max-h-40 overflow-auto rounded-md p-2 font-mono text-xs whitespace-pre-wrap break-all",children:d}),o.length>0&&e.jsx("div",{className:"flex flex-wrap items-center gap-1",children:o.map((u,c)=>e.jsx(Ne,{variant:"outline",className:"font-mono",children:u},`${c}-${u}`))}),l&&e.jsx(E,{label:s("agent.tool.result"),text:l})]})}function mt({call:t}){const{t:s}=k(),a=M(t.output)?t.output:{},d=typeof a.screen=="string"?a.screen:"";return d?e.jsx(E,{label:s("agent.tool.screen"),text:d}):null}function xt({call:t}){const{t:s}=k(),a=M(t.input)?t.input:{},d=typeof a.query=="string"?a.query:"",o=t.resolved&&!t.isError&&!t.denied?ct(t.output):null;return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[d&&e.jsxs("p",{className:"text-muted-foreground text-xs break-words",children:["“",d,"”"]}),o&&o.length>0&&e.jsx("ul",{className:"flex flex-col gap-1",children:o.map(i=>e.jsxs("li",{className:"min-w-0 text-xs",children:[e.jsx("a",{href:i.url,target:"_blank",rel:"noopener noreferrer",className:"text-primary block truncate underline underline-offset-2",title:i.title||i.url,children:i.title||i.url}),i.snippet&&e.jsx("p",{className:"text-muted-foreground line-clamp-2 break-words",children:i.snippet})]},i.url))}),t.resolved&&!t.isError&&!t.denied&&!o&&typeof t.output=="string"&&e.jsx(E,{label:s("agent.tool.result"),text:t.output})]})}function pt({call:t}){const{t:s}=k(),a=M(t.input)?t.input:{},d=typeof a.url=="string"?a.url:"",o=typeof t.output=="string"?t.output:"";return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[d&&e.jsx("a",{href:d,target:"_blank",rel:"noopener noreferrer",className:"text-primary block truncate text-xs underline underline-offset-2",title:d,children:d}),t.resolved&&!t.isError&&!t.denied&&o&&e.jsx(E,{label:s("agent.tool.result"),text:o})]})}const ft=/^[A-Za-z0-9+/]{256,}={0,2}$/,gt=/^https?:\/\/\S+\.(png|jpe?g|webp|gif)(\?\S*)?$/i;function ht(t){return typeof t!="string"||t.length===0?null:t.startsWith("data:image/")||gt.test(t)?t:ft.test(t.replace(/\s/g,""))?`data:image/png;base64,${t.replace(/\s/g,"")}`:null}function jt(t){if(!t.resolved||t.isError||t.denied)return[];const s=[],a=(d,o)=>{if(s.length>=8||o>3)return;const i=ht(d);if(i){s.push(i);return}if(Array.isArray(d)){for(const l of d)a(l,o+1);return}if(M(d))for(const l of["result","image","images","url","b64_json","data"])l in d&&a(d[l],o+1)};return a(t.output,0),[...new Set(s)]}function wt({images:t}){return t.length===0?null:e.jsx("div",{className:"flex flex-wrap gap-2",children:t.map((s,a)=>e.jsx("a",{href:s,target:"_blank",rel:"noopener noreferrer",className:"block",children:e.jsx("img",{src:s,alt:"generated",className:"max-h-64 max-w-full rounded-md border border-border object-contain",loading:"lazy"})},a))})}function bt({call:t,hideOutput:s}){const{t:a}=k();return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.input!==void 0&&e.jsx(E,{label:a("agent.tool.input"),text:L(t.input)}),!s&&t.resolved&&!t.isError&&!t.denied&&t.output!==void 0&&e.jsx(E,{label:a("agent.tool.result"),text:L(t.output)})]})}function vt({call:t,confirmationId:s,onDecide:a,className:d}){const{t:o}=k(),i=!!s&&!t.resolved,l=t.resolved&&t.denied,u=t.resolved&&!l?dt(t):null,c=!t.resolved&&!i,j=l&&typeof t.output=="string"?t.output:"",h=`agent.tool.${t.toolName}`,p=["send_input","read_screen","web_search","fetch_url"].includes(t.toolName)?o(h):t.toolName,b=jt(t);return e.jsxs("div",{"data-testid":`agent-tool-card-${t.toolCallId}`,"data-tool-name":t.toolName,"data-tool-denied":l||void 0,className:C("border-border bg-card flex max-w-full min-w-0 flex-col gap-1.5 self-start rounded-lg border p-2",u!==null&&"border-destructive/50",l&&"opacity-80",d),children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-xs font-medium",children:[lt(t.toolName),e.jsx("span",{className:"min-w-0 truncate",children:p}),c&&e.jsx(se,{className:"text-muted-foreground size-3 animate-spin"}),t.resolved&&!l&&u===null&&e.jsx(F,{className:"size-3 text-emerald-500"}),u!==null&&e.jsx(B,{className:"text-destructive size-3"}),l&&e.jsxs("span",{className:"text-destructive flex items-center gap-0.5",children:[e.jsx(H,{className:"size-3"}),o("agent.tool.denied")]})]}),t.toolName==="send_input"&&e.jsx(ut,{call:t}),t.toolName==="read_screen"&&e.jsx(mt,{call:t}),t.toolName==="web_search"&&e.jsx(xt,{call:t}),t.toolName==="fetch_url"&&e.jsx(pt,{call:t}),!["send_input","read_screen","web_search","fetch_url"].includes(t.toolName)&&e.jsx(bt,{call:t,hideOutput:b.length>0}),e.jsx(wt,{images:b}),u!==null&&e.jsx("p",{className:"text-destructive text-xs break-words whitespace-pre-wrap",children:u}),j&&e.jsx("p",{className:"text-muted-foreground text-xs break-words whitespace-pre-wrap",children:j}),i&&s&&e.jsxs("div",{"data-testid":`agent-tool-approval-${t.toolCallId}`,className:"flex items-center gap-2 pt-1",children:[e.jsx("span",{className:"text-muted-foreground min-w-0 flex-1 text-xs",children:o("agent.confirm.title")}),e.jsxs(y,{"data-testid":"agent-confirm-approve",size:"xs",variant:"secondary",onClick:()=>a==null?void 0:a(s,!0),children:[e.jsx(F,{}),o("agent.confirm.approve")]}),e.jsxs(y,{"data-testid":"agent-confirm-deny",size:"xs",variant:"destructive",onClick:()=>a==null?void 0:a(s,!1),children:[e.jsx(H,{}),o("agent.confirm.deny")]})]})]})}function Nt({text:t,className:s}){return e.jsx("div",{"data-testid":"agent-user-message",className:C("bg-primary text-primary-foreground max-w-[85%] self-end rounded-2xl px-3 py-2 text-sm whitespace-pre-wrap break-words",s),children:t})}const yt=48;function kt(){return e.jsxs("div",{"data-testid":"agent-running-indicator",className:"flex items-center gap-1 self-start px-1",children:[e.jsx("span",{className:"bg-muted-foreground size-1.5 animate-pulse rounded-full"}),e.jsx("span",{className:"bg-muted-foreground size-1.5 animate-pulse rounded-full [animation-delay:150ms]"}),e.jsx("span",{className:"bg-muted-foreground size-1.5 animate-pulse rounded-full [animation-delay:300ms]"})]})}function It({blocks:t,running:s,emptyText:a,confirmationByToolCallId:d,onDecide:o,className:i}){const{t:l}=k(),u=N.useRef(null),c=N.useRef(!0),[j,h]=N.useState(!1),p=()=>{const m=u.current;m&&(m.scrollTop=m.scrollHeight,c.current=!0,h(!1))};N.useEffect(()=>{if(c.current){const m=u.current;m&&(m.scrollTop=m.scrollHeight)}else h(!0)},[t,s]);const b=()=>{const m=u.current;if(!m)return;const w=m.scrollHeight-m.scrollTop-m.clientHeight<yt;c.current=w,h(!w)};return t.length===0&&!s?e.jsx("div",{"data-testid":"agent-chat-thread",className:C("flex min-h-0 flex-1 items-center justify-center p-4",i),children:e.jsx("p",{className:"text-muted-foreground text-sm",children:a})}):e.jsxs("div",{className:C("relative min-h-0 flex-1",i),children:[e.jsx("div",{ref:u,"data-testid":"agent-chat-thread",className:"h-full overflow-y-auto p-3",onScroll:b,children:e.jsxs("div",{className:"flex flex-col gap-3",children:[t.map(m=>{switch(m.kind){case"user":return e.jsx(Nt,{text:m.text},m.key);case"assistant-text":return e.jsx(ot,{text:m.text,streaming:m.streaming},m.key);case"reasoning":return e.jsx(it,{text:m.text,streaming:m.streaming},m.key);case"tool-call":return e.jsx(vt,{call:m.call,confirmationId:d.get(m.call.toolCallId),onDecide:o},m.key);default:return null}}),s&&e.jsx(kt,{})]})}),j&&e.jsx(y,{"data-testid":"agent-scroll-to-bottom",size:"icon-sm",variant:"secondary",className:"absolute right-3 bottom-3 z-10 rounded-full shadow-md",onClick:p,"aria-label":l("agent.panel.scrollToBottom"),children:e.jsx(Oe,{})})]})}const O="::";function D(t,s){return`${t??""}${O}${s}`}function Ct(t){const s=t.indexOf(O);return s<0?{providerId:null,modelId:t}:{providerId:t.slice(0,s)||null,modelId:t.slice(s+O.length)}}function St({providerId:t,modelId:s,onChange:a,disabled:d,className:o}){var w;const{t:i}=k(),{data:l}=K({queryKey:["llm-providers"],queryFn:async()=>{const x=await fetch("/api/llm/providers");if(!x.ok)throw new Error("Failed to load providers");return await x.json()},throwOnError:!1}),{data:u}=K({queryKey:["llm-settings"],queryFn:async()=>{const x=await fetch("/api/llm/settings");if(!x.ok)throw new Error("Failed to load settings");return await x.json()},throwOnError:!1}),c=((l==null?void 0:l.providers)??[]).filter(x=>x.enabled&&x.models.length>0),j=t??(u==null?void 0:u.settings.defaultProviderId)??null,h=s??(u==null?void 0:u.settings.defaultModelId)??null,p=h?D(j,h):"",b=c.some(x=>x.id===j&&x.models.includes(h??"")),m=((w=c.find(x=>x.id===j))==null?void 0:w.name)??null,z=h?m?`${m}/${h}`:h:i("agent.model.placeholder");return e.jsxs(ye,{value:p,onValueChange:x=>{if(typeof x!="string"||!x)return;const n=Ct(x);a(n.providerId,n.modelId)},disabled:d||c.length===0,children:[e.jsx(ke,{size:"sm",className:C("h-7 w-full min-w-0 border-transparent bg-transparent text-muted-foreground text-xs hover:border-border/40 dark:bg-transparent dark:hover:bg-transparent",o),"data-testid":"agent-model-picker","aria-label":i("agent.model.select"),children:e.jsx("span",{className:"min-w-0 truncate",children:z})}),e.jsxs(Ie,{children:[!b&&h&&e.jsx(X,{value:p,className:"text-muted-foreground",children:h}),c.map(x=>e.jsxs(Ce,{children:[e.jsx(Se,{children:x.name}),x.models.map(n=>e.jsx(X,{value:D(x.id,n),children:n},`${x.id}:${n}`))]},x.id))]})]})}function Mt({queued:t,onEdit:s,onWithdraw:a,onSteer:d}){const{t:o}=k(),[i,l]=N.useState(null),[u,c]=N.useState("");if(t.length===0)return null;const j=p=>{l(p.id),c(p.text)},h=p=>{const b=u.trim();b&&s(p,b),l(null)};return e.jsxs("div",{"data-testid":"agent-queue",className:"bg-muted/50 mx-3 mb-2 flex shrink-0 flex-col gap-1.5 rounded-xl px-2.5 py-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-muted-foreground text-xs font-medium",children:o("agent.queue.title",{count:t.length})}),e.jsxs(y,{"data-testid":"agent-queue-steer",size:"xs",variant:"outline",onClick:d,title:o("agent.queue.steerHint"),children:[e.jsx(ae,{}),o("agent.queue.steer")]})]}),e.jsx("ul",{className:"flex flex-col gap-1",children:t.map(p=>e.jsx("li",{"data-testid":`agent-queue-item-${p.id}`,className:"bg-background/60 flex items-start gap-1.5 rounded-lg px-2 py-1",children:i===p.id?e.jsxs(e.Fragment,{children:[e.jsx(re,{value:u,onChange:b=>c(b.target.value),onKeyDown:b=>{b.key==="Enter"&&!b.shiftKey&&(b.preventDefault(),h(p.id)),b.key==="Escape"&&l(null)},rows:1,className:"max-h-32 min-h-7 flex-1 resize-none text-xs",autoFocus:!0}),e.jsx(y,{size:"icon-sm",variant:"ghost",onClick:()=>h(p.id),"aria-label":o("common.save"),children:e.jsx(F,{})})]}):e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"min-w-0 flex-1 truncate text-xs",children:p.text}),e.jsx(y,{size:"icon-sm",variant:"ghost",onClick:()=>j(p),"aria-label":o("common.edit"),children:e.jsx(Me,{})}),e.jsx(y,{"data-testid":`agent-queue-withdraw-${p.id}`,size:"icon-sm",variant:"ghost",onClick:()=>a(p.id),"aria-label":o("agent.queue.withdraw"),children:e.jsx(H,{})})]})},p.id))})]})}function _t({onSend:t,onSteer:s,onStop:a,running:d,steerable:o,disabled:i,modelPicker:l,writeModeControl:u}){const{t:c}=k(),[j,h]=N.useState(""),p=g(w=>{var x;return((x=w.draft)==null?void 0:x.prompt)??null}),b=N.useRef(null);N.useEffect(()=>{p&&p!==b.current&&(b.current=p,h(p))},[p]);const m=()=>{const w=j.trim();!w||i||(t==null||t(w),h(""))},z=()=>{const w=j.trim();!w||i||(s==null||s(w),h(""))};return e.jsxs("div",{"data-testid":"agent-chat-input",className:"bg-chat-surface flex shrink-0 flex-col gap-2 mx-3 mb-2.5 rounded-xl mt-1.5 focus-within:ring-1 focus-within:ring-ring/30",children:[e.jsx(re,{"data-testid":"agent-chat-input-textarea",value:j,onChange:w=>h(w.target.value),onKeyDown:w=>{w.key==="Enter"&&!w.shiftKey&&!w.nativeEvent.isComposing&&(w.preventDefault(),m())},placeholder:c("agent.panel.inputPlaceholder"),disabled:i,className:"max-h-40 min-h-[4.5rem] w-full resize-none border-transparent bg-transparent p-3 text-[13px] shadow-none focus-visible:border-transparent focus-visible:ring-0 disabled:bg-transparent dark:bg-transparent dark:disabled:bg-transparent",rows:3}),e.jsxs("div",{className:"flex min-w-0 flex-wrap items-center gap-2 px-2.5 pb-2.5",children:[e.jsxs("div",{className:"flex min-w-0 flex-1 items-center gap-2",children:[u,l&&e.jsx("div",{className:"min-w-0 flex-1",children:l})]}),d?e.jsxs("div",{className:"ml-auto flex shrink-0 items-center gap-1.5",children:[o&&e.jsx(y,{"data-testid":"agent-chat-steer",size:"icon",variant:"outline",disabled:i||j.trim().length===0,onClick:z,"aria-label":c("agent.queue.steer"),title:c("agent.queue.steerHint"),children:e.jsx(ae,{})}),e.jsx(y,{"data-testid":"agent-chat-send",size:"icon",variant:"secondary",disabled:i||j.trim().length===0,onClick:m,"aria-label":c("agent.panel.send"),children:e.jsx(Z,{})}),e.jsx(y,{"data-testid":"agent-chat-stop",size:"icon",variant:"destructive",onClick:()=>a==null?void 0:a(),"aria-label":c("agent.panel.stop"),children:e.jsx(Ze,{})})]}):e.jsx(y,{"data-testid":"agent-chat-send",size:"icon",className:"ml-auto shrink-0",disabled:i||j.trim().length===0,onClick:m,"aria-label":c("agent.panel.send"),children:e.jsx(Z,{})})]})]})}function zt(t,s,a){var i;if(!t.deviceId||!t.paneId)return null;const d=((i=a==null?void 0:a.find(l=>l.id===t.deviceId))==null?void 0:i.name)??null,o=s[t.deviceId];if(!(o!=null&&o.session))return{label:`${t.paneId}@${d??"?"}`,state:"unknown",windowId:null};for(const l of o.session.windows){const u=l.panes.find(c=>c.id===t.paneId);if(u)return{label:Re({paneCustomName:u.customName,paneTitle:u.title,windowName:l.name,windowCustomName:l.customName,deviceName:d}),state:"valid",windowId:l.id}}return{label:`${t.paneId}@${d??"?"}`,state:"invalid",windowId:null}}function $t(){var V;const{t}=k(),s=_e(),a=ze(r=>r.setSidebarTab),d=Te("/devices/:deviceId/windows/:windowId/panes/:paneId"),o=(d==null?void 0:d.params.deviceId)??null,i=(d==null?void 0:d.params.paneId)??null,l=g(r=>r.sessions),u=g(r=>r.activeSessionId),c=g(r=>r.draft),j=g(r=>r.activeSessionId?r.messages[r.activeSessionId]:void 0),h=g(r=>r.activeSessionId?r.inProgress[r.activeSessionId]:void 0),p=g(r=>r.activeSessionId?r.pendingConfirmations[r.activeSessionId]:void 0),b=g(r=>r.activeSessionId?r.sending[r.activeSessionId]:void 0),m=g(r=>r.activeSessionId?r.queued[r.activeSessionId]:void 0),z=g(r=>r.defaultWriteMode),w=Ee(r=>r.snapshots),{data:x}=K({queryKey:["devices"],queryFn:async()=>{const r=await fetch("/api/devices");if(!r.ok)throw new Error("Failed to load devices");return r.json()},throwOnError:!1});N.useEffect(()=>{const r=g.getState();r.ensureInitialized(),r.loadSessions()},[]);const n=u?l[u]:void 0,q=N.useMemo(()=>{var f,S;if(!o||!i)return null;const r=(S=(f=w[o])==null?void 0:f.session)==null?void 0:S.windows;for(const I of r??[]){const J=I.panes.find(we=>we.id===i);if(J)return J.title??null}return null},[o,i,w]);N.useEffect(()=>{!n&&!c&&o&&i&&g.getState().startDraft(o,i,q)},[n,c,o,i,q]);const oe=N.useMemo(()=>{const r=new Map;for(const f of p??[])r.set(f.toolCallId,f.id);return r},[p]),ie=N.useMemo(()=>{const r=Be(j,h),f=new Set;for(const I of r)I.kind==="tool-call"&&f.add(I.call.toolCallId);const S=[];for(const I of p??[])f.has(I.toolCallId)||S.push({kind:"tool-call",key:`confirmation-${I.id}`,call:{toolCallId:I.toolCallId,toolName:I.toolName,input:I.input,isError:!1,denied:!1,resolved:!1}});return S.length>0?[...r,...S]:r},[j,h,p]),W=n??(c?{deviceId:c.deviceId,paneId:c.paneId}:null),v=W?zt(W,w,x==null?void 0:x.devices):null,de=!!(n&&i&&o&&(n.paneId!==i||n.deviceId!==o)),$=(n==null?void 0:n.status)==="running",G=qe(j),T=!!(n&&(!n.deviceId||!((V=x==null?void 0:x.devices)!=null&&V.some(r=>r.id===n.deviceId))||(v==null?void 0:v.state)==="invalid")),P=m??[],le=(r,f)=>{u&&g.getState().decideConfirmation(u,r,f)},U=()=>{if(n!=null&&n.deviceId){if((v==null?void 0:v.state)==="valid"&&v.windowId&&n.paneId){s(`/devices/${n.deviceId}/windows/${v.windowId}/panes/${encodeURIComponent(n.paneId)}`);return}(v==null?void 0:v.state)==="unknown"&&s(`/devices/${n.deviceId}`)}},ce=()=>{!o||!i||g.getState().startDraft(o,i,q)},ue=(r,f)=>{n?g.getState().setSessionModel(n.id,r,f):c&&g.getState().updateDraft({providerId:r,modelId:f})},me=r=>{const f=g.getState();if(n){n.status==="running"?f.enqueueMessage(n.id,r):f.sendMessage(n.id,r);return}c&&(async()=>{const S=await f.materializeDraft();S&&await f.sendMessage(S.id,r)})()},xe=r=>{n&&g.getState().enqueueMessage(n.id,r,!0)},pe=()=>{if(!n)return;const r=P[0];if(!r)return;const f=g.getState();(async()=>(await f.withdrawQueuedMessage(n.id,r.id),await f.enqueueMessage(n.id,r.text,!0)))()},fe=n?n.providerId:(c==null?void 0:c.providerId)??null,ge=n?n.modelId:(c==null?void 0:c.modelId)??null,A=!!(n||c),R=!!(c&&!n),Q=n?n.writeMode:z,he=!!(n&&((j==null?void 0:j.length)??0)>0),je=T||!A||(n==null?void 0:n.status)==="waiting_confirmation"||!!b;return e.jsxs("div",{"data-testid":"agent-tab",className:"flex h-full min-h-0 flex-col",children:[e.jsxs("div",{className:"flex shrink-0 items-center gap-2 px-3 py-2",children:[v?e.jsxs("button",{type:"button","data-testid":"agent-binding-chip","data-binding-state":v.state,className:C("border-border flex min-w-0 items-center gap-1 rounded-full border px-2 py-0.5 text-xs",n&&v.state==="valid"?"hover:bg-muted cursor-pointer":"text-muted-foreground",v.state==="invalid"&&"opacity-60"),onClick:U,disabled:!n||v.state==="invalid",children:[e.jsx(Ye,{className:"size-3 shrink-0"}),e.jsx("span",{className:"min-w-0 truncate",children:v.label}),v.state==="invalid"&&e.jsxs("span",{className:"shrink-0",children:["· ",t("agent.binding.invalid")]})]}):e.jsx("div",{className:"min-w-0 flex-1"}),e.jsxs("div",{className:"ml-auto flex shrink-0 items-center gap-1",children:[e.jsx(y,{"data-testid":"agent-session-switch",size:"icon-sm",variant:"ghost",onClick:()=>a("panes"),"aria-label":t("agent.session.switch"),title:t("agent.session.switch"),children:e.jsx(Qe,{})}),he&&e.jsx(y,{"data-testid":"agent-session-new",size:"icon-sm",variant:"ghost",disabled:!o||!i,onClick:ce,"aria-label":t("agent.session.new"),title:t(!o||!i?"agent.session.selectPaneHint":"agent.session.new"),children:e.jsx($e,{})})]})]}),T&&e.jsxs("div",{"data-testid":"agent-orphan-banner",className:"bg-muted/50 text-muted-foreground mx-3 mb-1.5 flex shrink-0 items-start gap-2 rounded-lg px-2 py-1.5 text-xs",children:[e.jsx(B,{className:"mt-0.5 size-3.5 shrink-0"}),e.jsx("span",{className:"min-w-0 flex-1",children:t("agent.orphan.readonly")})]}),n&&!T&&de&&e.jsxs("div",{"data-testid":"agent-pane-mismatch",className:"bg-muted/50 mx-3 mb-1.5 flex shrink-0 flex-wrap items-center gap-2 rounded-lg px-2 py-1.5 text-xs",children:[e.jsx(B,{className:"text-muted-foreground size-3.5 shrink-0"}),e.jsx("span",{className:"text-muted-foreground min-w-0 flex-1",children:t("agent.binding.mismatchTitle")}),(v==null?void 0:v.state)==="valid"&&e.jsx(y,{"data-testid":"agent-binding-goto",size:"xs",variant:"outline",onClick:U,children:t("agent.binding.goTo")}),i&&e.jsx(y,{"data-testid":"agent-binding-rebind",size:"xs",variant:"outline",onClick:()=>{g.getState().rebindPane(n.id,i)},children:t("agent.binding.rebind")})]}),(n==null?void 0:n.status)==="error"&&n.lastError&&e.jsxs("div",{"data-testid":"agent-error-banner",className:"bg-destructive/10 text-destructive mx-3 mb-1.5 flex shrink-0 items-start gap-2 rounded-lg px-2 py-1.5 text-xs",children:[e.jsx(B,{className:"mt-0.5 size-3.5 shrink-0"}),e.jsx("span",{className:"min-w-0 flex-1 break-words",children:n.lastError}),G&&!T&&e.jsx(y,{"data-testid":"agent-error-retry",size:"xs",variant:"outline",className:"shrink-0",disabled:!!b,onClick:()=>{g.getState().sendMessage(n.id,G)},children:t("agent.panel.retry")})]}),!R&&e.jsx(It,{blocks:n?ie:[],running:!!$,emptyText:t(A?"agent.panel.empty":"agent.session.selectPaneHint"),confirmationByToolCallId:oe,onDecide:le,className:"bg-chat-surface mx-3 mb-2 overflow-hidden rounded-xl"},(n==null?void 0:n.id)??(c?"draft":"none")),n&&!T&&P.length>0&&e.jsx(Mt,{queued:P,onEdit:(r,f)=>void g.getState().editQueuedMessage(n.id,r,f),onWithdraw:r=>void g.getState().withdrawQueuedMessage(n.id,r),onSteer:pe}),A&&e.jsxs("div",{className:R?"flex min-h-0 flex-1 flex-col justify-center":"contents",children:[R&&e.jsxs("div",{className:"flex flex-col items-center gap-2 px-6 pb-6 text-center",children:[e.jsx(Pe,{className:"text-muted-foreground size-9"}),e.jsx("h3",{className:"text-sm font-medium",children:t("agent.welcome.title")}),e.jsx("p",{className:"text-muted-foreground text-xs",children:t("agent.welcome.subtitle")})]}),e.jsx(_t,{disabled:je,running:!!$,steerable:!!n,onSend:me,onSteer:xe,onStop:()=>{n&&g.getState().stopSession(n.id)},modelPicker:e.jsx(St,{providerId:fe,modelId:ge,onChange:ue,disabled:$}),writeModeControl:e.jsxs("div",{className:"flex shrink-0 items-center gap-1.5",children:[e.jsx("span",{className:"text-muted-foreground text-xs",children:t(Q==="auto"?"agent.writeMode.auto":"agent.writeMode.confirm")}),e.jsx(Ae,{"data-testid":"agent-write-mode-switch",checked:Q==="auto",disabled:!!n&&T,onCheckedChange:r=>{const f=r?"auto":"confirm";g.getState().setDefaultWriteMode(f),n&&g.getState().setWriteMode(n.id,f)}})]})})]})]})}export{$t as AgentTab};
@@ -1 +0,0 @@
1
- import{ai as o,aj as n}from"./mermaid.core-D-CshtYr.js";const t=(a,r)=>o.lang.round(n.parse(a)[r]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-727SXJPM-TyUdLEW5.js";import{_ as i}from"./mermaid.core-D-CshtYr.js";import"./chunk-FMBD7UC4-Dx0HVCZZ.js";import"./chunk-ND2GUHAM-BQCoMEti.js";import"./chunk-55IACEB6-CnnXwmY_.js";import"./chunk-2J33WTMH-DOjtL7ww.js";import"./index-B3ddLSja.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-727SXJPM-TyUdLEW5.js";import{_ as i}from"./mermaid.core-D-CshtYr.js";import"./chunk-FMBD7UC4-Dx0HVCZZ.js";import"./chunk-ND2GUHAM-BQCoMEti.js";import"./chunk-55IACEB6-CnnXwmY_.js";import"./chunk-2J33WTMH-DOjtL7ww.js";import"./index-B3ddLSja.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
@@ -1 +0,0 @@
1
- const e=JSON.parse('{"common":{"loading":"Loading...","save":"Save","saving":"Saving...","cancel":"Cancel","add":"Add","delete":"Delete","edit":"Edit","confirm":"Confirm","close":"Close","expand":"Expand","collapse":"Collapse","refresh":"Refresh","test":"Test","send":"Send","success":"Success","error":"Error","warning":"Warning","info":"Info","yes":"Yes","no":"No","enabled":"Enabled","disabled":"Disabled","pending":"Pending","authorized":"Authorized","unknown":"Unknown","empty":"Empty","none":"None","default":"Default","optional":"Optional","required":"Required","pwaInstallTitle":"Install as app","pwaInstallHintIOSSafari":"iOS Safari does not show an automatic install prompt. Tap Share, then \\"Add to Home Screen\\".","pwaInstallHintIOSChrome":"iOS Chrome does not show an automatic install prompt. Tap Share, then \\"Add to Home Screen\\"."},"nav":{"manageDevices":"Manage Devices","settings":"Settings","sidebarExpand":"Expand Sidebar","sidebarCollapse":"Collapse Sidebar","openSidebar":"Open Sidebar","closeSidebar":"Close Sidebar","jumpToLatest":"Jump to Latest","switchToEditor":"Switch to Editor Input","switchToDirect":"Switch to Direct Input","refreshPage":"Refresh Page","refreshPageConfirm":"Are you sure you want to refresh the page? Unsaved content will be lost."},"device":{"title":"Device Management","devices":"Devices","addDevice":"Add Device","addDeviceDescription":"Fill in device details and choose a connection method","addFirstDevice":"Add First Device","editDevice":"Edit Device","editDeviceDescription":"Update device configuration","sectionBasic":"Basic Info","sectionConnection":"Connection","sectionAuth":"Authentication","noDevices":"No Devices","noDevicesDescription":"Add a local or SSH device to get started","name":"Device Name","namePlaceholder":"e.g., My Server","type":"Type","typeLocal":"Local Device","typeSSH":"SSH Remote Device","typeSSHBadge":"SSH","host":"Host","hostPlaceholder":"example.com","port":"Port","username":"Username","usernamePlaceholder":"root","session":"Tmux Session Name","sessionPlaceholder":"tmex","sessionHint":"Leave empty to use default \\"tmex\\"","defaultWorkingDir":"Default Working Directory","defaultWorkingDirPlaceholder":"Leave empty for user home directory","authMode":"Authentication Mode","authPassword":"Password","authKey":"Private Key","authAgent":"SSH Agent","authConfigRef":"SSH Config","sshConfigRefPlaceholder":"Host alias, e.g. my-server","sshConfigRefHint":"A Host alias from your ssh config, resolved via `ssh -G`. Not the path to the config file.","password":"Password","privateKey":"Private Key","privateKeyPlaceholder":"-----BEGIN OPENSSH PRIVATE KEY-----","privateKeyPassphrase":"Private Key Passphrase (Optional)","passphrase":"Passphrase","connect":"Connect","connected":"Connected","disconnect":"Disconnect","disconnected":"Disconnected","connecting":"Connecting...","dragHandle":"Drag to reorder device","reorderFailed":"Failed to reorder devices","deleteConfirm":"Delete this device?","deleteDescription":"Device \\"{{name}}\\" will be permanently removed. This action cannot be undone.","deleteSuccess":"Device deleted","createSuccess":"Device created","updateSuccess":"Device updated","deleteFailed":"Failed to delete device","createFailed":"Failed to create device","updateFailed":"Failed to update device","loadFailed":"Failed to load devices","localDevice":"Local Device","subtitle":"{{username}}@{{host}}:{{port}}","modify":"Modify Device","delete":"Delete"},"terminal":{"keyboardBehavior":{"title":"Keyboard Behavior","description":"How the page makes room for the on-screen keyboard","modeLift":"Shift page","modeLiftDesc":"Move the whole page up; terminal size stays the same","modeResize":"Resize terminal","modeResizeDesc":"Shrink the terminal to fit above the keyboard (changes the remote window size)","modeFollow":"Follow cursor","modeFollowDesc":"Shift just enough to keep the cursor right above the keyboard; terminal size stays the same"},"initializing":"Initializing terminal...","connecting":"Connecting to device...","initFailed":"Terminal initialization failed","inputPlaceholder":"Type command here...","clear":"Clear","deviceError":"Device Error","deviceErrorWithType":"[{{type}}] Device Error","noDeviceSelected":"No device selected","windowClosed":"Current window has been closed, please select a window from the sidebar.","paneClosed":"Current pane has been closed, please select a pane from the sidebar.","bellNotification":"Terminal Bell","bellDescriptionWithTitle":"Window {{window}} · {{paneLabel}}","bellFallback":"Received tmux bell","notificationFallbackTitle":"Terminal Notification","notificationSourceLabel":"From {{source}}","notificationFallbackDetail":"Terminal notification","paneTitle":"Pane {{index}}","activePane":"Current Pane","activeWindow":"Current Window","editorPlaceholder":"Enter commands here...","editorClear":"Clear","editorSendWithEnter":"Send with Enter","editorSendLineByLine":"Send Line by Line","editorSend":"Send","sendShortcut":"Send {{key}}","inputModeDirect":"Direct Input","inputModeEditor":"Editor","newWindow":"New Window","closeWindow":"Close Window","closePane":"Close Pane","copy":"Copy","paste":"Paste","copied":"Copied to clipboard","copyFailed":"Copy failed","pasteFailed":"Could not read clipboard, check browser permissions","clearSelection":"Dismiss selection"},"settings":{"title":"System Settings","siteSettings":"Site Settings","siteName":"Site Name","siteNamePlaceholder":"tmex","siteUrl":"Site URL","siteUrlPlaceholder":"http://localhost:3000","bellThrottle":"Bell Throttle (seconds)","notificationThrottle":"Notification Throttle (seconds)","enableBrowserBellToast":"Enable Browser Bell Toast","enableBrowserNotificationToast":"Enable Browser Notification Toast","enableTelegramBellPush":"Enable Telegram Bell Push","enableTelegramNotificationPush":"Enable Telegram Notification Push","enableWeixinBellPush":"Enable WeChat Bell Push","enableWeixinNotificationPush":"Enable WeChat Notification Push","sshReconnectRetries":"SSH Reconnect Retries","sshReconnectDelay":"SSH Reconnect Delay (seconds)","language":"Language","languagePlaceholder":"Select language","language_en_US":"English","language_zh_CN":"简体中文","language_ja_JP":"日本語","theme":"Dark Mode","themeLight":"Light","themeDark":"Dark","siteTab":"Site","notificationsTab":"Notifications","tabGroup":{"general":"General","devicesAndFiles":"Devices & Files","notifications":"Notifications","ai":"AI","terminal":"Terminal"},"terminal":{"title":"Terminal Settings","description":"Adjust the terminal font size, line height, family, and mobile keyboard avoidance. The font family applies to all monospaced text across the app.","fontSize":"Font Size","lineHeight":"Line Height","fontFamily":"Font","preview":"Preview","savedInBrowser":"These settings are saved in this browser only.","shortcuts":{"title":"Custom Shortcuts","savedOnServer":"Saved on the server and shared across all your browsers — changes take effect after you click Save.","preview":"Preview","useIcons":"Show keys as icons","useIconsDesc":"Replace key names like Ctrl/Shift/Enter with Apple-style symbols (⌃⇧⏎).","dragHandle":"Drag to reorder","delete":"Delete","labelPlaceholder":"Label","payloadPlaceholder":"Sequence, e.g. \\\\x1b[A","addShortcut":"Add shortcut","capturePrompt":"Press any key combination…","captureHint":"Click here, then press a key to capture","advanced":"Advanced: enter sequence manually","add":"Add","reset":"Reset to default","save":"Save","saved":"Shortcuts saved","saveFailed":"Failed to save shortcuts","loading":"Loading…","action":{"paste":"Paste","toggleKeyboard":"Toggle text input / keyboard","newAgentSession":"New Agent session","scrollToBottom":"Scroll terminal to bottom"},"loadFailed":"Failed to load shortcuts","retry":"Retry"}},"deviceManagement":{"title":"Device Management","description":"Add, edit, and connect to your local and SSH devices.","openButton":"Open Device Management"},"refreshToApply":"Refresh to apply language change","saveSettings":"Save Settings","settingsSaved":"Settings saved","saveFailed":"Failed to save settings","loadFailed":"Failed to load settings","restartGateway":"Restart Gateway","restartScheduled":"Gateway restart scheduled","restartConfirm":"Are you sure you want to restart Gateway? This will interrupt all active connections.","restartFailed":"Failed to restart gateway","sshReconnectMaxRetries":"SSH Reconnect Retries","llm":{"title":"LLM Providers","name":"Name","namePlaceholder":"e.g. OpenAI","baseUrl":"Base URL","baseUrlPlaceholder":"https://api.openai.com","baseUrlHint":"Adds /v1 automatically; end with / to keep the path as-is","protocol":"Protocol","apiKey":"API Key","apiKeyPlaceholder":"Enter API key","apiKeySetPlaceholder":"Already set, leave blank to keep","addProvider":"Add Provider","editProvider":"Edit Provider","formHint":"Configure the provider connection","models":"Models","modelsTitle":"Models for {{name}}","modelsHint":"Manage the available models for this provider: toggle and add manually","modelManual":"Manual","addModelPlaceholder":"Add a model ID","empty":"No providers yet","refreshModels":"Refresh Models","modelsCount":"{{total}} models","modelsNotFetched":"Models not fetched yet","modelsFetchFailed":"Failed to fetch models: {{error}}","deleteProvider":"Delete Provider","deleteConfirm":"Delete provider \\"{{name}}\\"?","defaults":"Global Defaults","defaultProvider":"Default Provider","defaultProviderNone":"Not set","defaultModel":"Default Model","defaultModelPlaceholder":"Type or pick a model ID","saveDefaults":"Save Defaults","loadFailed":"Failed to load LLM providers","createFailed":"Failed to create provider","updateFailed":"Failed to update provider","deleteFailed":"Failed to delete provider","refreshModelsFailed":"Failed to refresh models","settingsLoadFailed":"Failed to load LLM settings","settingsSaveFailed":"Failed to save LLM settings"},"search":{"title":"Search","provider":"Search Provider","responsesApiHint":"If your LLM provider uses the OpenAI Responses API protocol, it can use that API\'s built-in hosted search tool; the third-party search below is an optional supplement.","providerNone":"Disabled","tavilyApiKey":"Tavily API Key","braveApiKey":"Brave API Key","keyPlaceholder":"Enter API key","keySetPlaceholder":"Already set, leave blank to keep","clearKey":"Clear","clearKeyConfirm":"Clear this API key? You will need to enter it again.","loadFailed":"Failed to load search settings","saveFailed":"Failed to save search settings"},"files":{"title":"Files","description":"Per-device directories browsable in the Files tab. Local devices read directly; SSH devices use rsync.","addRoot":"Add directory","roots":"Directories","empty":"No directories configured","missing":"Device missing","modalAddTitle":"Add directory","modalEditTitle":"Edit directory","device":"Device","devicePlaceholder":"Select a device","noDevices":"No devices yet — add one first","path":"Path","pathPlaceholder":"/absolute/path/to/directory","pathHint":"Absolute path on the selected device.","enabled":"Enabled","addFailed":"Failed to add directory","updateFailed":"Failed to update directory","deleteFailed":"Failed to remove directory","toggleFailed":"Failed to update directory","deleteTitle":"Remove directory?","deleteDesc":"Remove \\"{{path}}\\" from the whitelist? Files under it will no longer be accessible."},"version":{"title":"Version & Updates","currentVersion":"Current version","installMethod":"Install method","installMethodCli":"Installed via CLI","installMethodNonCli":"Not installed via CLI","deployment":"Deployment","deploymentLaunchd":"launchd (macOS)","deploymentSystemd":"systemd (Linux)","deploymentNone":"None","checkUpdate":"Check for updates","checking":"Checking…","upToDate":"You are on the latest version.","updateAvailable":"Update available: {{version}}","changelog":"Changelog","changelogUnavailable":"No changelog available for this version.","publishedAt":"Published {{date}}","upgrade":"Upgrade now","upgradeDisabledDev":"In-app update is disabled outside the production environment.","upgradeDisabledNonCli":"In-app update is only available for CLI installations.","upgradeWarningTitle":"Confirm upgrade","upgradeWarningBody":"Upgrading restarts the service and will interrupt your current session. It may also affect the survival of tmux processes managed by the service. Continue?","upgradeStarted":"Upgrade started","stateDownloading":"Downloading the new version…","stateExecuting":"Applying the upgrade, the service is restarting…","interruptNotice":"The connection will drop while the service restarts; it will recover shortly.","checkFailed":"Failed to check for updates","terminalHint":"Or upgrade from a terminal: npx tmex-cli@<version> upgrade"}},"telegram":{"title":"Telegram Bot Management","botName":"Bot Name","botNamePlaceholder":"e.g., ops-bot","botToken":"Bot Token","botTokenPlaceholder":"123456:AA...","addBot":"Add Bot","editBot":"Edit Bot","enableBot":"Enable Bot","allowAuthRequests":"Allow Authorization Requests","pendingChats":"Pending Authorization","chats":"Authorized Chats","authorizedChats":"Authorized","noPendingChats":"No pending chats","noAuthorizedChats":"No authorized chats","approve":"Approve","authorize":"Authorize","reject":"Reject","revokeAuth":"Revoke Authorization","testMessage":"Test Message","sendTestMessage":"Send Test Message","deleteBot":"Delete Bot","tokenOptional":"Token (leave empty to keep unchanged)","tokenPlaceholder":"Enter new token","botCreated":"Bot created","botUpdated":"Bot updated","botDeleted":"Bot deleted","authApproved":"Authorization approved","chatRemoved":"Chat removed","testMessageSent":"Test message sent","createFailed":"Failed to create bot","updateFailed":"Failed to update bot","deleteFailed":"Failed to delete bot","approveFailed":"Failed to approve authorization","removeFailed":"Failed to remove chat","testMessageFailed":"Failed to send test message","loadBotsFailed":"Failed to load bot list","loadChatsFailed":"Failed to load chat list","noBots":"No bots yet, add one first.","expand":"Expand","collapse":"Collapse","authCount":"{{authorized}} authorized / {{pending}} pending (max 8)","chatId":"Chat ID","applyTime":"Application Time","gatewayOnline":"🟢 Gateway online @ {{siteName}}","deviceConnectionError":"🔴 {{siteName}}: Connection error on device \\"{{deviceName}}\\" ({{host}}) [{{category}}]\\n{{error}}","agentCredentialWarning":"⚠️ {{siteName}}: A message in agent session \\"{{sessionTitle}}\\" appears to contain credentials ({{types}}). It will be sent to the LLM and stored — risk of leakage.","authSuccess":"✅ Authorized. You will now receive notifications.","authPending":"⏳ Authorization request received. Please approve in tmex settings.","authFailed":"❌ Authorization request failed. Please contact administrator.","testMessageTemplate":"🧪 Test Message\\nSite: {{siteName}}\\nTime: {{time}}","approveMessageTemplate":"✅ Authorized via tmex.\\nBot: {{botName}}\\nTime: {{time}}","botNotFound":"Bot not found or unavailable","botNotRunning":"Bot is not running or unavailable"},"weixin":{"title":"WeChat (ClawBot) Management","subtitle":"Push tmex alerts to your personal WeChat via the iLink bot protocol.","replyOnlyNotice":"iLink can only reply inside an active conversation window — message the bot first to activate; alerts then reuse that session. If it goes quiet too long the session expires; message the bot again to re-activate.","accountName":"Account Name","accountNamePlaceholder":"e.g., my-wechat","addAccount":"Add Account","editAccount":"Edit Account","enableAccount":"Enable Account","allowAuthRequests":"Allow Authorization Requests","scanToLogin":"Scan to Log In","relogin":"Re-login (Re-scan)","loggedIn":"Logged in","notLoggedIn":"Not logged in","scanQrcodeHint":"Open WeChat, scan the QR code, and confirm on your phone.","loginPending":"Waiting for scan…","loginConfirmed":"Login confirmed.","loginExpired":"QR code expired. Please retry.","loginError":"Login failed: {{message}}","loginFailed":"Login failed","refreshQrcode":"Refresh QR Code","closeLogin":"Close","pendingUsers":"Pending Authorization","authorizedUsers":"Authorized Users","noPendingUsers":"No pending users","noAuthorizedUsers":"No authorized users","needsReactivation":"Session expired","reactivationHint":"Ask this user to send the bot any message to re-activate alerts.","approve":"Approve","revokeAuth":"Revoke","removeUser":"Remove","testMessage":"Test Message","sendTestMessage":"Send Test Message","deleteAccount":"Delete Account","accountCreated":"Account created","accountUpdated":"Account updated","accountDeleted":"Account deleted","authApproved":"Authorization approved","userRemoved":"User removed","testMessageSent":"Test message sent","createFailed":"Failed to create account","updateFailed":"Failed to update account","deleteFailed":"Failed to delete account","approveFailed":"Failed to approve","removeFailed":"Failed to remove user","testMessageFailed":"Failed to send test message","loadAccountsFailed":"Failed to load accounts","loadUsersFailed":"Failed to load users","noAccounts":"No accounts yet, add one first.","userCount":"{{authorized}} authorized / {{pending}} pending (max 16)","userId":"WeChat User ID","applyTime":"First Contact","expand":"Expand","collapse":"Collapse","accountNameRequired":"Account name is required","accountNotFound":"Account not found or unavailable","accountNotRunning":"Account is not logged in or not running","userNotFound":"User not found","authSuccess":"✅ Authorized. You will now receive notifications.","authPending":"⏳ Authorization request received. Please approve in tmex settings.","testMessageTemplate":"🧪 Test Message\\nSite: {{siteName}}\\nTime: {{time}}","approveMessageTemplate":"✅ Authorized via tmex.\\nAccount: {{accountName}}\\nTime: {{time}}","keepalivePrompt":"【tmex】To keep notifications flowing, just reply with anything to keep the session alive 🙏","scanConfirmedSendHint":"Scan confirmed! Now send any message to this bot in WeChat to finish binding.","bindingInProgress":"Message received, finishing binding…","bindSuccess":"WeChat bound. You will now receive notifications.","bound":"Bound","unbound":"Not bound","bindAction":"Bind (scan)","gatewayOnline":"🟢 tmex online @ {{siteName}}"},"webhook":{"title":"Webhooks","url":"Webhook URL","secret":"Secret","secretPlaceholder":"Used to sign payloads (HMAC-SHA256)","enabled":"Enabled","eventMask":"Events","add":"Add Webhook","empty":"No webhooks yet.","createFailed":"Failed to create webhook","deleteFailed":"Failed to delete webhook","loadFailed":"Failed to load webhooks"},"sshError":{"sshConfigRefNotSupported":"SSH Config reference is not supported in this version. Please use host + username with Agent/Key/Password authentication.","configRefNotSupported":"SSH Config reference is not supported in this version. Please use host + username with Agent/Key/Password authentication.","agentUnavailable":"SSH Agent unavailable: SSH_AUTH_SOCK not detected. Please check agent environment.","agentNoIdentity":"SSH Agent has no available keys. Please run ssh-add first.","agentNoIdentities":"SSH Agent has no available keys. Please run ssh-add first.","authFailed":"Authentication failed: incorrect username, password, or key. Please check device configuration.","authFailedGeneric":"Authentication failed: incorrect username, password, or key. Please check device configuration.","networkUnreachable":"Network unreachable: Please check routing, firewall, or VPN configuration.","connectionRefused":"Connection refused: Unable to connect to target host. Please check host address and port.","timeout":"Connection timeout: Unable to connect to device. Please check network or firewall settings.","connectionTimeout":"Connection timeout: Unable to connect to device. Please check network or firewall settings.","hostNotFound":"Host not found: Unable to resolve hostname. Please check DNS or hostname configuration.","handshakeFailed":"Handshake failed: Unable to establish secure connection. Possibly incompatible key exchange algorithm.","tmuxUnavailable":"Remote tmux unavailable or failed to start. Please ensure tmux is installed and available in the remote shell PATH.","connectionClosed":"Connection closed, attempting to reconnect","unknown":"Connection failed: {{message}}","reconnecting":"Connection interrupted, reconnecting in {{delay}} seconds ({{attempt}}/{{maxRetries}})","reconnectFailed":"Auto-reconnect failed, please retry manually","reconnected":"Device reconnected automatically"},"deviceStatus":{"reconnecting":"Reconnecting {{delay}}s","offline":"Offline","errorBadge":{"authFailed":"Auth failed","agentUnavailable":"Agent unavailable","agentNoIdentity":"Agent has no keys","configRefNotSupported":"SSH Config unsupported","networkUnreachable":"Network unreachable","connectionRefused":"Refused","timeout":"Timeout","hostNotFound":"Host not found","handshakeFailed":"Handshake failed","tmuxUnavailable":"Tmux unavailable","connectionClosed":"Disconnected","unknown":"Connection error"}},"websocket":{"error":"WebSocket connection error","checkGateway":"Please check Gateway status","upgradeFailed":"Upgrade failed","invalidMessage":"Invalid message format","reconnecting":"Reconnecting","reconnect":"Reconnect"},"wsError":{"checkGateway":"Please check Gateway status"},"apiError":{"siteNameRequired":"Site name cannot be empty","siteUrlInvalid":"Site URL must start with http:// or https://","bellThrottleInvalid":"Bell throttle seconds must be between 0-300","sshRetriesInvalid":"SSH reconnect retries must be between 0-20","sshDelayInvalid":"SSH reconnect delay must be between 1-300 seconds","languageInvalid":"Language must be one of the supported locales","botNameRequired":"Bot name cannot be empty","botTokenRequired":"Bot token cannot be empty","missingFields":"Missing required fields","sshRequiresHost":"SSH device requires host or sshConfigRef","invalidRequest":"Invalid request","deviceNotFound":"Device not found","botNotFound":"Bot not found","chatNotFound":"Chat not found","urlAndSecretRequired":"URL and secret are required","notFound":"Not found","llmProviderNameRequired":"Provider name cannot be empty","llmProviderProtocolInvalid":"Protocol must be openai-chat or openai-responses","llmProviderBaseUrlInvalid":"Base URL must start with http:// or https://","llmProviderApiKeyRequired":"API key cannot be empty","llmProviderNotFound":"LLM provider not found","llmProviderDisabled":"LLM provider {{name}} is disabled","llmNoDefaultProvider":"No LLM provider specified and no default provider configured","llmNoDefaultModel":"No model specified and no default model configured","llmDefaultProviderNotFound":"Default provider does not exist","llmSearchProviderInvalid":"Search provider must be none, tavily or brave","llmFetchModelsFailed":"Failed to fetch model list: {{detail}}","agentSessionNotFound":"Agent session not found","agentSessionBusy":"Agent session is currently running, stop it or wait for completion","agentSessionAwaitingConfirmation":"Agent session has pending confirmations, resolve them first","agentDeviceRequired":"Device is required","agentPaneRequired":"Terminal pane is required","agentWriteModeInvalid":"Write mode must be confirm or auto","agentMaxStepsInvalid":"Max steps per turn must be between 1 and 100","agentProviderWebSearchRequiresResponses":"Provider built-in web search requires the openai-responses protocol","agentHostedToolUnknown":"Unknown hosted tool: {{name}}","agentHostedToolRequiresResponses":"Provider hosted tools require the openai-responses protocol","agentSessionOrphaned":"This agent session is orphaned (its terminal is gone) and is read-only","agentQueuedMessageNotFound":"Queued message not found","agentConfirmationNotFound":"Confirmation not found","agentConfirmationAlreadyDecided":"Confirmation has already been decided","agentMessageTextRequired":"Message text is required","watchRuleNotFound":"Watch rule not found","watchNameRequired":"Rule name is required","watchTriggerTypeInvalid":"Trigger type must be match, unchanged or llm","watchPatternRequired":"match/unchanged rules require a regular expression","watchPatternInvalid":"Invalid regular expression: {{detail}}","watchUnchangedMinutesInvalid":"unchanged rules require unchangedMinutes greater than 0","watchExtractGroupInvalid":"Capture group index must be an integer >= 0","watchConditionPromptRequired":"llm rules require a condition prompt","watchIntervalInvalid":"Sampling interval must be at least {{min}} seconds","watchNoMatchBehaviorInvalid":"No-match behavior must be reset or ignore","watchFireModeInvalid":"Fire mode must be once or repeat","watchCooldownInvalid":"Cooldown seconds must be an integer >= 0","watchAssistDescriptionRequired":"Please describe what to match","watchAssistModelUnavailable":"Model call failed: {{detail}}","fileRootInvalid":"Path must be an absolute, existing directory","fileOutsideRoots":"Path is outside the allowed directories","fileNotADirectory":"Not a directory","fileTooLarge":"File is too large","fileBinary":"Binary files are not supported","fileRootDeviceInvalid":"Invalid or unknown device","fileRootDuplicate":"This directory is already added for the device","upgradeNotAllowed":"In-app update is not available for this installation.","upgradeInProgress":"An upgrade is already in progress.","upgradeVersionRequired":"Target version is required.","updateCheckFailed":"Failed to query the npm registry.","terminalShortcutsTooMany":"Too many shortcuts","terminalShortcutInvalid":"Invalid shortcut configuration"},"notification":{"clickToJump":"Click to jump to corresponding pane","eventType":{"terminal_bell":"🔔 Terminal Bell","terminal_notification":"🔔 Terminal Notification","tmux_window_close":"🪟 Window Closed","tmux_pane_close":"📱 Pane Closed","device_tmux_missing":"⚠️ Tmux Missing","device_disconnect":"🔌 Device Disconnected","session_created":"🆕 Session Created","session_closed":"🚪 Session Closed","agent_confirmation_pending":"🤖 Agent Confirmation Pending","agent_turn_finished":"🤖 Agent Turn Finished","agent_error":"🤖 Agent Error","watch_triggered":"👁️ Watch Rule Triggered","watch_model_unavailable":"👁️ Watch Model Unavailable","watch_rule_error":"👁️ Watch Rule Error"},"site":"Site","device":"Device","window":"Window","pane":"Pane","time":"Time","directLink":"Direct Link","message":"Message","paneTitle":"Title","process":"Process","telegramBell":{"title":"🔔 Bell from {{siteName}}: {{terminalTopbarLabel}}","viewLink":"Click to view","terminalTopbarLabel":"Window {{window}} · Pane {{pane}} @ {{device}}"},"telegramNotification":{},"agent":{"confirmationPending":"Agent \\"{{title}}\\" requests to run tool {{toolName}}, awaiting confirmation","turnFinished":"Agent \\"{{title}}\\" turn finished","error":"Agent \\"{{title}}\\" error: {{message}}"},"watch":{"matchTriggered":"Watch \\"{{name}}\\" matched: {{text}}","unchangedTriggered":"Watch \\"{{name}}\\" value \\"{{value}}\\" has been unchanged for {{minutes}} minutes","llmTriggered":"Watch \\"{{name}}\\" condition met: {{reason}}","summaryTriggered":"Watch \\"{{name}}\\": {{summary}}","unconfirmedSuffix":" (model unavailable, not LLM-confirmed)","modelUnavailable":"Watch \\"{{name}}\\" model call failed: {{message}}","ruleError":"Watch \\"{{name}}\\" failed {{count}} times in a row and has been disabled: {{message}}","paneGone":"Watch \\"{{name}}\\" pane ({{paneId}}) was destroyed; the rule has been removed"}},"sidebar":{"noWindows":"No windows","noDevices":"No devices","addDeviceLink":"Add Device","openSettingsLink":"Open Settings","openSettings":"Open Settings","manageDevices":"Manage Devices","settings":"Settings","currentWindow":"Current Window","currentPane":"Current Pane","newWindow":"Create Window","closeWindow":"Close Window","closePane":"Close Pane","addDevice":"Add Device","tab":{"panes":"Panes","agent":"Agent","files":"Files"},"orphanedSessions":"Orphaned sessions"},"agent":{"error":{"streamStalled":"The model stopped responding (upstream stream stalled). Please retry."},"model":{"select":"Select model","placeholder":"Model","noProviders":"No models — configure a provider in Settings"},"queue":{"title":"Queued ({{count}})","steer":"Steer now","steerHint":"Interrupt the current step and inject the queue now","withdraw":"Withdraw"},"orphan":{"readonly":"This session is orphaned (its terminal is gone) — read-only","title":"Orphaned","process":"Process","startedAt":"Started"},"files":{"comingSoon":"Coming Soon"},"panel":{"title":"Agent","empty":"Select or create a session","inputPlaceholder":"Type a message…","send":"Send","stop":"Stop","retry":"Retry","scrollToBottom":"Scroll to bottom"},"welcome":{"title":"New Agent chat","subtitle":"Describe your task to start working in the selected terminal"},"session":{"none":"No session selected","new":"New agent session","switch":"Switch session","selectPaneHint":"Select a pane in the Panes tab to start a session","noSessions":"No sessions yet","showAll":"Show all sessions","rename":"Rename session","renameTitle":"Rename session","renamePlaceholder":"Session title","save":"Save","cancel":"Cancel","delete":"Delete session","deleteTitle":"Delete this session?","deleteDesc":"\\"{{title}}\\" and all its messages will be permanently deleted.","deleteConfirm":"Delete","createDisabledNoPane":"Open a terminal pane to create a session","privacyNotice":"Sessions send terminal screen content to the configured LLM service."},"binding":{"invalid":"Pane unavailable","mismatchTitle":"This session is bound to a different pane","goTo":"Go to pane","rebind":"Rebind here"},"writeMode":{"confirm":"Confirm writes","auto":"Auto execute"},"confirm":{"title":"Approval required","approve":"Allow","deny":"Deny"},"tool":{"input":"Input","result":"Result","screen":"Screen capture","send_input":"Send input","read_screen":"Read screen","web_search":"Web search","fetch_url":"Fetch URL","denied":"Denied"},"reasoning":{"title":"Reasoning"},"toast":{"errorTitle":"Agent \\"{{title}}\\" error","credentialWarningTitle":"Message may contain credentials","credentialWarningDescription":"Detected {{types}}. The content is not modified, but it will be sent to the LLM and stored — risk of leakage."}},"window":{"noWindows":"No windows","new":"New Window","newInCwd":"New window here","close":"Close window","closePane":"Close pane","closeConfirmTitle":"Close this window?","closePaneConfirmTitle":"Close this pane?","closeConfirmDesc":"Processes running in \\"{{name}}\\" will be terminated. This action cannot be undone.","menu":"Window actions","dragHandle":"Drag to reorder window","dragHandlePane":"Drag to reorder pane","rename":"Rename window","renamePlaceholder":"Enter a name","renameDesc":"The custom name overrides the title set by the terminal and is kept until the gateway restarts.","renameReset":"Use automatic name","switchPane":"Switch pane","splitRight":"Split right","splitDown":"Split down","paneCount":"{{count}} panes","pane":"Pane","moveToWindow":"Move into this window","breakToWindow":"Break into new window"},"watch":{"title":"Watch rules","dialogDesc":"Monitor this pane\'s screen and get notified when conditions are met","openMonitor":"Watch this pane","rules":{"empty":"No watch rules for this pane yet","addRule":"New rule","edit":"Edit","delete":"Delete","viewState":"Status","lastTriggered":"Last triggered: {{time}}","neverTriggered":"Never triggered","deleteTitle":"Delete this rule?","deleteDesc":"\\"{{name}}\\" will be permanently deleted.","deleteConfirm":"Delete"},"type":{"match":"Match","unchanged":"Stuck","llm":"LLM"},"typeDesc":{"match":"Trigger when a regex matches the screen","unchanged":"Trigger when an extracted value stays unchanged for N minutes (e.g. stalled download)","llm":"An LLM periodically checks the screen against a natural-language condition"},"form":{"createTitle":"New watch rule","editTitle":"Edit watch rule","name":"Rule name","namePlaceholder":"e.g. Download stalled","triggerType":"Trigger type","pattern":"Regular expression","patternPlaceholder":"e.g. (\\\\d+)%","flags":"Flags","flagsPlaceholder":"e.g. i","extractGroup":"Capture group index","extractGroupHint":"0 = whole match; the group value is tracked over time","unchangedMinutes":"Unchanged for (minutes)","noMatchBehavior":"When nothing matches","noMatchReset":"Reset timer (progress line gone = task done)","noMatchIgnore":"Ignore (keep last value)","conditionPrompt":"Condition (natural language)","conditionPromptPlaceholder":"e.g. The build has failed with a compile error","model":"Model","followGlobalDefault":"Follow global default","modelPlaceholder":"Model ID","modelRequiredHint":"This rule calls an LLM. Make sure the selected (or global default) model is available.","confirmWithLlm":"LLM double-check before notifying","confirmWithLlmDesc":"Reduce false positives; fails open if the model is unavailable","summarizeWithLlm":"LLM notification summary","summarizeWithLlmDesc":"Summarize the screen into the notification text","intervalSeconds":"Sampling interval (seconds)","intervalHint":"Minimum {{min}}s","fireMode":"Fire mode","fireOnce":"Once (auto-disable after firing)","fireRepeat":"Repeat","cooldownSeconds":"Cooldown (seconds)","enabled":"Enabled","assistLabel":"Generate regex from a description","assistPlaceholder":"e.g. match the download progress percentage","assistButton":"Generate","assistExplanation":"Explanation","assistPreview":"Matches on current screen","assistPreviewEmpty":"No matches on the current screen sample","create":"Create","save":"Save","providerUnavailable":"Original provider unavailable","providerDisabled":"disabled"},"validation":{"nameRequired":"Rule name is required","patternRequired":"Regular expression is required","patternInvalid":"Invalid regular expression: {{detail}}","unchangedMinutesInvalid":"Unchanged minutes must be greater than 0","conditionPromptRequired":"Condition prompt is required","intervalMin":"Sampling interval must be at least {{min}} seconds"},"state":{"title":"Rule status","back":"Back","lastSampledAt":"Last sampled","lastValue":"Last value","lastValueChangedAt":"Value last changed","lastTriggeredAt":"Last triggered","consecutiveErrors":"Consecutive errors","lastError":"Last error","samples":"Recent samples","samplesEmpty":"No samples yet","hit":"hit","none":"—"},"toast":{"created":"Watch rule created","updated":"Watch rule updated","deleted":"Watch rule deleted","triggeredTitle":"Watch triggered","openTerminal":"Open terminal","modelUnavailableTitle":"Watch model unavailable","modelUnavailableHint":"The rule keeps running with degraded behavior.","ruleErrorTitle":"Watch rule auto-disabled"},"notifPermission":{"title":"Enable browser notifications?","desc":"Get notified when watch rules trigger, even when this tab is in the background.","enable":"Enable","dismiss":"Not now"}},"validation":{"deviceNameRequired":"Device name is required","hostRequired":"Host is required for SSH devices","portRequired":"A valid port is required for SSH devices","usernameRequired":"Username is required for SSH devices","sshConfigRequired":"SSH config path is required for SSH devices"},"files":{"title":"Files","refresh":"Refresh file list","noRoots":"No accessible directories. Add one in Settings → Files.","emptyDir":"Empty","truncated":"Too many items — list truncated","download":"Download","error":{"invalid":"Invalid request","outside_roots":"Path is outside the allowed directory","not_found":"No longer exists","not_a_directory":"Not a directory","is_directory":"This is a directory","too_large":"File is too large to preview","binary":"Binary file cannot be previewed","permission_denied":"Permission denied","device_not_found":"Device not found","root_not_found":"Directory entry not found","root_disabled":"This directory is disabled","connection_failed":"Failed to connect to the device","auth_unsupported":"Device auth method unsupported for files (use key or ssh-agent)","rsync_missing_local":"rsync is not installed on the server","rsync_missing_remote":"rsync is not installed on the remote device","timeout":"Timed out","unknown":"Failed to load"},"retry":"Retry (collapse then expand)","menu":{"copyAbsolute":"Copy absolute path","copyRelative":"Copy relative path","sendToAgent":"Send to Agent","expand":"Expand","collapse":"Collapse","upload":"Upload files here","open":"Open"},"copied":"Copied to clipboard","copyFailed":"Copy failed","sendToAgent":{"prompt":"Please work with this path: `{{path}}`"},"upload":{"uploading":"Uploading {{name}}…","success":"Uploaded {{name}}","fail":"Failed to upload {{name}}"},"transfer":{"legUserToTmex":"Browser → tmex","legTmexToServer":"tmex → Server","legServerToTmex":"Server → tmex","legTmexToUser":"tmex → Browser","cancel":"Cancel","canceled":"Canceled {{name}}","downloaded":"Downloaded {{name}}","downloadFailed":"Failed to download {{name}}","dragDownloadStarted":"Started downloading {{name}} (handled by browser)","tooLarge":"{{name}} exceeds the size limit ({{max}})"},"agentLaunch":{"connectFailed":"Failed to connect to the device","windowFailed":"Failed to create a window"},"install":{"button":"Install rsync","scopeLocal":"server","scopeRemote":"remote","prompt":"rsync is not installed on {{device}} ({{scope}}). Please install rsync using the appropriate command for this system (e.g. `brew install rsync`, `sudo apt-get install -y rsync`, or `sudo yum install -y rsync`), then reply once it is done."}},"file":{"invalidRef":"Invalid file reference","notFound":"File no longer exists","accessDenied":"Access denied","loadFailed":"Failed to load file","isDirectory":"This is a directory","notPreviewable":"Preview is not available for this file type","tooLarge":"File is too large to preview","binary":"Binary file cannot be previewed","download":"Download","openRaw":"Open raw"}}'),t={translation:e};export{t as default,e as translation};