claude-issue-solver 1.29.0 â 1.30.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/select.d.ts +1 -3
- package/dist/commands/select.js +3 -3
- package/dist/commands/solve.d.ts +1 -3
- package/dist/commands/solve.js +3 -173
- package/dist/index.js +3 -4
- package/package.json +1 -1
package/dist/commands/select.js
CHANGED
|
@@ -9,7 +9,7 @@ const inquirer_1 = __importDefault(require("inquirer"));
|
|
|
9
9
|
const github_1 = require("../utils/github");
|
|
10
10
|
const git_1 = require("../utils/git");
|
|
11
11
|
const solve_1 = require("./solve");
|
|
12
|
-
async function selectCommand(
|
|
12
|
+
async function selectCommand() {
|
|
13
13
|
const projectName = (0, git_1.getProjectName)();
|
|
14
14
|
console.log(chalk_1.default.bold(`\nOpen issues for ${projectName}:\n`));
|
|
15
15
|
const issues = (0, github_1.listIssues)();
|
|
@@ -42,9 +42,9 @@ async function selectCommand(options = {}) {
|
|
|
42
42
|
console.log(chalk_1.default.dim('No issues selected.'));
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
|
-
console.log(chalk_1.default.cyan(`\nStarting ${issueNumbers.length} issue(s)
|
|
45
|
+
console.log(chalk_1.default.cyan(`\nStarting ${issueNumbers.length} issue(s)...\n`));
|
|
46
46
|
for (const issueNumber of issueNumbers) {
|
|
47
|
-
await (0, solve_1.solveCommand)(issueNumber
|
|
47
|
+
await (0, solve_1.solveCommand)(issueNumber);
|
|
48
48
|
console.log();
|
|
49
49
|
}
|
|
50
50
|
}
|
package/dist/commands/solve.d.ts
CHANGED
package/dist/commands/solve.js
CHANGED
|
@@ -45,8 +45,7 @@ const child_process_1 = require("child_process");
|
|
|
45
45
|
const github_1 = require("../utils/github");
|
|
46
46
|
const git_1 = require("../utils/git");
|
|
47
47
|
const helpers_1 = require("../utils/helpers");
|
|
48
|
-
|
|
49
|
-
async function solveCommand(issueNumber, options = {}) {
|
|
48
|
+
async function solveCommand(issueNumber) {
|
|
50
49
|
const spinner = (0, ora_1.default)(`Fetching issue #${issueNumber}...`).start();
|
|
51
50
|
const issue = (0, github_1.getIssue)(issueNumber);
|
|
52
51
|
if (!issue) {
|
|
@@ -123,9 +122,6 @@ Instructions:
|
|
|
123
122
|
// Write prompt to a file to avoid shell escaping issues with backticks, <>, etc.
|
|
124
123
|
const promptFile = path.join(worktreePath, '.claude-prompt.txt');
|
|
125
124
|
fs.writeFileSync(promptFile, prompt);
|
|
126
|
-
// Get bot token for auto mode
|
|
127
|
-
const botToken = (0, config_1.getBotToken)();
|
|
128
|
-
const autoMode = options.auto || false;
|
|
129
125
|
// Create runner script
|
|
130
126
|
const runnerScript = path.join(worktreePath, '.claude-runner.sh');
|
|
131
127
|
const runnerContent = `#!/bin/bash
|
|
@@ -137,17 +133,11 @@ echo -ne "\\033]0;Issue #${issueNumber}: ${issue.title.replace(/"/g, '\\"').slic
|
|
|
137
133
|
echo "đ¤ Claude Code - Issue #${issueNumber}: ${issue.title}"
|
|
138
134
|
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
139
135
|
echo ""
|
|
140
|
-
|
|
141
|
-
echo " Max 3 iterations. No user input required."
|
|
142
|
-
${!botToken ? 'echo "â ī¸ No bot token configured. Run: cis config bot-token"' : ''}` : 'echo "When Claude commits, a PR will be created automatically."'}
|
|
136
|
+
echo "When Claude commits, a PR will be created automatically."
|
|
143
137
|
echo "The terminal stays open for follow-up changes."
|
|
144
138
|
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
145
139
|
echo ""
|
|
146
140
|
|
|
147
|
-
${botToken ? `# Bot token for reviews (only used during review, not PR creation)
|
|
148
|
-
export BOT_TOKEN="${botToken}"
|
|
149
|
-
` : ''}
|
|
150
|
-
|
|
151
141
|
# Function to create PR
|
|
152
142
|
create_pr() {
|
|
153
143
|
COMMITS=$(git log origin/${baseBranch}..HEAD --oneline 2>/dev/null | wc -l | tr -d ' ')
|
|
@@ -192,7 +182,6 @@ $COMMIT_LIST
|
|
|
192
182
|
# Update terminal title with PR info
|
|
193
183
|
PR_NUM=$(echo "$PR_URL" | grep -oE '[0-9]+$')
|
|
194
184
|
echo -ne "\\033]0;Issue #${issueNumber} â PR #\$PR_NUM\\007"
|
|
195
|
-
echo "$PR_NUM"
|
|
196
185
|
fi
|
|
197
186
|
else
|
|
198
187
|
# PR exists, just push new commits
|
|
@@ -202,169 +191,11 @@ $COMMIT_LIST
|
|
|
202
191
|
echo "đ¤ Pushed new commits to PR #$EXISTING_PR"
|
|
203
192
|
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
204
193
|
echo ""
|
|
205
|
-
echo "$EXISTING_PR"
|
|
206
194
|
fi
|
|
207
195
|
fi
|
|
208
196
|
}
|
|
209
197
|
|
|
210
|
-
#
|
|
211
|
-
get_pr_number() {
|
|
212
|
-
gh pr list --head "${branchName}" --json number --jq '.[0].number' 2>/dev/null
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
# Function to get PR review status
|
|
216
|
-
get_review_status() {
|
|
217
|
-
gh pr view "$1" --json reviewDecision --jq '.reviewDecision' 2>/dev/null
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
${autoMode ? `# AUTO MODE: Non-interactive solve â review â fix loop
|
|
221
|
-
echo ""
|
|
222
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
223
|
-
echo "đ STEP 1: Solving issue..."
|
|
224
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
225
|
-
echo ""
|
|
226
|
-
|
|
227
|
-
# Run Claude non-interactively to solve
|
|
228
|
-
claude -p --dangerously-skip-permissions "$(cat '${promptFile}')"
|
|
229
|
-
|
|
230
|
-
# Clean up prompt file
|
|
231
|
-
rm -f '${promptFile}'
|
|
232
|
-
|
|
233
|
-
# Create PR
|
|
234
|
-
echo ""
|
|
235
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
236
|
-
echo "đ¤ Creating PR..."
|
|
237
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
238
|
-
create_pr
|
|
239
|
-
|
|
240
|
-
# Review loop
|
|
241
|
-
MAX_ITERATIONS=3
|
|
242
|
-
ITERATION=0
|
|
243
|
-
|
|
244
|
-
while [ $ITERATION -lt $MAX_ITERATIONS ]; do
|
|
245
|
-
ITERATION=$((ITERATION + 1))
|
|
246
|
-
|
|
247
|
-
sleep 2
|
|
248
|
-
PR_NUM=$(get_pr_number)
|
|
249
|
-
|
|
250
|
-
if [ -z "$PR_NUM" ]; then
|
|
251
|
-
echo ""
|
|
252
|
-
echo "â ī¸ No PR found, skipping auto-review"
|
|
253
|
-
break
|
|
254
|
-
fi
|
|
255
|
-
|
|
256
|
-
echo ""
|
|
257
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
258
|
-
echo "đ STEP 2: Review iteration $ITERATION of $MAX_ITERATIONS"
|
|
259
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
260
|
-
echo ""
|
|
261
|
-
|
|
262
|
-
# Get PR diff for review
|
|
263
|
-
PR_DIFF=$(gh pr diff $PR_NUM 2>/dev/null | head -500)
|
|
264
|
-
|
|
265
|
-
# Write review prompt to file (avoid escaping issues)
|
|
266
|
-
REVIEW_FILE=".claude-review-prompt.txt"
|
|
267
|
-
cat > "$REVIEW_FILE" << 'REVIEW_EOF'
|
|
268
|
-
You are reviewing a PR. Your task is to review the code and leave feedback using the gh CLI.
|
|
269
|
-
|
|
270
|
-
IMPORTANT: You must run ONE of these commands before finishing:
|
|
271
|
-
${botToken ? `
|
|
272
|
-
To APPROVE (if code looks good):
|
|
273
|
-
GH_TOKEN=$BOT_TOKEN gh pr review PR_NUM --approve --body "LGTM! Code looks good."
|
|
274
|
-
|
|
275
|
-
To REQUEST CHANGES (if issues found):
|
|
276
|
-
GH_TOKEN=$BOT_TOKEN gh pr review PR_NUM --request-changes --body "Your detailed feedback here"
|
|
277
|
-
` : `
|
|
278
|
-
To APPROVE (if code looks good):
|
|
279
|
-
gh pr review PR_NUM --approve --body "LGTM! Code looks good."
|
|
280
|
-
|
|
281
|
-
To REQUEST CHANGES (if issues found):
|
|
282
|
-
gh pr review PR_NUM --request-changes --body "Your detailed feedback here"
|
|
283
|
-
`}
|
|
284
|
-
Review criteria:
|
|
285
|
-
1. Does the code solve the issue correctly?
|
|
286
|
-
2. Are there bugs or logic errors?
|
|
287
|
-
3. Security vulnerabilities?
|
|
288
|
-
4. Missing error handling?
|
|
289
|
-
5. Code quality issues?
|
|
290
|
-
|
|
291
|
-
REVIEW_EOF
|
|
292
|
-
|
|
293
|
-
# Append issue and diff info
|
|
294
|
-
echo "" >> "$REVIEW_FILE"
|
|
295
|
-
echo "## Issue #${issueNumber}: ${issue.title.replace(/"/g, '\\"')}" >> "$REVIEW_FILE"
|
|
296
|
-
echo "${issue.body.replace(/"/g, '\\"').replace(/\$/g, '\\$').replace(/\`/g, '\\`')}" >> "$REVIEW_FILE"
|
|
297
|
-
echo "" >> "$REVIEW_FILE"
|
|
298
|
-
echo "## PR Diff:" >> "$REVIEW_FILE"
|
|
299
|
-
echo "\\\`\\\`\\\`diff" >> "$REVIEW_FILE"
|
|
300
|
-
echo "$PR_DIFF" >> "$REVIEW_FILE"
|
|
301
|
-
echo "\\\`\\\`\\\`" >> "$REVIEW_FILE"
|
|
302
|
-
|
|
303
|
-
# Replace PR_NUM placeholder
|
|
304
|
-
sed -i '' "s/PR_NUM/$PR_NUM/g" "$REVIEW_FILE" 2>/dev/null || sed -i "s/PR_NUM/$PR_NUM/g" "$REVIEW_FILE"
|
|
305
|
-
|
|
306
|
-
# Run Claude for review (non-interactive)
|
|
307
|
-
claude -p --dangerously-skip-permissions "$(cat "$REVIEW_FILE")"
|
|
308
|
-
rm -f "$REVIEW_FILE"
|
|
309
|
-
|
|
310
|
-
# Check review status
|
|
311
|
-
sleep 2
|
|
312
|
-
REVIEW_STATUS=$(get_review_status $PR_NUM)
|
|
313
|
-
|
|
314
|
-
echo ""
|
|
315
|
-
echo "đ Review status: $REVIEW_STATUS"
|
|
316
|
-
|
|
317
|
-
if [ "$REVIEW_STATUS" = "APPROVED" ]; then
|
|
318
|
-
echo ""
|
|
319
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
320
|
-
echo "â
PR APPROVED! Ready to merge."
|
|
321
|
-
echo " Run: cis merge"
|
|
322
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
323
|
-
break
|
|
324
|
-
elif [ "$REVIEW_STATUS" = "CHANGES_REQUESTED" ]; then
|
|
325
|
-
if [ $ITERATION -lt $MAX_ITERATIONS ]; then
|
|
326
|
-
echo ""
|
|
327
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
328
|
-
echo "đ§ STEP 3: Fixing requested changes..."
|
|
329
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
330
|
-
echo ""
|
|
331
|
-
|
|
332
|
-
# Get the review comments
|
|
333
|
-
REVIEW_COMMENTS=$(gh pr view $PR_NUM --json reviews --jq '.reviews[-1].body' 2>/dev/null)
|
|
334
|
-
|
|
335
|
-
# Write fix prompt to file
|
|
336
|
-
FIX_FILE=".claude-fix-prompt.txt"
|
|
337
|
-
cat > "$FIX_FILE" << FIX_EOF
|
|
338
|
-
The code review requested changes. Please fix them and commit.
|
|
339
|
-
|
|
340
|
-
## Review Feedback
|
|
341
|
-
$REVIEW_COMMENTS
|
|
342
|
-
|
|
343
|
-
Please address the feedback above, make the necessary changes, and commit them.
|
|
344
|
-
FIX_EOF
|
|
345
|
-
|
|
346
|
-
# Run Claude to fix (non-interactive)
|
|
347
|
-
claude -p --dangerously-skip-permissions "$(cat "$FIX_FILE")"
|
|
348
|
-
rm -f "$FIX_FILE"
|
|
349
|
-
|
|
350
|
-
# Push changes
|
|
351
|
-
git push origin "${branchName}" 2>/dev/null
|
|
352
|
-
sleep 2
|
|
353
|
-
else
|
|
354
|
-
echo ""
|
|
355
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
356
|
-
echo "â ī¸ Max iterations reached. Manual review needed."
|
|
357
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
358
|
-
fi
|
|
359
|
-
else
|
|
360
|
-
echo ""
|
|
361
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
362
|
-
echo "âšī¸ Review status: $REVIEW_STATUS"
|
|
363
|
-
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
|
364
|
-
break
|
|
365
|
-
fi
|
|
366
|
-
done
|
|
367
|
-
` : `# INTERACTIVE MODE: Watch for commits and create PR automatically
|
|
198
|
+
# Watch for new commits in background and create PR
|
|
368
199
|
LAST_COMMIT=""
|
|
369
200
|
while true; do
|
|
370
201
|
CURRENT_COMMIT=$(git rev-parse HEAD 2>/dev/null)
|
|
@@ -387,7 +218,6 @@ kill $WATCHER_PID 2>/dev/null
|
|
|
387
218
|
|
|
388
219
|
# Final PR check after Claude exits
|
|
389
220
|
create_pr > /dev/null
|
|
390
|
-
`}
|
|
391
221
|
|
|
392
222
|
echo ""
|
|
393
223
|
echo "ââââââââââââââââââââââââââââââââââââââââââââââââ"
|
package/dist/index.js
CHANGED
|
@@ -52,18 +52,17 @@ program.hook('preAction', (thisCommand) => {
|
|
|
52
52
|
// Default command - interactive selection
|
|
53
53
|
program
|
|
54
54
|
.argument('[issue]', 'Issue number to solve')
|
|
55
|
-
.
|
|
56
|
-
.action(async (issue, options) => {
|
|
55
|
+
.action(async (issue) => {
|
|
57
56
|
if (issue) {
|
|
58
57
|
const issueNumber = parseInt(issue, 10);
|
|
59
58
|
if (isNaN(issueNumber)) {
|
|
60
59
|
console.log(chalk_1.default.red(`â Invalid issue number: ${issue}`));
|
|
61
60
|
process.exit(1);
|
|
62
61
|
}
|
|
63
|
-
await (0, solve_1.solveCommand)(issueNumber
|
|
62
|
+
await (0, solve_1.solveCommand)(issueNumber);
|
|
64
63
|
}
|
|
65
64
|
else {
|
|
66
|
-
await (0, select_1.selectCommand)(
|
|
65
|
+
await (0, select_1.selectCommand)();
|
|
67
66
|
}
|
|
68
67
|
});
|
|
69
68
|
// List command
|