@vitest-agent/sdk 7.0.5 → 8.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.
@@ -1,3 +1,4 @@
1
+ import { FiniteNumber } from "./Common.js";
1
2
  import { Schema } from "effect";
2
3
 
3
4
  // src/schemas/ConsoleLeaks.ts
@@ -8,8 +9,8 @@ import { Schema } from "effect";
8
9
  */
9
10
  const ConsoleLeakFile = Schema.Struct({
10
11
  file: Schema.String,
11
- stdout: Schema.Number,
12
- stderr: Schema.Number,
12
+ stdout: FiniteNumber,
13
+ stderr: FiniteNumber,
13
14
  tests: Schema.optional(Schema.Array(Schema.String)),
14
15
  sample: Schema.optional(Schema.String)
15
16
  }).annotate({ identifier: "ConsoleLeakFile" });
@@ -22,8 +23,8 @@ const ConsoleLeakFile = Schema.Struct({
22
23
  * @public
23
24
  */
24
25
  const ConsoleLeaksFromFailingTests = Schema.Struct({
25
- total: Schema.Number,
26
- files: Schema.Number
26
+ total: FiniteNumber,
27
+ files: FiniteNumber
27
28
  }).annotate({ identifier: "ConsoleLeaksFromFailingTests" });
28
29
  /**
29
30
  * Aggregate stray-console-output signal for a single test run. Omitted from
@@ -35,7 +36,7 @@ const ConsoleLeaksFromFailingTests = Schema.Struct({
35
36
  * @public
36
37
  */
37
38
  const ConsoleLeaks = Schema.Struct({
38
- total: Schema.Number,
39
+ total: FiniteNumber,
39
40
  byFile: Schema.Array(ConsoleLeakFile),
40
41
  truncated: Schema.optional(Schema.Boolean),
41
42
  fromFailingTests: Schema.optional(ConsoleLeaksFromFailingTests)
@@ -1,3 +1,4 @@
1
+ import { FiniteNumber } from "./Common.js";
1
2
  import { MetricThresholds, PatternThresholds } from "./Thresholds.js";
2
3
  import { Effect, Schema } from "effect";
3
4
 
@@ -7,10 +8,10 @@ import { Effect, Schema } from "effect";
7
8
  * @public
8
9
  */
9
10
  const CoverageTotals = Schema.Struct({
10
- statements: Schema.Number,
11
- branches: Schema.Number,
12
- functions: Schema.Number,
13
- lines: Schema.Number
11
+ statements: FiniteNumber,
12
+ branches: FiniteNumber,
13
+ functions: FiniteNumber,
14
+ lines: FiniteNumber
14
15
  }).annotate({ identifier: "CoverageTotals" });
15
16
  /**
16
17
  * Per-file coverage data including uncovered line ranges.
@@ -58,7 +59,7 @@ const CoverageReport = Schema.Struct({
58
59
  })),
59
60
  scoped: Schema.Boolean.pipe(Schema.withDecodingDefaultKey(Effect.succeed(false))),
60
61
  scopedFiles: Schema.optional(Schema.Array(Schema.String)),
61
- totalFiles: Schema.optional(Schema.Number),
62
+ totalFiles: Schema.optional(FiniteNumber),
62
63
  lowCoverage: Schema.Array(FileCoverageReport),
63
64
  lowCoverageFiles: Schema.Array(Schema.String),
64
65
  belowTarget: Schema.optional(Schema.Array(FileCoverageReport)),
@@ -42,17 +42,45 @@ const ReportOption = Schema.Union([Schema.Literal(false), ReportSettings]).annot
42
42
  /**
43
43
  * The 2.0 user-facing options for `AgentPlugin`.
44
44
  *
45
- * Six fields total. Two are function-typed (`reporter`, `onRunEvent`)
45
+ * Seven fields total. Two are function-typed (`reporter`, `onRunEvent`)
46
46
  * and live on the `AgentPluginConstructorOptions` companion interface in
47
47
  * `@vitest-agent/plugin` — Effect Schema cannot encode functions cleanly,
48
- * so the schema-decodable struct carries the four data-shaped fields.
48
+ * so the schema-decodable struct carries the five data-shaped fields.
49
49
  * @public
50
50
  */
51
51
  const AgentPluginOptions = Schema.Struct({
52
52
  console: Schema.optional(ConsoleOutputs),
53
53
  coverageTargets: Schema.optional(CoverageTargets),
54
54
  transport: Schema.optional(Transport),
55
- report: Schema.optional(ReportOption)
55
+ report: Schema.optional(ReportOption),
56
+ /**
57
+ * Whether a run is recorded in the SQLite `data.db` (default `true`).
58
+ *
59
+ * `false` is the explicit opt-out for a runner where nothing reads the
60
+ * database back — a throwaway CI job, say. The run still renders every
61
+ * console and report-file output, still emits every `RunEvent`, and
62
+ * Vitest still enforces `coverage.thresholds` through its own
63
+ * mechanism; only the database writes are skipped: run rows, test
64
+ * cases, failure history, coverage rows and trends, and the baselines
65
+ * they feed. Consequences a renderer sees: failure classifications are
66
+ * empty (there is no history to classify against, so no test is
67
+ * labelled `stable`, `new-failure`, `persistent`, `flaky` or
68
+ * `recovered`), and coverage renders without a baseline delta or a
69
+ * trend line. The `data.db` file is never created or opened.
70
+ *
71
+ * The opt-out is never automatic: `CI=true` does not imply it, because
72
+ * some CI setups cache `data.db` between jobs and query it. The
73
+ * `VITEST_AGENT_PERSIST` environment variable (`0` / `false` / `off`
74
+ * to disable, `1` / `true` / `on` to enable) is the operator spelling
75
+ * for a runner whose config cannot be edited, and it wins over this
76
+ * option in either direction; any other value is ignored with one
77
+ * stderr line.
78
+ *
79
+ * `coverage.enabled: false` in Vitest's own config already skips
80
+ * persistence (UI-only mode, Decision 38) — this option is for a run
81
+ * that keeps coverage on and still wants no database.
82
+ */
83
+ persist: Schema.optional(Schema.Boolean)
56
84
  }).annotate({ identifier: "AgentPluginOptions" });
57
85
  /**
58
86
  * Reporter-implementation options.
@@ -1,4 +1,5 @@
1
1
  import { ReportError, TestClassification, TestState } from "./Common.js";
2
+ import { ConsoleLeaks } from "./ConsoleLeaks.js";
2
3
  import { MetricThresholds } from "./Thresholds.js";
3
4
  import { CoverageTotals, GlobShortfall } from "./Coverage.js";
4
5
  import { StrayOutput } from "./StrayOutput.js";
@@ -163,7 +164,13 @@ const RenderState = Schema.Struct({
163
164
  * capture, folded from `RunFinished.strayOutput`. Absent when the run
164
165
  * wrote nothing stray.
165
166
  */
166
- strayOutput: Schema.optional(StrayOutput)
167
+ strayOutput: Schema.optional(StrayOutput),
168
+ /**
169
+ * `console.*` output Vitest captured from tests that did not fail, folded
170
+ * from `RunFinished.consoleLeaks`. Absent when the run logged nothing
171
+ * (issue #544).
172
+ */
173
+ consoleLeaks: Schema.optional(ConsoleLeaks)
167
174
  }).annotate({ identifier: "RenderState" });
168
175
  /**
169
176
  * Initial state — what the reducer returns when no events have been
@@ -1,4 +1,5 @@
1
1
  import { ReportError, TestClassification, TestState } from "./Common.js";
2
+ import { ConsoleLeaks } from "./ConsoleLeaks.js";
2
3
  import { MetricThresholds } from "./Thresholds.js";
3
4
  import { CoverageTotals, FileCoverageReport, GlobShortfall } from "./Coverage.js";
4
5
  import { StrayOutput } from "./StrayOutput.js";
@@ -226,7 +227,13 @@ const RunEvent = Schema.Union([
226
227
  * capture (`AgentReport.strayOutput`). Optional: absent when the run
227
228
  * wrote nothing stray, and in older replay data.
228
229
  */
229
- strayOutput: Schema.optional(StrayOutput)
230
+ strayOutput: Schema.optional(StrayOutput),
231
+ /**
232
+ * `console.*` output Vitest captured from tests that did not fail
233
+ * (`AgentReport.consoleLeaks`). Optional: absent when the run logged
234
+ * nothing, and in older replay data (issue #544).
235
+ */
236
+ consoleLeaks: Schema.optional(ConsoleLeaks)
230
237
  })
