ccmanager 1.4.2 → 1.4.4
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/components/App.js
CHANGED
|
@@ -193,33 +193,6 @@ const App = ({ devcontainerConfig }) => {
|
|
|
193
193
|
const handleCancelDeleteWorktree = () => {
|
|
194
194
|
handleReturnToMenu();
|
|
195
195
|
};
|
|
196
|
-
const handleMergeWorktree = async (sourceBranch, targetBranch, deleteAfterMerge, useRebase) => {
|
|
197
|
-
setView('merging-worktree');
|
|
198
|
-
setError(null);
|
|
199
|
-
// Perform the merge
|
|
200
|
-
const mergeResult = worktreeService.mergeWorktree(sourceBranch, targetBranch, useRebase);
|
|
201
|
-
if (mergeResult.success) {
|
|
202
|
-
// If user wants to delete the merged branch
|
|
203
|
-
if (deleteAfterMerge) {
|
|
204
|
-
const deleteResult = worktreeService.deleteWorktreeByBranch(sourceBranch);
|
|
205
|
-
if (!deleteResult.success) {
|
|
206
|
-
setError(deleteResult.error || 'Failed to delete merged worktree');
|
|
207
|
-
setView('merge-worktree');
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
// Success - return to menu
|
|
212
|
-
handleReturnToMenu();
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
// Show error
|
|
216
|
-
setError(mergeResult.error || 'Failed to merge branches');
|
|
217
|
-
setView('merge-worktree');
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
const handleCancelMergeWorktree = () => {
|
|
221
|
-
handleReturnToMenu();
|
|
222
|
-
};
|
|
223
196
|
if (view === 'menu') {
|
|
224
197
|
return (React.createElement(Menu, { key: menuKey, sessionManager: sessionManager, onSelectWorktree: handleSelectWorktree, error: error, onDismissError: () => setError(null) }));
|
|
225
198
|
}
|
|
@@ -262,11 +235,7 @@ const App = ({ devcontainerConfig }) => {
|
|
|
262
235
|
React.createElement(Text, { color: "red" },
|
|
263
236
|
"Error: ",
|
|
264
237
|
error))),
|
|
265
|
-
React.createElement(MergeWorktree, { onComplete:
|
|
266
|
-
}
|
|
267
|
-
if (view === 'merging-worktree') {
|
|
268
|
-
return (React.createElement(Box, { flexDirection: "column" },
|
|
269
|
-
React.createElement(Text, { color: "green" }, "Merging worktrees...")));
|
|
238
|
+
React.createElement(MergeWorktree, { onComplete: handleReturnToMenu, onCancel: handleReturnToMenu })));
|
|
270
239
|
}
|
|
271
240
|
if (view === 'configuration') {
|
|
272
241
|
return React.createElement(Configuration, { onComplete: handleReturnToMenu });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
interface MergeWorktreeProps {
|
|
3
|
-
onComplete: (
|
|
3
|
+
onComplete: () => void;
|
|
4
4
|
onCancel: () => void;
|
|
5
5
|
}
|
|
6
6
|
declare const MergeWorktree: React.FC<MergeWorktreeProps>;
|
|
@@ -9,10 +9,12 @@ const MergeWorktree = ({ onComplete, onCancel, }) => {
|
|
|
9
9
|
const [sourceBranch, setSourceBranch] = useState('');
|
|
10
10
|
const [targetBranch, setTargetBranch] = useState('');
|
|
11
11
|
const [branchItems, setBranchItems] = useState([]);
|
|
12
|
+
const [originalBranchItems, setOriginalBranchItems] = useState([]);
|
|
12
13
|
const [useRebase, setUseRebase] = useState(false);
|
|
13
14
|
const [operationFocused, setOperationFocused] = useState(false);
|
|
15
|
+
const [mergeError, setMergeError] = useState(null);
|
|
16
|
+
const [worktreeService] = useState(() => new WorktreeService());
|
|
14
17
|
useEffect(() => {
|
|
15
|
-
const worktreeService = new WorktreeService();
|
|
16
18
|
const loadedWorktrees = worktreeService.getWorktrees();
|
|
17
19
|
// Create branch items for selection
|
|
18
20
|
const items = loadedWorktrees.map(wt => ({
|
|
@@ -21,7 +23,8 @@ const MergeWorktree = ({ onComplete, onCancel, }) => {
|
|
|
21
23
|
value: wt.branch ? wt.branch.replace('refs/heads/', '') : 'detached',
|
|
22
24
|
}));
|
|
23
25
|
setBranchItems(items);
|
|
24
|
-
|
|
26
|
+
setOriginalBranchItems(items);
|
|
27
|
+
}, [worktreeService]);
|
|
25
28
|
useInput((input, key) => {
|
|
26
29
|
if (shortcutManager.matchesShortcut('cancel', input, key)) {
|
|
27
30
|
onCancel();
|
|
@@ -37,11 +40,15 @@ const MergeWorktree = ({ onComplete, onCancel, }) => {
|
|
|
37
40
|
setStep('confirm-merge');
|
|
38
41
|
}
|
|
39
42
|
}
|
|
43
|
+
if (step === 'merge-error') {
|
|
44
|
+
// Any key press returns to menu
|
|
45
|
+
onCancel();
|
|
46
|
+
}
|
|
40
47
|
});
|
|
41
48
|
const handleSelectSource = (item) => {
|
|
42
49
|
setSourceBranch(item.value);
|
|
43
50
|
// Filter out the selected source branch for target selection
|
|
44
|
-
const filteredItems =
|
|
51
|
+
const filteredItems = originalBranchItems.filter(b => b.value !== item.value);
|
|
45
52
|
setBranchItems(filteredItems);
|
|
46
53
|
setStep('select-target');
|
|
47
54
|
};
|
|
@@ -49,6 +56,24 @@ const MergeWorktree = ({ onComplete, onCancel, }) => {
|
|
|
49
56
|
setTargetBranch(item.value);
|
|
50
57
|
setStep('select-operation');
|
|
51
58
|
};
|
|
59
|
+
// Execute the merge operation when step changes to executing-merge
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (step !== 'executing-merge')
|
|
62
|
+
return;
|
|
63
|
+
const performMerge = async () => {
|
|
64
|
+
const result = worktreeService.mergeWorktree(sourceBranch, targetBranch, useRebase);
|
|
65
|
+
if (result.success) {
|
|
66
|
+
// Merge successful, ask about deleting source branch
|
|
67
|
+
setStep('delete-confirm');
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
// Merge failed, show error
|
|
71
|
+
setMergeError(result.error || 'Merge operation failed');
|
|
72
|
+
setStep('merge-error');
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
performMerge();
|
|
76
|
+
}, [step, sourceBranch, targetBranch, useRebase, worktreeService]);
|
|
52
77
|
if (step === 'select-source') {
|
|
53
78
|
return (React.createElement(Box, { flexDirection: "column" },
|
|
54
79
|
React.createElement(Box, { marginBottom: 1 },
|
|
@@ -124,7 +149,24 @@ const MergeWorktree = ({ onComplete, onCancel, }) => {
|
|
|
124
149
|
' ',
|
|
125
150
|
React.createElement(Text, { color: "yellow" }, targetBranch),
|
|
126
151
|
"?")));
|
|
127
|
-
return (React.createElement(Confirmation, { message: confirmMessage, onConfirm: () => setStep('
|
|
152
|
+
return (React.createElement(Confirmation, { message: confirmMessage, onConfirm: () => setStep('executing-merge'), onCancel: onCancel }));
|
|
153
|
+
}
|
|
154
|
+
if (step === 'executing-merge') {
|
|
155
|
+
return (React.createElement(Box, { flexDirection: "column" },
|
|
156
|
+
React.createElement(Text, { color: "green" },
|
|
157
|
+
useRebase ? 'Rebasing' : 'Merging',
|
|
158
|
+
" branches...")));
|
|
159
|
+
}
|
|
160
|
+
if (step === 'merge-error') {
|
|
161
|
+
return (React.createElement(Box, { flexDirection: "column" },
|
|
162
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
163
|
+
React.createElement(Text, { bold: true, color: "red" },
|
|
164
|
+
useRebase ? 'Rebase' : 'Merge',
|
|
165
|
+
" Failed")),
|
|
166
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
167
|
+
React.createElement(Text, { color: "red" }, mergeError)),
|
|
168
|
+
React.createElement(Box, { marginTop: 1 },
|
|
169
|
+
React.createElement(Text, { dimColor: true }, "Press any key to return to menu"))));
|
|
128
170
|
}
|
|
129
171
|
if (step === 'delete-confirm') {
|
|
130
172
|
const deleteMessage = (React.createElement(Box, { flexDirection: "column" },
|
|
@@ -135,7 +177,19 @@ const MergeWorktree = ({ onComplete, onCancel, }) => {
|
|
|
135
177
|
React.createElement(Text, { color: "yellow" }, sourceBranch),
|
|
136
178
|
' ',
|
|
137
179
|
"and its worktree?")));
|
|
138
|
-
return (React.createElement(Confirmation, { message: deleteMessage, onConfirm: () =>
|
|
180
|
+
return (React.createElement(Confirmation, { message: deleteMessage, onConfirm: () => {
|
|
181
|
+
const deleteResult = worktreeService.deleteWorktreeByBranch(sourceBranch);
|
|
182
|
+
if (deleteResult.success) {
|
|
183
|
+
onComplete();
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
setMergeError(deleteResult.error || 'Failed to delete worktree');
|
|
187
|
+
setStep('merge-error');
|
|
188
|
+
}
|
|
189
|
+
}, onCancel: () => {
|
|
190
|
+
// Skip deletion and complete
|
|
191
|
+
onComplete();
|
|
192
|
+
} }));
|
|
139
193
|
}
|
|
140
194
|
return null;
|
|
141
195
|
};
|
|
@@ -73,10 +73,20 @@ const Session = ({ session, sessionManager, onReturnToMenu, }) => {
|
|
|
73
73
|
const handleResize = () => {
|
|
74
74
|
const cols = process.stdout.columns || 80;
|
|
75
75
|
const rows = process.stdout.rows || 24;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
session.terminal
|
|
76
|
+
try {
|
|
77
|
+
session.process.resize(cols, rows);
|
|
78
|
+
// Also resize the virtual terminal
|
|
79
|
+
if (session.terminal) {
|
|
80
|
+
try {
|
|
81
|
+
session.terminal.resize(cols, rows);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Suppress xterm.js parsing errors
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Suppress PTY resize errors
|
|
80
90
|
}
|
|
81
91
|
};
|
|
82
92
|
stdout.on('resize', handleResize);
|
|
@@ -109,8 +109,13 @@ export class SessionManager extends EventEmitter {
|
|
|
109
109
|
setupDataHandler(session) {
|
|
110
110
|
// This handler always runs for all data
|
|
111
111
|
session.process.onData((data) => {
|
|
112
|
-
// Write data to virtual terminal
|
|
113
|
-
|
|
112
|
+
// Write data to virtual terminal with error suppression
|
|
113
|
+
try {
|
|
114
|
+
session.terminal.write(data);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Suppress xterm.js parsing errors
|
|
118
|
+
}
|
|
114
119
|
// Store in output history as Buffer
|
|
115
120
|
const buffer = Buffer.from(data, 'utf8');
|
|
116
121
|
session.outputHistory.push(buffer);
|