@vitest-agent/reporter 1.0.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/LICENSE +21 -0
- package/LiveInkRenderer.js +119 -0
- package/README.md +61 -0
- package/defaultReporter.js +208 -0
- package/index.d.ts +1010 -0
- package/index.js +18 -0
- package/package.json +72 -0
- package/tsdoc-metadata.json +11 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 C. Spencer Beggs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { SPINNER_FRAME_MS, StreamApp, reduceRenderState, spinnerFrameForTime } from "@vitest-agent/ui";
|
|
2
|
+
import { initialRenderState } from "@vitest-agent/sdk";
|
|
3
|
+
import { Box, render, renderToString } from "ink";
|
|
4
|
+
import { createElement } from "react";
|
|
5
|
+
|
|
6
|
+
//#region src/LiveInkRenderer.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Create a {@link LiveInkRenderer} that drives a live Ink mount for
|
|
9
|
+
* `consoleMode: "stream"`. Call `event(e)` for each `RunEvent` published
|
|
10
|
+
* by the plugin; the renderer mounts on `RunStarted`, rerenders on each
|
|
11
|
+
* subsequent event, and commits the final frame on `RunFinished` /
|
|
12
|
+
* `RunTimedOut`.
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
const createLiveInk = (options = {}) => {
|
|
17
|
+
let state = initialRenderState;
|
|
18
|
+
let instance = null;
|
|
19
|
+
let clock = null;
|
|
20
|
+
let firstRunStarted = false;
|
|
21
|
+
const targetStream = options.stream ?? process.stdout;
|
|
22
|
+
const frameWidth = () => {
|
|
23
|
+
const cols = targetStream.columns;
|
|
24
|
+
return typeof cols === "number" && cols > 1 ? cols - 1 : void 0;
|
|
25
|
+
};
|
|
26
|
+
const frameElement = () => {
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
return createElement(Box, {
|
|
29
|
+
flexDirection: "column",
|
|
30
|
+
width: frameWidth()
|
|
31
|
+
}, createElement(StreamApp, {
|
|
32
|
+
state,
|
|
33
|
+
frameIndex: spinnerFrameForTime(now),
|
|
34
|
+
nowMs: now
|
|
35
|
+
}));
|
|
36
|
+
};
|
|
37
|
+
const mount = () => {
|
|
38
|
+
if (instance !== null) return;
|
|
39
|
+
instance = render(frameElement(), { stdout: targetStream });
|
|
40
|
+
};
|
|
41
|
+
const stopClock = () => {
|
|
42
|
+
if (clock === null) return;
|
|
43
|
+
clearInterval(clock);
|
|
44
|
+
clock = null;
|
|
45
|
+
};
|
|
46
|
+
const startClock = () => {
|
|
47
|
+
if (clock !== null) return;
|
|
48
|
+
clock = setInterval(() => {
|
|
49
|
+
if (instance === null) return;
|
|
50
|
+
try {
|
|
51
|
+
instance.rerender(frameElement());
|
|
52
|
+
} catch {
|
|
53
|
+
instance = null;
|
|
54
|
+
stopClock();
|
|
55
|
+
}
|
|
56
|
+
}, SPINNER_FRAME_MS);
|
|
57
|
+
clock.unref?.();
|
|
58
|
+
};
|
|
59
|
+
const tearDown = () => {
|
|
60
|
+
stopClock();
|
|
61
|
+
if (instance === null) return;
|
|
62
|
+
instance.unmount();
|
|
63
|
+
instance = null;
|
|
64
|
+
firstRunStarted = false;
|
|
65
|
+
};
|
|
66
|
+
return {
|
|
67
|
+
event(event) {
|
|
68
|
+
const previousPhase = state.phase;
|
|
69
|
+
state = reduceRenderState(state, event);
|
|
70
|
+
if (event._tag === "RunStarted" || previousPhase === "idle" && state.phase !== "idle") {
|
|
71
|
+
if (firstRunStarted) {
|
|
72
|
+
if (instance !== null) try {
|
|
73
|
+
instance.clear();
|
|
74
|
+
} catch {}
|
|
75
|
+
} else try {
|
|
76
|
+
mount();
|
|
77
|
+
} catch (err) {
|
|
78
|
+
process.stderr.write(`@vitest-agent/reporter: live ink renderer failed; falling back silently (${err.message})\n`);
|
|
79
|
+
instance = null;
|
|
80
|
+
}
|
|
81
|
+
firstRunStarted = true;
|
|
82
|
+
startClock();
|
|
83
|
+
} else if (instance !== null) try {
|
|
84
|
+
instance.rerender(frameElement());
|
|
85
|
+
} catch (err) {
|
|
86
|
+
process.stderr.write(`@vitest-agent/reporter: live ink renderer failed; falling back silently (${err.message})\n`);
|
|
87
|
+
instance = null;
|
|
88
|
+
stopClock();
|
|
89
|
+
}
|
|
90
|
+
if (event._tag === "RunFinished" || event._tag === "RunTimedOut") {
|
|
91
|
+
stopClock();
|
|
92
|
+
if (instance !== null) {
|
|
93
|
+
try {
|
|
94
|
+
instance.unmount();
|
|
95
|
+
} catch {}
|
|
96
|
+
instance = null;
|
|
97
|
+
} else {
|
|
98
|
+
const now = Date.now();
|
|
99
|
+
const finalFrameText = renderToString(createElement(StreamApp, {
|
|
100
|
+
state,
|
|
101
|
+
frameIndex: spinnerFrameForTime(now),
|
|
102
|
+
nowMs: now
|
|
103
|
+
}));
|
|
104
|
+
targetStream.write(`${finalFrameText}\n`);
|
|
105
|
+
}
|
|
106
|
+
firstRunStarted = false;
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
unmount() {
|
|
110
|
+
tearDown();
|
|
111
|
+
},
|
|
112
|
+
snapshot() {
|
|
113
|
+
return state;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
//#endregion
|
|
119
|
+
export { createLiveInk };
|
package/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# @vitest-agent/reporter
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@vitest-agent/reporter)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
|
|
7
|
+
> **Part of the [vitest-agent](https://vitest-agent.dev) ecosystem.** Most users want **[@vitest-agent/plugin](https://www.npmjs.com/package/@vitest-agent/plugin)**, which pulls this package in automatically. Install `@vitest-agent/reporter` directly only if you are writing a custom reporter.
|
|
8
|
+
|
|
9
|
+
The default reporter package and the reference for custom-reporter authors. Ships `DefaultVitestAgentReporter`, owns the live React Ink mount lifecycle, and re-exports the reporter contract types and dispatch helpers — everything a custom factory needs in one import.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **`DefaultVitestAgentReporter`** — the production default `VitestAgentReporterFactory` the plugin wires automatically; classifies runs into one of 12 shape × outcome cells, owns the Ink live-mount lifecycle, and emits a GitHub Actions Step Summary in CI
|
|
14
|
+
- **Dispatch helpers** — `buildDispatchInputs`, `resolveCellOptions`, `renderAgentStringForReport`, `renderHumanStringForReport`
|
|
15
|
+
- **Contract re-exports** — `VitestAgentReporterFactory`, `ReporterKit`, `ReporterRenderInput`, `RenderedOutput`, `VitestAgentReporter`, `ResolvedReporterConfig` all re-exported from `@vitest-agent/sdk` so you only need one import
|
|
16
|
+
- **Worked example** — `DefaultVitestAgentReporter` source in this package is the canonical reference for the `VitestAgentReporterFactory` contract
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install --save-dev @vitest-agent/reporter
|
|
22
|
+
# or
|
|
23
|
+
pnpm add -D @vitest-agent/reporter
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`@vitest-agent/reporter` arrives automatically as a dependency of `@vitest-agent/plugin`. Install it directly only when authoring a custom reporter.
|
|
27
|
+
|
|
28
|
+
## Quick start
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import type {
|
|
32
|
+
ReporterKit,
|
|
33
|
+
ReporterRenderInput,
|
|
34
|
+
RenderedOutput,
|
|
35
|
+
VitestAgentReporter,
|
|
36
|
+
VitestAgentReporterFactory,
|
|
37
|
+
} from "@vitest-agent/reporter";
|
|
38
|
+
|
|
39
|
+
const myReporter: VitestAgentReporterFactory = (kit: ReporterKit): VitestAgentReporter => ({
|
|
40
|
+
render(input: ReporterRenderInput): ReadonlyArray<RenderedOutput> {
|
|
41
|
+
const passed = input.reports.reduce((n, r) => n + r.summary.passed, 0);
|
|
42
|
+
return [{ target: "stdout", content: `${passed} passed\n` }];
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Pass the factory to the plugin:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { AgentPlugin } from "@vitest-agent/plugin";
|
|
51
|
+
|
|
52
|
+
AgentPlugin({ reporter: myReporter });
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Documentation
|
|
56
|
+
|
|
57
|
+
Custom-reporter guide at [vitest-agent.dev/reporter](https://vitest-agent.dev/reporter).
|
|
58
|
+
|
|
59
|
+
## License
|
|
60
|
+
|
|
61
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { createLiveInk } from "./LiveInkRenderer.js";
|
|
2
|
+
import { classifyOutcome, classifyRunShape, dispatch, dispatcherTable, reduceRenderStateAll, synthesizeFromAgentReport } from "@vitest-agent/ui";
|
|
3
|
+
import { Effect, PubSub, Queue } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/defaultReporter.ts
|
|
6
|
+
const summarizeProject = (report) => {
|
|
7
|
+
const collapsedTagCounts = report.tagCounts !== void 0 ? collapseTagCounts(report.tagCounts) : void 0;
|
|
8
|
+
const tagCountsHasEntries = collapsedTagCounts !== void 0 && Object.keys(collapsedTagCounts).length > 0;
|
|
9
|
+
const belowTargetCount = report.coverage?.belowTargetFiles?.length;
|
|
10
|
+
const violationsCount = report.coverage !== void 0 && report.coverage.lowCoverage.length > 0 ? report.coverage.lowCoverage.length : void 0;
|
|
11
|
+
return {
|
|
12
|
+
name: report.project ?? "default",
|
|
13
|
+
passCount: report.summary.passed,
|
|
14
|
+
failCount: report.summary.failed,
|
|
15
|
+
skipCount: report.summary.skipped,
|
|
16
|
+
durationMs: report.summary.duration,
|
|
17
|
+
...tagCountsHasEntries && collapsedTagCounts !== void 0 ? { tagCounts: collapsedTagCounts } : {},
|
|
18
|
+
...belowTargetCount !== void 0 ? { belowTarget: belowTargetCount } : {},
|
|
19
|
+
...violationsCount !== void 0 ? { violations: violationsCount } : {}
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
const collapseTagCounts = (entries) => {
|
|
23
|
+
const out = {};
|
|
24
|
+
if (entries === void 0) return out;
|
|
25
|
+
for (const [tag, entry] of Object.entries(entries)) {
|
|
26
|
+
const total = (entry.passed ?? 0) + (entry.failed ?? 0) + (entry.skipped ?? 0);
|
|
27
|
+
if (total > 0) out[tag] = total;
|
|
28
|
+
}
|
|
29
|
+
return out;
|
|
30
|
+
};
|
|
31
|
+
const collectBelowTarget = (reports) => {
|
|
32
|
+
const out = [];
|
|
33
|
+
for (const r of reports) {
|
|
34
|
+
const list = r.coverage?.belowTarget;
|
|
35
|
+
if (list !== void 0) out.push(...list);
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
};
|
|
39
|
+
const liftTrendSummary = (input) => {
|
|
40
|
+
const trend = input.trendSummary;
|
|
41
|
+
if (trend === void 0) return null;
|
|
42
|
+
return {
|
|
43
|
+
direction: trend.direction,
|
|
44
|
+
runCount: trend.runCount,
|
|
45
|
+
...trend.firstMetric !== void 0 ? { firstMetric: trend.firstMetric } : {}
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Build a `DispatchInputs` from a {@link ReporterRenderInput} and
|
|
50
|
+
* the reduced `RenderState`.
|
|
51
|
+
*
|
|
52
|
+
* Exported so a custom reporter built on the same dispatcher can reuse
|
|
53
|
+
* this assembly step without rebuilding it from scratch.
|
|
54
|
+
*
|
|
55
|
+
* @public
|
|
56
|
+
*/
|
|
57
|
+
const buildDispatchInputs = (state, input, overrides = {}) => {
|
|
58
|
+
const projects = input.reports.map((r) => summarizeProject(r));
|
|
59
|
+
return {
|
|
60
|
+
state,
|
|
61
|
+
shape: overrides.shape ?? classifyRunShape(state, projects),
|
|
62
|
+
outcome: overrides.outcome ?? classifyOutcome(state),
|
|
63
|
+
projects,
|
|
64
|
+
trend: liftTrendSummary(input),
|
|
65
|
+
belowTarget: collectBelowTarget(input.reports),
|
|
66
|
+
runCommand: overrides.runCommand ?? null
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Build `CellOptions` from a {@link ReporterKit}. Picks the kit's
|
|
71
|
+
* resolved `noColor` value and the pre-bound OSC-8 hyperlink helper.
|
|
72
|
+
*
|
|
73
|
+
* @public
|
|
74
|
+
*/
|
|
75
|
+
const resolveCellOptions = (kit) => ({
|
|
76
|
+
noColor: kit.config.noColor,
|
|
77
|
+
osc8: kit.stdOsc8
|
|
78
|
+
});
|
|
79
|
+
const shouldRenderForMode = (mode) => mode === "agent";
|
|
80
|
+
/**
|
|
81
|
+
* Convenience helper for one-shot consumers (e.g. a CLI command
|
|
82
|
+
* replaying a stored run). Synthesizes a minimal `ReporterRenderInput`
|
|
83
|
+
* from a single `AgentReport`, classifies the shape and outcome, and
|
|
84
|
+
* returns the dispatched agent-string for the matching cell. Equivalent
|
|
85
|
+
* to the pre-2.0 `renderRun(events, "agent")` shortcut.
|
|
86
|
+
*
|
|
87
|
+
* @public
|
|
88
|
+
*/
|
|
89
|
+
const renderAgentStringForReport = (report) => {
|
|
90
|
+
const state = reduceRenderStateAll(synthesizeFromAgentReport(report));
|
|
91
|
+
const projects = [summarizeProject(report)];
|
|
92
|
+
return dispatch({
|
|
93
|
+
state,
|
|
94
|
+
shape: classifyRunShape(state, projects),
|
|
95
|
+
outcome: classifyOutcome(state),
|
|
96
|
+
projects,
|
|
97
|
+
trend: null,
|
|
98
|
+
belowTarget: collectBelowTarget([report]),
|
|
99
|
+
runCommand: null
|
|
100
|
+
}, {
|
|
101
|
+
noColor: true,
|
|
102
|
+
osc8: (_url, label) => label
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Same as {@link renderAgentStringForReport} but returns the Ink-half
|
|
107
|
+
* rendered to a string via Ink's `renderToString`. ANSI escape
|
|
108
|
+
* sequences are preserved so a terminal renders the colors live.
|
|
109
|
+
* Returns the agent-string fallback when the matched cell has no Ink
|
|
110
|
+
* half.
|
|
111
|
+
*
|
|
112
|
+
* @public
|
|
113
|
+
*/
|
|
114
|
+
const renderHumanStringForReport = async (report, options = {}) => {
|
|
115
|
+
const { renderToString } = await import("ink");
|
|
116
|
+
const state = reduceRenderStateAll(synthesizeFromAgentReport(report));
|
|
117
|
+
const projects = [summarizeProject(report)];
|
|
118
|
+
const inputs = {
|
|
119
|
+
state,
|
|
120
|
+
shape: classifyRunShape(state, projects),
|
|
121
|
+
outcome: classifyOutcome(state),
|
|
122
|
+
projects,
|
|
123
|
+
trend: null,
|
|
124
|
+
belowTarget: collectBelowTarget([report]),
|
|
125
|
+
runCommand: null
|
|
126
|
+
};
|
|
127
|
+
const opts = {
|
|
128
|
+
noColor: false,
|
|
129
|
+
osc8: (_url, label) => label
|
|
130
|
+
};
|
|
131
|
+
const cell = dispatcherTable[inputs.shape][inputs.outcome];
|
|
132
|
+
if (cell.ink === void 0) return dispatch(inputs, opts);
|
|
133
|
+
return renderToString(cell.ink(inputs, opts), { columns: options.width ?? 80 });
|
|
134
|
+
};
|
|
135
|
+
const renderGithubSummary = (input) => {
|
|
136
|
+
const out = [];
|
|
137
|
+
for (const report of input.reports) {
|
|
138
|
+
const body = `${`## ${report.project ?? "Vitest Results"}`}\n\n${`${report.summary.passed}/${report.summary.total} passed, ${report.summary.failed} failed, ${report.summary.skipped} skipped`}\n`;
|
|
139
|
+
out.push({
|
|
140
|
+
target: "github-summary",
|
|
141
|
+
content: body,
|
|
142
|
+
contentType: "text/markdown"
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return out;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Subscribe a live Ink mount to the kit's run-event channel.
|
|
149
|
+
*
|
|
150
|
+
* Called from the factory when `consoleMode` is `stream`. The factory runs
|
|
151
|
+
* at run start — before the plugin publishes the first `RunStarted`
|
|
152
|
+
* event — so the subscription is registered in time. `Effect.runFork`
|
|
153
|
+
* advances the forked fiber up to its first suspension (the
|
|
154
|
+
* `Queue.take` below); that suspension point is past `PubSub.subscribe`,
|
|
155
|
+
* so the subscription is live before this function returns. The drain
|
|
156
|
+
* loop runs forever: `createLiveInk` handles `RunFinished` (schedules
|
|
157
|
+
* unmount) and a subsequent `RunStarted` (remounts) itself, so the loop
|
|
158
|
+
* stays open across watch-mode reruns and ends only when the process
|
|
159
|
+
* exits.
|
|
160
|
+
*
|
|
161
|
+
* @internal
|
|
162
|
+
*/
|
|
163
|
+
const subscribeLiveInk = (channel) => {
|
|
164
|
+
const live = createLiveInk();
|
|
165
|
+
Effect.runFork(Effect.scoped(Effect.gen(function* () {
|
|
166
|
+
const dequeue = yield* PubSub.subscribe(channel);
|
|
167
|
+
yield* Effect.forever(Queue.take(dequeue).pipe(Effect.flatMap((event) => Effect.sync(() => live.event(event)))));
|
|
168
|
+
})));
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* The default reporter factory.
|
|
172
|
+
*
|
|
173
|
+
* The plugin uses this as its built-in when no user `reporter` option
|
|
174
|
+
* is supplied, and a custom-reporter author reads it as the canonical
|
|
175
|
+
* worked example of the `VitestAgentReporterFactory` contract.
|
|
176
|
+
*
|
|
177
|
+
* The factory is invoked once at run start with the run-start kit. In
|
|
178
|
+
* `consoleMode: "stream"` it subscribes a live Ink mount to the kit's
|
|
179
|
+
* run-event channel and owns that mount's lifecycle end to end.
|
|
180
|
+
*
|
|
181
|
+
* The `render` call (invoked once at run end with the health-aware kit)
|
|
182
|
+
* assembles the reduced state, classifies the shape and outcome, and
|
|
183
|
+
* dispatches to the matching cell. Output is one stdout entry carrying
|
|
184
|
+
* the cell's string. When `kit.config.githubActions` is true a GFM
|
|
185
|
+
* step-summary payload is appended for routing to GITHUB_STEP_SUMMARY.
|
|
186
|
+
* In `stream` mode `render` emits nothing — the live mount painted the run.
|
|
187
|
+
*
|
|
188
|
+
* @public
|
|
189
|
+
*/
|
|
190
|
+
const DefaultVitestAgentReporter = (kit) => {
|
|
191
|
+
if (kit.config.consoleMode === "stream" && kit.runEvents !== void 0) subscribeLiveInk(kit.runEvents);
|
|
192
|
+
return { render(input, renderKit) {
|
|
193
|
+
const out = [];
|
|
194
|
+
if (shouldRenderForMode(renderKit.config.consoleMode)) {
|
|
195
|
+
const content = dispatch(buildDispatchInputs(reduceRenderStateAll(input.reports.flatMap((r) => synthesizeFromAgentReport(r))), input, { runCommand: renderKit.config.runCommand ?? null }), resolveCellOptions(renderKit));
|
|
196
|
+
if (content.length > 0) out.push({
|
|
197
|
+
target: "stdout",
|
|
198
|
+
content,
|
|
199
|
+
contentType: "text/plain"
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (renderKit.config.githubActions === true) out.push(...renderGithubSummary(input));
|
|
203
|
+
return out;
|
|
204
|
+
} };
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
//#endregion
|
|
208
|
+
export { DefaultVitestAgentReporter, buildDispatchInputs, renderAgentStringForReport, renderHumanStringForReport, resolveCellOptions };
|