@open-cr-agent/core 0.4.0 → 0.6.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.
Files changed (131) hide show
  1. package/dist/agent/json.d.ts +2 -0
  2. package/dist/agent/json.js +12 -0
  3. package/dist/{pipeline → agent}/pool.js +2 -1
  4. package/dist/{pipeline/agents.d.ts → agent/settings.d.ts} +21 -7
  5. package/dist/agent/settings.js +86 -0
  6. package/dist/anchor/match.js +5 -4
  7. package/dist/anchor/relocate.d.ts +3 -3
  8. package/dist/anchor/relocate.js +4 -4
  9. package/dist/at.d.ts +2 -0
  10. package/dist/at.js +12 -0
  11. package/dist/bundle/bundle.d.ts +2 -1
  12. package/dist/bundle/bundle.js +3 -2
  13. package/dist/bundle/grouping.d.ts +0 -1
  14. package/dist/bundle/runtime-grouper.d.ts +5 -0
  15. package/dist/{pipeline/helpers.js → bundle/runtime-grouper.js} +7 -16
  16. package/dist/contracts.d.ts +8 -14
  17. package/dist/contracts.js +2 -1
  18. package/dist/diff/hunks.js +3 -2
  19. package/dist/diff/parse.js +5 -4
  20. package/dist/diff/quoted-path.js +16 -15
  21. package/dist/domain.d.ts +10 -2
  22. package/dist/domain.js +2 -2
  23. package/dist/errors.d.ts +3 -1
  24. package/dist/errors.js +12 -0
  25. package/dist/hash.d.ts +2 -0
  26. package/dist/hash.js +7 -0
  27. package/dist/index.d.ts +28 -14
  28. package/dist/index.js +16 -5
  29. package/dist/internal.d.ts +10 -13
  30. package/dist/internal.js +10 -13
  31. package/dist/judge/judge.d.ts +3 -3
  32. package/dist/judge/judge.js +10 -9
  33. package/dist/judge/verdict.d.ts +0 -1
  34. package/dist/judge/verdict.js +1 -1
  35. package/dist/memory/memory.d.ts +7 -2
  36. package/dist/memory/memory.js +14 -2
  37. package/dist/net/proxied-fetch.js +2 -1
  38. package/dist/pipeline/assemble-report.d.ts +22 -0
  39. package/dist/pipeline/assemble-report.js +99 -0
  40. package/dist/pipeline/check-stage.d.ts +13 -0
  41. package/dist/pipeline/check-stage.js +70 -0
  42. package/dist/pipeline/context.d.ts +2 -1
  43. package/dist/pipeline/coverage.d.ts +1 -1
  44. package/dist/pipeline/coverage.js +2 -1
  45. package/dist/pipeline/execute-stage.d.ts +26 -0
  46. package/dist/pipeline/execute-stage.js +104 -0
  47. package/dist/pipeline/execute.d.ts +2 -4
  48. package/dist/pipeline/execute.js +65 -58
  49. package/dist/pipeline/filter-stage.d.ts +16 -0
  50. package/dist/pipeline/filter-stage.js +46 -0
  51. package/dist/pipeline/findings.js +3 -2
  52. package/dist/pipeline/imports.d.ts +1 -1
  53. package/dist/pipeline/imports.js +1 -1
  54. package/dist/pipeline/matrix.d.ts +1 -7
  55. package/dist/pipeline/options.d.ts +65 -0
  56. package/dist/pipeline/options.js +9 -0
  57. package/dist/pipeline/plan-output.d.ts +90 -0
  58. package/dist/pipeline/plan-output.js +109 -0
  59. package/dist/pipeline/plan.d.ts +7 -8
  60. package/dist/pipeline/plan.js +12 -9
  61. package/dist/pipeline/preview.d.ts +24 -7
  62. package/dist/pipeline/preview.js +31 -7
  63. package/dist/pipeline/provenance.d.ts +8 -17
  64. package/dist/pipeline/provenance.js +20 -8
  65. package/dist/pipeline/run.d.ts +2 -44
  66. package/dist/pipeline/run.js +18 -273
  67. package/dist/pipeline/task.d.ts +1 -3
  68. package/dist/pipeline/task.js +4 -4
  69. package/dist/plugin/registry.d.ts +5 -4
  70. package/dist/plugin/registry.js +3 -3
  71. package/dist/plugin/types.d.ts +4 -5
  72. package/dist/{pipeline → report}/output-schema.d.ts +70 -58
  73. package/dist/{pipeline → report}/output-schema.js +60 -36
  74. package/dist/report/output.d.ts +8 -0
  75. package/dist/report/output.js +211 -0
  76. package/dist/report/provenance.d.ts +26 -0
  77. package/dist/report/provenance.js +2 -0
  78. package/dist/report/read.d.ts +3 -0
  79. package/dist/report/read.js +34 -0
  80. package/dist/{pipeline → report}/report.d.ts +3 -3
  81. package/dist/report/serialize.d.ts +3 -0
  82. package/dist/report/serialize.js +27 -0
  83. package/dist/rereview/presence.js +1 -1
  84. package/dist/rereview/quote.js +2 -2
  85. package/dist/rereview/reconcile.d.ts +1 -1
  86. package/dist/review/impact.d.ts +0 -2
  87. package/dist/review/impact.js +2 -2
  88. package/dist/review/plan-phase.d.ts +3 -3
  89. package/dist/review/plan-phase.js +4 -4
  90. package/dist/review/prompt-text.d.ts +1 -1
  91. package/dist/review/prompt-text.js +1 -1
  92. package/dist/review/prompt.d.ts +0 -3
  93. package/dist/review/prompt.js +3 -3
  94. package/dist/rules/builtin/index.d.ts +0 -4
  95. package/dist/rules/builtin/index.js +1 -2
  96. package/dist/rules/repo-rules.d.ts +4 -6
  97. package/dist/rules/repo-rules.js +3 -3
  98. package/dist/runtime/chain-runner.d.ts +19 -0
  99. package/dist/runtime/chain-runner.js +63 -0
  100. package/dist/runtime/effort-capability.d.ts +14 -0
  101. package/dist/runtime/effort-capability.js +70 -0
  102. package/dist/runtime/failback.d.ts +2 -9
  103. package/dist/runtime/failback.js +23 -8
  104. package/dist/runtime/models.d.ts +2 -0
  105. package/dist/runtime/models.js +6 -0
  106. package/dist/runtime/tools.d.ts +0 -16
  107. package/dist/runtime/tools.js +3 -3
  108. package/dist/sarif/candidates.d.ts +2 -1
  109. package/dist/sarif/schema.d.ts +2 -2
  110. package/dist/sarif/schema.js +4 -4
  111. package/dist/session/jsonl.d.ts +2 -2
  112. package/dist/session/jsonl.js +5 -4
  113. package/dist/triage.d.ts +2 -2
  114. package/dist/triage.js +1 -1
  115. package/dist/vcs.d.ts +15 -0
  116. package/dist/vcs.js +2 -0
  117. package/dist/verify/prompt.d.ts +0 -6
  118. package/dist/verify/prompt.js +1 -1
  119. package/dist/verify/verify.d.ts +4 -4
  120. package/dist/verify/verify.js +5 -5
  121. package/package.json +1 -1
  122. package/dist/pipeline/agents.js +0 -55
  123. package/dist/pipeline/helpers.d.ts +0 -6
  124. package/dist/pipeline/output.d.ts +0 -77
  125. package/dist/pipeline/output.js +0 -132
  126. /package/dist/{pipeline → agent}/budget.d.ts +0 -0
  127. /package/dist/{pipeline → agent}/budget.js +0 -0
  128. /package/dist/{pipeline → agent}/pool.d.ts +0 -0
  129. /package/dist/{pipeline → agent}/usage.d.ts +0 -0
  130. /package/dist/{pipeline → agent}/usage.js +0 -0
  131. /package/dist/{pipeline → report}/report.js +0 -0
