tmex-cli 0.15.1 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +37 -7
  2. package/dist/runtime/server.js +886 -172
  3. package/package.json +1 -1
  4. package/resources/fe-dist/assets/DevicePage-CxCVolw8.js +24 -0
  5. package/resources/fe-dist/assets/{DevicesPage-Ngrej5Ot.js → DevicesPage-_SYGKgwy.js} +1 -1
  6. package/resources/fe-dist/assets/{FilePage-HbiQHaa9.js → FilePage-Blf_MlAq.js} +1 -1
  7. package/resources/fe-dist/assets/{SettingsPage-CPdwRwyS.js → SettingsPage-BRt22APt.js} +1 -1
  8. package/resources/fe-dist/assets/{agent-tab--8AsTl-t.js → agent-tab-DRkW6D0y.js} +4 -4
  9. package/resources/fe-dist/assets/{api-BLIQkwae.js → api-C2-crTt8.js} +1 -1
  10. package/resources/fe-dist/assets/{arc-BxPdcU4u.js → arc-Bzi-2Wgo.js} +1 -1
  11. package/resources/fe-dist/assets/{architectureDiagram-3BPJPVTR-BTgMKoOk.js → architectureDiagram-3BPJPVTR-DZYFrhja.js} +1 -1
  12. package/resources/fe-dist/assets/{blockDiagram-GPEHLZMM-DGbVoBx0.js → blockDiagram-GPEHLZMM-lpc1A1G1.js} +1 -1
  13. package/resources/fe-dist/assets/{c4Diagram-AAUBKEIU-6Xsfbwgs.js → c4Diagram-AAUBKEIU-DOc1BzPY.js} +1 -1
  14. package/resources/fe-dist/assets/{card-LIHKdO48.js → card-BA66zlg1.js} +1 -1
  15. package/resources/fe-dist/assets/channel-DFyg9jlp.js +1 -0
  16. package/resources/fe-dist/assets/{chunk-2J33WTMH-gstBqLVO.js → chunk-2J33WTMH-DqycjO3G.js} +1 -1
  17. package/resources/fe-dist/assets/{chunk-4BX2VUAB-C-o3q6jv.js → chunk-4BX2VUAB-t2B-Cl6x.js} +1 -1
  18. package/resources/fe-dist/assets/{chunk-55IACEB6-DddgDLxO.js → chunk-55IACEB6-BmFdQL7n.js} +1 -1
  19. package/resources/fe-dist/assets/{chunk-727SXJPM-CXYmmkMi.js → chunk-727SXJPM-DEa9FPer.js} +1 -1
  20. package/resources/fe-dist/assets/{chunk-AQP2D5EJ-DRLECkLk.js → chunk-AQP2D5EJ-DiZ9AoB9.js} +1 -1
  21. package/resources/fe-dist/assets/{chunk-FMBD7UC4-BExWPgsD.js → chunk-FMBD7UC4-DLcIMhi1.js} +1 -1
  22. package/resources/fe-dist/assets/{chunk-ND2GUHAM-C7VdaZU9.js → chunk-ND2GUHAM-Cu1P2Ot8.js} +1 -1
  23. package/resources/fe-dist/assets/{chunk-QZHKN3VN-BzDQ08zM.js → chunk-QZHKN3VN-C8ki16q3.js} +1 -1
  24. package/resources/fe-dist/assets/classDiagram-4FO5ZUOK-CAgGMVvn.js +1 -0
  25. package/resources/fe-dist/assets/classDiagram-v2-Q7XG4LA2-CAgGMVvn.js +1 -0
  26. package/resources/fe-dist/assets/{copy-BF0hUIaY.js → copy-C8vDYUVz.js} +1 -1
  27. package/resources/fe-dist/assets/{cose-bilkent-S5V4N54A-D6PcYL8a.js → cose-bilkent-S5V4N54A-baMBJteT.js} +1 -1
  28. package/resources/fe-dist/assets/{dagre-BM42HDAG-CRImj5gw.js → dagre-BM42HDAG-CwWSiSwb.js} +1 -1
  29. package/resources/fe-dist/assets/{diagram-2AECGRRQ-rxXesmyb.js → diagram-2AECGRRQ-CeSwouYZ.js} +1 -1
  30. package/resources/fe-dist/assets/{diagram-5GNKFQAL-1cV1ezU8.js → diagram-5GNKFQAL-DgxdcMax.js} +1 -1
  31. package/resources/fe-dist/assets/{diagram-KO2AKTUF-D_t6oZ15.js → diagram-KO2AKTUF-DrglkRZC.js} +1 -1
  32. package/resources/fe-dist/assets/{diagram-LMA3HP47-Bv2rw6Uu.js → diagram-LMA3HP47-BLHZ3p7v.js} +1 -1
  33. package/resources/fe-dist/assets/{diagram-OG6HWLK6-CDr2E2aw.js → diagram-OG6HWLK6-_I_mMaa6.js} +1 -1
  34. package/resources/fe-dist/assets/{en_US-Chxeay8F.js → en_US-CjVU4anP.js} +1 -1
  35. package/resources/fe-dist/assets/{erDiagram-TEJ5UH35-Dji-ptHQ.js → erDiagram-TEJ5UH35-Zkbnn8Kh.js} +1 -1
  36. package/resources/fe-dist/assets/{files-tab-BW0vpgW7.js → files-tab-CPud4eIT.js} +16 -21
  37. package/resources/fe-dist/assets/{flowDiagram-I6XJVG4X-CeBLfMwm.js → flowDiagram-I6XJVG4X-BnV7dZI4.js} +1 -1
  38. package/resources/fe-dist/assets/{ganttDiagram-6RSMTGT7-C0W5vjVi.js → ganttDiagram-6RSMTGT7-Cn2f5kRI.js} +1 -1
  39. package/resources/fe-dist/assets/{gitGraphDiagram-PVQCEYII-1BOW9mBR.js → gitGraphDiagram-PVQCEYII-CEswG7nI.js} +1 -1
  40. package/resources/fe-dist/assets/index-BK6c5W5S.js +314 -0
  41. package/resources/fe-dist/assets/index-CuFTSN9i.css +1 -0
  42. package/resources/fe-dist/assets/{index-BbHTMCQt.js → index-DLyPliOu.js} +1 -1
  43. package/resources/fe-dist/assets/{infoDiagram-5YYISTIA-rY2E1Qtb.js → infoDiagram-5YYISTIA-Dsx1fQI9.js} +1 -1
  44. package/resources/fe-dist/assets/{ishikawaDiagram-YF4QCWOH-bISKs9QA.js → ishikawaDiagram-YF4QCWOH-CgNMvXgO.js} +1 -1
  45. package/resources/fe-dist/assets/{ja_JP-BI-C8I9X.js → ja_JP-Bq-BwOH_.js} +1 -1
  46. package/resources/fe-dist/assets/{journeyDiagram-JHISSGLW-D5V6twg8.js → journeyDiagram-JHISSGLW-CVeui1xn.js} +1 -1
  47. package/resources/fe-dist/assets/{kanban-definition-UN3LZRKU-DqOygrx5.js → kanban-definition-UN3LZRKU-WnLUDsz4.js} +1 -1
  48. package/resources/fe-dist/assets/{linear-CvBar11D.js → linear-B0SWPrkI.js} +1 -1
  49. package/resources/fe-dist/assets/{markdown-preview-sViGxElv.js → markdown-preview-CDjnYorp.js} +3 -3
  50. package/resources/fe-dist/assets/{mermaid.core-m9JEGou3.js → mermaid.core-CXD-Pc2r.js} +5 -5
  51. package/resources/fe-dist/assets/{mindmap-definition-RKZ34NQL-DMyUzSwg.js → mindmap-definition-RKZ34NQL-DYEXXmag.js} +1 -1
  52. package/resources/fe-dist/assets/{pieDiagram-4H26LBE5-Cp3KArEr.js → pieDiagram-4H26LBE5-DkZtnbYj.js} +1 -1
  53. package/resources/fe-dist/assets/{quadrantDiagram-W4KKPZXB-B7aVg4vb.js → quadrantDiagram-W4KKPZXB-DblvGass.js} +1 -1
  54. package/resources/fe-dist/assets/{requirementDiagram-4Y6WPE33-WDLGaUPr.js → requirementDiagram-4Y6WPE33-KAX1DxRY.js} +1 -1
  55. package/resources/fe-dist/assets/{sankeyDiagram-5OEKKPKP-AElPZwq5.js → sankeyDiagram-5OEKKPKP-h9Z2LXNr.js} +1 -1
  56. package/resources/fe-dist/assets/{selection-clipboard-Dq6Zemfd.js → selection-clipboard-D3gUQQ7L.js} +1 -1
  57. package/resources/fe-dist/assets/{send-DjlZMim3.js → send-BVxB0Ywb.js} +1 -1
  58. package/resources/fe-dist/assets/{sequenceDiagram-3UESZ5HK-CUYki1W3.js → sequenceDiagram-3UESZ5HK-DUJcq5qX.js} +1 -1
  59. package/resources/fe-dist/assets/{stateDiagram-AJRCARHV-BlImbgYm.js → stateDiagram-AJRCARHV-BBT56nPD.js} +1 -1
  60. package/resources/fe-dist/assets/stateDiagram-v2-BHNVJYJU-wyzFZc_5.js +1 -0
  61. package/resources/fe-dist/assets/{terminal-settings-panel-DCm6ZfTX.js → terminal-settings-panel-DHrIp0wf.js} +1 -1
  62. package/resources/fe-dist/assets/{timeline-definition-PNZ67QCA-DnXXxVyb.js → timeline-definition-PNZ67QCA-DLkgXxGG.js} +1 -1
  63. package/resources/fe-dist/assets/{transfer-toast-BWwT4yFg.js → transfer-toast-BYw9LLNi.js} +1 -1
  64. package/resources/fe-dist/assets/{triangle-alert-D1TuPKVl.js → triangle-alert-D4oQhgpz.js} +1 -1
  65. package/resources/fe-dist/assets/{vennDiagram-CIIHVFJN-BziXMAwl.js → vennDiagram-CIIHVFJN-CyUw7cRl.js} +1 -1
  66. package/resources/fe-dist/assets/{wardley-L42UT6IY-B6fovAcQ.js → wardley-L42UT6IY-UVd2D_HQ.js} +1 -1
  67. package/resources/fe-dist/assets/{wardleyDiagram-YWT4CUSO-DdAfrCkO.js → wardleyDiagram-YWT4CUSO-B6As-5ml.js} +1 -1
  68. package/resources/fe-dist/assets/{xychartDiagram-2RQKCTM6-CWuCpr0w.js → xychartDiagram-2RQKCTM6-DFypVaEh.js} +1 -1
  69. package/resources/fe-dist/assets/{zap-CCdOD6uR.js → zap-DxVtkroR.js} +1 -1
  70. package/resources/fe-dist/assets/{zh_CN-DE-BaQ3P.js → zh_CN-BuxyXhCT.js} +1 -1
  71. package/resources/fe-dist/index.html +2 -2
  72. package/resources/fe-dist/assets/DevicePage--HOY0kN6.js +0 -19
  73. package/resources/fe-dist/assets/channel-BGHWdKHN.js +0 -1
  74. package/resources/fe-dist/assets/classDiagram-4FO5ZUOK-B47Acuru.js +0 -1
  75. package/resources/fe-dist/assets/classDiagram-v2-Q7XG4LA2-B47Acuru.js +0 -1
  76. package/resources/fe-dist/assets/index-B3aiK6xC.js +0 -299
  77. package/resources/fe-dist/assets/index-CHeveVji.css +0 -1
  78. package/resources/fe-dist/assets/stateDiagram-v2-BHNVJYJU-CzqYErp9.js +0 -1
@@ -23363,6 +23363,7 @@ Time: {{time}}`,
23363
23363
  window: {
23364
23364
  noWindows: "No windows",
23365
23365
  new: "New Window",
23366
+ newInCwd: "New window here",
23366
23367
  close: "Close window",
23367
23368
  closePane: "Close pane",
23368
23369
  closeConfirmTitle: "Close this window?",
@@ -23374,7 +23375,14 @@ Time: {{time}}`,
23374
23375
  rename: "Rename window",
