git-watchtower 1.5.0 → 1.6.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/bin/git-watchtower.js +68 -1
- package/package.json +1 -1
package/bin/git-watchtower.js
CHANGED
|
@@ -77,7 +77,7 @@ const { parseGitHubPr, parseGitLabMr, parseGitHubPrList, parseGitLabMrList, isBa
|
|
|
77
77
|
// ============================================================================
|
|
78
78
|
// Security & Validation (imported from src/git/branch.js and src/git/commands.js)
|
|
79
79
|
// ============================================================================
|
|
80
|
-
const { isValidBranchName, sanitizeBranchName } = require('../src/git/branch');
|
|
80
|
+
const { isValidBranchName, sanitizeBranchName, getGoneBranches, deleteGoneBranches } = require('../src/git/branch');
|
|
81
81
|
const { isGitAvailable: checkGitAvailable } = require('../src/git/commands');
|
|
82
82
|
|
|
83
83
|
// ============================================================================
|
|
@@ -1191,6 +1191,11 @@ function render() {
|
|
|
1191
1191
|
renderer.renderErrorToast(state, write);
|
|
1192
1192
|
}
|
|
1193
1193
|
|
|
1194
|
+
// Cleanup confirmation dialog
|
|
1195
|
+
if (state.cleanupConfirmMode) {
|
|
1196
|
+
renderer.renderCleanupConfirm(state, write);
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1194
1199
|
// Stash confirmation dialog renders on top of everything
|
|
1195
1200
|
if (state.stashConfirmMode) {
|
|
1196
1201
|
renderer.renderStashConfirm(state, write);
|
|
@@ -2329,6 +2334,59 @@ function setupKeyboardInput() {
|
|
|
2329
2334
|
return; // Ignore other keys in action mode
|
|
2330
2335
|
}
|
|
2331
2336
|
|
|
2337
|
+
// Handle cleanup confirmation dialog
|
|
2338
|
+
if (store.get('cleanupConfirmMode')) {
|
|
2339
|
+
const cleanupBranches = store.get('cleanupBranches') || [];
|
|
2340
|
+
const maxOptions = cleanupBranches.length > 0 ? 3 : 1;
|
|
2341
|
+
if (key === '\u001b[A' || key === 'k') { // Up
|
|
2342
|
+
const idx = store.get('cleanupSelectedIndex') || 0;
|
|
2343
|
+
if (idx > 0) {
|
|
2344
|
+
store.setState({ cleanupSelectedIndex: idx - 1 });
|
|
2345
|
+
render();
|
|
2346
|
+
}
|
|
2347
|
+
return;
|
|
2348
|
+
}
|
|
2349
|
+
if (key === '\u001b[B' || key === 'j') { // Down
|
|
2350
|
+
const idx = store.get('cleanupSelectedIndex') || 0;
|
|
2351
|
+
if (idx < maxOptions - 1) {
|
|
2352
|
+
store.setState({ cleanupSelectedIndex: idx + 1 });
|
|
2353
|
+
render();
|
|
2354
|
+
}
|
|
2355
|
+
return;
|
|
2356
|
+
}
|
|
2357
|
+
if (key === '\r' || key === '\n') { // Enter — execute selected option
|
|
2358
|
+
const idx = store.get('cleanupSelectedIndex') || 0;
|
|
2359
|
+
applyUpdates(actions.closeCleanupConfirm(getActionState()));
|
|
2360
|
+
render();
|
|
2361
|
+
if (cleanupBranches.length === 0 || idx === maxOptions - 1) {
|
|
2362
|
+
// Cancel or Close (no branches)
|
|
2363
|
+
return;
|
|
2364
|
+
}
|
|
2365
|
+
const force = idx === 1; // 0=safe delete, 1=force delete, 2=cancel
|
|
2366
|
+
addLog(`Cleaning up ${cleanupBranches.length} stale branch${cleanupBranches.length === 1 ? '' : 'es'}${force ? ' (force)' : ''}...`, 'update');
|
|
2367
|
+
render();
|
|
2368
|
+
const result = await deleteGoneBranches(cleanupBranches, { force });
|
|
2369
|
+
for (const name of result.deleted) {
|
|
2370
|
+
addLog(`Deleted branch: ${name}`, 'success');
|
|
2371
|
+
}
|
|
2372
|
+
for (const f of result.failed) {
|
|
2373
|
+
addLog(`Failed to delete ${f.name}: ${f.error}`, 'error');
|
|
2374
|
+
}
|
|
2375
|
+
if (result.deleted.length > 0) {
|
|
2376
|
+
addLog(`Cleaned up ${result.deleted.length} branch${result.deleted.length === 1 ? '' : 'es'}`, 'success');
|
|
2377
|
+
await pollGitChanges();
|
|
2378
|
+
}
|
|
2379
|
+
render();
|
|
2380
|
+
return;
|
|
2381
|
+
}
|
|
2382
|
+
if (key === '\u001b') { // Escape — cancel
|
|
2383
|
+
applyUpdates(actions.closeCleanupConfirm(getActionState()));
|
|
2384
|
+
render();
|
|
2385
|
+
return;
|
|
2386
|
+
}
|
|
2387
|
+
return; // Ignore other keys in cleanup mode
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2332
2390
|
// Handle stash confirmation dialog
|
|
2333
2391
|
if (store.get('stashConfirmMode')) {
|
|
2334
2392
|
if (key === '\u001b[A' || key === 'k') { // Up
|
|
@@ -2565,6 +2623,15 @@ function setupKeyboardInput() {
|
|
|
2565
2623
|
break;
|
|
2566
2624
|
}
|
|
2567
2625
|
|
|
2626
|
+
case 'd': { // Cleanup stale branches (remotes deleted)
|
|
2627
|
+
addLog('Scanning for stale branches...', 'info');
|
|
2628
|
+
render();
|
|
2629
|
+
const goneBranches = await getGoneBranches();
|
|
2630
|
+
applyUpdates(actions.openCleanupConfirm(actionState, goneBranches));
|
|
2631
|
+
render();
|
|
2632
|
+
break;
|
|
2633
|
+
}
|
|
2634
|
+
|
|
2568
2635
|
// Number keys to set visible branch count
|
|
2569
2636
|
case '1': case '2': case '3': case '4': case '5':
|
|
2570
2637
|
case '6': case '7': case '8': case '9':
|
package/package.json
CHANGED