next-issue 0.16.0 → 0.17.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/README.md CHANGED
@@ -58,8 +58,10 @@ For each open issue, oldest first:
58
58
  round gets no review. Thus `maxReviewRounds` of `1` never fixes a minor
59
59
  finding.
60
60
  10. No open finding means approval: mark the pull request ready for review and
61
- set `status:done`. The merge stays with you. The worktree, the local branch
62
- and the state file go away. The remote branch stays. A problem that the
61
+ set `status:done`. The merge stays with you, unless you pass `--merge`:
62
+ then the harness squash-merges the pull request and deletes the remote
63
+ branch. The worktree, the local branch and the state file go away. Without
64
+ `--merge`, the remote branch stays. A problem that the
63
65
  reviewer leaves out of the findings thus gets an approval: only the findings
64
66
  count.
65
67
  11. With an open finding, run the fixer agent and go to step 6 again. The
@@ -91,6 +93,8 @@ when:
91
93
  ping-pong between the fixer and the reviewer, or a finding that the fixer
92
94
  disputed and the reviewer holds to. The person then decides;
93
95
  - the reviewer gives no verdict, or the checks do not finish in time;
96
+ - with `--merge`, the merge of an approved pull request fails, for example
97
+ because branch protection asks for a human approval;
94
98
  - an agent does not finish in `agentTimeoutMinutes`;
95
99
  - the setup command fails, or does not finish in `setupTimeoutMinutes`;
96
100
  - a step of the run fails with an error.
@@ -335,6 +339,7 @@ that a label still holds back stays as it was.
335
339
  | `--once` | Stop after the first handled issue |
336
340
  | `--max <n>` | Handle at most n issues |
337
341
  | `--agent <a>` | Run the agents with `claude` or `pi`, whatever the config file says |
342
+ | `--merge` | Squash-merge the pull request after the approval, and delete the remote branch |
338
343
  | `--reset` | Drop the saved budgets and findings, and keep the rest of the state |
339
344
  | `--json` | Print the machine summary instead of the text one |
340
345
  | `--verbose` | Show every command and all agent output |
package/dist/args.mjs CHANGED
@@ -6,6 +6,7 @@ export const USAGE = `next-issue [command] [options]
6
6
  --once stop after the first handled issue
7
7
  --max <n> handle at most n issues
8
8
  --agent <a> run the agents with claude or pi
9
+ --merge squash-merge the pull request after the approval
9
10
  --reset drop the saved budgets and findings first
10
11
  --json print the machine summary instead of the text one
11
12
  --force replace an existing config file, with init
@@ -21,6 +22,7 @@ export function parseArgs(argv) {
21
22
  json: false,
22
23
  reset: false,
23
24
  force: false,
25
+ merge: false,
24
26
  level: "normal",
25
27
  };
26
28
  for (let index = 0; index < argv.length; index += 1) {
@@ -40,6 +42,9 @@ export function parseArgs(argv) {
40
42
  else if (arg === "--help") {
41
43
  args.help = true;
42
44
  }
45
+ else if (arg === "--merge") {
46
+ args.merge = true;
47
+ }
43
48
  else if (arg === "--reset") {
44
49
  args.reset = true;
45
50
  }
package/dist/cli.mjs CHANGED
@@ -62,7 +62,7 @@ async function init(root, force) {
62
62
  }
63
63
  async function handle(args, config, repo, recorder) {
64
64
  const base = await defaultBranch(repo);
65
- const context = { repo, config, base, reset: args.reset, recorder, ports: PORTS };
65
+ const context = { repo, config, base, reset: args.reset, merge: args.merge, recorder, ports: PORTS };
66
66
  recorder.event("run.start", {
67
67
  version: await packageVersion(),
68
68
  repo: `${repo.owner}/${repo.name}`,
package/dist/github.mjs CHANGED
@@ -240,6 +240,10 @@ export async function markPrReady(repo, pr) {
240
240
  });
241
241
  return result.code === 0;
242
242
  }
243
+ export async function mergePr(repo, pr) {
244
+ const result = await run("gh", ["pr", "merge", String(pr), "--squash", "--delete-branch", "--repo", slug(repo)], { cwd: repo.root });
245
+ return result.code === 0;
246
+ }
243
247
  export async function commentOnPr(repo, pr, body) {
244
248
  await gh(repo, ["pr", "comment", String(pr), "--body-file", "-"], body);
245
249
  }
package/dist/pipeline.mjs CHANGED
@@ -2,7 +2,7 @@ import { CODING, REVIEWING, runAgent } from "./agents.mjs";
2
2
  import { managedLabels } from "./config.mjs";
3
3
  import { run } from "./exec.mjs";
4
4
  import { addWorktree, branchName, commitAll, deleteBranch, diff, discardChanges, hasWorktree, isDirty, push, removeWorktree, revision, worktreePath, } from "./git.mjs";
5
- import { commentOnPr, createPr, failedCheckLogs, findPr, issueComments, markPrReady, openBlockers, setLabel, waitForChecks, } from "./github.mjs";
5
+ import { commentOnPr, createPr, failedCheckLogs, findPr, issueComments, markPrReady, mergePr, openBlockers, setLabel, waitForChecks, } from "./github.mjs";
6
6
  import { message } from "./observe.mjs";
7
7
  import { capDiff, fixPrompt, implementPrompt, parseCommitSubject, parseUnrelated, reviewPrompt, } from "./prompts.mjs";
8
8
  import { detectSetupCommand } from "./setup.mjs";
@@ -23,6 +23,7 @@ export const PORTS = {
23
23
  isDirty,
24
24
  issueComments,
25
25
  markPrReady,
26
+ mergePr,
26
27
  openBlockers,
27
28
  push,
28
29
  removeWorktree,
@@ -288,6 +289,10 @@ async function reviewRound(job) {
288
289
  if (config.draftPullRequest && !(await ports.markPrReady(repo, pr))) {
289
290
  log.event("pull-request.undraft.fail", { pr }, "quiet");
290
291
  }
292
+ if (context.merge && !(await ports.mergePr(repo, pr))) {
293
+ await escalate(job, "The merge of the pull request failed.");
294
+ return { done: true, report: await finish(job, "needs-human", "merge failed") };
295
+ }
291
296
  await setStatus(context, issue.number, pr, config.labels.done);
292
297
  return { done: true, report: await finish(job, "done") };
293
298
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-issue",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Autonomous issue harness driven by the Claude Agent SDK",
5
5
  "keywords": [
6
6
  "github",
@@ -37,10 +37,10 @@
37
37
  "prepublishOnly": "npm run typecheck && npm test"
38
38
  },
39
39
  "devDependencies": {
40
- "@types/node": "^26.6.5",
40
+ "@types/node": "^26.6.6",
41
41
  "typescript": "^7.0.2"
42
42
  },
43
43
  "dependencies": {
44
- "@anthropic-ai/claude-agent-sdk": "^0.3.310"
44
+ "@anthropic-ai/claude-agent-sdk": "^0.3.316"
45
45
  }
46
46
  }