23375
23376
  renamePlaceholder: "Enter a name",
23376
23377
  renameDesc: "The custom name overrides the title set by the terminal and is kept until the gateway restarts.",
23377
- renameReset: "Use automatic name"
23378
+ renameReset: "Use automatic name",
23379
+ switchPane: "Switch pane",
23380
+ splitRight: "Split right",
23381
+ splitDown: "Split down",
23382
+ paneCount: "{{count}} panes",
23383
+ pane: "Pane",
23384
+ moveToWindow: "Move into this window",
23385
+ breakToWindow: "Break into new window"
23378
23386
  },
23379
23387
  watch: {
23380
23388
  title: "Watch rules",
@@ -24361,6 +24369,7 @@ Bot\uFF1A{{botName}}
24361
24369
  window: {
24362
24370
  noWindows: "\u6682\u65E0\u7A97\u53E3",
24363
24371
  new: "\u65B0\u5EFA\u7A97\u53E3",
24372
+ newInCwd: "\u5728\u6B64\u76EE\u5F55\u65B0\u5EFA\u7A97\u53E3",
24364
24373
  close: "\u5173\u95ED\u7A97\u53E3",
24365
24374
  closePane: "\u5173\u95ED\u9762\u677F",
24366
24375
  closeConfirmTitle: "\u5173\u95ED\u6B64\u7A97\u53E3\uFF1F",
@@ -24372,7 +24381,14 @@ Bot\uFF1A{{botName}}
24372
24381
  rename: "\u91CD\u547D\u540D\u7A97\u53E3",
24373
24382
  renamePlaceholder: "\u8F93\u5165\u540D\u79F0",
24374
24383
  renameDesc: "\u81EA\u5B9A\u4E49\u540D\u79F0\u4F1A\u8986\u76D6\u7EC8\u7AEF\u8BBE\u7F6E\u7684\u6807\u9898\uFF0C\u5E76\u4FDD\u7559\u81F3 gateway \u91CD\u542F\u3002",
24375
- renameReset: "\u6062\u590D\u81EA\u52A8\u540D\u79F0"
24384
+ renameReset: "\u6062\u590D\u81EA\u52A8\u540D\u79F0",
24385
+ switchPane: "\u5207\u6362 Pane",
24386
+ splitRight: "\u5411\u53F3\u5206\u5C4F",
24387
+ splitDown: "\u5411\u4E0B\u5206\u5C4F",
24388
+ paneCount: "{{count}} \u4E2A pane",
24389
+ pane: "Pane",
24390
+ moveToWindow: "\u79FB\u5165\u6B64\u7A97\u53E3",
24391
+ breakToWindow: "\u62C6\u4E3A\u72EC\u7ACB\u7A97\u53E3"
24376
24392
  },
24377
24393
  watch: {
24378
24394
  title: "\u76D1\u63A7\u89C4\u5219",
@@ -25359,6 +25375,7 @@ Bot\uFF1A{{botName}}
25359
25375
  window: {
25360
25376
  noWindows: "\u30A6\u30A3\u30F3\u30C9\u30A6\u304C\u3042\u308A\u307E\u305B\u3093",
25361
25377
  new: "\u65B0\u898F\u30A6\u30A3\u30F3\u30C9\u30A6",
25378
+ newInCwd: "\u3053\u306E\u5834\u6240\u3067\u65B0\u898F\u30A6\u30A3\u30F3\u30C9\u30A6",
25362
25379
  close: "\u30A6\u30A3\u30F3\u30C9\u30A6\u3092\u9589\u3058\u308B",
25363
25380
  closePane: "\u30DA\u30A4\u30F3\u3092\u9589\u3058\u308B",
25364
25381
  closeConfirmTitle: "\u3053\u306E\u30A6\u30A3\u30F3\u30C9\u30A6\u3092\u9589\u3058\u307E\u3059\u304B\uFF1F",
@@ -25370,7 +25387,14 @@ Bot\uFF1A{{botName}}
25370
25387
  rename: "\u30A6\u30A3\u30F3\u30C9\u30A6\u540D\u3092\u5909\u66F4",
25371
25388
  renamePlaceholder: "\u540D\u524D\u3092\u5165\u529B",
25372
25389
  renameDesc: "\u30AB\u30B9\u30BF\u30E0\u540D\u306F\u30BF\u30FC\u30DF\u30CA\u30EB\u304C\u8A2D\u5B9A\u3057\u305F\u30BF\u30A4\u30C8\u30EB\u3092\u4E0A\u66F8\u304D\u3057\u3001\u30B2\u30FC\u30C8\u30A6\u30A7\u30A4\u304C\u518D\u8D77\u52D5\u3059\u308B\u307E\u3067\u4FDD\u6301\u3055\u308C\u307E\u3059\u3002",
25373
- renameReset: "\u81EA\u52D5\u540D\u306B\u623B\u3059"
25390
+ renameReset: "\u81EA\u52D5\u540D\u306B\u623B\u3059",
25391
+ switchPane: "\u30DA\u30A4\u30F3\u5207\u66FF",
25392
+ splitRight: "\u53F3\u306B\u5206\u5272",
25393
+ splitDown: "\u4E0B\u306B\u5206\u5272",
25394
+ paneCount: "{{count}} \u30DA\u30A4\u30F3",
25395
+ pane: "\u30DA\u30A4\u30F3",
25396
+ moveToWindow: "\u3053\u306E\u30A6\u30A3\u30F3\u30C9\u30A6\u3078\u79FB\u52D5",
25397
+ breakToWindow: "\u65B0\u3057\u3044\u30A6\u30A3\u30F3\u30C9\u30A6\u306B\u5206\u96E2"
25374
25398
  },
25375
25399
  watch: {
25376
25400
  title: "\u76E3\u8996\u30EB\u30FC\u30EB",
@@ -25618,16 +25642,25 @@ __export(exports_ws_borsh, {
25618
25642
  MAX_CHUNKS_PER_MESSAGE: () => MAX_CHUNKS_PER_MESSAGE,
25619
25643
  MAGIC: () => MAGIC,
25620
25644
  KIND_WATCH_EVENT: () => KIND_WATCH_EVENT,
25645
+ KIND_TMUX_SUBSCRIBE_PANES: () => KIND_TMUX_SUBSCRIBE_PANES,
25646
+ KIND_TMUX_SPLIT_PANE: () => KIND_TMUX_SPLIT_PANE,
25621
25647
  KIND_TMUX_SET_WINDOW_STYLE: () => KIND_TMUX_SET_WINDOW_STYLE,
25622
25648
  KIND_TMUX_SELECT_WINDOW: () => KIND_TMUX_SELECT_WINDOW,
25623
25649
  KIND_TMUX_SELECT: () => KIND_TMUX_SELECT,
25650
+ KIND_TMUX_RESIZE_PANE: () => KIND_TMUX_RESIZE_PANE,
25624
25651
  KIND_TMUX_REORDER_WINDOWS: () => KIND_TMUX_REORDER_WINDOWS,
25625
25652
  KIND_TMUX_REORDER_PANES: () => KIND_TMUX_REORDER_PANES,
25626
25653
  KIND_TMUX_RENAME_WINDOW: () => KIND_TMUX_RENAME_WINDOW,
25654
+ KIND_TMUX_RENAME_PANE: () => KIND_TMUX_RENAME_PANE,
25655
+ KIND_TMUX_MOVE_PANE: () => KIND_TMUX_MOVE_PANE,
25656
+ KIND_TMUX_FOCUS_PANE: () => KIND_TMUX_FOCUS_PANE,
25657
+ KIND_TMUX_FETCH_PANE_HISTORY: () => KIND_TMUX_FETCH_PANE_HISTORY,
25627
25658
  KIND_TMUX_EVENT: () => KIND_TMUX_EVENT,
25628
25659
  KIND_TMUX_CREATE_WINDOW: () => KIND_TMUX_CREATE_WINDOW,
25629
25660
  KIND_TMUX_CLOSE_WINDOW: () => KIND_TMUX_CLOSE_WINDOW,
25630
25661
  KIND_TMUX_CLOSE_PANE: () => KIND_TMUX_CLOSE_PANE,
25662
+ KIND_TMUX_BREAK_PANE: () => KIND_TMUX_BREAK_PANE,
25663
+ KIND_TMUX_APPLY_STACKED_LAYOUT: () => KIND_TMUX_APPLY_STACKED_LAYOUT,
25631
25664
  KIND_TERM_SYNC_SIZE: () => KIND_TERM_SYNC_SIZE,
25632
25665
  KIND_TERM_RESIZE: () => KIND_TERM_RESIZE,
25633
25666
  KIND_TERM_PASTE: () => KIND_TERM_PASTE,
@@ -25714,6 +25747,15 @@ var KIND_STATE_SNAPSHOT_DIFF = 521;
25714
25747
  var KIND_TMUX_SET_WINDOW_STYLE = 522;
25715
25748
  var KIND_TMUX_REORDER_WINDOWS = 523;
25716
25749
  var KIND_TMUX_REORDER_PANES = 524;
25750
+ var KIND_TMUX_SUBSCRIBE_PANES = 525;
25751
+ var KIND_TMUX_FETCH_PANE_HISTORY = 526;
25752
+ var KIND_TMUX_RESIZE_PANE = 527;
25753
+ var KIND_TMUX_APPLY_STACKED_LAYOUT = 528;
25754
+ var KIND_TMUX_SPLIT_PANE = 529;
25755
+ var KIND_TMUX_FOCUS_PANE = 530;
25756
+ var KIND_TMUX_RENAME_PANE = 531;
25757
+ var KIND_TMUX_MOVE_PANE = 532;
25758
+ var KIND_TMUX_BREAK_PANE = 533;
25717
25759
  var KIND_TERM_INPUT = 769;
25718
25760
  var KIND_TERM_PASTE = 770;
25719
25761
  var KIND_TERM_RESIZE = 771;
@@ -25751,6 +25793,15 @@ var VALID_KINDS = new Set([
25751
25793
  KIND_TMUX_SET_WINDOW_STYLE,
25752
25794
  KIND_TMUX_REORDER_WINDOWS,
25753
25795
  KIND_TMUX_REORDER_PANES,
25796
+ KIND_TMUX_SUBSCRIBE_PANES,
25797
+ KIND_TMUX_FETCH_PANE_HISTORY,
25798
+ KIND_TMUX_RESIZE_PANE,
25799
+ KIND_TMUX_APPLY_STACKED_LAYOUT,
25800
+ KIND_TMUX_SPLIT_PANE,
25801
+ KIND_TMUX_FOCUS_PANE,
25802
+ KIND_TMUX_RENAME_PANE,
25803
+ KIND_TMUX_MOVE_PANE,
25804
+ KIND_TMUX_BREAK_PANE,
25754
25805
  KIND_TERM_INPUT,
25755
25806
  KIND_TERM_PASTE,
25756
25807
  KIND_TERM_RESIZE,
@@ -25793,6 +25844,15 @@ function kindToString(kind) {
25793
25844
  [KIND_TMUX_SET_WINDOW_STYLE]: "TMUX_SET_WINDOW_STYLE",
25794
25845
  [KIND_TMUX_REORDER_WINDOWS]: "TMUX_REORDER_WINDOWS",
25795
25846
  [KIND_TMUX_REORDER_PANES]: "TMUX_REORDER_PANES",
25847
+ [KIND_TMUX_SUBSCRIBE_PANES]: "TMUX_SUBSCRIBE_PANES",
25848
+ [KIND_TMUX_FETCH_PANE_HISTORY]: "TMUX_FETCH_PANE_HISTORY",
25849
+ [KIND_TMUX_RESIZE_PANE]: "TMUX_RESIZE_PANE",
25850
+ [KIND_TMUX_APPLY_STACKED_LAYOUT]: "TMUX_APPLY_STACKED_LAYOUT",
25851
+ [KIND_TMUX_SPLIT_PANE]: "TMUX_SPLIT_PANE",
25852
+ [KIND_TMUX_FOCUS_PANE]: "TMUX_FOCUS_PANE",
25853
+ [KIND_TMUX_RENAME_PANE]: "TMUX_RENAME_PANE",
25854
+ [KIND_TMUX_MOVE_PANE]: "TMUX_MOVE_PANE",
25855
+ [KIND_TMUX_BREAK_PANE]: "TMUX_BREAK_PANE",
25796
25856
  [KIND_TERM_INPUT]: "TERM_INPUT",
25797
25857
  [KIND_TERM_PASTE]: "TERM_PASTE",
25798
25858
  [KIND_TERM_RESIZE]: "TERM_RESIZE",
@@ -25877,16 +25937,25 @@ __export(exports_schema, {
25877
25937
  WindowAddEventSchema: () => WindowAddEventSchema,
25878
25938
  WindowActiveEventSchema: () => WindowActiveEventSchema,
25879
25939
  WatchEventSchema: () => WatchEventSchema,
25940
+ TmuxSubscribePanesSchema: () => TmuxSubscribePanesSchema,
25941
+ TmuxSplitPaneSchema: () => TmuxSplitPaneSchema,
25880
25942
  TmuxSetWindowStyleSchema: () => TmuxSetWindowStyleSchema,
25881
25943
  TmuxSelectWindowSchema: () => TmuxSelectWindowSchema,
25882
25944
  TmuxSelectSchema: () => TmuxSelectSchema,
25945
+ TmuxResizePaneSchema: () => TmuxResizePaneSchema,
25883
25946
  TmuxReorderWindowsSchema: () => TmuxReorderWindowsSchema,
25884
25947
  TmuxReorderPanesSchema: () => TmuxReorderPanesSchema,
25885
25948
  TmuxRenameWindowSchema: () => TmuxRenameWindowSchema,
25949
+ TmuxRenamePaneSchema: () => TmuxRenamePaneSchema,
25950
+ TmuxMovePaneSchema: () => TmuxMovePaneSchema,
25951
+ TmuxFocusPaneSchema: () => TmuxFocusPaneSchema,
25952
+ TmuxFetchPaneHistorySchema: () => TmuxFetchPaneHistorySchema,
25886
25953
  TmuxEventSchema: () => TmuxEventSchema,
25887
25954
  TmuxCreateWindowSchema: () => TmuxCreateWindowSchema,
25888
25955
  TmuxCloseWindowSchema: () => TmuxCloseWindowSchema,
25889
25956
  TmuxClosePaneSchema: () => TmuxClosePaneSchema,
25957
+ TmuxBreakPaneSchema: () => TmuxBreakPaneSchema,
25958
+ TmuxApplyStackedLayoutSchema: () => TmuxApplyStackedLayoutSchema,
25890
25959
  TermSyncSizeSchema: () => TermSyncSizeSchema,
25891
25960
  TermResizeSchema: () => TermResizeSchema,
25892
25961
  TermPasteSchema: () => TermPasteSchema,
@@ -25995,7 +26064,8 @@ var TmuxSelectWindowSchema = import_zorsh.b.struct({
25995
26064
  });
25996
26065
  var TmuxCreateWindowSchema = import_zorsh.b.struct({
25997
26066
  deviceId: import_zorsh.b.string(),
25998
- name: OptionStringSchema
26067
+ name: OptionStringSchema,
26068
+ cwd: OptionStringSchema
25999
26069
  });
26000
26070
  var TmuxCloseWindowSchema = import_zorsh.b.struct({
26001
26071
  deviceId: import_zorsh.b.string(),
@@ -26028,6 +26098,53 @@ var TmuxEventSchema = import_zorsh.b.struct({
26028
26098
  eventType: import_zorsh.b.u8(),
26029
26099
  eventData: import_zorsh.b.bytes()
26030
26100
  });
26101
+ var TmuxSubscribePanesSchema = import_zorsh.b.struct({
26102
+ deviceId: import_zorsh.b.string(),
26103
+ paneIds: import_zorsh.b.vec(import_zorsh.b.string())
26104
+ });
26105
+ var TmuxFetchPaneHistorySchema = import_zorsh.b.struct({
26106
+ deviceId: import_zorsh.b.string(),
26107
+ paneId: import_zorsh.b.string(),
26108
+ requestToken: import_zorsh.b.bytes(16)
26109
+ });
26110
+ var TmuxResizePaneSchema = import_zorsh.b.struct({
26111
+ deviceId: import_zorsh.b.string(),
26112
+ paneId: import_zorsh.b.string(),
26113
+ cols: OptionU16Schema,
26114
+ rows: OptionU16Schema
26115
+ });
26116
+ var TmuxApplyStackedLayoutSchema = import_zorsh.b.struct({
26117
+ deviceId: import_zorsh.b.string(),
26118
+ windowId: import_zorsh.b.string(),
26119
+ cols: import_zorsh.b.u16(),
26120
+ rows: import_zorsh.b.u16()
26121
+ });
26122
+ var TmuxSplitPaneSchema = import_zorsh.b.struct({
26123
+ deviceId: import_zorsh.b.string(),
26124
+ paneId: import_zorsh.b.string(),
26125
+ direction: import_zorsh.b.u8(),
26126
+ cwd: OptionStringSchema
26127
+ });
26128
+ var TmuxFocusPaneSchema = import_zorsh.b.struct({
26129
+ deviceId: import_zorsh.b.string(),
26130
+ windowId: import_zorsh.b.string(),
26131
+ paneId: import_zorsh.b.string()
26132
+ });
26133
+ var TmuxRenamePaneSchema = import_zorsh.b.struct({
26134
+ deviceId: import_zorsh.b.string(),
26135
+ paneId: import_zorsh.b.string(),
26136
+ name: import_zorsh.b.string()
26137
+ });
26138
+ var TmuxMovePaneSchema = import_zorsh.b.struct({
26139
+ deviceId: import_zorsh.b.string(),
26140
+ srcPaneId: import_zorsh.b.string(),
26141
+ dstPaneId: import_zorsh.b.string(),
26142
+ position: import_zorsh.b.u8()
26143
+ });
26144
+ var TmuxBreakPaneSchema = import_zorsh.b.struct({
26145
+ deviceId: import_zorsh.b.string(),
26146
+ paneId: import_zorsh.b.string()
26147
+ });
26031
26148
  var TermInputSchema = import_zorsh.b.struct({
26032
26149
  deviceId: import_zorsh.b.string(),
26033
26150
  paneId: import_zorsh.b.string(),
@@ -26092,9 +26209,14 @@ var PaneWireSchema = import_zorsh.b.struct({
26092
26209
  windowId: import_zorsh.b.string(),
26093
26210
  index: import_zorsh.b.u16(),
26094
26211
  title: OptionStringSchema,
26212
+ customName: OptionStringSchema,
26095
26213
  active: import_zorsh.b.bool(),
26096
26214
  width: import_zorsh.b.u16(),
26097
- height: import_zorsh.b.u16()
26215
+ height: import_zorsh.b.u16(),
26216
+ currentPath: OptionStringSchema,
26217
+ currentCommand: OptionStringSchema,
26218
+ left: OptionU16Schema,
26219
+ top: OptionU16Schema
26098
26220
  });
26099
26221
  var WindowWireSchema = import_zorsh.b.struct({
26100
26222
  id: import_zorsh.b.string(),
@@ -26102,6 +26224,7 @@ var WindowWireSchema = import_zorsh.b.struct({
26102
26224
  customName: OptionStringSchema,
26103
26225
  index: import_zorsh.b.u16(),
26104
26226
  active: import_zorsh.b.bool(),
26227
+ layout: OptionStringSchema,
26105
26228
  panes: import_zorsh.b.vec(PaneWireSchema)
26106
26229
  });
26107
26230
  var SessionWireSchema = import_zorsh.b.struct({
@@ -26550,6 +26673,7 @@ function encodeWindowWire(window2) {
26550
26673
  customName: window2.customName ?? null,
26551
26674
  index: window2.index,
26552
26675
  active: window2.active,
26676
+ layout: window2.layout ?? null,
26553
26677
  panes: window2.panes.map(encodePaneWire)
26554
26678
  };
26555
26679
  }
@@ -26559,9 +26683,14 @@ function encodePaneWire(pane) {
26559
26683
  windowId: pane.windowId,
26560
26684
  index: pane.index,
26561
26685
  title: pane.title ?? null,
26686
+ customName: pane.customName ?? null,
26562
26687
  active: pane.active,
26563
26688
  width: pane.width,
26564
- height: pane.height
26689
+ height: pane.height,
26690
+ currentPath: pane.currentPath ?? null,
26691
+ currentCommand: pane.currentCommand ?? null,
26692
+ left: pane.left ?? null,
26693
+ top: pane.top ?? null
26565
26694
  };
26566
26695
  }
26567
26696
  function decodeDeviceEventPayload(data) {
@@ -26681,6 +26810,7 @@ function decodeWindowWire(wire) {
26681
26810
  customName: wire.customName ?? undefined,
26682
26811
  index: wire.index,
26683
26812
  active: wire.active,
26813
+ layout: wire.layout ?? undefined,
26684
26814
  panes: wire.panes.map(decodePaneWire)
26685
26815
  };
26686
26816
  }
@@ -26690,9 +26820,14 @@ function decodePaneWire(wire) {
26690
26820
  windowId: wire.windowId,
26691
26821
  index: wire.index,
26692
26822
  title: wire.title ?? undefined,
26823
+ customName: wire.customName ?? undefined,
26693
26824
  active: wire.active,
26694
26825
  width: wire.width,
26695
- height: wire.height
26826
+ height: wire.height,
26827
+ currentPath: wire.currentPath ?? undefined,
26828
+ currentCommand: wire.currentCommand ?? undefined,
26829
+ left: wire.left ?? undefined,
26830
+ top: wire.top ?? undefined
26696
26831
  };
26697
26832
  }
26698
26833
  // ../shared/src/index.ts
@@ -98801,6 +98936,78 @@ function formatSnapshotRowForLog(line, limit = 160) {
98801
98936
  }
98802
98937
  return `${line.slice(0, Math.max(0, limit - 3))}...`;
98803
98938
  }
98939
+ var WINDOW_SNAPSHOT_FORMAT = [
98940
+ "#{window_id}",
98941
+ "#{window_index}",
98942
+ "#{window_active}",
98943
+ "#{window_layout}",
98944
+ "#{window_name}"
98945
+ ].join(SNAPSHOT_FIELD_SEPARATOR);
98946
+ var PANE_SNAPSHOT_FORMAT = [
98947
+ "#{pane_id}",
98948
+ "#{window_id}",
98949
+ "#{pane_index}",
98950
+ "#{pane_active}",
98951
+ "#{pane_width}",
98952
+ "#{pane_height}",
98953
+ "#{pane_left}",
98954
+ "#{pane_top}",
98955
+ "#{window_active}",
98956
+ "#{pane_title}",
98957
+ "#{pane_current_command}",
98958
+ "#{pane_current_path}"
98959
+ ].join(SNAPSHOT_FIELD_SEPARATOR);
98960
+ function isSnapshotFlag(value) {
98961
+ return value === "0" || value === "1";
98962
+ }
98963
+ var WINDOW_LAYOUT_PATTERN = /^[0-9a-fA-F]{4},[0-9x,{}[\]]+$/;
98964
+ function parseWindowSnapshotRow(line) {
98965
+ const parts = line.split(SNAPSHOT_FIELD_SEPARATOR);
98966
+ if (parts.length < 5) {
98967
+ return null;
98968
+ }
98969
+ const [id, indexRaw, activeRaw, layoutRaw] = parts;
98970
+ const name24 = parts.slice(4).join(SNAPSHOT_FIELD_SEPARATOR);
98971
+ const index = parseSnapshotInteger(indexRaw);
98972
+ if (!isTmuxWindowId(id) || index === null || !isSnapshotFlag(activeRaw)) {
98973
+ return null;
98974
+ }
98975
+ const layout = typeof layoutRaw === "string" && WINDOW_LAYOUT_PATTERN.test(layoutRaw) ? layoutRaw : undefined;
98976
+ return { id, index, active: activeRaw === "1", layout, name: name24 };
98977
+ }
98978
+ function parsePaneSnapshotRow(line) {
98979
+ const parts = line.split(SNAPSHOT_FIELD_SEPARATOR);
98980
+ if (parts.length < 12) {
98981
+ return null;
98982
+ }
98983
+ const [id, windowId, indexRaw, activeRaw, widthRaw, heightRaw, leftRaw, topRaw, windowActiveRaw] = parts;
98984
+ const rest = parts.slice(9);
98985
+ const title = rest.slice(0, rest.length - 2).join(SNAPSHOT_FIELD_SEPARATOR);
98986
+ const currentCommand = rest.at(-2) ?? "";
98987
+ const currentPath = rest.at(-1) ?? "";
98988
+ const index = parseSnapshotInteger(indexRaw);
98989
+ const width = parseSnapshotInteger(widthRaw);
98990
+ const height = parseSnapshotInteger(heightRaw);
98991
+ const left = parseSnapshotInteger(leftRaw);
98992
+ const top = parseSnapshotInteger(topRaw);
98993
+ if (!isTmuxPaneId(id) || !isTmuxWindowId(windowId) || index === null || width === null || height === null || !isSnapshotFlag(activeRaw) || !isSnapshotFlag(windowActiveRaw)) {
98994
+ return null;
98995
+ }
98996
+ return {
98997
+ id,
98998
+ windowId,
98999
+ index,
99000
+ active: activeRaw === "1",
99001
+ width,
99002
+ height,
99003
+ left: left ?? undefined,
99004
+ top: top ?? undefined,
99005
+ windowActive: windowActiveRaw === "1",
99006
+ title: title.trim() ? title : undefined,
99007
+ currentCommand: currentCommand.trim() ? currentCommand.trim() : undefined,
99008
+ currentPath: currentPath.trim() ? currentPath.trim() : undefined
99009
+ };
99010
+ }
98804
99011
  function splitSnapshotFields(line, fieldCount) {
98805
99012
  const parts = line.split(SNAPSHOT_FIELD_SEPARATOR);
98806
99013
  if (parts.length <= fieldCount) {
@@ -99102,11 +99309,11 @@ class LocalExternalTmuxConnection {
99102
99309
  this.callbacks.onError(error51);
99103
99310
  });
99104
99311
  }
99105
- createWindow(name24) {
99312
+ createWindow(name24, cwd) {
99106
99313
  if (!this.connected) {
99107
99314
  return;
99108
99315
  }
99109
- const argv = ["new-window", "-t", this.sessionName, "-c", this.resolveDefaultWorkingDir()];
99316
+ const argv = ["new-window", "-t", this.sessionName, "-c", cwd ?? this.resolveDefaultWorkingDir()];
99110
99317
  if (name24) {
99111
99318
  argv.push("-n", name24);
99112
99319
  }
@@ -99130,6 +99337,96 @@ class LocalExternalTmuxConnection {
99130
99337
  this.callbacks.onError(error51);
99131
99338
  });
99132
99339
  }
99340
+ splitPane(paneId, direction, cwd) {
99341
+ if (!this.connected) {
99342
+ return;
99343
+ }
99344
+ this.splitPaneInternal(paneId, direction, cwd).catch((error51) => {
99345
+ this.callbacks.onError(error51);
99346
+ });
99347
+ }
99348
+ resizePaneById(paneId, size) {
99349
+ if (!this.connected) {
99350
+ return;
99351
+ }
99352
+ this.resizePaneByIdInternal(paneId, size).catch((error51) => {
99353
+ this.callbacks.onError(error51);
99354
+ });
99355
+ }
99356
+ resizeWindow(windowId, cols, rows) {
99357
+ if (!this.connected) {
99358
+ return;
99359
+ }
99360
+ this.resizeWindowInternal(windowId, cols, rows).catch((error51) => {
99361
+ this.callbacks.onError(error51);
99362
+ });
99363
+ }
99364
+ selectLayout(windowId, preset) {
99365
+ if (!this.connected) {
99366
+ return;
99367
+ }
99368
+ this.runAndRefresh(["select-layout", "-t", windowId, preset], true).catch((error51) => {
99369
+ this.callbacks.onError(error51);
99370
+ });
99371
+ }
99372
+ focusPane(windowId, paneId) {
99373
+ if (!this.connected) {
99374
+ return;
99375
+ }
99376
+ this.focusPaneInternal(windowId, paneId).catch((error51) => {
99377
+ this.callbacks.onError(error51);
99378
+ });
99379
+ }
99380
+ movePane(srcPaneId, dstPaneId, position) {
99381
+ if (!this.connected) {
99382
+ return;
99383
+ }
99384
+ const argv = ["move-pane"];
99385
+ argv.push(position === "left" || position === "right" ? "-h" : "-v");
99386
+ if (position === "left" || position === "top") {
99387
+ argv.push("-b");
99388
+ }
99389
+ argv.push("-s", srcPaneId, "-t", dstPaneId);
99390
+ this.runAndRefresh(argv, true).catch((error51) => {
99391
+ this.callbacks.onError(error51);
99392
+ });
99393
+ }
99394
+ breakPane(paneId) {
99395
+ if (!this.connected) {
99396
+ return;
99397
+ }
99398
+ this.breakPaneInternal(paneId).catch((error51) => {
99399
+ this.callbacks.onError(error51);
99400
+ });
99401
+ }
99402
+ async breakPaneInternal(paneId) {
99403
+ const result = await this.runTmux([
99404
+ "break-pane",
99405
+ "-s",
99406
+ paneId,
99407
+ "-t",
99408
+ `${this.sessionName}:`,
99409
+ "-P",
99410
+ "-F",
99411
+ `#{window_id}${SNAPSHOT_FIELD_SEPARATOR}#{pane_id}`
99412
+ ], true);
99413
+ const [windowId, newPaneId] = result.stdout.trim().split(SNAPSHOT_FIELD_SEPARATOR);
99414
+ if (isTmuxWindowId(windowId) && isTmuxPaneId(newPaneId)) {
99415
+ this.activeWindowId = windowId;
99416
+ this.activePaneId = newPaneId;
99417
+ this.callbacks.onEvent({
99418
+ type: "pane-active",
99419
+ data: { windowId, paneId: newPaneId }
99420
+ });
99421
+ }
99422
+ await this.requestSnapshotInternal();
99423
+ }
99424
+ async requestPaneHistory(paneId) {
99425
+ if (!this.connected) {
99426
+ return;
99427
+ }
99428
+ await this.capturePaneHistory(paneId);
99429
+ }
99133
99430
  renameWindow(windowId, name24) {
99134
99431
  if (!this.connected) {
99135
99432
  return;
@@ -99575,15 +99872,66 @@ class LocalExternalTmuxConnection {
99575
99872
  await this.runAndRefresh(["kill-window", "-t", windowId], true);
99576
99873
  }
99577
99874
  async resizePaneInternal(paneId, cols, rows) {
99578
- const safeCols = Math.max(2, Math.floor(cols));
99579
- const safeRows = Math.max(2, Math.floor(rows));
99580
99875
  const windowId = this.findPaneWindowId(paneId) ?? (await this.runTmux(["display-message", "-p", "-t", paneId, "#{window_id}"], true)).stdout.trim();
99581
99876
  if (!windowId) {
99582
99877
  return;
99583
99878
  }
99879
+ await this.resizeWindowInternal(windowId, cols, rows);
99880
+ }
99881
+ async resizeWindowInternal(windowId, cols, rows) {
99882
+ const safeCols = Math.max(2, Math.floor(cols));
99883
+ const safeRows = Math.max(2, Math.floor(rows));
99584
99884
  await this.runTmux(["resize-window", "-t", windowId, "-x", String(safeCols), "-y", String(safeRows)], true);
99585
99885
  await this.requestSnapshotInternal();
99586
99886
  }
99887
+ async resizePaneByIdInternal(paneId, size) {
99888
+ const argv = ["resize-pane", "-t", paneId];
99889
+ if (size.cols !== undefined) {
99890
+ argv.push("-x", String(Math.max(2, Math.floor(size.cols))));
99891
+ }
99892
+ if (size.rows !== undefined) {
99893
+ argv.push("-y", String(Math.max(2, Math.floor(size.rows))));
99894
+ }
99895
+ if (argv.length === 3) {
99896
+ return;
99897
+ }
99898
+ await this.runTmux(argv, true);
99899
+ await this.requestSnapshotInternal();
99900
+ }
99901
+ async splitPaneInternal(paneId, direction, cwd) {
99902
+ const result = await this.runTmux([
99903
+ "split-window",
99904
+ direction === "h" ? "-h" : "-v",
99905
+ "-t",
99906
+ paneId,
99907
+ "-c",
99908
+ cwd ?? this.resolveDefaultWorkingDir(),
99909
+ "-P",
99910
+ "-F",
99911
+ `#{window_id}${SNAPSHOT_FIELD_SEPARATOR}#{pane_id}`
99912
+ ], true);
99913
+ const [windowId, newPaneId] = result.stdout.trim().split(SNAPSHOT_FIELD_SEPARATOR);
99914
+ if (isTmuxWindowId(windowId) && isTmuxPaneId(newPaneId)) {
99915
+ this.activeWindowId = windowId;
99916
+ this.activePaneId = newPaneId;
99917
+ this.callbacks.onEvent({
99918
+ type: "pane-active",
99919
+ data: { windowId, paneId: newPaneId }
99920
+ });
99921
+ }
99922
+ await this.requestSnapshotInternal();
99923
+ }
99924
+ async focusPaneInternal(windowId, paneId) {
99925
+ this.activeWindowId = windowId;
99926
+ this.activePaneId = paneId;
99927
+ await this.runTmux(["select-window", "-t", windowId], true);
99928
+ await this.runTmux(["select-pane", "-t", paneId], true);
99929
+ this.callbacks.onEvent({
99930
+ type: "pane-active",
99931
+ data: { windowId, paneId }
99932
+ });
99933
+ await this.requestSnapshotInternal();
99934
+ }
99587
99935
  async selectPaneInternal(windowId, paneId, size) {
99588
99936
  this.activeWindowId = windowId;
99589
99937
  this.activePaneId = paneId;
@@ -99626,26 +99974,9 @@ class LocalExternalTmuxConnection {
99626
99974
  "-t",
99627
99975
  this.sessionName,
99628
99976
  "-F",
99629
- ["#{window_id}", "#{window_index}", "#{window_name}", "#{window_active}"].join(SNAPSHOT_FIELD_SEPARATOR)
99977
+ WINDOW_SNAPSHOT_FORMAT
99630
99978
  ]),
99631
- this.runTmuxAllowFailure([
99632
- "list-panes",
99633
- "-s",
99634
- "-t",
99635
- this.sessionName,
99636
- "-F",
99637
- [
99638
- "#{pane_id}",
99639
- "#{window_id}",
99640
- "#{pane_index}",
99641
- "#{pane_title}",
99642
- "#{pane_active}",
99643
- "#{pane_width}",
99644
- "#{pane_height}",
99645
- "#{window_active}",
99646
- "#{pane_current_command}"
99647
- ].join(SNAPSHOT_FIELD_SEPARATOR)
99648
- ])
99979
+ this.runTmuxAllowFailure(["list-panes", "-s", "-t", this.sessionName, "-F", PANE_SNAPSHOT_FORMAT])
99649
99980
  ]);
99650
99981
  const transientResult = [sessionRes, windowsRes, panesRes].find((res) => res.exitCode === TMUX_SPAWN_UNAVAILABLE_EXIT);
99651
99982
  if (transientResult) {
@@ -99699,21 +100030,20 @@ ${panesRes.stderr}`;
99699
100030
  if (!line.trim()) {
99700
100031
  continue;
99701
100032
  }
99702
- const [id, indexRaw, name24, activeRaw] = splitSnapshotFields(line, 4);
99703
- const index = parseSnapshotInteger(indexRaw);
99704
- if (!isTmuxWindowId(id) || index === null || !this.isSnapshotFlag(activeRaw)) {
100033
+ const row = parseWindowSnapshotRow(line);
100034
+ if (!row) {
99705
100035
  console.warn(`[local] ignoring invalid tmux window snapshot row on ${this.deviceId}: ${formatSnapshotRowForLog(line)}`);
99706
100036
  continue;
99707
100037
  }
99708
- const active = activeRaw === "1";
99709
- if (active) {
99710
- this.activeWindowId = id;
100038
+ if (row.active) {
100039
+ this.activeWindowId = row.id;
99711
100040
  }
99712
- this.snapshotWindows.set(id, {
99713
- id,
99714
- index,
99715
- name: name24 ?? "",
99716
- active,
100041
+ this.snapshotWindows.set(row.id, {
100042
+ id: row.id,
100043
+ index: row.index,
100044
+ name: row.name,
100045
+ active: row.active,
100046
+ layout: row.layout,
99717
100047
  panes: []
99718
100048
  });
99719
100049
  }
@@ -99726,34 +100056,34 @@ ${panesRes.stderr}`;
99726
100056
  if (!line.trim()) {
99727
100057
  continue;
99728
100058
  }
99729
- const [paneId, windowId, indexRaw, titleRaw, activeRaw, widthRaw, heightRaw, windowActiveRaw, currentCommandRaw] = splitSnapshotFields(line, 9);
99730
- const index = parseSnapshotInteger(indexRaw);
99731
- const width = parseSnapshotInteger(widthRaw);
99732
- const height = parseSnapshotInteger(heightRaw);
99733
- if (!isTmuxPaneId(paneId) || !isTmuxWindowId(windowId) || index === null || width === null || height === null || !this.isSnapshotFlag(activeRaw) || !this.isSnapshotFlag(windowActiveRaw)) {
100059
+ const row = parsePaneSnapshotRow(line);
100060
+ if (!row) {
99734
100061
  console.warn(`[local] ignoring invalid tmux pane snapshot row on ${this.deviceId}: ${formatSnapshotRowForLog(line)}`);
99735
100062
  continue;
99736
100063
  }
99737
100064
  const pane = {
99738
- id: paneId,
99739
- windowId,
99740
- index,
99741
- title: this.pendingPaneTitles.get(paneId) ?? (titleRaw?.trim() ? titleRaw : undefined),
99742
- currentCommand: currentCommandRaw?.trim() ? currentCommandRaw.trim() : undefined,
99743
- active: activeRaw === "1",
99744
- width,
99745
- height
100065
+ id: row.id,
100066
+ windowId: row.windowId,
100067
+ index: row.index,
100068
+ title: this.pendingPaneTitles.get(row.id) ?? row.title,
100069
+ currentCommand: row.currentCommand,
100070
+ currentPath: row.currentPath,
100071
+ active: row.active,
100072
+ width: row.width,
100073
+ height: row.height,
100074
+ left: row.left,
100075
+ top: row.top
99746
100076
  };
99747
- if (pane.active && windowActiveRaw === "1") {
99748
- this.activePaneId = paneId;
99749
- this.activeWindowId = windowId;
100077
+ if (pane.active && row.windowActive) {
100078
+ this.activePaneId = row.id;
100079
+ this.activeWindowId = row.windowId;
99750
100080
  }
99751
- const window2 = this.snapshotWindows.get(windowId);
100081
+ const window2 = this.snapshotWindows.get(row.windowId);
99752
100082
  if (!window2) {
99753
100083
  continue;
99754
100084
  }
99755
100085
  window2.panes.push(pane);
99756
- this.pendingPaneTitles.delete(paneId);
100086
+ this.pendingPaneTitles.delete(row.id);
99757
100087
  }
99758
100088
  for (const window2 of this.snapshotWindows.values()) {
99759
100089
  window2.panes.sort((left, right) => left.index - right.index);
@@ -100395,11 +100725,11 @@ class SshExternalTmuxConnection {
100395
100725
  this.callbacks.onError(error51);
100396
100726
  });
100397
100727
  }
100398
- createWindow(name24) {
100728
+ createWindow(name24, cwd) {
100399
100729
  if (!this.connected) {
100400
100730
  return;
100401
100731
  }
100402
- const argv = ["new-window", "-t", this.sessionName, "-c", this.resolveDefaultWorkingDir()];
100732
+ const argv = ["new-window", "-t", this.sessionName, "-c", cwd ?? this.resolveDefaultWorkingDir()];
100403
100733
  if (name24) {
100404
100734
  argv.push("-n", name24);
100405
100735
  }
@@ -100423,6 +100753,96 @@ class SshExternalTmuxConnection {
100423
100753
  this.callbacks.onError(error51);
100424
100754
  });
100425
100755
  }
100756
+ splitPane(paneId, direction, cwd) {
100757
+ if (!this.connected) {
100758
+ return;
100759
+ }
100760
+ this.splitPaneInternal(paneId, direction, cwd).catch((error51) => {
100761
+ this.callbacks.onError(error51);
100762
+ });
100763
+ }
100764
+ resizePaneById(paneId, size) {
100765
+ if (!this.connected) {
100766
+ return;
100767
+ }
100768
+ this.resizePaneByIdInternal(paneId, size).catch((error51) => {
100769
+ this.callbacks.onError(error51);
100770
+ });
100771
+ }
100772
+ resizeWindow(windowId, cols, rows) {
100773
+ if (!this.connected) {
100774
+ return;
100775
+ }
100776
+ this.resizeWindowInternal(windowId, cols, rows).catch((error51) => {
100777
+ this.callbacks.onError(error51);
100778
+ });
100779
+ }
100780
+ selectLayout(windowId, preset) {
100781
+ if (!this.connected) {
100782
+ return;
100783
+ }
100784
+ this.runAndRefresh(["select-layout", "-t", windowId, preset], true).catch((error51) => {
100785
+ this.callbacks.onError(error51);
100786
+ });
100787
+ }
100788
+ focusPane(windowId, paneId) {
100789
+ if (!this.connected) {
100790
+ return;
100791
+ }
100792
+ this.focusPaneInternal(windowId, paneId).catch((error51) => {
100793
+ this.callbacks.onError(error51);
100794
+ });
100795
+ }
100796
+ movePane(srcPaneId, dstPaneId, position) {
100797
+ if (!this.connected) {
100798
+ return;
100799
+ }
100800
+ const argv = ["move-pane"];
100801
+ argv.push(position === "left" || position === "right" ? "-h" : "-v");
100802
+ if (position === "left" || position === "top") {
100803
+ argv.push("-b");
100804
+ }
100805
+ argv.push("-s", srcPaneId, "-t", dstPaneId);
100806
+ this.runAndRefresh(argv, true).catch((error51) => {
100807
+ this.callbacks.onError(error51);
100808
+ });
100809
+ }
100810
+ breakPane(paneId) {
100811
+ if (!this.connected) {
100812
+ return;
100813
+ }
100814
+ this.breakPaneInternal(paneId).catch((error51) => {
100815
+ this.callbacks.onError(error51);
100816
+ });
100817
+ }
100818
+ async breakPaneInternal(paneId) {
100819
+ const result = await this.runTmux([
100820
+ "break-pane",
100821
+ "-s",
100822
+ paneId,
100823
+ "-t",
100824
+ `${this.sessionName}:`,
100825
+ "-P",
100826
+ "-F",
100827
+ `#{window_id}${SNAPSHOT_FIELD_SEPARATOR}#{pane_id}`
100828
+ ], true);
100829
+ const [windowId, newPaneId] = result.stdout.trim().split(SNAPSHOT_FIELD_SEPARATOR);
100830
+ if (isTmuxWindowId(windowId) && isTmuxPaneId(newPaneId)) {
100831
+ this.activeWindowId = windowId;
100832
+ this.activePaneId = newPaneId;
100833
+ this.callbacks.onEvent({
100834
+ type: "pane-active",
100835
+ data: { windowId, paneId: newPaneId }
100836
+ });
100837
+ }
100838
+ await this.requestSnapshotInternal();
100839
+ }
100840
+ async requestPaneHistory(paneId) {
100841
+ if (!this.connected) {
100842
+ return;
100843
+ }
100844
+ await this.capturePaneHistory(paneId);
100845
+ }
100426
100846
  renameWindow(windowId, name24) {
100427
100847
  if (!this.connected) {
100428
100848
  return;
@@ -100933,15 +101353,66 @@ class SshExternalTmuxConnection {
100933
101353
  await this.runAndRefresh(["kill-window", "-t", windowId], true);
100934
101354
  }
100935
101355
  async resizePaneInternal(paneId, cols, rows) {
100936
- const safeCols = Math.max(2, Math.floor(cols));
100937
- const safeRows = Math.max(2, Math.floor(rows));
100938
101356
  const windowId = this.findPaneWindowId(paneId) ?? (await this.runTmux(["display-message", "-p", "-t", paneId, "#{window_id}"], true)).stdout.trim();
100939
101357
  if (!windowId) {
100940
101358
  return;
100941
101359
  }
101360
+ await this.resizeWindowInternal(windowId, cols, rows);
101361
+ }
101362
+ async resizeWindowInternal(windowId, cols, rows) {
101363
+ const safeCols = Math.max(2, Math.floor(cols));
101364
+ const safeRows = Math.max(2, Math.floor(rows));
100942
101365
  await this.runTmux(["resize-window", "-t", windowId, "-x", String(safeCols), "-y", String(safeRows)], true);
100943
101366
  await this.requestSnapshotInternal();
100944
101367
  }
101368
+ async resizePaneByIdInternal(paneId, size) {
101369
+ const argv = ["resize-pane", "-t", paneId];
101370
+ if (size.cols !== undefined) {
101371
+ argv.push("-x", String(Math.max(2, Math.floor(size.cols))));
101372
+ }
101373
+ if (size.rows !== undefined) {
101374
+ argv.push("-y", String(Math.max(2, Math.floor(size.rows))));
101375
+ }
101376
+ if (argv.length === 3) {
101377
+ return;
101378
+ }
101379
+ await this.runTmux(argv, true);
101380
+ await this.requestSnapshotInternal();
101381
+ }
101382
+ async splitPaneInternal(paneId, direction, cwd) {
101383
+ const result = await this.runTmux([
101384
+ "split-window",
101385
+ direction === "h" ? "-h" : "-v",
101386
+ "-t",
101387
+ paneId,
101388
+ "-c",
101389
+ cwd ?? this.resolveDefaultWorkingDir(),
101390
+ "-P",
101391
+ "-F",
101392
+ `#{window_id}${SNAPSHOT_FIELD_SEPARATOR}#{pane_id}`
101393
+ ], true);
101394
+ const [windowId, newPaneId] = result.stdout.trim().split(SNAPSHOT_FIELD_SEPARATOR);
101395
+ if (isTmuxWindowId(windowId) && isTmuxPaneId(newPaneId)) {
101396
+ this.activeWindowId = windowId;
101397
+ this.activePaneId = newPaneId;
101398
+ this.callbacks.onEvent({
101399
+ type: "pane-active",
101400
+ data: { windowId, paneId: newPaneId }
101401
+ });
101402
+ }
101403
+ await this.requestSnapshotInternal();
101404
+ }
101405
+ async focusPaneInternal(windowId, paneId) {
101406
+ this.activeWindowId = windowId;
101407
+ this.activePaneId = paneId;
101408
+ await this.runTmux(["select-window", "-t", windowId], true);
101409
+ await this.runTmux(["select-pane", "-t", paneId], true);
101410
+ this.callbacks.onEvent({
101411
+ type: "pane-active",
101412
+ data: { windowId, paneId }
101413
+ });
101414
+ await this.requestSnapshotInternal();
101415
+ }
100945
101416
  async selectPaneInternal(windowId, paneId, size) {
100946
101417
  this.activeWindowId = windowId;
100947
101418
  this.activePaneId = paneId;
@@ -100984,16 +101455,9 @@ class SshExternalTmuxConnection {
100984
101455
  "-t",
100985
101456
  this.sessionName,
100986
101457
  "-F",
100987
- "#{window_id}|#{window_index}|#{window_name}|#{window_active}"
101458
+ WINDOW_SNAPSHOT_FORMAT
100988
101459
  ]),
100989
- this.runTmuxAllowFailure([
100990
- "list-panes",
100991
- "-s",
100992
- "-t",
100993
- this.sessionName,
100994
- "-F",
100995
- "#{pane_id}|#{window_id}|#{pane_index}|#{pane_title}|#{pane_active}|#{pane_width}|#{pane_height}|#{window_active}|#{pane_current_command}"
100996
- ])
101460
+ this.runTmuxAllowFailure(["list-panes", "-s", "-t", this.sessionName, "-F", PANE_SNAPSHOT_FORMAT])
100997
101461
  ]);
100998
101462
  if (sessionRes.exitCode !== 0 || windowsRes.exitCode !== 0 || panesRes.exitCode !== 0) {
100999
101463
  const stderrBlob = `${sessionRes.stderr}
@@ -101041,21 +101505,20 @@ ${panesRes.stderr}`;
101041
101505
  if (!line.trim()) {
101042
101506
  continue;
101043
101507
  }
101044
- const [id, indexRaw, name24, activeRaw] = splitSnapshotFields(line, 4);
101045
- const index = parseSnapshotInteger(indexRaw);
101046
- if (!isTmuxWindowId(id) || index === null || !this.isSnapshotFlag(activeRaw)) {
101508
+ const row = parseWindowSnapshotRow(line);
101509
+ if (!row) {
101047
101510
  console.warn(`[ssh] ignoring invalid tmux window snapshot row on ${this.deviceId}: ${formatSnapshotRowForLog(line)}`);
101048
101511
  continue;
101049
101512
  }
101050
- const active = activeRaw === "1";
101051
- if (active) {
101052
- this.activeWindowId = id;
101513
+ if (row.active) {
101514
+ this.activeWindowId = row.id;
101053
101515
  }
101054
- this.snapshotWindows.set(id, {
101055
- id,
101056
- index,
101057
- name: name24 ?? "",
101058
- active,
101516
+ this.snapshotWindows.set(row.id, {
101517
+ id: row.id,
101518
+ index: row.index,
101519
+ name: row.name,
101520
+ active: row.active,
101521
+ layout: row.layout,
101059
101522
  panes: []
101060
101523
  });
101061
101524
  }
@@ -101068,34 +101531,34 @@ ${panesRes.stderr}`;
101068
101531
  if (!line.trim()) {
101069
101532
  continue;
101070
101533
  }
101071
- const [paneId, windowId, indexRaw, titleRaw, activeRaw, widthRaw, heightRaw, windowActiveRaw, currentCommandRaw] = splitSnapshotFields(line, 9);
101072
- const index = parseSnapshotInteger(indexRaw);
101073
- const width = parseSnapshotInteger(widthRaw);
101074
- const height = parseSnapshotInteger(heightRaw);
101075
- if (!isTmuxPaneId(paneId) || !isTmuxWindowId(windowId) || index === null || width === null || height === null || !this.isSnapshotFlag(activeRaw) || !this.isSnapshotFlag(windowActiveRaw)) {
101534
+ const row = parsePaneSnapshotRow(line);
101535
+ if (!row) {
101076
101536
  console.warn(`[ssh] ignoring invalid tmux pane snapshot row on ${this.deviceId}: ${formatSnapshotRowForLog(line)}`);
101077
101537
  continue;
101078
101538
  }
101079
101539
  const pane = {
101080
- id: paneId,
101081
- windowId,
101082
- index,
101083
- title: this.pendingPaneTitles.get(paneId) ?? (titleRaw?.trim() ? titleRaw : undefined),
101084
- currentCommand: currentCommandRaw?.trim() ? currentCommandRaw.trim() : undefined,
101085
- active: activeRaw === "1",
101086
- width,
101087
- height
101540
+ id: row.id,
101541
+ windowId: row.windowId,
101542
+ index: row.index,
101543
+ title: this.pendingPaneTitles.get(row.id) ?? row.title,
101544
+ currentCommand: row.currentCommand,
101545
+ currentPath: row.currentPath,
101546
+ active: row.active,
101547
+ width: row.width,
101548
+ height: row.height,
101549
+ left: row.left,
101550
+ top: row.top
101088
101551
  };
101089
- if (pane.active && windowActiveRaw === "1") {
101090
- this.activePaneId = paneId;
101091
- this.activeWindowId = windowId;
101552
+ if (pane.active && row.windowActive) {
101553
+ this.activePaneId = row.id;
101554
+ this.activeWindowId = row.windowId;
101092
101555
  }
101093
- const window2 = this.snapshotWindows.get(windowId);
101556
+ const window2 = this.snapshotWindows.get(row.windowId);
101094
101557
  if (!window2) {
101095
101558
  continue;
101096
101559
  }
101097
101560
  window2.panes.push(pane);
101098
- this.pendingPaneTitles.delete(paneId);
101561
+ this.pendingPaneTitles.delete(row.id);
101099
101562
  }
101100
101563
  for (const window2 of this.snapshotWindows.values()) {
101101
101564
  window2.panes.sort((left, right) => left.index - right.index);
@@ -101481,8 +101944,8 @@ class DeviceSessionRuntime {
101481
101944
  updateDefaultWorkingDir(dir2) {
101482
101945
  this.connection.updateDefaultWorkingDir(dir2);
101483
101946
  }
101484
- createWindow(name24) {
101485
- this.connection.createWindow(name24);
101947
+ createWindow(name24, cwd) {
101948
+ this.connection.createWindow(name24, cwd);
101486
101949
  }
101487
101950
  closeWindow(windowId) {
101488
101951
  this.connection.closeWindow(windowId);
@@ -101490,6 +101953,30 @@ class DeviceSessionRuntime {
101490
101953
  closePane(paneId) {
101491
101954
  this.connection.closePane(paneId);
101492
101955
  }
101956
+ splitPane(paneId, direction, cwd) {
101957
+ this.connection.splitPane(paneId, direction, cwd);
101958
+ }
101959
+ resizePaneById(paneId, size) {
101960
+ this.connection.resizePaneById(paneId, size);
101961
+ }
101962
+ resizeWindow(windowId, cols, rows) {
101963
+ this.connection.resizeWindow(windowId, cols, rows);
101964
+ }
101965
+ selectLayout(windowId, preset) {
101966
+ this.connection.selectLayout(windowId, preset);
101967
+ }
101968
+ focusPane(windowId, paneId) {
101969
+ this.connection.focusPane(windowId, paneId);
101970
+ }
101971
+ movePane(srcPaneId, dstPaneId, position) {
101972
+ this.connection.movePane(srcPaneId, dstPaneId, position);
101973
+ }
101974
+ breakPane(paneId) {
101975
+ this.connection.breakPane(paneId);
101976
+ }
101977
+ async requestPaneHistory(paneId) {
101978
+ return this.connection.requestPaneHistory(paneId);
101979
+ }
101493
101980
  renameWindow(windowId, name24) {
101494
101981
  this.connection.renameWindow(windowId, name24);
101495
101982
  }
@@ -101612,6 +102099,67 @@ var tmuxRuntimeRegistry = createTmuxRuntimeRegistry({
101612
102099
  }
101613
102100
  });
101614
102101
 
102102
+ // ../../apps/gateway/src/tmux/bell-context.ts
102103
+ function pickPaneById(windows, paneId) {
102104
+ for (const window2 of windows) {
102105
+ const pane = window2.panes.find((item) => item.id === paneId);
102106
+ if (pane) {
102107
+ return { window: window2, pane };
102108
+ }
102109
+ }
102110
+ return null;
102111
+ }
102112
+ function resolvePaneContext(options) {
102113
+ const { deviceId, snapshot, rawData } = options;
102114
+ const raw = rawData ?? {};
102115
+ const bellWindowId = typeof raw.windowId === "string" && raw.windowId ? raw.windowId : undefined;
102116
+ const bellPaneId = typeof raw.paneId === "string" && raw.paneId ? raw.paneId : undefined;
102117
+ if (!snapshot?.session) {
102118
+ return {
102119
+ windowId: bellWindowId,
102120
+ paneId: bellPaneId
102121
+ };
102122
+ }
102123
+ let targetWindow;
102124
+ let targetPane;
102125
+ if (bellPaneId) {
102126
+ const matched = pickPaneById(snapshot.session.windows, bellPaneId);
102127
+ if (matched) {
102128
+ targetWindow = matched.window;
102129
+ targetPane = matched.pane;
102130
+ }
102131
+ }
102132
+ if (!targetWindow && bellWindowId) {
102133
+ targetWindow = snapshot.session.windows.find((window2) => window2.id === bellWindowId);
102134
+ }
102135
+ if (!targetWindow) {
102136
+ targetWindow = snapshot.session.windows.find((window2) => window2.active) ?? snapshot.session.windows[0];
102137
+ }
102138
+ if (!targetPane && targetWindow) {
102139
+ targetPane = (bellPaneId ? targetWindow.panes.find((pane) => pane.id === bellPaneId) : undefined) ?? targetWindow.panes.find((pane) => pane.active) ?? targetWindow.panes[0];
102140
+ }
102141
+ const siteUrl = options.siteUrl.endsWith("/") ? options.siteUrl.slice(0, -1) : options.siteUrl;
102142
+ const paneUrl = targetWindow && targetPane ? `${siteUrl}/devices/${encodeURIComponent(deviceId)}/windows/${encodeURIComponent(targetWindow.id)}/panes/${encodeURIComponent(targetPane.id)}` : undefined;
102143
+ return {
102144
+ windowId: targetWindow?.id ?? bellWindowId,
102145
+ paneId: targetPane?.id ?? bellPaneId,
102146
+ windowIndex: targetWindow?.index,
102147
+ paneIndex: targetPane?.index,
102148
+ paneUrl,
102149
+ paneTitle: targetPane?.title,
102150
+ paneCurrentCommand: targetPane?.currentCommand
102151
+ };
102152
+ }
102153
+
102154
+ // ../../apps/gateway/src/tmux/snapshot-directory.ts
102155
+ var lookup = null;
102156
+ function registerSnapshotLookup(fn) {
102157
+ lookup = fn;
102158
+ }
102159
+ function getDeviceSnapshot(deviceId) {
102160
+ return lookup?.(deviceId) ?? null;
102161
+ }
102162
+
101615
102163
  // ../../apps/gateway/src/agent/secret-scan.ts
101616
102164
  var REDACTED = (type) => `[REDACTED:${type}]`;
101617
102165
  var RULES = [
@@ -103388,6 +103936,12 @@ class AgentRun {
103388
103936
  try {
103389
103937
  const settings = getSiteSettings();
103390
103938
  const device = session.deviceId ? getDeviceById(session.deviceId) : null;
103939
+ const paneContext = session.deviceId && session.paneId ? resolvePaneContext({
103940
+ deviceId: session.deviceId,
103941
+ siteUrl: settings.siteUrl,
103942
+ snapshot: getDeviceSnapshot(session.deviceId),
103943
+ rawData: { paneId: session.paneId }
103944
+ }) : null;
103391
103945
  await this.deps.notify(eventType, {
103392
103946
  site: {
103393
103947
  name: settings.siteName,
@@ -103401,6 +103955,7 @@ class AgentRun {
103401
103955
  },
103402
103956
  tmux: {
103403
103957
  sessionName: device?.session,
103958
+ ...paneContext ?? {},
103404
103959
  paneId: session.paneId ?? undefined
103405
103960
  },
103406
103961
  payload: {
@@ -103873,58 +104428,6 @@ class RuntimeController {
103873
104428
  }
103874
104429
  var runtimeController = new RuntimeController;
103875
104430
 
103876
- // ../../apps/gateway/src/tmux/bell-context.ts
103877
- function pickPaneById(windows, paneId) {
103878
- for (const window2 of windows) {
103879
- const pane = window2.panes.find((item) => item.id === paneId);
103880
- if (pane) {
103881
- return { window: window2, pane };
103882
- }
103883
- }
103884
- return null;
103885
- }
103886
- function resolvePaneContext(options) {
103887
- const { deviceId, snapshot, rawData } = options;
103888
- const raw = rawData ?? {};
103889
- const bellWindowId = typeof raw.windowId === "string" && raw.windowId ? raw.windowId : undefined;
103890
- const bellPaneId = typeof raw.paneId === "string" && raw.paneId ? raw.paneId : undefined;
103891
- if (!snapshot?.session) {
103892
- return {
103893
- windowId: bellWindowId,
103894
- paneId: bellPaneId
103895
- };
103896
- }
103897
- let targetWindow;
103898
- let targetPane;
103899
- if (bellPaneId) {
103900
- const matched = pickPaneById(snapshot.session.windows, bellPaneId);
103901
- if (matched) {
103902
- targetWindow = matched.window;
103903
- targetPane = matched.pane;
103904
- }
103905
- }
103906
- if (!targetWindow && bellWindowId) {
103907
- targetWindow = snapshot.session.windows.find((window2) => window2.id === bellWindowId);
103908
- }
103909
- if (!targetWindow) {
103910
- targetWindow = snapshot.session.windows.find((window2) => window2.active) ?? snapshot.session.windows[0];
103911
- }
103912
- if (!targetPane && targetWindow) {
103913
- targetPane = (bellPaneId ? targetWindow.panes.find((pane) => pane.id === bellPaneId) : undefined) ?? targetWindow.panes.find((pane) => pane.active) ?? targetWindow.panes[0];
103914
- }
103915
- const siteUrl = options.siteUrl.endsWith("/") ? options.siteUrl.slice(0, -1) : options.siteUrl;
103916
- const paneUrl = targetWindow && targetPane ? `${siteUrl}/devices/${encodeURIComponent(deviceId)}/windows/${encodeURIComponent(targetWindow.id)}/panes/${encodeURIComponent(targetPane.id)}` : undefined;
103917
- return {
103918
- windowId: targetWindow?.id ?? bellWindowId,
103919
- paneId: targetPane?.id ?? bellPaneId,
103920
- windowIndex: targetWindow?.index,
103921
- paneIndex: targetPane?.index,
103922
- paneUrl,
103923
- paneTitle: targetPane?.title,
103924
- paneCurrentCommand: targetPane?.currentCommand
103925
- };
103926
- }
103927
-
103928
104431
  // ../../apps/gateway/src/push/supervisor.ts
103929
104432
  var defaultDeps2 = {
103930
104433
  listDevices: () => getAllDevices(),
@@ -106745,8 +107248,8 @@ function getBaseVersion() {
106745
107248
  if (cachedBase !== undefined)
106746
107249
  return cachedBase;
106747
107250
  let base = null;
106748
- if ("0.15.1") {
106749
- base = "0.15.1";
107251
+ if ("0.16.0") {
107252
+ base = "0.16.0";
106750
107253
  }
106751
107254
  if (!base && config.isProd) {
106752
107255
  base = readInstallMeta()?.cliVersion ?? null;
@@ -109266,7 +109769,9 @@ function createBorshClientState() {
109266
109769
  negotiated: false,
109267
109770
  maxFrameBytes: exports_ws_borsh.DEFAULT_MAX_FRAME_BYTES,
109268
109771
  chunkReassembler: new exports_ws_borsh.ChunkReassembler,
109269
- selectedPanes: {}
109772
+ selectedPanes: {},
109773
+ subscribedPanes: {},
109774
+ pendingHistoryFetches: new Map
109270
109775
  };
109271
109776
  }
109272
109777
  function encodeTermOutput(params, seq) {
@@ -109898,6 +110403,7 @@ class WebSocketServer {
109898
110403
  connections = new Map;
109899
110404
  pendingConnectionEntries = new Map;
109900
110405
  windowCustomNames = new Map;
110406
+ paneCustomNames = new Map;
109901
110407
  deps;
109902
110408
  constructor(options = {}) {
109903
110409
  this.deps = {
@@ -109961,7 +110467,7 @@ class WebSocketServer {
109961
110467
  const entry = this.connections.get(deviceId);
109962
110468
  if (!entry)
109963
110469
  return;
109964
- const hasSelectedPaneClient = Array.from(entry.clients).some((client) => Boolean(client.data.borshState.selectedPanes[deviceId]));
110470
+ const hasSelectedPaneClient = Array.from(entry.clients).some((client) => Boolean(client.data.borshState.selectedPanes[deviceId]) || Boolean(client.data.borshState.subscribedPanes[deviceId]?.size));
109965
110471
  if (!hasSelectedPaneClient) {
109966
110472
  this.clearSnapshotPollTimer(entry);
109967
110473
  return;
@@ -110060,6 +110566,8 @@ class WebSocketServer {
110060
110566
  continue;
110061
110567
  entry.clients.delete(ws);
110062
110568
  delete ws.data.borshState.selectedPanes[deviceId];
110569
+ delete ws.data.borshState.subscribedPanes[deviceId];
110570
+ this.clearPendingHistoryFetches(ws, deviceId);
110063
110571
  if (entry.clients.size === 0) {
110064
110572
  console.log(`[ws] no more clients for device ${deviceId}, disconnecting`);
110065
110573
  this.releaseConnectionEntry(deviceId, entry);
@@ -110076,6 +110584,9 @@ class WebSocketServer {
110076
110584
  const entry = this.connections.get(deviceId);
110077
110585
  entry?.runtime.updateDefaultWorkingDir(dir2);
110078
110586
  }
110587
+ getLastSnapshot(deviceId) {
110588
+ return this.connections.get(deviceId)?.lastSnapshot ?? null;
110589
+ }
110079
110590
  closeAll() {
110080
110591
  for (const [deviceId, entry] of this.connections) {
110081
110592
  this.releaseConnectionEntry(deviceId, entry);
@@ -110120,7 +110631,7 @@ class WebSocketServer {
110120
110631
  }
110121
110632
  case exports_ws_borsh.KIND_TMUX_CREATE_WINDOW: {
110122
110633
  const decoded = exports_ws_borsh.decodePayload(exports_ws_borsh.schema.TmuxCreateWindowSchema, payload);
110123
- this.handleCreateWindow(decoded.deviceId, decoded.name ?? undefined);
110634
+ this.handleCreateWindow(decoded.deviceId, decoded.name ?? undefined, decoded.cwd ?? undefined);
110124
110635
  return;
110125
110636
  }
110126
110637
  case exports_ws_borsh.KIND_TMUX_CLOSE_WINDOW: {
@@ -110153,6 +110664,51 @@ class WebSocketServer {
110153
110664
  this.handleReorderPanes(decoded.deviceId, decoded.windowId, decoded.paneIds);
110154
110665
  return;
110155
110666
  }
110667
+ case exports_ws_borsh.KIND_TMUX_SUBSCRIBE_PANES: {
110668
+ const decoded = exports_ws_borsh.decodePayload(exports_ws_borsh.schema.TmuxSubscribePanesSchema, payload);
110669
+ this.handleSubscribePanes(ws, decoded.deviceId, decoded.paneIds);
110670
+ return;
110671
+ }
110672
+ case exports_ws_borsh.KIND_TMUX_FETCH_PANE_HISTORY: {
110673
+ const decoded = exports_ws_borsh.decodePayload(exports_ws_borsh.schema.TmuxFetchPaneHistorySchema, payload);
110674
+ this.handleFetchPaneHistory(ws, decoded.deviceId, decoded.paneId, decoded.requestToken);
110675
+ return;
110676
+ }
110677
+ case exports_ws_borsh.KIND_TMUX_RESIZE_PANE: {
110678
+ const decoded = exports_ws_borsh.decodePayload(exports_ws_borsh.schema.TmuxResizePaneSchema, payload);
110679
+ this.handleResizePaneById(decoded.deviceId, decoded.paneId, decoded.cols ?? undefined, decoded.rows ?? undefined);
110680
+ return;
110681
+ }
110682
+ case exports_ws_borsh.KIND_TMUX_APPLY_STACKED_LAYOUT: {
110683
+ const decoded = exports_ws_borsh.decodePayload(exports_ws_borsh.schema.TmuxApplyStackedLayoutSchema, payload);
110684
+ this.handleApplyStackedLayout(decoded.deviceId, decoded.windowId, decoded.cols, decoded.rows);
110685
+ return;
110686
+ }
110687
+ case exports_ws_borsh.KIND_TMUX_SPLIT_PANE: {
110688
+ const decoded = exports_ws_borsh.decodePayload(exports_ws_borsh.schema.TmuxSplitPaneSchema, payload);
110689
+ this.handleSplitPane(decoded.deviceId, decoded.paneId, decoded.direction, decoded.cwd ?? undefined);
110690
+ return;
110691
+ }
110692
+ case exports_ws_borsh.KIND_TMUX_FOCUS_PANE: {
110693
+ const decoded = exports_ws_borsh.decodePayload(exports_ws_borsh.schema.TmuxFocusPaneSchema, payload);
110694
+ this.handleFocusPane(ws, decoded.deviceId, decoded.windowId, decoded.paneId);
110695
+ return;
110696
+ }
110697
+ case exports_ws_borsh.KIND_TMUX_RENAME_PANE: {
110698
+ const decoded = exports_ws_borsh.decodePayload(exports_ws_borsh.schema.TmuxRenamePaneSchema, payload);
110699
+ this.handleRenamePane(decoded.deviceId, decoded.paneId, decoded.name);
110700
+ return;
110701
+ }
110702
+ case exports_ws_borsh.KIND_TMUX_MOVE_PANE: {
110703
+ const decoded = exports_ws_borsh.decodePayload(exports_ws_borsh.schema.TmuxMovePaneSchema, payload);
110704
+ this.handleMovePane(decoded.deviceId, decoded.srcPaneId, decoded.dstPaneId, decoded.position);
110705
+ return;
110706
+ }
110707
+ case exports_ws_borsh.KIND_TMUX_BREAK_PANE: {
110708
+ const decoded = exports_ws_borsh.decodePayload(exports_ws_borsh.schema.TmuxBreakPaneSchema, payload);
110709
+ this.handleBreakPane(decoded.deviceId, decoded.paneId);
110710
+ return;
110711
+ }
110156
110712
  case exports_ws_borsh.KIND_TERM_INPUT: {
110157
110713
  const decoded = exports_ws_borsh.decodePayload(exports_ws_borsh.schema.TermInputSchema, payload);
110158
110714
  if (decoded.isComposing)
@@ -110211,7 +110767,7 @@ class WebSocketServer {
110211
110767
  selectedVersion: exports_ws_borsh.CURRENT_VERSION,
110212
110768
  maxFrameBytes: serverMaxFrameBytes,
110213
110769
  heartbeatIntervalMs: 15000,
110214
- capabilities: ["tmex-ws-borsh-v1", "tmex-agent-v1"]
110770
+ capabilities: ["tmex-ws-borsh-v1", "tmex-agent-v1", "tmex-split-v1"]
110215
110771
  };
110216
110772
  const payloadBytes = exports_ws_borsh.encodePayload(exports_ws_borsh.schema.HelloS2CSchema, helloS2C);
110217
110773
  this.sendEnvelope(ws, exports_ws_borsh.KIND_HELLO_S2C, payloadBytes);
@@ -110308,11 +110864,21 @@ class WebSocketServer {
110308
110864
  }
110309
110865
  }
110310
110866
  delete ws.data.borshState.selectedPanes[deviceId];
110867
+ delete ws.data.borshState.subscribedPanes[deviceId];
110868
+ this.clearPendingHistoryFetches(ws, deviceId);
110311
110869
  const disconnectedPayload = exports_ws_borsh.encodePayload(exports_ws_borsh.schema.DeviceDisconnectedSchema, {
110312
110870
  deviceId
110313
110871
  });
110314
110872
  this.sendEnvelope(ws, exports_ws_borsh.KIND_DEVICE_DISCONNECTED, disconnectedPayload);
110315
110873
  }
110874
+ clearPendingHistoryFetches(ws, deviceId) {
110875
+ const prefix = `${deviceId}:`;
110876
+ for (const key of ws.data.borshState.pendingHistoryFetches.keys()) {
110877
+ if (key.startsWith(prefix)) {
110878
+ ws.data.borshState.pendingHistoryFetches.delete(key);
110879
+ }
110880
+ }
110881
+ }
110316
110882
  handleTmuxSelect(ws, data) {
110317
110883
  const deviceId = data.deviceId;
110318
110884
  const entry = this.connections.get(deviceId);
@@ -110409,11 +110975,11 @@ class WebSocketServer {
110409
110975
  entry.runtime.sendInput(paneId, chunk2);
110410
110976
  }
110411
110977
  }
110412
- handleCreateWindow(deviceId, name24) {
110978
+ handleCreateWindow(deviceId, name24, cwd) {
110413
110979
  const entry = this.connections.get(deviceId);
110414
110980
  if (!entry)
110415
110981
  return;
110416
- entry.runtime.createWindow(name24);
110982
+ entry.runtime.createWindow(name24, cwd);
110417
110983
  }
110418
110984
  handleCloseWindow(deviceId, windowId) {
110419
110985
  const entry = this.connections.get(deviceId);
@@ -110427,6 +110993,46 @@ class WebSocketServer {
110427
110993
  return;
110428
110994
  entry.runtime.closePane(paneId);
110429
110995
  }
110996
+ handleRenamePane(deviceId, paneId, name24) {
110997
+ if (!isTmuxPaneId(paneId))
110998
+ return;
110999
+ const trimmed = name24.trim().slice(0, 64);
111000
+ const names = this.paneCustomNames.get(deviceId);
111001
+ if (!trimmed) {
111002
+ names?.delete(paneId);
111003
+ } else if (names) {
111004
+ names.set(paneId, trimmed);
111005
+ } else {
111006
+ this.paneCustomNames.set(deviceId, new Map([[paneId, trimmed]]));
111007
+ }
111008
+ const entry = this.connections.get(deviceId);
111009
+ if (!entry?.lastSnapshot)
111010
+ return;
111011
+ this.sendSnapshotToClients(entry, entry.lastSnapshot);
111012
+ }
111013
+ handleBreakPane(deviceId, paneId) {
111014
+ const entry = this.connections.get(deviceId);
111015
+ if (!entry || !isTmuxPaneId(paneId))
111016
+ return;
111017
+ entry.runtime.breakPane(paneId);
111018
+ }
111019
+ handleMovePane(deviceId, srcPaneId, dstPaneId, position) {
111020
+ const entry = this.connections.get(deviceId);
111021
+ if (!entry || !isTmuxPaneId(srcPaneId) || !isTmuxPaneId(dstPaneId))
111022
+ return;
111023
+ if (srcPaneId === dstPaneId)
111024
+ return;
111025
+ const positionMap = {
111026
+ 1: "left",
111027
+ 2: "right",
111028
+ 3: "top",
111029
+ 4: "bottom"
111030
+ };
111031
+ const resolved = positionMap[position];
111032
+ if (!resolved)
111033
+ return;
111034
+ entry.runtime.movePane(srcPaneId, dstPaneId, resolved);
111035
+ }
110430
111036
  handleRenameWindow(deviceId, windowId, name24) {
110431
111037
  const trimmed = name24.trim().slice(0, 64);
110432
111038
  const names = this.windowCustomNames.get(deviceId);
@@ -110462,14 +111068,100 @@ class WebSocketServer {
110462
111068
  return;
110463
111069
  this.sendSnapshotToClients(entry, entry.lastSnapshot);
110464
111070
  }
111071
+ handleSubscribePanes(ws, deviceId, paneIds) {
111072
+ const entry = this.connections.get(deviceId);
111073
+ if (!entry)
111074
+ return;
111075
+ const knownPaneIds = new Set(entry.lastSnapshot?.session?.windows.flatMap((window2) => window2.panes.map((pane) => pane.id)) ?? []);
111076
+ const accepted = new Set;
111077
+ for (const paneId of paneIds) {
111078
+ if (isTmuxPaneId(paneId) && knownPaneIds.has(paneId)) {
111079
+ accepted.add(paneId);
111080
+ }
111081
+ }
111082
+ if (accepted.size > 0) {
111083
+ ws.data.borshState.subscribedPanes[deviceId] = accepted;
111084
+ } else {
111085
+ delete ws.data.borshState.subscribedPanes[deviceId];
111086
+ }
111087
+ this.refreshSnapshotPolling(deviceId);
111088
+ }
111089
+ handleFetchPaneHistory(ws, deviceId, paneId, requestToken) {
111090
+ const entry = this.connections.get(deviceId);
111091
+ if (!entry || !isTmuxPaneId(paneId))
111092
+ return;
111093
+ ws.data.borshState.pendingHistoryFetches.set(`${deviceId}:${paneId}`, requestToken);
111094
+ entry.runtime.requestPaneHistory(paneId).catch((error51) => {
111095
+ console.warn(`[ws] fetch pane history failed on ${deviceId}/${paneId}:`, error51);
111096
+ ws.data.borshState.pendingHistoryFetches.delete(`${deviceId}:${paneId}`);
111097
+ });
111098
+ }
111099
+ handleResizePaneById(deviceId, paneId, cols, rows) {
111100
+ const entry = this.connections.get(deviceId);
111101
+ if (!entry || !isTmuxPaneId(paneId))
111102
+ return;
111103
+ if (cols === undefined && rows === undefined)
111104
+ return;
111105
+ entry.runtime.resizePaneById(paneId, { cols, rows });
111106
+ }
111107
+ handleApplyStackedLayout(deviceId, windowId, cols, rows) {
111108
+ const entry = this.connections.get(deviceId);
111109
+ if (!entry)
111110
+ return;
111111
+ if (!this.canSelectWindow(entry, deviceId, windowId))
111112
+ return;
111113
+ if (cols < 2 || rows < 2)
111114
+ return;
111115
+ const window2 = entry.lastSnapshot?.session?.windows.find((candidate) => candidate.id === windowId);
111116
+ const paneCount = window2?.panes.length ?? 0;
111117
+ if (!window2 || paneCount === 0)
111118
+ return;
111119
+ const alreadyStacked = window2.panes.every((pane) => pane.width === cols && pane.height === rows);
111120
+ if (alreadyStacked)
111121
+ return;
111122
+ const TMUX_MAX_WINDOW_COLS = 1e4;
111123
+ const totalCols = paneCount * cols + (paneCount - 1);
111124
+ const clampedCols = Math.min(totalCols, TMUX_MAX_WINDOW_COLS);
111125
+ if (clampedCols !== totalCols) {
111126
+ console.warn(`[ws] stacked layout width clamped on ${deviceId}/${windowId}: ${totalCols} -> ${clampedCols}`);
111127
+ }
111128
+ entry.runtime.resizeWindow(windowId, clampedCols, rows);
111129
+ if (paneCount > 1) {
111130
+ entry.runtime.selectLayout(windowId, "even-horizontal");
111131
+ }
111132
+ }
111133
+ handleSplitPane(deviceId, paneId, direction, cwd) {
111134
+ const entry = this.connections.get(deviceId);
111135
+ if (!entry || !isTmuxPaneId(paneId))
111136
+ return;
111137
+ const dir2 = direction === 2 ? "v" : "h";
111138
+ entry.runtime.splitPane(paneId, dir2, cwd);
111139
+ }
111140
+ handleFocusPane(ws, deviceId, windowId, paneId) {
111141
+ const entry = this.connections.get(deviceId);
111142
+ if (!entry)
111143
+ return;
111144
+ if (!this.canSelectPane(entry, deviceId, windowId, paneId))
111145
+ return;
111146
+ ws.data.borshState.selectedPanes[deviceId] = paneId;
111147
+ this.refreshSnapshotPolling(deviceId);
111148
+ entry.runtime.focusPane(windowId, paneId);
111149
+ }
110465
111150
  applyWindowCustomNames(payload) {
110466
111151
  const names = this.windowCustomNames.get(payload.deviceId);
110467
- if (!names?.size || !payload.session)
111152
+ const paneNames = this.paneCustomNames.get(payload.deviceId);
111153
+ if (!names?.size && !paneNames?.size || !payload.session)
110468
111154
  return payload;
110469
111155
  const liveWindowIds = new Set(payload.session.windows.map((w) => w.id));
110470
- for (const windowId of names.keys()) {
111156
+ for (const windowId of names?.keys() ?? []) {
110471
111157
  if (!liveWindowIds.has(windowId)) {
110472
- names.delete(windowId);
111158
+ names?.delete(windowId);
111159
+ }
111160
+ }
111161
+ const livePaneIds = new Set(payload.session.windows.flatMap((w) => w.panes.map((pane) => pane.id)));
111162
+ for (const paneId of paneNames?.keys() ?? []) {
111163
+ if (!livePaneIds.has(paneId)) {
111164
+ paneNames?.delete(paneId);
110473
111165
  }
110474
111166
  }
110475
111167
  return {
@@ -110477,8 +111169,12 @@ class WebSocketServer {
110477
111169
  session: {
110478
111170
  ...payload.session,
110479
111171
  windows: payload.session.windows.map((window2) => {
110480
- const customName = names.get(window2.id);
110481
- return customName ? { ...window2, customName } : window2;
111172
+ const customName = names?.get(window2.id);
111173
+ const panes = paneNames?.size ? window2.panes.map((pane) => {
111174
+ const paneCustomName = paneNames.get(pane.id);
111175
+ return paneCustomName ? { ...pane, customName: paneCustomName } : pane;
111176
+ }) : window2.panes;
111177
+ return customName || panes !== window2.panes ? { ...window2, ...customName ? { customName } : {}, panes } : window2;
110482
111178
  })
110483
111179
  }
110484
111180
  };
@@ -110617,10 +111313,12 @@ class WebSocketServer {
110617
111313
  if (!entry)
110618
111314
  return;
110619
111315
  for (const client of entry.clients) {
110620
- if (client.data.borshState.selectedPanes[deviceId] !== paneId) {
111316
+ const isFocused = client.data.borshState.selectedPanes[deviceId] === paneId;
111317
+ const isSubscribed = client.data.borshState.subscribedPanes[deviceId]?.has(paneId) ?? false;
111318
+ if (!isFocused && !isSubscribed) {
110621
111319
  continue;
110622
111320
  }
110623
- if (switchBarrier.shouldBufferOutput(client, deviceId)) {
111321
+ if (isFocused && switchBarrier.shouldBufferOutput(client, deviceId)) {
110624
111322
  switchBarrier.bufferOutput(client, deviceId, data);
110625
111323
  continue;
110626
111324
  }
@@ -110654,11 +111352,26 @@ class WebSocketServer {
110654
111352
  if (!entry)
110655
111353
  return;
110656
111354
  const historyBytes = new TextEncoder().encode(data);
111355
+ const fetchKey = `${deviceId}:${paneId}`;
110657
111356
  for (const client of entry.clients) {
110658
- if (client.data.borshState.selectedPanes[deviceId] !== paneId) {
111357
+ if (client.data.borshState.selectedPanes[deviceId] === paneId) {
111358
+ switchBarrier.sendTermHistory(client, deviceId, paneId, historyBytes, alternateScreen);
110659
111359
  continue;
110660
111360
  }
110661
- switchBarrier.sendTermHistory(client, deviceId, paneId, historyBytes, alternateScreen);
111361
+ const requestToken = client.data.borshState.pendingHistoryFetches.get(fetchKey);
111362
+ if (!requestToken) {
111363
+ continue;
111364
+ }
111365
+ client.data.borshState.pendingHistoryFetches.delete(fetchKey);
111366
+ const payloadBytes = exports_ws_borsh.encodePayload(exports_ws_borsh.schema.TermHistorySchema, {
111367
+ deviceId,
111368
+ paneId,
111369
+ selectToken: requestToken,
111370
+ encoding: 1,
111371
+ alternateScreen,
111372
+ data: historyBytes
111373
+ });
111374
+ this.sendChunked(client, exports_ws_borsh.KIND_TERM_HISTORY, payloadBytes);
110662
111375
  }
110663
111376
  }
110664
111377
  broadcastError(deviceId, err) {
@@ -110783,6 +111496,7 @@ async function createGatewayRuntime(options = {}) {
110783
111496
  connectionAlertNotifier.setBroadcaster((deviceId, payload) => {
110784
111497
  wsServer.broadcastDeviceError(deviceId, payload);
110785
111498
  });
111499
+ registerSnapshotLookup((deviceId) => wsServer.getLastSnapshot(deviceId));
110786
111500
  await telegramService.refresh();
110787
111501
  await weixinService.refresh();
110788
111502
  await pushSupervisor.start();