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.
- package/dist/actions/implementations/closeAction.d.ts.map +1 -1
- package/dist/actions/implementations/closeAction.js +22 -6
- package/dist/actions/implementations/closeAction.js.map +1 -1
- package/dist/actions/implementations/mergeAction.d.ts +3 -1
- package/dist/actions/implementations/mergeAction.d.ts.map +1 -1
- package/dist/actions/implementations/mergeAction.js +38 -4
- package/dist/actions/implementations/mergeAction.js.map +1 -1
- package/dist/actions/merge/multiMergeOrchestrator.d.ts +22 -0
- package/dist/actions/merge/multiMergeOrchestrator.d.ts.map +1 -0
- package/dist/actions/merge/multiMergeOrchestrator.js +452 -0
- package/dist/actions/merge/multiMergeOrchestrator.js.map +1 -0
- package/dist/actions/merge/types.d.ts +62 -0
- package/dist/actions/merge/types.d.ts.map +1 -0
- package/dist/actions/merge/types.js +7 -0
- package/dist/actions/merge/types.js.map +1 -0
- package/dist/chunks/styles.css_vue_type_style_index_0_src_true_lang-pW5mq51o.js +17 -0
- package/dist/components/popups/logsPopup.js +33 -17
- package/dist/components/popups/logsPopup.js.map +1 -1
- package/dist/dashboard.html +2 -2
- package/dist/dashboard.js +2 -2
- package/dist/hooks/useLayoutManagement.d.ts.map +1 -1
- package/dist/hooks/useLayoutManagement.js +43 -14
- package/dist/hooks/useLayoutManagement.js.map +1 -1
- package/dist/hooks/usePaneLoading.d.ts +3 -0
- package/dist/hooks/usePaneLoading.d.ts.map +1 -1
- package/dist/hooks/usePaneLoading.js +21 -1
- package/dist/hooks/usePaneLoading.js.map +1 -1
- package/dist/hooks/usePaneSync.d.ts +3 -0
- package/dist/hooks/usePaneSync.d.ts.map +1 -1
- package/dist/hooks/usePaneSync.js +11 -0
- package/dist/hooks/usePaneSync.js.map +1 -1
- package/dist/layout/TmuxLayoutApplier.d.ts.map +1 -1
- package/dist/layout/TmuxLayoutApplier.js +4 -9
- package/dist/layout/TmuxLayoutApplier.js.map +1 -1
- package/dist/server/embedded-assets.d.ts.map +1 -1
- package/dist/server/embedded-assets.js +26 -37
- package/dist/server/embedded-assets.js.map +1 -1
- package/dist/services/PaneAnalyzer.d.ts +12 -3
- package/dist/services/PaneAnalyzer.d.ts.map +1 -1
- package/dist/services/PaneAnalyzer.js +57 -8
- package/dist/services/PaneAnalyzer.js.map +1 -1
- package/dist/services/PopupManager.d.ts.map +1 -1
- package/dist/services/PopupManager.js +7 -1
- package/dist/services/PopupManager.js.map +1 -1
- package/dist/services/StatusDetector.d.ts.map +1 -1
- package/dist/services/StatusDetector.js +28 -9
- package/dist/services/StatusDetector.js.map +1 -1
- package/dist/services/TmuxService.d.ts +9 -3
- package/dist/services/TmuxService.d.ts.map +1 -1
- package/dist/services/TmuxService.js +12 -3
- package/dist/services/TmuxService.js.map +1 -1
- package/dist/terminal.html +2 -2
- package/dist/terminal.js +3 -3
- package/dist/utils/generated-agents-doc.d.ts +1 -1
- package/dist/utils/generated-agents-doc.js +1 -1
- package/dist/utils/hooksDocs.d.ts +1 -1
- package/dist/utils/layoutManager.d.ts.map +1 -1
- package/dist/utils/layoutManager.js +226 -202
- package/dist/utils/layoutManager.js.map +1 -1
- package/dist/utils/worktreeDiscovery.d.ts +39 -0
- package/dist/utils/worktreeDiscovery.d.ts.map +1 -0
- package/dist/utils/worktreeDiscovery.js +241 -0
- package/dist/utils/worktreeDiscovery.js.map +1 -0
- package/package.json +7 -7
- package/dist/chunks/_plugin-vue_export-helper-Cvoq67hi.js +0 -28
- /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
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
-
|
|
113
|
-
LogService.getInstance().
|
|
114
|
-
|
|
135
|
+
catch (error) {
|
|
136
|
+
// LogService.getInstance().debug(`Continuing without spacer pane: ${error}`, 'Layout');
|
|
137
|
+
spacerId = null;
|
|
115
138
|
}
|
|
116
139
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
194
|
-
|
|
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
|
-
|
|
202
|
-
|
|
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
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAA6B,MAAM,wBAAwB,CAAC;AAE7F,6BAA6B;AAC7B,OAAO,EAAE,gBAAgB,EAA4B,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAanE,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,aAAa,EAAE,EAAE;IACjB,qBAAqB,EAAE,EAAE;IACzB,qBAAqB,EAAE,EAAE;IACzB,sBAAsB,EAAE,EAAE;CAC3B,CAAC;AAEF,sEAAsE;AACtE,MAAM,CAAC,MAAM,aAAa,GAAG,qBAAqB,CAAC,aAAa,CAAC;AACjE,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAC,qBAAqB,CAAC;AACjF,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAC,qBAAqB,CAAC;AACjF,MAAM,CAAC,MAAM,sBAAsB,GAAG,qBAAqB,CAAC,sBAAsB,CAAC;AAKnF,sEAAsE;AACtE,IAAI,oBAAoB,GAAgE,IAAI,CAAC;AAE7F;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,aAAqB,EACrB,cAAwB,EACxB,aAAqB,EACrB,cAAsB,EACtB,SAAuB,qBAAqB;IAE5C,qCAAqC;
|
|
1
|
+
{"version":3,"file":"layoutManager.js","sourceRoot":"","sources":["../../src/utils/layoutManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAA6B,MAAM,wBAAwB,CAAC;AAE7F,6BAA6B;AAC7B,OAAO,EAAE,gBAAgB,EAA4B,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAanE,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,aAAa,EAAE,EAAE;IACjB,qBAAqB,EAAE,EAAE;IACzB,qBAAqB,EAAE,EAAE;IACzB,sBAAsB,EAAE,EAAE;CAC3B,CAAC;AAEF,sEAAsE;AACtE,MAAM,CAAC,MAAM,aAAa,GAAG,qBAAqB,CAAC,aAAa,CAAC;AACjE,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAC,qBAAqB,CAAC;AACjF,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAC,qBAAqB,CAAC;AACjF,MAAM,CAAC,MAAM,sBAAsB,GAAG,qBAAqB,CAAC,sBAAsB,CAAC;AAKnF,sEAAsE;AACtE,IAAI,oBAAoB,GAAgE,IAAI,CAAC;AAE7F;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,aAAqB,EACrB,cAAwB,EACxB,aAAqB,EACrB,cAAsB,EACtB,SAAuB,qBAAqB;IAE5C,qEAAqE;IACrE,IAAI,CAAC;QACH,mDAAmD;QACnD,IAAI,CAAC,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;YACxD,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,wCAAwC,EAAE,QAAQ,CAAC,CAAC;YAClF,OAAO;QACT,CAAC;QACD,IAAI,aAAa,IAAI,CAAC,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;YAC9C,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,CAC3B,gCAAgC,aAAa,IAAI,cAAc,mBAAmB,EAClF,QAAQ,CACT,CAAC;YACF,OAAO;QACT,CAAC;QAED,qCAAqC;QACrC,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,aAAa,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAEpD,4DAA4D;QAC5D,IAAI,gBAAgB,GAAkB,IAAI,CAAC;QAC3C,IAAI,CAAC;YACH,gBAAgB,GAAG,aAAa,CAAC,cAAc,EAAE,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,+BAA+B,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,gBAAgB,GAAG,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,gBAAgB,CAAC,CAAC;QAEhF,oEAAoE;QACpE,MAAM,mBAAmB,GACvB,oBAAoB;YACpB,oBAAoB,CAAC,KAAK,KAAK,aAAa;YAC5C,oBAAoB,CAAC,MAAM,KAAK,cAAc;YAC9C,oBAAoB,CAAC,SAAS,KAAK,gBAAgB,CAAC,MAAM,CAAC;QAE7D,IAAI,mBAAmB,EAAE,CAAC;YACxB,sEAAsE;YACtE,8EAA8E;YAC9E,sDAAsD;YACtD,OAAO;QACT,CAAC;QAED,6DAA6D;QAC7D,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,CAC3B,8BAA8B,aAAa,IAAI,cAAc,KAAK,gBAAgB,CAAC,MAAM,QAAQ,EACjG,QAAQ,CACT,CAAC;QAEF,gCAAgC;QAChC,oBAAoB,GAAG;YACrB,KAAK,EAAE,aAAa;YACpB,MAAM,EAAE,cAAc;YACtB,SAAS,EAAE,gBAAgB,CAAC,MAAM;SACnC,CAAC;QAEF,uDAAuD;QACvD,MAAM,MAAM,GAAG,UAAU,CAAC,sBAAsB,CAC9C,gBAAgB,CAAC,MAAM,EACvB,aAAa,EACb,cAAc,CACf,CAAC;QAEF,6CAA6C;QAC7C,MAAM,WAAW,GAAG,aAAa,CAAC,eAAe,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAEnF,kDAAkD;QAClD,8EAA8E;QAC9E,IAAI,QAAQ,GAAkB,IAAI,CAAC;QAEnC,kCAAkC;QAClC,uFAAuF;QACvF,aAAa;QACb,KAAK;QAEL,gEAAgE;QAChE,IAAI,gBAAgB,EAAE,CAAC;YACrB,8GAA8G;YAC9G,aAAa,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;QACpD,CAAC;QAED,8BAA8B;QAC9B,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACxE,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBACvB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;gBAC9D,CAAC;gBACD,QAAQ,GAAG,aAAa,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;gBAC7D,sFAAsF;gBAEtF,gFAAgF;gBAChF,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC;gBAE5E,+CAA+C;gBAC/C,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;gBAC9C,IAAI,YAAY,GAAG,KAAK,CAAC;gBACzB,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC;oBAChD,IAAI,CAAC;wBACH,MAAM,UAAU,GAAG,WAAW,CAAC,iBAAiB,EAAE,CAAC;wBAEnD,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;4BAClC,YAAY,GAAG,IAAI,CAAC;4BACpB,kCAAkC;4BAClC,gFAAgF;4BAChF,aAAa;4BACb,KAAK;4BACL,MAAM;wBACR,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,iCAAiC;wBACjC,IAAI,QAAQ,GAAG,CAAC;4BAAE,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC;oBAChG,CAAC;gBACH,CAAC;gBAED,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,CAC3B,eAAe,QAAQ,kCAAkC,EACzD,QAAQ,CACT,CAAC;oBACF,0DAA0D;gBAC5D,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,wFAAwF;gBACxF,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;QACH,CAAC;QAED,gEAAgE;QAChE,IAAI,iBAAiB,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,gBAAgB,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAEtF,2DAA2D;QAC3D,oDAAoD;QACpD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;YAC9C,wDAAwD;YACxD,MAAM,WAAW,GAAG,WAAW,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAC;YAC1E,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAEjE,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBACxB,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC3C,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;oBACvB,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,6CAA6C;YAC7C,iBAAiB,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBAClD,qBAAqB;gBACrB,IAAI,CAAC,KAAK,QAAQ;oBAAE,OAAO,CAAC,CAAC;gBAC7B,IAAI,CAAC,KAAK,QAAQ;oBAAE,OAAO,CAAC,CAAC,CAAC;gBAE9B,+BAA+B;gBAC/B,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACvC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACvC,OAAO,MAAM,GAAG,MAAM,CAAC;YACzB,CAAC,CAAC,CAAC;YAEH,kCAAkC;YAClC,+GAA+G;YAC/G,aAAa;YACb,KAAK;QACP,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,+EAA+E;QACjF,CAAC;QAED,6DAA6D;QAC7D,MAAM,WAAW,GAAG,QAAQ;YAC1B,CAAC,CAAC,UAAU,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,cAAc,CAAC;YAC5F,CAAC,CAAC,MAAM,CAAC;QAEX,gFAAgF;QAChF,QAAQ;QACR,mDAAmD;QACnD,0DAA0D;QAC1D,4CAA4C;QAC5C,+DAA+D;QAC/D,kBAAkB;QAClB,wGAAwG;QACxG,aAAa;QAEb,oEAAoE;QACpE,6EAA6E;QAE7E,kDAAkD;QAClD,4FAA4F;QAC5F,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;QAC9C,IAAI,mBAAmB,GAAG,aAAa,CAAC;QACxC,IAAI,CAAC;YACH,wDAAwD;YACxD,MAAM,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;YACvE,mFAAmF;YACnF,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,WAAW,CAAC,oBAAoB,EAAE,CAAC;gBACrD,IAAI,kBAAkB,GAAyC,IAAI,CAAC;gBAEpE,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;oBAC5B,qDAAqD;oBACrD,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,kBAAkB,IAAI,GAAG,CAAC,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;wBACpF,kBAAkB,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;oBAC5D,CAAC;gBACH,CAAC;gBAED,IAAI,kBAAkB,EAAE,CAAC;oBACvB,mBAAmB,GAAG,kBAAkB,CAAC,EAAE,CAAC;oBAC5C,kCAAkC;oBAClC,+GAA+G;oBAC/G,aAAa;oBACb,KAAK;gBACP,CAAC;YACH,CAAC;YAAC,OAAO,SAAS,EAAE,CAAC;gBACnB,qGAAqG;YACvG,CAAC;QACH,CAAC;QAED,qDAAqD;QACrD,4EAA4E;QAC5E,oCAAoC;QACpC,QAAQ;QACR,mFAAmF;QACnF,EAAE;QACF,wDAAwD;QACxD,sCAAsC;QACtC,6HAA6H;QAC7H,iBAAiB;QACjB,SAAS;QACT,aAAa;QACb,0GAA0G;QAC1G,MAAM;QACN,oBAAoB;QACpB,yFAAyF;QACzF,IAAI;QAEJ,uDAAuD;QACvD,0DAA0D;QAC1D,MAAM,iBAAiB,GAAG,mBAAmB,EAAE,CAAC;QAEhD,6DAA6D;QAC7D,MAAM,eAAe,GAAG,WAAW,CAAC,sBAAsB,EAAE,CAAC;QAC7D,MAAM,kBAAkB,GAAG,cAAc,GAAG,eAAe,CAAC;QAE5D,MAAM,iBAAiB,GACrB,iBAAiB,CAAC,KAAK,KAAK,WAAW,CAAC,WAAW;YACnD,iBAAiB,CAAC,MAAM,KAAK,kBAAkB,CAAC;QAElD,IAAI,iBAAiB,EAAE,CAAC;YACtB,kCAAkC;YAClC,kIAAkI;YAClI,aAAa;YACb,KAAK;YACL,aAAa,CAAC,mBAAmB,CAAC,WAAW,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YAE3E,8CAA8C;YAC9C,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC;YAE5E,uDAAuD;YACvD,6EAA6E;QAC/E,CAAC;aAAM,CAAC;YACN,kCAAkC;YAClC,uFAAuF;YACvF,aAAa;YACb,KAAK;QACP,CAAC;QAED,6EAA6E;QAC7E,QAAQ;QACR,8DAA8D;QAC9D,uDAAuD;QACvD,oCAAoC;QACpC,wGAAwG;QACxG,eAAe;QACf,OAAO;QACP,aAAa;QAEb,mCAAmC;QACnC,aAAa,CAAC,eAAe,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;IACnG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uDAAuD;QACvD,oEAAoE;QACpE,UAAU,CAAC,WAAW,EAAE,CAAC,KAAK,CAC5B,gCAAgC,KAAK,EAAE,EACvC,QAAQ,EACR,SAAS,EACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,eAAuB,EACvB,aAAqB,EACrB,cAAsB,EACtB,SAAuB,qBAAqB;IAE5C,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAChD,OAAO,UAAU,CAAC,sBAAsB,CAAC,eAAe,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC;AAC3F,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,IAAY;IAC5D,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;IAC/D,OAAO,UAAU,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -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"}
|