claude-issue-solver 1.7.2 โ 1.8.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/commands/clean.d.ts +1 -0
- package/dist/commands/clean.js +118 -0
- package/dist/index.js +6 -2
- package/package.json +1 -1
package/dist/commands/clean.d.ts
CHANGED
package/dist/commands/clean.js
CHANGED
|
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.cleanAllCommand = cleanAllCommand;
|
|
40
40
|
exports.cleanCommand = cleanCommand;
|
|
41
|
+
exports.cleanMergedCommand = cleanMergedCommand;
|
|
41
42
|
const chalk_1 = __importDefault(require("chalk"));
|
|
42
43
|
const ora_1 = __importDefault(require("ora"));
|
|
43
44
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
@@ -492,3 +493,120 @@ async function cleanCommand(issueNumber) {
|
|
|
492
493
|
console.log();
|
|
493
494
|
console.log(chalk_1.default.green('โ
Cleanup complete!'));
|
|
494
495
|
}
|
|
496
|
+
async function cleanMergedCommand() {
|
|
497
|
+
const projectRoot = (0, git_1.getProjectRoot)();
|
|
498
|
+
const worktrees = getIssueWorktrees();
|
|
499
|
+
if (worktrees.length === 0) {
|
|
500
|
+
console.log(chalk_1.default.yellow('\nNo issue worktrees found.'));
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
// Fetch status for all worktrees
|
|
504
|
+
const statusSpinner = (0, ora_1.default)('Fetching PR status...').start();
|
|
505
|
+
const worktreesWithStatus = worktrees.map((wt) => ({
|
|
506
|
+
...wt,
|
|
507
|
+
issueStatus: (0, github_1.getIssueStatus)(parseInt(wt.issueNumber, 10)),
|
|
508
|
+
prStatus: wt.branch ? (0, github_1.getPRForBranch)(wt.branch) : null,
|
|
509
|
+
}));
|
|
510
|
+
statusSpinner.stop();
|
|
511
|
+
// Filter to only merged PRs
|
|
512
|
+
const mergedWorktrees = worktreesWithStatus.filter((wt) => wt.prStatus?.state === 'merged');
|
|
513
|
+
if (mergedWorktrees.length === 0) {
|
|
514
|
+
console.log(chalk_1.default.yellow('\nNo worktrees with merged PRs found.'));
|
|
515
|
+
// Show what's available
|
|
516
|
+
if (worktreesWithStatus.length > 0) {
|
|
517
|
+
console.log(chalk_1.default.dim('\nExisting worktrees:'));
|
|
518
|
+
for (const wt of worktreesWithStatus) {
|
|
519
|
+
const status = getStatusLabel(wt);
|
|
520
|
+
console.log(` ${chalk_1.default.cyan(`#${wt.issueNumber}`)}\t${status}`);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
console.log(chalk_1.default.bold(`\n๐งน Cleaning ${mergedWorktrees.length} worktree(s) with merged PRs:\n`));
|
|
526
|
+
for (const wt of mergedWorktrees) {
|
|
527
|
+
console.log(` ${chalk_1.default.cyan(`#${wt.issueNumber}`)}\t${chalk_1.default.green('โ PR merged')}`);
|
|
528
|
+
if (wt.branch) {
|
|
529
|
+
console.log(chalk_1.default.dim(` \t${wt.branch}`));
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
console.log();
|
|
533
|
+
for (const wt of mergedWorktrees) {
|
|
534
|
+
const spinner = (0, ora_1.default)(`Cleaning issue #${wt.issueNumber}...`).start();
|
|
535
|
+
try {
|
|
536
|
+
// Close terminal and VS Code windows for this worktree
|
|
537
|
+
try {
|
|
538
|
+
closeWindowsWithPath(wt.path, wt.issueNumber);
|
|
539
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
540
|
+
}
|
|
541
|
+
catch {
|
|
542
|
+
// Ignore errors closing windows
|
|
543
|
+
}
|
|
544
|
+
// Remove worktree/folder
|
|
545
|
+
const isOrphaned = !wt.branch;
|
|
546
|
+
// Try git worktree remove first (only if not orphaned)
|
|
547
|
+
if (!isOrphaned && fs.existsSync(wt.path)) {
|
|
548
|
+
try {
|
|
549
|
+
(0, child_process_1.execSync)(`git worktree remove "${wt.path}" --force`, {
|
|
550
|
+
cwd: projectRoot,
|
|
551
|
+
stdio: 'pipe',
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
catch {
|
|
555
|
+
// Ignore - we'll force delete below
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
// Always try to force delete the folder
|
|
559
|
+
if (fs.existsSync(wt.path)) {
|
|
560
|
+
try {
|
|
561
|
+
(0, child_process_1.execSync)(`/bin/rm -rf "${wt.path}"`, { stdio: 'pipe', timeout: 10000 });
|
|
562
|
+
}
|
|
563
|
+
catch {
|
|
564
|
+
try {
|
|
565
|
+
(0, child_process_1.execSync)(`rm -rf "${wt.path}"`, { shell: '/bin/bash', stdio: 'pipe', timeout: 10000 });
|
|
566
|
+
}
|
|
567
|
+
catch {
|
|
568
|
+
try {
|
|
569
|
+
fs.rmSync(wt.path, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 });
|
|
570
|
+
}
|
|
571
|
+
catch {
|
|
572
|
+
// Will report failure below
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
// Prune git worktrees
|
|
578
|
+
try {
|
|
579
|
+
(0, child_process_1.execSync)('git worktree prune', { cwd: projectRoot, stdio: 'pipe' });
|
|
580
|
+
}
|
|
581
|
+
catch {
|
|
582
|
+
// Ignore
|
|
583
|
+
}
|
|
584
|
+
// Delete branch (if we have one)
|
|
585
|
+
if (wt.branch) {
|
|
586
|
+
try {
|
|
587
|
+
(0, child_process_1.execSync)(`git branch -D "${wt.branch}"`, {
|
|
588
|
+
cwd: projectRoot,
|
|
589
|
+
stdio: 'pipe',
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
catch {
|
|
593
|
+
// Branch may already be deleted
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
// Check if cleanup was successful
|
|
597
|
+
if (fs.existsSync(wt.path)) {
|
|
598
|
+
spinner.warn(`Cleaned issue #${wt.issueNumber} (folder may remain: ${wt.path})`);
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
spinner.succeed(`Cleaned issue #${wt.issueNumber}`);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
catch (error) {
|
|
605
|
+
spinner.fail(`Failed to clean issue #${wt.issueNumber}: ${error}`);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
// Prune stale worktrees
|
|
609
|
+
(0, child_process_1.execSync)('git worktree prune', { cwd: projectRoot, stdio: 'pipe' });
|
|
610
|
+
console.log();
|
|
611
|
+
console.log(chalk_1.default.green(`โ
Cleaned up ${mergedWorktrees.length} merged worktree(s)!`));
|
|
612
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -76,9 +76,13 @@ program
|
|
|
76
76
|
.command('clean [issue]')
|
|
77
77
|
.alias('rm')
|
|
78
78
|
.option('-a, --all', 'Clean all issue worktrees')
|
|
79
|
-
.
|
|
79
|
+
.option('-m, --merged', 'Clean only worktrees with merged PRs (no confirmation)')
|
|
80
|
+
.description('Remove worktree and branch for an issue (or all with --all, or merged with --merged)')
|
|
80
81
|
.action(async (issue, options) => {
|
|
81
|
-
if (options.
|
|
82
|
+
if (options.merged) {
|
|
83
|
+
await (0, clean_1.cleanMergedCommand)();
|
|
84
|
+
}
|
|
85
|
+
else if (options.all) {
|
|
82
86
|
await (0, clean_1.cleanAllCommand)();
|
|
83
87
|
}
|
|
84
88
|
else if (issue) {
|