argus-reviewer-e2e 0.3.1 → 0.4.1

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.
Files changed (89) hide show
  1. package/README.md +84 -71
  2. package/action/action.yml +129 -11
  3. package/action/approval-review.mjs +13 -3
  4. package/action/bootstrap.mjs +2 -0
  5. package/action/emit-review.mjs +16 -0
  6. package/action/runtime.mjs +20 -0
  7. package/action/sticky-comment.cjs +1260 -479
  8. package/dist/cli.d.ts +103 -7
  9. package/dist/cli.js +1202 -186
  10. package/dist/config.d.ts +96 -11
  11. package/dist/config.js +102 -4
  12. package/dist/detect.d.ts +29 -2
  13. package/dist/detect.js +98 -7
  14. package/dist/driver/browser.d.ts +32 -0
  15. package/dist/driver/browser.js +56 -1
  16. package/dist/driver/target.d.ts +4 -1
  17. package/dist/driver/target.js +27 -6
  18. package/dist/engine/actions.d.ts +5 -0
  19. package/dist/engine/actions.js +8 -0
  20. package/dist/engine/explore.d.ts +78 -0
  21. package/dist/engine/explore.js +373 -0
  22. package/dist/engine/loop.d.ts +2 -2
  23. package/dist/engine/loop.js +8 -8
  24. package/dist/engine/prompts.d.ts +28 -1
  25. package/dist/engine/prompts.js +88 -0
  26. package/dist/evidence/ci.d.ts +13 -1
  27. package/dist/evidence/ci.js +38 -3
  28. package/dist/evidence/gate.d.ts +8 -0
  29. package/dist/evidence/gate.js +1 -1
  30. package/dist/evidence/link.js +1 -1
  31. package/dist/executor/a0.d.ts +114 -1
  32. package/dist/executor/a0.js +216 -4
  33. package/dist/fsutil.d.ts +3 -2
  34. package/dist/fsutil.js +7 -4
  35. package/dist/journal/schema.d.ts +1 -1
  36. package/dist/log.d.ts +2 -1
  37. package/dist/log.js +10 -2
  38. package/dist/mention.d.ts +45 -0
  39. package/dist/mention.js +107 -0
  40. package/dist/pipeline/app.d.ts +126 -0
  41. package/dist/pipeline/app.js +250 -0
  42. package/dist/pipeline/budget.d.ts +1 -0
  43. package/dist/pipeline/budget.js +1 -1
  44. package/dist/pipeline/verify.d.ts +20 -3
  45. package/dist/pipeline/verify.js +189 -35
  46. package/dist/probe/persist.d.ts +68 -0
  47. package/dist/probe/persist.js +184 -0
  48. package/dist/probe/queue.d.ts +12 -0
  49. package/dist/probe/queue.js +10 -2
  50. package/dist/report/brand-assets.generated.d.ts +9 -0
  51. package/dist/report/brand-assets.generated.js +8 -0
  52. package/dist/report/comment.d.ts +99 -6
  53. package/dist/report/comment.js +292 -103
  54. package/dist/report/html.d.ts +50 -0
  55. package/dist/report/html.js +879 -0
  56. package/dist/report/manifest.d.ts +29 -0
  57. package/dist/report/manifest.js +37 -0
  58. package/dist/report/run.d.ts +54 -1
  59. package/dist/report/run.js +34 -9
  60. package/dist/report/viewmodel.d.ts +91 -0
  61. package/dist/report/viewmodel.js +241 -0
  62. package/dist/review/adjudicate.d.ts +6 -6
  63. package/dist/review/adjudicate.js +2 -2
  64. package/dist/review/inline.d.ts +44 -0
  65. package/dist/review/inline.js +95 -0
  66. package/dist/review/packs.d.ts +21 -0
  67. package/dist/review/packs.js +47 -0
  68. package/dist/review/scope.d.ts +16 -0
  69. package/dist/review/scope.js +74 -0
  70. package/dist/review/secrets.d.ts +10 -10
  71. package/dist/review/secrets.js +7 -7
  72. package/dist/review/testfiles.d.ts +18 -0
  73. package/dist/review/testfiles.js +26 -0
  74. package/dist/review/triage.d.ts +1 -1
  75. package/dist/review/triage.js +10 -10
  76. package/dist/review/validate.d.ts +41 -0
  77. package/dist/review/validate.js +76 -0
  78. package/dist/ui/errors.d.ts +54 -0
  79. package/dist/ui/errors.js +236 -0
  80. package/dist/ui/style.d.ts +34 -0
  81. package/dist/ui/style.js +48 -0
  82. package/dist/ui/summary.d.ts +38 -0
  83. package/dist/ui/summary.js +101 -0
  84. package/dist/vision/cost.d.ts +1 -1
  85. package/dist/vision/decisions.d.ts +9 -3
  86. package/dist/vision/decisions.js +31 -21
  87. package/dist/vision/openrouter.d.ts +4 -0
  88. package/dist/vision/openrouter.js +30 -4
  89. 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 — Jev true-positive probability (absent = unadjudicated). */
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
- /** R10 — path:line:bodyFirstLine:hash8(suggestion); a corrected suggestion re-posts. */
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 Jev P(true-positive) gate. */
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 — Jev pre-review signals (annotate/route, never gates). */
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
- * R3/KTD2 — Jev P(true-positive) at/above which a blocker-severity finding
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 Jev-confident finding is reported under both.
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';