@vitest-agent/ui 1.1.1 → 2.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/index.js CHANGED
@@ -22,7 +22,7 @@ import { TrendLine } from "./render-ink/TrendLine.js";
22
22
  import { StreamApp } from "./render-ink/StreamApp.js";
23
23
  import { SuggestedActions } from "./render-ink/SuggestedActions.js";
24
24
  import "./render-ink/index.js";
25
- import { synthesizeFromAgentReport, synthesizeRunEvents } from "./synthesize.js";
25
+ import { SUITE_LOAD_FAILURE_LABEL, synthesizeFromAgentReport, synthesizeRunEvents } from "./synthesize.js";
26
26
  import { ActionSeverity, CoverageFile, CoverageGap, CoverageMetric, CoverageRenderState, FailureRecord, ModuleRecord, RenderState, RenderTotals, RunEvent, SuggestedActionRecord, TestRecord, initialRenderState } from "@vitest-agent/sdk";
27
27
 
28
28
  //#region src/index.ts
@@ -33,7 +33,7 @@ import { ActionSeverity, CoverageFile, CoverageGap, CoverageMetric, CoverageRend
33
33
  *
34
34
  * @public
35
35
  */
36
- const CURRENT_UI_VERSION = "1.1.1";
36
+ const CURRENT_UI_VERSION = "2.0.0";
37
37
 
38
38
  //#endregion
39
- export { ActionSeverity, CURRENT_UI_VERSION, CountColumns, CoverageBlock, CoverageFile, CoverageGap, CoverageMetric, CoverageRenderState, DURATION_CELL_WIDTH, FailureRecord, FailureSection, FailuresSection, ModuleHeader, ModuleRecord, ProjectRow, RenderState, RenderTotals, RunEvent, RunEventChannel, RunEventChannelLive, SPINNER_FRAMES, SPINNER_FRAME_MS, StatusIcon, StreamApp, SuggestedActionRecord, SuggestedActions, TagColumns, TestRecord, TestRow, TrendLine, accumulateUntilFinished, buildFooter, classifyOutcome, classifyRunShape, dispatch, dispatchInk, dispatcherTable, dominantClassification, forEachRenderState, formatDisplayDuration, initialRenderState, publish, publishAll, reduceRenderState, reduceRenderStateAll, renderAgent, renderStateStream, spinnerFrame, spinnerFrameForTime, subscribeRaw, synthesizeFromAgentReport, synthesizeRunEvents, tagUnion };
39
+ export { ActionSeverity, CURRENT_UI_VERSION, CountColumns, CoverageBlock, CoverageFile, CoverageGap, CoverageMetric, CoverageRenderState, DURATION_CELL_WIDTH, FailureRecord, FailureSection, FailuresSection, ModuleHeader, ModuleRecord, ProjectRow, RenderState, RenderTotals, RunEvent, RunEventChannel, RunEventChannelLive, SPINNER_FRAMES, SPINNER_FRAME_MS, SUITE_LOAD_FAILURE_LABEL, StatusIcon, StreamApp, SuggestedActionRecord, SuggestedActions, TagColumns, TestRecord, TestRow, TrendLine, accumulateUntilFinished, buildFooter, classifyOutcome, classifyRunShape, dispatch, dispatchInk, dispatcherTable, dominantClassification, forEachRenderState, formatDisplayDuration, initialRenderState, publish, publishAll, reduceRenderState, reduceRenderStateAll, renderAgent, renderStateStream, spinnerFrame, spinnerFrameForTime, subscribeRaw, synthesizeFromAgentReport, synthesizeRunEvents, tagUnion };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitest-agent/ui",
3
- "version": "1.1.1",
3
+ "version": "2.0.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": [
@@ -33,13 +33,14 @@
33
33
  "exports": {
34
34
  ".": {
35
35
  "types": "./index.d.ts",
36
- "import": "./index.js"
36
+ "import": "./index.js",
37
+ "default": "./index.js"
37
38
  },
38
39
  "./package.json": "./package.json"
39
40
  },
40
41
  "dependencies": {
41
- "@vitest-agent/sdk": "1.3.3",
42
- "effect": "^3.21.4"
42
+ "@vitest-agent/sdk": "2.0.0",
43
+ "effect": "4.0.0-beta.98"
43
44
  },
44
45
  "peerDependencies": {
45
46
  "ink": "^7.1.0",
package/pubsub/Channel.js CHANGED
@@ -8,7 +8,7 @@ import { Context, Layer, PubSub } from "effect";
8
8
  *
9
9
  * @public
10
10
  */
11
- var RunEventChannel = class extends Context.Tag("vitest-agent-ui/RunEventChannel")() {};
11
+ var RunEventChannel = class extends Context.Service()("vitest-agent-ui/RunEventChannel") {};
12
12
  /**
13
13
  * Default live layer providing an unbounded Effect `PubSub` for
14
14
  * the run-event channel. The PubSub is scoped — when the surrounding
@@ -24,7 +24,7 @@ var RunEventChannel = class extends Context.Tag("vitest-agent-ui/RunEventChannel
24
24
  *
25
25
  * @public
26
26
  */
27
- const RunEventChannelLive = Layer.scoped(RunEventChannel, PubSub.unbounded());
27
+ const RunEventChannelLive = Layer.effect(RunEventChannel, PubSub.unbounded());
28
28
 
29
29
  //#endregion
30
30
  export { RunEventChannel, RunEventChannelLive };
@@ -1,7 +1,7 @@
1
1
  import { RunEventChannel } from "./Channel.js";
2
2
  import { reduceRenderState } from "../reducer.js";
3
3
  import { initialRenderState } from "@vitest-agent/sdk";
4
- import { Effect, PubSub, Queue, Stream } from "effect";
4
+ import { Effect, PubSub, Stream } from "effect";
5
5
 
6
6
  //#region src/pubsub/Subscriber.ts
7
7
  /**
@@ -17,10 +17,10 @@ import { Effect, PubSub, Queue, Stream } from "effect";
17
17
  */
18
18
  const accumulateUntilFinished = (initial = initialRenderState) => Effect.scoped(Effect.gen(function* () {
19
19
  const channel = yield* RunEventChannel;
20
- const dequeue = yield* PubSub.subscribe(channel);
20
+ const subscription = yield* PubSub.subscribe(channel);
21
21
  let state = initial;
22
22
  while (state.phase !== "finished" && state.phase !== "timed-out") {
23
- const event = yield* Queue.take(dequeue);
23
+ const event = yield* PubSub.take(subscription);
24
24
  state = reduceRenderState(state, event);
25
25
  }
26
26
  return state;
@@ -42,7 +42,7 @@ const accumulateUntilFinished = (initial = initialRenderState) => Effect.scoped(
42
42
  */
43
43
  const forEachRenderState = (onState, initial = initialRenderState) => Effect.scoped(Effect.gen(function* () {
44
44
  const channel = yield* RunEventChannel;
45
- yield* (yield* Stream.fromPubSub(channel, { scoped: true })).pipe(Stream.scan(initial, reduceRenderState), Stream.runForEach(onState));
45
+ yield* Stream.fromPubSub(channel).pipe(Stream.scan(initial, reduceRenderState), Stream.runForEach(onState));
46
46
  }));
47
47
  /**
48
48
  * Build an Effect `Stream` of accumulated states over the channel.
@@ -57,7 +57,7 @@ const forEachRenderState = (onState, initial = initialRenderState) => Effect.sco
57
57
  */
58
58
  const renderStateStream = (initial = initialRenderState) => Effect.gen(function* () {
59
59
  const channel = yield* RunEventChannel;
60
- return (yield* Stream.fromPubSub(channel, { scoped: true })).pipe(Stream.scan(initial, reduceRenderState));
60
+ return Stream.fromPubSub(channel).pipe(Stream.scan(initial, reduceRenderState));
61
61
  });
62
62
  /**
63
63
  * Convenience: subscribe and produce a low-level dequeue of raw
package/synthesize.js CHANGED
@@ -1,6 +1,15 @@
1
1
  import { isTimeoutError } from "@vitest-agent/sdk";
2
2
 
3
3
  //#region src/synthesize.ts
4
+ /**
5
+ * Synthetic test name used to surface a suite-level (collection/load)
6
+ * failure in the Failures detail. A module that fails to import has no real
7
+ * test case to attach the error to, so the synthesizer emits one failed
8
+ * "test" under this label carrying the module's import error.
9
+ *
10
+ * @public
11
+ */
12
+ const SUITE_LOAD_FAILURE_LABEL = "test suite failed to load";
4
13
  const ISO_ZERO = "1970-01-01T00:00:00.000Z";
5
14
  const normalizeTestState = (state) => {
6
15
  if (state === "passed") return "passed";
@@ -237,6 +246,7 @@ const synthesizeFromAgentReport = (report, options = {}) => {
237
246
  modulePath: mod.file
238
247
  });
239
248
  let totalTimeoutCount = 0;
249
+ let suiteFailureCount = 0;
240
250
  for (const mod of report.failed) {
241
251
  events.push({
242
252
  _tag: "ModuleStarted",
@@ -279,6 +289,30 @@ const synthesizeFromAgentReport = (report, options = {}) => {
279
289
  if (!timedOut) fail++;
280
290
  } else skip++;
281
291
  }
292
+ if (fail === 0 && moduleTimeoutCount === 0) {
293
+ fail = 1;
294
+ suiteFailureCount++;
295
+ const moduleError = mod.errors?.[0];
296
+ events.push({
297
+ _tag: "TestStarted",
298
+ modulePath: mod.file,
299
+ testName: SUITE_LOAD_FAILURE_LABEL,
300
+ suitePath: []
301
+ });
302
+ events.push({
303
+ _tag: "TestFinished",
304
+ modulePath: mod.file,
305
+ testName: SUITE_LOAD_FAILURE_LABEL,
306
+ suitePath: [],
307
+ status: "failed",
308
+ durationMs: 0,
309
+ ...moduleError !== void 0 && { error: {
310
+ message: moduleError.message,
311
+ ...moduleError.diff !== void 0 && { diff: moduleError.diff },
312
+ ...moduleError.stack !== void 0 && { stack: moduleError.stack }
313
+ } }
314
+ });
315
+ }
282
316
  totalTimeoutCount += moduleTimeoutCount;
283
317
  events.push({
284
318
  _tag: "ModuleFinished",
@@ -323,7 +357,7 @@ const synthesizeFromAgentReport = (report, options = {}) => {
323
357
  runId,
324
358
  finishedAt,
325
359
  passCount: report.summary.passed,
326
- failCount: report.summary.failed,
360
+ failCount: report.summary.failed + suiteFailureCount,
327
361
  skipCount: report.summary.skipped,
328
362
  durationMs: report.summary.duration,
329
363
  ...totalTimeoutCount > 0 && { timeoutCount: totalTimeoutCount }
@@ -332,4 +366,4 @@ const synthesizeFromAgentReport = (report, options = {}) => {
332
366
  };
333
367
 
334
368
  //#endregion
335
- export { synthesizeFromAgentReport, synthesizeRunEvents };
369
+ export { SUITE_LOAD_FAILURE_LABEL, synthesizeFromAgentReport, synthesizeRunEvents };
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.58.9"
8
+ "packageVersion": "7.58.10"
9
9
  }
10
10
  ]
11
11
  }