argus-reviewer-e2e 0.3.1 → 0.4.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 +84 -71
- package/action/action.yml +129 -11
- package/action/approval-review.mjs +13 -3
- package/action/bootstrap.mjs +2 -0
- package/action/emit-review.mjs +16 -0
- package/action/runtime.mjs +20 -0
- package/action/sticky-comment.cjs +1260 -479
- package/dist/cli.d.ts +103 -7
- package/dist/cli.js +1202 -186
- package/dist/config.d.ts +96 -11
- package/dist/config.js +102 -4
- package/dist/detect.d.ts +29 -2
- package/dist/detect.js +98 -7
- package/dist/driver/browser.d.ts +32 -0
- package/dist/driver/browser.js +56 -1
- package/dist/driver/target.d.ts +4 -1
- package/dist/driver/target.js +27 -6
- package/dist/engine/actions.d.ts +5 -0
- package/dist/engine/actions.js +8 -0
- package/dist/engine/explore.d.ts +78 -0
- package/dist/engine/explore.js +373 -0
- package/dist/engine/loop.d.ts +2 -2
- package/dist/engine/loop.js +8 -8
- package/dist/engine/prompts.d.ts +28 -1
- package/dist/engine/prompts.js +88 -0
- package/dist/evidence/ci.d.ts +13 -1
- package/dist/evidence/ci.js +38 -3
- package/dist/evidence/gate.d.ts +8 -0
- package/dist/evidence/gate.js +1 -1
- package/dist/evidence/link.js +1 -1
- package/dist/executor/a0.d.ts +114 -1
- package/dist/executor/a0.js +216 -4
- package/dist/fsutil.d.ts +3 -2
- package/dist/fsutil.js +7 -4
- package/dist/journal/schema.d.ts +1 -1
- package/dist/log.d.ts +2 -1
- package/dist/log.js +10 -2
- package/dist/mention.d.ts +45 -0
- package/dist/mention.js +107 -0
- package/dist/pipeline/app.d.ts +126 -0
- package/dist/pipeline/app.js +250 -0
- package/dist/pipeline/budget.d.ts +1 -0
- package/dist/pipeline/budget.js +1 -1
- package/dist/pipeline/verify.d.ts +20 -3
- package/dist/pipeline/verify.js +189 -35
- package/dist/probe/persist.d.ts +68 -0
- package/dist/probe/persist.js +184 -0
- package/dist/probe/queue.d.ts +12 -0
- package/dist/probe/queue.js +10 -2
- package/dist/report/brand-assets.generated.d.ts +9 -0
- package/dist/report/brand-assets.generated.js +8 -0
- package/dist/report/comment.d.ts +99 -6
- package/dist/report/comment.js +292 -103
- package/dist/report/html.d.ts +50 -0
- package/dist/report/html.js +879 -0
- package/dist/report/manifest.d.ts +29 -0
- package/dist/report/manifest.js +37 -0
- package/dist/report/run.d.ts +54 -1
- package/dist/report/run.js +34 -9
- package/dist/report/viewmodel.d.ts +91 -0
- package/dist/report/viewmodel.js +241 -0
- package/dist/review/adjudicate.d.ts +6 -6
- package/dist/review/adjudicate.js +2 -2
- package/dist/review/inline.d.ts +44 -0
- package/dist/review/inline.js +95 -0
- package/dist/review/packs.d.ts +21 -0
- package/dist/review/packs.js +47 -0
- package/dist/review/scope.d.ts +16 -0
- package/dist/review/scope.js +74 -0
- package/dist/review/secrets.d.ts +10 -10
- package/dist/review/secrets.js +7 -7
- package/dist/review/testfiles.d.ts +18 -0
- package/dist/review/testfiles.js +26 -0
- package/dist/review/triage.d.ts +1 -1
- package/dist/review/triage.js +10 -10
- package/dist/review/validate.d.ts +41 -0
- package/dist/review/validate.js +76 -0
- package/dist/ui/errors.d.ts +54 -0
- package/dist/ui/errors.js +236 -0
- package/dist/ui/style.d.ts +34 -0
- package/dist/ui/style.js +48 -0
- package/dist/ui/summary.d.ts +38 -0
- package/dist/ui/summary.js +101 -0
- package/dist/vision/cost.d.ts +1 -1
- package/dist/vision/decisions.d.ts +9 -3
- package/dist/vision/decisions.js +31 -21
- package/dist/vision/openrouter.d.ts +4 -0
- package/dist/vision/openrouter.js +30 -4
- package/package.json +11 -2
package/dist/cli.d.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Config } from './config.js';
|
|
3
|
-
import { type ExecFn } from './detect.js';
|
|
3
|
+
import { type ExecFn, type ProbeFn } from './detect.js';
|
|
4
4
|
import { BrowserDriver } from './driver/browser.js';
|
|
5
5
|
import { VisionClient } from './engine/loop.js';
|
|
6
6
|
import { type PrMeta } from './evidence/ci.js';
|
|
7
7
|
import { type Evidence } from './evidence/link.js';
|
|
8
|
+
import { type ValidationAudit } from './review/validate.js';
|
|
8
9
|
import { type SecretsScanResult } from './review/secrets.js';
|
|
9
10
|
import { type TriageRecord } from './review/triage.js';
|
|
10
11
|
import { type FindingAdjudicationAudit } from './review/adjudicate.js';
|
|
11
12
|
import { type ProbeRecord } from './probe/queue.js';
|
|
12
13
|
import { type HeadBinding } from './report/manifest.js';
|
|
13
14
|
import { CallCost } from './vision/cost.js';
|
|
15
|
+
import { Message } from './vision/openrouter.js';
|
|
14
16
|
export interface CliDeps {
|
|
15
17
|
cwd?: string;
|
|
16
18
|
env?: NodeJS.ProcessEnv;
|
|
@@ -22,6 +24,15 @@ export interface CliDeps {
|
|
|
22
24
|
launchDriver?: (config: Config) => Promise<BrowserDriver>;
|
|
23
25
|
/** Inject a subprocess runner (tests stub `a0`/`gh` detection + delegation). */
|
|
24
26
|
exec?: ExecFn;
|
|
27
|
+
/** Inject the host reachability probe (tests stub a0 detection). */
|
|
28
|
+
probe?: ProbeFn;
|
|
29
|
+
/**
|
|
30
|
+
* Whether output goes to a terminal. Defaults to process.stdout.isTTY
|
|
31
|
+
* when `out` is not injected, and to false when it is.
|
|
32
|
+
*/
|
|
33
|
+
isTTY?: boolean;
|
|
34
|
+
/** Terminal width for the summary block (default process.stdout.columns, else 80). */
|
|
35
|
+
columns?: number;
|
|
25
36
|
}
|
|
26
37
|
export declare function main(argv: string[], deps?: CliDeps): Promise<number>;
|
|
27
38
|
interface PrFile {
|
|
@@ -35,7 +46,7 @@ export interface ReviewFinding {
|
|
|
35
46
|
severity: string;
|
|
36
47
|
category?: string;
|
|
37
48
|
message: string;
|
|
38
|
-
/** U8
|
|
49
|
+
/** U8: confidence-model true-positive probability (absent = unadjudicated). */
|
|
39
50
|
p?: number;
|
|
40
51
|
/** R1 — committable replacement lines for the commented range (parse-bounded). */
|
|
41
52
|
suggestion?: string;
|
|
@@ -51,9 +62,28 @@ export interface ReviewComment {
|
|
|
51
62
|
start_side?: 'RIGHT';
|
|
52
63
|
side: 'RIGHT';
|
|
53
64
|
body: string;
|
|
54
|
-
/**
|
|
65
|
+
/** KTD4: path:line:severity:normalizedMessage:hash8(suggestion); a corrected suggestion re-posts. */
|
|
55
66
|
dedupKey: string;
|
|
56
67
|
}
|
|
68
|
+
/** Per-finding audit record for a finding the post-parse filters removed. */
|
|
69
|
+
export interface DroppedFinding {
|
|
70
|
+
file: string;
|
|
71
|
+
line?: number;
|
|
72
|
+
severity: string;
|
|
73
|
+
category?: string;
|
|
74
|
+
message: string;
|
|
75
|
+
reason: 'outside-diff' | 'revert-nit';
|
|
76
|
+
}
|
|
77
|
+
export interface ReviewScope {
|
|
78
|
+
/** Changed files in the PR with a patch. */
|
|
79
|
+
totalFiles: number;
|
|
80
|
+
/** Files that reached the review model. */
|
|
81
|
+
reviewedFiles: number;
|
|
82
|
+
/** Files kept out by `review.exclude`. */
|
|
83
|
+
excludedFiles: number;
|
|
84
|
+
/** Up to 5 excluded paths, for the Diagnostics line. */
|
|
85
|
+
excludedSample: string[];
|
|
86
|
+
}
|
|
57
87
|
interface CodeReviewReport {
|
|
58
88
|
ok: boolean;
|
|
59
89
|
skipped: boolean;
|
|
@@ -66,7 +96,7 @@ interface CodeReviewReport {
|
|
|
66
96
|
reviewEvent: 'comment' | 'request_changes';
|
|
67
97
|
/** Blocker-severity findings a sandbox probe reproduced. */
|
|
68
98
|
provenBlockers: number;
|
|
69
|
-
/** Blocker-severity findings at/above the
|
|
99
|
+
/** Blocker-severity findings at/above the confidence-model P(true-positive) gate. */
|
|
70
100
|
highConfidenceBlockers: number;
|
|
71
101
|
/** KTD3 — eligibility-filtered, severity-sorted, sanitized, capped. */
|
|
72
102
|
reviewComments: ReviewComment[];
|
|
@@ -80,10 +110,24 @@ interface CodeReviewReport {
|
|
|
80
110
|
secretsScan?: SecretsScanResult | {
|
|
81
111
|
skipped: string;
|
|
82
112
|
};
|
|
83
|
-
/** U7 triage record
|
|
113
|
+
/** U7 triage record: confidence-model pre-review signals (annotate/route, never gates). */
|
|
84
114
|
triage?: TriageRecord;
|
|
85
115
|
/** U8 adjudication audit — per-finding p + suppressed records. */
|
|
86
116
|
findingAdjudication?: FindingAdjudicationAudit;
|
|
117
|
+
/** Findings dropped for citing a file/line the diff never shows. */
|
|
118
|
+
droppedUnanchored?: number;
|
|
119
|
+
/** nit/q findings dropped for asking to revert text the diff added. */
|
|
120
|
+
droppedReverted?: number;
|
|
121
|
+
/** Per-finding audit of dropped findings (capped at 50); counters stay total. */
|
|
122
|
+
droppedFindings?: DroppedFinding[];
|
|
123
|
+
/** Synthesis verdict when it diverges from the post-filter derived verdict. */
|
|
124
|
+
modelVerdict?: 'pass' | 'needs_changes' | 'approve';
|
|
125
|
+
/** How much of the PR the review covered, and what was left out. */
|
|
126
|
+
scope?: ReviewScope;
|
|
127
|
+
/** Findings dropped by deterministic validation, with reasons. */
|
|
128
|
+
validation?: ValidationAudit;
|
|
129
|
+
/** Test-file findings capped at nit (bug/risk with no non-test citation). */
|
|
130
|
+
testFileCapped?: number;
|
|
87
131
|
calls: CallCost[];
|
|
88
132
|
visionCostUsd: number;
|
|
89
133
|
tokens: number;
|
|
@@ -91,6 +135,14 @@ interface CodeReviewReport {
|
|
|
91
135
|
budgetExceeded: boolean;
|
|
92
136
|
/** Identity relationship between the report source and checkout. */
|
|
93
137
|
headBinding?: HeadBinding;
|
|
138
|
+
/** Workflow-run nonce (GITHUB_RUN_ID) — see runNonceFrom. */
|
|
139
|
+
runNonce?: string;
|
|
140
|
+
/**
|
|
141
|
+
* Base64 HTML-comment payload (`argus-probe-persist`) carrying reproduced
|
|
142
|
+
* probe source — the sticky poster embeds it verbatim so `@argus persist`
|
|
143
|
+
* can commit the probes later from a base-only checkout (E1.U3).
|
|
144
|
+
*/
|
|
145
|
+
persistPayload?: string;
|
|
94
146
|
}
|
|
95
147
|
/**
|
|
96
148
|
* Split `git diff` text into per-file PrFile entries — the local-diff
|
|
@@ -113,6 +165,7 @@ export declare function loadFixture(dir: string, exec?: ExecFn): Promise<{
|
|
|
113
165
|
skipped: string;
|
|
114
166
|
}>;
|
|
115
167
|
export declare function buildPatchChunks(files: PrFile[], contexts?: Record<string, string>): string[];
|
|
168
|
+
export declare function buildCodeReviewMessages(repo: string, pr: string, patchText: string, chunkIndex?: number, totalChunks?: number, profiles?: readonly string[]): Message[];
|
|
116
169
|
export declare function parseCodeReview(content: string): {
|
|
117
170
|
summary: string;
|
|
118
171
|
verdict: 'pass' | 'needs_changes' | 'approve';
|
|
@@ -126,7 +179,50 @@ export declare function parseCodeReview(content: string): {
|
|
|
126
179
|
*/
|
|
127
180
|
export declare function carryForwardSuggestions(findings: CodeReviewReport['findings'], originals: CodeReviewReport['findings']): CodeReviewReport['findings'];
|
|
128
181
|
/**
|
|
129
|
-
*
|
|
182
|
+
* New-side (RIGHT) line ranges covered by each file's diff hunks — the
|
|
183
|
+
* only lines a finding can anchor to (and the only ones it could have
|
|
184
|
+
* seen).
|
|
185
|
+
*/
|
|
186
|
+
export declare function diffLineRanges(files: readonly {
|
|
187
|
+
filename: string;
|
|
188
|
+
patch?: string | undefined;
|
|
189
|
+
}[]): Map<string, [number, number][]>;
|
|
190
|
+
/**
|
|
191
|
+
* New-side line number -> line text for every line the diff shows
|
|
192
|
+
* (added and context). Lets post-parse checks compare a finding's claim
|
|
193
|
+
* against what the cited line actually says.
|
|
194
|
+
*/
|
|
195
|
+
export declare function diffLineTexts(files: readonly {
|
|
196
|
+
filename: string;
|
|
197
|
+
patch?: string | undefined;
|
|
198
|
+
}[]): Map<string, Map<number, string>>;
|
|
199
|
+
/**
|
|
200
|
+
* Drop nit/q findings that ask to remove or revert text the cited diff
|
|
201
|
+
* line itself contains — i.e. findings that would undo wording the PR
|
|
202
|
+
* deliberately added ("remove `inconclusive`", "replace 'self-reported'
|
|
203
|
+
* with 'self-reported'"). Verdict-driving findings (bug/risk, security-
|
|
204
|
+
* category, configured blocking severities) are never touched: if the
|
|
205
|
+
* claim is real, severity stays the reviewer's call.
|
|
206
|
+
*/
|
|
207
|
+
export declare function filterRevertNits(findings: readonly ReviewFinding[], textsByFile: Map<string, Map<number, string>>, blockSeverities?: readonly string[]): {
|
|
208
|
+
kept: ReviewFinding[];
|
|
209
|
+
dropped: ReviewFinding[];
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* Drop findings whose line isn't visible in the file's diff. A finding on
|
|
213
|
+
* a file the diff doesn't touch, or at a line outside every hunk, is
|
|
214
|
+
* unverifiable and unpostable — misnumbered and fabricated citations land
|
|
215
|
+
* here. Line-less (file-level) findings always survive. Verdict-driving
|
|
216
|
+
* findings (bug/risk, security-category, configured blocking severities)
|
|
217
|
+
* are never dropped — a misnumbered cite on a real defect must still
|
|
218
|
+
* gate; the post-time isOnDiff check keeps its comment off the PR.
|
|
219
|
+
*/
|
|
220
|
+
export declare function filterToDiffLines(findings: readonly ReviewFinding[], rangesByFile: Map<string, [number, number][]>, blockSeverities?: readonly string[]): {
|
|
221
|
+
kept: ReviewFinding[];
|
|
222
|
+
dropped: ReviewFinding[];
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* R3/KTD2: confidence-model P(true-positive) at/above which a blocker-severity finding
|
|
130
226
|
* counts as proven for the REQUEST_CHANGES gate. This is a different axis
|
|
131
227
|
* from `review.findingThreshold` (P(false-positive) for nit/q suppression)
|
|
132
228
|
* — never reuse that knob. 0.7: high-confidence without demanding
|
|
@@ -140,7 +236,7 @@ export declare const P_TRUE_POSITIVE_THRESHOLD = 0.7;
|
|
|
140
236
|
* code-review.json; posters read `reviewEvent`, never recompute.
|
|
141
237
|
* Unadjudicated blockers (no p, not reproduced) never escalate —
|
|
142
238
|
* degrade-open by design. The two counts overlap deliberately: a
|
|
143
|
-
* reproduced AND
|
|
239
|
+
* reproduced AND high-confidence finding is reported under both.
|
|
144
240
|
*/
|
|
145
241
|
export declare function computeReviewEvent(findings: ReviewFinding[], blockSeverities: string[], allowRequestChanges: boolean): {
|
|
146
242
|
reviewEvent: 'comment' | 'request_changes';
|