@crvouga/atlas 0.13.0 → 0.15.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 (56) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/playwright-reporter/src/index.d.ts +11 -0
  3. package/dist/playwright-reporter/src/index.js +4 -2
  4. package/dist/reports/src/artifact-tag-store.d.ts +20 -0
  5. package/dist/reports/src/artifact-tag-store.js +70 -0
  6. package/dist/reports/src/artifact-tags.d.ts +96 -0
  7. package/dist/reports/src/artifact-tags.js +96 -0
  8. package/dist/reports/src/evidence-detail.d.ts +1 -1
  9. package/dist/reports/src/evidence-detail.js +6 -2
  10. package/dist/reports/src/evidence-types.d.ts +5 -0
  11. package/dist/reports/src/layer-merge.d.ts +1 -1
  12. package/dist/reports/src/layer-merge.js +3 -2
  13. package/dist/reports/src/layer-types.d.ts +3 -0
  14. package/dist/reports/src/publish-checks.js +1 -0
  15. package/dist/reports/src/report-cli.d.ts +1 -1
  16. package/dist/reports/src/report-cli.js +30 -2
  17. package/dist/reports/src/reporter.d.ts +1 -1
  18. package/dist/reports/src/reports-explorer-route.d.ts +8 -0
  19. package/dist/reports/src/reports-route.d.ts +8 -0
  20. package/dist/reports/src/test-catalog.d.ts +31 -27
  21. package/dist/reports/src/test-catalog.js +73 -12
  22. package/dist/schema/src/api.d.ts +128 -1
  23. package/dist/schema/src/api.js +38 -4
  24. package/dist/schema/src/layer.d.ts +59 -0
  25. package/dist/schema/src/layer.js +28 -1
  26. package/dist/server/src/app.js +32 -1
  27. package/dist/server/src/openapi.d.ts +1 -1
  28. package/dist/server/src/openapi.js +18 -2
  29. package/docs/extending.md +3 -0
  30. package/docs/integrating.md +8 -0
  31. package/docs/reference/cli.md +7 -0
  32. package/docs/reference/http-api.md +48 -0
  33. package/docs/reference/playwright-reporter.md +6 -6
  34. package/docs/reference/reports.md +235 -8
  35. package/docs/reference/schema.md +52 -1
  36. package/docs/report-contract.md +1 -0
  37. package/docs/rich-evidence.md +28 -0
  38. package/docs/server.md +24 -0
  39. package/llms-full.txt +119 -0
  40. package/package.json +1 -1
  41. package/packages/schema/schemas/check-detail.schema.json +28 -0
  42. package/packages/schema/schemas/effective-delta.schema.json +44 -0
  43. package/packages/schema/schemas/effective-evidence.schema.json +44 -0
  44. package/packages/schema/schemas/evidence-page.schema.json +37 -0
  45. package/packages/schema/schemas/layer-rows.schema.json +7 -0
  46. package/packages/schema/schemas/layer.schema.json +100 -0
  47. package/packages/schema/schemas/publish-checks.schema.json +65 -0
  48. package/packages/schema/schemas/report-run.schema.json +17 -1
  49. package/packages/schema/schemas/report-runs.schema.json +17 -1
  50. package/packages/schema/schemas/test-catalog.schema.json +42 -0
  51. package/packages/schema/schemas/test-history.schema.json +28 -0
  52. package/packages/server/openapi.json +886 -3
  53. package/packages/visualizer/src/evidence/artifact-tags.tsx +285 -0
  54. package/packages/visualizer/src/evidence/artifacts.tsx +18 -12
  55. package/packages/visualizer/src/explorer/RunsView.tsx +23 -4
  56. package/packages/visualizer/src/explorer/parts.tsx +2 -1
