next-issue 2.4.3 → 2.4.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/README.md CHANGED
@@ -100,13 +100,19 @@ when:
100
100
  - the fixer reports that the checks fail for a reason the change did not cause,
101
101
  such as a test already broken on the base branch or one that fails only under
102
102
  load. It changes nothing and the reason reaches the pull request, rather than
103
- the fixer spending its whole budget on a failure it cannot fix;
103
+ the fixer spending its whole budget on a failure it cannot fix. A commit it
104
+ makes anyway moves aside, as for a dispute of the findings;
104
105
  - a fixer disputes the findings and leaves a change behind, either in the
105
106
  worktree or in a commit of its own. A dispute carries a reason, not a diff,
106
107
  so the harness throws none of it away: an unclean worktree stays on the
107
- disk, and a commit of the fixer stays on the local branch. Neither is
108
- pushed, so the pull request shows no such change. It holds the reason of the
109
- dispute, and the change is on the machine that ran the harness;
108
+ disk, and a commit of the fixer moves to a new local
109
+ `<n>-dispute-<commit>` branch, so the `<n>` branch keeps only what the pull
110
+ request holds. The worktree drops the change of that commit, unless the fixer
111
+ edited the worktree after the commit: then the worktree keeps both and stays
112
+ on the disk. Neither is pushed, so the pull request shows no such change. It
113
+ holds the reason of the dispute, and the change is on the machine that ran
114
+ the harness. The `<n>-dispute-<commit>` branches go away with the `<n>`
115
+ branch when the issue is done;
110
116
  - the reviewer repeats a finding set from an earlier round, which shows a
111
117
  ping-pong between the fixer and the reviewer, or a finding that the fixer
112
118
  disputed and the reviewer holds to. The person then decides;
package/dist/git.mjs CHANGED
@@ -113,6 +113,18 @@ export async function discardChanges(cwd, target) {
113
113
  await must('git', ['clean', '-fd'], { cwd });
114
114
  return true;
115
115
  }
116
+ export async function setAside(cwd, target, branch) {
117
+ await must('git', ['branch', branch], { cwd });
118
+ if (await isDirty(cwd)) {
119
+ await must('git', ['reset', '--soft', target], { cwd });
120
+ return;
121
+ }
122
+ await discardChanges(cwd, target);
123
+ }
124
+ export async function disputeBranches(repo, branch) {
125
+ const list = await must('git', ['for-each-ref', '--format=%(refname:short)', `refs/heads/${branch}-dispute-*`], { cwd: repo.root });
126
+ return list.split('\n').filter((line) => line.length > 0);
127
+ }
116
128
  export async function push(cwd, remote, branch, force = false) {
117
129
  await must('git', ['push', '-u', ...(force ? ['--force'] : []), remote, branch], { cwd });
118
130
  }
package/dist/pipeline.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { CODING, REVIEWING, runAgent } from './agents.mjs';
2
2
  import { managedLabels } from './config.mjs';
3
3
  import { run } from './exec.mjs';
4
- import { addWorktree, branchName, commitAll, deleteBranch, diff, discardChanges, findWorktree, isDirty, push, removeWorktree, resetToBase, revision, } from './git.mjs';
4
+ import { addWorktree, branchName, commitAll, deleteBranch, diff, discardChanges, disputeBranches, findWorktree, isDirty, push, removeWorktree, resetToBase, revision, setAside, } from './git.mjs';
5
5
  import { commentOnPr, createPr, failedBaseLogs, failedCheckLogs, findPr, issueComments, markPrReady, mergeCommit, mergePr, openBlockers, openIssues, prMerged, reopenIssue, setLabel, viewIssue, waitForBaseChecks, waitForChecks, } from './github.mjs';
6
6
  import { message } from './observe.mjs';
7
7
  import { capDiff, fixPrompt, hookPrompt, implementPrompt, parseCommitSubject, parseUnrelated, reviewPrompt, } from './prompts.mjs';
@@ -17,6 +17,7 @@ export const PORTS = {
17
17
  detectSetupCommand,
18
18
  diff,
19
19
  discardChanges,
20
+ disputeBranches,
20
21
  failedBaseLogs,
21
22
  failedCheckLogs,
22
23
  findPr,
@@ -36,6 +37,7 @@ export const PORTS = {
36
37
  revision,
37
38
  runAgent,
38
39
  runSetup: async (command, cwd, timeoutMs) => run('bash', ['-lc', command], { cwd, timeoutMs }),
40
+ setAside,
39
41
  setLabel,
40
42
  viewIssue,
41
43
  waitForBaseChecks,
@@ -501,8 +503,10 @@ async function finish(job, outcome, reason) {
501
503
  const { repo, ports } = context;
502
504
  await cleanUp(context, log, branch);
503
505
  if (outcome === 'done') {
504
- if (!(await ports.deleteBranch(repo, branch))) {
505
- log.event('branch.kept', { branch }, 'quiet');
506
+ for (const name of [branch, ...(await ports.disputeBranches(repo, branch))]) {
507
+ if (!(await ports.deleteBranch(repo, name))) {
508
+ log.event('branch.kept', { branch: name }, 'quiet');
509
+ }
506
510
  }
507
511
  await dropState(repo, issue.number);
508
512
  }
@@ -531,7 +535,14 @@ async function fixRound(job, reason, detail, earlier, kind, force = false, from)
531
535
  }));
532
536
  const unrelated = parseUnrelated(result.text);
533
537
  if (unrelated !== undefined) {
534
- const stray = (await ports.revision(worktree)) !== before || (await ports.isDirty(worktree));
538
+ const disputed = await ports.revision(worktree);
539
+ const moved = disputed !== before;
540
+ if (moved) {
541
+ const aside = `${branch}-dispute-${disputed.slice(0, 7)}`;
542
+ await ports.setAside(worktree, before, aside);
543
+ log.event('fix.aside', { branch: aside }, 'quiet');
544
+ }
545
+ const stray = moved || (await ports.isDirty(worktree));
535
546
  log.event('fix.unrelated', { reason, note: unrelated, stray }, 'quiet');
536
547
  return { committed: false, unrelated, stray };
537
548
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-issue",
3
- "version": "2.4.3",
3
+ "version": "2.4.4",
4
4
  "description": "Autonomous issue harness driven by the pi SDK",
5
5
  "keywords": [
6
6
  "github",