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.
@@ -1,2 +1,3 @@
1
1
  export declare function cleanAllCommand(): Promise<void>;
2
2
  export declare function cleanCommand(issueNumber: number): Promise<void>;
3
+ export declare function cleanMergedCommand(): Promise<void>;
@@ -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
- .description('Remove worktree and branch for an issue (or all with --all)')
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.all) {
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-issue-solver",
3
- "version": "1.7.2",
3
+ "version": "1.8.0",
4
4
  "description": "Automatically solve GitHub issues using Claude Code",
5
5
  "main": "dist/index.js",
6
6
  "bin": {