next-issue 2.17.0 → 2.19.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 +7 -6
- package/dist/agents.mjs +6 -2
- package/dist/fix.mjs +10 -7
- package/dist/progress.mjs +19 -6
- package/dist/review.mjs +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -304,12 +304,13 @@ Three levels of console output:
|
|
|
304
304
|
- Node 24 or later
|
|
305
305
|
- `gh`, authenticated with write access to the repository
|
|
306
306
|
- pi, logged in to a model provider. The agents use the model, the thinking
|
|
307
|
-
level and the
|
|
308
|
-
extension
|
|
309
|
-
settings, the `grep`, `find` and `ls` tools
|
|
310
|
-
extensions. The reviewer gets all of them except
|
|
311
|
-
agents run with `GIT_OPTIONAL_LOCKS=0`, so a
|
|
312
|
-
an extension does not hold the index lock
|
|
307
|
+
level, the extensions and the skills from your pi settings, except the
|
|
308
|
+
extension and the skills of `pi-next-issue`. The implementer and the fixer
|
|
309
|
+
get the default tools of your pi settings, the `grep`, `find` and `ls` tools
|
|
310
|
+
and the tools of your extensions. The reviewer gets all of them except
|
|
311
|
+
`edit` and `write`. The agents run with `GIT_OPTIONAL_LOCKS=0`, so a
|
|
312
|
+
`git status` from an agent or an extension does not hold the index lock
|
|
313
|
+
while the harness commits.
|
|
313
314
|
|
|
314
315
|
## Configuration
|
|
315
316
|
|
package/dist/agents.mjs
CHANGED
|
@@ -9,7 +9,7 @@ const CODING = {
|
|
|
9
9
|
tools: ['+grep', '+find', '+ls'],
|
|
10
10
|
};
|
|
11
11
|
export { CODING, REVIEWING };
|
|
12
|
-
export function
|
|
12
|
+
export function isOwnResource(path) {
|
|
13
13
|
return path.split(sep).includes('pi-next-issue');
|
|
14
14
|
}
|
|
15
15
|
export async function runAgent(recorder, request) {
|
|
@@ -24,7 +24,11 @@ export async function runAgent(recorder, request) {
|
|
|
24
24
|
agentDir,
|
|
25
25
|
extensionsOverride: (base) => ({
|
|
26
26
|
...base,
|
|
27
|
-
extensions: base.extensions.filter((extension) => !
|
|
27
|
+
extensions: base.extensions.filter((extension) => !isOwnResource(extension.resolvedPath)),
|
|
28
|
+
}),
|
|
29
|
+
skillsOverride: (base) => ({
|
|
30
|
+
...base,
|
|
31
|
+
skills: base.skills.filter((skill) => !isOwnResource(skill.filePath)),
|
|
28
32
|
}),
|
|
29
33
|
});
|
|
30
34
|
await resourceLoader.reload();
|
package/dist/fix.mjs
CHANGED
|
@@ -4,16 +4,19 @@ import { message } from './observe.mjs';
|
|
|
4
4
|
import { fixPrompt, hookPrompt, parseCommitSubject, parseUnrelated, } from './prompts.mjs';
|
|
5
5
|
import { writeState } from './state.mjs';
|
|
6
6
|
export async function fixRound(job, reason, detail, earlier, kind, force = false, from) {
|
|
7
|
-
const { context, issue, log, worktree, branch } = job;
|
|
8
|
-
const { ports } = context;
|
|
7
|
+
const { context, issue, log, state, worktree, branch } = job;
|
|
8
|
+
const { ports, config } = context;
|
|
9
9
|
const before = from ?? (await ports.revision(worktree));
|
|
10
|
-
const
|
|
10
|
+
const budget = kind === 'review'
|
|
11
|
+
? { round: state.reviewRounds, limit: config.maxReviewRounds }
|
|
12
|
+
: { round: state.ciFixes, limit: config.maxCiFixes };
|
|
13
|
+
const result = await log.step('fix', { reason, cause: kind, ...budget }, () => ports.runAgent(log, {
|
|
11
14
|
name: 'fixer',
|
|
12
15
|
cwd: worktree,
|
|
13
16
|
prompt: fixPrompt(issue, reason, detail, earlier, kind, job.reply),
|
|
14
17
|
profile: CODING,
|
|
15
|
-
model:
|
|
16
|
-
timeoutMs:
|
|
18
|
+
model: config.models.fixer,
|
|
19
|
+
timeoutMs: config.agentTimeoutMinutes * 60_000,
|
|
17
20
|
}));
|
|
18
21
|
const unrelated = parseUnrelated(result.text);
|
|
19
22
|
if (unrelated !== undefined) {
|
|
@@ -33,7 +36,7 @@ export async function fixRound(job, reason, detail, earlier, kind, force = false
|
|
|
33
36
|
log.event('commit.empty', { reason }, 'quiet');
|
|
34
37
|
return { committed: false };
|
|
35
38
|
}
|
|
36
|
-
await ports.push(worktree,
|
|
39
|
+
await ports.push(worktree, config.remote, branch, force);
|
|
37
40
|
return { committed: true };
|
|
38
41
|
}
|
|
39
42
|
export async function commitWork(job, before, subject, role) {
|
|
@@ -59,7 +62,7 @@ export async function commitWork(job, before, subject, role) {
|
|
|
59
62
|
await writeState(repo, state);
|
|
60
63
|
const output = message(error).slice(-config.logMaxChars);
|
|
61
64
|
log.event('commit.fail', { role, output }, 'quiet');
|
|
62
|
-
const fix = await log.step('commit-fix', { role }, () => ports.runAgent(log, {
|
|
65
|
+
const fix = await log.step('commit-fix', { role, round: state.commitFixes, limit: config.maxCommitFixes }, () => ports.runAgent(log, {
|
|
63
66
|
name: role,
|
|
64
67
|
cwd: worktree,
|
|
65
68
|
prompt: hookPrompt(issue, comments, role, output),
|
package/dist/progress.mjs
CHANGED
|
@@ -9,6 +9,20 @@ function toolLine(record) {
|
|
|
9
9
|
const line = typeof command === 'string' ? `${tool} ${command.split('\n')[0]}` : tool;
|
|
10
10
|
return line.length > TOOL_LINE_MAX ? `${line.slice(0, TOOL_LINE_MAX - 1)}…` : line;
|
|
11
11
|
}
|
|
12
|
+
function stageOf(step, record) {
|
|
13
|
+
const cause = record['cause'];
|
|
14
|
+
const name = step === 'fix' && typeof cause === 'string'
|
|
15
|
+
? `${cause} fix`
|
|
16
|
+
: step === 'commit-fix'
|
|
17
|
+
? 'commit fix'
|
|
18
|
+
: step;
|
|
19
|
+
const round = record['round'];
|
|
20
|
+
const limit = record['limit'];
|
|
21
|
+
if (typeof round !== 'number') {
|
|
22
|
+
return name;
|
|
23
|
+
}
|
|
24
|
+
return typeof limit === 'number' ? `${name} ${round}/${limit}` : `${name} ${round}`;
|
|
25
|
+
}
|
|
12
26
|
function change(progress, issue, update) {
|
|
13
27
|
return {
|
|
14
28
|
...progress,
|
|
@@ -45,16 +59,15 @@ export function applyEvent(progress, record) {
|
|
|
45
59
|
const issues = progress.issues.filter((current) => current.issue !== issue);
|
|
46
60
|
return { ...progress, issues, handled };
|
|
47
61
|
}
|
|
62
|
+
if (kind === 'issues') {
|
|
63
|
+
return { ...progress, open: Number(record['open']) };
|
|
64
|
+
}
|
|
48
65
|
if (kind === 'issues.fail') {
|
|
49
66
|
return { ...progress, error: String(record['error']) };
|
|
50
67
|
}
|
|
51
68
|
if (kind.endsWith('.start') && !NOT_STAGES.has(kind)) {
|
|
52
|
-
const stage = kind.slice(0, -'.start'.length);
|
|
53
|
-
|
|
54
|
-
return change(progress, issue, (current) => ({
|
|
55
|
-
...current,
|
|
56
|
-
stage: typeof round === 'number' ? `${stage} ${round}` : stage,
|
|
57
|
-
}));
|
|
69
|
+
const stage = stageOf(kind.slice(0, -'.start'.length), record);
|
|
70
|
+
return change(progress, issue, (current) => ({ ...current, stage }));
|
|
58
71
|
}
|
|
59
72
|
return progress;
|
|
60
73
|
}
|
package/dist/review.mjs
CHANGED