dmux 3.2.0 → 3.3.1

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 (655) hide show
  1. package/dist/DmuxApp.d.ts.map +1 -1
  2. package/dist/DmuxApp.js +270 -1606
  3. package/dist/DmuxApp.js.map +1 -1
  4. package/dist/actions/implementations/closeAction.d.ts +10 -0
  5. package/dist/actions/implementations/closeAction.d.ts.map +1 -0
  6. package/dist/actions/implementations/closeAction.js +201 -0
  7. package/dist/actions/implementations/closeAction.js.map +1 -0
  8. package/dist/actions/implementations/copyPathAction.d.ts +10 -0
  9. package/dist/actions/implementations/copyPathAction.d.ts.map +1 -0
  10. package/dist/actions/implementations/copyPathAction.js +34 -0
  11. package/dist/actions/implementations/copyPathAction.js.map +1 -0
  12. package/dist/actions/implementations/duplicateAction.d.ts +10 -0
  13. package/dist/actions/implementations/duplicateAction.d.ts.map +1 -0
  14. package/dist/actions/implementations/duplicateAction.js +25 -0
  15. package/dist/actions/implementations/duplicateAction.js.map +1 -0
  16. package/dist/actions/implementations/index.d.ts +14 -0
  17. package/dist/actions/implementations/index.d.ts.map +1 -0
  18. package/dist/actions/implementations/index.js +14 -0
  19. package/dist/actions/implementations/index.js.map +1 -0
  20. package/dist/actions/implementations/mergeAction.d.ts +14 -0
  21. package/dist/actions/implementations/mergeAction.d.ts.map +1 -0
  22. package/dist/actions/implementations/mergeAction.js +84 -0
  23. package/dist/actions/implementations/mergeAction.js.map +1 -0
  24. package/dist/actions/implementations/openInEditorAction.d.ts +12 -0
  25. package/dist/actions/implementations/openInEditorAction.d.ts.map +1 -0
  26. package/dist/actions/implementations/openInEditorAction.js +33 -0
  27. package/dist/actions/implementations/openInEditorAction.js.map +1 -0
  28. package/dist/actions/implementations/renameAction.d.ts +13 -0
  29. package/dist/actions/implementations/renameAction.d.ts.map +1 -0
  30. package/dist/actions/implementations/renameAction.js +18 -0
  31. package/dist/actions/implementations/renameAction.js.map +1 -0
  32. package/dist/actions/implementations/toggleAutopilotAction.d.ts +10 -0
  33. package/dist/actions/implementations/toggleAutopilotAction.d.ts.map +1 -0
  34. package/dist/actions/implementations/toggleAutopilotAction.js +33 -0
  35. package/dist/actions/implementations/toggleAutopilotAction.js.map +1 -0
  36. package/dist/actions/implementations/viewAction.d.ts +10 -0
  37. package/dist/actions/implementations/viewAction.d.ts.map +1 -0
  38. package/dist/actions/implementations/viewAction.js +26 -0
  39. package/dist/actions/implementations/viewAction.js.map +1 -0
  40. package/dist/actions/merge/commitMessageHandler.d.ts +27 -0
  41. package/dist/actions/merge/commitMessageHandler.d.ts.map +1 -0
  42. package/dist/actions/merge/commitMessageHandler.js +123 -0
  43. package/dist/actions/merge/commitMessageHandler.js.map +1 -0
  44. package/dist/actions/merge/conflictResolution.d.ts +13 -0
  45. package/dist/actions/merge/conflictResolution.d.ts.map +1 -0
  46. package/dist/actions/merge/conflictResolution.js +134 -0
  47. package/dist/actions/merge/conflictResolution.js.map +1 -0
  48. package/dist/actions/merge/issueHandlers/index.d.ts +11 -0
  49. package/dist/actions/merge/issueHandlers/index.d.ts.map +1 -0
  50. package/dist/actions/merge/issueHandlers/index.js +8 -0
  51. package/dist/actions/merge/issueHandlers/index.js.map +1 -0
  52. package/dist/actions/merge/issueHandlers/mainDirtyHandler.d.ts +13 -0
  53. package/dist/actions/merge/issueHandlers/mainDirtyHandler.d.ts.map +1 -0
  54. package/dist/actions/merge/issueHandlers/mainDirtyHandler.js +72 -0
  55. package/dist/actions/merge/issueHandlers/mainDirtyHandler.js.map +1 -0
  56. package/dist/actions/merge/issueHandlers/mergeConflictHandler.d.ts +13 -0
  57. package/dist/actions/merge/issueHandlers/mergeConflictHandler.d.ts.map +1 -0
  58. package/dist/actions/merge/issueHandlers/mergeConflictHandler.js +52 -0
  59. package/dist/actions/merge/issueHandlers/mergeConflictHandler.js.map +1 -0
  60. package/dist/actions/merge/issueHandlers/nothingToMergeHandler.d.ts +7 -0
  61. package/dist/actions/merge/issueHandlers/nothingToMergeHandler.d.ts.map +1 -0
  62. package/dist/actions/merge/issueHandlers/nothingToMergeHandler.js +12 -0
  63. package/dist/actions/merge/issueHandlers/nothingToMergeHandler.js.map +1 -0
  64. package/dist/actions/merge/issueHandlers/worktreeUncommittedHandler.d.ts +13 -0
  65. package/dist/actions/merge/issueHandlers/worktreeUncommittedHandler.d.ts.map +1 -0
  66. package/dist/actions/merge/issueHandlers/worktreeUncommittedHandler.js +49 -0
  67. package/dist/actions/merge/issueHandlers/worktreeUncommittedHandler.js.map +1 -0
  68. package/dist/actions/merge/mergeExecution.d.ts +22 -0
  69. package/dist/actions/merge/mergeExecution.d.ts.map +1 -0
  70. package/dist/actions/merge/mergeExecution.js +184 -0
  71. package/dist/actions/merge/mergeExecution.js.map +1 -0
  72. package/dist/actions/paneActions.d.ts +3 -40
  73. package/dist/actions/paneActions.d.ts.map +1 -1
  74. package/dist/actions/paneActions.js +4 -1038
  75. package/dist/actions/paneActions.js.map +1 -1
  76. package/dist/actions/types.d.ts +1 -0
  77. package/dist/actions/types.d.ts.map +1 -1
  78. package/dist/actions/types.js.map +1 -1
  79. package/dist/components/{ActionChoiceDialog.d.ts → dialogs/ActionChoiceDialog.d.ts} +1 -1
  80. package/dist/components/dialogs/ActionChoiceDialog.d.ts.map +1 -0
  81. package/dist/components/dialogs/ActionChoiceDialog.js.map +1 -0
  82. package/dist/components/dialogs/ActionConfirmDialog.d.ts.map +1 -0
  83. package/dist/components/dialogs/ActionConfirmDialog.js.map +1 -0
  84. package/dist/components/dialogs/ActionInputDialog.d.ts.map +1 -0
  85. package/dist/components/{ActionInputDialog.js → dialogs/ActionInputDialog.js} +2 -2
  86. package/dist/components/dialogs/ActionInputDialog.js.map +1 -0
  87. package/dist/components/dialogs/ActionProgressDialog.d.ts.map +1 -0
  88. package/dist/components/dialogs/ActionProgressDialog.js.map +1 -0
  89. package/dist/components/dialogs/AgentChoiceDialog.d.ts.map +1 -0
  90. package/dist/components/dialogs/AgentChoiceDialog.js.map +1 -0
  91. package/dist/components/{CloseOptionsDialog.d.ts → dialogs/CloseOptionsDialog.d.ts} +1 -1
  92. package/dist/components/dialogs/CloseOptionsDialog.d.ts.map +1 -0
  93. package/dist/components/dialogs/CloseOptionsDialog.js.map +1 -0
  94. package/dist/components/dialogs/CommandPromptDialog.d.ts.map +1 -0
  95. package/dist/components/{CommandPromptDialog.js → dialogs/CommandPromptDialog.js} +1 -1
  96. package/dist/components/dialogs/CommandPromptDialog.js.map +1 -0
  97. package/dist/components/dialogs/DialogBox.d.ts.map +1 -0
  98. package/dist/components/dialogs/DialogBox.js.map +1 -0
  99. package/dist/components/dialogs/HooksDialog.d.ts.map +1 -0
  100. package/dist/components/dialogs/HooksDialog.js.map +1 -0
  101. package/dist/components/{MergeConfirmationDialog.d.ts → dialogs/MergeConfirmationDialog.d.ts} +1 -1
  102. package/dist/components/dialogs/MergeConfirmationDialog.d.ts.map +1 -0
  103. package/dist/components/dialogs/MergeConfirmationDialog.js.map +1 -0
  104. package/dist/components/{SettingsDialog.d.ts → dialogs/SettingsDialog.d.ts} +1 -1
  105. package/dist/components/dialogs/SettingsDialog.d.ts.map +1 -0
  106. package/dist/components/dialogs/SettingsDialog.js.map +1 -0
  107. package/dist/components/dialogs/UpdateDialog.d.ts.map +1 -0
  108. package/dist/components/dialogs/UpdateDialog.js.map +1 -0
  109. package/dist/components/indicators/CreatingIndicator.d.ts.map +1 -0
  110. package/dist/components/indicators/CreatingIndicator.js.map +1 -0
  111. package/dist/components/indicators/LoadingIndicator.d.ts.map +1 -0
  112. package/dist/components/indicators/LoadingIndicator.js.map +1 -0
  113. package/dist/components/indicators/RunningIndicator.d.ts.map +1 -0
  114. package/dist/components/indicators/RunningIndicator.js.map +1 -0
  115. package/dist/components/indicators/Spinner.d.ts.map +1 -0
  116. package/dist/components/indicators/Spinner.js.map +1 -0
  117. package/dist/components/indicators/UpdatingIndicator.d.ts.map +1 -0
  118. package/dist/components/indicators/UpdatingIndicator.js.map +1 -0
  119. package/dist/components/indicators/index.d.ts +6 -0
  120. package/dist/components/indicators/index.d.ts.map +1 -0
  121. package/dist/components/indicators/index.js +6 -0
  122. package/dist/components/indicators/index.js.map +1 -0
  123. package/dist/components/inputs/CleanTextInput.d.ts.map +1 -0
  124. package/dist/{CleanTextInput.js → components/inputs/CleanTextInput.js} +2 -144
  125. package/dist/components/inputs/CleanTextInput.js.map +1 -0
  126. package/dist/components/inputs/StyledTextInput.d.ts.map +1 -0
  127. package/dist/components/inputs/StyledTextInput.js.map +1 -0
  128. package/dist/components/inputs/index.d.ts +3 -0
  129. package/dist/components/inputs/index.d.ts.map +1 -0
  130. package/dist/components/inputs/index.js +3 -0
  131. package/dist/components/inputs/index.js.map +1 -0
  132. package/dist/components/{KebabMenu.d.ts → panes/KebabMenu.d.ts} +1 -1
  133. package/dist/components/panes/KebabMenu.d.ts.map +1 -0
  134. package/dist/components/panes/KebabMenu.js.map +1 -0
  135. package/dist/components/panes/MergePane.d.ts.map +1 -0
  136. package/dist/{MergePane.js → components/panes/MergePane.js} +1 -1
  137. package/dist/components/panes/MergePane.js.map +1 -0
  138. package/dist/components/{PaneCard.d.ts → panes/PaneCard.d.ts} +1 -1
  139. package/dist/components/panes/PaneCard.d.ts.map +1 -0
  140. package/dist/components/{PaneCard.js → panes/PaneCard.js} +1 -1
  141. package/dist/components/panes/PaneCard.js.map +1 -0
  142. package/dist/components/{PanesGrid.d.ts → panes/PanesGrid.d.ts} +2 -2
  143. package/dist/components/panes/PanesGrid.d.ts.map +1 -0
  144. package/dist/components/{PanesGrid.js → panes/PanesGrid.js} +1 -1
  145. package/dist/components/panes/PanesGrid.js.map +1 -0
  146. package/dist/components/panes/index.d.ts +5 -0
  147. package/dist/components/panes/index.d.ts.map +1 -0
  148. package/dist/components/panes/index.js +5 -0
  149. package/dist/components/panes/index.js.map +1 -0
  150. package/dist/components/popups/agentChoicePopup.d.ts.map +1 -0
  151. package/dist/{popups → components/popups}/agentChoicePopup.js +1 -1
  152. package/dist/components/popups/agentChoicePopup.js.map +1 -0
  153. package/dist/components/popups/choicePopup.d.ts.map +1 -0
  154. package/dist/{popups → components/popups}/choicePopup.js +3 -3
  155. package/dist/components/popups/choicePopup.js.map +1 -0
  156. package/dist/components/popups/config.d.ts.map +1 -0
  157. package/dist/{popups → components/popups}/config.js +1 -1
  158. package/dist/components/popups/config.js.map +1 -0
  159. package/dist/components/popups/confirmPopup.d.ts.map +1 -0
  160. package/dist/{popups → components/popups}/confirmPopup.js +2 -3
  161. package/dist/components/popups/confirmPopup.js.map +1 -0
  162. package/dist/components/popups/hooksPopup.d.ts.map +1 -0
  163. package/dist/{popups → components/popups}/hooksPopup.js +1 -1
  164. package/dist/components/popups/hooksPopup.js.map +1 -0
  165. package/dist/components/popups/inputPopup.d.ts.map +1 -0
  166. package/dist/{popups → components/popups}/inputPopup.js +3 -4
  167. package/dist/components/popups/inputPopup.js.map +1 -0
  168. package/dist/components/popups/kebabMenuPopup.d.ts.map +1 -0
  169. package/dist/{popups → components/popups}/kebabMenuPopup.js +1 -1
  170. package/dist/components/popups/kebabMenuPopup.js.map +1 -0
  171. package/dist/components/popups/logsPopup.d.ts.map +1 -0
  172. package/dist/{popups → components/popups}/logsPopup.js +15 -7
  173. package/dist/components/popups/logsPopup.js.map +1 -0
  174. package/dist/components/popups/mergePopup.d.ts.map +1 -0
  175. package/dist/{popups → components/popups}/mergePopup.js +6 -6
  176. package/dist/components/popups/mergePopup.js.map +1 -0
  177. package/dist/components/popups/newPanePopup.d.ts.map +1 -0
  178. package/dist/{popups → components/popups}/newPanePopup.js +3 -3
  179. package/dist/components/popups/newPanePopup.js.map +1 -0
  180. package/dist/components/popups/progressPopup.d.ts.map +1 -0
  181. package/dist/{popups → components/popups}/progressPopup.js +1 -2
  182. package/dist/components/popups/progressPopup.js.map +1 -0
  183. package/dist/components/popups/remotePopup.d.ts.map +1 -0
  184. package/dist/{popups → components/popups}/remotePopup.js +1 -1
  185. package/dist/components/popups/remotePopup.js.map +1 -0
  186. package/dist/components/popups/settingsPopup.d.ts.map +1 -0
  187. package/dist/{popups → components/popups}/settingsPopup.js +1 -1
  188. package/dist/components/popups/settingsPopup.js.map +1 -0
  189. package/dist/components/popups/shared/FileList.d.ts.map +1 -0
  190. package/dist/components/popups/shared/FileList.js.map +1 -0
  191. package/dist/components/popups/shared/PopupContainer.d.ts.map +1 -0
  192. package/dist/components/popups/shared/PopupContainer.js.map +1 -0
  193. package/dist/components/popups/shared/PopupInputBox.d.ts.map +1 -0
  194. package/dist/components/popups/shared/PopupInputBox.js.map +1 -0
  195. package/dist/components/popups/shared/PopupWrapper.d.ts.map +1 -0
  196. package/dist/components/popups/shared/PopupWrapper.js.map +1 -0
  197. package/dist/components/popups/shared/index.d.ts.map +1 -0
  198. package/dist/components/popups/shared/index.js.map +1 -0
  199. package/dist/components/popups/shortcutsPopup.d.ts.map +1 -0
  200. package/dist/{popups → components/popups}/shortcutsPopup.js +1 -1
  201. package/dist/components/popups/shortcutsPopup.js.map +1 -0
  202. package/dist/components/popups/templates/SimpleInputPopup.d.ts.map +1 -0
  203. package/dist/{popups → components/popups}/templates/SimpleInputPopup.js +2 -2
  204. package/dist/components/popups/templates/SimpleInputPopup.js.map +1 -0
  205. package/dist/components/ui/FileCopyPrompt.d.ts.map +1 -0
  206. package/dist/components/ui/FileCopyPrompt.js.map +1 -0
  207. package/dist/components/{FooterHelp.d.ts → ui/FooterHelp.d.ts} +4 -0
  208. package/dist/components/ui/FooterHelp.d.ts.map +1 -0
  209. package/dist/components/{FooterHelp.js → ui/FooterHelp.js} +45 -1
  210. package/dist/components/ui/FooterHelp.js.map +1 -0
  211. package/dist/components/ui/QRCode.d.ts.map +1 -0
  212. package/dist/components/ui/QRCode.js.map +1 -0
  213. package/dist/components/ui/ToastNotification.d.ts +13 -0
  214. package/dist/components/ui/ToastNotification.d.ts.map +1 -0
  215. package/dist/components/ui/ToastNotification.js +22 -0
  216. package/dist/components/ui/ToastNotification.js.map +1 -0
  217. package/dist/components/ui/index.d.ts +4 -0
  218. package/dist/components/ui/index.d.ts.map +1 -0
  219. package/dist/components/ui/index.js +4 -0
  220. package/dist/components/ui/index.js.map +1 -0
  221. package/dist/constants/timing.d.ts +22 -0
  222. package/dist/constants/timing.d.ts.map +1 -0
  223. package/dist/constants/timing.js +26 -0
  224. package/dist/constants/timing.js.map +1 -0
  225. package/dist/dashboard.js +2 -2
  226. package/dist/hooks/useActionSystem.d.ts +5 -4
  227. package/dist/hooks/useActionSystem.d.ts.map +1 -1
  228. package/dist/hooks/useActionSystem.js +105 -114
  229. package/dist/hooks/useActionSystem.js.map +1 -1
  230. package/dist/hooks/useDebugInfo.d.ts +11 -0
  231. package/dist/hooks/useDebugInfo.d.ts.map +1 -0
  232. package/dist/hooks/useDebugInfo.js +34 -0
  233. package/dist/hooks/useDebugInfo.js.map +1 -0
  234. package/dist/hooks/useDialogState.d.ts +22 -0
  235. package/dist/hooks/useDialogState.d.ts.map +1 -0
  236. package/dist/hooks/useDialogState.js +62 -0
  237. package/dist/hooks/useDialogState.js.map +1 -0
  238. package/dist/hooks/useInputHandling.d.ts +60 -0
  239. package/dist/hooks/useInputHandling.d.ts.map +1 -0
  240. package/dist/hooks/useInputHandling.js +294 -0
  241. package/dist/hooks/useInputHandling.js.map +1 -0
  242. package/dist/hooks/useLayoutManagement.d.ts +12 -0
  243. package/dist/hooks/useLayoutManagement.d.ts.map +1 -0
  244. package/dist/hooks/useLayoutManagement.js +63 -0
  245. package/dist/hooks/useLayoutManagement.js.map +1 -0
  246. package/dist/hooks/usePaneCreation.d.ts.map +1 -1
  247. package/dist/hooks/usePaneCreation.js +4 -9
  248. package/dist/hooks/usePaneCreation.js.map +1 -1
  249. package/dist/hooks/usePaneLoading.d.ts +45 -0
  250. package/dist/hooks/usePaneLoading.d.ts.map +1 -0
  251. package/dist/hooks/usePaneLoading.js +208 -0
  252. package/dist/hooks/usePaneLoading.js.map +1 -0
  253. package/dist/hooks/usePaneRunner.d.ts.map +1 -1
  254. package/dist/hooks/usePaneRunner.js +9 -6
  255. package/dist/hooks/usePaneRunner.js.map +1 -1
  256. package/dist/hooks/usePaneSync.d.ts +34 -0
  257. package/dist/hooks/usePaneSync.d.ts.map +1 -0
  258. package/dist/hooks/usePaneSync.js +186 -0
  259. package/dist/hooks/usePaneSync.js.map +1 -0
  260. package/dist/hooks/usePanes.d.ts.map +1 -1
  261. package/dist/hooks/usePanes.js +68 -406
  262. package/dist/hooks/usePanes.js.map +1 -1
  263. package/dist/hooks/useServices.d.ts +24 -0
  264. package/dist/hooks/useServices.d.ts.map +1 -0
  265. package/dist/hooks/useServices.js +39 -0
  266. package/dist/hooks/useServices.js.map +1 -0
  267. package/dist/hooks/useShellDetection.d.ts +10 -0
  268. package/dist/hooks/useShellDetection.d.ts.map +1 -0
  269. package/dist/hooks/useShellDetection.js +67 -0
  270. package/dist/hooks/useShellDetection.js.map +1 -0
  271. package/dist/hooks/useStatusMessages.d.ts +11 -0
  272. package/dist/hooks/useStatusMessages.d.ts.map +1 -0
  273. package/dist/hooks/useStatusMessages.js +32 -0
  274. package/dist/hooks/useStatusMessages.js.map +1 -0
  275. package/dist/hooks/useTemporaryStatus.d.ts +13 -0
  276. package/dist/hooks/useTemporaryStatus.d.ts.map +1 -0
  277. package/dist/hooks/useTemporaryStatus.js +30 -0
  278. package/dist/hooks/useTemporaryStatus.js.map +1 -0
  279. package/dist/hooks/useTerminalWidth.d.ts.map +1 -1
  280. package/dist/hooks/useTerminalWidth.js +7 -12
  281. package/dist/hooks/useTerminalWidth.js.map +1 -1
  282. package/dist/hooks/useTunnelManagement.d.ts +18 -0
  283. package/dist/hooks/useTunnelManagement.d.ts.map +1 -0
  284. package/dist/hooks/useTunnelManagement.js +55 -0
  285. package/dist/hooks/useTunnelManagement.js.map +1 -0
  286. package/dist/hooks/useWorktreeActions.d.ts.map +1 -1
  287. package/dist/hooks/useWorktreeActions.js +18 -13
  288. package/dist/hooks/useWorktreeActions.js.map +1 -1
  289. package/dist/index.js +124 -94
  290. package/dist/index.js.map +1 -1
  291. package/dist/layout/LayoutCalculator.d.ts +62 -0
  292. package/dist/layout/LayoutCalculator.d.ts.map +1 -0
  293. package/dist/layout/LayoutCalculator.js +140 -0
  294. package/dist/layout/LayoutCalculator.js.map +1 -0
  295. package/dist/layout/SpacerManager.d.ts +64 -0
  296. package/dist/layout/SpacerManager.d.ts.map +1 -0
  297. package/dist/layout/SpacerManager.js +156 -0
  298. package/dist/layout/SpacerManager.js.map +1 -0
  299. package/dist/layout/TmuxLayoutApplier.d.ts +62 -0
  300. package/dist/layout/TmuxLayoutApplier.d.ts.map +1 -0
  301. package/dist/layout/TmuxLayoutApplier.js +147 -0
  302. package/dist/layout/TmuxLayoutApplier.js.map +1 -0
  303. package/dist/panes/decorative-pane.d.ts.map +1 -0
  304. package/dist/{decorative-pane.js → panes/decorative-pane.js} +1 -1
  305. package/dist/panes/decorative-pane.js.map +1 -0
  306. package/dist/panes/spacer-pane.d.ts.map +1 -0
  307. package/dist/panes/spacer-pane.js.map +1 -0
  308. package/dist/server/embedded-assets.d.ts.map +1 -1
  309. package/dist/server/embedded-assets.js +727 -5677
  310. package/dist/server/embedded-assets.js.map +1 -1
  311. package/dist/server/routes/actionsRoutes.d.ts +2 -0
  312. package/dist/server/routes/actionsRoutes.d.ts.map +1 -0
  313. package/dist/server/routes/actionsRoutes.js +110 -0
  314. package/dist/server/routes/actionsRoutes.js.map +1 -0
  315. package/dist/server/routes/healthRoutes.d.ts +13 -0
  316. package/dist/server/routes/healthRoutes.d.ts.map +1 -0
  317. package/dist/server/routes/healthRoutes.js +70 -0
  318. package/dist/server/routes/healthRoutes.js.map +1 -0
  319. package/dist/server/routes/index.d.ts +8 -0
  320. package/dist/server/routes/index.d.ts.map +1 -0
  321. package/dist/server/routes/index.js +67 -0
  322. package/dist/server/routes/index.js.map +1 -0
  323. package/dist/server/routes/keysRoutes.d.ts +33 -0
  324. package/dist/server/routes/keysRoutes.d.ts.map +1 -0
  325. package/dist/server/routes/keysRoutes.js +128 -0
  326. package/dist/server/routes/keysRoutes.js.map +1 -0
  327. package/dist/server/routes/panesRoutes.d.ts +2 -0
  328. package/dist/server/routes/panesRoutes.d.ts.map +1 -0
  329. package/dist/server/routes/panesRoutes.js +373 -0
  330. package/dist/server/routes/panesRoutes.js.map +1 -0
  331. package/dist/server/routes/settingsRoutes.d.ts +94 -0
  332. package/dist/server/routes/settingsRoutes.d.ts.map +1 -0
  333. package/dist/server/routes/settingsRoutes.js +159 -0
  334. package/dist/server/routes/settingsRoutes.js.map +1 -0
  335. package/dist/server/routes/streamRoutes.d.ts +18 -0
  336. package/dist/server/routes/streamRoutes.d.ts.map +1 -0
  337. package/dist/server/routes/streamRoutes.js +87 -0
  338. package/dist/server/routes/streamRoutes.js.map +1 -0
  339. package/dist/server/routes/tunnelRoutes.d.ts +11 -0
  340. package/dist/server/routes/tunnelRoutes.d.ts.map +1 -0
  341. package/dist/server/routes/tunnelRoutes.js +28 -0
  342. package/dist/server/routes/tunnelRoutes.js.map +1 -0
  343. package/dist/server/routes.d.ts +16 -2
  344. package/dist/server/routes.d.ts.map +1 -1
  345. package/dist/server/routes.js +16 -878
  346. package/dist/server/routes.js.map +1 -1
  347. package/dist/{AutoUpdater.d.ts → services/AutoUpdater.d.ts} +1 -0
  348. package/dist/services/AutoUpdater.d.ts.map +1 -0
  349. package/dist/{AutoUpdater.js → services/AutoUpdater.js} +44 -10
  350. package/dist/services/AutoUpdater.js.map +1 -0
  351. package/dist/services/PaneAnalyzer.d.ts.map +1 -0
  352. package/dist/{PaneAnalyzer.js → services/PaneAnalyzer.js} +1 -1
  353. package/dist/services/PaneAnalyzer.js.map +1 -0
  354. package/dist/services/PaneLifecycleManager.d.ts +60 -0
  355. package/dist/services/PaneLifecycleManager.d.ts.map +1 -0
  356. package/dist/services/PaneLifecycleManager.js +119 -0
  357. package/dist/services/PaneLifecycleManager.js.map +1 -0
  358. package/dist/services/PaneWorkerManager.d.ts.map +1 -1
  359. package/dist/services/PaneWorkerManager.js +6 -3
  360. package/dist/services/PaneWorkerManager.js.map +1 -1
  361. package/dist/services/PopupManager.d.ts +68 -0
  362. package/dist/services/PopupManager.d.ts.map +1 -0
  363. package/dist/services/PopupManager.js +415 -0
  364. package/dist/services/PopupManager.js.map +1 -0
  365. package/dist/services/StatusDetector.d.ts.map +1 -1
  366. package/dist/services/StatusDetector.js +6 -8
  367. package/dist/services/StatusDetector.js.map +1 -1
  368. package/dist/services/TerminalStreamer.d.ts +1 -0
  369. package/dist/services/TerminalStreamer.d.ts.map +1 -1
  370. package/dist/services/TerminalStreamer.js +22 -16
  371. package/dist/services/TerminalStreamer.js.map +1 -1
  372. package/dist/services/TmuxService.d.ts +346 -0
  373. package/dist/services/TmuxService.d.ts.map +1 -0
  374. package/dist/services/TmuxService.js +849 -0
  375. package/dist/services/TmuxService.js.map +1 -0
  376. package/dist/services/ToastService.d.ts +71 -0
  377. package/dist/services/ToastService.d.ts.map +1 -0
  378. package/dist/services/ToastService.js +151 -0
  379. package/dist/services/ToastService.js.map +1 -0
  380. package/dist/services/TunnelService.d.ts.map +1 -1
  381. package/dist/services/TunnelService.js +2 -1
  382. package/dist/services/TunnelService.js.map +1 -1
  383. package/dist/shared/StateManager.d.ts +22 -0
  384. package/dist/shared/StateManager.d.ts.map +1 -1
  385. package/dist/shared/StateManager.js +68 -1
  386. package/dist/shared/StateManager.js.map +1 -1
  387. package/dist/terminal.js +3 -3
  388. package/dist/types.d.ts +7 -0
  389. package/dist/types.d.ts.map +1 -1
  390. package/dist/utils/asciiArt.d.ts.map +1 -1
  391. package/dist/utils/asciiArt.js +9 -22
  392. package/dist/utils/asciiArt.js.map +1 -1
  393. package/dist/utils/atomicWrite.d.ts +33 -0
  394. package/dist/utils/atomicWrite.d.ts.map +1 -0
  395. package/dist/utils/atomicWrite.js +89 -0
  396. package/dist/utils/atomicWrite.js.map +1 -0
  397. package/dist/utils/conflictMonitor.d.ts +20 -0
  398. package/dist/utils/conflictMonitor.d.ts.map +1 -0
  399. package/dist/utils/conflictMonitor.js +113 -0
  400. package/dist/utils/conflictMonitor.js.map +1 -0
  401. package/dist/utils/conflictResolutionPane.d.ts.map +1 -1
  402. package/dist/utils/conflictResolutionPane.js +70 -79
  403. package/dist/utils/conflictResolutionPane.js.map +1 -1
  404. package/dist/utils/errorHandling.d.ts +37 -0
  405. package/dist/utils/errorHandling.d.ts.map +1 -0
  406. package/dist/utils/errorHandling.js +138 -0
  407. package/dist/utils/errorHandling.js.map +1 -0
  408. package/dist/utils/generated-agents-doc.d.ts +1 -1
  409. package/dist/utils/generated-agents-doc.js +1 -1
  410. package/dist/utils/git.d.ts +4 -0
  411. package/dist/utils/git.d.ts.map +1 -1
  412. package/dist/utils/git.js +15 -0
  413. package/dist/utils/git.js.map +1 -1
  414. package/dist/utils/hooksDocs.d.ts +1 -1
  415. package/dist/utils/layoutManager.d.ts +20 -16
  416. package/dist/utils/layoutManager.d.ts.map +1 -1
  417. package/dist/utils/layoutManager.js +159 -380
  418. package/dist/utils/layoutManager.js.map +1 -1
  419. package/dist/utils/mergeExecution.d.ts.map +1 -1
  420. package/dist/utils/mergeExecution.js +8 -1
  421. package/dist/utils/mergeExecution.js.map +1 -1
  422. package/dist/utils/mergeValidation.d.ts.map +1 -1
  423. package/dist/utils/mergeValidation.js +46 -13
  424. package/dist/utils/mergeValidation.js.map +1 -1
  425. package/dist/utils/paneCreation.d.ts.map +1 -1
  426. package/dist/utils/paneCreation.js +115 -106
  427. package/dist/utils/paneCreation.js.map +1 -1
  428. package/dist/utils/paneRebinding.d.ts +14 -0
  429. package/dist/utils/paneRebinding.d.ts.map +1 -0
  430. package/dist/utils/paneRebinding.js +30 -0
  431. package/dist/utils/paneRebinding.js.map +1 -0
  432. package/dist/utils/popup.d.ts.map +1 -1
  433. package/dist/utils/popup.js +11 -17
  434. package/dist/utils/popup.js.map +1 -1
  435. package/dist/utils/postPaneCleanup.d.ts.map +1 -1
  436. package/dist/utils/postPaneCleanup.js +5 -14
  437. package/dist/utils/postPaneCleanup.js.map +1 -1
  438. package/dist/utils/shellPaneDetection.d.ts +3 -3
  439. package/dist/utils/shellPaneDetection.d.ts.map +1 -1
  440. package/dist/utils/shellPaneDetection.js +43 -29
  441. package/dist/utils/shellPaneDetection.js.map +1 -1
  442. package/dist/utils/systemCheck.d.ts +19 -0
  443. package/dist/utils/systemCheck.d.ts.map +1 -0
  444. package/dist/utils/systemCheck.js +160 -0
  445. package/dist/utils/systemCheck.js.map +1 -0
  446. package/dist/utils/tmux.d.ts +26 -7
  447. package/dist/utils/tmux.d.ts.map +1 -1
  448. package/dist/utils/tmux.js +84 -76
  449. package/dist/utils/tmux.js.map +1 -1
  450. package/dist/utils/welcomePane.d.ts +2 -2
  451. package/dist/utils/welcomePane.d.ts.map +1 -1
  452. package/dist/utils/welcomePane.js +19 -33
  453. package/dist/utils/welcomePane.js.map +1 -1
  454. package/dist/utils/welcomePaneManager.d.ts.map +1 -1
  455. package/dist/utils/welcomePaneManager.js +11 -25
  456. package/dist/utils/welcomePaneManager.js.map +1 -1
  457. package/dist/workers/PaneWorker.js +7 -9
  458. package/dist/workers/PaneWorker.js.map +1 -1
  459. package/dist/workers/updateChecker.js +1 -1
  460. package/dist/workers/updateChecker.js.map +1 -1
  461. package/package.json +3 -1
  462. package/dist/AutoUpdater.d.ts.map +0 -1
  463. package/dist/AutoUpdater.js.map +0 -1
  464. package/dist/BetterTextInput.d.ts +0 -10
  465. package/dist/BetterTextInput.d.ts.map +0 -1
  466. package/dist/BetterTextInput.js +0 -177
  467. package/dist/BetterTextInput.js.map +0 -1
  468. package/dist/CleanTextInput.d.ts.map +0 -1
  469. package/dist/CleanTextInput.js.map +0 -1
  470. package/dist/EnhancedTextInput.d.ts +0 -13
  471. package/dist/EnhancedTextInput.d.ts.map +0 -1
  472. package/dist/EnhancedTextInput.js +0 -443
  473. package/dist/EnhancedTextInput.js.map +0 -1
  474. package/dist/GeminiTextInput.d.ts +0 -12
  475. package/dist/GeminiTextInput.d.ts.map +0 -1
  476. package/dist/GeminiTextInput.js +0 -210
  477. package/dist/GeminiTextInput.js.map +0 -1
  478. package/dist/MergePane.d.ts.map +0 -1
  479. package/dist/MergePane.js.map +0 -1
  480. package/dist/MultilineTextInput.d.ts +0 -10
  481. package/dist/MultilineTextInput.d.ts.map +0 -1
  482. package/dist/MultilineTextInput.js +0 -184
  483. package/dist/MultilineTextInput.js.map +0 -1
  484. package/dist/PaneAnalyzer.d.ts.map +0 -1
  485. package/dist/PaneAnalyzer.js.map +0 -1
  486. package/dist/SimpleEnhancedInput.d.ts +0 -13
  487. package/dist/SimpleEnhancedInput.d.ts.map +0 -1
  488. package/dist/SimpleEnhancedInput.js +0 -639
  489. package/dist/SimpleEnhancedInput.js.map +0 -1
  490. package/dist/SimpleGeminiInput.d.ts +0 -12
  491. package/dist/SimpleGeminiInput.d.ts.map +0 -1
  492. package/dist/SimpleGeminiInput.js +0 -223
  493. package/dist/SimpleGeminiInput.js.map +0 -1
  494. package/dist/StyledTextInput.d.ts.map +0 -1
  495. package/dist/StyledTextInput.js.map +0 -1
  496. package/dist/components/ActionChoiceDialog.d.ts.map +0 -1
  497. package/dist/components/ActionChoiceDialog.js.map +0 -1
  498. package/dist/components/ActionConfirmDialog.d.ts.map +0 -1
  499. package/dist/components/ActionConfirmDialog.js.map +0 -1
  500. package/dist/components/ActionInputDialog.d.ts.map +0 -1
  501. package/dist/components/ActionInputDialog.js.map +0 -1
  502. package/dist/components/ActionProgressDialog.d.ts.map +0 -1
  503. package/dist/components/ActionProgressDialog.js.map +0 -1
  504. package/dist/components/AgentChoiceDialog.d.ts.map +0 -1
  505. package/dist/components/AgentChoiceDialog.js.map +0 -1
  506. package/dist/components/CloseOptionsDialog.d.ts.map +0 -1
  507. package/dist/components/CloseOptionsDialog.js.map +0 -1
  508. package/dist/components/CommandPromptDialog.d.ts.map +0 -1
  509. package/dist/components/CommandPromptDialog.js.map +0 -1
  510. package/dist/components/CreatingIndicator.d.ts.map +0 -1
  511. package/dist/components/CreatingIndicator.js.map +0 -1
  512. package/dist/components/DialogBox.d.ts.map +0 -1
  513. package/dist/components/DialogBox.js.map +0 -1
  514. package/dist/components/FileCopyPrompt.d.ts.map +0 -1
  515. package/dist/components/FileCopyPrompt.js.map +0 -1
  516. package/dist/components/FooterHelp.d.ts.map +0 -1
  517. package/dist/components/FooterHelp.js.map +0 -1
  518. package/dist/components/HooksDialog.d.ts.map +0 -1
  519. package/dist/components/HooksDialog.js.map +0 -1
  520. package/dist/components/KebabMenu.d.ts.map +0 -1
  521. package/dist/components/KebabMenu.js.map +0 -1
  522. package/dist/components/LoadingIndicator.d.ts.map +0 -1
  523. package/dist/components/LoadingIndicator.js.map +0 -1
  524. package/dist/components/MergeConfirmationDialog.d.ts.map +0 -1
  525. package/dist/components/MergeConfirmationDialog.js.map +0 -1
  526. package/dist/components/PaneCard.d.ts.map +0 -1
  527. package/dist/components/PaneCard.js.map +0 -1
  528. package/dist/components/PanesGrid.d.ts.map +0 -1
  529. package/dist/components/PanesGrid.js.map +0 -1
  530. package/dist/components/QRCode.d.ts.map +0 -1
  531. package/dist/components/QRCode.js.map +0 -1
  532. package/dist/components/RunningIndicator.d.ts.map +0 -1
  533. package/dist/components/RunningIndicator.js.map +0 -1
  534. package/dist/components/SettingsDialog.d.ts.map +0 -1
  535. package/dist/components/SettingsDialog.js.map +0 -1
  536. package/dist/components/Spinner.d.ts.map +0 -1
  537. package/dist/components/Spinner.js.map +0 -1
  538. package/dist/components/UpdateDialog.d.ts.map +0 -1
  539. package/dist/components/UpdateDialog.js.map +0 -1
  540. package/dist/components/UpdatingIndicator.d.ts.map +0 -1
  541. package/dist/components/UpdatingIndicator.js.map +0 -1
  542. package/dist/decorative-pane.d.ts.map +0 -1
  543. package/dist/decorative-pane.js.map +0 -1
  544. package/dist/popups/agentChoicePopup.d.ts.map +0 -1
  545. package/dist/popups/agentChoicePopup.js.map +0 -1
  546. package/dist/popups/choicePopup.d.ts.map +0 -1
  547. package/dist/popups/choicePopup.js.map +0 -1
  548. package/dist/popups/components/FileList.d.ts.map +0 -1
  549. package/dist/popups/components/FileList.js.map +0 -1
  550. package/dist/popups/components/PopupContainer.d.ts.map +0 -1
  551. package/dist/popups/components/PopupContainer.js.map +0 -1
  552. package/dist/popups/components/PopupInputBox.d.ts.map +0 -1
  553. package/dist/popups/components/PopupInputBox.js.map +0 -1
  554. package/dist/popups/components/PopupWrapper.d.ts.map +0 -1
  555. package/dist/popups/components/PopupWrapper.js.map +0 -1
  556. package/dist/popups/components/index.d.ts.map +0 -1
  557. package/dist/popups/components/index.js.map +0 -1
  558. package/dist/popups/config.d.ts.map +0 -1
  559. package/dist/popups/config.js.map +0 -1
  560. package/dist/popups/confirmPopup.d.ts.map +0 -1
  561. package/dist/popups/confirmPopup.js.map +0 -1
  562. package/dist/popups/hooksPopup.d.ts.map +0 -1
  563. package/dist/popups/hooksPopup.js.map +0 -1
  564. package/dist/popups/inputPopup.d.ts.map +0 -1
  565. package/dist/popups/inputPopup.js.map +0 -1
  566. package/dist/popups/kebabMenuPopup.d.ts.map +0 -1
  567. package/dist/popups/kebabMenuPopup.js.map +0 -1
  568. package/dist/popups/logsPopup.d.ts.map +0 -1
  569. package/dist/popups/logsPopup.js.map +0 -1
  570. package/dist/popups/mergePopup.d.ts.map +0 -1
  571. package/dist/popups/mergePopup.js.map +0 -1
  572. package/dist/popups/newPanePopup.d.ts.map +0 -1
  573. package/dist/popups/newPanePopup.js.map +0 -1
  574. package/dist/popups/progressPopup.d.ts.map +0 -1
  575. package/dist/popups/progressPopup.js.map +0 -1
  576. package/dist/popups/remotePopup.d.ts.map +0 -1
  577. package/dist/popups/remotePopup.js.map +0 -1
  578. package/dist/popups/settingsPopup.d.ts.map +0 -1
  579. package/dist/popups/settingsPopup.js.map +0 -1
  580. package/dist/popups/shortcutsPopup.d.ts.map +0 -1
  581. package/dist/popups/shortcutsPopup.js.map +0 -1
  582. package/dist/popups/templates/SimpleInputPopup.d.ts.map +0 -1
  583. package/dist/popups/templates/SimpleInputPopup.js.map +0 -1
  584. package/dist/server/static.d.ts +0 -6
  585. package/dist/server/static.d.ts.map +0 -1
  586. package/dist/server/static.js +0 -3040
  587. package/dist/server/static.js.map +0 -1
  588. package/dist/spacer-pane.d.ts.map +0 -1
  589. package/dist/spacer-pane.js.map +0 -1
  590. /package/dist/components/{ActionChoiceDialog.js → dialogs/ActionChoiceDialog.js} +0 -0
  591. /package/dist/components/{ActionConfirmDialog.d.ts → dialogs/ActionConfirmDialog.d.ts} +0 -0
  592. /package/dist/components/{ActionConfirmDialog.js → dialogs/ActionConfirmDialog.js} +0 -0
  593. /package/dist/components/{ActionInputDialog.d.ts → dialogs/ActionInputDialog.d.ts} +0 -0
  594. /package/dist/components/{ActionProgressDialog.d.ts → dialogs/ActionProgressDialog.d.ts} +0 -0
  595. /package/dist/components/{ActionProgressDialog.js → dialogs/ActionProgressDialog.js} +0 -0
  596. /package/dist/components/{AgentChoiceDialog.d.ts → dialogs/AgentChoiceDialog.d.ts} +0 -0
  597. /package/dist/components/{AgentChoiceDialog.js → dialogs/AgentChoiceDialog.js} +0 -0
  598. /package/dist/components/{CloseOptionsDialog.js → dialogs/CloseOptionsDialog.js} +0 -0
  599. /package/dist/components/{CommandPromptDialog.d.ts → dialogs/CommandPromptDialog.d.ts} +0 -0
  600. /package/dist/components/{DialogBox.d.ts → dialogs/DialogBox.d.ts} +0 -0
  601. /package/dist/components/{DialogBox.js → dialogs/DialogBox.js} +0 -0
  602. /package/dist/components/{HooksDialog.d.ts → dialogs/HooksDialog.d.ts} +0 -0
  603. /package/dist/components/{HooksDialog.js → dialogs/HooksDialog.js} +0 -0
  604. /package/dist/components/{MergeConfirmationDialog.js → dialogs/MergeConfirmationDialog.js} +0 -0
  605. /package/dist/components/{SettingsDialog.js → dialogs/SettingsDialog.js} +0 -0
  606. /package/dist/components/{UpdateDialog.d.ts → dialogs/UpdateDialog.d.ts} +0 -0
  607. /package/dist/components/{UpdateDialog.js → dialogs/UpdateDialog.js} +0 -0
  608. /package/dist/components/{CreatingIndicator.d.ts → indicators/CreatingIndicator.d.ts} +0 -0
  609. /package/dist/components/{CreatingIndicator.js → indicators/CreatingIndicator.js} +0 -0
  610. /package/dist/components/{LoadingIndicator.d.ts → indicators/LoadingIndicator.d.ts} +0 -0
  611. /package/dist/components/{LoadingIndicator.js → indicators/LoadingIndicator.js} +0 -0
  612. /package/dist/components/{RunningIndicator.d.ts → indicators/RunningIndicator.d.ts} +0 -0
  613. /package/dist/components/{RunningIndicator.js → indicators/RunningIndicator.js} +0 -0
  614. /package/dist/components/{Spinner.d.ts → indicators/Spinner.d.ts} +0 -0
  615. /package/dist/components/{Spinner.js → indicators/Spinner.js} +0 -0
  616. /package/dist/components/{UpdatingIndicator.d.ts → indicators/UpdatingIndicator.d.ts} +0 -0
  617. /package/dist/components/{UpdatingIndicator.js → indicators/UpdatingIndicator.js} +0 -0
  618. /package/dist/{CleanTextInput.d.ts → components/inputs/CleanTextInput.d.ts} +0 -0
  619. /package/dist/{StyledTextInput.d.ts → components/inputs/StyledTextInput.d.ts} +0 -0
  620. /package/dist/{StyledTextInput.js → components/inputs/StyledTextInput.js} +0 -0
  621. /package/dist/components/{KebabMenu.js → panes/KebabMenu.js} +0 -0
  622. /package/dist/{MergePane.d.ts → components/panes/MergePane.d.ts} +0 -0
  623. /package/dist/{popups → components/popups}/agentChoicePopup.d.ts +0 -0
  624. /package/dist/{popups → components/popups}/choicePopup.d.ts +0 -0
  625. /package/dist/{popups → components/popups}/config.d.ts +0 -0
  626. /package/dist/{popups → components/popups}/confirmPopup.d.ts +0 -0
  627. /package/dist/{popups → components/popups}/hooksPopup.d.ts +0 -0
  628. /package/dist/{popups → components/popups}/inputPopup.d.ts +0 -0
  629. /package/dist/{popups → components/popups}/kebabMenuPopup.d.ts +0 -0
  630. /package/dist/{popups → components/popups}/logsPopup.d.ts +0 -0
  631. /package/dist/{popups → components/popups}/mergePopup.d.ts +0 -0
  632. /package/dist/{popups → components/popups}/newPanePopup.d.ts +0 -0
  633. /package/dist/{popups → components/popups}/progressPopup.d.ts +0 -0
  634. /package/dist/{popups → components/popups}/remotePopup.d.ts +0 -0
  635. /package/dist/{popups → components/popups}/settingsPopup.d.ts +0 -0
  636. /package/dist/{popups/components → components/popups/shared}/FileList.d.ts +0 -0
  637. /package/dist/{popups/components → components/popups/shared}/FileList.js +0 -0
  638. /package/dist/{popups/components → components/popups/shared}/PopupContainer.d.ts +0 -0
  639. /package/dist/{popups/components → components/popups/shared}/PopupContainer.js +0 -0
  640. /package/dist/{popups/components → components/popups/shared}/PopupInputBox.d.ts +0 -0
  641. /package/dist/{popups/components → components/popups/shared}/PopupInputBox.js +0 -0
  642. /package/dist/{popups/components → components/popups/shared}/PopupWrapper.d.ts +0 -0
  643. /package/dist/{popups/components → components/popups/shared}/PopupWrapper.js +0 -0
  644. /package/dist/{popups/components → components/popups/shared}/index.d.ts +0 -0
  645. /package/dist/{popups/components → components/popups/shared}/index.js +0 -0
  646. /package/dist/{popups → components/popups}/shortcutsPopup.d.ts +0 -0
  647. /package/dist/{popups → components/popups}/templates/SimpleInputPopup.d.ts +0 -0
  648. /package/dist/components/{FileCopyPrompt.d.ts → ui/FileCopyPrompt.d.ts} +0 -0
  649. /package/dist/components/{FileCopyPrompt.js → ui/FileCopyPrompt.js} +0 -0
  650. /package/dist/components/{QRCode.d.ts → ui/QRCode.d.ts} +0 -0
  651. /package/dist/components/{QRCode.js → ui/QRCode.js} +0 -0
  652. /package/dist/{decorative-pane.d.ts → panes/decorative-pane.d.ts} +0 -0
  653. /package/dist/{spacer-pane.d.ts → panes/spacer-pane.d.ts} +0 -0
  654. /package/dist/{spacer-pane.js → panes/spacer-pane.js} +0 -0
  655. /package/dist/{PaneAnalyzer.d.ts → services/PaneAnalyzer.d.ts} +0 -0
