claude-issue-solver 1.6.2 → 1.6.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/commands/clean.js +107 -25
- package/package.json +1 -1
package/dist/commands/clean.js
CHANGED
|
@@ -45,14 +45,13 @@ 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
|
-
|
|
51
|
-
function closeWindowsWithPath(folderPath) {
|
|
49
|
+
function closeWindowsWithPath(folderPath, issueNumber) {
|
|
52
50
|
if (os.platform() !== 'darwin')
|
|
53
51
|
return;
|
|
54
52
|
const folderName = path.basename(folderPath);
|
|
55
|
-
|
|
53
|
+
const issuePattern = `Issue #${issueNumber}`;
|
|
54
|
+
// Try to close iTerm2 tabs/windows with this path or issue number
|
|
56
55
|
try {
|
|
57
56
|
(0, child_process_1.execSync)(`osascript -e '
|
|
58
57
|
tell application "iTerm"
|
|
@@ -60,7 +59,7 @@ function closeWindowsWithPath(folderPath) {
|
|
|
60
59
|
repeat with t in tabs of w
|
|
61
60
|
repeat with s in sessions of t
|
|
62
61
|
set sessionName to name of s
|
|
63
|
-
if sessionName contains "${folderName}" then
|
|
62
|
+
if sessionName contains "${folderName}" or sessionName contains "${issuePattern}" then
|
|
64
63
|
close s
|
|
65
64
|
end if
|
|
66
65
|
end repeat
|
|
@@ -72,12 +71,13 @@ function closeWindowsWithPath(folderPath) {
|
|
|
72
71
|
catch {
|
|
73
72
|
// iTerm not running or no matching sessions
|
|
74
73
|
}
|
|
75
|
-
// Try to close Terminal.app windows with this path
|
|
74
|
+
// Try to close Terminal.app windows with this path or issue number
|
|
76
75
|
try {
|
|
77
76
|
(0, child_process_1.execSync)(`osascript -e '
|
|
78
77
|
tell application "Terminal"
|
|
79
78
|
repeat with w in windows
|
|
80
|
-
|
|
79
|
+
set windowName to name of w
|
|
80
|
+
if windowName contains "${folderName}" or windowName contains "${issuePattern}" then
|
|
81
81
|
close w
|
|
82
82
|
end if
|
|
83
83
|
end repeat
|
|
@@ -88,6 +88,16 @@ function closeWindowsWithPath(folderPath) {
|
|
|
88
88
|
// Terminal not running or no matching windows
|
|
89
89
|
}
|
|
90
90
|
// Try to close VS Code windows with this path
|
|
91
|
+
try {
|
|
92
|
+
// Use VS Code CLI to close the folder if it's open
|
|
93
|
+
(0, child_process_1.execSync)(`code --folder-uri "file://${folderPath}" --command "workbench.action.closeWindow"`, {
|
|
94
|
+
stdio: 'pipe',
|
|
95
|
+
timeout: 3000
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// VS Code CLI method failed, try AppleScript
|
|
100
|
+
}
|
|
91
101
|
try {
|
|
92
102
|
(0, child_process_1.execSync)(`osascript -e '
|
|
93
103
|
tell application "System Events"
|
|
@@ -170,13 +180,33 @@ async function cleanAllCommand() {
|
|
|
170
180
|
const spinner = (0, ora_1.default)(`Cleaning issue #${wt.issueNumber}...`).start();
|
|
171
181
|
try {
|
|
172
182
|
// Close terminal and VS Code windows for this worktree
|
|
173
|
-
|
|
183
|
+
try {
|
|
184
|
+
closeWindowsWithPath(wt.path, wt.issueNumber);
|
|
185
|
+
// Give windows time to close before removing folder
|
|
186
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// Ignore errors closing windows
|
|
190
|
+
}
|
|
174
191
|
// Remove worktree
|
|
175
192
|
if (fs.existsSync(wt.path)) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
193
|
+
try {
|
|
194
|
+
(0, child_process_1.execSync)(`git worktree remove "${wt.path}" --force`, {
|
|
195
|
+
cwd: projectRoot,
|
|
196
|
+
stdio: 'pipe',
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// If git worktree remove fails, try removing directory manually with rm -rf
|
|
201
|
+
// This handles locked files better than fs.rmSync
|
|
202
|
+
try {
|
|
203
|
+
(0, child_process_1.execSync)(`rm -rf "${wt.path}"`, { stdio: 'pipe' });
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
fs.rmSync(wt.path, { recursive: true, force: true });
|
|
207
|
+
}
|
|
208
|
+
(0, child_process_1.execSync)('git worktree prune', { cwd: projectRoot, stdio: 'pipe' });
|
|
209
|
+
}
|
|
180
210
|
}
|
|
181
211
|
// Delete branch
|
|
182
212
|
try {
|
|
@@ -191,7 +221,7 @@ async function cleanAllCommand() {
|
|
|
191
221
|
spinner.succeed(`Cleaned issue #${wt.issueNumber}`);
|
|
192
222
|
}
|
|
193
223
|
catch (error) {
|
|
194
|
-
spinner.fail(`Failed to clean issue #${wt.issueNumber}`);
|
|
224
|
+
spinner.fail(`Failed to clean issue #${wt.issueNumber}: ${error}`);
|
|
195
225
|
}
|
|
196
226
|
}
|
|
197
227
|
// Prune stale worktrees
|
|
@@ -200,18 +230,46 @@ async function cleanAllCommand() {
|
|
|
200
230
|
console.log(chalk_1.default.green(`✅ Cleaned up ${worktrees.length} issue worktree(s)!`));
|
|
201
231
|
}
|
|
202
232
|
async function cleanCommand(issueNumber) {
|
|
203
|
-
const spinner = (0, ora_1.default)(`Fetching issue #${issueNumber}...`).start();
|
|
204
|
-
const issue = (0, github_1.getIssue)(issueNumber);
|
|
205
|
-
if (!issue) {
|
|
206
|
-
spinner.fail(`Could not find issue #${issueNumber}`);
|
|
207
|
-
process.exit(1);
|
|
208
|
-
}
|
|
209
|
-
spinner.succeed(`Found issue #${issueNumber}`);
|
|
210
233
|
const projectRoot = (0, git_1.getProjectRoot)();
|
|
211
234
|
const projectName = (0, git_1.getProjectName)();
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
const
|
|
235
|
+
// Find the worktree for this issue number (don't need to fetch from GitHub)
|
|
236
|
+
const worktrees = getIssueWorktrees();
|
|
237
|
+
const worktree = worktrees.find((wt) => wt.issueNumber === String(issueNumber));
|
|
238
|
+
if (!worktree) {
|
|
239
|
+
// Try to find by looking for the branch pattern
|
|
240
|
+
const branchPattern = `issue-${issueNumber}-`;
|
|
241
|
+
const output = (0, git_1.exec)('git branch', projectRoot);
|
|
242
|
+
const branches = output.split('\n').map((b) => b.trim().replace('* ', ''));
|
|
243
|
+
const matchingBranch = branches.find((b) => b.startsWith(branchPattern));
|
|
244
|
+
if (!matchingBranch) {
|
|
245
|
+
console.log(chalk_1.default.red(`\n❌ No worktree or branch found for issue #${issueNumber}`));
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
// Found a branch but no worktree - just delete the branch
|
|
249
|
+
console.log(chalk_1.default.bold(`\n🧹 Cleaning up issue #${issueNumber}`));
|
|
250
|
+
console.log(chalk_1.default.dim(` Branch: ${matchingBranch}`));
|
|
251
|
+
console.log(chalk_1.default.dim(` (No worktree found)`));
|
|
252
|
+
const { confirm } = await inquirer_1.default.prompt([
|
|
253
|
+
{
|
|
254
|
+
type: 'confirm',
|
|
255
|
+
name: 'confirm',
|
|
256
|
+
message: 'Delete branch?',
|
|
257
|
+
default: false,
|
|
258
|
+
},
|
|
259
|
+
]);
|
|
260
|
+
if (confirm) {
|
|
261
|
+
try {
|
|
262
|
+
(0, child_process_1.execSync)(`git branch -D "${matchingBranch}"`, { cwd: projectRoot, stdio: 'pipe' });
|
|
263
|
+
console.log(chalk_1.default.green('\n✅ Branch deleted!'));
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
console.log(chalk_1.default.yellow('\n⚠️ Could not delete branch'));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const branchName = worktree.branch;
|
|
272
|
+
const worktreePath = worktree.path;
|
|
215
273
|
console.log();
|
|
216
274
|
console.log(chalk_1.default.bold(`🧹 Cleaning up issue #${issueNumber}`));
|
|
217
275
|
console.log(chalk_1.default.dim(` Branch: ${branchName}`));
|
|
@@ -230,7 +288,16 @@ async function cleanCommand(issueNumber) {
|
|
|
230
288
|
return;
|
|
231
289
|
}
|
|
232
290
|
// Close terminal and VS Code windows for this worktree
|
|
233
|
-
|
|
291
|
+
const windowSpinner = (0, ora_1.default)('Closing terminal and VS Code windows...').start();
|
|
292
|
+
try {
|
|
293
|
+
closeWindowsWithPath(worktreePath, String(issueNumber));
|
|
294
|
+
// Give windows time to close before removing folder
|
|
295
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
296
|
+
windowSpinner.succeed('Windows closed');
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
windowSpinner.warn('Could not close some windows');
|
|
300
|
+
}
|
|
234
301
|
// Remove worktree
|
|
235
302
|
if (fs.existsSync(worktreePath)) {
|
|
236
303
|
const worktreeSpinner = (0, ora_1.default)('Removing worktree...').start();
|
|
@@ -242,7 +309,22 @@ async function cleanCommand(issueNumber) {
|
|
|
242
309
|
worktreeSpinner.succeed('Worktree removed');
|
|
243
310
|
}
|
|
244
311
|
catch {
|
|
245
|
-
|
|
312
|
+
// If git worktree remove fails, try removing directory manually with rm -rf
|
|
313
|
+
try {
|
|
314
|
+
(0, child_process_1.execSync)(`rm -rf "${worktreePath}"`, { stdio: 'pipe' });
|
|
315
|
+
(0, child_process_1.execSync)('git worktree prune', { cwd: projectRoot, stdio: 'pipe' });
|
|
316
|
+
worktreeSpinner.succeed('Worktree removed (manually)');
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
try {
|
|
320
|
+
fs.rmSync(worktreePath, { recursive: true, force: true });
|
|
321
|
+
(0, child_process_1.execSync)('git worktree prune', { cwd: projectRoot, stdio: 'pipe' });
|
|
322
|
+
worktreeSpinner.succeed('Worktree removed (manually)');
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
worktreeSpinner.warn('Could not remove worktree directory');
|
|
326
|
+
}
|
|
327
|
+
}
|
|
246
328
|
}
|
|
247
329
|
}
|
|
248
330
|
// Delete branch
|