@crvouga/atlas 0.14.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.
- package/CHANGELOG.md +6 -0
- package/dist/reports/src/artifact-tag-store.d.ts +20 -0
- package/dist/reports/src/artifact-tag-store.js +70 -0
- package/dist/reports/src/artifact-tags.d.ts +96 -0
- package/dist/reports/src/artifact-tags.js +96 -0
- package/dist/reports/src/evidence-detail.d.ts +1 -1
- package/dist/reports/src/evidence-detail.js +6 -2
- package/dist/reports/src/evidence-types.d.ts +2 -0
- package/dist/reports/src/reports-explorer-route.d.ts +8 -0
- package/dist/reports/src/reports-route.d.ts +8 -0
- package/dist/reports/src/test-catalog.d.ts +11 -23
- package/dist/reports/src/test-catalog.js +42 -4
- package/dist/schema/src/api.d.ts +79 -0
- package/dist/schema/src/api.js +31 -1
- package/dist/schema/src/layer.d.ts +33 -0
- package/dist/schema/src/layer.js +11 -1
- package/dist/server/src/app.js +32 -1
- package/dist/server/src/openapi.d.ts +1 -1
- package/dist/server/src/openapi.js +18 -2
- package/docs/extending.md +3 -0
- package/docs/reference/http-api.md +48 -0
- package/docs/reference/reports.md +217 -2
- package/docs/reference/schema.md +32 -0
- package/docs/rich-evidence.md +28 -0
- package/docs/server.md +24 -0
- package/llms-full.txt +103 -0
- package/package.json +1 -1
- package/packages/schema/schemas/check-detail.schema.json +28 -0
- package/packages/schema/schemas/effective-delta.schema.json +14 -0
- package/packages/schema/schemas/effective-evidence.schema.json +14 -0
- package/packages/schema/schemas/evidence-page.schema.json +7 -0
- package/packages/schema/schemas/layer-rows.schema.json +7 -0
- package/packages/schema/schemas/layer.schema.json +70 -0
- package/packages/schema/schemas/publish-checks.schema.json +35 -0
- package/packages/schema/schemas/test-catalog.schema.json +42 -0
- package/packages/schema/schemas/test-history.schema.json +28 -0
- package/packages/server/openapi.json +732 -1
- package/packages/visualizer/src/evidence/artifact-tags.tsx +285 -0
- package/packages/visualizer/src/evidence/artifacts.tsx +18 -12
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Test catalog, history and runs
|
|
3
|
+
*
|
|
4
|
+
* What a person or an agent asks of a report once it holds more than a handful of checks: every test with where it ran,
|
|
5
|
+
* how it went over time and how long it takes; the specs, domains, environments and producers they fall under; the CI
|
|
6
|
+
* runs that produced them and which tests each one ran.
|
|
7
|
+
*
|
|
8
|
+
* - `TestHistory` keeps every recorded result of every test (bounded per test) and every run's results, folded in one
|
|
9
|
+
* layer at a time, in any order, with the same outcome. It never decides a status: the current status of a test is
|
|
10
|
+
* always the report's winner (`combineEvidence`), and history only describes how it got there.
|
|
11
|
+
* - `testCatalog` turns the report's winners (plus a history, when there is one) into a `TestCatalog`: a summary with
|
|
12
|
+
* insights (slowest, flaky, failing), facets to filter by, and the tests that match a `TestQuery`.
|
|
13
|
+
* - `testHistory`, `runList` and `runDetail` answer for one test, every run, and one run.
|
|
14
|
+
* - `catalogMarkdown`, `historyMarkdown`, `runsMarkdown` and `runMarkdown` say the same in Markdown, for an agent or a
|
|
15
|
+
* terminal.
|
|
16
|
+
*
|
|
17
|
+
* A test is a check identity (its spec path and id) regardless of producer, environment and parameters; each of those
|
|
18
|
+
* combinations is one of its results. A result that is not `passed` is never counted as a pass, and a test with no
|
|
19
|
+
* completed result has no pass rate.
|
|
20
|
+
*
|
|
21
|
+
* @see docs/server.md#reading-the-report-as-an-agent
|
|
22
|
+
*/
|
|
23
|
+
import { displayTag, normalizeTag, normalizeTags } from './artifact-tags.js';
|
|
1
24
|
import { checkSlots } from './evidence-view.js';
|
|
2
25
|
import { combineEvidence, emptyCounts, slotKey, specPath as normalSpecPath } from './layer-merge.js';
|
|
3
26
|
import { RecordedSpecs } from './recorded-specs.js';
|
|
@@ -337,15 +360,22 @@ function outcomeOf(result) {
|
|
|
337
360
|
function summaryOf(slot, history, known) {
|
|
338
361
|
const outcomes = slot.outcomes.map(outcomeOf);
|
|
339
362
|
const tags = new Set();
|
|
363
|
+
const artifactTags = new Set();
|
|
364
|
+
const inheritedTags = new Set();
|
|
340
365
|
const labels = {};
|
|
341
366
|
let attachments = 0, steps = 0, attempts = 0;
|
|
342
367
|
const roles = new Set();
|
|
343
|
-
for (const outcome of outcomes) {
|
|
368
|
+
for (const [at, outcome] of outcomes.entries()) {
|
|
344
369
|
const evidence = outcome.evidence;
|
|
345
370
|
if (!evidence)
|
|
346
371
|
continue;
|
|
372
|
+
if (evidence.attachments > 0)
|
|
373
|
+
for (const tag of normalizeTags([...evidence.tags, ...(slot.outcomes[at]?.layer.evidence?.tags ?? [])]))
|
|
374
|
+
inheritedTags.add(tag);
|
|
347
375
|
for (const tag of evidence.tags)
|
|
348
376
|
tags.add(tag);
|
|
377
|
+
for (const tag of evidence.artifactTags ?? [])
|
|
378
|
+
artifactTags.add(tag);
|
|
349
379
|
Object.assign(labels, evidence.labels);
|
|
350
380
|
attachments += evidence.attachments;
|
|
351
381
|
steps += evidence.steps;
|
|
@@ -366,6 +396,8 @@ function summaryOf(slot, history, known) {
|
|
|
366
396
|
outcomes,
|
|
367
397
|
stats: statsOf(history?.of(slot.key) ?? [], outcomes, tagList, labels),
|
|
368
398
|
tags: tagList,
|
|
399
|
+
...(artifactTags.size ? { artifactTags: [...artifactTags].sort() } : {}),
|
|
400
|
+
...([...inheritedTags].some(tag => !artifactTags.has(tag)) ? { inheritedArtifactTags: [...inheritedTags].filter(tag => !artifactTags.has(tag)).sort() } : {}),
|
|
369
401
|
labels,
|
|
370
402
|
evidence: { attachments, steps, attempts, roles: [...roles].sort() },
|
|
371
403
|
lastRecordedAtMs: slot.latestAtMs,
|
|
@@ -375,7 +407,7 @@ function summaryOf(slot, history, known) {
|
|
|
375
407
|
/** The lowercase text a search matches a test against: title, id, spec, domain, tags, labels, environments and producers. */
|
|
376
408
|
export function haystackOf(test) {
|
|
377
409
|
return [
|
|
378
|
-
test.title, test.id, test.specPath ?? '', test.spec?.title ?? '', test.spec?.domain ?? '', ...test.tags,
|
|
410
|
+
test.title, test.id, test.specPath ?? '', test.spec?.title ?? '', test.spec?.domain ?? '', ...test.tags, ...(test.artifactTags ?? []).map(displayTag),
|
|
379
411
|
...Object.entries(test.labels).flatMap(([key, value]) => [key, value]), ...test.environments, ...test.producers,
|
|
380
412
|
].join('\n').toLowerCase();
|
|
381
413
|
}
|
|
@@ -481,6 +513,7 @@ export function catalogModel(layers, sources = {}) {
|
|
|
481
513
|
domains: facet(tests, test => [test.spec?.domain || '(no spec)']),
|
|
482
514
|
specs: [...specGroups].map(([, list]) => { const g = group(list[0].spec.path, list); return { ...list[0].spec, tests: g.tests, counts: g.counts }; }).sort((a, b) => compareText(a.domain, b.domain) || compareText(a.title, b.title)),
|
|
483
515
|
tags: facet(tests, test => test.tags),
|
|
516
|
+
artifactTags: facet(tests, test => test.artifactTags ?? []),
|
|
484
517
|
branches: facet(tests, test => test.stats.branches),
|
|
485
518
|
labels: Object.fromEntries([...labelKeys].sort().map(key => [key, facet(tests, test => (test.labels[key] === undefined ? [] : [test.labels[key]]))])),
|
|
486
519
|
};
|
|
@@ -515,6 +548,8 @@ export function matchesQuery(model, test, query, inRun) {
|
|
|
515
548
|
return false;
|
|
516
549
|
if (query.tag?.length && !query.tag.some(tag => test.tags.includes(tag)))
|
|
517
550
|
return false;
|
|
551
|
+
if (query.artifactTag?.length && !query.artifactTag.some(tag => { const wanted = normalizeTag(tag); return wanted !== null && ((test.artifactTags?.includes(wanted) ?? false) || (query.inherited === true && (test.inheritedArtifactTags?.includes(wanted) ?? false))); }))
|
|
552
|
+
return false;
|
|
518
553
|
if (inRun && !inRun.has(test.key))
|
|
519
554
|
return false;
|
|
520
555
|
return true;
|
|
@@ -546,7 +581,7 @@ export function runDetail(history, version, key) {
|
|
|
546
581
|
const found = history.run(key);
|
|
547
582
|
return found ? { schemaVersion: TEST_CATALOG_VERSION, version, ...found } : null;
|
|
548
583
|
}
|
|
549
|
-
/** Reads a `TestQuery` from URL search parameters: `q`, `sort`, `offset`, `limit`, `run`, and repeatable or comma-separated `status`, `environment`, `producer`, `domain`, `spec`, `tag`. */
|
|
584
|
+
/** Reads a `TestQuery` from URL search parameters: `q`, `sort`, `offset`, `limit`, `run`, and repeatable or comma-separated `status`, `environment`, `producer`, `domain`, `spec`, `tag`, `artifactTag`, and `inherited=1`. */
|
|
550
585
|
export function parseTestQuery(params) {
|
|
551
586
|
const many = (name) => params.getAll(name).flatMap(value => value.split(',')).map(value => value.trim()).filter(Boolean);
|
|
552
587
|
const number = (name) => { const value = params.get(name); return value !== null && /^\d+$/.test(value) ? Number(value) : undefined; };
|
|
@@ -555,11 +590,13 @@ export function parseTestQuery(params) {
|
|
|
555
590
|
const q = params.get('q');
|
|
556
591
|
if (q)
|
|
557
592
|
query.q = q;
|
|
558
|
-
for (const name of ['status', 'environment', 'producer', 'domain', 'spec', 'tag']) {
|
|
593
|
+
for (const name of ['status', 'environment', 'producer', 'domain', 'spec', 'tag', 'artifactTag']) {
|
|
559
594
|
const values = many(name);
|
|
560
595
|
if (values.length)
|
|
561
596
|
query[name] = values;
|
|
562
597
|
}
|
|
598
|
+
if (['1', 'true'].includes(params.get('inherited') ?? ''))
|
|
599
|
+
query.inherited = true;
|
|
563
600
|
const run = params.get('run');
|
|
564
601
|
if (run)
|
|
565
602
|
query.run = run;
|
|
@@ -633,6 +670,7 @@ export function historyMarkdown(document) {
|
|
|
633
670
|
`- Results: ${test.stats.results} recorded, ${test.stats.passed} passed, ${test.stats.failed} failed${test.stats.passRate === null ? '' : `, pass rate ${Math.round(test.stats.passRate * 100)}%`}, in ${test.stats.runs} runs`,
|
|
634
671
|
`- Duration: ${d ? `avg ${formatMs(d.avgMs)}, p50 ${formatMs(d.p50Ms)}, p95 ${formatMs(d.p95Ms)}, min ${formatMs(d.minMs)}, max ${formatMs(d.maxMs)}, last ${formatMs(d.lastMs)}` : 'not measured'}`,
|
|
635
672
|
...(test.tags.length ? [`- Tags: ${test.tags.join(', ')}`] : []),
|
|
673
|
+
...(test.artifactTags?.length ? [`- Artifact tags: ${test.artifactTags.map(displayTag).join(', ')}`] : []),
|
|
636
674
|
...(Object.keys(test.labels).length ? [`- Labels: ${Object.entries(test.labels).map(([k, v]) => `${k}=${v}`).join(', ')}`] : []),
|
|
637
675
|
`- Evidence: ${test.evidence.attachments} attachments${test.evidence.roles.length ? ` (${test.evidence.roles.join(', ')})` : ''}, ${test.evidence.steps} steps`,
|
|
638
676
|
'',
|
package/dist/schema/src/api.d.ts
CHANGED
|
@@ -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>;
|
|
@@ -129,6 +130,7 @@ export declare const LayerHeaderSchema: z.ZodObject<{
|
|
|
129
130
|
attempts: z.ZodNumber;
|
|
130
131
|
links: z.ZodNumber;
|
|
131
132
|
tags: z.ZodArray<z.ZodString>;
|
|
133
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
132
134
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
133
135
|
roles: z.ZodArray<z.ZodString>;
|
|
134
136
|
}, z.core.$loose>>;
|
|
@@ -162,6 +164,7 @@ export declare const LayerRowSchema: z.ZodObject<{
|
|
|
162
164
|
attempts: z.ZodNumber;
|
|
163
165
|
links: z.ZodNumber;
|
|
164
166
|
tags: z.ZodArray<z.ZodString>;
|
|
167
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
165
168
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
166
169
|
roles: z.ZodArray<z.ZodString>;
|
|
167
170
|
}, z.core.$loose>>;
|
|
@@ -197,6 +200,7 @@ export declare const LayerRowsSchema: z.ZodObject<{
|
|
|
197
200
|
attempts: z.ZodNumber;
|
|
198
201
|
links: z.ZodNumber;
|
|
199
202
|
tags: z.ZodArray<z.ZodString>;
|
|
203
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
200
204
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
201
205
|
roles: z.ZodArray<z.ZodString>;
|
|
202
206
|
}, z.core.$loose>>;
|
|
@@ -234,6 +238,7 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
|
|
|
234
238
|
attempts: z.ZodNumber;
|
|
235
239
|
links: z.ZodNumber;
|
|
236
240
|
tags: z.ZodArray<z.ZodString>;
|
|
241
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
237
242
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
238
243
|
roles: z.ZodArray<z.ZodString>;
|
|
239
244
|
}, z.core.$loose>>;
|
|
@@ -276,6 +281,7 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
|
|
|
276
281
|
attempts: z.ZodNumber;
|
|
277
282
|
links: z.ZodNumber;
|
|
278
283
|
tags: z.ZodArray<z.ZodString>;
|
|
284
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
279
285
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
280
286
|
roles: z.ZodArray<z.ZodString>;
|
|
281
287
|
}, z.core.$loose>>;
|
|
@@ -318,6 +324,7 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
|
|
|
318
324
|
attempts: z.ZodNumber;
|
|
319
325
|
links: z.ZodNumber;
|
|
320
326
|
tags: z.ZodArray<z.ZodString>;
|
|
327
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
321
328
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
322
329
|
roles: z.ZodArray<z.ZodString>;
|
|
323
330
|
}, z.core.$loose>>;
|
|
@@ -360,6 +367,7 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
|
|
|
360
367
|
attempts: z.ZodNumber;
|
|
361
368
|
links: z.ZodNumber;
|
|
362
369
|
tags: z.ZodArray<z.ZodString>;
|
|
370
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
363
371
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
364
372
|
roles: z.ZodArray<z.ZodString>;
|
|
365
373
|
}, z.core.$loose>>;
|
|
@@ -423,6 +431,7 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
|
|
|
423
431
|
attempts: z.ZodNumber;
|
|
424
432
|
links: z.ZodNumber;
|
|
425
433
|
tags: z.ZodArray<z.ZodString>;
|
|
434
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
426
435
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
427
436
|
roles: z.ZodArray<z.ZodString>;
|
|
428
437
|
}, z.core.$loose>>;
|
|
@@ -465,6 +474,7 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
|
|
|
465
474
|
attempts: z.ZodNumber;
|
|
466
475
|
links: z.ZodNumber;
|
|
467
476
|
tags: z.ZodArray<z.ZodString>;
|
|
477
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
468
478
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
469
479
|
roles: z.ZodArray<z.ZodString>;
|
|
470
480
|
}, z.core.$loose>>;
|
|
@@ -531,6 +541,7 @@ export declare const EvidencePageSchema: z.ZodObject<{
|
|
|
531
541
|
attempts: z.ZodNumber;
|
|
532
542
|
links: z.ZodNumber;
|
|
533
543
|
tags: z.ZodArray<z.ZodString>;
|
|
544
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
534
545
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
535
546
|
roles: z.ZodArray<z.ZodString>;
|
|
536
547
|
}, z.core.$loose>>;
|
|
@@ -573,6 +584,7 @@ export declare const CheckDetailSchema: z.ZodObject<{
|
|
|
573
584
|
height: z.ZodOptional<z.ZodNumber>;
|
|
574
585
|
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
575
586
|
description: z.ZodOptional<z.ZodString>;
|
|
587
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
576
588
|
at: z.ZodOptional<z.ZodObject<{
|
|
577
589
|
step: z.ZodOptional<z.ZodString>;
|
|
578
590
|
offsetMs: z.ZodOptional<z.ZodNumber>;
|
|
@@ -637,6 +649,7 @@ export declare const CheckDetailSchema: z.ZodObject<{
|
|
|
637
649
|
height: z.ZodOptional<z.ZodNumber>;
|
|
638
650
|
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
639
651
|
description: z.ZodOptional<z.ZodString>;
|
|
652
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
640
653
|
at: z.ZodOptional<z.ZodObject<{
|
|
641
654
|
step: z.ZodOptional<z.ZodString>;
|
|
642
655
|
offsetMs: z.ZodOptional<z.ZodNumber>;
|
|
@@ -681,6 +694,7 @@ export declare const CheckDetailSchema: z.ZodObject<{
|
|
|
681
694
|
height: z.ZodOptional<z.ZodNumber>;
|
|
682
695
|
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
683
696
|
description: z.ZodOptional<z.ZodString>;
|
|
697
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
684
698
|
at: z.ZodOptional<z.ZodObject<{
|
|
685
699
|
step: z.ZodOptional<z.ZodString>;
|
|
686
700
|
offsetMs: z.ZodOptional<z.ZodNumber>;
|
|
@@ -732,6 +746,7 @@ export declare const CheckDetailSchema: z.ZodObject<{
|
|
|
732
746
|
height: z.ZodOptional<z.ZodNumber>;
|
|
733
747
|
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
734
748
|
description: z.ZodOptional<z.ZodString>;
|
|
749
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
735
750
|
at: z.ZodOptional<z.ZodObject<{
|
|
736
751
|
step: z.ZodOptional<z.ZodString>;
|
|
737
752
|
offsetMs: z.ZodOptional<z.ZodNumber>;
|
|
@@ -799,6 +814,55 @@ export declare const ChecksResultSchema: z.ZodObject<{
|
|
|
799
814
|
id: z.ZodString;
|
|
800
815
|
checks: z.ZodNumber;
|
|
801
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>;
|
|
802
866
|
/** The data of the `hello` event: sent first on `/api/events`. */
|
|
803
867
|
export declare const HelloEventSchema: z.ZodObject<{
|
|
804
868
|
version: z.ZodString;
|
|
@@ -856,6 +920,7 @@ export declare const TestResultEntrySchema: z.ZodObject<{
|
|
|
856
920
|
attempts: z.ZodNumber;
|
|
857
921
|
links: z.ZodNumber;
|
|
858
922
|
tags: z.ZodArray<z.ZodString>;
|
|
923
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
859
924
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
860
925
|
roles: z.ZodArray<z.ZodString>;
|
|
861
926
|
}, z.core.$loose>>;
|
|
@@ -907,6 +972,7 @@ export declare const TestSummarySchema: z.ZodObject<{
|
|
|
907
972
|
attempts: z.ZodNumber;
|
|
908
973
|
links: z.ZodNumber;
|
|
909
974
|
tags: z.ZodArray<z.ZodString>;
|
|
975
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
910
976
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
911
977
|
roles: z.ZodArray<z.ZodString>;
|
|
912
978
|
}, z.core.$loose>>;
|
|
@@ -937,6 +1003,8 @@ export declare const TestSummarySchema: z.ZodObject<{
|
|
|
937
1003
|
branches: z.ZodArray<z.ZodString>;
|
|
938
1004
|
}, z.core.$loose>;
|
|
939
1005
|
tags: z.ZodArray<z.ZodString>;
|
|
1006
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1007
|
+
inheritedArtifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
940
1008
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
941
1009
|
evidence: z.ZodObject<{
|
|
942
1010
|
attachments: z.ZodNumber;
|
|
@@ -1084,6 +1152,10 @@ export declare const TestCatalogSchema: z.ZodObject<{
|
|
|
1084
1152
|
value: z.ZodString;
|
|
1085
1153
|
count: z.ZodNumber;
|
|
1086
1154
|
}, z.core.$loose>>;
|
|
1155
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1156
|
+
value: z.ZodString;
|
|
1157
|
+
count: z.ZodNumber;
|
|
1158
|
+
}, z.core.$loose>>>;
|
|
1087
1159
|
branches: z.ZodArray<z.ZodObject<{
|
|
1088
1160
|
value: z.ZodString;
|
|
1089
1161
|
count: z.ZodNumber;
|
|
@@ -1142,6 +1214,7 @@ export declare const TestCatalogSchema: z.ZodObject<{
|
|
|
1142
1214
|
attempts: z.ZodNumber;
|
|
1143
1215
|
links: z.ZodNumber;
|
|
1144
1216
|
tags: z.ZodArray<z.ZodString>;
|
|
1217
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1145
1218
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1146
1219
|
roles: z.ZodArray<z.ZodString>;
|
|
1147
1220
|
}, z.core.$loose>>;
|
|
@@ -1172,6 +1245,8 @@ export declare const TestCatalogSchema: z.ZodObject<{
|
|
|
1172
1245
|
branches: z.ZodArray<z.ZodString>;
|
|
1173
1246
|
}, z.core.$loose>;
|
|
1174
1247
|
tags: z.ZodArray<z.ZodString>;
|
|
1248
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1249
|
+
inheritedArtifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1175
1250
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1176
1251
|
evidence: z.ZodObject<{
|
|
1177
1252
|
attachments: z.ZodNumber;
|
|
@@ -1312,6 +1387,7 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
1312
1387
|
attempts: z.ZodNumber;
|
|
1313
1388
|
links: z.ZodNumber;
|
|
1314
1389
|
tags: z.ZodArray<z.ZodString>;
|
|
1390
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1315
1391
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1316
1392
|
roles: z.ZodArray<z.ZodString>;
|
|
1317
1393
|
}, z.core.$loose>>;
|
|
@@ -1342,6 +1418,8 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
1342
1418
|
branches: z.ZodArray<z.ZodString>;
|
|
1343
1419
|
}, z.core.$loose>;
|
|
1344
1420
|
tags: z.ZodArray<z.ZodString>;
|
|
1421
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1422
|
+
inheritedArtifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1345
1423
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1346
1424
|
evidence: z.ZodObject<{
|
|
1347
1425
|
attachments: z.ZodNumber;
|
|
@@ -1379,6 +1457,7 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
1379
1457
|
attempts: z.ZodNumber;
|
|
1380
1458
|
links: z.ZodNumber;
|
|
1381
1459
|
tags: z.ZodArray<z.ZodString>;
|
|
1460
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1382
1461
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1383
1462
|
roles: z.ZodArray<z.ZodString>;
|
|
1384
1463
|
}, z.core.$loose>>;
|
package/dist/schema/src/api.js
CHANGED
|
@@ -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
|
});
|
|
@@ -186,6 +187,33 @@ export const ChecksResultSchema = z.looseObject({
|
|
|
186
187
|
id: z.string().describe('The layer id'),
|
|
187
188
|
checks: z.number().int().nonnegative()
|
|
188
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
|
+
});
|
|
189
217
|
/** The data of the `hello` event: sent first on `/api/events`. */
|
|
190
218
|
export const HelloEventSchema = z.looseObject({ version: z.string(), ready: z.boolean(), time: z.number(), heartbeatMs: z.number().positive().optional() });
|
|
191
219
|
/** The data of the `report` event: layers arrived. Enough to say who sent what, without asking. */
|
|
@@ -243,6 +271,8 @@ export const TestSummarySchema = z.looseObject({
|
|
|
243
271
|
runs: z.number().int().nonnegative(), branches: z.array(z.string())
|
|
244
272
|
}),
|
|
245
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'),
|
|
246
276
|
labels: z.record(z.string(), z.string()),
|
|
247
277
|
evidence: z.looseObject({ attachments: z.number().int().nonnegative(), steps: z.number().int().nonnegative(), attempts: z.number().int().nonnegative(), roles: z.array(z.string()) }),
|
|
248
278
|
lastRecordedAtMs: z.number(),
|
|
@@ -269,7 +299,7 @@ export const TestCatalogSchema = z.looseObject({
|
|
|
269
299
|
facets: z.looseObject({
|
|
270
300
|
statuses: z.array(FacetValueSchema), environments: z.array(FacetValueSchema), producers: z.array(FacetValueSchema), domains: z.array(FacetValueSchema),
|
|
271
301
|
specs: z.array(CatalogSpecSchema.extend({ tests: z.number().int().nonnegative(), counts: StatusCountsSchema })),
|
|
272
|
-
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))
|
|
273
303
|
}),
|
|
274
304
|
total: z.number().int().nonnegative().describe('Tests the query matched, before offset and limit'),
|
|
275
305
|
offset: z.number().int().nonnegative(),
|