dmux 3.3.1 → 3.5.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 (66) hide show
  1. package/dist/actions/implementations/closeAction.d.ts.map +1 -1
  2. package/dist/actions/implementations/closeAction.js +22 -6
  3. package/dist/actions/implementations/closeAction.js.map +1 -1
  4. package/dist/actions/implementations/mergeAction.d.ts +3 -1
  5. package/dist/actions/implementations/mergeAction.d.ts.map +1 -1
  6. package/dist/actions/implementations/mergeAction.js +38 -4
  7. package/dist/actions/implementations/mergeAction.js.map +1 -1
  8. package/dist/actions/merge/multiMergeOrchestrator.d.ts +22 -0
  9. package/dist/actions/merge/multiMergeOrchestrator.d.ts.map +1 -0
  10. package/dist/actions/merge/multiMergeOrchestrator.js +452 -0
  11. package/dist/actions/merge/multiMergeOrchestrator.js.map +1 -0
  12. package/dist/actions/merge/types.d.ts +62 -0
  13. package/dist/actions/merge/types.d.ts.map +1 -0
  14. package/dist/actions/merge/types.js +7 -0
  15. package/dist/actions/merge/types.js.map +1 -0
  16. package/dist/chunks/styles.css_vue_type_style_index_0_src_true_lang-pW5mq51o.js +17 -0
  17. package/dist/components/popups/logsPopup.js +33 -17
  18. package/dist/components/popups/logsPopup.js.map +1 -1
  19. package/dist/dashboard.html +2 -2
  20. package/dist/dashboard.js +2 -2
  21. package/dist/hooks/useLayoutManagement.d.ts.map +1 -1
  22. package/dist/hooks/useLayoutManagement.js +43 -14
  23. package/dist/hooks/useLayoutManagement.js.map +1 -1
  24. package/dist/hooks/usePaneLoading.d.ts +3 -0
  25. package/dist/hooks/usePaneLoading.d.ts.map +1 -1
  26. package/dist/hooks/usePaneLoading.js +21 -1
  27. package/dist/hooks/usePaneLoading.js.map +1 -1
  28. package/dist/hooks/usePaneSync.d.ts +3 -0
  29. package/dist/hooks/usePaneSync.d.ts.map +1 -1
  30. package/dist/hooks/usePaneSync.js +11 -0
  31. package/dist/hooks/usePaneSync.js.map +1 -1
  32. package/dist/layout/TmuxLayoutApplier.d.ts.map +1 -1
  33. package/dist/layout/TmuxLayoutApplier.js +4 -9
  34. package/dist/layout/TmuxLayoutApplier.js.map +1 -1
  35. package/dist/server/embedded-assets.d.ts.map +1 -1
  36. package/dist/server/embedded-assets.js +26 -37
  37. package/dist/server/embedded-assets.js.map +1 -1
  38. package/dist/services/PaneAnalyzer.d.ts +12 -3
  39. package/dist/services/PaneAnalyzer.d.ts.map +1 -1
  40. package/dist/services/PaneAnalyzer.js +57 -8
  41. package/dist/services/PaneAnalyzer.js.map +1 -1
  42. package/dist/services/PopupManager.d.ts.map +1 -1
  43. package/dist/services/PopupManager.js +7 -1
  44. package/dist/services/PopupManager.js.map +1 -1
  45. package/dist/services/StatusDetector.d.ts.map +1 -1
  46. package/dist/services/StatusDetector.js +28 -9
  47. package/dist/services/StatusDetector.js.map +1 -1
  48. package/dist/services/TmuxService.d.ts +9 -3
  49. package/dist/services/TmuxService.d.ts.map +1 -1
  50. package/dist/services/TmuxService.js +12 -3
  51. package/dist/services/TmuxService.js.map +1 -1
  52. package/dist/terminal.html +2 -2
  53. package/dist/terminal.js +3 -3
  54. package/dist/utils/generated-agents-doc.d.ts +1 -1
  55. package/dist/utils/generated-agents-doc.js +1 -1
  56. package/dist/utils/hooksDocs.d.ts +1 -1
  57. package/dist/utils/layoutManager.d.ts.map +1 -1
  58. package/dist/utils/layoutManager.js +226 -202
  59. package/dist/utils/layoutManager.js.map +1 -1
  60. package/dist/utils/worktreeDiscovery.d.ts +39 -0
  61. package/dist/utils/worktreeDiscovery.d.ts.map +1 -0
  62. package/dist/utils/worktreeDiscovery.js +241 -0
  63. package/dist/utils/worktreeDiscovery.js.map +1 -0
  64. package/package.json +7 -7
  65. package/dist/chunks/_plugin-vue_export-helper-Cvoq67hi.js +0 -28
  66. /package/dist/{_plugin-vue_export-helper.css → styles.css} +0 -0
