tmex-cli 0.12.0 → 0.12.2

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 (80) hide show
  1. package/CHANGELOG.md +9 -23
  2. package/dist/runtime/server.js +69 -9
  3. package/package.json +1 -1
  4. package/resources/fe-dist/assets/DevicePage-B0fQ6yWB.js +25 -0
  5. package/resources/fe-dist/assets/{DevicesPage-Bm7E9QAf.js → DevicesPage-C7THDzTX.js} +2 -2
  6. package/resources/fe-dist/assets/{FilePage-DtXS6Krk.js → FilePage-D8V8P2IA.js} +2 -2
  7. package/resources/fe-dist/assets/{SettingsPage-Bxat-d_V.js → SettingsPage-BOTyBhHH.js} +8 -8
  8. package/resources/fe-dist/assets/{arc-CWkT1O24.js → arc-DcujnLz7.js} +2 -2
  9. package/resources/fe-dist/assets/architectureDiagram-3BPJPVTR-i8499Wfc.js +37 -0
  10. package/resources/fe-dist/assets/{blockDiagram-GPEHLZMM-DLFLNzT_.js → blockDiagram-GPEHLZMM-BFh4xZY2.js} +2 -2
  11. package/resources/fe-dist/assets/{c4Diagram-AAUBKEIU-BE8aWxc1.js → c4Diagram-AAUBKEIU-nUyGK7Ke.js} +2 -2
  12. package/resources/fe-dist/assets/{card-Duis2VHj.js → card-BkRqR9zz.js} +2 -2
  13. package/resources/fe-dist/assets/channel-DqmfsuLY.js +2 -0
  14. package/resources/fe-dist/assets/{chunk-2J33WTMH-Dlc3MV0y.js → chunk-2J33WTMH-z2oMKYMn.js} +2 -2
  15. package/resources/fe-dist/assets/{chunk-4BX2VUAB-E9XGobks.js → chunk-4BX2VUAB-CCD_pyAh.js} +2 -2
  16. package/resources/fe-dist/assets/{chunk-55IACEB6-Bp7ueFZf.js → chunk-55IACEB6-Dx2_9d-z.js} +2 -2
  17. package/resources/fe-dist/assets/{chunk-727SXJPM-CQrvyHfQ.js → chunk-727SXJPM-DA36poir.js} +2 -2
  18. package/resources/fe-dist/assets/{chunk-AQP2D5EJ-c0B1XNZr.js → chunk-AQP2D5EJ-CQoXkVd4.js} +2 -2
  19. package/resources/fe-dist/assets/{chunk-FMBD7UC4-BWQBkKWs.js → chunk-FMBD7UC4-A6Yn7A44.js} +2 -2
  20. package/resources/fe-dist/assets/{chunk-ND2GUHAM-D9TROogS.js → chunk-ND2GUHAM-BsNl2EMT.js} +2 -2
  21. package/resources/fe-dist/assets/{chunk-QZHKN3VN-DRXr6zVP.js → chunk-QZHKN3VN-BM_QNxf6.js} +2 -2
  22. package/resources/fe-dist/assets/classDiagram-4FO5ZUOK-D3Z9BeOE.js +2 -0
  23. package/resources/fe-dist/assets/classDiagram-v2-Q7XG4LA2-D3Z9BeOE.js +2 -0
  24. package/resources/fe-dist/assets/cose-bilkent-S5V4N54A-1lMO_Dod.js +2 -0
  25. package/resources/fe-dist/assets/{dagre-BM42HDAG-ClYznWvX.js → dagre-BM42HDAG-C9Up3ckQ.js} +2 -2
  26. package/resources/fe-dist/assets/{diagram-2AECGRRQ-Br_41uIc.js → diagram-2AECGRRQ-CtuDndmY.js} +2 -2
  27. package/resources/fe-dist/assets/{diagram-5GNKFQAL-BD9o1BrS.js → diagram-5GNKFQAL-BQfskK8S.js} +2 -2
  28. package/resources/fe-dist/assets/{diagram-KO2AKTUF-Diq2zS9Y.js → diagram-KO2AKTUF-CGJi8q81.js} +2 -2
  29. package/resources/fe-dist/assets/{diagram-LMA3HP47-CLaOalPy.js → diagram-LMA3HP47-DAMQIoLQ.js} +2 -2
  30. package/resources/fe-dist/assets/{diagram-OG6HWLK6-BcSlvdPy.js → diagram-OG6HWLK6-D2s__dFc.js} +2 -2
  31. package/resources/fe-dist/assets/{erDiagram-TEJ5UH35-BNlad0c4.js → erDiagram-TEJ5UH35-_UJYLIQN.js} +2 -2
  32. package/resources/fe-dist/assets/{flowDiagram-I6XJVG4X-Zb1FLY00.js → flowDiagram-I6XJVG4X-DN-qktDh.js} +2 -2
  33. package/resources/fe-dist/assets/ganttDiagram-6RSMTGT7-CNuuuhXX.js +293 -0
  34. package/resources/fe-dist/assets/{gitGraphDiagram-PVQCEYII-BENU2uEN.js → gitGraphDiagram-PVQCEYII-Qar2sVRo.js} +2 -2
  35. package/resources/fe-dist/assets/index-BhU3LRKb.css +1 -0
  36. package/resources/fe-dist/assets/{index-Den36xcn.js → index-Ra6pj0rt.js} +116 -116
  37. package/resources/fe-dist/assets/{infoDiagram-5YYISTIA-NfMlH21e.js → infoDiagram-5YYISTIA-2e6tU_v9.js} +2 -2
  38. package/resources/fe-dist/assets/{ishikawaDiagram-YF4QCWOH-CzK9-7uY.js → ishikawaDiagram-YF4QCWOH-BghKvoM4.js} +2 -2
  39. package/resources/fe-dist/assets/{journeyDiagram-JHISSGLW-CIX5Ahuw.js → journeyDiagram-JHISSGLW-D-cHSGb_.js} +2 -2
  40. package/resources/fe-dist/assets/{kanban-definition-UN3LZRKU-C5Ccl5Cw.js → kanban-definition-UN3LZRKU-BE6Cb-OK.js} +2 -2
  41. package/resources/fe-dist/assets/{linear-CBC08yeS.js → linear-CwDBnUH0.js} +2 -2
  42. package/resources/fe-dist/assets/{markdown-preview-Drd503bU.js → markdown-preview-BlQiC8ND.js} +4 -4
  43. package/resources/fe-dist/assets/{mermaid.core-DYl6mxS0.js → mermaid.core-DDMkLXrp.js} +6 -6
  44. package/resources/fe-dist/assets/{mindmap-definition-RKZ34NQL-ACR2SUDm.js → mindmap-definition-RKZ34NQL-C9xVR7Ut.js} +2 -2
  45. package/resources/fe-dist/assets/{pieDiagram-4H26LBE5-BuDDdwwy.js → pieDiagram-4H26LBE5-DW_4RcBv.js} +2 -2
  46. package/resources/fe-dist/assets/{quadrantDiagram-W4KKPZXB-CzM2Ydhy.js → quadrantDiagram-W4KKPZXB-DoIrZmk2.js} +2 -2
  47. package/resources/fe-dist/assets/{requirementDiagram-4Y6WPE33-BveKh_kW.js → requirementDiagram-4Y6WPE33-CYcJSuPe.js} +2 -2
  48. package/resources/fe-dist/assets/{sankeyDiagram-5OEKKPKP-BGQ6jtyE.js → sankeyDiagram-5OEKKPKP-CrIkKM6h.js} +2 -2
  49. package/resources/fe-dist/assets/{sequenceDiagram-3UESZ5HK-D2fdqire.js → sequenceDiagram-3UESZ5HK-DgzGHhGk.js} +2 -2
  50. package/resources/fe-dist/assets/{stateDiagram-AJRCARHV-DtuVBIq9.js → stateDiagram-AJRCARHV-C6Dhr3fY.js} +2 -2
  51. package/resources/fe-dist/assets/stateDiagram-v2-BHNVJYJU-BiSh2azE.js +2 -0
  52. package/resources/fe-dist/assets/terminal-settings-panel-CpnmWQtf.js +9 -0
  53. package/resources/fe-dist/assets/{timeline-definition-PNZ67QCA-Dslo0JFS.js → timeline-definition-PNZ67QCA-jJ1iauQ0.js} +2 -2
  54. package/resources/fe-dist/assets/{vennDiagram-CIIHVFJN-BLcoN4xU.js → vennDiagram-CIIHVFJN-DLRoaoJ9.js} +2 -2
  55. package/resources/fe-dist/assets/{wardley-L42UT6IY-OsbD5r1L.js → wardley-L42UT6IY-CykeHWp8.js} +2 -2
  56. package/resources/fe-dist/assets/{wardleyDiagram-YWT4CUSO-B_33zIif.js → wardleyDiagram-YWT4CUSO-U22jzD8a.js} +2 -2
  57. package/resources/fe-dist/assets/{xychartDiagram-2RQKCTM6-DcB27Ap1.js → xychartDiagram-2RQKCTM6-CiXS9PJ2.js} +2 -2
  58. package/resources/fe-dist/fonts/generated/blex-mono/blex-mono-bold.woff2 +0 -0
  59. package/resources/fe-dist/fonts/generated/blex-mono/blex-mono-regular.woff2 +0 -0
  60. package/resources/fe-dist/fonts/generated/fira-code/fira-code-bold.woff2 +0 -0
  61. package/resources/fe-dist/fonts/generated/fira-code/fira-code-regular.woff2 +0 -0
  62. package/resources/fe-dist/fonts/generated/jetbrains-mono/jetbrains-mono-bold.woff2 +0 -0
  63. package/resources/fe-dist/fonts/generated/jetbrains-mono/jetbrains-mono-regular.woff2 +0 -0
  64. package/resources/fe-dist/fonts/generated/noto-sans-mono/noto-sans-mono-bold.woff2 +0 -0
  65. package/resources/fe-dist/fonts/generated/noto-sans-mono/noto-sans-mono-regular.woff2 +0 -0
  66. package/resources/fe-dist/fonts/generated/victor-mono/victor-mono-bold.woff2 +0 -0
  67. package/resources/fe-dist/fonts/generated/victor-mono/victor-mono-regular.woff2 +0 -0
  68. package/resources/fe-dist/fonts/generated/zed-mono/zed-mono-bold.woff2 +0 -0
  69. package/resources/fe-dist/fonts/generated/zed-mono/zed-mono-regular.woff2 +0 -0
  70. package/resources/fe-dist/index.html +2 -2
  71. package/resources/fe-dist/assets/DevicePage-B2xsa-ys.js +0 -21
  72. package/resources/fe-dist/assets/architectureDiagram-3BPJPVTR-nu1LX68y.js +0 -37
  73. package/resources/fe-dist/assets/channel-zKL2OH3S.js +0 -2
  74. package/resources/fe-dist/assets/classDiagram-4FO5ZUOK-Drw216KI.js +0 -2
  75. package/resources/fe-dist/assets/classDiagram-v2-Q7XG4LA2-Drw216KI.js +0 -2
  76. package/resources/fe-dist/assets/cose-bilkent-S5V4N54A-CBgJRn7g.js +0 -2
  77. package/resources/fe-dist/assets/ganttDiagram-6RSMTGT7-DPRPR5Is.js +0 -293
  78. package/resources/fe-dist/assets/index-CRCD4gPw.css +0 -1
  79. package/resources/fe-dist/assets/refresh-cw-DhzvbVDA.js +0 -7
  80. package/resources/fe-dist/assets/stateDiagram-v2-BHNVJYJU-gun__PvU.js +0 -2
package/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- # 0.12.0
1
+ # 0.12.2
2
2
 
3
3
  _2026-06-15_
4
4
 
@@ -6,20 +6,13 @@ _2026-06-15_
6
6
 
7
7
  ### New
8
8
 
9
- - Files: the file tree now has a right-click / long-press menu, and large files transfer with live progress, speed, and a cancel button (up to 2 GB).
10
- - Files: dragging a file to your desktop now shows a brief notification once the download finishes.
9
+ - Terminal font settings: pick from bundled monospaced fonts and adjust the font size and line height. Changes apply live to your terminals, and the chosen font is used for monospaced text across the app.
10
+ - Mobile keyboard behavior: choose how the page reacts when the on-screen keyboard opens shift the page up, resize the terminal, or keep the cursor above the keyboard — for smoother typing on phones.
11
11
 
12
12
  ### Improvements
13
13
 
14
- - Files: better transfer feedback a two-stage progress bar, dark-theme support, file sizes shown in the menu, and human-readable sizes in the preview.
15
- - This changelog is now bilingual (English first, then Chinese).
16
-
17
- ### Fixes
18
-
19
- - Terminal: fixed inconsistent line height across platforms and glyphs being clipped at the top or bottom.
20
- - SSH: fixed connections that authenticate via an SSH config reference, and now show the real error when a connection fails.
21
- - Files: fixed some downloads failing with a 500 error.
22
- - Notifications: fixed pane links in Telegram messages failing to open because they were double-encoded.
14
+ - Terminal settings are now in one place: a dedicated Settings tab and a quick panel from the terminal, both with a live preview.
15
+ - UI polish and refinements (spacing, dark-mode readability, settings tabs on mobile).
23
16
 
24
17
  ---
25
18
 
@@ -27,17 +20,10 @@ _2026-06-15_
27
20
 
28
21
  ### 新增
29
22
 
30
- - 文件浏览:文件树新增右键 / 长按菜单,大文件传输支持实时进度、速度与取消(最大 2GB)。
31
- - 文件浏览:把文件拖到桌面,下载完成后会有一条轻提示。
23
+ - 终端字体设置:可从内置等宽字体中选择,并调整字号与行高。改动实时应用到当前终端,所选字体也会用于全应用的等宽文本。
24
+ - 手机键盘行为:可选择软键盘弹出时页面的避让方式——整页上移、缩放终端、或让光标始终在键盘上方——手机上输入更顺手。
32
25
 
33
26
  ### 改进
34
27
 