@@ -1,8 +1,11 @@
1
- import { execSync } from "child_process";
2
- import { generateSidebarGridLayout, getWindowDimensions, getAllPaneIds, } from "./tmux.js";
3
- import { LogService } from "../services/LogService.js";
4
- // Spacer pane identifier
5
- const SPACER_PANE_TITLE = "dmux-spacer";
1
+ import { getWindowDimensions } from './tmux.js';
2
+ import { TmuxService } from '../services/TmuxService.js';
3
+ import { LogService } from '../services/LogService.js';
4
+ import { TMUX_PANE_CREATION_DELAY } from '../constants/timing.js';
5
+ // Import new focused classes
6
+ import { LayoutCalculator } from '../layout/LayoutCalculator.js';
7
+ import { SpacerManager } from '../layout/SpacerManager.js';
8
+ import { TmuxLayoutApplier } from '../layout/TmuxLayoutApplier.js';
6
9
  export const DEFAULT_LAYOUT_CONFIG = {
7
10
  SIDEBAR_WIDTH: 40,
8
11
  MIN_COMFORTABLE_WIDTH: 50,
@@ -14,144 +17,65 @@ export const SIDEBAR_WIDTH = DEFAULT_LAYOUT_CONFIG.SIDEBAR_WIDTH;
14
17
  export const MIN_COMFORTABLE_WIDTH = DEFAULT_LAYOUT_CONFIG.MIN_COMFORTABLE_WIDTH;
15
18
  export const MAX_COMFORTABLE_WIDTH = DEFAULT_LAYOUT_CONFIG.MAX_COMFORTABLE_WIDTH;
16
19
  export const MIN_COMFORTABLE_HEIGHT = DEFAULT_LAYOUT_CONFIG.MIN_COMFORTABLE_HEIGHT;
17
- /**
18
- * Finds the spacer pane ID if it exists
19
- */
20
- function findSpacerPane() {
21
- try {
22
- const allPanes = getAllPaneIds();
23
- for (const paneId of allPanes) {
24
- const title = execSync(`tmux display-message -t '${paneId}' -p '#{pane_title}'`, { encoding: "utf-8", stdio: "pipe" }).trim();
25
- if (title === SPACER_PANE_TITLE) {
26
- return paneId;
27
- }
28
- }
29
- }
30
- catch {
31
- // Ignore errors
32
- }
33
- return null;
34
- }
35
- /**
36
- * Creates a spacer pane that displays static gray dots
37
- * Always splits from the last content pane to ensure spacer comes last
38
- * @param lastContentPaneId - The ID of the last content pane to split from
39
- * Returns the new pane ID
40
- */
41
- function createSpacerPane(lastContentPaneId) {
42
- try {
43
- // Store the currently active pane
44
- const originalPaneId = execSync(`tmux display-message -p '#{pane_id}'`, { encoding: "utf-8", stdio: "pipe" }).trim();
45
- // Switch to the last content pane
46
- execSync(`tmux select-pane -t '${lastContentPaneId}'`, { stdio: "pipe" });
47
- // Create a new pane running our spacer-pane script (just dots, no ASCII art)
48
- // This will split from the currently active pane (the last content pane)
49
- const scriptPath = `${process.cwd()}/dist/spacer-pane.js`;
50
- const newPaneId = execSync(`tmux split-window -h -P -F '#{pane_id}' "node '${scriptPath}'"`, { encoding: "utf-8", stdio: "pipe" }).trim();
51
- // Set the pane title to identify it as a spacer
52
- execSync(`tmux select-pane -t '${newPaneId}' -T '${SPACER_PANE_TITLE}'`, {
53
- stdio: "pipe"
54
- });
55
- // Return focus to the originally active pane
56
- execSync(`tmux select-pane -t '${originalPaneId}'`, { stdio: "pipe" });
57
- LogService.getInstance().debug(`Created spacer pane: ${newPaneId} (split from ${lastContentPaneId}, restored focus to ${originalPaneId})`, "Layout");
58
- return newPaneId;
59
- }
60
- catch (error) {
61
- LogService.getInstance().debug(`Failed to create spacer pane: ${error}`, "Layout");
62
- throw error;
63
- }
64
- }
65
- /**
66
- * Destroys the spacer pane if it exists
67
- */
68
- function destroySpacerPane(spacerId) {
69
- try {
70
- execSync(`tmux kill-pane -t '${spacerId}'`, { stdio: "pipe" });
71
- LogService.getInstance().debug(`Destroyed spacer pane: ${spacerId}`, "Layout");
72
- }
73
- catch (error) {
74
- LogService.getInstance().debug(`Failed to destroy spacer pane: ${error}`, "Layout");
75
- }
76
- }
77
- /**
78
- * Determines if we need a spacer pane based on layout configuration
79
- * We need a spacer when panes in the last row would exceed MAX_COMFORTABLE_WIDTH if stretched to fill
80
- */
81
- function needsSpacerPane(numContentPanes, layout, config) {
82
- const { cols, rows } = layout;
83
- const MIN_SPACER_WIDTH = 20; // Minimum width for spacer pane (tmux may reject layouts with tiny panes)
84
- // No spacer needed if we have no content or only one column
85
- if (cols === 0 || cols === 1)
86
- return false;
87
- // Calculate number of panes in last row (row-based layout)
88
- // For 5 panes in 3 cols: (5 % 3) || 3 = 2 (last row has 2 panes)
89
- // For 6 panes in 3 cols: (6 % 3) || 3 = 3 (last row is full)
90
- const panesInLastRow = (numContentPanes % cols) || cols;
91
- // If last row is full, no spacer needed
92
- if (panesInLastRow === cols)
93
- return false;
94
- // Calculate available width for the last row
95
- const contentWidth = layout.windowWidth - config.SIDEBAR_WIDTH - 1;
96
- const bordersInLastRow = panesInLastRow - 1;
97
- const availableWidth = contentWidth - bordersInLastRow;
98
- // Calculate width per pane if we distribute evenly
99
- const widthPerPane = availableWidth / panesInLastRow;
100
- LogService.getInstance().debug(`Spacer check: ${panesInLastRow} panes in last row, ${Math.round(availableWidth)} available width, ${Math.round(widthPerPane)} per pane (max: ${config.MAX_COMFORTABLE_WIDTH})`, "Layout");
101
- // Need spacer if distributing width evenly would exceed comfortable width
102
- if (widthPerPane <= config.MAX_COMFORTABLE_WIDTH) {
103
- return false;
104
- }
105
- // Calculate what the spacer width would be
106
- const contentPaneWidth = config.MAX_COMFORTABLE_WIDTH;
107
- const totalBorders = panesInLastRow; // Total borders if we add spacer (between N+1 panes)
108
- const totalContentWidth = panesInLastRow * contentPaneWidth;
109
- const spacerWidth = contentWidth - totalContentWidth - totalBorders;
110
- // Only use spacer if it would be wide enough (avoid tmux rejecting tiny panes)
111
- if (spacerWidth < MIN_SPACER_WIDTH) {
112
- LogService.getInstance().debug(`Spacer would be too narrow (${spacerWidth} < ${MIN_SPACER_WIDTH}), skipping spacer`, "Layout");
113
- return false;
114
- }
115
- return true;
116
- }
117
20
  // Cache last layout dimensions to avoid unnecessary spacer recreation
118
21
  let lastLayoutDimensions = null;
119
22
  /**
120
23
  * MASTER LAYOUT FUNCTION
121
24
  * Single entry point for all layout operations
122
25
  * Called on: initial setup, pane creation, pane deletion, terminal resize
26
+ *
27
+ * Algorithm:
28
+ * 1. Filter out existing spacer from content panes
29
+ * 2. Calculate optimal layout for real content panes
30
+ * 3. Determine if spacer is needed
31
+ * 4. Destroy existing spacer (if present)
32
+ * 5. Create new spacer (if needed)
33
+ * 6. Resize sidebar (before window resize)
34
+ * 7. Resize window dimensions
35
+ * 8. Re-enforce sidebar width (after window resize)
36
+ * 9. Apply layout to tmux
123
37
  */
124
- export function recalculateAndApplyLayout(controlPaneId, contentPaneIds, terminalWidth, terminalHeight, config = DEFAULT_LAYOUT_CONFIG) {
38
+ export async function recalculateAndApplyLayout(controlPaneId, contentPaneIds, terminalWidth, terminalHeight, config = DEFAULT_LAYOUT_CONFIG) {
39
+ // Create class instances with config
40
+ const calculator = new LayoutCalculator(config);
41
+ const spacerManager = new SpacerManager(config);
42
+ const layoutApplier = new TmuxLayoutApplier(config);
125
43
  // Step 1: Filter out any existing spacer from content panes
126
- const existingSpacerId = findSpacerPane();
44
+ const existingSpacerId = spacerManager.findSpacerPane();
127
45
  const realContentPanes = contentPaneIds.filter(id => id !== existingSpacerId);
128
46
  // Check if dimensions and pane count have changed since last layout
129
47
  const dimensionsUnchanged = lastLayoutDimensions &&
130
48
  lastLayoutDimensions.width === terminalWidth &&
131
49
  lastLayoutDimensions.height === terminalHeight &&
132
50
  lastLayoutDimensions.paneCount === realContentPanes.length;
133
- if (dimensionsUnchanged && existingSpacerId) {
134
- LogService.getInstance().debug(`Layout unchanged (${terminalWidth}x${terminalHeight}, ${realContentPanes.length} panes), skipping spacer recreation`, "Layout");
51
+ if (dimensionsUnchanged) {
52
+ // Layout unchanged - skip ALL layout operations to prevent Ink redraw
53
+ // This prevents the dmux UI from being cleared on resize when nothing changed
54
+ LogService.getInstance().debug(`Layout unchanged (${terminalWidth}x${terminalHeight}, ${realContentPanes.length} panes), skipping layout application`, 'ResizeDebug');
135
55
  return;
136
56
  }
57
+ LogService.getInstance().debug(`Dimensions changed, applying layout: ${terminalWidth}x${terminalHeight}, ${realContentPanes.length} panes`, 'ResizeDebug');
137
58
  // Update last layout dimensions
138
59
  lastLayoutDimensions = {
139
60
  width: terminalWidth,
140
61
  height: terminalHeight,
141
- paneCount: realContentPanes.length
62
+ paneCount: realContentPanes.length,
142
63
  };
143
64
  // Step 2: Calculate layout for real content panes only
144
- const layout = calculateOptimalLayout(realContentPanes.length, terminalWidth, terminalHeight, config);
65
+ const layout = calculator.calculateOptimalLayout(realContentPanes.length, terminalWidth, terminalHeight);
145
66
  // Step 3: Determine if we need a spacer pane
146
- const needsSpacer = needsSpacerPane(realContentPanes.length, layout, config);
67
+ const needsSpacer = spacerManager.needsSpacerPane(realContentPanes.length, layout);
147
68
  // Step 4: Manage spacer pane creation/destruction
148
69
  // ALWAYS destroy existing spacer on layout recalc to ensure fresh positioning
149
70
  let spacerId = null;
150
- LogService.getInstance().debug(`Spacer management: needs=${needsSpacer}, existing=${existingSpacerId || 'none'}`, "Layout");
71
+ // LogService.getInstance().debug(
72
+ // `Spacer management: needs=${needsSpacer}, existing=${existingSpacerId || 'none'}`,
73
+ // 'Layout'
74
+ // );
151
75
  // Destroy existing spacer if present (we'll recreate if needed)
152
76
  if (existingSpacerId) {
153
- LogService.getInstance().debug(`Destroying existing spacer for recreation: ${existingSpacerId}`, "Layout");
154
- destroySpacerPane(existingSpacerId);
77
+ // LogService.getInstance().debug(`Destroying existing spacer for recreation: ${existingSpacerId}`, 'Layout');
78
+ spacerManager.destroySpacerPane(existingSpacerId);
155
79
  }
156
80
  // Create new spacer if needed
157
81
  if (needsSpacer) {
@@ -160,56 +84,56 @@ export function recalculateAndApplyLayout(controlPaneId, contentPaneIds, termina
160
84
  if (!lastContentPaneId) {
161
85
  throw new Error('No content panes available to split from');
162
86
  }
163
- spacerId = createSpacerPane(lastContentPaneId);
164
- LogService.getInstance().debug(`Created fresh spacer pane: ${spacerId}`, "Layout");
87
+ spacerId = spacerManager.createSpacerPane(lastContentPaneId);
88
+ // LogService.getInstance().debug(`Created fresh spacer pane: ${spacerId}`, 'Layout');
165
89
  // CRITICAL: Wait for tmux to fully register the new pane before applying layout
166
- execSync("sleep 0.05", { stdio: "pipe" });
90
+ await new Promise(resolve => setTimeout(resolve, TMUX_PANE_CREATION_DELAY));
167
91
  // Verify the pane appears in list-panes output
92
+ const tmuxService = TmuxService.getInstance();
168
93
  let paneVerified = false;
169
94
  for (let attempts = 0; attempts < 3; attempts++) {
170
95
  try {
171
- const output = execSync('tmux list-panes -F "#{pane_id}"', {
172
- encoding: 'utf-8',
173
- stdio: 'pipe',
174
- }).trim();
175
- if (output.includes(spacerId)) {
96
+ const allPaneIds = tmuxService.getAllPaneIdsSync();
97
+ if (allPaneIds.includes(spacerId)) {
176
98
  paneVerified = true;
177
- LogService.getInstance().debug(`Verified spacer pane ${spacerId} in list-panes (attempt ${attempts + 1})`, "Layout");
99
+ // LogService.getInstance().debug(
100
+ // `Verified spacer pane ${spacerId} in list-panes (attempt ${attempts + 1})`,
101
+ // 'Layout'
102
+ // );
178
103
  break;
179
104
  }
180
105
  }
181
106
  catch {
182
107
  // Pane not ready yet, wait a bit
183
108
  if (attempts < 2)
184
- execSync("sleep 0.05", { stdio: "pipe" });
109
+ await new Promise(resolve => setTimeout(resolve, TMUX_PANE_CREATION_DELAY));
185
110
  }
186
111
  }
187
112
  if (!paneVerified) {
188
- LogService.getInstance().debug(`WARNING: Spacer pane ${spacerId} not verified, continuing anyway`, "Layout");
113
+ LogService.getInstance().warn(`Spacer pane ${spacerId} not verified, continuing anyway`, 'Layout');
189
114
  // Don't throw - continue and let it fail with better logs
190
115
  }
191
116
  }
192
117
  catch (error) {
193
- LogService.getInstance().debug(`Continuing without spacer pane: ${error}`, "Layout");
118
+ // LogService.getInstance().debug(`Continuing without spacer pane: ${error}`, 'Layout');
194
119
  spacerId = null;
195
120
  }
196
121
  }
197
122
  // Step 5: Build final pane list (real panes + spacer if exists)
198
- let finalContentPanes = spacerId
199
- ? [...realContentPanes, spacerId]
200
- : realContentPanes;
123
+ let finalContentPanes = spacerId ? [...realContentPanes, spacerId] : realContentPanes;
201
124
  // CRITICAL: Sort panes by tmux index, then put spacer LAST
202
125
  // Tmux applies layout geometry by pane index order!
203
126
  const paneIndices = new Map();
204
127
  try {
205
- const output = execSync(`tmux list-panes -F '#{pane_index} #{pane_id}'`, {
206
- encoding: 'utf-8',
207
- stdio: 'pipe'
208
- }).trim();
209
- output.split('\n').forEach(line => {
210
- const [index, id] = line.split(' ');
211
- if (id)
212
- paneIndices.set(id, parseInt(index));
128
+ const tmuxService = TmuxService.getInstance();
129
+ // Get pane index from tmux (pane_index format variable)
130
+ const indexOutput = tmuxService.listPanesSync('#{pane_id}=#{pane_index}');
131
+ const indexLines = indexOutput.split('\n').filter(l => l.trim());
132
+ indexLines.forEach(line => {
133
+ const [paneId, indexStr] = line.split('=');
134
+ if (paneId && indexStr) {
135
+ paneIndices.set(paneId, parseInt(indexStr, 10));
136
+ }
213
137
  });
214
138
  // Sort by index, but force spacer to the end
215
139
  finalContentPanes = finalContentPanes.sort((a, b) => {
@@ -223,278 +147,133 @@ export function recalculateAndApplyLayout(controlPaneId, contentPaneIds, termina
223
147
  const indexB = paneIndices.get(b) || 0;
224
148
  return indexA - indexB;
225
149
  });
226
- LogService.getInstance().debug(`Pane order sorted by index: ${finalContentPanes.map(p => `${p}(idx:${paneIndices.get(p)})`).join(', ')}`, "Layout");
150
+ // LogService.getInstance().debug(
151
+ // `Pane order sorted by index: ${finalContentPanes.map(p => `${p}(idx:${paneIndices.get(p)})`).join(', ')}`,
152
+ // 'Layout'
153
+ // );
227
154
  }
228
155
  catch (err) {
229
- LogService.getInstance().debug(`Failed to sort by index: ${err}`, "Layout");
156
+ // LogService.getInstance().debug(`Failed to sort by index: ${err}`, 'Layout');
230
157
  }
231
158
  // Step 6: Recalculate layout with spacer included if present
232
159
  const finalLayout = spacerId
233
- ? calculateOptimalLayout(finalContentPanes.length, terminalWidth, terminalHeight, config)
160
+ ? calculator.calculateOptimalLayout(finalContentPanes.length, terminalWidth, terminalHeight)
234
161
  : layout;
235
- // Log current tmux state before applying layout
236
- try {
237
- const currentPanes = execSync('tmux list-panes -F "#{pane_id} #{pane_width}x#{pane_height} @#{pane_left},#{pane_top}"', {
238
- encoding: 'utf-8',
239
- stdio: 'pipe'
240
- }).trim();
241
- LogService.getInstance().debug(`Current pane positions before layout:\n${currentPanes}`, "Layout");
242
- }
243
- catch { }
162
+ // Log current tmux state before applying layout (commented out to reduce noise)
163
+ // try {
164
+ // const tmuxService = TmuxService.getInstance();
165
+ // const positions = tmuxService.getPanePositionsSync();
166
+ // const positionsStr = positions.map(p =>
167
+ // `${p.paneId} ${p.width}x${p.height} @${p.left},${p.top}`
168
+ // ).join('\n');
169
+ // LogService.getInstance().debug(`Current pane positions before layout:\n${positionsStr}`, 'Layout');
170
+ // } catch {}
244
171
  // CRITICAL ORDER: Resize sidebar FIRST (before window), then window
245
172
  // This prevents tmux from redistributing window width changes to the sidebar
246
- // Step 1: Check sidebar width and resize if needed
247
- // Do this BEFORE window resize to lock sidebar width
248
- let sidebarResized = false;
173
+ // Step 7: Find and verify the actual control pane
174
+ // The control pane ID may change after layout operations, so we need to find it by position
175
+ const tmuxService = TmuxService.getInstance();
176
+ let actualControlPaneId = controlPaneId;
249
177
  try {
250
- const currentSidebarWidth = execSync(`tmux display-message -t '${controlPaneId}' -p '#{pane_width}'`, { encoding: 'utf-8', stdio: 'pipe' }).trim();
251
- if (currentSidebarWidth !== String(config.SIDEBAR_WIDTH)) {
252
- LogService.getInstance().debug(`Resizing sidebar: ${currentSidebarWidth} → ${config.SIDEBAR_WIDTH}`, "Layout");
253
- execSync(`tmux resize-pane -t '${controlPaneId}' -x ${config.SIDEBAR_WIDTH}`, { stdio: "pipe" });
254
- sidebarResized = true;
255
- // Wait for tmux to settle after sidebar resize
256
- try {
257
- execSync("sleep 0.1", { stdio: "pipe" });
178
+ // First, verify the provided controlPaneId still exists
179
+ await tmuxService.paneExists(controlPaneId);
180
+ }
181
+ catch {
182
+ // Control pane ID is stale, find it by position (leftmost pane at x=0)
183
+ // Use the smallest pane at x=0 as the sidebar (allows for slight width variations)
184
+ try {
185
+ const positions = tmuxService.getPanePositionsSync();
186
+ let smallestPaneAtLeft = null;
187
+ for (const pos of positions) {
188
+ // Find the smallest pane at x=0 (likely the sidebar)
189
+ if (pos.left === 0 && (!smallestPaneAtLeft || pos.width < smallestPaneAtLeft.width)) {
190
+ smallestPaneAtLeft = { id: pos.paneId, width: pos.width };
191
+ }
192
+ }
193
+ if (smallestPaneAtLeft) {
194
+ actualControlPaneId = smallestPaneAtLeft.id;
195
+ // LogService.getInstance().debug(
196
+ // `Control pane ID updated: ${controlPaneId} → ${actualControlPaneId} (width: ${smallestPaneAtLeft.width})`,
197
+ // 'Layout'
198
+ // );
258
199
  }
259
- catch { }
260
200
  }
261
- else {
262
- LogService.getInstance().debug(`Sidebar width already correct: ${config.SIDEBAR_WIDTH}`, "Layout");
201
+ catch (findError) {
202
+ // LogService.getInstance().debug(`Failed to find control pane by position: ${findError}`, 'Layout');
263
203
  }
264
204
  }
265
- catch (error) {
266
- LogService.getInstance().debug(`Failed to check/resize sidebar: ${error}`, "Layout");
267
- }
268
- // Step 2: Check window dimensions and resize if needed
205
+ // Step 8: Check sidebar width (but DON'T resize yet)
206
+ // We'll let the layout application handle the sizing to avoid pane swapping
207
+ // Commented out to reduce log noise
208
+ // try {
209
+ // const currentSidebarWidth = tmuxService.getPaneWidthSync(actualControlPaneId);
210
+ //
211
+ // if (currentSidebarWidth !== config.SIDEBAR_WIDTH) {
212
+ // LogService.getInstance().debug(
213
+ // `Sidebar width mismatch: ${currentSidebarWidth} (current) vs ${config.SIDEBAR_WIDTH} (target), will fix via layout`,
214
+ // 'Layout'
215
+ // );
216
+ // } else {
217
+ // LogService.getInstance().debug(`Sidebar width already correct: ${config.SIDEBAR_WIDTH}`, 'Layout');
218
+ // }
219
+ // } catch (error) {
220
+ // LogService.getInstance().debug(`Failed to check sidebar width: ${error}`, 'Layout');
221
+ // }
222
+ // Step 8: Check window dimensions and resize if needed
269
223
  // Do this AFTER sidebar resize so sidebar width is locked
270
224
  const currentWindowDims = getWindowDimensions();
225
+ // Calculate target window height (accounting for status bar)
226
+ const statusBarHeight = tmuxService.getStatusBarHeightSync();
227
+ const targetWindowHeight = terminalHeight - statusBarHeight;
271
228
  const needsWindowResize = currentWindowDims.width !== finalLayout.windowWidth ||
272
- currentWindowDims.height !== terminalHeight;
229
+ currentWindowDims.height !== targetWindowHeight;
273
230
  if (needsWindowResize) {
274
- LogService.getInstance().debug(`Resizing window: ${currentWindowDims.width}x${currentWindowDims.height} → ${finalLayout.windowWidth}x${terminalHeight}`, "Layout");
275
- setWindowDimensions(finalLayout.windowWidth, terminalHeight);
231
+ // LogService.getInstance().debug(
232
+ // `Resizing window: ${currentWindowDims.width}x${currentWindowDims.height} → ${finalLayout.windowWidth}x${targetWindowHeight}`,
233
+ // 'Layout'
234
+ // );
235
+ layoutApplier.setWindowDimensions(finalLayout.windowWidth, terminalHeight);
276
236
  // Wait for tmux to complete the window resize
277
- try {
278
- execSync("sleep 0.05", { stdio: "pipe" });
279
- }
280
- catch { }
281
- // CRITICAL: Re-enforce sidebar width after window resize!
282
- // Window resizes cause tmux to redistribute width changes to ALL panes including sidebar
283
- try {
284
- const sidebarWidthAfterResize = execSync(`tmux display-message -t '${controlPaneId}' -p '#{pane_width}'`, { encoding: 'utf-8', stdio: 'pipe' }).trim();
285
- if (sidebarWidthAfterResize !== String(config.SIDEBAR_WIDTH)) {
286
- LogService.getInstance().debug(`Sidebar changed after window resize: ${sidebarWidthAfterResize} → ${config.SIDEBAR_WIDTH}, fixing`, "Layout");
287
- execSync(`tmux resize-pane -t '${controlPaneId}' -x ${config.SIDEBAR_WIDTH}`, { stdio: "pipe" });
288
- // Wait for tmux to settle
289
- try {
290
- execSync("sleep 0.1", { stdio: "pipe" });
291
- }
292
- catch { }
293
- }
294
- }
295
- catch (error) {
296
- LogService.getInstance().debug(`Failed to re-check sidebar after window resize: ${error}`, "Layout");
297
- }
237
+ await new Promise(resolve => setTimeout(resolve, TMUX_PANE_CREATION_DELAY));
238
+ // Note: We don't re-enforce sidebar width here anymore
239
+ // The layout application below will set the correct dimensions for all panes
298
240
  }
299
241
  else {
300
- LogService.getInstance().debug(`Window dimensions already correct: ${finalLayout.windowWidth}x${terminalHeight}`, "Layout");
242
+ // LogService.getInstance().debug(
243
+ // `Window dimensions already correct: ${finalLayout.windowWidth}x${terminalHeight}`,
244
+ // 'Layout'
245
+ // );
301
246
  }
302
- // Log window state after sidebar enforcement
303
- try {
304
- const windowInfo = execSync('tmux display-message -p "Window: #{window_width}x#{window_height}, Layout: #{window_layout}"', {
305
- encoding: 'utf-8',
306
- stdio: 'pipe'
307
- }).trim();
308
- LogService.getInstance().debug(`After sidebar enforcement: ${windowInfo}`, "Layout");
309
- }
310
- catch { }
311
- applyPaneLayout(controlPaneId, finalContentPanes, finalLayout, terminalHeight, config);
247
+ // Log window state after sidebar enforcement (commented out to reduce noise)
248
+ // try {
249
+ // const windowDims = tmuxService.getWindowDimensionsSync();
250
+ // const layout = tmuxService.getCurrentLayoutSync();
251
+ // LogService.getInstance().debug(
252
+ // `After sidebar enforcement: Window: ${windowDims.width}x${windowDims.height}, Layout: ${layout}`,
253
+ // 'Layout'
254
+ // );
255
+ // } catch {}
256
+ // Step 9: Apply the layout to tmux
257
+ layoutApplier.applyPaneLayout(actualControlPaneId, finalContentPanes, finalLayout, terminalHeight);
312
258
  }
313
259
  /**
314
260
  * Calculates optimal layout configuration based on terminal dimensions
315
- * Prioritizes columns over rows for maximum horizontal space usage
261
+ * Maintained for backward compatibility - delegates to LayoutCalculator
262
+ *
263
+ * @deprecated Use LayoutCalculator class directly for better testability
316
264
  */
317
265
  export function calculateOptimalLayout(numContentPanes, terminalWidth, terminalHeight, config = DEFAULT_LAYOUT_CONFIG) {
318
- const { SIDEBAR_WIDTH, MIN_COMFORTABLE_WIDTH, MAX_COMFORTABLE_WIDTH, MIN_COMFORTABLE_HEIGHT, } = config;
319
- // Special case: welcome pane or no panes
320
- if (numContentPanes === 0) {
321
- return {
322
- cols: 0,
323
- rows: 0,
324
- windowWidth: terminalWidth, // Unlimited width for welcome pane
325
- paneDistribution: [],
326
- actualPaneWidth: 0,
327
- };
328
- }
329
- // Try all column counts and score them to find the best layout
330
- let bestLayout = null;
331
- let bestScore = -1;
332
- for (let cols = numContentPanes; cols >= 1; cols--) {
333
- const rows = Math.ceil(numContentPanes / cols);
334
- const columnBorders = cols - 1; // Vertical borders between columns
335
- const rowBorders = rows - 1; // Horizontal borders between rows
336
- // Calculate minimum required dimensions (can we fit at MIN width?)
337
- const minRequiredWidth = SIDEBAR_WIDTH + cols * MIN_COMFORTABLE_WIDTH + columnBorders;
338
- const minRequiredHeight = rows * MIN_COMFORTABLE_HEIGHT + rowBorders;
339
- // Check if this layout fits in terminal at minimum comfortable size
340
- if (minRequiredWidth <= terminalWidth &&
341
- minRequiredHeight <= terminalHeight) {
342
- // This layout fits! Now calculate actual pane dimensions
343
- // Calculate ideal window max-width (cap each pane at MAX_COMFORTABLE_WIDTH)
344
- // Window should be: sidebar + (columns * MAX width) + borders OR terminal width, whichever is smaller
345
- const idealMaxWidth = SIDEBAR_WIDTH + cols * MAX_COMFORTABLE_WIDTH + columnBorders;
346
- const windowWidth = Math.min(idealMaxWidth, terminalWidth);
347
- // Calculate actual pane width using the constrained windowWidth (not terminalWidth)
348
- // This ensures panes don't exceed MAX_COMFORTABLE_WIDTH
349
- const effectiveContentWidth = windowWidth - SIDEBAR_WIDTH - columnBorders;
350
- const actualPaneWidth = effectiveContentWidth / cols;
351
- // Calculate pane distribution for spanning (e.g., [2, 1, 1, 1])
352
- const distribution = distributePanes(numContentPanes, cols);
353
- // Calculate pane height
354
- const availableHeight = terminalHeight - rowBorders;
355
- const paneHeight = Math.floor(availableHeight / rows);
356
- // Score this layout (higher is better)
357
- // Prefer layouts that:
358
- // 1. Have more vertical space (bigger height)
359
- // 2. Are more balanced (fewer rows, but not too wide)
360
- // 3. Don't have a single pane in the last row
361
- const panesInLastRow = (numContentPanes % cols) || cols;
362
- const balanceScore = panesInLastRow === 1 ? 0.5 : 1.0; // Penalize single pane in last row
363
- const heightScore = paneHeight / terminalHeight; // More vertical space is better
364
- const widthScore = actualPaneWidth <= MAX_COMFORTABLE_WIDTH ? 1.0 : 0.8; // Prefer panes within comfortable width
365
- const score = balanceScore * heightScore * widthScore;
366
- LogService.getInstance().debug(`Layout option: ${cols} cols x ${rows} rows, paneHeight=${paneHeight}, score=${score.toFixed(3)}`, "Layout");
367
- // Update best if this score is higher, OR if tied but with fewer columns (more width per pane)
368
- const isBetter = score > bestScore || (score === bestScore && cols < (bestLayout?.cols || Infinity));
369
- if (isBetter) {
370
- bestScore = score;
371
- bestLayout = {
372
- cols,
373
- rows,
374
- windowWidth,
375
- paneDistribution: distribution,
376
- actualPaneWidth,
377
- };
378
- }
379
- }
380
- }
381
- // Return the best layout we found
382
- if (bestLayout) {
383
- LogService.getInstance().debug(`Best layout: ${numContentPanes} panes → ${bestLayout.cols} cols x ${bestLayout.rows} rows, window=${bestLayout.windowWidth}, paneWidth=${bestLayout.actualPaneWidth}`, "Layout");
384
- return bestLayout;
385
- }
386
- // Ultimate fallback: single column (forced cramped layout if terminal too small)
387
- return {
388
- cols: 1,
389
- rows: numContentPanes,
390
- windowWidth: terminalWidth,
391
- paneDistribution: [numContentPanes],
392
- actualPaneWidth: terminalWidth - SIDEBAR_WIDTH,
393
- };
266
+ const calculator = new LayoutCalculator(config);
267
+ return calculator.calculateOptimalLayout(numContentPanes, terminalWidth, terminalHeight);
394
268
  }
395
269
  /**
396
270
  * Distributes panes as evenly as possible across columns
397
- * Examples:
398
- * 5 panes, 3 cols → [2, 2, 1] (first 2 columns get extra pane)
399
- * 5 panes, 4 cols [2, 1, 1, 1] (first column gets extra pane)
400
- * 6 panes, 3 cols → [2, 2, 2] (perfectly even)
271
+ * Maintained for backward compatibility - delegates to LayoutCalculator
272
+ *
273
+ * @deprecated Use LayoutCalculator class directly for better testability
401
274
  */
402
275
  export function distributePanes(numPanes, cols) {
403
- const distribution = [];
404
- const basePerCol = Math.floor(numPanes / cols);
405
- const remainder = numPanes % cols;
406
- for (let i = 0; i < cols; i++) {
407
- // First 'remainder' columns get an extra pane
408
- distribution.push(basePerCol + (i < remainder ? 1 : 0));
409
- }
410
- return distribution;
411
- }
412
- /**
413
- * Sets window dimensions using tmux resize-window
414
- * Constrains width (for max-width behavior) while letting height follow terminal
415
- */
416
- function setWindowDimensions(width, height) {
417
- try {
418
- // Use manual mode to constrain width, but also set height to match terminal
419
- execSync(`tmux set-window-option window-size manual`, { stdio: "pipe" });
420
- execSync(`tmux resize-window -x ${width} -y ${height}`, { stdio: "pipe" });
421
- }
422
- catch (error) {
423
- // Log but don't fail - some tmux versions may not support this
424
- LogService.getInstance().warn(`Could not set window dimensions to ${width}x${height}: ${error}`, "Layout");
425
- }
426
- }
427
- /**
428
- * Applies the calculated layout to tmux panes
429
- * Unified approach: trust the layout calculation for all cases
430
- */
431
- function applyPaneLayout(controlPaneId, contentPaneIds, layout, terminalHeight, config) {
432
- const numContentPanes = contentPaneIds.length;
433
- if (numContentPanes === 0) {
434
- // No content panes, just resize sidebar
435
- try {
436
- execSync(`tmux resize-pane -t '${controlPaneId}' -x ${config.SIDEBAR_WIDTH}`, { stdio: "pipe" });
437
- }
438
- catch (error) {
439
- LogService.getInstance().error("Error resizing control pane", "Layout", undefined, error instanceof Error ? error : undefined);
440
- }
441
- return;
442
- }
443
- try {
444
- // Always use custom layout string generation - unified approach for all cases
445
- // Use the calculated window dimensions, not current tmux dimensions (may be stale)
446
- const layoutString = generateSidebarGridLayout(controlPaneId, contentPaneIds, config.SIDEBAR_WIDTH, layout.windowWidth, terminalHeight, layout.cols, config.MAX_COMFORTABLE_WIDTH);
447
- if (layoutString) {
448
- // Log pane state right before applying layout
449
- try {
450
- const paneList = execSync('tmux list-panes -F "#{pane_id}=#{pane_index}"', {
451
- encoding: 'utf-8',
452
- stdio: 'pipe'
453
- }).trim();
454
- LogService.getInstance().debug(`Panes right before layout apply: ${paneList}`, "Layout");
455
- }
456
- catch { }
457
- try {
458
- execSync(`tmux select-layout '${layoutString}'`, { stdio: "pipe" });
459
- LogService.getInstance().debug("Layout string applied successfully", "Layout");
460
- }
461
- catch (layoutError) {
462
- // Log the error for debugging
463
- const errorMsg = layoutError?.message || String(layoutError);
464
- LogService.getInstance().debug(`Layout string application failed: ${errorMsg}`, "Layout");
465
- LogService.getInstance().debug(`Failed layout string: ${layoutString}`, "Layout");
466
- // Fallback to main-vertical if custom layout fails
467
- execSync(`tmux set-window-option main-pane-width ${config.SIDEBAR_WIDTH}`, { stdio: "pipe" });
468
- execSync("tmux select-layout main-vertical", { stdio: "pipe" });
469
- LogService.getInstance().debug("Fell back to main-vertical layout", "Layout");
470
- }
471
- }
472
- else {
473
- // Empty layout string - fallback to main-vertical
474
- LogService.getInstance().debug("Empty layout string, using main-vertical fallback", "Layout");
475
- execSync(`tmux set-window-option main-pane-width ${config.SIDEBAR_WIDTH}`, { stdio: "pipe" });
476
- execSync("tmux select-layout main-vertical", { stdio: "pipe" });
477
- }
478
- }
479
- catch (error) {
480
- // Fallback: just resize sidebar
481
- try {
482
- execSync(`tmux resize-pane -t '${controlPaneId}' -x ${config.SIDEBAR_WIDTH}`, { stdio: "pipe" });
483
- }
484
- catch {
485
- // Ignore
486
- }
487
- }
488
- }
489
- /**
490
- * Generates a custom tmux layout string with pane spanning support
491
- * This is a complex function that will be fully implemented in Phase 8
492
- */
493
- function generateLayoutString(controlPaneId, contentPanes, layout, config) {
494
- // TODO: Implement custom layout string generation
495
- // This will create layout strings like:
496
- // "layout-string,40x24,0,0{20x24,0,0,1,19x24,21,0[19x12,21,0,2,19x11,21,13,3]}"
497
- // For now, return empty string to use default layout
498
- return "";
276
+ const calculator = new LayoutCalculator(DEFAULT_LAYOUT_CONFIG);
277
+ return calculator.distributePanes(numPanes, cols);
499
278
  }
500
279
  //# sourceMappingURL=layoutManager.js.map