next-issue 2.5.8 → 2.5.10

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
@@ -30,12 +30,13 @@ and exits with code 1. For each issue:
30
30
  state keeps the branch name that the state holds, and a worktree that
31
31
  holds that branch already stays in use. A branch that exists on the
32
32
  remote is the start, and a local branch that fell behind the remote is
33
- fast-forwarded. An issue with no saved state does not reuse a local
34
- `<n>` branch: it resets that branch, and any worktree that holds it, to
35
- the remote branch, or to the remote base when there is none. A
36
- fast-forward of the base that is not safe leaves the local base branch as
37
- it is and writes a `base.behind` event. A new branch then starts from the
38
- remote base.
33
+ fast-forwarded. A local branch that the remote does not hold and that has
34
+ no commits of its own starts again from the remote base. An issue with no
35
+ saved state does not reuse a local `<n>` branch: it resets that branch,
36
+ and any worktree that holds it, to the remote branch, or to the remote
37
+ base when there is none. A fast-forward of the base that is not safe
38
+ leaves the local base branch as it is and writes a `base.behind` event. A
39
+ new branch then starts from the remote base.
39
40
  4. Let the implementer agent do the work, then commit and push. When a git
40
41
  hook stops a commit, the agent that made the change gets the hook output,
41
42
  fixes it, and the harness commits again. A `commit:` line in the reply of
@@ -249,7 +250,9 @@ Three levels of console output:
249
250
  level and the extensions from your pi settings, except the `pi-next-issue`
250
251
  extension. The implementer and the fixer get the default tools of your pi
251
252
  settings, the `grep`, `find` and `ls` tools and the tools of your
252
- extensions. The reviewer gets all of them except `edit` and `write`.
253
+ extensions. The reviewer gets all of them except `edit` and `write`. The
254
+ agents run with `GIT_OPTIONAL_LOCKS=0`, so a `git status` from an agent or
255
+ an extension does not hold the index lock while the harness commits.
253
256
 
254
257
  ## Configuration
255
258
 
package/dist/agents.mjs CHANGED
@@ -17,6 +17,7 @@ export async function runAgent(recorder, request) {
17
17
  const runtime = request.runtime ?? {};
18
18
  const agentDir = runtime.agentDir ?? getAgentDir();
19
19
  const started = Date.now();
20
+ process.env.GIT_OPTIONAL_LOCKS = '0';
20
21
  log.event('agent.start', { model: request.model, timeoutMs: request.timeoutMs }, 'normal');
21
22
  const resourceLoader = new DefaultResourceLoader({
22
23
  cwd: request.cwd,
package/dist/git.mjs CHANGED
@@ -39,7 +39,7 @@ export async function addWorktree(repo, issue, branch, base, remote, start) {
39
39
  const path = existing ?? worktreePath(repo, issue);
40
40
  const target = pushed ? upstream : `${remote}/${base}`;
41
41
  if (existing === undefined) {
42
- const args = !start && (await hasBranch(repo, branch))
42
+ const args = !start && (await hasWork(repo, branch, pushed, `${remote}/${base}`))
43
43
  ? ['worktree', 'add', path, branch]
44
44
  : ['worktree', 'add', '-B', branch, path, target];
45
45
  await must('git', args, { cwd: repo.root });
@@ -52,6 +52,12 @@ export async function addWorktree(repo, issue, branch, base, remote, start) {
52
52
  }
53
53
  return { path, baseUpdated };
54
54
  }
55
+ async function hasWork(repo, branch, pushed, base) {
56
+ if (!(await hasBranch(repo, branch))) {
57
+ return false;
58
+ }
59
+ return pushed || !(await isAncestor(repo.root, branch, base));
60
+ }
55
61
  async function hasBranch(repo, name, ...flags) {
56
62
  const list = await must('git', ['branch', '--list', ...flags, name], { cwd: repo.root });
57
63
  return list.length > 0;
package/dist/github.mjs CHANGED
@@ -62,7 +62,7 @@ export async function openIssues(repo, limit, labels) {
62
62
  ISSUE_FIELDS,
63
63
  ]);
64
64
  const parsed = JSON.parse(raw);
65
- return parsed.map(toIssue).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
65
+ return parsed.map(toIssue);
66
66
  }
67
67
  export async function viewIssue(repo, issue) {
68
68
  const raw = await gh(repo, ['issue', 'view', String(issue), '--json', `${ISSUE_FIELDS},state`]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-issue",
3
- "version": "2.5.8",
3
+ "version": "2.5.10",
4
4
  "description": "Autonomous issue harness driven by the pi SDK",
5
5
  "keywords": [
6
6
  "github",