@jwilger/pi-development-system 0.41.0 → 0.43.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/agents/reviewer.md
CHANGED
|
@@ -53,4 +53,4 @@ Use exactly this packet; the coordinator parses it.
|
|
|
53
53
|
no-blocking | blocking
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
Severity: **blocking** = demonstrable defect or broken non-negotiable; **should-fix** = real defect or missing test with a realistic trigger; **nit** = style
|
|
56
|
+
Severity: **blocking** = demonstrable defect or broken non-negotiable; **should-fix** = real defect or missing test with a realistic trigger; **nit** = style or naming; do not report these unless asked, because nothing stores them. Zero findings is a valid result. End with **Not verified**: checks you could not run.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jwilger/pi-development-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.43.0",
|
|
4
4
|
"description": "A pi extension package representing a seasoned approach to software development using a full AI SDLC.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package"
|
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"test": "node --experimental-transform-types --no-warnings --test \"test/**/*.test.ts\"",
|
|
58
|
+
"test:jev": "node --experimental-transform-types --no-warnings --test \"test/live/*.live.ts\"",
|
|
59
|
+
"check:jev": "node scripts/run-jev-fixtures.ts",
|
|
58
60
|
"typecheck": "tsc --noEmit",
|
|
59
61
|
"lint": "biome check .",
|
|
60
62
|
"lint:fix": "biome check --write .",
|
|
@@ -48,8 +48,9 @@ The verdict must agree with the findings.
|
|
|
48
48
|
|
|
49
49
|
- **blocking**: a demonstrable defect or a broken non-negotiable.
|
|
50
50
|
- **should-fix**: a real defect or missing test with a realistic trigger.
|
|
51
|
-
- **nit**: style or report-only.
|
|
52
|
-
|
|
51
|
+
- **nit**: style or report-only. Reviewers should not send these. If one arrives it
|
|
52
|
+
never resets the streak, and nothing stores it: fix it now, or drop it and say why
|
|
53
|
+
in your reply. A finding nobody will act on is not worth recording.
|
|
53
54
|
- **false-positive**: refuted; ignored.
|
|
54
55
|
|
|
55
56
|
Jev may raise a finding's severity when it is at least 0.8 confident; it never
|
package/src/core/review-flow.ts
CHANGED
|
@@ -143,16 +143,17 @@ export function adoptSeverity(
|
|
|
143
143
|
const where = (f: Finding): string =>
|
|
144
144
|
f.path === undefined ? "" : ` \`${f.path}${f.line === undefined ? "" : `:${f.line}`}\``;
|
|
145
145
|
|
|
146
|
-
/**
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
): string | undefined {
|
|
146
|
+
/**
|
|
147
|
+
* Nits are never stored. Each is reported back so the coordinator fixes it now or drops it
|
|
148
|
+
* with a stated reason; a finding nobody will act on is not worth recording.
|
|
149
|
+
*/
|
|
150
|
+
export function nitLines(findings: readonly Finding[]): string[] {
|
|
152
151
|
const nits = findings.filter((f) => f.severity === "nit");
|
|
153
|
-
if (nits.length === 0) return
|
|
154
|
-
|
|
155
|
-
|
|
152
|
+
if (nits.length === 0) return [];
|
|
153
|
+
return [
|
|
154
|
+
"Nits are not stored anywhere: fix each now, or drop it and say why in your reply.",
|
|
155
|
+
...nits.map((f) => `- nit ${f.lens}${where(f)} — ${f.summary}`),
|
|
156
|
+
];
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
/** The task text for a fresh reviewer: slice, lenses, how to see the diff, and the packet to return. */
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { appendFile, mkdir } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
3
1
|
import type { ExtensionContext, ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
4
2
|
import { type Static, Type } from "typebox";
|
|
5
3
|
import type { Exec } from "../core/exec.ts";
|
|
@@ -16,7 +14,7 @@ import {
|
|
|
16
14
|
import {
|
|
17
15
|
adoptSeverity,
|
|
18
16
|
combinePackets,
|
|
19
|
-
|
|
17
|
+
nitLines,
|
|
20
18
|
reviewerTask,
|
|
21
19
|
reviewLabel,
|
|
22
20
|
reviewOf,
|
|
@@ -209,7 +207,7 @@ export function createReviewRecordTool(
|
|
|
209
207
|
name: "devsys_review_record",
|
|
210
208
|
label: "Record review round",
|
|
211
209
|
description:
|
|
212
|
-
"Record one review round from the reviewer's packet(s): parses findings, lets Jev adjust severity when confident,
|
|
210
|
+
"Record one review round from the reviewer's packet(s): parses findings, lets Jev adjust severity when confident, and returns the clean-round count and the next action.",
|
|
213
211
|
promptSnippet: "Record a reviewer packet as a review round",
|
|
214
212
|
parameters: RecordParameters,
|
|
215
213
|
exposure: "direct",
|
|
@@ -259,27 +257,7 @@ export function createReviewRecordTool(
|
|
|
259
257
|
|
|
260
258
|
const merged = combinePackets(packets);
|
|
261
259
|
const { findings, notes } = await adjusted(deps, ctx, merged.findings, snap.value.sample);
|
|
262
|
-
|
|
263
|
-
const followups = renderFollowups(slice, expected, findings);
|
|
264
|
-
let reviewed = snap.value;
|
|
265
|
-
if (followups !== undefined) {
|
|
266
|
-
try {
|
|
267
|
-
const dir = join(ctx.cwd, "docs", "decisions");
|
|
268
|
-
await mkdir(dir, { recursive: true });
|
|
269
|
-
await appendFile(join(dir, "followups.md"), followups);
|
|
270
|
-
} catch (cause) {
|
|
271
|
-
return reply(
|
|
272
|
-
`could not write docs/decisions/followups.md (${cause instanceof Error ? cause.message : String(cause)}); the round was not recorded, retry`,
|
|
273
|
-
true,
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
// The file is part of the work tree, so writing it changed the diff. The round covers the
|
|
277
|
-
// reviewed code plus its own follow-up note; otherwise `done` would be stale on arrival.
|
|
278
|
-
const after = await snapshotDiff(deps.exec, ctx.cwd, params.diffRange?.trim() || "HEAD");
|
|
279
|
-
if (!after.ok)
|
|
280
|
-
return reply(`cannot read the diff after filing follow-ups: ${after.error}`, true);
|
|
281
|
-
reviewed = after.value;
|
|
282
|
-
}
|
|
260
|
+
const reviewed = snap.value;
|
|
283
261
|
const review = addRound(
|
|
284
262
|
{ ...before, required },
|
|
285
263
|
{
|
|
@@ -298,6 +276,7 @@ export function createReviewRecordTool(
|
|
|
298
276
|
`Round ${review.rounds.length} recorded: ${counts("blocking")} blocking, ${counts("should-fix")} should-fix, ${counts("nit")} nit, ${counts("false-positive")} false-positive.`,
|
|
299
277
|
reviewLabel(review),
|
|
300
278
|
...notes,
|
|
279
|
+
...nitLines(findings),
|
|
301
280
|
`next: ${nextAction(review, reviewed.digest)}`,
|
|
302
281
|
...(range === "HEAD" ? [] : [GATE_RANGE_NOTE]),
|
|
303
282
|
].join("\n"),
|