next-issue 0.12.2 → 0.12.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 +3 -1
- package/dist/config.mjs +6 -7
- package/dist/git.mjs +2 -2
- package/dist/pipeline.mjs +5 -2
- package/dist/state.mjs +1 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,7 +28,9 @@ For each open issue, oldest first:
|
|
|
28
28
|
3. Fetch the remote, fast-forward the local copy of the default branch when
|
|
29
29
|
that is safe, then add a git worktree at `../<repo>-issue-<n>` on the
|
|
30
30
|
`issue-<n>` branch. A branch that exists on the remote is the start, and a
|
|
31
|
-
local branch that fell behind the remote is fast-forwarded.
|
|
31
|
+
local branch that fell behind the remote is fast-forwarded. A fast-forward
|
|
32
|
+
of the base that is not safe leaves the local base branch as it is and
|
|
33
|
+
writes a `base.behind` event. A new branch then starts from the remote base.
|
|
32
34
|
4. Let the implementer agent do the work, then commit and push.
|
|
33
35
|
5. Open a draft pull request that closes the issue.
|
|
34
36
|
6. Wait for the checks, once the pull request shows the pushed commit. A
|
package/dist/config.mjs
CHANGED
|
@@ -26,6 +26,9 @@ const DEFAULTS = {
|
|
|
26
26
|
skip: "status:blocked",
|
|
27
27
|
},
|
|
28
28
|
};
|
|
29
|
+
function defaults() {
|
|
30
|
+
return { ...DEFAULTS, models: { ...DEFAULTS.models }, labels: { ...DEFAULTS.labels } };
|
|
31
|
+
}
|
|
29
32
|
const FIELDS = [...Object.keys(DEFAULTS), "setupCommand"];
|
|
30
33
|
const WHOLE_FIELDS = [
|
|
31
34
|
["issueLimit", 1],
|
|
@@ -44,7 +47,7 @@ const WHOLE_FIELDS = [
|
|
|
44
47
|
const MODEL_ROLES = ["implementer", "reviewer", "fixer"];
|
|
45
48
|
const LABEL_NAMES = ["ready", "inProgress", "inReview", "done", "needsHuman", "skip"];
|
|
46
49
|
const FILE_DEFAULTS = {
|
|
47
|
-
...
|
|
50
|
+
...defaults(),
|
|
48
51
|
models: Object.fromEntries(MODEL_ROLES.map((role) => [role, null])),
|
|
49
52
|
};
|
|
50
53
|
export const CONFIG_FILE = "next-issue.config.json";
|
|
@@ -69,7 +72,7 @@ export async function loadConfig(root) {
|
|
|
69
72
|
raw = await readFile(join(root, CONFIG_FILE), "utf8");
|
|
70
73
|
}
|
|
71
74
|
catch {
|
|
72
|
-
return
|
|
75
|
+
return defaults();
|
|
73
76
|
}
|
|
74
77
|
let parsed;
|
|
75
78
|
try {
|
|
@@ -87,11 +90,7 @@ export function parseConfig(value) {
|
|
|
87
90
|
throw new Error(`${CONFIG_FILE} holds an unknown field: ${key}`);
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
|
-
const config =
|
|
91
|
-
...DEFAULTS,
|
|
92
|
-
models: { ...DEFAULTS.models },
|
|
93
|
-
labels: { ...DEFAULTS.labels },
|
|
94
|
-
};
|
|
93
|
+
const config = defaults();
|
|
95
94
|
if (file.remote !== undefined) {
|
|
96
95
|
config.remote = text(file.remote, "remote", false);
|
|
97
96
|
}
|
package/dist/git.mjs
CHANGED
|
@@ -32,7 +32,7 @@ export async function addWorktree(repo, issue, base, remote) {
|
|
|
32
32
|
const branch = branchName(issue);
|
|
33
33
|
const upstream = `${remote}/${branch}`;
|
|
34
34
|
await must("git", ["fetch", remote], { cwd: repo.root });
|
|
35
|
-
await updateBase(repo, base, remote);
|
|
35
|
+
const baseUpdated = await updateBase(repo, base, remote);
|
|
36
36
|
await must("git", ["worktree", "prune"], { cwd: repo.root });
|
|
37
37
|
const pushed = await hasBranch(repo, upstream, "--remotes");
|
|
38
38
|
if (!(await hasWorktree(repo, path))) {
|
|
@@ -44,7 +44,7 @@ export async function addWorktree(repo, issue, base, remote) {
|
|
|
44
44
|
if (pushed) {
|
|
45
45
|
await run("git", ["merge", "--ff-only", upstream], { cwd: path });
|
|
46
46
|
}
|
|
47
|
-
return path;
|
|
47
|
+
return { path, baseUpdated };
|
|
48
48
|
}
|
|
49
49
|
async function hasBranch(repo, name, ...flags) {
|
|
50
50
|
const list = await must("git", ["branch", "--list", ...flags, name], { cwd: repo.root });
|
package/dist/pipeline.mjs
CHANGED
|
@@ -102,7 +102,11 @@ async function work(context, issue, log, state) {
|
|
|
102
102
|
await writeState(repo, state);
|
|
103
103
|
});
|
|
104
104
|
const comments = await log.step("comments", {}, () => ports.issueComments(repo, issue.number));
|
|
105
|
-
const
|
|
105
|
+
const added = await log.step("worktree", { branch }, () => ports.addWorktree(repo, issue.number, context.base, config.remote));
|
|
106
|
+
const worktree = added.path;
|
|
107
|
+
if (!added.baseUpdated) {
|
|
108
|
+
log.event("base.behind", { base: context.base }, "quiet");
|
|
109
|
+
}
|
|
106
110
|
const job = { context, issue, log, state, branch, worktree, comments };
|
|
107
111
|
const escalate = (reason) => handOver(context, log, issue.number, state, reason);
|
|
108
112
|
const finish = async (outcome, reason) => {
|
|
@@ -328,7 +332,6 @@ async function cleanUp(context, log, issue) {
|
|
|
328
332
|
}
|
|
329
333
|
async function handOver(context, log, issue, state, reason) {
|
|
330
334
|
log.event("hand-over", { reason }, "quiet");
|
|
331
|
-
state.handedOver = true;
|
|
332
335
|
await writeState(context.repo, state);
|
|
333
336
|
await setStatus(context, issue, state.pr, context.config.labels.needsHuman);
|
|
334
337
|
if (state.pr !== undefined) {
|
package/dist/state.mjs
CHANGED
|
@@ -16,9 +16,7 @@ export async function readState(repo, issue) {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
export function resetState(state) {
|
|
19
|
-
|
|
20
|
-
delete next.handedOver;
|
|
21
|
-
return next;
|
|
19
|
+
return { ...state, ciFixes: 0, reviewRounds: 0, reviewLog: [] };
|
|
22
20
|
}
|
|
23
21
|
export async function writeState(repo, state) {
|
|
24
22
|
await mkdir(dir(repo), { recursive: true });
|