@@ -1,50 +1,37 @@
1
1
  import { z } from "zod";
2
- import { type ReportOutput } from "./output.js";
3
- export declare const outputFindingSchema: z.ZodObject<{
4
- fingerprint: z.ZodString;
5
- reviewer: z.ZodString;
6
- category: z.ZodString;
7
- severity: z.ZodEnum<{
8
- critical: "critical";
9
- suggestion: "suggestion";
10
- warning: "warning";
11
- }>;
12
- verification: z.ZodEnum<{
13
- confirmed: "confirmed";
14
- uncertain: "uncertain";
15
- unchecked: "unchecked";
16
- }>;
17
- file: z.ZodString;
18
- lines: z.ZodOptional<z.ZodObject<{
19
- start: z.ZodInt;
20
- end: z.ZodInt;
21
- }, z.core.$strict>>;
22
- inDiff: z.ZodBoolean;
23
- status: z.ZodEnum<{
24
- new: "new";
25
- unfixed: "unfixed";
26
- }>;
2
+ export declare const REPORT_VERSION = 1;
3
+ export declare const changeRequestSchema: z.ZodObject<{
4
+ id: z.ZodString;
27
5
  title: z.ZodString;
28
- body: z.ZodString;
29
- suggestion: z.ZodOptional<z.ZodString>;
30
- evidence: z.ZodArray<z.ZodString>;
31
- code: z.ZodString;
32
- lowConfidence: z.ZodOptional<z.ZodLiteral<true>>;
33
- provenance: z.ZodOptional<z.ZodObject<{
34
- task: z.ZodString;
35
- model: z.ZodOptional<z.ZodString>;
6
+ description: z.ZodString;
7
+ baseSha: z.ZodString;
8
+ headSha: z.ZodString;
9
+ override: z.ZodExactOptional<z.ZodObject<{
10
+ by: z.ZodString;
11
+ reason: z.ZodString;
36
12
  }, z.core.$strict>>;
37
13
  }, z.core.$strict>;
14
+ export declare const skippedCellSchema: z.ZodObject<{
15
+ reviewer: z.ZodString;
16
+ bundle: z.ZodString;
17
+ reason: z.ZodEnum<{
18
+ below_tier: "below_tier";
19
+ disabled: "disabled";
20
+ no_guidelines: "no_guidelines";
21
+ no_matching_files: "no_matching_files";
22
+ task_limit: "task_limit";
23
+ }>;
24
+ }, z.core.$strict>;
38
25
  export declare const reportOutputSchema: z.ZodObject<{
39
26
  version: z.ZodLiteral<1>;
40
- runId: z.ZodOptional<z.ZodString>;
27
+ runId: z.ZodExactOptional<z.ZodString>;
41
28
  changeRequest: z.ZodObject<{
42
29
  id: z.ZodString;
43
30
  title: z.ZodString;
44
31
  description: z.ZodString;
45
32
  baseSha: z.ZodString;
46
33
  headSha: z.ZodString;
47
- override: z.ZodOptional<z.ZodObject<{
34
+ override: z.ZodExactOptional<z.ZodObject<{
48
35
  by: z.ZodString;
49
36
  reason: z.ZodString;
50
37
  }, z.core.$strict>>;
@@ -61,7 +48,7 @@ export declare const reportOutputSchema: z.ZodObject<{
61
48
  significant_concerns: "significant_concerns";
62
49
  }>;
63
50
  summary: z.ZodString;
64
- scope: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
51
+ scope: z.ZodExactOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
65
52
  mode: z.ZodLiteral<"incremental">;
66
53
  since: z.ZodString;
67
54
  }, z.core.$strict>, z.ZodObject<{
@@ -104,7 +91,7 @@ export declare const reportOutputSchema: z.ZodObject<{
104
91
  unchecked: "unchecked";
105
92
  }>;
106
93
  file: z.ZodString;
107
- lines: z.ZodOptional<z.ZodObject<{
94
+ lines: z.ZodExactOptional<z.ZodObject<{
108
95
  start: z.ZodInt;
109
96
  end: z.ZodInt;
110
97
  }, z.core.$strict>>;
@@ -115,13 +102,18 @@ export declare const reportOutputSchema: z.ZodObject<{
115
102
  }>;
116
103
  title: z.ZodString;
117
104
  body: z.ZodString;
118
- suggestion: z.ZodOptional<z.ZodString>;
105
+ suggestion: z.ZodExactOptional<z.ZodString>;
106
+ fix: z.ZodExactOptional<z.ZodObject<{
107
+ startLine: z.ZodInt;
108
+ endLine: z.ZodInt;
109
+ replacement: z.ZodString;
110
+ }, z.core.$strict>>;
119
111
  evidence: z.ZodArray<z.ZodString>;
120
112
  code: z.ZodString;
121
- lowConfidence: z.ZodOptional<z.ZodLiteral<true>>;
122
- provenance: z.ZodOptional<z.ZodObject<{
113
+ lowConfidence: z.ZodExactOptional<z.ZodLiteral<true>>;
114
+ provenance: z.ZodExactOptional<z.ZodObject<{
123
115
  task: z.ZodString;
124
- model: z.ZodOptional<z.ZodString>;
116
+ model: z.ZodExactOptional<z.ZodString>;
125
117
  }, z.core.$strict>>;
126
118
  }, z.core.$strict>>;
127
119
  unverifiedCriticals: z.ZodInt;
@@ -137,8 +129,12 @@ export declare const reportOutputSchema: z.ZodObject<{
137
129
  title: z.ZodString;
138
130
  reason: z.ZodString;
139
131
  added: z.ZodOptional<z.ZodString>;
132
+ source: z.ZodExactOptional<z.ZodEnum<{
133
+ account: "account";
134
+ repository: "repository";
135
+ }>>;
140
136
  }, z.core.$strip>>;
141
- judgement: z.ZodOptional<z.ZodObject<{
137
+ judgement: z.ZodExactOptional<z.ZodObject<{
142
138
  merged: z.ZodArray<z.ZodObject<{
143
139
  kept: z.ZodString;
144
140
  merged: z.ZodArray<z.ZodString>;
@@ -164,7 +160,7 @@ export declare const reportOutputSchema: z.ZodObject<{
164
160
  reason: z.ZodString;
165
161
  }, z.core.$strict>>;
166
162
  }, z.core.$strict>>;
167
- rereview: z.ZodOptional<z.ZodObject<{
163
+ rereview: z.ZodExactOptional<z.ZodObject<{
168
164
  fixed: z.ZodArray<z.ZodObject<{
169
165
  fingerprint: z.ZodString;
170
166
  title: z.ZodString;
@@ -179,6 +175,7 @@ export declare const reportOutputSchema: z.ZodObject<{
179
175
  uncertain: "uncertain";
180
176
  unchecked: "unchecked";
181
177
  }>;
178
+ reviewer: z.ZodExactOptional<z.ZodString>;
182
179
  }, z.core.$strict>>;
183
180
  notReproduced: z.ZodArray<z.ZodObject<{
184
181
  fingerprint: z.ZodString;
@@ -194,6 +191,7 @@ export declare const reportOutputSchema: z.ZodObject<{
194
191
  uncertain: "uncertain";
195
192
  unchecked: "unchecked";
196
193
  }>;
194
+ reviewer: z.ZodExactOptional<z.ZodString>;
197
195
  }, z.core.$strict>>;
198
196
  notRechecked: z.ZodArray<z.ZodObject<{
199
197
  fingerprint: z.ZodString;
@@ -209,6 +207,7 @@ export declare const reportOutputSchema: z.ZodObject<{
209
207
  uncertain: "uncertain";
210
208
  unchecked: "unchecked";
211
209
  }>;
210
+ reviewer: z.ZodExactOptional<z.ZodString>;
212
211
  }, z.core.$strict>>;
213
212
  unchanged: z.ZodArray<z.ZodObject<{
214
213
  fingerprint: z.ZodString;
@@ -224,6 +223,7 @@ export declare const reportOutputSchema: z.ZodObject<{
224
223
  uncertain: "uncertain";
225
224
  unchecked: "unchecked";
226
225
  }>;
226
+ reviewer: z.ZodExactOptional<z.ZodString>;
227
227
  }, z.core.$strict>>;
228
228
  dismissed: z.ZodArray<z.ZodObject<{
229
229
  fingerprint: z.ZodString;
@@ -239,6 +239,7 @@ export declare const reportOutputSchema: z.ZodObject<{
239
239
  uncertain: "uncertain";
240
240
  unchecked: "unchecked";
241
241
  }>;
242
+ reviewer: z.ZodExactOptional<z.ZodString>;
242
243
  }, z.core.$strict>>;
243
244
  }, z.core.$strict>>;
244
245
  tasks: z.ZodArray<z.ZodObject<{
@@ -252,7 +253,7 @@ export declare const reportOutputSchema: z.ZodObject<{
252
253
  failed: "failed";
253
254
  timed_out: "timed_out";
254
255
  }>;
255
- error: z.ZodOptional<z.ZodString>;
256
+ error: z.ZodExactOptional<z.ZodString>;
256
257
  findings: z.ZodInt;
257
258
  durationMs: z.ZodNumber;
258
259
  usage: z.ZodObject<{
@@ -278,7 +279,7 @@ export declare const reportOutputSchema: z.ZodObject<{
278
279
  label: z.ZodString;
279
280
  files: z.ZodArray<z.ZodString>;
280
281
  }, z.core.$strict>>;
281
- anchoring: z.ZodOptional<z.ZodObject<{
282
+ anchoring: z.ZodExactOptional<z.ZodObject<{
282
283
  byMethod: z.ZodRecord<z.ZodEnum<{
283
284
  cross_file: "cross_file";
284
285
  file: "file";
@@ -289,44 +290,58 @@ export declare const reportOutputSchema: z.ZodObject<{
289
290
  ambiguous: z.ZodInt;
290
291
  relocationCalls: z.ZodInt;
291
292
  }, z.core.$strict>>;
292
- spendLimit: z.ZodOptional<z.ZodObject<{
293
+ spendLimit: z.ZodExactOptional<z.ZodObject<{
293
294
  usd: z.ZodNumber;
294
- reached: z.ZodOptional<z.ZodEnum<{
295
+ reached: z.ZodExactOptional<z.ZodEnum<{
295
296
  review: "review";
296
297
  total: "total";
297
298
  }>>;
298
299
  }, z.core.$strict>>;
299
- provenance: z.ZodOptional<z.ZodObject<{
300
+ provenance: z.ZodExactOptional<z.ZodObject<{
300
301
  ocraVersion: z.ZodString;
301
302
  promptHash: z.ZodString;
302
303
  configHash: z.ZodString;
303
304
  sampling: z.ZodObject<{
304
- temperature: z.ZodOptional<z.ZodNumber>;
305
- seed: z.ZodOptional<z.ZodInt>;
306
- notApplied: z.ZodOptional<z.ZodArray<z.ZodEnum<{
305
+ temperature: z.ZodExactOptional<z.ZodNumber>;
306
+ seed: z.ZodExactOptional<z.ZodInt>;
307
+ notApplied: z.ZodExactOptional<z.ZodArray<z.ZodEnum<{
307
308
  seed: "seed";
308
309
  temperature: "temperature";
309
310
  }>>>;
310
311
  }, z.core.$strict>;
311
- agents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
312
+ agents: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
312
313
  tier: z.ZodEnum<{
313
314
  light: "light";
314
315
  standard: "standard";
315
316
  top: "top";
316
317
  }>;
317
- effort: z.ZodOptional<z.ZodEnum<{
318
+ models: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
319
+ effort: z.ZodExactOptional<z.ZodEnum<{
318
320
  high: "high";
319
321
  low: "low";
320
322
  medium: "medium";
321
323
  minimal: "minimal";
322
324
  none: "none";
323
325
  }>>;
324
- applied: z.ZodOptional<z.ZodBoolean>;
325
- notApplied: z.ZodOptional<z.ZodArray<z.ZodEnum<{
326
+ applied: z.ZodExactOptional<z.ZodBoolean>;
327
+ notApplied: z.ZodExactOptional<z.ZodArray<z.ZodEnum<{
326
328
  seed: "seed";
327
329
  temperature: "temperature";
328
330
  }>>>;
329
331
  }, z.core.$strict>>>;
332
+ rules: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
333
+ path: z.ZodArray<z.ZodString>;
334
+ rule: z.ZodString;
335
+ source: z.ZodExactOptional<z.ZodEnum<{
336
+ account: "account";
337
+ plugin: "plugin";
338
+ repository: "repository";
339
+ shared: "shared";
340
+ }>>;
341
+ }, z.core.$strict>>>;
342
+ accountSettings: z.ZodExactOptional<z.ZodObject<{
343
+ version: z.ZodNullable<z.ZodString>;
344
+ }, z.core.$strict>>;
330
345
  }, z.core.$strict>>;
331
346
  usage: z.ZodObject<{
332
347
  inputTokens: z.ZodNumber;
@@ -337,9 +352,6 @@ export declare const reportOutputSchema: z.ZodObject<{
337
352
  }, z.core.$strict>;
338
353
  warnings: z.ZodArray<z.ZodString>;
339
354
  }, z.core.$strict>;
340
- type OutputFromSchema = z.output<typeof reportOutputSchema>;
341
- export declare function asSchemaOutput(output: ReportOutput): OutputFromSchema;
342
355
  export declare const REPORT_SCHEMA_ID = "https://ocra.majincheng.com/schema/report.v1.json";
343
356
  export declare function reportJsonSchema(): Record<string, unknown>;
344
- export {};
345
357
  //# sourceMappingURL=output-schema.d.ts.map
@@ -1,15 +1,22 @@
1
1
  import { z } from "zod";
2
+ import { EFFORT_LEVELS } from "../agent/settings.js";
3
+ import { MODEL_TIERS } from "../contracts.js";
2
4
  import { anchorMethodSchema, riskTierSchema, severitySchema, verdictSchema, verificationSchema, } from "../domain.js";
3
5
  import { memoryEntrySchema } from "../memory/memory.js";
6
+ import { skipReasonSchema } from "../pipeline/matrix.js";
4
7
  import { exclusionReasonSchema } from "../select/select.js";
5
- import { EFFORT_LEVELS } from "./agents.js";
6
- import { skipReasonSchema } from "./matrix.js";
7
- import { REPORT_VERSION } from "./output.js";
8
8
  import { taskStatusSchema } from "./report.js";
9
- // The JSON report as a schema: what `toReportOutput` writes, no more. Every
10
- // object is strict, so a field added to the output without a schema change
11
- // fails the tests, and the published JSON Schema (docs/schema/report.v1.json)
12
- // is generated from here, never written by hand.
9
+ // The published shape of a review: `--format json` and a session's
10
+ // report.json. It is a contract with scripts and CI, so it carries a version
11
+ // and only what a reader can rely on; internal fields (per-run ids, how each
12
+ // finding was anchored, code signatures, platform state) stay out, though the
13
+ // anchoring counts of the whole run are in. Change it only by adding optional
14
+ // fields, or by a new version.
15
+ export const REPORT_VERSION = 1;
16
+ // The JSON report as a schema, the one definition of its shape: the
17
+ // `ReportOutput` type is derived from it, and the published JSON Schema
18
+ // (docs/schema/report.v1.json) is generated from it. Every object is strict,
19
+ // so a field `toReportOutput` writes without a schema change fails the tests.
13
20
  const usageSchema = z.strictObject({
14
21
  inputTokens: z.number(),
15
22
  outputTokens: z.number(),
@@ -17,13 +24,13 @@ const usageSchema = z.strictObject({
17
24
  cachedTokens: z.number(),
18
25
  costUsd: z.number(),
19
26
  });
20
- const changeRequestSchema = z.strictObject({
27
+ export const changeRequestSchema = z.strictObject({
21
28
  id: z.string(),
22
29
  title: z.string(),
23
30
  description: z.string(),
24
31
  baseSha: z.string(),
25
32
  headSha: z.string(),
26
- override: z.strictObject({ by: z.string(), reason: z.string() }).optional(),
33
+ override: z.strictObject({ by: z.string(), reason: z.string() }).exactOptional(),
27
34
  });
28
35
  const coverageEntrySchema = z.discriminatedUnion("status", [
29
36
  z.strictObject({
@@ -37,23 +44,33 @@ const coverageEntrySchema = z.discriminatedUnion("status", [
37
44
  }),
38
45
  ]);
39
46
  const linesSchema = z.strictObject({ start: z.int().positive(), end: z.int().positive() });
40
- export const outputFindingSchema = z.strictObject({
47
+ const fixSchema = z
48
+ .strictObject({
49
+ startLine: z.int().positive(),
50
+ endLine: z.int().positive(),
51
+ replacement: z.string(),
52
+ })
53
+ .refine((f) => f.endLine >= f.startLine, { message: "endLine is before startLine" });
54
+ const outputFindingSchema = z.strictObject({
41
55
  fingerprint: z.string(),
42
56
  reviewer: z.string(),
43
57
  category: z.string(),
44
58
  severity: severitySchema,
45
59
  verification: verificationSchema,
46
60
  file: z.string(),
47
- lines: linesSchema.optional(),
61
+ lines: linesSchema.exactOptional(),
48
62
  inDiff: z.boolean(),
49
63
  status: z.enum(["new", "unfixed"]),
50
64
  title: z.string(),
51
65
  body: z.string(),
52
- suggestion: z.string().optional(),
66
+ suggestion: z.string().exactOptional(),
67
+ fix: fixSchema.exactOptional(),
53
68
  evidence: z.array(z.string()),
54
69
  code: z.string(),
55
- lowConfidence: z.literal(true).optional(),
56
- provenance: z.strictObject({ task: z.string(), model: z.string().optional() }).optional(),
70
+ lowConfidence: z.literal(true).exactOptional(),
71
+ provenance: z
72
+ .strictObject({ task: z.string(), model: z.string().exactOptional() })
73
+ .exactOptional(),
57
74
  });
58
75
  const outputPriorFindingSchema = z.strictObject({
59
76
  fingerprint: z.string(),
@@ -61,6 +78,7 @@ const outputPriorFindingSchema = z.strictObject({
61
78
  file: z.string(),
62
79
  severity: severitySchema,
63
80
  verification: verificationSchema,
81
+ reviewer: z.string().exactOptional(),
64
82
  });
65
83
  const refutedFindingSchema = z.strictObject({
66
84
  fingerprint: z.string(),
@@ -89,12 +107,12 @@ const taskOutcomeSchema = z.strictObject({
89
107
  bundle: z.string(),
90
108
  files: z.array(z.string()),
91
109
  status: taskStatusSchema,
92
- error: z.string().optional(),
110
+ error: z.string().exactOptional(),
93
111
  findings: z.int().nonnegative(),
94
112
  durationMs: z.number(),
95
113
  usage: usageSchema,
96
114
  });
97
- const skippedCellSchema = z.strictObject({
115
+ export const skippedCellSchema = z.strictObject({
98
116
  reviewer: z.string(),
99
117
  bundle: z.string(),
100
118
  reason: skipReasonSchema,
@@ -110,37 +128,46 @@ const scopeSchema = z.discriminatedUnion("mode", [
110
128
  ]);
111
129
  const priorList = z.array(outputPriorFindingSchema);
112
130
  const samplingSchema = z.strictObject({
113
- temperature: z.number().optional(),
114
- seed: z.int().optional(),
115
- notApplied: z.array(z.enum(["temperature", "seed"])).optional(),
131
+ temperature: z.number().exactOptional(),
132
+ seed: z.int().exactOptional(),
133
+ notApplied: z.array(z.enum(["temperature", "seed"])).exactOptional(),
116
134
  });
117
135
  const agentProvenanceSchema = z.strictObject({
118
- tier: z.enum(["top", "standard", "light"]),
119
- effort: z.enum(EFFORT_LEVELS).optional(),
120
- applied: z.boolean().optional(),
121
- notApplied: z.array(z.enum(["temperature", "seed"])).optional(),
136
+ tier: z.enum(MODEL_TIERS),
137
+ models: z.array(z.string()).exactOptional(),
138
+ effort: z.enum(EFFORT_LEVELS).exactOptional(),
139
+ applied: z.boolean().exactOptional(),
140
+ notApplied: z.array(z.enum(["temperature", "seed"])).exactOptional(),
122
141
  });
123
142
  const provenanceSchema = z.strictObject({
124
143
  ocraVersion: z.string(),
125
144
  promptHash: z.string(),
126
145
  configHash: z.string(),
127
146
  sampling: samplingSchema,
128
- agents: z.record(z.string(), agentProvenanceSchema).optional(),
147
+ agents: z.record(z.string(), agentProvenanceSchema).exactOptional(),
148
+ rules: z
149
+ .array(z.strictObject({
150
+ path: z.array(z.string()),
151
+ rule: z.string(),
152
+ source: z.enum(["repository", "shared", "account", "plugin"]).exactOptional(),
153
+ }))
154
+ .exactOptional(),
155
+ accountSettings: z.strictObject({ version: z.string().nullable() }).exactOptional(),
129
156
  });
130
157
  export const reportOutputSchema = z.strictObject({
131
158
  version: z.literal(REPORT_VERSION),
132
- runId: z.string().optional(),
159
+ runId: z.string().exactOptional(),
133
160
  changeRequest: changeRequestSchema,
134
161
  tier: riskTierSchema,
135
162
  verdict: verdictSchema,
136
163
  summary: z.string(),
137
- scope: scopeSchema.optional(),
164
+ scope: scopeSchema.exactOptional(),
138
165
  coverage: z.array(coverageEntrySchema),
139
166
  findings: z.array(outputFindingSchema),
140
167
  unverifiedCriticals: z.int().nonnegative(),
141
168
  refuted: z.array(refutedFindingSchema),
142
- remembered: z.array(memoryEntrySchema),
143
- judgement: judgeDecisionsSchema.optional(),
169
+ remembered: z.array(memoryEntrySchema.extend({ source: z.enum(["repository", "account"]).exactOptional() })),
170
+ judgement: judgeDecisionsSchema.exactOptional(),
144
171
  rereview: z
145
172
  .strictObject({
146
173
  fixed: priorList,
@@ -149,21 +176,18 @@ export const reportOutputSchema = z.strictObject({
149
176
  unchanged: priorList,
150
177
  dismissed: priorList,
151
178
  })
152
- .optional(),
179
+ .exactOptional(),
153
180
  tasks: z.array(taskOutcomeSchema),
154
181
  skipped: z.array(skippedCellSchema),
155
182
  bundles: z.array(z.strictObject({ label: z.string(), files: z.array(z.string()) })),
156
- anchoring: anchoringSummarySchema.optional(),
183
+ anchoring: anchoringSummarySchema.exactOptional(),
157
184
  spendLimit: z
158
- .strictObject({ usd: z.number(), reached: z.enum(["review", "total"]).optional() })
159
- .optional(),
160
- provenance: provenanceSchema.optional(),
185
+ .strictObject({ usd: z.number(), reached: z.enum(["review", "total"]).exactOptional() })
186
+ .exactOptional(),
187
+ provenance: provenanceSchema.exactOptional(),
161
188
  usage: usageSchema,
162
189
  warnings: z.array(z.string()),
163
190
  });
164
- export function asSchemaOutput(output) {
165
- return output;
166
- }
167
191
  export const REPORT_SCHEMA_ID = "https://ocra.majincheng.com/schema/report.v1.json";
168
192
  // JSON Schema (draft 2020-12) for `--format json` and a session's
169
193
  // report.json, for validators and code generators outside this codebase.
@@ -0,0 +1,8 @@
1
+ import type { z } from "zod";
2
+ import { type reportOutputSchema } from "./output-schema.js";
3
+ import type { ReviewReport } from "./report.js";
4
+ export type ReportOutput = z.output<typeof reportOutputSchema>;
5
+ export type OutputFinding = ReportOutput["findings"][number];
6
+ export type OutputPriorFinding = NonNullable<ReportOutput["rereview"]>["fixed"][number];
7
+ export declare function toReportOutput(report: ReviewReport): ReportOutput;
8
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1,211 @@
1
+ import { REPORT_VERSION } from "./output-schema.js";
2
+ export function toReportOutput(report) {
3
+ const output = {
4
+ version: REPORT_VERSION,
5
+ runId: report.runId,
6
+ changeRequest: outputChangeRequest(report.changeRequest),
7
+ tier: report.tier,
8
+ verdict: report.verdict,
9
+ summary: report.summary,
10
+ coverage: report.coverage.map(outputCoverage),
11
+ findings: report.findings.map(outputFinding),
12
+ unverifiedCriticals: report.unverifiedCriticals,
13
+ refuted: report.refuted.map(outputRefuted),
14
+ remembered: report.remembered.map(outputRemembered),
15
+ tasks: report.tasks.map(outputTask),
16
+ skipped: report.skipped.map(outputSkipped),
17
+ bundles: report.bundles.map((b) => ({ label: b.label, files: [...b.files] })),
18
+ usage: outputUsage(report.usage),
19
+ warnings: [...report.warnings],
20
+ };
21
+ if (report.scope)
22
+ output.scope = outputScope(report.scope);
23
+ if (report.judgement)
24
+ output.judgement = outputJudgement(report.judgement);
25
+ if (report.anchoring)
26
+ output.anchoring = outputAnchoring(report.anchoring);
27
+ if (report.spendLimit)
28
+ output.spendLimit = outputSpendLimit(report.spendLimit);
29
+ if (report.provenance)
30
+ output.provenance = outputProvenance(report.provenance);
31
+ if (report.rereview) {
32
+ const r = report.rereview;
33
+ output.rereview = {
34
+ fixed: r.fixed.map(outputPrior),
35
+ notReproduced: r.notReproduced.map(outputPrior),
36
+ notRechecked: r.notRechecked.map(outputPrior),
37
+ unchanged: r.unchanged.map(outputPrior),
38
+ dismissed: r.dismissed.map(outputPrior),
39
+ };
40
+ }
41
+ return output;
42
+ }
43
+ function outputChangeRequest(c) {
44
+ return {
45
+ id: c.id,
46
+ title: c.title,
47
+ description: c.description,
48
+ baseSha: c.baseSha,
49
+ headSha: c.headSha,
50
+ ...(c.override ? { override: { by: c.override.by, reason: c.override.reason } } : {}),
51
+ };
52
+ }
53
+ function outputCoverage(c) {
54
+ return c.status === "excluded"
55
+ ? { path: c.path, status: c.status, reason: c.reason }
56
+ : { path: c.path, status: c.status };
57
+ }
58
+ function outputFinding(f) {
59
+ const output = {
60
+ fingerprint: f.fingerprint,
61
+ reviewer: f.reviewer,
62
+ category: f.category,
63
+ severity: f.severity,
64
+ verification: f.verification ?? "unchecked",
65
+ file: f.file,
66
+ inDiff: f.anchor.inDiff,
67
+ status: f.status === "unfixed" ? "unfixed" : "new",
68
+ title: f.title,
69
+ body: f.body,
70
+ evidence: f.evidence,
71
+ code: f.existingCode,
72
+ };
73
+ if (f.lineRange)
74
+ output.lines = { start: f.lineRange.start, end: f.lineRange.end };
75
+ if (f.suggestion !== undefined)
76
+ output.suggestion = f.suggestion;
77
+ if (f.fix) {
78
+ output.fix = {
79
+ startLine: f.fix.startLine,
80
+ endLine: f.fix.endLine,
81
+ replacement: f.fix.replacement,
82
+ };
83
+ }
84
+ if (f.lowConfidence)
85
+ output.lowConfidence = true;
86
+ output.provenance =
87
+ f.provenance.model === undefined
88
+ ? { task: f.provenance.task }
89
+ : { task: f.provenance.task, model: f.provenance.model };
90
+ return output;
91
+ }
92
+ function outputRefuted(r) {
93
+ return { fingerprint: r.fingerprint, file: r.file, title: r.title, reason: r.reason };
94
+ }
95
+ function outputRemembered(e) {
96
+ return {
97
+ fingerprint: e.fingerprint,
98
+ file: e.file,
99
+ title: e.title,
100
+ reason: e.reason,
101
+ ...(e.added === undefined ? {} : { added: e.added }),
102
+ source: e.source,
103
+ };
104
+ }
105
+ function outputTask(t) {
106
+ return {
107
+ taskId: t.taskId,
108
+ reviewer: t.reviewer,
109
+ bundle: t.bundle,
110
+ files: [...t.files],
111
+ status: t.status,
112
+ findings: t.findings,
113
+ durationMs: t.durationMs,
114
+ usage: outputUsage(t.usage),
115
+ ...(t.error === undefined ? {} : { error: t.error }),
116
+ };
117
+ }
118
+ function outputSkipped(s) {
119
+ return { reviewer: s.reviewer, bundle: s.bundle, reason: s.reason };
120
+ }
121
+ function outputUsage(u) {
122
+ return {
123
+ inputTokens: u.inputTokens,
124
+ outputTokens: u.outputTokens,
125
+ reasoningTokens: u.reasoningTokens,
126
+ cachedTokens: u.cachedTokens,
127
+ costUsd: u.costUsd,
128
+ };
129
+ }
130
+ function outputScope(s) {
131
+ return s.mode === "incremental"
132
+ ? { mode: s.mode, since: s.since }
133
+ : { mode: s.mode, reason: s.reason };
134
+ }
135
+ function outputJudgement(j) {
136
+ return {
137
+ merged: j.merged.map((m) => ({ kept: m.kept, merged: [...m.merged] })),
138
+ dropped: j.dropped.map((d) => ({
139
+ fingerprint: d.fingerprint,
140
+ file: d.file,
141
+ title: d.title,
142
+ reason: d.reason,
143
+ })),
144
+ recalibrated: j.recalibrated.map((r) => ({
145
+ fingerprint: r.fingerprint,
146
+ from: r.from,
147
+ to: r.to,
148
+ reason: r.reason,
149
+ })),
150
+ };
151
+ }
152
+ function outputAnchoring(a) {
153
+ return {
154
+ byMethod: { ...a.byMethod },
155
+ ambiguous: a.ambiguous,
156
+ relocationCalls: a.relocationCalls,
157
+ };
158
+ }
159
+ function outputSpendLimit(s) {
160
+ return s.reached === undefined ? { usd: s.usd } : { usd: s.usd, reached: s.reached };
161
+ }
162
+ function outputProvenance(p) {
163
+ return {
164
+ ocraVersion: p.ocraVersion,
165
+ promptHash: p.promptHash,
166
+ configHash: p.configHash,
167
+ sampling: outputSampling(p.sampling),
168
+ ...(p.agents
169
+ ? {
170
+ agents: Object.fromEntries(Object.entries(p.agents).map(([id, agent]) => [id, outputAgent(agent)])),
171
+ }
172
+ : {}),
173
+ ...(p.rules
174
+ ? {
175
+ rules: p.rules.map((r) => ({
176
+ path: [...r.path],
177
+ rule: r.rule,
178
+ ...(r.source ? { source: r.source } : {}),
179
+ })),
180
+ }
181
+ : {}),
182
+ ...(p.accountSettings ? { accountSettings: { version: p.accountSettings.version } } : {}),
183
+ };
184
+ }
185
+ function outputSampling(s) {
186
+ return {
187
+ ...(s.temperature === undefined ? {} : { temperature: s.temperature }),
188
+ ...(s.seed === undefined ? {} : { seed: s.seed }),
189
+ ...(s.notApplied ? { notApplied: [...s.notApplied] } : {}),
190
+ };
191
+ }
192
+ function outputAgent(a) {
193
+ return {
194
+ tier: a.tier,
195
+ ...(a.models ? { models: [...a.models] } : {}),
196
+ ...(a.effort === undefined ? {} : { effort: a.effort }),
197
+ ...(a.applied === undefined ? {} : { applied: a.applied }),
198
+ ...(a.notApplied ? { notApplied: [...a.notApplied] } : {}),
199
+ };
200
+ }
201
+ function outputPrior(f) {
202
+ return {
203
+ fingerprint: f.fingerprint,
204
+ title: f.title,
205
+ file: f.file,
206
+ severity: f.severity,
207
+ verification: f.verification ?? "unchecked",
208
+ ...(f.reviewer ? { reviewer: f.reviewer } : {}),
209
+ };
210
+ }
211
+ //# sourceMappingURL=output.js.map