231
238
  ]).annotate({ identifier: "RunEvent" });
232
239
 
@@ -1,3 +1,4 @@
1
+ import { FiniteNumber } from "./Common.js";
1
2
  import { Schema } from "effect";
2
3
 
3
4
  // src/schemas/StrayOutput.ts
@@ -27,10 +28,10 @@ const StrayOutputSample = Schema.Struct({
27
28
  * @public
28
29
  */
29
30
  const StrayOutput = Schema.Struct({
30
- total: Schema.Number,
31
- stdout: Schema.Number,
32
- stderr: Schema.Number,
33
- bytes: Schema.Number,
31
+ total: FiniteNumber,
32
+ stdout: FiniteNumber,
33
+ stderr: FiniteNumber,
34
+ bytes: FiniteNumber,
34
35
  samples: Schema.Array(StrayOutputSample)
35
36
  }).annotate({ identifier: "StrayOutput" });
36
37
 
@@ -1,3 +1,4 @@
1
+ import { FiniteNumber } from "./Common.js";
1
2
  import { Effect, Schema } from "effect";
2
3
 
3
4
  // src/schemas/Thresholds.ts
@@ -6,10 +7,10 @@ import { Effect, Schema } from "effect";
6
7
  * @public
7
8
  */
8
9
  const MetricThresholds = Schema.Struct({
9
- lines: Schema.optional(Schema.Number),
10
- functions: Schema.optional(Schema.Number),
11
- branches: Schema.optional(Schema.Number),
12
- statements: Schema.optional(Schema.Number)
10
+ lines: Schema.optional(FiniteNumber),
11
+ functions: Schema.optional(FiniteNumber),
12
+ branches: Schema.optional(FiniteNumber),
13
+ statements: Schema.optional(FiniteNumber)
13
14
  }).annotate({ identifier: "MetricThresholds" });
14
15
  /**
15
16
  * A `perFile` setting. Vitest 5 allows either a plain boolean or a
@@ -99,5 +99,31 @@ function collectConsoleLeakEntries(files) {
99
99
  }
100
100
  return entries;
101
101
  }
102
+ const MAX_NOTE_FILES = 3;
103
+ /**
104
+ * The note a renderer prints for a run's console leaks: one line naming the
105
+ * write count, the file count and the fix, then up to three files with
106
+ * their stream split and sample, how many files it left out, and the output
107
+ * from failing tests that the leak count excludes. Empty when the run has no
108
+ * leak from a passing test (output from failing tests alone is not a leak).
109
+ * @public
110
+ */
111
+ const formatConsoleLeaksNote = (leaks) => {
112
+ if (leaks.total === 0) return [];
113
+ const files = leaks.byFile.length;
114
+ const lines = [`Console leaks: passing tests wrote ${leaks.total} console ${leaks.total === 1 ? "line" : "lines"} in ${files} ${files === 1 ? "file" : "files"}; Vitest captured them, so they are noise an agent never sees. Remove the logging or route it through a logger the tests silence.`];
115
+ const shown = leaks.byFile.slice(0, MAX_NOTE_FILES);
116
+ for (const file of shown) {
117
+ const streams = [file.stdout > 0 ? `${file.stdout} stdout` : "", file.stderr > 0 ? `${file.stderr} stderr` : ""].filter((part) => part.length > 0).join(", ");
118
+ const sample = file.sample !== void 0 ? `: ${file.sample}` : "";
119
+ lines.push(` ${file.file} (${streams})${sample}`);
120
+ }
121
+ const more = leaks.byFile.length - shown.length;
122
+ if (more > 0) lines.push(` (+${more} more ${more === 1 ? "file" : "files"}${leaks.truncated === true ? ", list truncated" : ""})`);
123
+ else if (leaks.truncated === true) lines.push(" (file list truncated)");
124
+ const failing = leaks.fromFailingTests;
125
+ if (failing !== void 0 && failing.total > 0) lines.push(` (${failing.total} more ${failing.total === 1 ? "line" : "lines"} from failing tests in ${failing.files} ${failing.files === 1 ? "file" : "files"}, not counted as leaks)`);
126
+ return lines;
127
+ };
102
128
 
103
- export { buildConsoleLeaks, collectConsoleLeakEntries };
129
+ export { buildConsoleLeaks, collectConsoleLeakEntries, formatConsoleLeaksNote };
package/version.js CHANGED
@@ -11,6 +11,6 @@
11
11
  * survives into the published artifact.
12
12
  * @public
13
13
  */
14
- const CURRENT_SDK_VERSION = "7.0.5";
14
+ const CURRENT_SDK_VERSION = "8.0.0";
15
15
 
16
16
  export { CURRENT_SDK_VERSION };
@@ -1,10 +0,0 @@
1
- // src/utils/hyperlink.ts
2
- const ESC = "\x1B";
3
- const BEL = "\x07";
4
- /** @public */
5
- const osc8 = (url, label, options) => {
6
- if (!options.enabled) return label;
7
- return `${ESC}]8;;${url}${BEL}${label}${ESC}]8;;${BEL}`;
8
- };
9
-
10
- export { osc8 };