@@ -36,225 +36,249 @@ let lastLayoutDimensions = null;
36
36
  * 9. Apply layout to tmux
37
37
  */
38
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);
43
- // Step 1: Filter out any existing spacer from content panes
44
- const existingSpacerId = spacerManager.findSpacerPane();
45
- const realContentPanes = contentPaneIds.filter(id => id !== existingSpacerId);
46
- // Check if dimensions and pane count have changed since last layout
47
- const dimensionsUnchanged = lastLayoutDimensions &&
48
- lastLayoutDimensions.width === terminalWidth &&
49
- lastLayoutDimensions.height === terminalHeight &&
50
- lastLayoutDimensions.paneCount === realContentPanes.length;
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');
55
- return;
56
- }
57
- LogService.getInstance().debug(`Dimensions changed, applying layout: ${terminalWidth}x${terminalHeight}, ${realContentPanes.length} panes`, 'ResizeDebug');
58
- // Update last layout dimensions
59
- lastLayoutDimensions = {
60
- width: terminalWidth,
61
- height: terminalHeight,
62
- paneCount: realContentPanes.length,
63
- };
64
- // Step 2: Calculate layout for real content panes only
65
- const layout = calculator.calculateOptimalLayout(realContentPanes.length, terminalWidth, terminalHeight);
66
- // Step 3: Determine if we need a spacer pane
67
- const needsSpacer = spacerManager.needsSpacerPane(realContentPanes.length, layout);
68
- // Step 4: Manage spacer pane creation/destruction
69
- // ALWAYS destroy existing spacer on layout recalc to ensure fresh positioning
70
- let spacerId = null;
71
- // LogService.getInstance().debug(
72
- // `Spacer management: needs=${needsSpacer}, existing=${existingSpacerId || 'none'}`,
73
- // 'Layout'
74
- // );
75
- // Destroy existing spacer if present (we'll recreate if needed)
76
- if (existingSpacerId) {
77
- // LogService.getInstance().debug(`Destroying existing spacer for recreation: ${existingSpacerId}`, 'Layout');
78
- spacerManager.destroySpacerPane(existingSpacerId);
79
- }
80
- // Create new spacer if needed
81
- if (needsSpacer) {
39
+ // Wrap entire function in try-catch to prevent crashes during resize
40
+ try {
41
+ // Validate inputs to prevent crashes from bad data
42
+ if (!controlPaneId || typeof controlPaneId !== 'string') {
43
+ LogService.getInstance().warn('Invalid controlPaneId, skipping layout', 'Layout');
44
+ return;
45
+ }
46
+ if (terminalWidth <= 0 || terminalHeight <= 0) {
47
+ LogService.getInstance().warn(`Invalid terminal dimensions: ${terminalWidth}x${terminalHeight}, skipping layout`, 'Layout');
48
+ return;
49
+ }
50
+ // Create class instances with config
51
+ const calculator = new LayoutCalculator(config);
52
+ const spacerManager = new SpacerManager(config);
53
+ const layoutApplier = new TmuxLayoutApplier(config);
54
+ // Step 1: Filter out any existing spacer from content panes
55
+ let existingSpacerId = null;
82
56
  try {
83
- const lastContentPaneId = realContentPanes[realContentPanes.length - 1];
84
- if (!lastContentPaneId) {
85
- throw new Error('No content panes available to split from');
86
- }
87
- spacerId = spacerManager.createSpacerPane(lastContentPaneId);
88
- // LogService.getInstance().debug(`Created fresh spacer pane: ${spacerId}`, 'Layout');
89
- // CRITICAL: Wait for tmux to fully register the new pane before applying layout
90
- await new Promise(resolve => setTimeout(resolve, TMUX_PANE_CREATION_DELAY));
91
- // Verify the pane appears in list-panes output
92
- const tmuxService = TmuxService.getInstance();
93
- let paneVerified = false;
94
- for (let attempts = 0; attempts < 3; attempts++) {
95
- try {
96
- const allPaneIds = tmuxService.getAllPaneIdsSync();
97
- if (allPaneIds.includes(spacerId)) {
98
- paneVerified = true;
99
- // LogService.getInstance().debug(
100
- // `Verified spacer pane ${spacerId} in list-panes (attempt ${attempts + 1})`,
101
- // 'Layout'
102
- // );
103
- break;
57
+ existingSpacerId = spacerManager.findSpacerPane();
58
+ }
59
+ catch (error) {
60
+ LogService.getInstance().debug(`Failed to find spacer pane: ${error}`, 'Layout');
61
+ }
62
+ const realContentPanes = contentPaneIds.filter(id => id !== existingSpacerId);
63
+ // Check if dimensions and pane count have changed since last layout
64
+ const dimensionsUnchanged = lastLayoutDimensions &&
65
+ lastLayoutDimensions.width === terminalWidth &&
66
+ lastLayoutDimensions.height === terminalHeight &&
67
+ lastLayoutDimensions.paneCount === realContentPanes.length;
68
+ if (dimensionsUnchanged) {
69
+ // Layout unchanged - skip ALL layout operations to prevent Ink redraw
70
+ // This prevents the dmux UI from being cleared on resize when nothing changed
71
+ // (Removed noisy debug log that fires on every check)
72
+ return;
73
+ }
74
+ // Only log when dimensions actually change (much less noisy)
75
+ LogService.getInstance().info(`Layout dimensions changed: ${terminalWidth}x${terminalHeight}, ${realContentPanes.length} panes`, 'layout');
76
+ // Update last layout dimensions
77
+ lastLayoutDimensions = {
78
+ width: terminalWidth,
79
+ height: terminalHeight,
80
+ paneCount: realContentPanes.length,
81
+ };
82
+ // Step 2: Calculate layout for real content panes only
83
+ const layout = calculator.calculateOptimalLayout(realContentPanes.length, terminalWidth, terminalHeight);
84
+ // Step 3: Determine if we need a spacer pane
85
+ const needsSpacer = spacerManager.needsSpacerPane(realContentPanes.length, layout);
86
+ // Step 4: Manage spacer pane creation/destruction
87
+ // ALWAYS destroy existing spacer on layout recalc to ensure fresh positioning
88
+ let spacerId = null;
89
+ // LogService.getInstance().debug(
90
+ // `Spacer management: needs=${needsSpacer}, existing=${existingSpacerId || 'none'}`,
91
+ // 'Layout'
92
+ // );
93
+ // Destroy existing spacer if present (we'll recreate if needed)
94
+ if (existingSpacerId) {
95
+ // LogService.getInstance().debug(`Destroying existing spacer for recreation: ${existingSpacerId}`, 'Layout');
96
+ spacerManager.destroySpacerPane(existingSpacerId);
97
+ }
98
+ // Create new spacer if needed
99
+ if (needsSpacer) {
100
+ try {
101
+ const lastContentPaneId = realContentPanes[realContentPanes.length - 1];
102
+ if (!lastContentPaneId) {
103
+ throw new Error('No content panes available to split from');
104
+ }
105
+ spacerId = spacerManager.createSpacerPane(lastContentPaneId);
106
+ // LogService.getInstance().debug(`Created fresh spacer pane: ${spacerId}`, 'Layout');
107
+ // CRITICAL: Wait for tmux to fully register the new pane before applying layout
108
+ await new Promise(resolve => setTimeout(resolve, TMUX_PANE_CREATION_DELAY));
109
+ // Verify the pane appears in list-panes output
110
+ const tmuxService = TmuxService.getInstance();
111
+ let paneVerified = false;
112
+ for (let attempts = 0; attempts < 3; attempts++) {
113
+ try {
114
+ const allPaneIds = tmuxService.getAllPaneIdsSync();
115
+ if (allPaneIds.includes(spacerId)) {
116
+ paneVerified = true;
117
+ // LogService.getInstance().debug(
118
+ // `Verified spacer pane ${spacerId} in list-panes (attempt ${attempts + 1})`,
119
+ // 'Layout'
120
+ // );
121
+ break;
122
+ }
123
+ }
124
+ catch {
125
+ // Pane not ready yet, wait a bit
126
+ if (attempts < 2)
127
+ await new Promise(resolve => setTimeout(resolve, TMUX_PANE_CREATION_DELAY));
104
128
  }
105
129
  }
106
- catch {
107
- // Pane not ready yet, wait a bit
108
- if (attempts < 2)
109
- await new Promise(resolve => setTimeout(resolve, TMUX_PANE_CREATION_DELAY));
130
+ if (!paneVerified) {
131
+ LogService.getInstance().warn(`Spacer pane ${spacerId} not verified, continuing anyway`, 'Layout');
132
+ // Don't throw - continue and let it fail with better logs
110
133
  }
111
134
  }
112
- if (!paneVerified) {
113
- LogService.getInstance().warn(`Spacer pane ${spacerId} not verified, continuing anyway`, 'Layout');
114
- // Don't throw - continue and let it fail with better logs
135
+ catch (error) {
136
+ // LogService.getInstance().debug(`Continuing without spacer pane: ${error}`, 'Layout');
137
+ spacerId = null;
115
138
  }
116
139
  }
117
- catch (error) {
118
- // LogService.getInstance().debug(`Continuing without spacer pane: ${error}`, 'Layout');
119
- spacerId = null;
140
+ // Step 5: Build final pane list (real panes + spacer if exists)
141
+ let finalContentPanes = spacerId ? [...realContentPanes, spacerId] : realContentPanes;
142
+ // CRITICAL: Sort panes by tmux index, then put spacer LAST
143
+ // Tmux applies layout geometry by pane index order!
144
+ const paneIndices = new Map();
145
+ try {
146
+ const tmuxService = TmuxService.getInstance();
147
+ // Get pane index from tmux (pane_index format variable)
148
+ const indexOutput = tmuxService.listPanesSync('#{pane_id}=#{pane_index}');
149
+ const indexLines = indexOutput.split('\n').filter(l => l.trim());
150
+ indexLines.forEach(line => {
151
+ const [paneId, indexStr] = line.split('=');
152
+ if (paneId && indexStr) {
153
+ paneIndices.set(paneId, parseInt(indexStr, 10));
154
+ }
155
+ });
156
+ // Sort by index, but force spacer to the end
157
+ finalContentPanes = finalContentPanes.sort((a, b) => {
158
+ // Spacer always last
159
+ if (a === spacerId)
160
+ return 1;
161
+ if (b === spacerId)
162
+ return -1;
163
+ // Otherwise sort by tmux index
164
+ const indexA = paneIndices.get(a) || 0;
165
+ const indexB = paneIndices.get(b) || 0;
166
+ return indexA - indexB;
167
+ });
168
+ // LogService.getInstance().debug(
169
+ // `Pane order sorted by index: ${finalContentPanes.map(p => `${p}(idx:${paneIndices.get(p)})`).join(', ')}`,
170
+ // 'Layout'
171
+ // );
120
172
  }
121
- }
122
- // Step 5: Build final pane list (real panes + spacer if exists)
123
- let finalContentPanes = spacerId ? [...realContentPanes, spacerId] : realContentPanes;
124
- // CRITICAL: Sort panes by tmux index, then put spacer LAST
125
- // Tmux applies layout geometry by pane index order!
126
- const paneIndices = new Map();
127
- try {
173
+ catch (err) {
174
+ // LogService.getInstance().debug(`Failed to sort by index: ${err}`, 'Layout');
175
+ }
176
+ // Step 6: Recalculate layout with spacer included if present
177
+ const finalLayout = spacerId
178
+ ? calculator.calculateOptimalLayout(finalContentPanes.length, terminalWidth, terminalHeight)
179
+ : layout;
180
+ // Log current tmux state before applying layout (commented out to reduce noise)
181
+ // try {
182
+ // const tmuxService = TmuxService.getInstance();
183
+ // const positions = tmuxService.getPanePositionsSync();
184
+ // const positionsStr = positions.map(p =>
185
+ // `${p.paneId} ${p.width}x${p.height} @${p.left},${p.top}`
186
+ // ).join('\n');
187
+ // LogService.getInstance().debug(`Current pane positions before layout:\n${positionsStr}`, 'Layout');
188
+ // } catch {}
189
+ // CRITICAL ORDER: Resize sidebar FIRST (before window), then window
190
+ // This prevents tmux from redistributing window width changes to the sidebar
191
+ // Step 7: Find and verify the actual control pane
192
+ // The control pane ID may change after layout operations, so we need to find it by position
128
193
  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
- }
137
- });
138
- // Sort by index, but force spacer to the end
139
- finalContentPanes = finalContentPanes.sort((a, b) => {
140
- // Spacer always last
141
- if (a === spacerId)
142
- return 1;
143
- if (b === spacerId)
144
- return -1;
145
- // Otherwise sort by tmux index
146
- const indexA = paneIndices.get(a) || 0;
147
- const indexB = paneIndices.get(b) || 0;
148
- return indexA - indexB;
149
- });
150
- // LogService.getInstance().debug(
151
- // `Pane order sorted by index: ${finalContentPanes.map(p => `${p}(idx:${paneIndices.get(p)})`).join(', ')}`,
152
- // 'Layout'
153
- // );
154
- }
155
- catch (err) {
156
- // LogService.getInstance().debug(`Failed to sort by index: ${err}`, 'Layout');
157
- }
158
- // Step 6: Recalculate layout with spacer included if present
159
- const finalLayout = spacerId
160
- ? calculator.calculateOptimalLayout(finalContentPanes.length, terminalWidth, terminalHeight)
161
- : layout;
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 {}
171
- // CRITICAL ORDER: Resize sidebar FIRST (before window), then window
172
- // This prevents tmux from redistributing window width changes to the sidebar
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;
177
- try {
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)
194
+ let actualControlPaneId = controlPaneId;
184
195
  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 };
196
+ // First, verify the provided controlPaneId still exists
197
+ await tmuxService.paneExists(controlPaneId);
198
+ }
199
+ catch {
200
+ // Control pane ID is stale, find it by position (leftmost pane at x=0)
201
+ // Use the smallest pane at x=0 as the sidebar (allows for slight width variations)
202
+ try {
203
+ const positions = tmuxService.getPanePositionsSync();
204
+ let smallestPaneAtLeft = null;
205
+ for (const pos of positions) {
206
+ // Find the smallest pane at x=0 (likely the sidebar)
207
+ if (pos.left === 0 && (!smallestPaneAtLeft || pos.width < smallestPaneAtLeft.width)) {
208
+ smallestPaneAtLeft = { id: pos.paneId, width: pos.width };
209
+ }
210
+ }
211
+ if (smallestPaneAtLeft) {
212
+ actualControlPaneId = smallestPaneAtLeft.id;
213
+ // LogService.getInstance().debug(
214
+ // `Control pane ID updated: ${controlPaneId} → ${actualControlPaneId} (width: ${smallestPaneAtLeft.width})`,
215
+ // 'Layout'
216
+ // );
191
217
  }
192
218
  }
193
- if (smallestPaneAtLeft) {
194
- actualControlPaneId = smallestPaneAtLeft.id;
195
- // LogService.getInstance().debug(
196
- // `Control pane ID updated: ${controlPaneId} → ${actualControlPaneId} (width: ${smallestPaneAtLeft.width})`,
197
- // 'Layout'
198
- // );
219
+ catch (findError) {
220
+ // LogService.getInstance().debug(`Failed to find control pane by position: ${findError}`, 'Layout');
199
221
  }
200
222
  }
201
- catch (findError) {
202
- // LogService.getInstance().debug(`Failed to find control pane by position: ${findError}`, 'Layout');
223
+ // Step 8: Check sidebar width (but DON'T resize yet)
224
+ // We'll let the layout application handle the sizing to avoid pane swapping
225
+ // Commented out to reduce log noise
226
+ // try {
227
+ // const currentSidebarWidth = tmuxService.getPaneWidthSync(actualControlPaneId);
228
+ //
229
+ // if (currentSidebarWidth !== config.SIDEBAR_WIDTH) {
230
+ // LogService.getInstance().debug(
231
+ // `Sidebar width mismatch: ${currentSidebarWidth} (current) vs ${config.SIDEBAR_WIDTH} (target), will fix via layout`,
232
+ // 'Layout'
233
+ // );
234
+ // } else {
235
+ // LogService.getInstance().debug(`Sidebar width already correct: ${config.SIDEBAR_WIDTH}`, 'Layout');
236
+ // }
237
+ // } catch (error) {
238
+ // LogService.getInstance().debug(`Failed to check sidebar width: ${error}`, 'Layout');
239
+ // }
240
+ // Step 8: Check window dimensions and resize if needed
241
+ // Do this AFTER sidebar resize so sidebar width is locked
242
+ const currentWindowDims = getWindowDimensions();
243
+ // Calculate target window height (accounting for status bar)
244
+ const statusBarHeight = tmuxService.getStatusBarHeightSync();
245
+ const targetWindowHeight = terminalHeight - statusBarHeight;
246
+ const needsWindowResize = currentWindowDims.width !== finalLayout.windowWidth ||
247
+ currentWindowDims.height !== targetWindowHeight;
248
+ if (needsWindowResize) {
249
+ // LogService.getInstance().debug(
250
+ // `Resizing window: ${currentWindowDims.width}x${currentWindowDims.height} → ${finalLayout.windowWidth}x${targetWindowHeight}`,
251
+ // 'Layout'
252
+ // );
253
+ layoutApplier.setWindowDimensions(finalLayout.windowWidth, terminalHeight);
254
+ // Wait for tmux to complete the window resize
255
+ await new Promise(resolve => setTimeout(resolve, TMUX_PANE_CREATION_DELAY));
256
+ // Note: We don't re-enforce sidebar width here anymore
257
+ // The layout application below will set the correct dimensions for all panes
203
258
  }
259
+ else {
260
+ // LogService.getInstance().debug(
261
+ // `Window dimensions already correct: ${finalLayout.windowWidth}x${terminalHeight}`,
262
+ // 'Layout'
263
+ // );
264
+ }
265
+ // Log window state after sidebar enforcement (commented out to reduce noise)
266
+ // try {
267
+ // const windowDims = tmuxService.getWindowDimensionsSync();
268
+ // const layout = tmuxService.getCurrentLayoutSync();
269
+ // LogService.getInstance().debug(
270
+ // `After sidebar enforcement: Window: ${windowDims.width}x${windowDims.height}, Layout: ${layout}`,
271
+ // 'Layout'
272
+ // );
273
+ // } catch {}
274
+ // Step 9: Apply the layout to tmux
275
+ layoutApplier.applyPaneLayout(actualControlPaneId, finalContentPanes, finalLayout, terminalHeight);
204
276
  }
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
223
- // Do this AFTER sidebar resize so sidebar width is locked
224
- const currentWindowDims = getWindowDimensions();
225
- // Calculate target window height (accounting for status bar)
226
- const statusBarHeight = tmuxService.getStatusBarHeightSync();
227
- const targetWindowHeight = terminalHeight - statusBarHeight;
228
- const needsWindowResize = currentWindowDims.width !== finalLayout.windowWidth ||
229
- currentWindowDims.height !== targetWindowHeight;
230
- if (needsWindowResize) {
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);
236
- // Wait for tmux to complete the window resize
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
240
- }
241
- else {
242
- // LogService.getInstance().debug(
243
- // `Window dimensions already correct: ${finalLayout.windowWidth}x${terminalHeight}`,
244
- // 'Layout'
245
- // );
277
+ catch (error) {
278
+ // Catch-all for any errors during layout recalculation
279
+ // Log but don't crash - layout will be retried on next resize event
280
+ LogService.getInstance().error(`Layout recalculation failed: ${error}`, 'Layout', undefined, error instanceof Error ? error : undefined);
246
281
  }
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);
258
282
  }
259
283
  /**
260
284
  * Calculates optimal layout configuration based on terminal dimensions
@@ -1 +1 @@
1
- {"version":3,"file":"layoutManager.js","sourceRoot":"","sources":["../../src/utils/layoutManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layoutManager.js","sourceRoot":"","sources":["../../src/utils/layoutManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Worktree Discovery Utilities
3
+ *
4
+ * Scans a directory for nested git worktrees (including the root).
5
+ * Used for multi-merge to find sub-worktrees created by hooks.
6
+ */
7
+ import type { WorktreeInfo } from '../actions/merge/types.js';
8
+ /**
9
+ * Detect all git worktrees within a directory (recursively)
10
+ *
11
+ * @param rootWorktreePath - The root worktree path (dmux pane's worktree)
12
+ * @returns Array of WorktreeInfo objects, ordered by depth (deepest first, root last)
13
+ */
14
+ export declare function detectAllWorktrees(rootWorktreePath: string): WorktreeInfo[];
15
+ /**
16
+ * Get the parent repository path for a worktree
17
+ *
18
+ * Uses: git rev-parse --path-format=absolute --git-common-dir
19
+ * Then removes ".git" suffix to get repo root
20
+ */
21
+ export declare function getWorktreeParentPath(worktreePath: string): string | null;
22
+ /**
23
+ * Get repository name from path (directory name)
24
+ */
25
+ export declare function getRepoName(repoPath: string): string;
26
+ /**
27
+ * Check if a directory is a git worktree (has .git file, not directory)
28
+ */
29
+ export declare function isGitWorktree(dirPath: string): boolean;
30
+ /**
31
+ * Check if a directory is a git repository root (has .git directory)
32
+ */
33
+ export declare function isGitRepository(dirPath: string): boolean;
34
+ /**
35
+ * Generate a display label for a worktree
36
+ * Format: "repo-name (branch)" or "repo-name (branch) - relative/path"
37
+ */
38
+ export declare function getWorktreeDisplayLabel(worktree: WorktreeInfo): string;
39
+ //# sourceMappingURL=worktreeDiscovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktreeDiscovery.d.ts","sourceRoot":"","sources":["../../src/utils/worktreeDiscovery.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAG9D;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,GAAG,YAAY,EAAE,CAiB3E;AAwGD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqCzE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpD;AAiDD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAOtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAOxD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAMtE"}