@@ -88,6 +88,7 @@ export declare const EvidenceSummarySchema: z.ZodObject<{
88
88
  attempts: z.ZodNumber;
89
89
  links: z.ZodNumber;
90
90
  tags: z.ZodArray<z.ZodString>;
91
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
91
92
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
92
93
  roles: z.ZodArray<z.ZodString>;
93
94
  }, z.core.$loose>;
@@ -107,6 +108,12 @@ export declare const LayerHeaderSchema: z.ZodObject<{
107
108
  unknown: "unknown";
108
109
  modified: "modified";
109
110
  }>>;
111
+ run: z.ZodOptional<z.ZodObject<{
112
+ id: z.ZodString;
113
+ title: z.ZodOptional<z.ZodString>;
114
+ startedAtMs: z.ZodOptional<z.ZodNumber>;
115
+ endedAtMs: z.ZodOptional<z.ZodNumber>;
116
+ }, z.core.$loose>>;
110
117
  recording: z.ZodNullable<z.ZodUnknown>;
111
118
  live: z.ZodBoolean;
112
119
  counts: z.ZodRecord<z.ZodEnum<{
@@ -123,6 +130,7 @@ export declare const LayerHeaderSchema: z.ZodObject<{
123
130
  attempts: z.ZodNumber;
124
131
  links: z.ZodNumber;
125
132
  tags: z.ZodArray<z.ZodString>;
133
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
126
134
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
127
135
  roles: z.ZodArray<z.ZodString>;
128
136
  }, z.core.$loose>>;
@@ -156,6 +164,7 @@ export declare const LayerRowSchema: z.ZodObject<{
156
164
  attempts: z.ZodNumber;
157
165
  links: z.ZodNumber;
158
166
  tags: z.ZodArray<z.ZodString>;
167
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
159
168
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
160
169
  roles: z.ZodArray<z.ZodString>;
161
170
  }, z.core.$loose>>;
@@ -191,6 +200,7 @@ export declare const LayerRowsSchema: z.ZodObject<{
191
200
  attempts: z.ZodNumber;
192
201
  links: z.ZodNumber;
193
202
  tags: z.ZodArray<z.ZodString>;
203
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
194
204
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
195
205
  roles: z.ZodArray<z.ZodString>;
196
206
  }, z.core.$loose>>;
@@ -228,6 +238,7 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
228
238
  attempts: z.ZodNumber;
229
239
  links: z.ZodNumber;
230
240
  tags: z.ZodArray<z.ZodString>;
241
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
231
242
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
232
243
  roles: z.ZodArray<z.ZodString>;
233
244
  }, z.core.$loose>>;
@@ -248,6 +259,12 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
248
259
  unknown: "unknown";
249
260
  modified: "modified";
250
261
  }>>;
262
+ run: z.ZodOptional<z.ZodObject<{
263
+ id: z.ZodString;
264
+ title: z.ZodOptional<z.ZodString>;
265
+ startedAtMs: z.ZodOptional<z.ZodNumber>;
266
+ endedAtMs: z.ZodOptional<z.ZodNumber>;
267
+ }, z.core.$loose>>;
251
268
  recording: z.ZodNullable<z.ZodUnknown>;
252
269
  live: z.ZodBoolean;
253
270
  counts: z.ZodRecord<z.ZodEnum<{
@@ -264,6 +281,7 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
264
281
  attempts: z.ZodNumber;
265
282
  links: z.ZodNumber;
266
283
  tags: z.ZodArray<z.ZodString>;
284
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
267
285
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
268
286
  roles: z.ZodArray<z.ZodString>;
269
287
  }, z.core.$loose>>;
@@ -306,6 +324,7 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
306
324
  attempts: z.ZodNumber;
307
325
  links: z.ZodNumber;
308
326
  tags: z.ZodArray<z.ZodString>;
327
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
309
328
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
310
329
  roles: z.ZodArray<z.ZodString>;
311
330
  }, z.core.$loose>>;
@@ -326,6 +345,12 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
326
345
  unknown: "unknown";
