@crvouga/atlas 1.0.0 → 1.2.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 +12 -0
- package/dist/reports/src/artifact-query.d.ts +123 -0
- package/dist/reports/src/artifact-query.js +234 -0
- package/dist/reports/src/evidence-detail.js +2 -1
- package/dist/reports/src/evidence-types.d.ts +2 -0
- package/dist/reports/src/test-catalog.d.ts +101 -5
- package/dist/reports/src/test-catalog.js +140 -5
- package/dist/schema/src/api.d.ts +225 -0
- package/dist/schema/src/api.js +41 -2
- package/dist/server/src/app.js +16 -5
- package/dist/server/src/openapi.js +41 -3
- package/docs/reference/http-api.md +84 -2
- package/docs/reference/reports.md +371 -7
- package/docs/reference/schema.md +32 -0
- package/docs/rich-evidence.md +31 -0
- package/docs/server.md +4 -1
- package/docs/ui.md +8 -1
- package/llms-full.txt +127 -4
- package/package.json +1 -1
- 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/report-run.schema.json +35 -0
- package/packages/schema/schemas/report-runs.schema.json +221 -0
- package/packages/schema/schemas/test-catalog.schema.json +7 -0
- package/packages/schema/schemas/test-history.schema.json +14 -0
- package/packages/server/openapi.json +2473 -1035
- package/packages/visualizer/src/evidence/check-detail.tsx +6 -1
- package/packages/visualizer/src/evidence/evidence-context.tsx +9 -2
- package/packages/visualizer/src/evidence/load-state.tsx +65 -0
- package/packages/visualizer/src/evidence/overview.tsx +4 -6
- package/packages/visualizer/src/evidence/recording-page.tsx +17 -7
- package/packages/visualizer/src/evidence/spec-header.tsx +8 -6
- package/packages/visualizer/src/evidence/spec-page.tsx +98 -15
- package/packages/visualizer/src/explorer/ArtifactsView.tsx +162 -0
- package/packages/visualizer/src/explorer/Explorer.tsx +28 -3
- package/packages/visualizer/src/explorer/RunsView.tsx +43 -19
- package/packages/visualizer/src/explorer/catalog.tsx +97 -12
- package/packages/visualizer/src/explorer/filters.tsx +279 -0
- package/packages/visualizer/src/explorer/search.ts +81 -6
- package/packages/visualizer/src/explorer/views.ts +75 -0
- package/packages/visualizer/src/find/Finder.tsx +45 -7
- package/packages/visualizer/src/spec-kind.test.ts +14 -1
- package/packages/visualizer/src/spec-kind.ts +28 -2
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
* always the report's winner (`combineEvidence`), and history only describes how it got there.
|
|
11
11
|
* - `testCatalog` turns the report's winners (plus a history, when there is one) into a `TestCatalog`: a summary with
|
|
12
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.
|
|
13
|
+
* - `testHistory`, `runList` and `runDetail` answer for one test, every run, and one run. `runList` and `artifactList`
|
|
14
|
+
* narrow by tag, label, media type, environment, branch, outcome and time (see `artifact-query.ts`); `artifactList` finds
|
|
15
|
+
* the recorded results that carry evidence across the whole history, not only the latest winners.
|
|
14
16
|
* - `catalogMarkdown`, `historyMarkdown`, `runsMarkdown` and `runMarkdown` say the same in Markdown, for an agent or a
|
|
15
17
|
* terminal.
|
|
16
18
|
*
|
|
@@ -21,6 +23,7 @@
|
|
|
21
23
|
* @see docs/server.md#reading-the-report-as-an-agent
|
|
22
24
|
*/
|
|
23
25
|
import { displayTag, normalizeTag, normalizeTags } from './artifact-tags.js';
|
|
26
|
+
import { facetsOf, forRuns, labelList, matchesFilter, outcomeOfCounts, splitList, usedFilters } from './artifact-query.js';
|
|
24
27
|
import { videoCounts } from './evidence-detail.js';
|
|
25
28
|
import { checkSlots } from './evidence-view.js';
|
|
26
29
|
import { combineEvidence, emptyCounts, slotKey, specPath as normalSpecPath } from './layer-merge.js';
|
|
@@ -101,6 +104,7 @@ export class TestHistory {
|
|
|
101
104
|
#seen = new Set();
|
|
102
105
|
#rev = 0;
|
|
103
106
|
#cells = null;
|
|
107
|
+
#evidence = null;
|
|
104
108
|
/** Changes each time a layer is added. */
|
|
105
109
|
get rev() {
|
|
106
110
|
return this.#rev;
|
|
@@ -127,7 +131,7 @@ export class TestHistory {
|
|
|
127
131
|
const key = runKey(layer);
|
|
128
132
|
let run = this.#runs.get(key);
|
|
129
133
|
if (!run) {
|
|
130
|
-
run = { key, runUrl: layer.runUrl, branch: layer.branch, sha: layer.sha, start: layer.recordedAtMs, end: layer.recordedAtMs, firstAt: layer.recordedAtMs, first: layer.id, producers: new Set(), environments: new Set(), layers: 0, runId: layer.run?.id, title: undefined, titledAt: 0, titledBy: '', freshness: undefined, videos: [] };
|
|
134
|
+
run = { key, runUrl: layer.runUrl, branch: layer.branch, sha: layer.sha, start: layer.recordedAtMs, end: layer.recordedAtMs, firstAt: layer.recordedAtMs, first: layer.id, producers: new Set(), environments: new Set(), layers: 0, runId: layer.run?.id, title: undefined, titledAt: 0, titledBy: '', freshness: undefined, videos: [], evidence: { tags: new Set(), artifactTags: new Set(), roles: new Set(), labels: new Set() } };
|
|
131
135
|
this.#runs.set(key, run);
|
|
132
136
|
}
|
|
133
137
|
// A run is told by its first layer (by time, then id), whatever order its layers arrive in.
|
|
@@ -156,6 +160,8 @@ export class TestHistory {
|
|
|
156
160
|
run.layers += 1;
|
|
157
161
|
if (layer.evidence?.videos)
|
|
158
162
|
run.videos.push(...layer.evidence.videos);
|
|
163
|
+
if (layer.evidence)
|
|
164
|
+
takeEvidence(run.evidence, layer.evidence);
|
|
159
165
|
const origin = originOf(layer, backend);
|
|
160
166
|
for (const row of rows) {
|
|
161
167
|
// "Still running" is progress, not history: a test running now shows it as its current outcome.
|
|
@@ -248,13 +254,75 @@ export class TestHistory {
|
|
|
248
254
|
results.sort((a, b) => FAILURE_RANK[b.status] - FAILURE_RANK[a.status] || compareText(a.specPath ?? '', b.specPath ?? '') || compareText(a.title, b.title) || compareText(a.environment ?? '', b.environment ?? '') || compareText(a.producer, b.producer) || compareText(a.key, b.key));
|
|
249
255
|
return { run: runSummary(run, cells), results };
|
|
250
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Every recorded result that carries an attachment, newest first, with the values a query looks at. Built once per
|
|
259
|
+
* layer added. The domain is left to the caller (`artifactList`), which may know more specs than the layers recorded.
|
|
260
|
+
*/
|
|
261
|
+
evidenceResults() {
|
|
262
|
+
if (this.#evidence?.rev === this.#rev)
|
|
263
|
+
return this.#evidence.items;
|
|
264
|
+
const items = [];
|
|
265
|
+
for (const [slot, list] of this.#bySlot) {
|
|
266
|
+
const i = this.#idents.get(slot);
|
|
267
|
+
for (const held of list) {
|
|
268
|
+
const e = held.e;
|
|
269
|
+
if (!e || e.attachments < 1)
|
|
270
|
+
continue;
|
|
271
|
+
const playable = (videoCounts(e.videos)?.recordings ?? 0) > 0;
|
|
272
|
+
const types = typesOf(e.roles, playable);
|
|
273
|
+
const artifactTags = [...(e.artifactTags ?? [])];
|
|
274
|
+
const o = held.o;
|
|
275
|
+
const result = {
|
|
276
|
+
key: i.slot, id: i.id, title: i.title, specPath: i.specPath, domain: null, at: o.at, status: held.s, environment: o.environment, producer: o.producer, kind: held.k,
|
|
277
|
+
parameters: o.parameters, branch: o.branch, sha: o.sha, run: o.run, runUrl: o.runUrl, layer: o.layer, backend: o.backend, attachments: e.attachments,
|
|
278
|
+
artifactTags, tags: [...e.tags], types, labels: e.labels, ...(e.videos ? { videos: e.videos } : {}),
|
|
279
|
+
};
|
|
280
|
+
const media = [
|
|
281
|
+
...types.filter(type => type !== 'video').map(type => ({ type, tags: artifactTags })),
|
|
282
|
+
...(e.videos ?? []).filter(video => video.available).map(video => ({ type: 'video', tags: video.tags ?? [] })),
|
|
283
|
+
];
|
|
284
|
+
const labels = labelList(e.labels);
|
|
285
|
+
items.push({
|
|
286
|
+
result,
|
|
287
|
+
fields: {
|
|
288
|
+
text: [i.title, i.id, i.specPath ?? '', o.branch ?? '', o.producer, o.environment ?? '', ...artifactTags, ...e.tags, ...labels].join('\n').toLowerCase(),
|
|
289
|
+
artifactTags, tags: [...new Set([...e.tags, ...artifactTags])], types, media, labels,
|
|
290
|
+
environments: o.environment ? [o.environment] : [], producers: [o.producer], branches: o.branch ? [o.branch] : [], shas: o.sha ? [o.sha.toLowerCase()] : [],
|
|
291
|
+
outcomes: [held.s], at: o.at,
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
items.sort((a, b) => b.result.at - a.result.at || compareText(a.result.layer, b.result.layer) || compareText(a.result.key, b.result.key) || compareText(a.result.kind, b.result.kind) || compareText(a.result.producer, b.result.producer));
|
|
297
|
+
this.#evidence = { rev: this.#rev, items };
|
|
298
|
+
return items;
|
|
299
|
+
}
|
|
251
300
|
/** The keys of the tests one run recorded. */
|
|
252
301
|
testsIn(key) {
|
|
253
302
|
return new Set((this.#runCells().get(key) ?? []).map(cell => cell.i.slot));
|
|
254
303
|
}
|
|
255
304
|
}
|
|
305
|
+
function takeEvidence(into, evidence) {
|
|
306
|
+
for (const tag of evidence.tags)
|
|
307
|
+
into.tags.add(tag);
|
|
308
|
+
for (const tag of evidence.artifactTags ?? [])
|
|
309
|
+
into.artifactTags.add(tag);
|
|
310
|
+
for (const role of evidence.roles)
|
|
311
|
+
into.roles.add(role);
|
|
312
|
+
for (const label of labelList(evidence.labels))
|
|
313
|
+
into.labels.add(label);
|
|
314
|
+
}
|
|
315
|
+
/** The media types of an evidence summary: its roles, with `video` only when a recording can be played. */
|
|
316
|
+
function typesOf(roles, playable) {
|
|
317
|
+
const types = new Set(roles);
|
|
318
|
+
types.delete('video');
|
|
319
|
+
if (playable)
|
|
320
|
+
types.add('video');
|
|
321
|
+
return [...types].sort();
|
|
322
|
+
}
|
|
256
323
|
function runSummary(run, cells) {
|
|
257
324
|
const counts = emptyCounts();
|
|
325
|
+
const carried = { tags: new Set(run.evidence.tags), artifactTags: new Set(run.evidence.artifactTags), roles: new Set(run.evidence.roles), labels: new Set(run.evidence.labels) };
|
|
258
326
|
const tests = new Set();
|
|
259
327
|
let total = 0, measured = false;
|
|
260
328
|
const failed = [];
|
|
@@ -262,6 +330,8 @@ function runSummary(run, cells) {
|
|
|
262
330
|
for (const cell of cells) {
|
|
263
331
|
if (cell.r.e?.videos)
|
|
264
332
|
videos.push(...cell.r.e.videos);
|
|
333
|
+
if (cell.r.e)
|
|
334
|
+
takeEvidence(carried, cell.r.e);
|
|
265
335
|
counts[cell.r.s] += 1;
|
|
266
336
|
tests.add(cell.i.slot);
|
|
267
337
|
if (cell.r.d !== null) {
|
|
@@ -281,6 +351,10 @@ function runSummary(run, cells) {
|
|
|
281
351
|
producers: [...run.producers].sort(), environments: [...run.environments].sort(),
|
|
282
352
|
layers: run.layers, tests: tests.size, counts, totalDurationMs: measured ? total : null, failing,
|
|
283
353
|
...(video ? { videos: video } : {}),
|
|
354
|
+
...(carried.artifactTags.size ? { artifactTags: [...carried.artifactTags].sort() } : {}),
|
|
355
|
+
...(carried.roles.size ? { types: typesOf(carried.roles, (video?.recordings ?? 0) > 0) } : {}),
|
|
356
|
+
...(carried.labels.size ? { labels: [...carried.labels].sort() } : {}),
|
|
357
|
+
...(carried.tags.size ? { tags: [...carried.tags].sort() } : {}),
|
|
284
358
|
};
|
|
285
359
|
}
|
|
286
360
|
function compareText(a, b) {
|
|
@@ -592,8 +666,59 @@ export function hasVideo(run) {
|
|
|
592
666
|
export function runList(history, version, limit = 100, query = {}) {
|
|
593
667
|
const all = history.runs();
|
|
594
668
|
const withVideo = all.filter(hasVideo).length;
|
|
595
|
-
const
|
|
596
|
-
|
|
669
|
+
const filter = forRuns(query);
|
|
670
|
+
const fields = all.map(fieldsOfRun);
|
|
671
|
+
const runs = all.filter((_, at) => matchesFilter(fields[at], filter));
|
|
672
|
+
return {
|
|
673
|
+
schemaVersion: TEST_CATALOG_VERSION, version, total: runs.length, runs: runs.slice(0, Math.max(0, limit)), withVideo,
|
|
674
|
+
filters: usedFilters(filter), facets: facetsOf(fields, filter),
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
/** What a query looks at in a run: see {@link ArtifactFilter}. A run's outcome is `failed` when any result failed. */
|
|
678
|
+
export function fieldsOfRun(run) {
|
|
679
|
+
const artifactTags = run.artifactTags ?? [];
|
|
680
|
+
// A run summary of an older server has no `types`, but it says whether it has a playable video.
|
|
681
|
+
const types = run.types ?? (hasVideo(run) ? ['video'] : []);
|
|
682
|
+
const labels = run.labels ?? [];
|
|
683
|
+
return {
|
|
684
|
+
text: [run.title ?? '', run.key, run.branch ?? '', run.sha ?? '', ...run.producers, ...run.environments, ...artifactTags, ...(run.tags ?? []), ...labels].join('\n').toLowerCase(),
|
|
685
|
+
artifactTags, tags: [...new Set([...(run.tags ?? []), ...artifactTags])], types, media: types.map(type => ({ type, tags: artifactTags })), labels,
|
|
686
|
+
environments: run.environments, producers: run.producers, branches: run.branch ? [run.branch] : [], shas: run.sha ? [run.sha.toLowerCase()] : [],
|
|
687
|
+
outcomes: [outcomeOfCounts(run.counts)], at: run.endedAtMs,
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* The recorded results that carry evidence and match a query, newest first, across the whole history (`limit` default
|
|
692
|
+
* 100). `total` and the facet counts apply to every match before `offset` and `limit`. `domainOf` tells the domain of a
|
|
693
|
+
* spec path when the caller knows more than the layers recorded (a server with a spec set); otherwise it is the
|
|
694
|
+
* recorded spec's domain, else the folder the path implies.
|
|
695
|
+
*
|
|
696
|
+
* @example
|
|
697
|
+
* ```ts
|
|
698
|
+
* const list = artifactList(history, 'v1', { artifactTag: ['demo'], type: ['video'], environment: ['ios'] });
|
|
699
|
+
* list.results.map(r => [r.title, r.run, r.sha, r.status]);
|
|
700
|
+
* ```
|
|
701
|
+
*/
|
|
702
|
+
export function artifactList(history, version, query = {}, page = {}) {
|
|
703
|
+
const domains = new Map();
|
|
704
|
+
const domainOf = (path) => {
|
|
705
|
+
if (path === null)
|
|
706
|
+
return null;
|
|
707
|
+
if (!domains.has(path))
|
|
708
|
+
domains.set(path, (page.domainOf?.(path) ?? catalogSpec(path, known => history.specs.get(known))?.domain) || null);
|
|
709
|
+
return domains.get(path);
|
|
710
|
+
};
|
|
711
|
+
const items = history.evidenceResults().map(({ result, fields }) => {
|
|
712
|
+
const domain = domainOf(result.specPath);
|
|
713
|
+
return { result: { ...result, domain }, fields: { ...fields, domains: domain ? [domain] : [], specs: result.specPath ? [normalSpecPath(result.specPath)] : [] } };
|
|
714
|
+
});
|
|
715
|
+
const matched = items.filter(item => matchesFilter(item.fields, query));
|
|
716
|
+
const limit = Math.max(0, page.limit ?? 100);
|
|
717
|
+
const offset = Math.max(0, page.offset ?? 0);
|
|
718
|
+
return {
|
|
719
|
+
schemaVersion: TEST_CATALOG_VERSION, version, total: matched.length, offset, limit,
|
|
720
|
+
results: matched.slice(offset, offset + limit).map(item => item.result), filters: usedFilters(query), facets: facetsOf(items.map(item => item.fields), query),
|
|
721
|
+
};
|
|
597
722
|
}
|
|
598
723
|
/** One run with every result it recorded, or null when no run has that key. */
|
|
599
724
|
export function runDetail(history, version, key) {
|
|
@@ -602,7 +727,7 @@ export function runDetail(history, version, key) {
|
|
|
602
727
|
}
|
|
603
728
|
/** 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`. */
|
|
604
729
|
export function parseTestQuery(params) {
|
|
605
|
-
const many = (name) => params.getAll(name).flatMap(
|
|
730
|
+
const many = (name) => params.getAll(name).flatMap(splitList);
|
|
606
731
|
const number = (name) => { const value = params.get(name); return value !== null && /^\d+$/.test(value) ? Number(value) : undefined; };
|
|
607
732
|
const sort = params.get('sort');
|
|
608
733
|
const query = {};
|
|
@@ -726,6 +851,16 @@ export function runsMarkdown(list) {
|
|
|
726
851
|
...list.runs.map(r => `| ${iso(r.endedAtMs)} | ${cell(r.branch ?? '—')} | ${r.sha?.slice(0, 10) ?? '—'}${freshnessNote(r.freshness)} | ${r.environments.join(', ') || '—'} | ${r.tests} | ${r.counts.passed} | ${r.counts.failed} | ${r.counts['not-run']} | ${formatMs(r.spanMs)} | ${videosText(r.videos)} | ${cell(r.title ? `${r.title} (${r.key})` : r.key)} |`),
|
|
727
852
|
].join('\n')}\n`;
|
|
728
853
|
}
|
|
854
|
+
/** The artifact results as Markdown, for an agent or a terminal. */
|
|
855
|
+
export function artifactsMarkdown(list) {
|
|
856
|
+
return `${[
|
|
857
|
+
`# Artifacts (${list.results.length} of ${list.total})`,
|
|
858
|
+
'',
|
|
859
|
+
'| Recorded | Test | Status | Environment | Branch | Commit | Types | Tags | Videos | Run |',
|
|
860
|
+
'|---|---|---|---|---|---|---|---|---|---|',
|
|
861
|
+
...list.results.map(r => `| ${iso(r.at)} | ${cell(r.title)} | ${r.status} | ${r.environment ?? '—'} | ${cell(r.branch ?? '—')} | ${r.sha?.slice(0, 10) ?? '—'} | ${r.types.join(', ') || '—'} | ${r.artifactTags.map(displayTag).join(' ') || '—'} | ${videosText(videoCounts(r.videos))} | ${cell(r.runUrl ?? r.run)} |`),
|
|
862
|
+
].join('\n')}\n`;
|
|
863
|
+
}
|
|
729
864
|
/** One run as Markdown. */
|
|
730
865
|
export function runMarkdown(detail) {
|
|
731
866
|
const { run } = detail;
|
package/dist/schema/src/api.d.ts
CHANGED
|
@@ -86,6 +86,7 @@ export declare const VideoRefSchema: z.ZodObject<{
|
|
|
86
86
|
owner: z.ZodString;
|
|
87
87
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
88
88
|
step: z.ZodOptional<z.ZodString>;
|
|
89
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
89
90
|
recording: z.ZodOptional<z.ZodString>;
|
|
90
91
|
available: z.ZodBoolean;
|
|
91
92
|
}, z.core.$loose>;
|
|
@@ -111,6 +112,7 @@ export declare const EvidenceSummarySchema: z.ZodObject<{
|
|
|
111
112
|
owner: z.ZodString;
|
|
112
113
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
113
114
|
step: z.ZodOptional<z.ZodString>;
|
|
115
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
114
116
|
recording: z.ZodOptional<z.ZodString>;
|
|
115
117
|
available: z.ZodBoolean;
|
|
116
118
|
}, z.core.$loose>>>;
|
|
@@ -161,6 +163,7 @@ export declare const LayerHeaderSchema: z.ZodObject<{
|
|
|
161
163
|
owner: z.ZodString;
|
|
162
164
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
163
165
|
step: z.ZodOptional<z.ZodString>;
|
|
166
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
164
167
|
recording: z.ZodOptional<z.ZodString>;
|
|
165
168
|
available: z.ZodBoolean;
|
|
166
169
|
}, z.core.$loose>>>;
|
|
@@ -211,6 +214,7 @@ export declare const LayerRowSchema: z.ZodObject<{
|
|
|
211
214
|
owner: z.ZodString;
|
|
212
215
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
213
216
|
step: z.ZodOptional<z.ZodString>;
|
|
217
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
214
218
|
recording: z.ZodOptional<z.ZodString>;
|
|
215
219
|
available: z.ZodBoolean;
|
|
216
220
|
}, z.core.$loose>>>;
|
|
@@ -259,6 +263,7 @@ export declare const LayerRowsSchema: z.ZodObject<{
|
|
|
259
263
|
owner: z.ZodString;
|
|
260
264
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
261
265
|
step: z.ZodOptional<z.ZodString>;
|
|
266
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
262
267
|
recording: z.ZodOptional<z.ZodString>;
|
|
263
268
|
available: z.ZodBoolean;
|
|
264
269
|
}, z.core.$loose>>>;
|
|
@@ -309,6 +314,7 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
|
|
|
309
314
|
owner: z.ZodString;
|
|
310
315
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
311
316
|
step: z.ZodOptional<z.ZodString>;
|
|
317
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
312
318
|
recording: z.ZodOptional<z.ZodString>;
|
|
313
319
|
available: z.ZodBoolean;
|
|
314
320
|
}, z.core.$loose>>>;
|
|
@@ -364,6 +370,7 @@ export declare const LayerEvidenceSchema: z.ZodObject<{
|
|
|
364
370
|
owner: z.ZodString;
|
|
365
371
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
366
372
|
step: z.ZodOptional<z.ZodString>;
|
|
373
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
367
374
|
recording: z.ZodOptional<z.ZodString>;
|
|
368
375
|
available: z.ZodBoolean;
|
|
369
376
|
}, z.core.$loose>>>;
|
|
@@ -423,6 +430,7 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
|
|
|
423
430
|
owner: z.ZodString;
|
|
424
431
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
425
432
|
step: z.ZodOptional<z.ZodString>;
|
|
433
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
426
434
|
recording: z.ZodOptional<z.ZodString>;
|
|
427
435
|
available: z.ZodBoolean;
|
|
428
436
|
}, z.core.$loose>>>;
|
|
@@ -478,6 +486,7 @@ export declare const EffectiveEvidenceSchema: z.ZodObject<{
|
|
|
478
486
|
owner: z.ZodString;
|
|
479
487
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
480
488
|
step: z.ZodOptional<z.ZodString>;
|
|
489
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
481
490
|
recording: z.ZodOptional<z.ZodString>;
|
|
482
491
|
available: z.ZodBoolean;
|
|
483
492
|
}, z.core.$loose>>>;
|
|
@@ -558,6 +567,7 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
|
|
|
558
567
|
owner: z.ZodString;
|
|
559
568
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
560
569
|
step: z.ZodOptional<z.ZodString>;
|
|
570
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
561
571
|
recording: z.ZodOptional<z.ZodString>;
|
|
562
572
|
available: z.ZodBoolean;
|
|
563
573
|
}, z.core.$loose>>>;
|
|
@@ -613,6 +623,7 @@ export declare const EffectiveDeltaSchema: z.ZodObject<{
|
|
|
613
623
|
owner: z.ZodString;
|
|
614
624
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
615
625
|
step: z.ZodOptional<z.ZodString>;
|
|
626
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
616
627
|
recording: z.ZodOptional<z.ZodString>;
|
|
617
628
|
available: z.ZodBoolean;
|
|
618
629
|
}, z.core.$loose>>>;
|
|
@@ -696,6 +707,7 @@ export declare const EvidencePageSchema: z.ZodObject<{
|
|
|
696
707
|
owner: z.ZodString;
|
|
697
708
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
698
709
|
step: z.ZodOptional<z.ZodString>;
|
|
710
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
699
711
|
recording: z.ZodOptional<z.ZodString>;
|
|
700
712
|
available: z.ZodBoolean;
|
|
701
713
|
}, z.core.$loose>>>;
|
|
@@ -1096,6 +1108,7 @@ export declare const TestResultEntrySchema: z.ZodObject<{
|
|
|
1096
1108
|
owner: z.ZodString;
|
|
1097
1109
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
1098
1110
|
step: z.ZodOptional<z.ZodString>;
|
|
1111
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1099
1112
|
recording: z.ZodOptional<z.ZodString>;
|
|
1100
1113
|
available: z.ZodBoolean;
|
|
1101
1114
|
}, z.core.$loose>>>;
|
|
@@ -1156,6 +1169,7 @@ export declare const TestSummarySchema: z.ZodObject<{
|
|
|
1156
1169
|
owner: z.ZodString;
|
|
1157
1170
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
1158
1171
|
step: z.ZodOptional<z.ZodString>;
|
|
1172
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1159
1173
|
recording: z.ZodOptional<z.ZodString>;
|
|
1160
1174
|
available: z.ZodBoolean;
|
|
1161
1175
|
}, z.core.$loose>>>;
|
|
@@ -1406,6 +1420,7 @@ export declare const TestCatalogSchema: z.ZodObject<{
|
|
|
1406
1420
|
owner: z.ZodString;
|
|
1407
1421
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
1408
1422
|
step: z.ZodOptional<z.ZodString>;
|
|
1423
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1409
1424
|
recording: z.ZodOptional<z.ZodString>;
|
|
1410
1425
|
available: z.ZodBoolean;
|
|
1411
1426
|
}, z.core.$loose>>>;
|
|
@@ -1587,6 +1602,7 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
1587
1602
|
owner: z.ZodString;
|
|
1588
1603
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
1589
1604
|
step: z.ZodOptional<z.ZodString>;
|
|
1605
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1590
1606
|
recording: z.ZodOptional<z.ZodString>;
|
|
1591
1607
|
available: z.ZodBoolean;
|
|
1592
1608
|
}, z.core.$loose>>>;
|
|
@@ -1665,6 +1681,7 @@ export declare const TestHistorySchema: z.ZodObject<{
|
|
|
1665
1681
|
owner: z.ZodString;
|
|
1666
1682
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
1667
1683
|
step: z.ZodOptional<z.ZodString>;
|
|
1684
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1668
1685
|
recording: z.ZodOptional<z.ZodString>;
|
|
1669
1686
|
available: z.ZodBoolean;
|
|
1670
1687
|
}, z.core.$loose>>>;
|
|
@@ -1708,6 +1725,50 @@ export declare const ReportRunSchema: z.ZodObject<{
|
|
|
1708
1725
|
recordings: z.ZodNumber;
|
|
1709
1726
|
unavailable: z.ZodNumber;
|
|
1710
1727
|
}, z.core.$loose>>;
|
|
1728
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1729
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1730
|
+
types: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1731
|
+
labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1732
|
+
}, z.core.$loose>;
|
|
1733
|
+
/** A value of a filter dimension and how many records have it. */
|
|
1734
|
+
export declare const QueryFacetValueSchema: z.ZodObject<{
|
|
1735
|
+
value: z.ZodString;
|
|
1736
|
+
count: z.ZodNumber;
|
|
1737
|
+
}, z.core.$loose>;
|
|
1738
|
+
/** The facets of a runs or artifacts query: per dimension, its values with disjunctive counts (the list's count if that value were the only one chosen, every other dimension's filter applied). */
|
|
1739
|
+
export declare const QueryFacetsSchema: z.ZodObject<{
|
|
1740
|
+
artifactTags: z.ZodArray<z.ZodObject<{
|
|
1741
|
+
value: z.ZodString;
|
|
1742
|
+
count: z.ZodNumber;
|
|
1743
|
+
}, z.core.$loose>>;
|
|
1744
|
+
types: z.ZodArray<z.ZodObject<{
|
|
1745
|
+
value: z.ZodString;
|
|
1746
|
+
count: z.ZodNumber;
|
|
1747
|
+
}, z.core.$loose>>;
|
|
1748
|
+
labels: z.ZodArray<z.ZodObject<{
|
|
1749
|
+
value: z.ZodString;
|
|
1750
|
+
count: z.ZodNumber;
|
|
1751
|
+
}, z.core.$loose>>;
|
|
1752
|
+
environments: z.ZodArray<z.ZodObject<{
|
|
1753
|
+
value: z.ZodString;
|
|
1754
|
+
count: z.ZodNumber;
|
|
1755
|
+
}, z.core.$loose>>;
|
|
1756
|
+
producers: z.ZodArray<z.ZodObject<{
|
|
1757
|
+
value: z.ZodString;
|
|
1758
|
+
count: z.ZodNumber;
|
|
1759
|
+
}, z.core.$loose>>;
|
|
1760
|
+
branches: z.ZodArray<z.ZodObject<{
|
|
1761
|
+
value: z.ZodString;
|
|
1762
|
+
count: z.ZodNumber;
|
|
1763
|
+
}, z.core.$loose>>;
|
|
1764
|
+
outcomes: z.ZodArray<z.ZodObject<{
|
|
1765
|
+
value: z.ZodString;
|
|
1766
|
+
count: z.ZodNumber;
|
|
1767
|
+
}, z.core.$loose>>;
|
|
1768
|
+
domains: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1769
|
+
value: z.ZodString;
|
|
1770
|
+
count: z.ZodNumber;
|
|
1771
|
+
}, z.core.$loose>>>;
|
|
1711
1772
|
}, z.core.$loose>;
|
|
1712
1773
|
/** `GET /api/reports/runs`: runs, newest first. */
|
|
1713
1774
|
export declare const RunListSchema: z.ZodObject<{
|
|
@@ -1750,8 +1811,167 @@ export declare const RunListSchema: z.ZodObject<{
|
|
|
1750
1811
|
recordings: z.ZodNumber;
|
|
1751
1812
|
unavailable: z.ZodNumber;
|
|
1752
1813
|
}, z.core.$loose>>;
|
|
1814
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1815
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1816
|
+
types: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1817
|
+
labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1753
1818
|
}, z.core.$loose>>;
|
|
1754
1819
|
withVideo: z.ZodOptional<z.ZodNumber>;
|
|
1820
|
+
filters: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1821
|
+
facets: z.ZodOptional<z.ZodObject<{
|
|
1822
|
+
artifactTags: z.ZodArray<z.ZodObject<{
|
|
1823
|
+
value: z.ZodString;
|
|
1824
|
+
count: z.ZodNumber;
|
|
1825
|
+
}, z.core.$loose>>;
|
|
1826
|
+
types: z.ZodArray<z.ZodObject<{
|
|
1827
|
+
value: z.ZodString;
|
|
1828
|
+
count: z.ZodNumber;
|
|
1829
|
+
}, z.core.$loose>>;
|
|
1830
|
+
labels: z.ZodArray<z.ZodObject<{
|
|
1831
|
+
value: z.ZodString;
|
|
1832
|
+
count: z.ZodNumber;
|
|
1833
|
+
}, z.core.$loose>>;
|
|
1834
|
+
environments: z.ZodArray<z.ZodObject<{
|
|
1835
|
+
value: z.ZodString;
|
|
1836
|
+
count: z.ZodNumber;
|
|
1837
|
+
}, z.core.$loose>>;
|
|
1838
|
+
producers: z.ZodArray<z.ZodObject<{
|
|
1839
|
+
value: z.ZodString;
|
|
1840
|
+
count: z.ZodNumber;
|
|
1841
|
+
}, z.core.$loose>>;
|
|
1842
|
+
branches: z.ZodArray<z.ZodObject<{
|
|
1843
|
+
value: z.ZodString;
|
|
1844
|
+
count: z.ZodNumber;
|
|
1845
|
+
}, z.core.$loose>>;
|
|
1846
|
+
outcomes: z.ZodArray<z.ZodObject<{
|
|
1847
|
+
value: z.ZodString;
|
|
1848
|
+
count: z.ZodNumber;
|
|
1849
|
+
}, z.core.$loose>>;
|
|
1850
|
+
domains: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1851
|
+
value: z.ZodString;
|
|
1852
|
+
count: z.ZodNumber;
|
|
1853
|
+
}, z.core.$loose>>>;
|
|
1854
|
+
}, z.core.$loose>>;
|
|
1855
|
+
}, z.core.$loose>;
|
|
1856
|
+
/** One recorded result that carries evidence: where and when it was recorded and what it carries. */
|
|
1857
|
+
export declare const ArtifactResultSchema: z.ZodObject<{
|
|
1858
|
+
key: z.ZodString;
|
|
1859
|
+
id: z.ZodString;
|
|
1860
|
+
title: z.ZodString;
|
|
1861
|
+
specPath: z.ZodNullable<z.ZodString>;
|
|
1862
|
+
domain: z.ZodNullable<z.ZodString>;
|
|
1863
|
+
at: z.ZodNumber;
|
|
1864
|
+
status: z.ZodEnum<{
|
|
1865
|
+
passed: "passed";
|
|
1866
|
+
failed: "failed";
|
|
1867
|
+
running: "running";
|
|
1868
|
+
"not-run": "not-run";
|
|
1869
|
+
}>;
|
|
1870
|
+
environment: z.ZodNullable<z.ZodString>;
|
|
1871
|
+
producer: z.ZodString;
|
|
1872
|
+
kind: z.ZodString;
|
|
1873
|
+
parameters: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1874
|
+
branch: z.ZodNullable<z.ZodString>;
|
|
1875
|
+
sha: z.ZodNullable<z.ZodString>;
|
|
1876
|
+
run: z.ZodString;
|
|
1877
|
+
runUrl: z.ZodNullable<z.ZodString>;
|
|
1878
|
+
layer: z.ZodString;
|
|
1879
|
+
backend: z.ZodString;
|
|
1880
|
+
attachments: z.ZodNumber;
|
|
1881
|
+
artifactTags: z.ZodArray<z.ZodString>;
|
|
1882
|
+
tags: z.ZodArray<z.ZodString>;
|
|
1883
|
+
types: z.ZodArray<z.ZodString>;
|
|
1884
|
+
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1885
|
+
videos: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1886
|
+
name: z.ZodString;
|
|
1887
|
+
owner: z.ZodString;
|
|
1888
|
+
attempt: z.ZodOptional<z.ZodNumber>;
|
|
1889
|
+
step: z.ZodOptional<z.ZodString>;
|
|
1890
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1891
|
+
recording: z.ZodOptional<z.ZodString>;
|
|
1892
|
+
available: z.ZodBoolean;
|
|
1893
|
+
}, z.core.$loose>>>;
|
|
1894
|
+
}, z.core.$loose>;
|
|
1895
|
+
/** `GET /api/reports/artifacts`: recorded results that carry evidence, newest first, with the facets of the query. */
|
|
1896
|
+
export declare const ArtifactListSchema: z.ZodObject<{
|
|
1897
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
1898
|
+
version: z.ZodString;
|
|
1899
|
+
total: z.ZodNumber;
|
|
1900
|
+
offset: z.ZodNumber;
|
|
1901
|
+
limit: z.ZodNumber;
|
|
1902
|
+
results: z.ZodArray<z.ZodObject<{
|
|
1903
|
+
key: z.ZodString;
|
|
1904
|
+
id: z.ZodString;
|
|
1905
|
+
title: z.ZodString;
|
|
1906
|
+
specPath: z.ZodNullable<z.ZodString>;
|
|
1907
|
+
domain: z.ZodNullable<z.ZodString>;
|
|
1908
|
+
at: z.ZodNumber;
|
|
1909
|
+
status: z.ZodEnum<{
|
|
1910
|
+
passed: "passed";
|
|
1911
|
+
failed: "failed";
|
|
1912
|
+
running: "running";
|
|
1913
|
+
"not-run": "not-run";
|
|
1914
|
+
}>;
|
|
1915
|
+
environment: z.ZodNullable<z.ZodString>;
|
|
1916
|
+
producer: z.ZodString;
|
|
1917
|
+
kind: z.ZodString;
|
|
1918
|
+
parameters: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1919
|
+
branch: z.ZodNullable<z.ZodString>;
|
|
1920
|
+
sha: z.ZodNullable<z.ZodString>;
|
|
1921
|
+
run: z.ZodString;
|
|
1922
|
+
runUrl: z.ZodNullable<z.ZodString>;
|
|
1923
|
+
layer: z.ZodString;
|
|
1924
|
+
backend: z.ZodString;
|
|
1925
|
+
attachments: z.ZodNumber;
|
|
1926
|
+
artifactTags: z.ZodArray<z.ZodString>;
|
|
1927
|
+
tags: z.ZodArray<z.ZodString>;
|
|
1928
|
+
types: z.ZodArray<z.ZodString>;
|
|
1929
|
+
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1930
|
+
videos: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1931
|
+
name: z.ZodString;
|
|
1932
|
+
owner: z.ZodString;
|
|
1933
|
+
attempt: z.ZodOptional<z.ZodNumber>;
|
|
1934
|
+
step: z.ZodOptional<z.ZodString>;
|
|
1935
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1936
|
+
recording: z.ZodOptional<z.ZodString>;
|
|
1937
|
+
available: z.ZodBoolean;
|
|
1938
|
+
}, z.core.$loose>>>;
|
|
1939
|
+
}, z.core.$loose>>;
|
|
1940
|
+
filters: z.ZodArray<z.ZodString>;
|
|
1941
|
+
facets: z.ZodObject<{
|
|
1942
|
+
artifactTags: z.ZodArray<z.ZodObject<{
|
|
1943
|
+
value: z.ZodString;
|
|
1944
|
+
count: z.ZodNumber;
|
|
1945
|
+
}, z.core.$loose>>;
|
|
1946
|
+
types: z.ZodArray<z.ZodObject<{
|
|
1947
|
+
value: z.ZodString;
|
|
1948
|
+
count: z.ZodNumber;
|
|
1949
|
+
}, z.core.$loose>>;
|
|
1950
|
+
labels: z.ZodArray<z.ZodObject<{
|
|
1951
|
+
value: z.ZodString;
|
|
1952
|
+
count: z.ZodNumber;
|
|
1953
|
+
}, z.core.$loose>>;
|
|
1954
|
+
environments: z.ZodArray<z.ZodObject<{
|
|
1955
|
+
value: z.ZodString;
|
|
1956
|
+
count: z.ZodNumber;
|
|
1957
|
+
}, z.core.$loose>>;
|
|
1958
|
+
producers: z.ZodArray<z.ZodObject<{
|
|
1959
|
+
value: z.ZodString;
|
|
1960
|
+
count: z.ZodNumber;
|
|
1961
|
+
}, z.core.$loose>>;
|
|
1962
|
+
branches: z.ZodArray<z.ZodObject<{
|
|
1963
|
+
value: z.ZodString;
|
|
1964
|
+
count: z.ZodNumber;
|
|
1965
|
+
}, z.core.$loose>>;
|
|
1966
|
+
outcomes: z.ZodArray<z.ZodObject<{
|
|
1967
|
+
value: z.ZodString;
|
|
1968
|
+
count: z.ZodNumber;
|
|
1969
|
+
}, z.core.$loose>>;
|
|
1970
|
+
domains: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1971
|
+
value: z.ZodString;
|
|
1972
|
+
count: z.ZodNumber;
|
|
1973
|
+
}, z.core.$loose>>>;
|
|
1974
|
+
}, z.core.$loose>;
|
|
1755
1975
|
}, z.core.$loose>;
|
|
1756
1976
|
/** `GET /api/reports/runs/detail`: one run and its last result for every test, environment and producer it recorded. */
|
|
1757
1977
|
export declare const RunDetailSchema: z.ZodObject<{
|
|
@@ -1793,6 +2013,10 @@ export declare const RunDetailSchema: z.ZodObject<{
|
|
|
1793
2013
|
recordings: z.ZodNumber;
|
|
1794
2014
|
unavailable: z.ZodNumber;
|
|
1795
2015
|
}, z.core.$loose>>;
|
|
2016
|
+
artifactTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2017
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2018
|
+
types: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2019
|
+
labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1796
2020
|
}, z.core.$loose>;
|
|
1797
2021
|
results: z.ZodArray<z.ZodObject<{
|
|
1798
2022
|
key: z.ZodString;
|
|
@@ -1816,6 +2040,7 @@ export declare const RunDetailSchema: z.ZodObject<{
|
|
|
1816
2040
|
owner: z.ZodString;
|
|
1817
2041
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
1818
2042
|
step: z.ZodOptional<z.ZodString>;
|
|
2043
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1819
2044
|
recording: z.ZodOptional<z.ZodString>;
|
|
1820
2045
|
available: z.ZodBoolean;
|
|
1821
2046
|
}, z.core.$loose>>>;
|
package/dist/schema/src/api.js
CHANGED
|
@@ -68,6 +68,7 @@ export const VideoRefSchema = z.looseObject({
|
|
|
68
68
|
owner: z.string().describe('Who holds it: `layer`, `check`, `attempt` or `step`. An open vocabulary: treat an unknown owner as a check'),
|
|
69
69
|
attempt: z.number().int().nonnegative().optional().describe('The retry attempt that holds it, or that holds the step that does'),
|
|
70
70
|
step: z.string().optional().describe('The name of the step that holds it'),
|
|
71
|
+
tags: z.array(z.string()).optional().describe('The normalized tags of this attachment itself. Absent when it has none (and in documents of older servers)'),
|
|
71
72
|
recording: z.string().optional().describe('What identifies the bytes; references with the same value are one recording. Absent when it cannot be played'),
|
|
72
73
|
available: z.boolean().describe('False when the reference names no bytes (no bundle key, address or inline text)')
|
|
73
74
|
});
|
|
@@ -396,7 +397,19 @@ export const ReportRunSchema = z.looseObject({
|
|
|
396
397
|
layers: z.number().int().nonnegative(), tests: z.number().int().nonnegative(), counts: StatusCountsSchema,
|
|
397
398
|
totalDurationMs: z.number().nullable(),
|
|
398
399
|
failing: z.array(z.looseObject({ key: z.string(), title: z.string(), environment: z.string().nullable(), detail: z.string() })),
|
|
399
|
-
videos: VideoCountsSchema.optional().describe('Its videos, from its layers and the last result of each test. Absent when it has none or the report carries no video information')
|
|
400
|
+
videos: VideoCountsSchema.optional().describe('Its videos, from its layers and the last result of each test. Absent when it has none or the report carries no video information'),
|
|
401
|
+
artifactTags: z.array(z.string()).optional().describe('The normalized tags of the attachments of its results, sorted and distinct. Absent when none is tagged, and in reports of older servers'),
|
|
402
|
+
tags: z.array(z.string()).optional().describe('The tags of its checks and layers, which its attachments inherit (what `inherited=1` also matches). Absent when none'),
|
|
403
|
+
types: z.array(z.string()).optional().describe('The media types (roles) of its attachments, sorted and distinct; `video` only for a playable recording. Absent when it has no attachment'),
|
|
404
|
+
labels: z.array(z.string()).optional().describe('The `key=value` labels of its results and layers, sorted and distinct. Absent when it has none')
|
|
405
|
+
});
|
|
406
|
+
/** A value of a filter dimension and how many records have it. */
|
|
407
|
+
export const QueryFacetValueSchema = z.looseObject({ value: z.string(), count: z.number().int().nonnegative() });
|
|
408
|
+
/** The facets of a runs or artifacts query: per dimension, its values with disjunctive counts (the list's count if that value were the only one chosen, every other dimension's filter applied). */
|
|
409
|
+
export const QueryFacetsSchema = z.looseObject({
|
|
410
|
+
artifactTags: z.array(QueryFacetValueSchema), types: z.array(QueryFacetValueSchema), labels: z.array(QueryFacetValueSchema).describe('Values are `key=value`'),
|
|
411
|
+
environments: z.array(QueryFacetValueSchema), producers: z.array(QueryFacetValueSchema), branches: z.array(QueryFacetValueSchema), outcomes: z.array(QueryFacetValueSchema),
|
|
412
|
+
domains: z.array(QueryFacetValueSchema).optional().describe('Only for artifacts: runs have no domain')
|
|
400
413
|
});
|
|
401
414
|
/** `GET /api/reports/runs`: runs, newest first. */
|
|
402
415
|
export const RunListSchema = z.looseObject({
|
|
@@ -404,7 +417,33 @@ export const RunListSchema = z.looseObject({
|
|
|
404
417
|
version: z.string(),
|
|
405
418
|
total: z.number().int().nonnegative().describe('Runs that matched, before `limit`'),
|
|
406
419
|
runs: z.array(ReportRunSchema),
|
|
407
|
-
withVideo: z.number().int().nonnegative().optional().describe('How many of all runs (before `video` and `limit`) have a playable video recording')
|
|
420
|
+
withVideo: z.number().int().nonnegative().optional().describe('How many of all runs (before `video` and `limit`) have a playable video recording'),
|
|
421
|
+
filters: z.array(z.string()).optional().describe('The filter parameters this server applied (`artifactTag`, `type`, `outcome`…). A viewer that asked for one that is missing here knows the server ignored it. Absent on servers that predate filtering'),
|
|
422
|
+
facets: QueryFacetsSchema.optional().describe('The values each filter dimension offers, counted over every run. Absent on servers that predate filtering')
|
|
423
|
+
});
|
|
424
|
+
/** One recorded result that carries evidence: where and when it was recorded and what it carries. */
|
|
425
|
+
export const ArtifactResultSchema = z.looseObject({
|
|
426
|
+
key: z.string().describe('The test\'s key, as in `/api/reports/tests`'), id: z.string(), title: z.string(), specPath: z.string().nullable(), domain: z.string().nullable(),
|
|
427
|
+
at: z.number().describe('When it was recorded, epoch milliseconds'), status: EvidenceStatusSchema,
|
|
428
|
+
environment: z.string().nullable(), producer: z.string(), kind: z.string(), parameters: z.record(z.string(), z.string()),
|
|
429
|
+
branch: z.string().nullable(), sha: z.string().nullable(), run: z.string().describe('The run\'s key, as in `/api/reports/runs`'), runUrl: z.string().nullable(),
|
|
430
|
+
layer: z.string().describe('The id of the layer that recorded it. Pass it as the `layer` of the explorer to see exactly this result'), backend: z.string(),
|
|
431
|
+
attachments: z.number().int().nonnegative(),
|
|
432
|
+
artifactTags: z.array(z.string()).describe('Normalized tags of its attachments'),
|
|
433
|
+
tags: z.array(z.string()).describe('Tags of its check and run, which its attachments inherit'),
|
|
434
|
+
types: z.array(z.string()).describe('Media types (roles) of its attachments; `video` only for a playable recording'),
|
|
435
|
+
labels: z.record(z.string(), z.string()),
|
|
436
|
+
videos: z.array(VideoRefSchema).optional()
|
|
437
|
+
});
|
|
438
|
+
/** `GET /api/reports/artifacts`: recorded results that carry evidence, newest first, with the facets of the query. */
|
|
439
|
+
export const ArtifactListSchema = z.looseObject({
|
|
440
|
+
schemaVersion: z.literal(1),
|
|
441
|
+
version: z.string(),
|
|
442
|
+
total: z.number().int().nonnegative().describe('Results that matched, before `offset` and `limit`'),
|
|
443
|
+
offset: z.number().int().nonnegative(), limit: z.number().int().nonnegative(),
|
|
444
|
+
results: z.array(ArtifactResultSchema),
|
|
445
|
+
filters: z.array(z.string()).describe('The filters of the query that were applied'),
|
|
446
|
+
facets: QueryFacetsSchema
|
|
408
447
|
});
|
|
409
448
|
/** `GET /api/reports/runs/detail`: one run and its last result for every test, environment and producer it recorded. */
|
|
410
449
|
export const RunDetailSchema = z.looseObject({
|