claude-issue-solver 1.6.1 → 1.6.3

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.
@@ -45,10 +45,8 @@ const fs = __importStar(require("fs"));
45
45
  const path = __importStar(require("path"));
46
46
  const os = __importStar(require("os"));
47
47
  const child_process_1 = require("child_process");
48
- const github_1 = require("../utils/github");
49
48
  const git_1 = require("../utils/git");
50
- const helpers_1 = require("../utils/helpers");
51
- function closeTerminalWithPath(folderPath) {
49
+ function closeWindowsWithPath(folderPath) {
52
50
  if (os.platform() !== 'darwin')
53
51
  return;
54
52
  const folderName = path.basename(folderPath);
@@ -87,6 +85,27 @@ function closeTerminalWithPath(folderPath) {
87
85
  catch {
88
86
  // Terminal not running or no matching windows
89
87
  }
88
+ // Try to close VS Code windows with this path
89
+ try {
90
+ (0, child_process_1.execSync)(`osascript -e '
91
+ tell application "System Events"
92
+ if exists process "Code" then
93
+ tell process "Code"
94
+ set windowList to every window
95
+ repeat with w in windowList
96
+ set windowName to name of w
97
+ if windowName contains "${folderName}" then
98
+ perform action "AXPress" of (first button of w whose subrole is "AXCloseButton")
99
+ end if
100
+ end repeat
101
+ end tell
102
+ end if
103
+ end tell
104
+ '`, { stdio: 'pipe' });
105
+ }
106
+ catch {
107
+ // VS Code not running or no matching windows
108
+ }
90
109
  }
91
110
  function getIssueWorktrees() {
92
111
  const projectRoot = (0, git_1.getProjectRoot)();
@@ -148,14 +167,26 @@ async function cleanAllCommand() {
148
167
  for (const wt of worktrees) {
149
168
  const spinner = (0, ora_1.default)(`Cleaning issue #${wt.issueNumber}...`).start();
150
169
  try {
151
- // Close terminal windows for this worktree
152
- closeTerminalWithPath(wt.path);
170
+ // Close terminal and VS Code windows for this worktree
171
+ try {
172
+ closeWindowsWithPath(wt.path);
173
+ }
174
+ catch {
175
+ // Ignore errors closing windows
176
+ }
153
177
  // Remove worktree
154
178
  if (fs.existsSync(wt.path)) {
155
- (0, child_process_1.execSync)(`git worktree remove "${wt.path}" --force`, {
156
- cwd: projectRoot,
157
- stdio: 'pipe',
158
- });
179
+ try {
180
+ (0, child_process_1.execSync)(`git worktree remove "${wt.path}" --force`, {
181
+ cwd: projectRoot,
182
+ stdio: 'pipe',
183
+ });
184
+ }
185
+ catch {
186
+ // If git worktree remove fails, try removing directory manually
187
+ fs.rmSync(wt.path, { recursive: true, force: true });
188
+ (0, child_process_1.execSync)('git worktree prune', { cwd: projectRoot, stdio: 'pipe' });
189
+ }
159
190
  }
160
191
  // Delete branch
161
192
  try {
@@ -170,7 +201,7 @@ async function cleanAllCommand() {
170
201
  spinner.succeed(`Cleaned issue #${wt.issueNumber}`);
171
202
  }
172
203
  catch (error) {
173
- spinner.fail(`Failed to clean issue #${wt.issueNumber}`);
204
+ spinner.fail(`Failed to clean issue #${wt.issueNumber}: ${error}`);
174
205
  }
175
206
  }
176
207
  // Prune stale worktrees
@@ -179,18 +210,46 @@ async function cleanAllCommand() {
179
210
  console.log(chalk_1.default.green(`✅ Cleaned up ${worktrees.length} issue worktree(s)!`));
180
211
  }
181
212
  async function cleanCommand(issueNumber) {
182
- const spinner = (0, ora_1.default)(`Fetching issue #${issueNumber}...`).start();
183
- const issue = (0, github_1.getIssue)(issueNumber);
184
- if (!issue) {
185
- spinner.fail(`Could not find issue #${issueNumber}`);
186
- process.exit(1);
187
- }
188
- spinner.succeed(`Found issue #${issueNumber}`);
189
213
  const projectRoot = (0, git_1.getProjectRoot)();
190
214
  const projectName = (0, git_1.getProjectName)();
191
- const branchSlug = (0, helpers_1.slugify)(issue.title);
192
- const branchName = `issue-${issueNumber}-${branchSlug}`;
193
- const worktreePath = path.join(path.dirname(projectRoot), `${projectName}-${branchName}`);
215
+ // Find the worktree for this issue number (don't need to fetch from GitHub)
216
+ const worktrees = getIssueWorktrees();
217
+ const worktree = worktrees.find((wt) => wt.issueNumber === String(issueNumber));
218
+ if (!worktree) {
219
+ // Try to find by looking for the branch pattern
220
+ const branchPattern = `issue-${issueNumber}-`;
221
+ const output = (0, git_1.exec)('git branch', projectRoot);
222
+ const branches = output.split('\n').map((b) => b.trim().replace('* ', ''));
223
+ const matchingBranch = branches.find((b) => b.startsWith(branchPattern));
224
+ if (!matchingBranch) {
225
+ console.log(chalk_1.default.red(`\n❌ No worktree or branch found for issue #${issueNumber}`));
226
+ return;
227
+ }
228
+ // Found a branch but no worktree - just delete the branch
229
+ console.log(chalk_1.default.bold(`\n🧹 Cleaning up issue #${issueNumber}`));
230
+ console.log(chalk_1.default.dim(` Branch: ${matchingBranch}`));
231
+ console.log(chalk_1.default.dim(` (No worktree found)`));
232
+ const { confirm } = await inquirer_1.default.prompt([
233
+ {
234
+ type: 'confirm',
235
+ name: 'confirm',
236
+ message: 'Delete branch?',
237
+ default: false,
238
+ },
239
+ ]);
240
+ if (confirm) {
241
+ try {
242
+ (0, child_process_1.execSync)(`git branch -D "${matchingBranch}"`, { cwd: projectRoot, stdio: 'pipe' });
243
+ console.log(chalk_1.default.green('\n✅ Branch deleted!'));
244
+ }
245
+ catch {
246
+ console.log(chalk_1.default.yellow('\n⚠️ Could not delete branch'));
247
+ }
248
+ }
249
+ return;
250
+ }
251
+ const branchName = worktree.branch;
252
+ const worktreePath = worktree.path;
194
253
  console.log();
195
254
  console.log(chalk_1.default.bold(`🧹 Cleaning up issue #${issueNumber}`));
196
255
  console.log(chalk_1.default.dim(` Branch: ${branchName}`));
@@ -208,8 +267,13 @@ async function cleanCommand(issueNumber) {
208
267
  console.log(chalk_1.default.dim('Cancelled.'));
209
268
  return;
210
269
  }
211
- // Close terminal windows for this worktree
212
- closeTerminalWithPath(worktreePath);
270
+ // Close terminal and VS Code windows for this worktree
271
+ try {
272
+ closeWindowsWithPath(worktreePath);
273
+ }
274
+ catch {
275
+ // Ignore errors closing windows
276
+ }
213
277
  // Remove worktree
214
278
  if (fs.existsSync(worktreePath)) {
215
279
  const worktreeSpinner = (0, ora_1.default)('Removing worktree...').start();
@@ -221,7 +285,15 @@ async function cleanCommand(issueNumber) {
221
285
  worktreeSpinner.succeed('Worktree removed');
222
286
  }
223
287
  catch {
224
- worktreeSpinner.warn('Could not remove worktree (may already be removed)');
288
+ // If git worktree remove fails, try removing directory manually
289
+ try {
290
+ fs.rmSync(worktreePath, { recursive: true, force: true });
291
+ (0, child_process_1.execSync)('git worktree prune', { cwd: projectRoot, stdio: 'pipe' });
292
+ worktreeSpinner.succeed('Worktree removed (manually)');
293
+ }
294
+ catch {
295
+ worktreeSpinner.warn('Could not remove worktree directory');
296
+ }
225
297
  }
226
298
  }
227
299
  // Delete branch
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-issue-solver",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "description": "Automatically solve GitHub issues using Claude Code",
5
5
  "main": "dist/index.js",
6
6
  "bin": {