327
346
  modified: "modified";
328
347
  }>>;
348
+ run: z.ZodOptional<z.ZodObject<{
349
+ id: z.ZodString;
350
+ title: z.ZodOptional<z.ZodString>;
351
+ startedAtMs: z.ZodOptional<z.ZodNumber>;
352
+ endedAtMs: z.ZodOptional<z.ZodNumber>;
353
+ }, z.core.$loose>>;
329
354
  recording: z.ZodNullable<z.ZodUnknown>;
330
355
  live: z.ZodBoolean;
331
356
  counts: z.ZodRecord<z.ZodEnum<{
@@ -342,6 +367,7 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
342
367
  attempts: z.ZodNumber;
343
368
  links: z.ZodNumber;
344
369
  tags: z.ZodArray<z.ZodString>;
370
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
345
371
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
346
372
  roles: z.ZodArray<z.ZodString>;
347
373
  }, z.core.$loose>>;
@@ -405,6 +431,7 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
405
431
  attempts: z.ZodNumber;
406
432
  links: z.ZodNumber;
407
433
  tags: z.ZodArray<z.ZodString>;
434
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
408
435
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
409
436
  roles: z.ZodArray<z.ZodString>;
410
437
  }, z.core.$loose>>;
@@ -425,6 +452,12 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
425
452
  unknown: "unknown";
426
453
  modified: "modified";
427
454
  }>>;
455
+ run: z.ZodOptional<z.ZodObject<{
456
+ id: z.ZodString;
457
+ title: z.ZodOptional<z.ZodString>;
458
+ startedAtMs: z.ZodOptional<z.ZodNumber>;
459
+ endedAtMs: z.ZodOptional<z.ZodNumber>;
460
+ }, z.core.$loose>>;
428
461
  recording: z.ZodNullable<z.ZodUnknown>;
429
462
  live: z.ZodBoolean;
430
463
  counts: z.ZodRecord<z.ZodEnum<{
@@ -441,6 +474,7 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
441
474
  attempts: z.ZodNumber;
442
475
  links: z.ZodNumber;
443
476
  tags: z.ZodArray<z.ZodString>;
477
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
444
478
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
445
479
  roles: z.ZodArray<z.ZodString>;
446
480
  }, z.core.$loose>>;
@@ -485,6 +519,12 @@ export declare const EvidencePageSchema: z.ZodObject<{
485
519
  unknown: "unknown";
486
520
  modified: "modified";
487
521
  }>>;
522
+ run: z.ZodOptional<z.ZodObject<{
523
+ id: z.ZodString;
524
+ title: z.ZodOptional<z.ZodString>;
525
+ startedAtMs: z.ZodOptional<z.ZodNumber>;
526
+ endedAtMs: z.ZodOptional<z.ZodNumber>;
527
+ }, z.core.$loose>>;
488
528
  recording: z.ZodNullable<z.ZodUnknown>;
489
529
  live: z.ZodBoolean;
