@vitest-agent/ui 5.1.1 → 5.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/dispatcher/helpers.js +75 -57
- package/index.d.ts +9 -0
- package/index.js +3 -2
- package/ink/CountColumns.js +2 -1
- package/ink/ProjectRow.js +10 -2
- package/ink/StreamApp.js +6 -7
- package/ink/TagColumns.js +2 -1
- package/package.json +6 -6
package/dispatcher/helpers.js
CHANGED
|
@@ -152,22 +152,23 @@ const formatTrendLine = (trend) => {
|
|
|
152
152
|
return `Trend: ${trend.direction} (${Fmt.plural(trend.runCount, "run")})`;
|
|
153
153
|
};
|
|
154
154
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
155
|
+
* The two cells of one project's row: the status glyph with the name, then
|
|
156
|
+
* the counts, duration and (for a multi-tag project) the tag counts. The
|
|
157
|
+
* glyph is `✓` for a clean project and `✗` for one carrying failures or
|
|
158
|
+
* timeouts.
|
|
159
159
|
*/
|
|
160
|
-
const
|
|
160
|
+
const projectCells = (project) => {
|
|
161
161
|
const timeoutCount = project.timeoutCount ?? 0;
|
|
162
162
|
const total = project.passCount + project.failCount + project.skipCount + timeoutCount;
|
|
163
|
-
const
|
|
163
|
+
const failing = project.failCount > 0 || timeoutCount > 0;
|
|
164
|
+
const glyph = statusGlyph(failing ? "failure" : "success");
|
|
164
165
|
const countParts = [`${project.passCount}/${total} passed`];
|
|
165
166
|
if (project.failCount > 0) countParts.push(`${project.failCount} failed`);
|
|
166
167
|
if (timeoutCount > 0) countParts.push(`${timeoutCount} timed out`);
|
|
167
|
-
const counts =
|
|
168
|
+
const counts = failing ? countParts.join(", ") : `${project.passCount} passed`;
|
|
168
169
|
const tagSuffix = formatTagCountSuffix(project.tagCounts);
|
|
169
|
-
const base =
|
|
170
|
-
return tagSuffix.length === 0 ? base : `${base} ${tagSuffix}
|
|
170
|
+
const base = `${counts} (${formatDisplayDuration(project.durationMs)})`;
|
|
171
|
+
return [`${glyph} ${project.name}`, tagSuffix.length === 0 ? base : `${base} ${tagSuffix}`];
|
|
171
172
|
};
|
|
172
173
|
const formatTagCountSuffix = (tagCounts) => {
|
|
173
174
|
if (tagCounts === void 0) return "";
|
|
@@ -176,14 +177,29 @@ const formatTagCountSuffix = (tagCounts) => {
|
|
|
176
177
|
return [...entries].sort(([a], [b]) => a.localeCompare(b)).map(([tag, count]) => `${tag}:${count}`).join(" ");
|
|
177
178
|
};
|
|
178
179
|
/**
|
|
180
|
+
* A render width no table reaches, so the kit never truncates a cell: a
|
|
181
|
+
* project name or a coverage path is printed whole however long it is
|
|
182
|
+
* (issue #237 follow-up).
|
|
183
|
+
*/
|
|
184
|
+
const UNBOUNDED_WIDTH = Number.MAX_SAFE_INTEGER;
|
|
185
|
+
/**
|
|
179
186
|
* Format the `Projects (N):` block as an array of lines including the
|
|
180
|
-
* leading header and each project row
|
|
181
|
-
*
|
|
187
|
+
* leading header and each project row, indented two spaces.
|
|
188
|
+
*
|
|
189
|
+
* @remarks
|
|
190
|
+
* The rows are a header-less, space-aligned kit `Doc.table` rendered plain,
|
|
191
|
+
* so the name column is padded by display width (a wide or combining
|
|
192
|
+
* character in a project name keeps the counts aligned) rather than by
|
|
193
|
+
* UTF-16 length.
|
|
182
194
|
*/
|
|
183
195
|
const formatProjectsTable = (projects) => {
|
|
184
196
|
if (projects.length === 0) return [];
|
|
185
|
-
const
|
|
186
|
-
|
|
197
|
+
const table = Doc.table([{ header: "" }, { header: "" }], projects.map(projectCells));
|
|
198
|
+
const rows = Render.plain([table], Render.contextOf({
|
|
199
|
+
audience: "agent",
|
|
200
|
+
width: UNBOUNDED_WIDTH
|
|
201
|
+
})).split("\n").map((row) => ` ${row}`);
|
|
202
|
+
return [`Projects (${projects.length}):`, ...rows];
|
|
187
203
|
};
|
|
188
204
|
/**
|
|
189
205
|
* Format the `Total:` footer for a workspace run.
|
|
@@ -197,55 +213,55 @@ const formatWorkspaceTotal = (projects) => formatTotalsLine({
|
|
|
197
213
|
durationMs: sumOf(projects, (p) => p.durationMs)
|
|
198
214
|
});
|
|
199
215
|
const sumOf = (projects, pick) => projects.reduce((sum, p) => sum + pick(p), 0);
|
|
200
|
-
const TABLE_COL_FILE_MIN = 60;
|
|
201
216
|
/**
|
|
202
|
-
* Format the `Files below aspirational target:` block —
|
|
203
|
-
* table
|
|
204
|
-
*
|
|
217
|
+
* Format the `Files below aspirational target:` block — an istanbul-shaped
|
|
218
|
+
* pipe table (`Doc.table` with `style: "pipe"`) of the first `limit` files,
|
|
219
|
+
* followed by a `… N more` line when files were omitted. Returns an empty
|
|
220
|
+
* array when `belowTarget` is empty.
|
|
205
221
|
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
222
|
+
* @remarks
|
|
223
|
+
* The table renders at {@link UNBOUNDED_WIDTH}, so the kit never truncates a
|
|
224
|
+
* cell and a printed path is always whole (issue #237 follow-up). Columns are
|
|
225
|
+
* padded by display width and the percentage cells are centred by the kit.
|
|
226
|
+
* Each path is a `Doc.link` written through `link`, so a hyperlink wraps the
|
|
227
|
+
* path alone and never the padding. It renders through `Render.ansi` at
|
|
228
|
+
* colour `none` (as {@link formatFailure} does), since `plain` never calls
|
|
229
|
+
* `link`.
|
|
212
230
|
*/
|
|
213
231
|
const formatBelowTargetTable = (belowTarget, limit, link = (_target, label) => label) => {
|
|
214
232
|
if (belowTarget.length === 0) return [];
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const left = Math.floor(pad / 2);
|
|
246
|
-
const right = pad - left;
|
|
247
|
-
return `${" ".repeat(left + 1)}${text}${" ".repeat(right)}`;
|
|
233
|
+
const pct = (header) => ({
|
|
234
|
+
header,
|
|
235
|
+
align: "center"
|
|
236
|
+
});
|
|
237
|
+
const table = Doc.table([
|
|
238
|
+
{ header: "File" },
|
|
239
|
+
pct("% Stmts"),
|
|
240
|
+
pct("% Branch"),
|
|
241
|
+
pct("% Funcs"),
|
|
242
|
+
pct("% Lines"),
|
|
243
|
+
{ header: "Uncovered Line #s" }
|
|
244
|
+
], belowTarget.map((file) => [
|
|
245
|
+
Doc.link({ file: file.file }, file.file, { suffix: false }),
|
|
246
|
+
pctCell(file.summary.statements),
|
|
247
|
+
pctCell(file.summary.branches),
|
|
248
|
+
pctCell(file.summary.functions),
|
|
249
|
+
pctCell(file.summary.lines),
|
|
250
|
+
file.uncoveredLines
|
|
251
|
+
]), {
|
|
252
|
+
style: "pipe",
|
|
253
|
+
cap: limit,
|
|
254
|
+
overflow: (hidden) => `… ${hidden} more (use the test_coverage MCP tool for the full list)`
|
|
255
|
+
});
|
|
256
|
+
return ["Files below aspirational target:", ...Render.ansi([table], {
|
|
257
|
+
...Render.contextOf({
|
|
258
|
+
audience: "human",
|
|
259
|
+
width: UNBOUNDED_WIDTH
|
|
260
|
+
}),
|
|
261
|
+
link: (target, label) => "file" in target ? link(target, label) : label
|
|
262
|
+
}).split("\n")];
|
|
248
263
|
};
|
|
264
|
+
const pctCell = (n) => `${Math.round(n)}`;
|
|
249
265
|
const SEVERITY_LABEL = {
|
|
250
266
|
info: "info",
|
|
251
267
|
warn: "warn",
|
|
@@ -256,6 +272,8 @@ const SEVERITY_LABEL = {
|
|
|
256
272
|
* `- <severity>: <title> (tool: <targetTool>)` with the detail indented under
|
|
257
273
|
* it. Empty when there is nothing to suggest. Shared by `renderAgent` and the
|
|
258
274
|
* dispatcher, so the one-shot and cell paths print the same list (issue #544).
|
|
275
|
+
*
|
|
276
|
+
* @public
|
|
259
277
|
*/
|
|
260
278
|
const formatSuggestedActionLines = (actions) => {
|
|
261
279
|
if (actions.length === 0) return [];
|
|
@@ -267,4 +285,4 @@ const formatSuggestedActionLines = (actions) => {
|
|
|
267
285
|
return lines;
|
|
268
286
|
};
|
|
269
287
|
|
|
270
|
-
export { formatBelowTargetTable, formatCoverageJudgmentLine, formatCoverageSummaryLines, formatDisplayDuration, formatFailure, formatGlobShortfallLines, formatPercent,
|
|
288
|
+
export { formatBelowTargetTable, formatCoverageJudgmentLine, formatCoverageSummaryLines, formatDisplayDuration, formatFailure, formatGlobShortfallLines, formatPercent, formatProjectsTable, formatSuggestedActionLines, formatTestName, formatTotals, formatTrendLine, formatWorkspaceTotal, soleModulePath, soleTest };
|
package/index.d.ts
CHANGED
|
@@ -1334,6 +1334,15 @@ export declare const buildFooter: (inputs: DispatchInputs) => string;
|
|
|
1334
1334
|
* @public
|
|
1335
1335
|
*/
|
|
1336
1336
|
export declare const formatDisplayDuration: (ms: number) => string;
|
|
1337
|
+
/**
|
|
1338
|
+
* The suggested-actions block as a compact list: `Actions:` then, per action,
|
|
1339
|
+
* `- <severity>: <title> (tool: <targetTool>)` with the detail indented under
|
|
1340
|
+
* it. Empty when there is nothing to suggest. Shared by `renderAgent` and the
|
|
1341
|
+
* dispatcher, so the one-shot and cell paths print the same list (issue #544).
|
|
1342
|
+
*
|
|
1343
|
+
* @public
|
|
1344
|
+
*/
|
|
1345
|
+
export declare const formatSuggestedActionLines: (actions: ReadonlyArray<SuggestedActionRecord>) => ReadonlyArray<string>;
|
|
1337
1346
|
/**
|
|
1338
1347
|
* Apply a single event to the previous state and return the next.
|
|
1339
1348
|
*
|
package/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { classifyOutcome, classifyRunShape } from "./dispatcher/classify.js";
|
|
|
2
2
|
import { buildFooter, dominantClassification } from "./dispatcher/footer.js";
|
|
3
3
|
import { VitestAgentStatus, VitestAgentTokens, inkStyle, statusGlyph, statusInkStyle } from "./theme.js";
|
|
4
4
|
import { formatDisplayDuration } from "./format-duration.js";
|
|
5
|
+
import { formatSuggestedActionLines } from "./dispatcher/helpers.js";
|
|
5
6
|
import { dispatch, dispatcherTable } from "./dispatcher/dispatch.js";
|
|
6
7
|
import { reduceRenderState, reduceRenderStateAll } from "./reducer.js";
|
|
7
8
|
import { renderAgent } from "./render-agent.js";
|
|
@@ -17,6 +18,6 @@ import { ActionSeverity, CoverageFile, CoverageGap, CoverageMetric, CoverageRend
|
|
|
17
18
|
*
|
|
18
19
|
* @public
|
|
19
20
|
*/
|
|
20
|
-
const CURRENT_UI_VERSION = "5.
|
|
21
|
+
const CURRENT_UI_VERSION = "5.2.0";
|
|
21
22
|
|
|
22
|
-
export { ActionSeverity, CURRENT_UI_VERSION, CoverageFile, CoverageGap, CoverageMetric, CoverageRenderState, FailureRecord, ModuleRecord, RenderState, RenderTotals, RunEvent, SPINNER_FRAMES, SPINNER_FRAME_MS, SUITE_FAILURE_LABEL, SUITE_LOAD_FAILURE_LABEL, SuggestedActionRecord, TestRecord, VitestAgentStatus, VitestAgentTokens, buildFooter, classifyOutcome, classifyRunShape, dispatch, dispatcherTable, dominantClassification, formatDisplayDuration, initialRenderState, inkStyle, reduceRenderState, reduceRenderStateAll, renderAgent, spinnerFrame, statusGlyph, statusInkStyle, synthesizeFromAgentReport, synthesizeRunEvents };
|
|
23
|
+
export { ActionSeverity, CURRENT_UI_VERSION, CoverageFile, CoverageGap, CoverageMetric, CoverageRenderState, FailureRecord, ModuleRecord, RenderState, RenderTotals, RunEvent, SPINNER_FRAMES, SPINNER_FRAME_MS, SUITE_FAILURE_LABEL, SUITE_LOAD_FAILURE_LABEL, SuggestedActionRecord, TestRecord, VitestAgentStatus, VitestAgentTokens, buildFooter, classifyOutcome, classifyRunShape, dispatch, dispatcherTable, dominantClassification, formatDisplayDuration, formatSuggestedActionLines, initialRenderState, inkStyle, reduceRenderState, reduceRenderStateAll, renderAgent, spinnerFrame, statusGlyph, statusInkStyle, synthesizeFromAgentReport, synthesizeRunEvents };
|
package/ink/CountColumns.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { VitestAgentTokens, inkStyle, statusGlyph, statusInkStyle } from "../theme.js";
|
|
2
|
+
import { Fmt } from "@effected/cli";
|
|
2
3
|
import { useGlyphs } from "@effected/cli/ui";
|
|
3
4
|
import { Text } from "ink";
|
|
4
5
|
import { jsxs } from "react/jsx-runtime";
|
|
@@ -14,7 +15,7 @@ import { jsxs } from "react/jsx-runtime";
|
|
|
14
15
|
const DURATION_CELL_WIDTH = 7;
|
|
15
16
|
const cell = (count, status, glyphs) => /* @__PURE__ */ jsxs(Text, {
|
|
16
17
|
...count > 0 ? statusInkStyle(status) : inkStyle(VitestAgentTokens.zero),
|
|
17
|
-
children: [String(count)
|
|
18
|
+
children: [Fmt.pad(String(count), 4, { align: "right" }), statusGlyph(status, glyphs)]
|
|
18
19
|
});
|
|
19
20
|
/**
|
|
20
21
|
* Renders four colored count columns (pass ✓, fail ✗, skip ↷, timeout ⧖)
|
package/ink/ProjectRow.js
CHANGED
|
@@ -3,11 +3,19 @@ import { formatDisplayDuration } from "../format-duration.js";
|
|
|
3
3
|
import { CountColumns, DURATION_CELL_WIDTH } from "./CountColumns.js";
|
|
4
4
|
import { StatusIcon } from "./StatusIcon.js";
|
|
5
5
|
import { TagColumns } from "./TagColumns.js";
|
|
6
|
+
import { Fmt } from "@effected/cli";
|
|
6
7
|
import { Box, Text } from "ink";
|
|
7
8
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
9
|
|
|
9
10
|
// src/ink/ProjectRow.tsx
|
|
10
11
|
/**
|
|
12
|
+
* One row of the `workspace`-shape `stream` view: a per-Vitest-project
|
|
13
|
+
* rollup. Carries the project name and the four-outcome count columns.
|
|
14
|
+
*
|
|
15
|
+
* The glyph animates while the project has running modules and resolves
|
|
16
|
+
* to the outcome on finish: ✗ failure, ⧖ timeout, ↷ skip-only, ✓ pass.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
11
19
|
* Pick the glyph element for the project row using the spec's severity
|
|
12
20
|
* precedence (`✗ > ⧖ > ⚠ > ↷ > ✓`). Skip-only projects (no passes, no
|
|
13
21
|
* failures, no timeouts) resolve to `↷`, not a false-positive `✓`.
|
|
@@ -34,7 +42,7 @@ const ProjectRow = ({ project, counts, running, timedOut = false, elapsedMs, fra
|
|
|
34
42
|
projectGlyph(counts, running, timedOut, frame),
|
|
35
43
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
36
44
|
" ",
|
|
37
|
-
project.name
|
|
45
|
+
Fmt.pad(project.name, nameWidth),
|
|
38
46
|
" "
|
|
39
47
|
] }),
|
|
40
48
|
/* @__PURE__ */ jsx(CountColumns, {
|
|
@@ -45,7 +53,7 @@ const ProjectRow = ({ project, counts, running, timedOut = false, elapsedMs, fra
|
|
|
45
53
|
}),
|
|
46
54
|
/* @__PURE__ */ jsxs(Text, {
|
|
47
55
|
dimColor: true,
|
|
48
|
-
children: [" ", formatDisplayDuration(elapsedMs)
|
|
56
|
+
children: [" ", Fmt.pad(formatDisplayDuration(elapsedMs), 7, { align: "right" })]
|
|
49
57
|
}),
|
|
50
58
|
tagUnion.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Text, { children: " " }), /* @__PURE__ */ jsx(TagColumns, {
|
|
51
59
|
tags: tagUnion,
|
package/ink/StreamApp.js
CHANGED
|
@@ -133,8 +133,7 @@ const ModuleStreamRow = ({ module, nowMs, frame, nameWidth, timedOut, tagUnion:
|
|
|
133
133
|
glyph,
|
|
134
134
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
135
135
|
" ",
|
|
136
|
-
link({ file: module.modulePath }, module.modulePath),
|
|
137
|
-
" ".repeat(Math.max(0, nameWidth - module.modulePath.length)),
|
|
136
|
+
Fmt.pad(link({ file: module.modulePath }, module.modulePath), nameWidth),
|
|
138
137
|
" "
|
|
139
138
|
] }),
|
|
140
139
|
/* @__PURE__ */ jsx(CountColumns, {
|
|
@@ -145,7 +144,7 @@ const ModuleStreamRow = ({ module, nowMs, frame, nameWidth, timedOut, tagUnion:
|
|
|
145
144
|
}),
|
|
146
145
|
/* @__PURE__ */ jsxs(Text, {
|
|
147
146
|
dimColor: true,
|
|
148
|
-
children: [" ", formatDisplayDuration(moduleElapsedMs(module, nowMs))
|
|
147
|
+
children: [" ", Fmt.pad(formatDisplayDuration(moduleElapsedMs(module, nowMs)), 7, { align: "right" })]
|
|
149
148
|
}),
|
|
150
149
|
rowTagUnion.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Text, { children: " " }), /* @__PURE__ */ jsx(TagColumns, {
|
|
151
150
|
tags: rowTagUnion,
|
|
@@ -246,7 +245,7 @@ const FailureItem = ({ failure }) => {
|
|
|
246
245
|
const TotalsLine = ({ totals, labelWidth }) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
247
246
|
/* @__PURE__ */ jsx(Text, {
|
|
248
247
|
bold: true,
|
|
249
|
-
children: labelWidth !== void 0 ? "Total:"
|
|
248
|
+
children: labelWidth !== void 0 ? Fmt.pad("Total:", labelWidth) : "Total:"
|
|
250
249
|
}),
|
|
251
250
|
" ",
|
|
252
251
|
/* @__PURE__ */ jsx(CountColumns, {
|
|
@@ -257,7 +256,7 @@ const TotalsLine = ({ totals, labelWidth }) => /* @__PURE__ */ jsxs(Text, { chil
|
|
|
257
256
|
}),
|
|
258
257
|
/* @__PURE__ */ jsxs(Text, {
|
|
259
258
|
dimColor: true,
|
|
260
|
-
children: [" ", formatDisplayDuration(totals.durationMs)
|
|
259
|
+
children: [" ", Fmt.pad(formatDisplayDuration(totals.durationMs), 7, { align: "right" })]
|
|
261
260
|
})
|
|
262
261
|
] });
|
|
263
262
|
/**
|
|
@@ -349,7 +348,7 @@ const liveRegion = (state, shape, nowMs, frame, glyphs, link) => {
|
|
|
349
348
|
})]
|
|
350
349
|
});
|
|
351
350
|
if (shape === "workspace") {
|
|
352
|
-
const nameWidth = Math.max(0, ...groups.map((g) => g.name
|
|
351
|
+
const nameWidth = Math.max(0, ...groups.map((g) => Fmt.width(g.name)));
|
|
353
352
|
const groupTagCounts = new Map(groups.map((g) => [g.name, mergeTagCounts(g.modules)]));
|
|
354
353
|
const workspaceTags = tagUnion(groups.map((g) => groupTagCounts.get(g.name)));
|
|
355
354
|
let runningVisible = 0;
|
|
@@ -415,7 +414,7 @@ const liveRegion = (state, shape, nowMs, frame, glyphs, link) => {
|
|
|
415
414
|
] });
|
|
416
415
|
}
|
|
417
416
|
if (shape === "single-project") {
|
|
418
|
-
const nameWidth = Math.max(0, ...ordered.map((m) => m.modulePath
|
|
417
|
+
const nameWidth = Math.max(0, ...ordered.map((m) => Fmt.width(m.modulePath)));
|
|
419
418
|
const moduleTags = tagUnion(ordered.map((m) => m.tagCounts));
|
|
420
419
|
let runningVisible = 0;
|
|
421
420
|
let runningOverflow = 0;
|
package/ink/TagColumns.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { VitestAgentTokens, inkStyle } from "../theme.js";
|
|
2
|
+
import { Fmt } from "@effected/cli";
|
|
2
3
|
import { Text } from "ink";
|
|
3
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
5
|
|
|
@@ -40,7 +41,7 @@ const TagColumns = ({ tags, counts }) => {
|
|
|
40
41
|
i > 0 ? " " : "",
|
|
41
42
|
tag,
|
|
42
43
|
":",
|
|
43
|
-
String(count)
|
|
44
|
+
Fmt.pad(String(count), 4, { align: "right" })
|
|
44
45
|
]
|
|
45
46
|
}, tag);
|
|
46
47
|
}) });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest-agent/ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Shared event-sourced renderer for vitest-agent. React Ink view for humans, plain-string view for agents, both fed by the same reducer over a RunEvent stream.",
|
|
6
6
|
"keywords": [
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
"./package.json": "./package.json"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@vitest-agent/sdk": "
|
|
47
|
+
"@vitest-agent/sdk": "9.0.0",
|
|
48
48
|
"effect": "^4.0.6"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@effected/cli": "^0.
|
|
52
|
-
"@effected/env": "^0.
|
|
53
|
-
"@effected/glob": "^0.
|
|
54
|
-
"@effected/walker": "^0.
|
|
51
|
+
"@effected/cli": "^0.23.0",
|
|
52
|
+
"@effected/env": "^0.6.0",
|
|
53
|
+
"@effected/glob": "^0.15.0",
|
|
54
|
+
"@effected/walker": "^0.21.0",
|
|
55
55
|
"ink": "^8.0.0",
|
|
56
56
|
"react": "^19.3.0"
|
|
57
57
|
},
|