35
- - 文件浏览:传输反馈更完善——两段式进度条、跟随暗色主题、菜单显示文件大小、预览大小以人类可读格式展示。
36
- - 更新日志现在提供中英双语(先英文、后中文)。
37
-
38
- ### 修复
39
-
40
- - 终端:修复文字行高在不同平台不一致、字形顶部或底部被裁切的问题。
41
- - SSH:修复使用 SSH 配置引用进行认证的连接,连接失败时现在会显示真实错误。
42
- - 文件浏览:修复部分文件下载失败(500)的问题。
43
- - 通知:修复 Telegram 消息中 pane 链接因二次编码而无法打开的问题。
28
+ - 终端设置集中到一处:独立的「终端」设置页,以及终端内的快捷面板,均带实时预览。
29
+ - 界面细节优化(间距、深色模式可读性、移动端设置 tab 等)。
@@ -22688,6 +22688,16 @@ var I18N_RESOURCES = {
22688
22688
  delete: "Delete"
22689
22689
  },
22690
22690
  terminal: {
22691
+ keyboardBehavior: {
22692
+ title: "Keyboard Behavior",
22693
+ description: "How the page makes room for the on-screen keyboard",
22694
+ modeLift: "Shift page",
22695
+ modeLiftDesc: "Move the whole page up; terminal size stays the same",
22696
+ modeResize: "Resize terminal",
22697
+ modeResizeDesc: "Shrink the terminal to fit above the keyboard (changes the remote window size)",
22698
+ modeFollow: "Follow cursor",
22699
+ modeFollowDesc: "Shift just enough to keep the cursor right above the keyboard; terminal size stays the same"
22700
+ },
22691
22701
  initializing: "Initializing terminal...",
22692
22702
  connecting: "Connecting to device...",
22693
22703
  initFailed: "Terminal initialization failed",
@@ -22751,7 +22761,17 @@ var I18N_RESOURCES = {
22751
22761
  general: "General",
22752
22762
  devicesAndFiles: "Devices & Files",
22753
22763
  notifications: "Notifications",
22754
- ai: "AI"
22764
+ ai: "AI",
22765
+ terminal: "Terminal"
22766
+ },
22767
+ terminal: {
22768
+ title: "Terminal Settings",
22769
+ description: "Adjust the terminal font size, line height, family, and mobile keyboard avoidance. The font family applies to all monospaced text across the app.",
22770
+ fontSize: "Font Size",
22771
+ lineHeight: "Line Height",
22772
+ fontFamily: "Font",
22773
+ preview: "Preview",
22774
+ savedInBrowser: "These settings are saved in this browser only."
22755
22775
  },
22756
22776
  deviceManagement: {
22757
22777
  title: "Device Management",
@@ -23551,6 +23571,16 @@ Time: {{time}}`,
23551
23571
  delete: "\u5220\u9664"
23552
23572
  },
23553
23573
  terminal: {
23574
+ keyboardBehavior: {
23575
+ title: "\u952E\u76D8\u884C\u4E3A",
23576
+ description: "\u9009\u62E9\u624B\u673A\u952E\u76D8\u5F39\u51FA\u65F6\u9875\u9762\u7684\u907F\u8BA9\u65B9\u5F0F",
23577
+ modeLift: "\u9875\u9762\u5E73\u79FB",
23578
+ modeLiftDesc: "\u952E\u76D8\u5F39\u51FA\u65F6\u6574\u9875\u4E0A\u79FB\uFF0C\u7EC8\u7AEF\u5927\u5C0F\u4E0D\u53D8",
23579
+ modeResize: "\u7EC8\u7AEF\u7F29\u653E",
23580
+ modeResizeDesc: "\u7F29\u5C0F\u7EC8\u7AEF\u94FA\u6EE1\u952E\u76D8\u4E0A\u65B9\u533A\u57DF\uFF08\u4F1A\u8C03\u6574\u8FDC\u7AEF\u7A97\u53E3\u884C\u6570\uFF09",
23581
+ modeFollow: "\u5149\u6807\u5BF9\u9F50",
23582
+ modeFollowDesc: "\u6309\u5149\u6807\u4F4D\u7F6E\u4E0A\u79FB\uFF0C\u5149\u6807\u59CB\u7EC8\u5728\u952E\u76D8\u6B63\u4E0A\u65B9\uFF0C\u7EC8\u7AEF\u5927\u5C0F\u4E0D\u53D8"
23583
+ },
23554
23584
  initializing: "\u521D\u59CB\u5316\u7EC8\u7AEF...",
23555
23585
  connecting: "\u8FDE\u63A5\u8BBE\u5907...",
23556
23586
  initFailed: "\u7EC8\u7AEF\u521D\u59CB\u5316\u5931\u8D25",
@@ -23611,10 +23641,20 @@ Time: {{time}}`,
23611
23641
  siteTab: "\u7AD9\u70B9",
23612
23642
  notificationsTab: "\u901A\u77E5",
23613
23643
  tabGroup: {
23614
- general: "\u901A\u7528\u8BBE\u7F6E",
23644
+ general: "\u901A\u7528",
23615
23645
  devicesAndFiles: "\u8BBE\u5907\u4E0E\u6587\u4EF6",
23616
- notifications: "\u901A\u77E5\u8BBE\u7F6E",
23617
- ai: "AI \u8BBE\u7F6E"
23646
+ notifications: "\u901A\u77E5",
23647
+ ai: "AI",
23648
+ terminal: "\u7EC8\u7AEF"
23649
+ },
23650
+ terminal: {
23651
+ title: "\u7EC8\u7AEF\u8BBE\u7F6E",
23652
+ description: "\u8C03\u6574\u7EC8\u7AEF\u7684\u5B57\u53F7\u3001\u884C\u9AD8\u3001\u5B57\u4F53\u4E0E\u624B\u673A\u952E\u76D8\u907F\u8BA9\u884C\u4E3A\u3002\u5B57\u4F53\u9009\u62E9\u5BF9\u5168\u5E94\u7528\u6240\u6709\u7B49\u5BBD\u6587\u672C\u751F\u6548\u3002",
23653
+ fontSize: "\u5B57\u53F7",
23654
+ lineHeight: "\u884C\u9AD8",
23655
+ fontFamily: "\u5B57\u4F53",
23656
+ preview: "\u9884\u89C8",
23657
+ savedInBrowser: "\u8FD9\u4E9B\u8BBE\u7F6E\u4EC5\u4FDD\u5B58\u5728\u5F53\u524D\u6D4F\u89C8\u5668\u4E2D\u3002"
23618
23658
  },
23619
23659
  deviceManagement: {
23620
23660
  title: "\u8BBE\u5907\u7BA1\u7406",
@@ -24414,6 +24454,16 @@ Bot\uFF1A{{botName}}
24414
24454
  delete: "\u524A\u9664"
24415
24455
  },
24416
24456
  terminal: {
24457
+ keyboardBehavior: {
24458
+ title: "\u30AD\u30FC\u30DC\u30FC\u30C9\u52D5\u4F5C",
24459
+ description: "\u30BD\u30D5\u30C8\u30A6\u30A7\u30A2\u30AD\u30FC\u30DC\u30FC\u30C9\u8868\u793A\u6642\u306E\u30DA\u30FC\u30B8\u306E\u56DE\u907F\u65B9\u6CD5",
24460
+ modeLift: "\u30DA\u30FC\u30B8\u79FB\u52D5",
24461
+ modeLiftDesc: "\u30AD\u30FC\u30DC\u30FC\u30C9\u8868\u793A\u6642\u306B\u30DA\u30FC\u30B8\u5168\u4F53\u3092\u4E0A\u306B\u79FB\u52D5\uFF08\u7AEF\u672B\u30B5\u30A4\u30BA\u306F\u4E0D\u5909\uFF09",
24462
+ modeResize: "\u7AEF\u672B\u30EA\u30B5\u30A4\u30BA",
24463
+ modeResizeDesc: "\u30AD\u30FC\u30DC\u30FC\u30C9\u4E0A\u306E\u9818\u57DF\u306B\u5408\u308F\u305B\u3066\u7AEF\u672B\u3092\u7E2E\u5C0F\uFF08\u30EA\u30E2\u30FC\u30C8\u306E\u884C\u6570\u304C\u5909\u308F\u308A\u307E\u3059\uFF09",
24464
+ modeFollow: "\u30AB\u30FC\u30BD\u30EB\u8FFD\u5F93",
24465
+ modeFollowDesc: "\u30AB\u30FC\u30BD\u30EB\u304C\u30AD\u30FC\u30DC\u30FC\u30C9\u306E\u771F\u4E0A\u306B\u6765\u308B\u3088\u3046\u79FB\u52D5\uFF08\u7AEF\u672B\u30B5\u30A4\u30BA\u306F\u4E0D\u5909\uFF09"
24466
+ },
24417
24467
  initializing: "\u30BF\u30FC\u30DF\u30CA\u30EB\u3092\u521D\u671F\u5316\u4E2D...",
24418
24468
  connecting: "\u30C7\u30D0\u30A4\u30B9\u306B\u63A5\u7D9A\u4E2D...",
24419
24469
  initFailed: "\u30BF\u30FC\u30DF\u30CA\u30EB\u306E\u521D\u671F\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
@@ -24474,10 +24524,20 @@ Bot\uFF1A{{botName}}
24474
24524
  siteTab: "\u30B5\u30A4\u30C8",
24475
24525
  notificationsTab: "\u901A\u77E5",
24476
24526
  tabGroup: {
24477
- general: "\u4E00\u822C\u8A2D\u5B9A",
24527
+ general: "\u4E00\u822C",
24478
24528
  devicesAndFiles: "\u30C7\u30D0\u30A4\u30B9\u3068\u30D5\u30A1\u30A4\u30EB",
24479
- notifications: "\u901A\u77E5\u8A2D\u5B9A",
24480
- ai: "AI \u8A2D\u5B9A"
24529
+ notifications: "\u901A\u77E5",
24530
+ ai: "AI",
24531
+ terminal: "\u30BF\u30FC\u30DF\u30CA\u30EB"
24532
+ },
24533
+ terminal: {
24534
+ title: "\u30BF\u30FC\u30DF\u30CA\u30EB\u8A2D\u5B9A",
24535
+ description: "\u30BF\u30FC\u30DF\u30CA\u30EB\u306E\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA\u30FB\u884C\u306E\u9AD8\u3055\u30FB\u30D5\u30A9\u30F3\u30C8\u3001\u30E2\u30D0\u30A4\u30EB\u306E\u30AD\u30FC\u30DC\u30FC\u30C9\u56DE\u907F\u3092\u8ABF\u6574\u3057\u307E\u3059\u3002\u30D5\u30A9\u30F3\u30C8\u306E\u9078\u629E\u306F\u30A2\u30D7\u30EA\u5168\u4F53\u306E\u7B49\u5E45\u30C6\u30AD\u30B9\u30C8\u306B\u9069\u7528\u3055\u308C\u307E\u3059\u3002",
24536
+ fontSize: "\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA",
24537
+ lineHeight: "\u884C\u306E\u9AD8\u3055",
24538
+ fontFamily: "\u30D5\u30A9\u30F3\u30C8",
24539
+ preview: "\u30D7\u30EC\u30D3\u30E5\u30FC",
24540
+ savedInBrowser: "\u3053\u308C\u3089\u306E\u8A2D\u5B9A\u306F\u3053\u306E\u30D6\u30E9\u30A6\u30B6\u306B\u306E\u307F\u4FDD\u5B58\u3055\u308C\u307E\u3059\u3002"
24481
24541
  },
24482
24542
  deviceManagement: {
24483
24543
  title: "\u30C7\u30D0\u30A4\u30B9\u7BA1\u7406",
@@ -104850,8 +104910,8 @@ function getBaseVersion() {
104850
104910
  if (cachedBase !== undefined)
104851
104911
  return cachedBase;
104852
104912
  let base = null;
104853
- if ("0.12.0") {
104854
- base = "0.12.0";
104913
+ if ("0.12.2") {
104914
+ base = "0.12.2";
104855
104915
  }
104856
104916
  if (!base && config.isProd) {
104857
104917
  base = readInstallMeta()?.cliVersion ?? null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tmex-cli",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "tmex": "./bin/tmex.js",
@@ -0,0 +1,25 @@
1
+ import{Y as je,u as Ee,j as o,ag as Ge,ah as Ke,ai as Ve,aj as Je,ak as Qe,al as Ze,am as et,r,d as V,a7 as te,aa as Fe,a9 as We,a8 as tt,ab as nt,an as rt,ao as _e,ap as st,o as xe,aq as ot,ar as Pe,as as it,b as He,at as Le,au as ct,c as $e,av as Oe,aw as pe,ax as at,ay as Me,az as lt,B as le,T as ut,aA as De,aB as dt,aC as ft,aD as mt,A as ht,f as wt,g as pt,i as xt,k as vt,l as gt,m as bt,n as St,aE as yt,aF as Et}from"./index-Ra6pj0rt.js";import{T as Tt,c as Rt,F as kt,a as qe,R as Ct}from"./terminal-settings-panel-CpnmWQtf.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 It=[["path",{d:"M12 17V3",key:"1cwfxf"}],["path",{d:"m6 11 6 6 6-6",key:"12ii2o"}],["path",{d:"M19 21H5",key:"150jfl"}]],jt=je("arrow-down-to-line",It);/**
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 Nt=[["path",{d:"M11 14h10",key:"1w8e9d"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v1.344",key:"1e62lh"}],["path",{d:"m17 18 4-4-4-4",key:"z2g111"}],["path",{d:"M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113",key:"bjbb7m"}],["rect",{x:"8",y:"2",width:"8",height:"4",rx:"1",key:"ublpy"}]],Mt=je("clipboard-paste",Nt);/**
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 At=[["path",{d:"M14 17H5",key:"gfn3mx"}],["path",{d:"M19 7h-9",key:"6i9tg"}],["circle",{cx:"17",cy:"17",r:"3",key:"18b49y"}],["circle",{cx:"7",cy:"7",r:"3",key:"dfmy0x"}]],Pt=je("settings-2",At);/**
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 Lt=[["rect",{width:"14",height:"20",x:"5",y:"2",rx:"2",ry:"2",key:"1yt0o3"}],["path",{d:"M12 18h.01",key:"mhygvu"}]],_t=je("smartphone",Lt);function Dt({open:n,onOpenChange:e}){const{t:i}=Ee();return o.jsx(Ge,{open:n,onOpenChange:e,children:o.jsxs(Ke,{side:"bottom",className:"max-h-[88dvh] overflow-y-auto pb-[var(--tmex-safe-area-bottom)] sm:mx-auto sm:max-w-md sm:rounded-t-2xl sm:border sm:border-b-0","data-testid":"keyboard-behavior-sheet",children:[o.jsxs(Ve,{children:[o.jsx(Je,{children:i("settings.terminal.title")}),o.jsx(Qe,{children:i("settings.terminal.savedInBrowser")})]}),o.jsx("div",{className:"px-4 pb-4",children:o.jsx(Tt,{})})]})})}function zt({visible:n,canPaste:e,onCopy:i,onPaste:c,onDismiss:p}){const{t:E}=Ee();if(!n)return null;const S=x=>{x.preventDefault()};return o.jsxs("div",{className:"absolute top-2 left-1/2 z-20 flex -translate-x-1/2 items-center gap-1 rounded-lg border bg-background/95 p-1 shadow-md backdrop-blur","data-testid":"terminal-selection-toolbar",children:[o.jsxs("button",{type:"button",className:"flex h-9 items-center gap-1.5 rounded-md px-3 text-sm font-medium hover:bg-accent hover:text-accent-foreground",onMouseDown:S,onClick:i,"data-testid":"terminal-selection-copy",children:[o.jsx(Ze,{className:"h-4 w-4"}),E("terminal.copy")]}),e&&o.jsxs("button",{type:"button",className:"flex h-9 items-center gap-1.5 rounded-md px-3 text-sm font-medium hover:bg-accent hover:text-accent-foreground",onMouseDown:S,onClick:c,"data-testid":"terminal-selection-paste",children:[o.jsx(Mt,{className:"h-4 w-4"}),E("terminal.paste")]}),o.jsx("button",{type:"button",className:"flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-accent-foreground",onMouseDown:S,onClick:p,"aria-label":E("terminal.clearSelection"),"data-testid":"terminal-selection-dismiss",children:o.jsx(et,{className:"h-4 w-4"})})]})}function Ue(n){if(!n)return n;const e=n.replace(/\r\n/g,`
22
+ `);return(e.endsWith(`
23
+ `)?e.slice(0,-1):e).replace(/\n/g,`\r
24
+ `)}const Bt="\x1B[?1049h\x1B[H\x1B[2J";function Ft(n){return Bt+Ue(n)}function ze(n,e){let i=e,c=0;for(const x of n)x===10&&!i&&(c+=1),i=x===13;const p=i;if(c===0)return{normalized:n,endedWithCR:p};const E=new Uint8Array(n.length+c);let S=0;i=e;for(const x of n)x===10&&!i&&(E[S]=13,S+=1),E[S]=x,S+=1,i=x===13;return{normalized:E,endedWithCR:p}}const Wt=1.3,Ht=36,$t=500,Ot=12;function qt(n,e){const i=r.useRef(!1);return r.useEffect(()=>{const c=n.current;if(!c||!(window.innerWidth<768||navigator.maxTouchPoints>0||"ontouchstart"in window))return;i.current=!0;let E=0,S=null,x=!1,R=0,G=0,s=0,I=null,F=!1;const K=()=>{I!==null&&(clearTimeout(I),I=null)},q=w=>w?!!(w.closest(".scrollbar")||w.closest(".slider")||w.closest(".xterm-scroll-area")):!1,g=(w,m,y)=>{const N=y instanceof Element?y:null;if(q(N))return!0;const O=document.elementFromPoint(w,m);if(q(O))return!0;const h=c.querySelector(".xterm");if(!(h instanceof HTMLElement))return!1;const v=h.getBoundingClientRect(),_=w>=v.left&&w<=v.right,D=m>=v.top&&m<=v.bottom;return!_||!D?!1:w>=v.right-Ht},J=()=>[c.querySelector(".xterm-viewport"),c.querySelector(".xterm-scrollable-element")].filter(m=>m instanceof HTMLElement),f=w=>{if(S===null)return null;for(let m=0;m<w.length;m+=1){const y=w.item(m);if(y&&y.identifier===S)return y}return null},P=w=>{if(K(),w.touches.length!==1)return;const m=w.touches.item(0);m&&(S=m.identifier,E=m.clientY,R=0,x=g(m.clientX,m.clientY,w.target),G=m.clientX,s=m.clientY,F=!1,x||(I=setTimeout(()=>{var N;I=null;const y=(e==null?void 0:e())??null;(N=y==null?void 0:y.startTouchSelection)!=null&&N.call(y,G,s,"word")&&(F=!0)},$t)))},L=w=>{var _,D,T,U,Y,X,se,k,ne;const m=f(w.touches)??w.touches.item(0);if(!m)return;if(F){const A=(e==null?void 0:e())??null;(_=A==null?void 0:A.updateTouchSelection)==null||_.call(A,m.clientX,m.clientY),w.cancelable&&w.preventDefault();return}if(I!==null&&Math.hypot(m.clientX-G,m.clientY-s)>Ot&&K(),x||(x=g(m.clientX,m.clientY,w.target),x&&(R=0)),x)return;const y=m.clientY,N=E-y;if(E=y,N===0)return;let O=!1,h=!1;const v=(e==null?void 0:e())??null;if(v){const A=v==null?void 0:v._core,M=((Y=(U=(T=(D=A==null?void 0:A._renderService)==null?void 0:D.dimensions)==null?void 0:T.css)==null?void 0:U.cell)==null?void 0:Y.height)??18;R+=N*Wt;const j=R>0?Math.floor(R/M):Math.ceil(R/M);if(typeof v.handleViewportGesture=="function")j!==0&&(O=v.handleViewportGesture({source:"touch",deltaY:j*M,clientX:m.clientX,clientY:m.clientY}),R-=j*M);else if(j!==0){const B=((se=(X=v.buffer)==null?void 0:X.active)==null?void 0:se.viewportY)??0;v.scrollLines(j);const re=((ne=(k=v.buffer)==null?void 0:k.active)==null?void 0:ne.viewportY)??0;O=B!==re,h=j<0&&B<=0&&re<=0,R-=j*M}}else{const A=J();if(A.length===0)return;for(const M of A){const j=M.scrollTop;M.scrollTop+=N;const B=M.scrollTop;Math.abs(B-j)>0&&(O=!0),N<0&&B<=0&&(h=!0)}if(!O){const M=c.querySelector(".xterm");if(M instanceof HTMLElement){const j=new WheelEvent("wheel",{bubbles:!0,cancelable:!0,deltaMode:WheelEvent.DOM_DELTA_PIXEL,deltaY:N}),B=M.dispatchEvent(j);O=j.defaultPrevented||!B}}}w.cancelable&&(O||h)&&w.preventDefault()},z=w=>{var y;if(K(),!(S===null||!f(w.changedTouches))&&(S=null,R=0,x=!1,F)){F=!1;const N=(e==null?void 0:e())??null;(y=N==null?void 0:N.endTouchSelection)==null||y.call(N)}},H=w=>{F&&w.preventDefault()};return c.addEventListener("touchstart",P,{passive:!0}),c.addEventListener("touchmove",L,{passive:!1}),c.addEventListener("touchend",z,{passive:!0}),c.addEventListener("touchcancel",z,{passive:!0}),c.addEventListener("contextmenu",H),()=>{i.current=!1,K(),c.removeEventListener("touchstart",P),c.removeEventListener("touchmove",L),c.removeEventListener("touchend",z),c.removeEventListener("touchcancel",z),c.removeEventListener("contextmenu",H)}},[n,e]),i}function Ut({now:n,remoteSize:e,pendingLocalSize:i,ttlMs:c=2e3}){return!i||n-i.at>c?!0:i.cols===e.cols&&i.rows===e.rows}function Yt({currentSize:n,containerSize:e,force:i=!1}){return i?!0:n.cols!==e.cols||n.rows!==e.rows}function Xt({deviceId:n,paneId:e,deviceConnected:i,isSelectionInvalid:c,onResize:p,onSync:E,getContainerRect:S}){const x=r.useRef(null),R=r.useRef(null),G=r.useRef(null),s=r.useRef(null),I=r.useRef(0),F=r.useRef([]),K=r.useRef(null),q=r.useRef(null),g=r.useRef(S),J=r.useRef(!1),f=r.useRef(p),P=r.useRef(E);r.useEffect(()=>{f.current=p},[p]),r.useEffect(()=>{P.current=E},[E]),r.useEffect(()=>{g.current=S},[S]);const L=r.useCallback(()=>{var X,se,k,ne,A,M,j,B,re,ve;const h=q.current,v=K.current;if(!h||!v||!h.element)return null;let _;try{const ae=v.proposeDimensions();if(!ae)throw new Error("fitAddon.proposeDimensions() returned null");_=Math.max(2,ae.cols)}catch{const ae=h._core,Te=((ne=(k=(se=(X=ae==null?void 0:ae._renderService)==null?void 0:X.dimensions)==null?void 0:se.css)==null?void 0:k.cell)==null?void 0:ne.width)??9,a=(A=g.current)==null?void 0:A.call(g);if(!a||a.width===0)return null;_=Math.max(2,Math.floor(a.width/Te))}const D=(M=g.current)==null?void 0:M.call(g);if(!D||D.height===0)return null;const T=h._core,U=((ve=(re=(B=(j=T==null?void 0:T._renderService)==null?void 0:j.dimensions)==null?void 0:B.css)==null?void 0:re.cell)==null?void 0:ve.height)??17,Y=Math.max(2,Math.floor(D.height/U));return{cols:_,rows:Y}},[]),z=r.useCallback((h,v)=>{const _=q.current;_&&(_.cols===h&&_.rows===v||_.resize(h,v))},[]),H=r.useCallback((h,v=!1)=>{if(!n||!e||!i||c&&h!=="sync"||!v&&Date.now()<I.current||!q.current)return!1;const D=L();if(!D)return!1;const{cols:T,rows:U}=D,Y=G.current;return!v&&Y&&Y.cols===T&&Y.rows===U?(z(T,U),!0):(z(T,U),h==="sync"?P.current(T,U):f.current(T,U),G.current={cols:T,rows:U},s.current={cols:T,rows:U,at:Date.now()},!0)},[z,i,n,c,L,e]),w=r.useCallback((h="resize",v={})=>{const{immediate:_=!1,force:D=!1}=v;R.current!==null&&(window.clearTimeout(R.current),R.current=null),x.current!==null&&(cancelAnimationFrame(x.current),x.current=null);const T=()=>{x.current=requestAnimationFrame(()=>{x.current=null,H(h,D)})};if(_){T();return}R.current=window.setTimeout(()=>{R.current=null,T()},150)},[H]),m=r.useCallback(()=>{for(const h of F.current)window.clearTimeout(h);F.current=[]},[]),y=r.useCallback(()=>{var v;m(),w("sync",{immediate:!0,force:!0});const h=window.setTimeout(()=>{w("sync",{immediate:!0,force:!0})},60);F.current.push(h),typeof document<"u"&&"fonts"in document&&((v=document.fonts)!=null&&v.ready)&&document.fonts.ready.then(()=>{w("sync",{immediate:!0,force:!0})}).catch(()=>{})},[m,w]);r.useEffect(()=>{let h=null;const v=()=>{h!==null&&cancelAnimationFrame(h),h=requestAnimationFrame(()=>{h=null,w("resize")})};return window.addEventListener("resize",v),()=>{window.removeEventListener("resize",v),h!==null&&cancelAnimationFrame(h)}},[w]),r.useEffect(()=>{const h=()=>{var X;const T=q.current,U=L();if(!T||!U)return;if(!Yt({currentSize:{cols:Math.max(2,T.cols),rows:Math.max(2,T.rows)},containerSize:U})){(X=T.refresh)==null||X.call(T);return}w("sync",{force:!0})},v=()=>{if(document.visibilityState!=="visible"){J.current=!0;return}J.current&&(J.current=!1,h())},_=()=>{J.current=!0},D=()=>{J.current&&(J.current=!1,h())};return document.addEventListener("visibilitychange",v),window.addEventListener("blur",_),window.addEventListener("focus",D),()=>{document.removeEventListener("visibilitychange",v),window.removeEventListener("blur",_),window.removeEventListener("focus",D)}},[L,w]),r.useEffect(()=>()=>{m(),R.current!==null&&window.clearTimeout(R.current),x.current!==null&&cancelAnimationFrame(x.current)},[m]);const N=r.useCallback(h=>{K.current=h},[]),O=r.useCallback(h=>{q.current=h},[]);return{scheduleResize:w,runPostSelectResize:y,clearPostSelectResizeTimers:m,setFitAddon:N,setTerminal:O,lastReportedSize:G,pendingLocalSize:s,suppressLocalResizeUntil:I}}const Gt=1e4,Ae="tmex:terminal-mode-cache";function Kt(n,e){try{const i=sessionStorage.getItem(Ae);return i?JSON.parse(i)[`${n}:${e}`]??null:null}catch{return null}}function Vt(n,e,i){try{const c=sessionStorage.getItem(Ae),p=c?JSON.parse(c):{},E=`${n}:${e}`;i?p[E]=i:delete p[E],sessionStorage.setItem(Ae,JSON.stringify(p))}catch{}}function Jt(){return{mouseX10:!1,mouseNormal:!0,mouseButton:!1,mouseAny:!1,mouseUtf8:!1,mouseSgr:!0,mouseSgrPixels:!1,mouseUrxvt:!1,altScroll:!0,altScreen1047:!1,altScreen1049:!1}}function Qt(n,e){if(!e)return n?{...n,mouseX10:!1,mouseNormal:!1,mouseButton:!1,mouseAny:!1,mouseUtf8:!1,mouseSgrPixels:!1,mouseUrxvt:!1,altScreen1047:!1,altScreen1049:!1}:null;const i=Jt();if(!n)return i;const c=n.mouseNormal||n.mouseButton||n.mouseAny;return{...n,mouseX10:!1,mouseUtf8:!1,mouseSgr:!0,mouseSgrPixels:!1,mouseUrxvt:!1,altScroll:!0,altScreen1047:!1,altScreen1049:!1,mouseNormal:c?n.mouseNormal:i.mouseNormal}}function Zt(n){var i;const e=globalThis;e.__tmexE2eXterm=n,e.__tmexE2eTerminal=n,e.__tmexE2eTerminalEngine=qe,e.__tmexE2eTerminalRenderer=((i=n.getRendererKind)==null?void 0:i.call(n))??null}function en(n){if(!n)return;const e=globalThis;e.__tmexE2eTerminal!==n&&e.__tmexE2eXterm!==n||(e.__tmexE2eXterm=null,e.__tmexE2eTerminal=null,e.__tmexE2eTerminalEngine=null,e.__tmexE2eTerminalRenderer=null,e.__tmexE2eTerminalSelectionText=null)}const Ye=r.forwardRef(({deviceId:n,paneId:e,theme:i,inputMode:c,deviceConnected:p,isSelectionInvalid:E,onResize:S,onSync:x,children:R},G)=>{const[s,I]=r.useState(null),[F,K]=r.useState(!1),q=V(a=>a.sendInput),g=te(a=>a.terminalFontId),J=te(a=>a.terminalFontSize),f=te(a=>a.terminalLineHeight),{t:P}=Ee(),L=r.useMemo(()=>{switch(i){case"light":return We;default:return Fe}},[i]),z=r.useRef(null),H=r.useRef(null),w=r.useRef(null),m=r.useRef(n),y=r.useRef(e),N=r.useRef(n),O=r.useRef(e),h=r.useRef(p&&!E),v=r.useRef(c),_=r.useRef(L),D=r.useRef(!1),T=r.useRef(!1),U=r.useRef(null),Y=r.useRef(!1),X=r.useCallback((a,l,C)=>{!(a!=null&&a.exportModeSnapshot)||!l||!C||Vt(l,C,a.exportModeSnapshot())},[]),se=r.useCallback(()=>s,[s]);qt(z,se),r.useEffect(()=>{m.current=n,y.current=e,T.current=!1},[n,e]),r.useEffect(()=>{h.current=p&&!E},[p,E]),r.useEffect(()=>{v.current=c},[c]),r.useEffect(()=>{_.current=L},[L]);const k=r.useCallback(a=>{if(!a||c!=="direct"||!h.current)return;const l=m.current,C=y.current;!l||!C||q(l,C,a,!1)},[c,q]),{pendingLocalSize:ne,scheduleResize:A,runPostSelectResize:M,setFitAddon:j,setTerminal:B}=Xt({deviceId:n,paneId:e,deviceConnected:p,isSelectionInvalid:E,onResize:S,onSync:x,getContainerRect:()=>{const a=z.current;if(!a)return null;const l=a.getBoundingClientRect();return{width:l.width,height:l.height}}});r.useEffect(()=>{let a=!1,l=null;return(async()=>{if(await tt(g,J),a)return;const C=await Rt({fontFamily:nt(g),fontSize:J,lineHeight:f,scrollback:Gt,theme:_.current,disableStdin:v.current==="editor"});if(a){C.dispose();return}l=C,H.current&&C.open(H.current),Zt(C),I(C)})(),()=>{a=!0,I(null),en(l),l==null||l.dispose()}},[g,J,f]),r.useEffect(()=>{!s||!("setTheme"in s)||s.setTheme(L)},[s,L]),r.useEffect(()=>{!s||!("setDisableStdin"in s)||s.setDisableStdin(c==="editor")},[s,c]),r.useEffect(()=>{if(!(s!=null&&s.getCursorViewportRect))return;const a=()=>{var l;return((l=s.getCursorViewportRect)==null?void 0:l.call(s))??null};return ot(a),()=>rt(a)},[s]),r.useEffect(()=>{!s||c!=="direct"||window.innerWidth<768||"ontouchstart"in window||s.focus()},[s,c]);const re=r.useMemo(()=>s?{onResetTerminal:a=>{m.current===a&&(X(s,N.current,O.current),Y.current=!0,s.reset(),D.current=!1,M())},onApplyHistory:(a,l,C)=>{var oe;if(m.current!==a)return;const W=Qt(Kt(m.current,y.current),C);W&&((oe=s.restoreModeSnapshot)==null||oe.call(s,W));const Z=C?Ft(l):Ue(l);T.current=!0,s.write(Z),Y.current=!1,N.current=m.current,O.current=y.current,X(s,m.current,y.current)},onFlushBuffer:(a,l)=>{if(m.current===a){for(const C of l){const W=ze(C,D.current);D.current=W.endedWithCR,s.write(W.normalized)}T.current&&(s.buffer.active.baseY<=1&&s.scrollToTop(),T.current=!1),N.current=m.current,O.current=y.current,X(s,m.current,y.current)}},onOutput:(a,l,C)=>{if(m.current!==a||y.current!==l)return;const W=ze(C,D.current);D.current=W.endedWithCR,s.write(W.normalized),T.current&&(s.buffer.active.baseY<=1&&s.scrollToTop(),T.current=!1),N.current=m.current,O.current=y.current,X(s,m.current,y.current)}}:{},[s,X,M]);r.useEffect(()=>{s?U.current!==s&&(D.current=!1,N.current=m.current,O.current=y.current,U.current=s):U.current=null},[s]),r.useEffect(()=>{if(!(!s||!n||!e))return()=>{if(Y.current){Y.current=!1;return}X(s,N.current,O.current)}},[n,s,e,X]),r.useEffect(()=>{_e(re)},[re]),r.useEffect(()=>()=>{_e({})},[]),r.useEffect(()=>{if(!s){w.current=null,j(null),B(null);return}const a=new kt;return s.loadAddon(a),w.current=a,j(a),B(s),M(),()=>{try{a.dispose()}finally{w.current=null,j(null),B(null)}}},[s,M,j,B]),r.useEffect(()=>{const a=z.current;if(!a)return;let l=null;const C=new ResizeObserver(()=>{l!==null&&cancelAnimationFrame(l),l=requestAnimationFrame(()=>{l=null,A("resize")})});return C.observe(a),()=>{C.disconnect(),l!==null&&cancelAnimationFrame(l)}},[A]),r.useEffect(()=>{if(!s||!n||!e)return;const a=s.onData(l=>{!p||E||k(l)});return s.attachCustomKeyEventHandler(l=>!p||E||l.type!=="keydown"||c!=="direct"?!0:l.shiftKey&&l.key==="Enter"?(l.preventDefault(),k("\x1B[13;2u"),!1):!0),()=>{a.dispose(),s.attachCustomKeyEventHandler(()=>!0)}},[s,p,E,c,k,n,e]),r.useEffect(()=>{if(!(s!=null&&s.onLinkActivated))return;const a=s.onLinkActivated(l=>{window.open(l,"_blank","noopener,noreferrer")});return()=>a.dispose()},[s]),r.useEffect(()=>{if(!(s!=null&&s.onSelectionChange)){K(!1);return}const a=s.onSelectionChange(l=>{K(!!l)});return()=>{a.dispose(),K(!1)}},[s]);const ve=r.useCallback(()=>{var l;if(!s)return;const a=((l=s.getSelection)==null?void 0:l.call(s))??"";a&&st(a).then(()=>{xe.success(P("terminal.copied"))}).catch(()=>{xe.error(P("terminal.copyFailed"))}).finally(()=>{var C;(C=s.clearSelection)==null||C.call(s),s.focus()})},[s,P]),ae=r.useCallback(()=>{var l;if(!s)return;((l=navigator.clipboard)!=null&&l.readText?navigator.clipboard.readText():Promise.reject(new Error("clipboard unavailable"))).then(C=>{var W;C&&s.paste(C),(W=s.clearSelection)==null||W.call(s),s.focus()}).catch(()=>{xe.error(P("terminal.pasteFailed"))})},[s,P]),Te=r.useCallback(()=>{var a;(a=s==null?void 0:s.clearSelection)==null||a.call(s),s==null||s.focus()},[s]);return r.useImperativeHandle(G,()=>({write:a=>s==null?void 0:s.write(a),reset:()=>{s==null||s.reset(),D.current=!1},scrollToBottom:()=>s==null?void 0:s.scrollToBottom(),resize:(a,l)=>s==null?void 0:s.resize(a,l),getTerminal:()=>s??null,getSize:()=>s?{cols:Math.max(2,s.cols),rows:Math.max(2,s.rows)}:null,runPostSelectResize:()=>M(),scheduleResize:(a,l)=>A(a,l),calculateSizeFromContainer:()=>{var ue,ce,Q,he,de,we,be,Re,ke,Ce,Ie,Se,t,d,u,b;const a=z.current,l=s,C=w.current;if(!a||!l)return null;const W=a.getBoundingClientRect();if(W.width===0||W.height===0)return null;const Z=l._core;let oe;if(C)try{const $=C.proposeDimensions();if($)oe=Math.max(2,$.cols);else{const ee=((he=(Q=(ce=(ue=Z==null?void 0:Z._renderService)==null?void 0:ue.dimensions)==null?void 0:ce.css)==null?void 0:Q.cell)==null?void 0:he.width)??9;oe=Math.max(2,Math.floor(W.width/ee))}}catch{const $=((Re=(be=(we=(de=Z==null?void 0:Z._renderService)==null?void 0:de.dimensions)==null?void 0:we.css)==null?void 0:be.cell)==null?void 0:Re.width)??9;oe=Math.max(2,Math.floor(W.width/$))}else{const $=((Se=(Ie=(Ce=(ke=Z==null?void 0:Z._renderService)==null?void 0:ke.dimensions)==null?void 0:Ce.css)==null?void 0:Ie.cell)==null?void 0:Se.width)??9;oe=Math.max(2,Math.floor(W.width/$))}const ie=((b=(u=(d=(t=Z==null?void 0:Z._renderService)==null?void 0:t.dimensions)==null?void 0:d.css)==null?void 0:u.cell)==null?void 0:b.height)??17,ge=Math.max(2,Math.floor(W.height/ie));return{cols:oe,rows:ge}},getPendingLocalSize:()=>ne.current}),[s,ne,M,A]),o.jsxs("div",{className:"flex h-full w-full flex-col",style:{backgroundColor:L.background},"data-terminal-engine":qe,children:[o.jsxs("div",{ref:z,className:"relative min-h-0 w-full flex-1",children:[o.jsx("div",{ref:H,className:"absolute inset-0"}),o.jsx(zt,{visible:F,canPaste:c==="direct"&&p&&!E,onCopy:ve,onPaste:ae,onDismiss:Te})]}),R]})});Ye.displayName="Terminal";const tn=1200,nn=2e3;function fe(n,e){return!n||!e?!1:n.windowId===e.windowId&&n.paneId===e.paneId}function Xe(n,e){const i=n.filter(c=>e-c.at<tn);return i.length===0?null:i.reduce((c,p)=>p.at>c.at?p:c)}function ye(n,e=Date.now()){return!n||e-n.at>nn?null:n}function rn(n){const e=n.now??Date.now(),i=Xe(n.recentSelectRequests,e);if(i&&!fe(i,n.activePaneFromEvent)||fe(n.currentRoute,n.activePaneFromEvent)||fe(n.lastHandledActive,n.activePaneFromEvent))return!0;const c=ye(n.pendingUserSelection,e);return!!(c&&!fe(c,n.activePaneFromEvent))}function sn(n){const e=n.now??Date.now(),i=Xe(n.recentSelectRequests,e),c=ye(n.pendingUserSelection,e);return!!(c&&!fe(c,n.snapshotActive)||i&&!fe(i,n.snapshotActive))}function on(n){const e=n.now??Date.now(),i=ye(n.pendingUserSelection,e);return!(i&&fe(i,n.routeTarget)||n.snapshotActive&&fe(n.snapshotActive,n.routeTarget))}const cn=[{key:"enter",label:"ENTER",payload:"\r"},{key:"ctrl-c",label:"CTRL-C",payload:""},{key:"ctrl-d",label:"CTRL-D",payload:""},{key:"up",label:"↑",payload:"\x1B[A"},{key:"down",label:"↓",payload:"\x1B[B"},{key:"left",label:"←",payload:"\x1B[D"},{key:"right",label:"→",payload:"\x1B[C"},{key:"shift-enter",label:"SHIFT+ENTER",payload:"\x1B[13;2u"},{key:"tab",label:"TAB",payload:" "},{key:"backspace",label:"BACKSPACE",payload:"\b"},{key:"esc",label:"ESC",payload:"\x1B"},{key:"delete",label:"DELETE",payload:""},{key:":",label:":",payload:":"},{key:"/",label:"/",payload:"/"},{key:"'",label:"'",payload:"'"},{key:'"',label:'"',payload:'"'},{key:"`",label:"`",payload:"`"}],Be=r.memo(function({onSend:e,onFocusEditor:i,disabled:c,isMobile:p,inputMode:E}){return o.jsx("div",{className:"terminal-shortcuts-strip","data-testid":"terminal-shortcuts-strip",children:o.jsx("div",{className:"shortcut-row flex items-center gap-1.5 py-2 overflow-x-auto scrollbar-thin","data-testid":"editor-shortcuts-row",children:cn.map(S=>o.jsx(le,{variant:"ghost",size:"sm",className:"terminal-shortcut-btn h-7 min-w-9 px-2.5 rounded-full text-[11px] font-medium tracking-wide shrink-0 [@media(any-pointer:coarse)]:h-9 [@media(any-pointer:coarse)]:min-w-10 [@media(any-pointer:coarse)]:px-3",title:S.label,"aria-label":S.label,"data-testid":`editor-shortcut-${S.key}`,onMouseDown:x=>x.preventDefault(),onClick:()=>{e(S.payload),p&&E==="editor"&&(i==null||i())},disabled:c,children:S.label},S.key))})})});function un(){var Se;const{t:n}=Ee(),{deviceId:e,windowId:i,paneId:c}=Pe(),p=it(),E=r.useRef(null),S=r.useRef(null),x=r.useRef(null),R=r.useRef(null),G=r.useRef(!1),s=r.useRef(!1),I=r.useRef(null),F=V(t=>t.selectPane),K=V(t=>e?t.snapshots[e]:void 0),q=V(t=>{var d;return e?(d=t.deviceErrors)==null?void 0:d[e]:void 0}),g=V(t=>{var d;return e?((d=t.deviceConnected)==null?void 0:d[e])??!1:!1}),J=He(t=>{var d;return((d=t.settings)==null?void 0:d.siteName)??"tmex"}),f=r.useMemo(()=>Le(c),[c]),P=r.useMemo(()=>e&&f?`${e}:${f}`:null,[e,f]),[L,z]=r.useState(!1),[H,w]=r.useState(""),m=r.useRef(!1),y=!g||!f,[N,O]=r.useState(!1),h=te(t=>t.inputMode),v=te(t=>t.theme),_=te(t=>t.editorSendWithEnter),D=te(t=>t.setEditorSendWithEnter),T=te(t=>t.addEditorHistory),U=te(t=>t.setEditorDraft),Y=te(t=>t.removeEditorDraft),X=te(t=>P?t.editorDrafts[P]??"":""),se=r.useMemo(()=>ct(),[]),k=(Se=K==null?void 0:K.session)==null?void 0:Se.windows,ne=v==="light"?We:Fe,{data:A}=$e({queryKey:["devices"],queryFn:async()=>{const t=await fetch("/api/devices");if(!t.ok)throw new Error("Failed to fetch devices");return t.json()},throwOnError:!1}),M=r.useMemo(()=>{if(e)return A==null?void 0:A.devices.find(t=>t.id===e)},[e,A==null?void 0:A.devices]),j=r.useMemo(()=>{if(!(!i||!k))return k.find(t=>t.id===i)},[i,k]),B=r.useMemo(()=>{if(!(!f||!j))return j.panes.find(t=>t.id===f)},[f,j]),re=!!k,a=!!(re&&!!i&&!j||re&&!!i&&!!f&&!!j&&!B?n("wsError.checkGateway"):null),l=!!(g&&f&&!a),C=r.useMemo(()=>{if(!j||!B)return null;const t=(M==null?void 0:M.name)??e;return Oe({paneIdx:B.index,windowIdx:j.index,paneTitle:B.title,windowName:j.name,windowCustomName:j.customName,deviceName:t})},[M==null?void 0:M.name,e,B,j]),W=r.useMemo(()=>{if(!k||k.length===0)return null;const t=k.find(u=>u.active),d=t==null?void 0:t.panes.find(u=>u.active);return!t||!d?null:{windowId:t.id,paneId:d.id}},[k]),Z=r.useCallback((t,d)=>{!e||!f||V.getState().resizePane(e,f,t,d)},[e,f]),oe=r.useCallback((t,d)=>{!e||!f||V.getState().syncPaneSize(e,f,t,d)},[e,f]),ie=r.useCallback((t,d)=>{const u=R.current,b=(u==null?void 0:u.calculateSizeFromContainer())??(u==null?void 0:u.getSize())??void 0;if(b)return b;if(!t||!d||!k)return;const $=k.find(me=>me.id===t),ee=$==null?void 0:$.panes.find(me=>me.id===d);if(!(!ee||ee.width<=1||ee.height<=1))return{cols:ee.width,rows:ee.height}},[k]);r.useEffect(()=>{const t=()=>{z(window.innerWidth<768||"ontouchstart"in window)};return t(),window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[]),r.useEffect(()=>{if(!L||!se||s.current)return;s.current=!0;const t=()=>{window.scrollTo(0,1)},d=window.requestAnimationFrame(t),u=window.setTimeout(t,120),b=window.setTimeout(t,420);return()=>{window.cancelAnimationFrame(d),window.clearTimeout(u),window.clearTimeout(b)}},[se,L]),r.useEffect(()=>{e&&(G.current=!1,he.current=null,de.current=null,I.current=null,ue.current=[])},[e]),r.useEffect(()=>{g||(G.current=!1)},[g]),r.useEffect(()=>{if(!e||!g||!i||!k)return;if(k.length===0){p("/devices",{replace:!0});return}const t=k.find(u=>u.id===i);if(!t)return;if(!f){const u=t.panes.find(b=>b.active)??t.panes[0];u&&p(`/devices/${e}/windows/${i}/panes/${pe(u.id)}`,{replace:!0});return}if(!t.panes.find(u=>u.id===f)){const u=t.panes.find(b=>b.active)??t.panes[0];u&&p(`/devices/${e}/windows/${i}/panes/${pe(u.id)}`,{replace:!0});return}},[e,g,k,i,f,p]),r.useEffect(()=>{if(!e||!g||!k||k.length===0||i&&f||G.current)return;const t=k.find(u=>u.active)??k[0],d=t.panes.find(u=>u.active)??t.panes[0];d&&(G.current=!0,p(`/devices/${e}/windows/${t.id}/panes/${pe(d.id)}`,{replace:!0}))},[g,e,p,f,i,k]);const ge=r.useRef(null);r.useEffect(()=>{ge.current=null},[e,f]),r.useEffect(()=>{if(!e||!i||!f||y||!g)return;const t=`${e}:${i}:${f}`;if(ge.current===t)return;ge.current=t;const d=ie(i,f);ce(i,f),F(e,i,f,d)},[g,e,ie,y,f,F,i]),r.useEffect(()=>{if(!e||!g||!i||!f)return;const t={windowId:i,paneId:f};on({routeTarget:t,snapshotActive:W,pendingUserSelection:I.current})&&(I.current={windowId:t.windowId,paneId:t.paneId,at:Date.now()})},[g,e,f,W,i]);const ue=r.useRef([]),ce=r.useCallback((t,d)=>{const u=Date.now(),b=[...ue.current.filter($=>u-$.at<2e3),{windowId:t,paneId:d,at:u}];ue.current=b.slice(-8)},[]),Q=V(t=>e?t.activePaneFromEvent[e]:void 0),he=r.useRef(null);r.useEffect(()=>{if(!e||!g||!i||!f||!Q)return;const t=Date.now(),d=ye(I.current,t);if(I.current=d,rn({now:t,pendingUserSelection:d,activePaneFromEvent:Q,currentRoute:{windowId:i,paneId:f},recentSelectRequests:ue.current,lastHandledActive:he.current}))return;he.current={...Q},d&&d.windowId===Q.windowId&&d.paneId===Q.paneId&&(I.current=null);const u=ie(Q.windowId,Q.paneId);ce(Q.windowId,Q.paneId),F(e,Q.windowId,Q.paneId,u),p(`/devices/${e}/windows/${Q.windowId}/panes/${pe(Q.paneId)}`,{replace:!0})},[e,g,i,f,Q,ce,ie,F,p]);const de=r.useRef(null);r.useEffect(()=>{if(!e||!g||!k||k.length===0)return;const t=ue.current,d=k.find(Ne=>Ne.active);if(!d)return;const u=d.panes.find(Ne=>Ne.active);if(!u)return;const b={windowId:d.id,paneId:u.id},$=Date.now(),ee=ye(I.current,$);if(I.current=ee,sn({now:$,pendingUserSelection:ee,snapshotActive:b,recentSelectRequests:t})||de.current&&de.current.windowId===b.windowId&&de.current.paneId===b.paneId||(de.current={...b},ee&&ee.windowId===b.windowId&&ee.paneId===b.paneId&&(I.current=null),i===b.windowId&&f===b.paneId))return;const me=ie(b.windowId,b.paneId);ce(b.windowId,b.paneId),F(e,b.windowId,b.paneId,me),p(`/devices/${e}/windows/${b.windowId}/panes/${pe(b.paneId)}`,{replace:!0})},[e,g,k,i,f,ce,ie,F,p]);const we=V(t=>e?t.pendingCreateWindowAt[e]:void 0);r.useEffect(()=>{if(!e||!g||!we)return;const t=5e3,d=Date.now()-we;if(d>t){V.getState().clearPendingCreateWindow(e);return}if(!W){const $=window.setTimeout(()=>{V.getState().clearPendingCreateWindow(e)},t-d);return()=>window.clearTimeout($)}const u=W;if(i===u.windowId&&f===u.paneId){const $=window.setTimeout(()=>{V.getState().clearPendingCreateWindow(e)},t-d);return()=>window.clearTimeout($)}I.current={windowId:u.windowId,paneId:u.paneId,at:Date.now()};const b=ie(u.windowId,u.paneId);ce(u.windowId,u.paneId),F(e,u.windowId,u.paneId,b),p(`/devices/${e}/windows/${u.windowId}/panes/${pe(u.paneId)}`,{replace:!0}),V.getState().clearPendingCreateWindow(e)},[e,g,we,W,i,f,ce,ie,F,p]),r.useEffect(()=>{if(!l||!B||y)return;const t=R.current,d=t==null?void 0:t.getTerminal();if(!d)return;const u=Math.max(2,Math.floor(B.width||0)),b=Math.max(2,Math.floor(B.height||0));if(!u||!b)return;const $=Date.now(),ee={cols:u,rows:b},me=(t==null?void 0:t.getPendingLocalSize())??null;Ut({now:$,remoteSize:ee,pendingLocalSize:me})&&(d.cols===u&&d.rows===b||d.resize(u,b))},[l,y,B]),r.useEffect(()=>{const t=window.requestAnimationFrame(()=>{var u;(u=R.current)==null||u.scrollToBottom()}),d=window.setTimeout(()=>{var u;(u=R.current)==null||u.scrollToBottom()},120);return()=>{window.cancelAnimationFrame(t),window.clearTimeout(d)}},[h]),r.useEffect(()=>{q!=null&&q.message&&xe.error(q.message)},[q==null?void 0:q.message]),r.useEffect(()=>(document.title=at(C),()=>{document.title=J}),[J,C]),r.useEffect(()=>{const t=()=>{var d;(d=R.current)==null||d.scrollToBottom()};return window.addEventListener("tmex:jump-to-latest",t),()=>{window.removeEventListener("tmex:jump-to-latest",t)}},[]),r.useEffect(()=>{const t=d=>{const{deviceId:u,windowId:b,paneId:$}=d.detail;u===e&&(I.current={windowId:b,paneId:$,at:Date.now()})};return window.addEventListener("tmex:user-initiated-selection",t),()=>{window.removeEventListener("tmex:user-initiated-selection",t)}},[e]),r.useEffect(()=>{w(X)},[X]);const be=r.useCallback(t=>{if(!e||!f||!l)return;V.getState().sendInput(e,f,t,!1)},[l,e,f]),Re=r.useCallback(()=>{if(!l){xe.error(n("wsError.checkGateway"));return}if(!e||!f||!H.trim())return;O(!0),window.setTimeout(()=>O(!1),150);const t=_?`${H}\r`:H;V.getState().sendInput(e,f,t,!1),T(H),P&&Y(P),w("")},[T,l,e,P,_,H,Y,f,n]),ke=r.useCallback(()=>{if(!l){xe.error(n("wsError.checkGateway"));return}if(!e||!f||!H.trim())return;O(!0),window.setTimeout(()=>O(!1),150);const t=H.split(/\r?\n/),d=V.getState();for(const u of t)u.trim()&&d.sendInput(e,f,`${u}\r`,!1);T(H),P&&Y(P),w("")},[T,l,e,P,H,Y,f,n]),Ce=r.useCallback(()=>{var t;(t=x.current)==null||t.focus({preventScroll:!0})},[]);if(!e)return o.jsx("div",{className:"flex h-full items-center justify-center p-4",children:o.jsx("div",{className:"rounded-lg border border-dashed border-border px-4 py-3 text-sm text-muted-foreground",children:n("device.noDevices")})});const Ie=!g&&!q;return o.jsxs("div",{className:"flex h-full min-h-0 flex-col bg-background","data-testid":"device-page",children:[o.jsxs("div",{className:`flex-1 relative overflow-hidden min-h-0 min-w-0 ${L&&h==="editor"?"pb-1":""}`,children:[o.jsx("div",{className:"h-full px-3 py-1 min-h-0 min-w-0 w-full relative flex rounded-xl",style:{backgroundColor:ne.background},children:g&&f?o.jsx("div",{ref:E,className:"flex-1 h-full min-h-0 w-full","data-virtual-keyboard-avoid":!0,children:o.jsx(Ye,{ref:R,deviceId:e,paneId:f,theme:v,inputMode:h,deviceConnected:g,isSelectionInvalid:a,onResize:Z,onSync:oe,children:h==="direct"&&o.jsx("div",{className:"kb-floating-shortcuts",style:{backgroundColor:ne.background},children:o.jsx(Be,{onSend:be,disabled:!l,isMobile:L,inputMode:h})})},`${e}:${f}`)}):o.jsx("div",{className:"absolute inset-0 flex flex-col items-center justify-center p-8 text-center",children:o.jsx("div",{className:"max-w-sm space-y-4",children:g?i?o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"h-12 w-12 rounded-full bg-muted flex items-center justify-center mx-auto",children:o.jsx(Me,{className:"h-6 w-6 text-muted-foreground animate-spin"})}),o.jsx("h3",{className:"text-lg font-medium",children:n("terminal.connecting")})]}):o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"h-12 w-12 rounded-full bg-muted flex items-center justify-center mx-auto",children:o.jsx("span",{className:"text-2xl text-muted-foreground",children:"📋"})}),o.jsx("h3",{className:"text-lg font-medium",children:n("window.noWindowSelected")}),o.jsx("p",{className:"text-sm text-muted-foreground",children:n("window.selectWindowToStart")})]}):o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"h-12 w-12 rounded-full bg-muted flex items-center justify-center mx-auto",children:o.jsx("span",{className:"text-2xl text-muted-foreground",children:"🔌"})}),o.jsx("h3",{className:"text-lg font-medium",children:n("device.disconnected")}),o.jsx("p",{className:"text-sm text-muted-foreground",children:n("device.connectToStart")})]})})})}),Ie&&o.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-background/85 backdrop-blur-sm","data-testid":"terminal-status-overlay",children:o.jsxs("div",{className:"flex flex-col items-center gap-2 rounded-lg border border-border bg-card/90 px-4 py-3 shadow-sm",children:[o.jsx("div",{className:"h-7 w-7 rounded-full border-2 border-primary border-t-transparent animate-spin"}),o.jsx("span",{className:"text-xs text-muted-foreground","data-testid":"terminal-status-text",children:n("terminal.connecting")})]})})]}),h==="editor"&&o.jsxs("div",{ref:S,"data-virtual-keyboard-avoid":!0,className:"editor-mode-input bg-card/85 backdrop-blur-sm",children:[L&&o.jsx(Be,{onSend:be,onFocusEditor:Ce,disabled:!l,isMobile:L,inputMode:h}),o.jsx("textarea",{ref:x,"data-testid":"editor-input",className:"min-h-[88px] max-h-[28vh] w-full resize-y rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground shadow-xs outline-none transition-colors focus:border-ring",value:H,onChange:t=>{const d=t.target.value;if(w(d),!!P){if(d){U(P,d);return}Y(P)}},placeholder:n("terminal.inputPlaceholder"),onCompositionStart:()=>{m.current=!0},onCompositionEnd:()=>{m.current=!1}}),o.jsx("div",{className:"actions mt-2",children:o.jsxs("div",{className:"send-row flex flex-wrap items-center justify-end gap-2","data-testid":"editor-send-row",children:[o.jsxs("div",{className:"send-with-enter-toggle mr-auto flex items-center gap-2 text-xs text-muted-foreground","data-testid":"editor-send-with-enter-toggle",children:[o.jsx(lt,{size:"sm",checked:_,onCheckedChange:t=>D(!!t)}),o.jsx("span",{children:n("terminal.editorSendWithEnter")})]}),o.jsxs(le,{variant:"outline",size:"sm","data-testid":"editor-clear",onMouseDown:t=>t.preventDefault(),onClick:()=>{var t;w(""),P&&Y(P),L&&h==="editor"&&((t=x.current)==null||t.focus({preventScroll:!0}))},title:n("terminal.clear"),children:[o.jsx(ut,{className:"h-4 w-4"}),n("terminal.clear")]}),o.jsxs(le,{variant:"secondary",size:"sm","data-testid":"editor-send-line-by-line",onMouseDown:t=>t.preventDefault(),onClick:()=>{var t;ke(),L&&h==="editor"&&((t=x.current)==null||t.focus({preventScroll:!0}))},disabled:!l||N,children:[N?o.jsx(Me,{className:"h-4 w-4 animate-spin"}):o.jsx(De,{className:"h-4 w-4"}),n("terminal.editorSendLineByLine")]}),o.jsxs(le,{variant:"default",size:"sm","data-testid":"editor-send",onMouseDown:t=>t.preventDefault(),onClick:()=>{var t;Re(),L&&h==="editor"&&((t=x.current)==null||t.focus({preventScroll:!0}))},disabled:!l||N,children:[N?o.jsx(Me,{className:"h-4 w-4 animate-spin"}):o.jsx(De,{className:"h-4 w-4"}),n("common.send")]})]})})]})]})}function dn(){const{deviceId:n,windowId:e,paneId:i}=Pe(),c=i?Le(i):void 0,p=V(s=>s.snapshots),E=He(s=>{var I;return((I=s.settings)==null?void 0:I.siteName)??"tmex"}),S=n?p[n]:void 0,x=r.useMemo(()=>{var s;if(!(!e||!((s=S==null?void 0:S.session)!=null&&s.windows)))return S.session.windows.find(I=>I.id===e)},[e,S]),R=r.useMemo(()=>{if(!(!c||!x))return x.panes.find(s=>s.id===c)},[c,x]),G=r.useMemo(()=>x&&R?Oe({paneIdx:R.index,windowIdx:x.index,paneTitle:R.title,windowName:x.name,windowCustomName:x.customName,deviceName:E}):n??"",[x,R,E,n]);return o.jsx(o.Fragment,{children:G})}function fn(){const{t:n}=Ee(),{deviceId:e,paneId:i}=Pe(),c=i?Le(i):void 0,p=te(z=>z.inputMode),E=te(z=>z.setInputMode),S=V(z=>{var H;return e?((H=z.deviceConnected)==null?void 0:H[e])??!1:!1}),[x,R]=r.useState(!1),[G,s]=r.useState(!1),[I,F]=r.useState(!1),K=!!(c&&S),g=($e({queryKey:Et(e??"",c??""),queryFn:()=>yt(e??"",c??""),enabled:!!(e&&c),throwOnError:!1}).data??[]).some(z=>z.enabled),J=()=>{E(p==="direct"?"editor":"direct")},f=()=>{window.dispatchEvent(new CustomEvent("tmex:jump-to-latest"))},P=()=>{R(!0)},L=()=>{window.location.reload()};return o.jsxs(o.Fragment,{children:[o.jsx(le,{variant:"ghost",size:"icon-sm",onClick:P,"aria-label":n("nav.refreshPage"),title:n("nav.refreshPage"),children:o.jsx(Ct,{className:"h-4 w-4"})}),o.jsx(le,{variant:"ghost",size:"icon-sm",onClick:J,disabled:!K,"data-testid":"terminal-input-mode-toggle","aria-label":n(p==="direct"?"nav.switchToEditor":"nav.switchToDirect"),title:n(p==="direct"?"nav.switchToEditor":"nav.switchToDirect"),children:p==="direct"?o.jsx(dt,{className:"h-4 w-4"}):o.jsx(_t,{className:"h-4 w-4"})}),o.jsx(le,{variant:"ghost",size:"icon-sm",onClick:f,disabled:!K,"aria-label":n("nav.jumpToLatest"),title:n("nav.jumpToLatest"),children:o.jsx(jt,{className:"h-4 w-4"})}),o.jsxs(le,{variant:"ghost",size:"icon-sm",className:"relative",onClick:()=>s(!0),disabled:!c,"data-testid":"watch-open-button","aria-label":n("watch.title"),title:n("watch.title"),children:[o.jsx(ft,{className:"h-4 w-4"}),g&&o.jsx("span",{className:"absolute right-1 top-1 h-1.5 w-1.5 rounded-full bg-primary","data-testid":"watch-active-indicator"})]}),o.jsx(le,{variant:"ghost",size:"icon-sm",onClick:()=>F(!0),"data-testid":"keyboard-behavior-open-button","aria-label":n("settings.terminal.title"),title:n("settings.terminal.title"),children:o.jsx(Pt,{className:"h-4 w-4"})}),o.jsx(Dt,{open:I,onOpenChange:F}),e&&c&&o.jsx(mt,{open:G,onOpenChange:s,deviceId:e,paneId:c}),o.jsx(ht,{open:x,onOpenChange:R,children:o.jsxs(wt,{children:[o.jsxs(pt,{children:[o.jsx(xt,{children:n("nav.refreshPage")}),o.jsx(vt,{children:n("nav.refreshPageConfirm")})]}),o.jsxs(gt,{children:[o.jsx(bt,{onClick:()=>R(!1),children:n("common.cancel")}),o.jsx(St,{onClick:L,children:n("common.confirm")})]})]})})]})}export{fn as PageActions,dn as PageTitle,un as default};
25
+ //# sourceMappingURL=DevicePage-B0fQ6yWB.js.map
@@ -1,2 +1,2 @@
1
- import{u as D,r as x,a as W,b as ae,c as ie,d as re,e as K,t as ne,j as e,M as _,B as C,P as X,A as oe,f as ce,g as de,h as le,T as Y,i as me,k as he,l as ue,m as pe,n as xe,G as ve,o as v,D as fe,p as ye,E as ge,q as je,s as A,v as we,Z as Ne,w as Ce,x as Q,y as De,S as be,L as Se,z as Ee,C as Me,F as Pe,H as Ke,I as Re,J as Ie,K as f,N as z,O as V,Q as U,R as J,U as j,V as ke,W as Ae}from"./index-Den36xcn.js";import{C as M,a as P,b as $e,c as Te,d as Fe}from"./card-Duis2VHj.js";function R(s){const o=s.trim();return o||void 0}function qe(s){return s?{name:s.name,type:s.type,host:s.host??"",port:s.port??22,username:s.username??"",sshConfigRef:s.sshConfigRef??"",session:s.session??"tmex",authMode:s.type==="local"?"auto":s.authMode,password:"",privateKey:"",privateKeyPassphrase:""}:{name:"",type:"local",host:"",port:22,username:"root",sshConfigRef:"",session:"tmex",authMode:"auto",password:"",privateKey:"",privateKeyPassphrase:""}}function Le(s){if(s.type==="local")return{name:s.name.trim(),type:"local",session:R(s.session)??"tmex",authMode:"auto"};const o={name:s.name.trim(),type:"ssh",host:s.host.trim(),port:s.port,username:s.username.trim(),session:R(s.session)??"tmex",authMode:s.authMode};return s.authMode==="configRef"&&(o.sshConfigRef=s.sshConfigRef.trim()),s.authMode==="password"&&(o.password=s.password),s.authMode==="key"&&(o.privateKey=s.privateKey,o.privateKeyPassphrase=s.privateKeyPassphrase||void 0),o}function He(s){if(s.type==="local")return{name:s.name.trim(),session:R(s.session)??"tmex",authMode:"auto"};const o={name:s.name.trim(),host:s.host.trim(),port:s.port,username:s.username.trim(),sshConfigRef:s.authMode==="configRef"?s.sshConfigRef.trim():"",session:R(s.session)??"tmex",authMode:s.authMode};return s.authMode==="password"&&s.password&&(o.password=s.password),s.authMode==="key"&&s.privateKey&&(o.privateKey=s.privateKey,o.privateKeyPassphrase=s.privateKeyPassphrase||void 0),o}function ee(s){return Number.isInteger(s)&&s>=1&&s<=65535}function Oe(s){return s.type!=="ssh"?null:s.host.trim()?ee(s.port)?s.username.trim()?s.authMode==="configRef"&&!s.sshConfigRef.trim()?"validation.sshConfigRequired":null:"validation.usernameRequired":"validation.portRequired":"validation.hostRequired"}async function G(s,o){try{return(await s.json()).error??o}catch{return o}}function Ve(){const{t:s}=D(),[o,m]=x.useState(!1),[t,y]=x.useState(null),[r,d]=x.useState(null),l=W(),u=ae(n=>{var p;return((p=n.settings)==null?void 0:p.language)??"en_US"});x.useEffect(()=>{const n=()=>m(!0);return window.addEventListener("tmex:open-add-device",n),()=>window.removeEventListener("tmex:open-add-device",n)},[]);const{data:c,isLoading:I,isError:w}=ie({queryKey:["devices"],queryFn:async()=>{const n=await fetch("/api/devices");if(!n.ok)throw new Error(s("device.loadFailed"));return n.json()},throwOnError:!1}),b=re(n=>n.hydrateDeviceErrors);x.useEffect(()=>{c!=null&&c.devices&&b(c.devices.map(n=>({deviceId:n.id,lastError:n.lastError??null,lastErrorType:n.lastErrorType??null})))},[c,b]);const S=K({mutationFn:async n=>{if(!(await fetch(`/api/devices/${n}`,{method:"DELETE"})).ok)throw new Error(s("device.deleteFailed"))},onSuccess:()=>{l.invalidateQueries({queryKey:["devices"]}),v.success(s("common.success"))},onError:n=>{v.error(n instanceof Error?n.message:s("common.error"))}}),E=x.useMemo(()=>[...(c==null?void 0:c.devices)??[]].sort((p,N)=>p.sortOrder-N.sortOrder||p.name.localeCompare(N.name,ne(u),{numeric:!0,sensitivity:"base"})),[c==null?void 0:c.devices,u]);return e.jsxs("div",{className:"mx-auto flex w-full max-w-6xl flex-col gap-3 p-3 pb-[calc(1rem+env(safe-area-inset-bottom))] sm:gap-4 sm:p-5","data-testid":"devices-page",children:[I?e.jsx(M,{children:e.jsx(P,{className:"py-16 text-center text-sm text-muted-foreground",children:s("common.loading")})}):w?e.jsx(M,{children:e.jsx(P,{className:"py-16 text-center text-sm text-destructive",children:s("device.loadFailed")})}):E.length===0?e.jsx(M,{children:e.jsxs(P,{className:"space-y-4 py-14 text-center",children:[e.jsx("div",{className:"mx-auto flex h-12 w-12 items-center justify-center rounded-xl border border-border bg-muted",children:e.jsx(_,{className:"h-6 w-6 text-muted-foreground"})}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("h2",{className:"text-lg font-medium",children:s("device.noDevices")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s("device.addDevice")})]}),e.jsxs(C,{variant:"default","data-testid":"devices-add-empty",onClick:()=>m(!0),children:[e.jsx(X,{className:"h-4 w-4"}),s("device.addDevice")]})]})}):e.jsx("div",{className:"grid gap-3 lg:grid-cols-2",children:E.map(n=>e.jsx(Be,{device:n,onEdit:()=>y(n),onDelete:()=>d(n)},n.id))}),o&&e.jsx(Z,{mode:"create",onClose:()=>m(!1)}),t&&e.jsx(Z,{mode:"edit",device:t,onClose:()=>y(null)}),e.jsx(oe,{open:r!==null,onOpenChange:n=>!n&&d(null),children:e.jsxs(ce,{children:[e.jsxs(de,{children:[e.jsx(le,{className:"bg-destructive/10",children:e.jsx(Y,{className:"h-5 w-5 text-destructive"})}),e.jsx(me,{children:s("device.deleteConfirm")}),e.jsx(he,{children:s("device.deleteDescription",{name:(r==null?void 0:r.name)??""})})]}),e.jsxs(ue,{children:[e.jsx(pe,{children:s("common.cancel")}),e.jsx(xe,{variant:"destructive",disabled:!r||S.isPending,onClick:()=>{r&&(S.mutate(r.id),d(null))},children:s("common.delete")})]})]})})]})}function Be({device:s,onEdit:o,onDelete:m}){const{t}=D(),y=s.type==="local"?e.jsx(_,{className:"h-4 w-4"}):e.jsx(ve,{className:"h-4 w-4"}),r=s.type==="local"?t("device.typeLocal"):`${s.username??"-"}@${s.host??"-"}:${s.port??22}`,d=K({mutationFn:async()=>{const l=await fetch(`/api/devices/${s.id}/test-connection`,{method:"POST"});let u=null;try{u=await l.json()}catch{u=null}if(!l.ok){const c=u;throw new Error((c==null?void 0:c.error)??t("common.error"))}return u},onSuccess:l=>{v.success(l.message??t("common.success"))},onError:l=>{v.error(l instanceof Error?l.message:t("common.error"))}});return e.jsxs(M,{"data-testid":"device-card","data-device-id":s.id,"data-device-name":s.name,className:"overflow-hidden border-border/50",children:[e.jsxs($e,{className:"space-y-2 pb-2",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2.5",children:[e.jsx("div",{className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border bg-muted text-muted-foreground",children:y}),e.jsxs("div",{className:"min-w-0 space-y-0.5",children:[e.jsx(Te,{className:"line-clamp-1 text-sm",title:s.name,children:s.name}),e.jsx(Fe,{className:"line-clamp-1 text-xs",children:r})]})]}),e.jsx("div",{className:"flex shrink-0 items-center gap-1",children:e.jsxs(fe,{children:[e.jsx(ye,{render:e.jsx(C,{variant:"ghost",size:"icon-sm","data-testid":`device-card-actions-${s.id}`,"aria-label":t("common.edit"),title:t("common.edit")}),children:e.jsx(ge,{className:"h-4 w-4"})}),e.jsxs(je,{align:"end",children:[e.jsxs(A,{"data-testid":`device-card-edit-${s.id}`,onClick:o,children:[e.jsx(we,{className:"h-4 w-4"}),t("common.edit")]}),s.type==="ssh"&&e.jsxs(A,{"data-testid":`device-card-test-${s.id}`,onClick:()=>d.mutate(),disabled:d.isPending,children:[e.jsx(Ne,{className:"h-4 w-4"}),t("common.test")]}),e.jsx(Ce,{}),e.jsxs(A,{"data-testid":`device-card-delete-${s.id}`,variant:"destructive",onClick:m,children:[e.jsx(Y,{className:"h-4 w-4"}),t("common.delete")]})]})]})})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[e.jsx(Q,{variant:"outline",className:"text-[11px] font-normal",children:s.type==="local"?t("device.typeLocal"):t("device.typeSSHBadge")}),s.session&&e.jsx(Q,{variant:"outline",className:"text-[11px] font-normal",children:s.session}),e.jsx(De,{deviceId:s.id})]})]}),e.jsxs(P,{className:"pt-0",children:[e.jsx(be,{className:"mb-2"}),e.jsx("div",{className:"flex items-center justify-end",children:e.jsx(Se,{to:`/devices/${s.id}`,"data-testid":`device-card-connect-${s.id}`,className:Ee({variant:"outline",size:"sm"}),children:t("device.connect")})})]})]})}function Z({mode:s,device:o,onClose:m}){const{t}=D(),y=W(),[r,d]=x.useState(qe(o)),[l,u]=x.useState(!1),[c,I]=x.useState(!1),w=s==="edit",b=r.type==="ssh",S=K({mutationFn:async a=>{const i=await fetch("/api/devices",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!i.ok)throw new Error(await G(i,t("device.createFailed")));return i.json()},onSuccess:()=>{y.invalidateQueries({queryKey:["devices"]}),v.success(t("common.success")),m()},onError:a=>{v.error(a instanceof Error?a.message:t("common.error"))}}),E=K({mutationFn:async a=>{if(!o)throw new Error(t("apiError.deviceNotFound"));const i=await fetch(`/api/devices/${o.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!i.ok)throw new Error(await G(i,t("device.updateFailed")));return i.json()},onSuccess:()=>{y.invalidateQueries({queryKey:["devices"]}),v.success(t("common.success")),m()},onError:a=>{v.error(a instanceof Error?a.message:t("common.error"))}}),n=async a=>{a.preventDefault(),I(!0);const i=Oe(r);if(i){v.error(t(i));return}u(!0);try{s==="create"?await S.mutateAsync(Le(r)):await E.mutateAsync(He(r))}catch{}finally{u(!1)}},p=`${s}-device-name`,N=`${s}-device-type`,$=`${s}-device-host`,T=`${s}-device-port`,F=`${s}-device-username`,q=`${s}-device-session`,L=`${s}-device-auth-mode`,H=`${s}-device-password`,O=`${s}-device-private-key`,B=`${s}-device-private-key-passphrase`,se={local:t("device.typeLocal"),ssh:t("device.typeSSH")},te={password:t("device.authPassword"),key:t("device.authKey"),agent:t("device.authAgent"),configRef:t("device.authConfigRef")},k=a=>e.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-muted-foreground",children:a}),h=(a,i,g)=>e.jsxs("label",{className:"block text-xs font-medium text-foreground",htmlFor:a,children:[i,g&&e.jsx("span",{className:"ml-0.5 text-destructive",children:"*"})]});return e.jsx(Me,{open:!0,onOpenChange:a=>!a&&m(),children:e.jsxs(Pe,{"data-testid":"device-dialog",className:"w-full max-w-2xl",children:[e.jsxs(Ke,{children:[e.jsx(Re,{children:t(w?"device.editDevice":"device.addDevice")}),e.jsx(Ie,{children:t(w?"device.editDeviceDescription":"device.addDeviceDescription")})]}),e.jsxs("form",{onSubmit:n,className:"space-y-4",children:[e.jsxs("div",{className:"-mr-2 max-h-[min(70dvh,720px)] space-y-5 overflow-y-auto pr-2",children:[e.jsxs("section",{className:"space-y-2.5",children:[k(t("device.sectionBasic")),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{className:"space-y-1.5 sm:col-span-2",children:[h(p,t("device.name"),!0),e.jsx(f,{id:p,"data-testid":"device-name-input",type:"text",value:r.name,onChange:a=>d(i=>({...i,name:a.target.value})),placeholder:t("device.namePlaceholder"),required:!0})]}),e.jsxs("div",{className:"space-y-1.5",children:[h(N,t("device.type")),e.jsxs(z,{value:r.type,onValueChange:a=>{if(!a)return;const i=a;d(g=>({...g,type:i,authMode:i==="local"?"auto":g.authMode==="auto"?"agent":g.authMode}))},disabled:w,children:[e.jsx(V,{id:N,"data-testid":"device-type-select",className:"w-full",children:e.jsx(U,{placeholder:t("device.type"),children:a=>se[a]??""})}),e.jsxs(J,{children:[e.jsx(j,{value:"local",children:t("device.typeLocal")}),e.jsx(j,{value:"ssh",children:t("device.typeSSH")})]})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[h(q,t("device.session")),e.jsx(f,{id:q,"data-testid":"device-session-input",type:"text",value:r.session,onChange:a=>d(i=>({...i,session:a.target.value})),placeholder:t("device.sessionPlaceholder")})]})]})]}),b&&e.jsxs(e.Fragment,{children:[e.jsxs("section",{className:"space-y-2.5",children:[k(t("device.sectionConnection")),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-3",children:[e.jsxs("div",{className:"space-y-1.5 sm:col-span-2",children:[h($,t("device.host"),!0),e.jsx(f,{id:$,type:"text",value:r.host,onChange:a=>d(i=>({...i,host:a.target.value})),placeholder:t("device.hostPlaceholder"),"aria-invalid":c&&!r.host.trim()})]}),e.jsxs("div",{className:"space-y-1.5",children:[h(T,t("device.port"),!0),e.jsx(f,{id:T,type:"number",value:Number.isNaN(r.port)?"":r.port,onChange:a=>{const i=a.target.value;d(g=>({...g,port:i===""?Number.NaN:Number.parseInt(i,10)}))},min:1,max:65535,"aria-invalid":c&&!ee(r.port)})]}),e.jsxs("div",{className:"space-y-1.5 sm:col-span-2",children:[h(F,t("device.username"),!0),e.jsx(f,{id:F,type:"text",value:r.username,onChange:a=>d(i=>({...i,username:a.target.value})),placeholder:t("device.usernamePlaceholder"),"aria-invalid":c&&!r.username.trim()})]})]})]}),e.jsxs("section",{className:"space-y-2.5",children:[k(t("device.sectionAuth")),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[h(L,t("device.authMode")),e.jsxs(z,{value:r.authMode,onValueChange:a=>{a&&d(i=>({...i,authMode:a}))},children:[e.jsx(V,{id:L,"data-testid":"device-auth-mode-select",className:"w-full",children:e.jsx(U,{placeholder:t("device.authMode"),children:a=>te[a]??""})}),e.jsxs(J,{children:[e.jsx(j,{value:"password",children:t("device.authPassword")}),e.jsx(j,{value:"key",children:t("device.authKey")}),e.jsx(j,{value:"agent",children:t("device.authAgent")}),e.jsx(j,{value:"configRef",children:t("device.authConfigRef")})]})]})]}),r.authMode==="password"&&e.jsxs("div",{className:"space-y-1.5",children:[h(H,t("device.password")),e.jsx(f,{id:H,type:"password",value:r.password,onChange:a=>d(i=>({...i,password:a.target.value}))})]}),r.authMode==="key"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1.5",children:[h(O,t("device.privateKey")),e.jsx(ke,{id:O,value:r.privateKey,onChange:a=>d(i=>({...i,privateKey:a.target.value})),className:"h-28 font-mono text-xs",placeholder:t("device.privateKeyPlaceholder")})]}),e.jsxs("div",{className:"space-y-1.5",children:[h(B,t("device.passphrase")),e.jsx(f,{id:B,type:"password",value:r.privateKeyPassphrase,onChange:a=>d(i=>({...i,privateKeyPassphrase:a.target.value}))})]})]}),r.authMode==="configRef"&&e.jsxs("div",{className:"space-y-1.5",children:[h(`${s}-device-ssh-config-ref`,t("device.authConfigRef"),!0),e.jsx(f,{id:`${s}-device-ssh-config-ref`,"data-testid":"device-ssh-config-ref-input",type:"text",value:r.sshConfigRef,onChange:a=>d(i=>({...i,sshConfigRef:a.target.value})),placeholder:t("device.sshConfigRefPlaceholder"),"aria-invalid":c&&!r.sshConfigRef.trim()}),e.jsx("p",{className:"text-[11px] text-muted-foreground",children:t("device.sshConfigRefHint")})]})]})]})]})]}),e.jsxs(Ae,{children:[e.jsx(C,{type:"button",variant:"outline",onClick:m,children:t("common.cancel")}),e.jsx(C,{type:"submit",variant:"default","data-testid":"device-dialog-save",disabled:l,children:t(l?"common.saving":"common.save")})]})]})]})})}function Ue(){const{t:s}=D();return e.jsx(e.Fragment,{children:s("sidebar.manageDevices")})}function Je(){const{t:s}=D(),o=()=>{window.dispatchEvent(new CustomEvent("tmex:open-add-device"))};return e.jsx(C,{variant:"ghost",size:"icon-sm","data-testid":"devices-add",onClick:o,"aria-label":s("sidebar.addDevice"),title:s("sidebar.addDevice"),children:e.jsx(X,{className:"h-4 w-4"})})}export{Je as PageActions,Ue as PageTitle,Ve as default};
2
- //# sourceMappingURL=DevicesPage-Bm7E9QAf.js.map
1
+ import{u as D,r as x,a as W,b as ae,c as ie,d as re,e as K,t as ne,j as e,M as _,B as C,P as X,A as oe,f as ce,g as de,h as le,T as Y,i as me,k as he,l as ue,m as pe,n as xe,G as ve,o as v,D as fe,p as ye,E as ge,q as je,s as A,v as we,Z as Ne,w as Ce,x as Q,y as De,S as be,L as Se,z as Ee,C as Me,F as Pe,H as Ke,I as Re,J as Ie,K as f,N as z,O as V,Q as U,R as J,U as j,V as ke,W as Ae}from"./index-Ra6pj0rt.js";import{C as M,a as P,b as $e,c as Te,d as Fe}from"./card-BkRqR9zz.js";function R(s){const o=s.trim();return o||void 0}function qe(s){return s?{name:s.name,type:s.type,host:s.host??"",port:s.port??22,username:s.username??"",sshConfigRef:s.sshConfigRef??"",session:s.session??"tmex",authMode:s.type==="local"?"auto":s.authMode,password:"",privateKey:"",privateKeyPassphrase:""}:{name:"",type:"local",host:"",port:22,username:"root",sshConfigRef:"",session:"tmex",authMode:"auto",password:"",privateKey:"",privateKeyPassphrase:""}}function Le(s){if(s.type==="local")return{name:s.name.trim(),type:"local",session:R(s.session)??"tmex",authMode:"auto"};const o={name:s.name.trim(),type:"ssh",host:s.host.trim(),port:s.port,username:s.username.trim(),session:R(s.session)??"tmex",authMode:s.authMode};return s.authMode==="configRef"&&(o.sshConfigRef=s.sshConfigRef.trim()),s.authMode==="password"&&(o.password=s.password),s.authMode==="key"&&(o.privateKey=s.privateKey,o.privateKeyPassphrase=s.privateKeyPassphrase||void 0),o}function He(s){if(s.type==="local")return{name:s.name.trim(),session:R(s.session)??"tmex",authMode:"auto"};const o={name:s.name.trim(),host:s.host.trim(),port:s.port,username:s.username.trim(),sshConfigRef:s.authMode==="configRef"?s.sshConfigRef.trim():"",session:R(s.session)??"tmex",authMode:s.authMode};return s.authMode==="password"&&s.password&&(o.password=s.password),s.authMode==="key"&&s.privateKey&&(o.privateKey=s.privateKey,o.privateKeyPassphrase=s.privateKeyPassphrase||void 0),o}function ee(s){return Number.isInteger(s)&&s>=1&&s<=65535}function Oe(s){return s.type!=="ssh"?null:s.host.trim()?ee(s.port)?s.username.trim()?s.authMode==="configRef"&&!s.sshConfigRef.trim()?"validation.sshConfigRequired":null:"validation.usernameRequired":"validation.portRequired":"validation.hostRequired"}async function G(s,o){try{return(await s.json()).error??o}catch{return o}}function Ve(){const{t:s}=D(),[o,m]=x.useState(!1),[t,y]=x.useState(null),[r,d]=x.useState(null),l=W(),u=ae(n=>{var p;return((p=n.settings)==null?void 0:p.language)??"en_US"});x.useEffect(()=>{const n=()=>m(!0);return window.addEventListener("tmex:open-add-device",n),()=>window.removeEventListener("tmex:open-add-device",n)},[]);const{data:c,isLoading:I,isError:w}=ie({queryKey:["devices"],queryFn:async()=>{const n=await fetch("/api/devices");if(!n.ok)throw new Error(s("device.loadFailed"));return n.json()},throwOnError:!1}),b=re(n=>n.hydrateDeviceErrors);x.useEffect(()=>{c!=null&&c.devices&&b(c.devices.map(n=>({deviceId:n.id,lastError:n.lastError??null,lastErrorType:n.lastErrorType??null})))},[c,b]);const S=K({mutationFn:async n=>{if(!(await fetch(`/api/devices/${n}`,{method:"DELETE"})).ok)throw new Error(s("device.deleteFailed"))},onSuccess:()=>{l.invalidateQueries({queryKey:["devices"]}),v.success(s("common.success"))},onError:n=>{v.error(n instanceof Error?n.message:s("common.error"))}}),E=x.useMemo(()=>[...(c==null?void 0:c.devices)??[]].sort((p,N)=>p.sortOrder-N.sortOrder||p.name.localeCompare(N.name,ne(u),{numeric:!0,sensitivity:"base"})),[c==null?void 0:c.devices,u]);return e.jsxs("div",{className:"mx-auto flex w-full max-w-6xl flex-col gap-3 p-3 pb-[calc(1rem+env(safe-area-inset-bottom))] sm:gap-4 sm:p-5","data-testid":"devices-page",children:[I?e.jsx(M,{children:e.jsx(P,{className:"py-16 text-center text-sm text-muted-foreground",children:s("common.loading")})}):w?e.jsx(M,{children:e.jsx(P,{className:"py-16 text-center text-sm text-destructive",children:s("device.loadFailed")})}):E.length===0?e.jsx(M,{children:e.jsxs(P,{className:"space-y-4 py-14 text-center",children:[e.jsx("div",{className:"mx-auto flex h-12 w-12 items-center justify-center rounded-xl border border-border bg-muted",children:e.jsx(_,{className:"h-6 w-6 text-muted-foreground"})}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("h2",{className:"text-lg font-medium",children:s("device.noDevices")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s("device.addDevice")})]}),e.jsxs(C,{variant:"default","data-testid":"devices-add-empty",onClick:()=>m(!0),children:[e.jsx(X,{className:"h-4 w-4"}),s("device.addDevice")]})]})}):e.jsx("div",{className:"grid gap-3 lg:grid-cols-2",children:E.map(n=>e.jsx(Be,{device:n,onEdit:()=>y(n),onDelete:()=>d(n)},n.id))}),o&&e.jsx(Z,{mode:"create",onClose:()=>m(!1)}),t&&e.jsx(Z,{mode:"edit",device:t,onClose:()=>y(null)}),e.jsx(oe,{open:r!==null,onOpenChange:n=>!n&&d(null),children:e.jsxs(ce,{children:[e.jsxs(de,{children:[e.jsx(le,{className:"bg-destructive/10",children:e.jsx(Y,{className:"h-5 w-5 text-destructive"})}),e.jsx(me,{children:s("device.deleteConfirm")}),e.jsx(he,{children:s("device.deleteDescription",{name:(r==null?void 0:r.name)??""})})]}),e.jsxs(ue,{children:[e.jsx(pe,{children:s("common.cancel")}),e.jsx(xe,{variant:"destructive",disabled:!r||S.isPending,onClick:()=>{r&&(S.mutate(r.id),d(null))},children:s("common.delete")})]})]})})]})}function Be({device:s,onEdit:o,onDelete:m}){const{t}=D(),y=s.type==="local"?e.jsx(_,{className:"h-4 w-4"}):e.jsx(ve,{className:"h-4 w-4"}),r=s.type==="local"?t("device.typeLocal"):`${s.username??"-"}@${s.host??"-"}:${s.port??22}`,d=K({mutationFn:async()=>{const l=await fetch(`/api/devices/${s.id}/test-connection`,{method:"POST"});let u=null;try{u=await l.json()}catch{u=null}if(!l.ok){const c=u;throw new Error((c==null?void 0:c.error)??t("common.error"))}return u},onSuccess:l=>{v.success(l.message??t("common.success"))},onError:l=>{v.error(l instanceof Error?l.message:t("common.error"))}});return e.jsxs(M,{"data-testid":"device-card","data-device-id":s.id,"data-device-name":s.name,className:"overflow-hidden border-border/50",children:[e.jsxs($e,{className:"space-y-2 pb-2",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2.5",children:[e.jsx("div",{className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border bg-muted text-muted-foreground",children:y}),e.jsxs("div",{className:"min-w-0 space-y-0.5",children:[e.jsx(Te,{className:"line-clamp-1 text-sm",title:s.name,children:s.name}),e.jsx(Fe,{className:"line-clamp-1 text-xs",children:r})]})]}),e.jsx("div",{className:"flex shrink-0 items-center gap-1",children:e.jsxs(fe,{children:[e.jsx(ye,{render:e.jsx(C,{variant:"ghost",size:"icon-sm","data-testid":`device-card-actions-${s.id}`,"aria-label":t("common.edit"),title:t("common.edit")}),children:e.jsx(ge,{className:"h-4 w-4"})}),e.jsxs(je,{align:"end",children:[e.jsxs(A,{"data-testid":`device-card-edit-${s.id}`,onClick:o,children:[e.jsx(we,{className:"h-4 w-4"}),t("common.edit")]}),s.type==="ssh"&&e.jsxs(A,{"data-testid":`device-card-test-${s.id}`,onClick:()=>d.mutate(),disabled:d.isPending,children:[e.jsx(Ne,{className:"h-4 w-4"}),t("common.test")]}),e.jsx(Ce,{}),e.jsxs(A,{"data-testid":`device-card-delete-${s.id}`,variant:"destructive",onClick:m,children:[e.jsx(Y,{className:"h-4 w-4"}),t("common.delete")]})]})]})})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[e.jsx(Q,{variant:"outline",className:"text-[11px] font-normal",children:s.type==="local"?t("device.typeLocal"):t("device.typeSSHBadge")}),s.session&&e.jsx(Q,{variant:"outline",className:"text-[11px] font-normal",children:s.session}),e.jsx(De,{deviceId:s.id})]})]}),e.jsxs(P,{className:"pt-0",children:[e.jsx(be,{className:"mb-2"}),e.jsx("div",{className:"flex items-center justify-end",children:e.jsx(Se,{to:`/devices/${s.id}`,"data-testid":`device-card-connect-${s.id}`,className:Ee({variant:"outline",size:"sm"}),children:t("device.connect")})})]})]})}function Z({mode:s,device:o,onClose:m}){const{t}=D(),y=W(),[r,d]=x.useState(qe(o)),[l,u]=x.useState(!1),[c,I]=x.useState(!1),w=s==="edit",b=r.type==="ssh",S=K({mutationFn:async a=>{const i=await fetch("/api/devices",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!i.ok)throw new Error(await G(i,t("device.createFailed")));return i.json()},onSuccess:()=>{y.invalidateQueries({queryKey:["devices"]}),v.success(t("common.success")),m()},onError:a=>{v.error(a instanceof Error?a.message:t("common.error"))}}),E=K({mutationFn:async a=>{if(!o)throw new Error(t("apiError.deviceNotFound"));const i=await fetch(`/api/devices/${o.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!i.ok)throw new Error(await G(i,t("device.updateFailed")));return i.json()},onSuccess:()=>{y.invalidateQueries({queryKey:["devices"]}),v.success(t("common.success")),m()},onError:a=>{v.error(a instanceof Error?a.message:t("common.error"))}}),n=async a=>{a.preventDefault(),I(!0);const i=Oe(r);if(i){v.error(t(i));return}u(!0);try{s==="create"?await S.mutateAsync(Le(r)):await E.mutateAsync(He(r))}catch{}finally{u(!1)}},p=`${s}-device-name`,N=`${s}-device-type`,$=`${s}-device-host`,T=`${s}-device-port`,F=`${s}-device-username`,q=`${s}-device-session`,L=`${s}-device-auth-mode`,H=`${s}-device-password`,O=`${s}-device-private-key`,B=`${s}-device-private-key-passphrase`,se={local:t("device.typeLocal"),ssh:t("device.typeSSH")},te={password:t("device.authPassword"),key:t("device.authKey"),agent:t("device.authAgent"),configRef:t("device.authConfigRef")},k=a=>e.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wider text-muted-foreground",children:a}),h=(a,i,g)=>e.jsxs("label",{className:"block text-xs font-medium text-foreground",htmlFor:a,children:[i,g&&e.jsx("span",{className:"ml-0.5 text-destructive",children:"*"})]});return e.jsx(Me,{open:!0,onOpenChange:a=>!a&&m(),children:e.jsxs(Pe,{"data-testid":"device-dialog",className:"w-full max-w-2xl",children:[e.jsxs(Ke,{children:[e.jsx(Re,{children:t(w?"device.editDevice":"device.addDevice")}),e.jsx(Ie,{children:t(w?"device.editDeviceDescription":"device.addDeviceDescription")})]}),e.jsxs("form",{onSubmit:n,className:"space-y-4",children:[e.jsxs("div",{className:"-mr-2 max-h-[min(70dvh,720px)] space-y-5 overflow-y-auto pr-2",children:[e.jsxs("section",{className:"space-y-2.5",children:[k(t("device.sectionBasic")),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{className:"space-y-1.5 sm:col-span-2",children:[h(p,t("device.name"),!0),e.jsx(f,{id:p,"data-testid":"device-name-input",type:"text",value:r.name,onChange:a=>d(i=>({...i,name:a.target.value})),placeholder:t("device.namePlaceholder"),required:!0})]}),e.jsxs("div",{className:"space-y-1.5",children:[h(N,t("device.type")),e.jsxs(z,{value:r.type,onValueChange:a=>{if(!a)return;const i=a;d(g=>({...g,type:i,authMode:i==="local"?"auto":g.authMode==="auto"?"agent":g.authMode}))},disabled:w,children:[e.jsx(V,{id:N,"data-testid":"device-type-select",className:"w-full",children:e.jsx(U,{placeholder:t("device.type"),children:a=>se[a]??""})}),e.jsxs(J,{children:[e.jsx(j,{value:"local",children:t("device.typeLocal")}),e.jsx(j,{value:"ssh",children:t("device.typeSSH")})]})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[h(q,t("device.session")),e.jsx(f,{id:q,"data-testid":"device-session-input",type:"text",value:r.session,onChange:a=>d(i=>({...i,session:a.target.value})),placeholder:t("device.sessionPlaceholder")})]})]})]}),b&&e.jsxs(e.Fragment,{children:[e.jsxs("section",{className:"space-y-2.5",children:[k(t("device.sectionConnection")),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-3",children:[e.jsxs("div",{className:"space-y-1.5 sm:col-span-2",children:[h($,t("device.host"),!0),e.jsx(f,{id:$,type:"text",value:r.host,onChange:a=>d(i=>({...i,host:a.target.value})),placeholder:t("device.hostPlaceholder"),"aria-invalid":c&&!r.host.trim()})]}),e.jsxs("div",{className:"space-y-1.5",children:[h(T,t("device.port"),!0),e.jsx(f,{id:T,type:"number",value:Number.isNaN(r.port)?"":r.port,onChange:a=>{const i=a.target.value;d(g=>({...g,port:i===""?Number.NaN:Number.parseInt(i,10)}))},min:1,max:65535,"aria-invalid":c&&!ee(r.port)})]}),e.jsxs("div",{className:"space-y-1.5 sm:col-span-2",children:[h(F,t("device.username"),!0),e.jsx(f,{id:F,type:"text",value:r.username,onChange:a=>d(i=>({...i,username:a.target.value})),placeholder:t("device.usernamePlaceholder"),"aria-invalid":c&&!r.username.trim()})]})]})]}),e.jsxs("section",{className:"space-y-2.5",children:[k(t("device.sectionAuth")),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[h(L,t("device.authMode")),e.jsxs(z,{value:r.authMode,onValueChange:a=>{a&&d(i=>({...i,authMode:a}))},children:[e.jsx(V,{id:L,"data-testid":"device-auth-mode-select",className:"w-full",children:e.jsx(U,{placeholder:t("device.authMode"),children:a=>te[a]??""})}),e.jsxs(J,{children:[e.jsx(j,{value:"password",children:t("device.authPassword")}),e.jsx(j,{value:"key",children:t("device.authKey")}),e.jsx(j,{value:"agent",children:t("device.authAgent")}),e.jsx(j,{value:"configRef",children:t("device.authConfigRef")})]})]})]}),r.authMode==="password"&&e.jsxs("div",{className:"space-y-1.5",children:[h(H,t("device.password")),e.jsx(f,{id:H,type:"password",value:r.password,onChange:a=>d(i=>({...i,password:a.target.value}))})]}),r.authMode==="key"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1.5",children:[h(O,t("device.privateKey")),e.jsx(ke,{id:O,value:r.privateKey,onChange:a=>d(i=>({...i,privateKey:a.target.value})),className:"h-28 font-mono text-xs",placeholder:t("device.privateKeyPlaceholder")})]}),e.jsxs("div",{className:"space-y-1.5",children:[h(B,t("device.passphrase")),e.jsx(f,{id:B,type:"password",value:r.privateKeyPassphrase,onChange:a=>d(i=>({...i,privateKeyPassphrase:a.target.value}))})]})]}),r.authMode==="configRef"&&e.jsxs("div",{className:"space-y-1.5",children:[h(`${s}-device-ssh-config-ref`,t("device.authConfigRef"),!0),e.jsx(f,{id:`${s}-device-ssh-config-ref`,"data-testid":"device-ssh-config-ref-input",type:"text",value:r.sshConfigRef,onChange:a=>d(i=>({...i,sshConfigRef:a.target.value})),placeholder:t("device.sshConfigRefPlaceholder"),"aria-invalid":c&&!r.sshConfigRef.trim()}),e.jsx("p",{className:"text-[11px] text-muted-foreground",children:t("device.sshConfigRefHint")})]})]})]})]})]}),e.jsxs(Ae,{children:[e.jsx(C,{type:"button",variant:"outline",onClick:m,children:t("common.cancel")}),e.jsx(C,{type:"submit",variant:"default","data-testid":"device-dialog-save",disabled:l,children:t(l?"common.saving":"common.save")})]})]})]})})}function Ue(){const{t:s}=D();return e.jsx(e.Fragment,{children:s("sidebar.manageDevices")})}function Je(){const{t:s}=D(),o=()=>{window.dispatchEvent(new CustomEvent("tmex:open-add-device"))};return e.jsx(C,{variant:"ghost",size:"icon-sm","data-testid":"devices-add",onClick:o,"aria-label":s("sidebar.addDevice"),title:s("sidebar.addDevice"),children:e.jsx(X,{className:"h-4 w-4"})})}export{Je as PageActions,Ue as PageTitle,Ve as default};
2
+ //# sourceMappingURL=DevicesPage-C7THDzTX.js.map