490
530
  counts: z.ZodRecord<z.ZodEnum<{
@@ -501,6 +541,7 @@ export declare const EvidencePageSchema: z.ZodObject<{
501
541
  attempts: z.ZodNumber;
502
542
  links: z.ZodNumber;
503
543
  tags: z.ZodArray<z.ZodString>;
544
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
504
545
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
505
546
  roles: z.ZodArray<z.ZodString>;
506
547
  }, z.core.$loose>>;
@@ -543,6 +584,7 @@ export declare const CheckDetailSchema: z.ZodObject<{
543
584
  height: z.ZodOptional<z.ZodNumber>;
544
585
  durationMs: z.ZodOptional<z.ZodNumber>;
545
586
  description: z.ZodOptional<z.ZodString>;
587
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
546
588
  at: z.ZodOptional<z.ZodObject<{
547
589
  step: z.ZodOptional<z.ZodString>;
548
590
  offsetMs: z.ZodOptional<z.ZodNumber>;
@@ -607,6 +649,7 @@ export declare const CheckDetailSchema: z.ZodObject<{
607
649
  height: z.ZodOptional<z.ZodNumber>;
608
650
  durationMs: z.ZodOptional<z.ZodNumber>;
609
651
  description: z.ZodOptional<z.ZodString>;
652
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
610
653
  at: z.ZodOptional<z.ZodObject<{
611
654
  step: z.ZodOptional<z.ZodString>;
612
655
  offsetMs: z.ZodOptional<z.ZodNumber>;
@@ -651,6 +694,7 @@ export declare const CheckDetailSchema: z.ZodObject<{
651
694
  height: z.ZodOptional<z.ZodNumber>;
652
695
  durationMs: z.ZodOptional<z.ZodNumber>;
653
696
  description: z.ZodOptional<z.ZodString>;
697
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
654
698
  at: z.ZodOptional<z.ZodObject<{
655
699
  step: z.ZodOptional<z.ZodString>;
656
700
  offsetMs: z.ZodOptional<z.ZodNumber>;
@@ -702,6 +746,7 @@ export declare const CheckDetailSchema: z.ZodObject<{
702
746
  height: z.ZodOptional<z.ZodNumber>;
703
747
  durationMs: z.ZodOptional<z.ZodNumber>;
704
748
  description: z.ZodOptional<z.ZodString>;
749
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
705
750
  at: z.ZodOptional<z.ZodObject<{
706
751
  step: z.ZodOptional<z.ZodString>;
707
752
  offsetMs: z.ZodOptional<z.ZodNumber>;
@@ -769,6 +814,55 @@ export declare const ChecksResultSchema: z.ZodObject<{
769
814
  id: z.ZodString;
770
815
  checks: z.ZodNumber;
771
816
  }, z.core.$loose>;
817
+ /** Which attachment a reviewer's tags belong to: one attachment of one check of one archived layer. */
818
+ export declare const ArtifactTargetSchema: z.ZodObject<{
819
+ layer: z.ZodString;
820
+ check: z.ZodString;
821
+ kind: z.ZodOptional<z.ZodString>;
822
+ artifact: z.ZodString;
823
+ }, z.core.$loose>;
824
+ /** The body of `POST /api/reports/artifact-tags`: tags to add to and to remove from one attachment. At least one tag overall. */
825
+ export declare const ArtifactTagEditSchema: z.ZodObject<{
826
+ target: z.ZodObject<{
827
+ layer: z.ZodString;
828
+ check: z.ZodString;
829
+ kind: z.ZodOptional<z.ZodString>;
830
+ artifact: z.ZodString;
831
+ }, z.core.$loose>;
832
+ add: z.ZodOptional<z.ZodArray<z.ZodString>>;
833
+ remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
834
+ }, z.core.$loose>;
835
+ /** One recorded edit of an attachment's reviewer tags. Entries are never changed or removed: they are the audit trail. */
836
+ export declare const ArtifactTagEntrySchema: z.ZodObject<{
837
+ id: z.ZodString;
838
+ target: z.ZodObject<{
839
+ layer: z.ZodString;
840
+ check: z.ZodString;
841
+ kind: z.ZodOptional<z.ZodString>;
842
+ artifact: z.ZodString;
843
+ }, z.core.$loose>;
844
+ add: z.ZodArray<z.ZodString>;
845
+ remove: z.ZodArray<z.ZodString>;
846
+ by: z.ZodString;
847
+ atMs: z.ZodNumber;
848
+ }, z.core.$loose>;
849
+ /** `GET /api/reports/artifact-tags`: every recorded edit, oldest first. Fold them with `foldArtifactTags`. */
850
+ export declare const ArtifactTagsSchema: z.ZodObject<{
851
+ schemaVersion: z.ZodLiteral<1>;
852
+ entries: z.ZodArray<z.ZodObject<{
853
+ id: z.ZodString;
854
+ target: z.ZodObject<{
855
+ layer: z.ZodString;
856
+ check: z.ZodString;
857
+ kind: z.ZodOptional<z.ZodString>;
858
+ artifact: z.ZodString;
859
+ }, z.core.$loose>;
860
+ add: z.ZodArray<z.ZodString>;
861
+ remove: z.ZodArray<z.ZodString>;
862
+ by: z.ZodString;
863
+ atMs: z.ZodNumber;
864
+ }, z.core.$loose>>;
865
+ }, z.core.$loose>;
772
866
  /** The data of the `hello` event: sent first on `/api/events`. */
773
867
  export declare const HelloEventSchema: z.ZodObject<{
774
868
  version: z.ZodString;
@@ -826,6 +920,7 @@ export declare const TestResultEntrySchema: z.ZodObject<{
826
920
  attempts: z.ZodNumber;
827
921
  links: z.ZodNumber;
828
922
  tags: z.ZodArray<z.ZodString>;
923
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
829
924
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
830
925
  roles: z.ZodArray<z.ZodString>;
831
926
  }, z.core.$loose>>;
@@ -877,6 +972,7 @@ export declare const TestSummarySchema: z.ZodObject<{
877
972
  attempts: z.ZodNumber;
878
973
  links: z.ZodNumber;
879
974
  tags: z.ZodArray<z.ZodString>;
975
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
880
976
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
881
977
  roles: z.ZodArray<z.ZodString>;
882
978
  }, z.core.$loose>>;
@@ -907,6 +1003,8 @@ export declare const TestSummarySchema: z.ZodObject<{
907
1003
  branches: z.ZodArray<z.ZodString>;
908
1004
  }, z.core.$loose>;
909
1005
  tags: z.ZodArray<z.ZodString>;
1006
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1007
+ inheritedArtifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
910
1008
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
911
1009
  evidence: z.ZodObject<{
912
1010
  attachments: z.ZodNumber;
@@ -1054,6 +1152,10 @@ export declare const TestCatalogSchema: z.ZodObject<{
1054
1152
  value: z.ZodString;
1055
1153
  count: z.ZodNumber;
1056
1154
  }, z.core.$loose>>;
1155
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodObject<{
1156
+ value: z.ZodString;
1157
+ count: z.ZodNumber;
1158
+ }, z.core.$loose>>>;
1057
1159
  branches: z.ZodArray<z.ZodObject<{
1058
1160
  value: z.ZodString;
1059
1161
  count: z.ZodNumber;
@@ -1112,6 +1214,7 @@ export declare const TestCatalogSchema: z.ZodObject<{
1112
1214
  attempts: z.ZodNumber;
1113
1215
  links: z.ZodNumber;
1114
1216
  tags: z.ZodArray<z.ZodString>;
1217
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1115
1218
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
1116
1219
  roles: z.ZodArray<z.ZodString>;
1117
1220
  }, z.core.$loose>>;
@@ -1142,6 +1245,8 @@ export declare const TestCatalogSchema: z.ZodObject<{
1142
1245
  branches: z.ZodArray<z.ZodString>;
1143
1246
  }, z.core.$loose>;
1144
1247
  tags: z.ZodArray<z.ZodString>;
1248
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1249
+ inheritedArtifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1145
1250
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
1146
1251
  evidence: z.ZodObject<{
1147
1252
  attachments: z.ZodNumber;
@@ -1282,6 +1387,7 @@ export declare const TestHistorySchema: z.ZodObject<{
1282
1387
  attempts: z.ZodNumber;
1283
1388
  links: z.ZodNumber;
1284
1389
  tags: z.ZodArray<z.ZodString>;
1390
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1285
1391
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
1286
1392
  roles: z.ZodArray<z.ZodString>;
1287
1393
  }, z.core.$loose>>;
@@ -1312,6 +1418,8 @@ export declare const TestHistorySchema: z.ZodObject<{
1312
1418
  branches: z.ZodArray<z.ZodString>;
1313
1419
  }, z.core.$loose>;
1314
1420
  tags: z.ZodArray<z.ZodString>;
1421
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1422
+ inheritedArtifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1315
1423
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
1316
1424
  evidence: z.ZodObject<{
1317
1425
  attachments: z.ZodNumber;
@@ -1349,14 +1457,21 @@ export declare const TestHistorySchema: z.ZodObject<{
1349
1457
  attempts: z.ZodNumber;
1350
1458
  links: z.ZodNumber;
1351
1459
  tags: z.ZodArray<z.ZodString>;
1460
+ artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
1352
1461
  labels: z.ZodRecord<z.ZodString, z.ZodString>;
1353
1462
  roles: z.ZodArray<z.ZodString>;
1354
1463
  }, z.core.$loose>>;
1355
1464
  }, z.core.$loose>>;
1356
1465
  }, z.core.$loose>;
1357
- /** A run: the layers that share a run URL (else a branch and commit), with what they recorded. */
1466
+ /** A run: the layers that name the same execution (else share a run URL, else a branch and commit), with what they recorded. */
1358
1467
  export declare const ReportRunSchema: z.ZodObject<{
1359
1468
  key: z.ZodString;
1469
+ runId: z.ZodOptional<z.ZodString>;
1470
+ title: z.ZodOptional<z.ZodString>;
1471
+ freshness: z.ZodOptional<z.ZodEnum<{
1472
+ unknown: "unknown";
1473
+ modified: "modified";
1474
+ }>>;
1360
1475
  runUrl: z.ZodNullable<z.ZodString>;
1361
1476
  branch: z.ZodNullable<z.ZodString>;
1362
1477
  sha: z.ZodNullable<z.ZodString>;
@@ -1388,6 +1503,12 @@ export declare const RunListSchema: z.ZodObject<{
1388
1503
  total: z.ZodNumber;
1389
1504
  runs: z.ZodArray<z.ZodObject<{
1390
1505
  key: z.ZodString;
1506
+ runId: z.ZodOptional<z.ZodString>;
1507
+ title: z.ZodOptional<z.ZodString>;
1508
+ freshness: z.ZodOptional<z.ZodEnum<{
1509
+ unknown: "unknown";
1510
+ modified: "modified";
1511
+ }>>;
1391
1512
  runUrl: z.ZodNullable<z.ZodString>;
1392
1513
  branch: z.ZodNullable<z.ZodString>;
1393
1514
  sha: z.ZodNullable<z.ZodString>;
@@ -1419,6 +1540,12 @@ export declare const RunDetailSchema: z.ZodObject<{
1419
1540
  version: z.ZodString;
1420
1541
  run: z.ZodObject<{
1421
1542
  key: z.ZodString;
1543
+ runId: z.ZodOptional<z.ZodString>;
1544
+ title: z.ZodOptional<z.ZodString>;
1545
+ freshness: z.ZodOptional<z.ZodEnum<{
1546
+ unknown: "unknown";
1547
+ modified: "modified";
1548
+ }>>;
1422
1549
  runUrl: z.ZodNullable<z.ZodString>;
1423
1550
  branch: z.ZodNullable<z.ZodString>;
1424
1551
  sha: z.ZodNullable<z.ZodString>;
@@ -14,7 +14,7 @@
14
14
  * @see docs/server.md
15
15
  */
16
16
  import { z } from 'zod/v4';
17
- import { CheckSchema } from './layer.js';
17
+ import { CheckSchema, LayerRunSchema } from './layer.js';
18
18
  /** One of the statuses a check has in a report: `passed`, `failed`, `running` (not finished) or `not-run`. Closed. */
19
19
  export const EvidenceStatusSchema = z.enum(['passed', 'failed', 'running', 'not-run']);
20
20
  /**
@@ -70,6 +70,7 @@ export const EvidenceSummarySchema = z.looseObject({
70
70
  attempts: z.number().int().nonnegative(),
71
71
  links: z.number().int().nonnegative(),
72
72
  tags: z.array(z.string()),
73
+ artifactTags: z.array(z.string()).optional().describe('Normalized tags of the attachments themselves, sorted and distinct. Absent when no attachment is tagged; never inherited from a check or run'),
73
74
  labels: z.record(z.string(), z.string()),
74
75
  roles: z.array(z.string())
75
76
  });
@@ -86,6 +87,7 @@ export const LayerHeaderSchema = z.looseObject({
86
87
  runUrl: z.string().nullable(),
87
88
  parameters: z.record(z.string(), z.string()).describe('Other choices that make a result its own slot'),
88
89
  freshness: z.enum(['unknown', 'modified']).optional().describe('`modified`: recorded from a checkout with uncommitted changes. `unknown`: origin not captured. Absent: clean'),
90
+ run: LayerRunSchema.optional().describe('The execution the producer named for it (one local or manual invocation). Grouping and display only; never part of the slot'),
89
91
  recording: z.unknown().nullable().describe('Where recorded timelines are read from, or null'),
90
92
  live: z.boolean(),
91
93
  counts: z.record(EvidenceStatusSchema, z.number().int().nonnegative()),
@@ -185,6 +187,33 @@ export const ChecksResultSchema = z.looseObject({
185
187
  id: z.string().describe('The layer id'),
186
188
  checks: z.number().int().nonnegative()
187
189
  });
190
+ /** Which attachment a reviewer's tags belong to: one attachment of one check of one archived layer. */
191
+ export const ArtifactTargetSchema = z.looseObject({
192
+ layer: z.string().regex(/^[0-9a-f]{64}$/).describe('The id of the archived layer that holds the check'),
193
+ check: z.string().min(1).describe('The check\'s id'),
194
+ kind: z.string().min(1).optional().describe('The kind of the part holding the check, when the same id exists in several parts'),
195
+ artifact: z.string().min(1).max(1024).describe('The attachment: `id:<id>` when it has an id, else `key:<bundleKey>`, else `name:<name>` (see `artifactRef`)')
196
+ });
197
+ /** The body of `POST /api/reports/artifact-tags`: tags to add to and to remove from one attachment. At least one tag overall. */
198
+ export const ArtifactTagEditSchema = z.looseObject({
199
+ target: ArtifactTargetSchema,
200
+ add: z.array(z.string()).max(20).optional().describe('Tags to add. `demo` and `#demo` are the same tag'),
201
+ remove: z.array(z.string()).max(20).optional().describe('Reviewer tags to remove. Tags the producer wrote are part of the immutable layer and stay')
202
+ });
203
+ /** One recorded edit of an attachment's reviewer tags. Entries are never changed or removed: they are the audit trail. */
204
+ export const ArtifactTagEntrySchema = z.looseObject({
205
+ id: z.string().describe('Unique and time-ordered'),
206
+ target: ArtifactTargetSchema,
207
+ add: z.array(z.string()).describe('Normalized tags added'),
208
+ remove: z.array(z.string()).describe('Normalized tags removed'),
209
+ by: z.string().describe('The name of the token that made the edit (never the token)'),
210
+ atMs: z.number().describe('When the server recorded it, epoch milliseconds')
211
+ });
212
+ /** `GET /api/reports/artifact-tags`: every recorded edit, oldest first. Fold them with `foldArtifactTags`. */
213
+ export const ArtifactTagsSchema = z.looseObject({
214
+ schemaVersion: z.literal(1),
215
+ entries: z.array(ArtifactTagEntrySchema)
216
+ });
188
217
  /** The data of the `hello` event: sent first on `/api/events`. */
189
218
  export const HelloEventSchema = z.looseObject({ version: z.string(), ready: z.boolean(), time: z.number(), heartbeatMs: z.number().positive().optional() });
190
219
  /** The data of the `report` event: layers arrived. Enough to say who sent what, without asking. */
@@ -242,6 +271,8 @@ export const TestSummarySchema = z.looseObject({
242
271
  runs: z.number().int().nonnegative(), branches: z.array(z.string())
243
272
  }),
244
273
  tags: z.array(z.string()),
274
+ artifactTags: z.array(z.string()).optional().describe('Normalized tags of the attachments of its current results, such as `demo` (shown `#demo`). Not inherited from a check or run, unlike `tags`'),
275
+ inheritedArtifactTags: z.array(z.string()).optional().describe('Normalized tags its attachments inherit from their check and run, apart from `artifactTags`: what `?artifactTag=…&inherited=1` also matches'),
245
276
  labels: z.record(z.string(), z.string()),
246
277
  evidence: z.looseObject({ attachments: z.number().int().nonnegative(), steps: z.number().int().nonnegative(), attempts: z.number().int().nonnegative(), roles: z.array(z.string()) }),
247
278
  lastRecordedAtMs: z.number(),
@@ -268,7 +299,7 @@ export const TestCatalogSchema = z.looseObject({
268
299
  facets: z.looseObject({
269
300
  statuses: z.array(FacetValueSchema), environments: z.array(FacetValueSchema), producers: z.array(FacetValueSchema), domains: z.array(FacetValueSchema),
270
301
  specs: z.array(CatalogSpecSchema.extend({ tests: z.number().int().nonnegative(), counts: StatusCountsSchema })),
271
- tags: z.array(FacetValueSchema), branches: z.array(FacetValueSchema), labels: z.record(z.string(), z.array(FacetValueSchema))
302
+ tags: z.array(FacetValueSchema), artifactTags: z.array(FacetValueSchema).optional(), branches: z.array(FacetValueSchema), labels: z.record(z.string(), z.array(FacetValueSchema))
272
303
  }),
273
304
  total: z.number().int().nonnegative().describe('Tests the query matched, before offset and limit'),
274
305
  offset: z.number().int().nonnegative(),
@@ -332,9 +363,12 @@ export const TestHistorySchema = z.looseObject({
332
363
  test: TestSummarySchema,
333
364
  history: z.array(TestResultEntrySchema)
334
365
  });
335
- /** A run: the layers that share a run URL (else a branch and commit), with what they recorded. */
366
+ /** A run: the layers that name the same execution (else share a run URL, else a branch and commit), with what they recorded. */
336
367
  export const ReportRunSchema = z.looseObject({
337
- key: z.string().describe('The run URL, or `branch@sha`. Pass it to `/api/reports/runs/detail?key=` or `/api/reports/tests?run=`'),
368
+ key: z.string().describe('`run:<id>` for an execution a producer named, else the run URL, else `branch@sha`. Pass it to `/api/reports/runs/detail?key=` or `/api/reports/tests?run=`'),
369
+ runId: z.string().optional().describe('The execution id the producer named, when it did. Layers that share it are one run however many uploads they took'),
370
+ title: z.string().optional().describe('The human title of the execution (the newest layer\'s). Presentation only: the key, commit and `freshness` are unaffected'),
371
+ freshness: z.enum(['unknown', 'modified']).optional().describe('`modified` when any layer of the run was recorded from a checkout with uncommitted changes; `unknown` when an origin was not captured; absent when all are clean. Shown beside the commit, never replaced by the title'),
338
372
  runUrl: z.string().nullable(), branch: z.string().nullable(), sha: z.string().nullable(),
339
373
  startedAtMs: z.number(), endedAtMs: z.number(), spanMs: z.number(),
340
374
  producers: z.array(z.string()), environments: z.array(z.string()),