claude-issue-solver 1.16.0 โ 1.18.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.js +10 -10
- package/dist/commands/pr.js +2 -1
- package/dist/commands/solve.js +10 -9
- package/dist/utils/git.d.ts +1 -0
- package/dist/utils/git.js +26 -2
- package/dist/utils/github.d.ts +2 -0
- package/dist/utils/github.js +31 -0
- package/package.json +1 -1
package/dist/commands/clean.js
CHANGED
|
@@ -236,13 +236,13 @@ async function cleanAllCommand() {
|
|
|
236
236
|
console.log(chalk_1.default.yellow(` Run this command from the main project directory for best results.`));
|
|
237
237
|
console.log(chalk_1.default.dim(` cd ${projectRoot}\n`));
|
|
238
238
|
}
|
|
239
|
-
// Fetch status for all worktrees
|
|
239
|
+
// Fetch status for all worktrees in parallel
|
|
240
240
|
const statusSpinner = (0, ora_1.default)('Fetching issue and PR status...').start();
|
|
241
|
-
const worktreesWithStatus = worktrees.map((wt) => ({
|
|
241
|
+
const worktreesWithStatus = await Promise.all(worktrees.map(async (wt) => ({
|
|
242
242
|
...wt,
|
|
243
|
-
issueStatus: (0, github_1.
|
|
244
|
-
prStatus: wt.branch ? (0, github_1.
|
|
245
|
-
}));
|
|
243
|
+
issueStatus: await (0, github_1.getIssueStatusAsync)(parseInt(wt.issueNumber, 10)),
|
|
244
|
+
prStatus: wt.branch ? await (0, github_1.getPRForBranchAsync)(wt.branch) : null,
|
|
245
|
+
})));
|
|
246
246
|
statusSpinner.stop();
|
|
247
247
|
console.log(chalk_1.default.bold('\n๐งน Found issue worktrees:\n'));
|
|
248
248
|
for (const wt of worktreesWithStatus) {
|
|
@@ -516,13 +516,13 @@ async function cleanMergedCommand() {
|
|
|
516
516
|
console.log(chalk_1.default.yellow(` Run this command from the main project directory for best results.`));
|
|
517
517
|
console.log(chalk_1.default.dim(` cd ${projectRoot}\n`));
|
|
518
518
|
}
|
|
519
|
-
// Fetch status for all worktrees
|
|
519
|
+
// Fetch status for all worktrees in parallel
|
|
520
520
|
const statusSpinner = (0, ora_1.default)('Fetching PR status...').start();
|
|
521
|
-
const worktreesWithStatus = worktrees.map((wt) => ({
|
|
521
|
+
const worktreesWithStatus = await Promise.all(worktrees.map(async (wt) => ({
|
|
522
522
|
...wt,
|
|
523
|
-
issueStatus: (0, github_1.
|
|
524
|
-
prStatus: wt.branch ? (0, github_1.
|
|
525
|
-
}));
|
|
523
|
+
issueStatus: await (0, github_1.getIssueStatusAsync)(parseInt(wt.issueNumber, 10)),
|
|
524
|
+
prStatus: wt.branch ? await (0, github_1.getPRForBranchAsync)(wt.branch) : null,
|
|
525
|
+
})));
|
|
526
526
|
statusSpinner.stop();
|
|
527
527
|
// Filter to only merged PRs
|
|
528
528
|
const mergedWorktrees = worktreesWithStatus.filter((wt) => wt.prStatus?.state === 'merged');
|
package/dist/commands/pr.js
CHANGED
|
@@ -105,7 +105,8 @@ ${commitList}
|
|
|
105
105
|
---
|
|
106
106
|
|
|
107
107
|
๐ค Generated with [Claude Code](https://claude.com/claude-code)`;
|
|
108
|
-
const
|
|
108
|
+
const baseBranch = (0, git_1.getDefaultBranch)();
|
|
109
|
+
const prUrl = (0, child_process_1.execSync)(`gh pr create --title "Fix #${issueNumber}: ${issue.title.replace(/"/g, '\\"')}" --body "${prBody.replace(/"/g, '\\"')}" --head "${branchName}" --base ${baseBranch}`, { cwd: worktreePath, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
109
110
|
pushSpinner.succeed('PR created!');
|
|
110
111
|
console.log();
|
|
111
112
|
console.log(chalk_1.default.green(`โ
PR created: ${prUrl}`));
|
package/dist/commands/solve.js
CHANGED
|
@@ -59,17 +59,18 @@ async function solveCommand(issueNumber) {
|
|
|
59
59
|
console.log();
|
|
60
60
|
const projectRoot = (0, git_1.getProjectRoot)();
|
|
61
61
|
const projectName = (0, git_1.getProjectName)();
|
|
62
|
+
const baseBranch = (0, git_1.getDefaultBranch)();
|
|
62
63
|
const branchSlug = (0, helpers_1.slugify)(issue.title);
|
|
63
64
|
const branchName = `issue-${issueNumber}-${branchSlug}`;
|
|
64
65
|
const worktreePath = path.join(path.dirname(projectRoot), `${projectName}-${branchName}`);
|
|
65
|
-
// Fetch latest
|
|
66
|
-
const fetchSpinner = (0, ora_1.default)(
|
|
66
|
+
// Fetch latest base branch
|
|
67
|
+
const fetchSpinner = (0, ora_1.default)(`Fetching latest ${baseBranch}...`).start();
|
|
67
68
|
try {
|
|
68
|
-
(0, child_process_1.execSync)(
|
|
69
|
-
fetchSpinner.succeed(
|
|
69
|
+
(0, child_process_1.execSync)(`git fetch origin ${baseBranch} --quiet`, { cwd: projectRoot, stdio: 'pipe' });
|
|
70
|
+
fetchSpinner.succeed(`Fetched latest ${baseBranch}`);
|
|
70
71
|
}
|
|
71
72
|
catch {
|
|
72
|
-
fetchSpinner.warn(
|
|
73
|
+
fetchSpinner.warn(`Could not fetch origin/${baseBranch}`);
|
|
73
74
|
}
|
|
74
75
|
// Check if worktree already exists
|
|
75
76
|
if (fs.existsSync(worktreePath)) {
|
|
@@ -86,7 +87,7 @@ async function solveCommand(issueNumber) {
|
|
|
86
87
|
});
|
|
87
88
|
}
|
|
88
89
|
else {
|
|
89
|
-
(0, child_process_1.execSync)(`git worktree add "${worktreePath}" -b "${branchName}" origin
|
|
90
|
+
(0, child_process_1.execSync)(`git worktree add "${worktreePath}" -b "${branchName}" origin/${baseBranch}`, {
|
|
90
91
|
cwd: projectRoot,
|
|
91
92
|
stdio: 'pipe',
|
|
92
93
|
});
|
|
@@ -139,7 +140,7 @@ echo ""
|
|
|
139
140
|
|
|
140
141
|
# Function to create PR
|
|
141
142
|
create_pr() {
|
|
142
|
-
COMMITS=$(git log origin
|
|
143
|
+
COMMITS=$(git log origin/${baseBranch}..HEAD --oneline 2>/dev/null | wc -l | tr -d ' ')
|
|
143
144
|
|
|
144
145
|
if [ "$COMMITS" -gt 0 ]; then
|
|
145
146
|
# Check if PR already exists
|
|
@@ -151,7 +152,7 @@ create_pr() {
|
|
|
151
152
|
|
|
152
153
|
git push -u origin "${branchName}" 2>/dev/null
|
|
153
154
|
|
|
154
|
-
COMMIT_LIST=$(git log origin
|
|
155
|
+
COMMIT_LIST=$(git log origin/${baseBranch}..HEAD --pretty=format:'- %s' | head -10)
|
|
155
156
|
|
|
156
157
|
PR_URL=$(gh pr create \\
|
|
157
158
|
--title "Fix #${issueNumber}: ${issue.title.replace(/"/g, '\\"')}" \\
|
|
@@ -167,7 +168,7 @@ $COMMIT_LIST
|
|
|
167
168
|
|
|
168
169
|
๐ค Generated with [Claude Code](https://claude.com/claude-code)" \\
|
|
169
170
|
--head "${branchName}" \\
|
|
170
|
-
--base
|
|
171
|
+
--base ${baseBranch} 2>/dev/null)
|
|
171
172
|
|
|
172
173
|
if [ -n "$PR_URL" ]; then
|
|
173
174
|
echo ""
|
package/dist/utils/git.d.ts
CHANGED
|
@@ -4,5 +4,6 @@ export declare function getProjectRoot(): string;
|
|
|
4
4
|
export declare function getProjectName(): string;
|
|
5
5
|
export declare function isGitRepo(): boolean;
|
|
6
6
|
export declare function branchExists(branchName: string): boolean;
|
|
7
|
+
export declare function getDefaultBranch(): string;
|
|
7
8
|
export declare function getCommitCount(worktreePath: string): number;
|
|
8
9
|
export declare function getCommitList(worktreePath: string, limit?: number): string;
|
package/dist/utils/git.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.getProjectRoot = getProjectRoot;
|
|
|
6
6
|
exports.getProjectName = getProjectName;
|
|
7
7
|
exports.isGitRepo = isGitRepo;
|
|
8
8
|
exports.branchExists = branchExists;
|
|
9
|
+
exports.getDefaultBranch = getDefaultBranch;
|
|
9
10
|
exports.getCommitCount = getCommitCount;
|
|
10
11
|
exports.getCommitList = getCommitList;
|
|
11
12
|
const child_process_1 = require("child_process");
|
|
@@ -69,9 +70,31 @@ function branchExists(branchName) {
|
|
|
69
70
|
return false;
|
|
70
71
|
}
|
|
71
72
|
}
|
|
73
|
+
function getDefaultBranch() {
|
|
74
|
+
// Try to get from remote HEAD
|
|
75
|
+
try {
|
|
76
|
+
const output = exec('git symbolic-ref refs/remotes/origin/HEAD');
|
|
77
|
+
if (output) {
|
|
78
|
+
// Output is like "refs/remotes/origin/main" or "refs/remotes/origin/develop"
|
|
79
|
+
const match = output.match(/refs\/remotes\/origin\/(.+)/);
|
|
80
|
+
if (match) {
|
|
81
|
+
return match[1];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Ignore
|
|
87
|
+
}
|
|
88
|
+
// Fallback: check if develop exists, otherwise main
|
|
89
|
+
if (branchExists('develop') || exec('git ls-remote --heads origin develop')) {
|
|
90
|
+
return 'develop';
|
|
91
|
+
}
|
|
92
|
+
return 'main';
|
|
93
|
+
}
|
|
72
94
|
function getCommitCount(worktreePath) {
|
|
73
95
|
try {
|
|
74
|
-
const
|
|
96
|
+
const baseBranch = getDefaultBranch();
|
|
97
|
+
const output = exec(`git log origin/${baseBranch}..HEAD --oneline`, worktreePath);
|
|
75
98
|
if (!output)
|
|
76
99
|
return 0;
|
|
77
100
|
return output.split('\n').filter(Boolean).length;
|
|
@@ -81,5 +104,6 @@ function getCommitCount(worktreePath) {
|
|
|
81
104
|
}
|
|
82
105
|
}
|
|
83
106
|
function getCommitList(worktreePath, limit = 10) {
|
|
84
|
-
|
|
107
|
+
const baseBranch = getDefaultBranch();
|
|
108
|
+
return exec(`git log origin/${baseBranch}..HEAD --pretty=format:'- %s' | head -${limit}`, worktreePath);
|
|
85
109
|
}
|
package/dist/utils/github.d.ts
CHANGED
|
@@ -25,7 +25,9 @@ export interface PRStatus {
|
|
|
25
25
|
url: string;
|
|
26
26
|
}
|
|
27
27
|
export declare function getIssueStatus(issueNumber: number): IssueStatus | null;
|
|
28
|
+
export declare function getIssueStatusAsync(issueNumber: number): Promise<IssueStatus | null>;
|
|
28
29
|
export declare function getPRForBranch(branch: string): PRStatus | null;
|
|
30
|
+
export declare function getPRForBranchAsync(branch: string): Promise<PRStatus | null>;
|
|
29
31
|
/**
|
|
30
32
|
* Get all open PRs with their head branch names (single API call)
|
|
31
33
|
* Returns a Set of issue numbers that have open PRs from issue-{number}-* branches
|
package/dist/utils/github.js
CHANGED
|
@@ -5,9 +5,13 @@ exports.getIssue = getIssue;
|
|
|
5
5
|
exports.listIssues = listIssues;
|
|
6
6
|
exports.createPullRequest = createPullRequest;
|
|
7
7
|
exports.getIssueStatus = getIssueStatus;
|
|
8
|
+
exports.getIssueStatusAsync = getIssueStatusAsync;
|
|
8
9
|
exports.getPRForBranch = getPRForBranch;
|
|
10
|
+
exports.getPRForBranchAsync = getPRForBranchAsync;
|
|
9
11
|
exports.getIssuesWithOpenPRs = getIssuesWithOpenPRs;
|
|
10
12
|
const child_process_1 = require("child_process");
|
|
13
|
+
const util_1 = require("util");
|
|
14
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
11
15
|
function createIssue(title, body, labels) {
|
|
12
16
|
try {
|
|
13
17
|
let cmd = `gh issue create --title "${title.replace(/"/g, '\\"')}"`;
|
|
@@ -71,6 +75,18 @@ function getIssueStatus(issueNumber) {
|
|
|
71
75
|
return null;
|
|
72
76
|
}
|
|
73
77
|
}
|
|
78
|
+
async function getIssueStatusAsync(issueNumber) {
|
|
79
|
+
try {
|
|
80
|
+
const { stdout } = await execAsync(`gh issue view ${issueNumber} --json state`);
|
|
81
|
+
const data = JSON.parse(stdout);
|
|
82
|
+
return {
|
|
83
|
+
state: data.state.toLowerCase(),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
74
90
|
function getPRForBranch(branch) {
|
|
75
91
|
try {
|
|
76
92
|
const output = (0, child_process_1.execSync)(`gh pr list --head "${branch}" --state all --json state,url --limit 1`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
@@ -86,6 +102,21 @@ function getPRForBranch(branch) {
|
|
|
86
102
|
return null;
|
|
87
103
|
}
|
|
88
104
|
}
|
|
105
|
+
async function getPRForBranchAsync(branch) {
|
|
106
|
+
try {
|
|
107
|
+
const { stdout } = await execAsync(`gh pr list --head "${branch}" --state all --json state,url --limit 1`);
|
|
108
|
+
const data = JSON.parse(stdout);
|
|
109
|
+
if (data.length === 0)
|
|
110
|
+
return null;
|
|
111
|
+
return {
|
|
112
|
+
state: data[0].state.toLowerCase(),
|
|
113
|
+
url: data[0].url,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
89
120
|
/**
|
|
90
121
|
* Get all open PRs with their head branch names (single API call)
|
|
91
122
|
* Returns a Set of issue numbers that have open PRs from issue-{number}-* branches
|