@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.
package/index.js CHANGED
@@ -2,12 +2,12 @@ import { AgentNotFoundError, ConversationNotFoundError, HostMetadataParseError,
2
2
  import { DataStoreError, extractSqlReason } from "./errors/DataStoreError.js";
3
3
  import { DiscoveryError } from "./errors/DiscoveryError.js";
4
4
  import { PathResolutionError } from "./errors/PathResolutionError.js";
5
- import { ProjectIdentityNotResolvableError } from "./errors/ProjectIdentityError.js";
5
+ import { ProjectIdentityNotResolvableError, ProjectIdentitySourceError } from "./errors/ProjectIdentityError.js";
6
6
  import { GitCommandError, ProbeMissError } from "./errors/RunContextError.js";
7
7
  import { BehaviorNotFoundError, GoalNotFoundError, IllegalStatusTransitionError, TddTaskAlreadyEndedError, TddTaskNotFoundError } from "./errors/TddErrors.js";
8
8
  import { ActorType, AgentId, ChatId, ConversationId, HostKind, ProjectKey, TddTaskId } from "./schemas/Identity.js";
9
9
  import { Agent, IdempotencyHit } from "./schemas/Agent.js";
10
- import { AgentConsoleMode, CiConsoleMode, ConsoleMode, ConsoleOutputMode, DetailLevel, Environment, Executor, HumanConsoleMode, PackageManager, ReportError, TestClassification, TestRunReason, TestState } from "./schemas/Common.js";
10
+ import { AgentConsoleMode, CiConsoleMode, ConsoleMode, ConsoleOutputMode, DetailLevel, Environment, Executor, FiniteNumber, HumanConsoleMode, PackageManager, ReportError, TestClassification, TestRunReason, TestState } from "./schemas/Common.js";
11
11
  import { ConsoleLeakFile, ConsoleLeaks, ConsoleLeaksFromFailingTests } from "./schemas/ConsoleLeaks.js";
12
12
  import { MetricThresholds, PatternMetricThresholds, PatternThresholds, PerFileThresholds, ResolvedThresholds } from "./schemas/Thresholds.js";
13
13
  import { CoverageReport, CoverageTotals, FileCoverageReport, GlobShortfall } from "./schemas/Coverage.js";
@@ -16,7 +16,7 @@ import { AgentReport, ModuleReport, ReportSummary, TagCountEntry, TestReport } f
16
16
  import { CoverageBaselines } from "./schemas/Baselines.js";
17
17
  import { CacheManifest, CacheManifestEntry } from "./schemas/CacheManifest.js";
18
18
  import { BehaviorAbandonedEvent, BehaviorAddedEvent, BehaviorCompletedEvent, BehaviorScopedEventTypes, BehaviorStartedEvent, BehaviorsReadyEvent, BlockedEvent, ChannelEvent, GoalAbandonedEvent, GoalAddedEvent, GoalCompletedEvent, GoalStartedEvent, GoalsReadyEvent, PhaseTransitionEvent, SessionCompleteEvent, SessionOutcome } from "./schemas/ChannelEvent.js";
19
- import { VitestAgentConfig } from "./schemas/Config.js";
19
+ import { RetentionConfig, RunRetentionPolicy, VitestAgentConfig } from "./schemas/Config.js";
20
20
  import { CoverageLevel, resolveCoverageInput, validateCoverageConfig } from "./schemas/CoverageLevel.js";
21
21
  import { CoverageTargets, CoverageTargetsMetrics } from "./schemas/CoverageTargets.js";
22
22
  import { HistoryRecord, TestHistory, TestRun } from "./schemas/History.js";
@@ -43,7 +43,7 @@ import { canonicalizeGitUrl, gitUrlToProjectKey } from "./utils/canonicalize-git
43
43
  import { classifyTest } from "./utils/classify-test.js";
44
44
  import { compressLines } from "./utils/compress-lines.js";
45
45
  import { computeTrend, getRecentDirection, hashTargets } from "./utils/compute-trend.js";
46
- import { buildConsoleLeaks, collectConsoleLeakEntries } from "./utils/console-leaks.js";
46
+ import { buildConsoleLeaks, collectConsoleLeakEntries, formatConsoleLeaksNote } from "./utils/console-leaks.js";
47
47
  import { detectNonDefaultDiscoverStrategy } from "./utils/detect-non-default-discover-strategy.js";
48
48
  import { detectPackageManager, getRunCommand } from "./utils/detect-pm.js";
49
49
  import { isTimeoutError } from "./utils/detect-timeout.js";
@@ -52,7 +52,6 @@ import { determineTier, formatConsoleMarkdown, getWorstMetric, relativePath } fr
52
52
  import { formatFatalError } from "./utils/format-fatal-error.js";
53
53
  import { formatGfm } from "./utils/format-gfm.js";
54
54
  import { findFunctionBoundary } from "./utils/function-boundary.js";
55
- import { osc8 } from "./utils/hyperlink.js";
56
55
  import { buildEnvPrefix, detectVitestScripts, isVitestInvocation, rewriteBashCommand } from "./utils/match-vitest-command.js";
57
56
  import { normalizeWorkspaceKey } from "./utils/normalize-workspace-key.js";
58
57
  import { basenamePosix, joinPosix, relativePosix, toPosix } from "./utils/posix-path.js";
@@ -64,4 +63,4 @@ import { validateCoverageTargetsShape } from "./utils/validate-coverage-targets-
64
63
  import { requiredArtifactForTransition, transitionEnforcesBehaviorMatch, validatePhaseTransition } from "./utils/validate-phase-transition.js";
65
64
  import { CURRENT_SDK_VERSION } from "./version.js";
66
65
 
67
- export { ActionSeverity, ActorType, Agent, AgentConsoleMode, AgentId, AgentNotFoundError, AgentPluginOptions, AgentReport, AgentReporterOptions, BATS_FILE_GLOB_SUFFIX, BehaviorAbandonedEvent, BehaviorAddedEvent, BehaviorCompletedEvent, BehaviorDetail, BehaviorNotFoundError, BehaviorRow, BehaviorScopedEventTypes, BehaviorStartedEvent, BehaviorStatus, BehaviorsReadyEvent, BlockedEvent, CURRENT_SDK_VERSION, CacheManifest, CacheManifestEntry, ChannelEvent, ChatId, CiConsoleMode, ConsoleLeakFile, ConsoleLeaks, ConsoleLeaksFromFailingTests, ConsoleLogLevel, ConsoleMode, ConsoleOutputMode, ConsoleOutputs, ConversationId, ConversationNotFoundError, CoverageBaselines, FileCoverageReport as CoverageFile, CoverageGap, CoverageLevel, CoverageMetric, CoverageRenderState, CoverageReport, CoverageTargets, CoverageTargetsMetrics, CoverageTotals, DataStoreError, DetailLevel, DiscoveryError, Environment, Executor, FailureRecord, FileCoverageReport, FileEditPayload, GitCommandError, GlobShortfall, GoalAbandonedEvent, GoalAddedEvent, GoalCompletedEvent, GoalDetail, GoalNotFoundError, GoalRow, GoalStartedEvent, GoalStatus, GoalsReadyEvent, HistoryRecord, HookFirePayload, HookStatus, HookType, HostKind, HostMetadataParseError, HumanConsoleMode, HypothesisPayload, IdempotencyHit, IllegalStatusTransitionError, MetricThresholds, ModuleRecord, ModuleReport, NON_DISCOVERABLE_DIRS, NotePayload, PackageManager, PathResolutionError, PatternMetricThresholds, PatternThresholds, PerFileThresholds, PhaseTransitionEvent, ProbeMissError, ProjectIdentityNotResolvableError, ProjectKey, RUN_REPORT_FILE_SCHEMA_URL, RegistrationConflictError, RenderState, RenderTotals, ReportError, ReportOption, ReportSettings, ReportSummary, ResolvedThresholds, RunEvent, RunReportFile, SRC_DIR, STRAY_OUTPUT_SOURCE, SessionCompleteEvent, SessionNotFoundError, SessionOutcome, SidecarTimeoutError, StrayOutput, StrayOutputSample, SuggestedActionRecord, TEST_DIR, TEST_FILE_GLOB_SUFFIX, TEST_HELPER_DIRS, TagCountEntry, TddTaskAlreadyEndedError, TddTaskId, TddTaskNotFoundError, TestAnnotation, TestArtifact, TestArtifactLocation, TestAttachment, TestClassification, TestHistory, TestRecord, TestReport, TestRun, TestRunReason, TestState, ToolCallPayload, ToolResultPayload, Transport, TrendEntry, TrendRecord, TurnPayload, UserPromptPayload, VitestAgentConfig, ansi, basenamePosix, buildAgentReport, buildConsoleLeaks, buildEnvPrefix, canonicalizeGitUrl, classifyTest, classifyTestPath, coerceErrorField, coerceErrorText, collectConsoleLeakEntries, compressLines, computeTrend, countSuiteFailures, detectNonDefaultDiscoverStrategy, detectPackageManager, detectVitestScripts, determineTier, extractSqlReason, findFunctionBoundary, findOwningWorkspace, formatConsoleMarkdown, formatFatalError, formatGfm, formatScopedCoverageNote, formatStrayOutputNote, getRecentDirection, getRunCommand, getWorstMetric, gitUrlToProjectKey, hashTargets, initialRenderState, isEscapeOnly, isTestFileName, isTimeoutError, isVitestInvocation, joinPosix, makeStrayOutputRecorder, normalizeWorkspaceKey, osc8, probeHostMetadataFromEnv, readStrayOutput, relativePath, relativePosix, requiredArtifactForTransition, resolveCoverageInput, rewriteBashCommand, safeFilename, stripAnsi, toPosix, transitionEnforcesBehaviorMatch, validateCoverageConfig, validateCoverageTargetsShape, validatePhaseTransition };
66
+ export { ActionSeverity, ActorType, Agent, AgentConsoleMode, AgentId, AgentNotFoundError, AgentPluginOptions, AgentReport, AgentReporterOptions, BATS_FILE_GLOB_SUFFIX, BehaviorAbandonedEvent, BehaviorAddedEvent, BehaviorCompletedEvent, BehaviorDetail, BehaviorNotFoundError, BehaviorRow, BehaviorScopedEventTypes, BehaviorStartedEvent, BehaviorStatus, BehaviorsReadyEvent, BlockedEvent, CURRENT_SDK_VERSION, CacheManifest, CacheManifestEntry, ChannelEvent, ChatId, CiConsoleMode, ConsoleLeakFile, ConsoleLeaks, ConsoleLeaksFromFailingTests, ConsoleLogLevel, ConsoleMode, ConsoleOutputMode, ConsoleOutputs, ConversationId, ConversationNotFoundError, CoverageBaselines, FileCoverageReport as CoverageFile, CoverageGap, CoverageLevel, CoverageMetric, CoverageRenderState, CoverageReport, CoverageTargets, CoverageTargetsMetrics, CoverageTotals, DataStoreError, DetailLevel, DiscoveryError, Environment, Executor, FailureRecord, FileCoverageReport, FileEditPayload, FiniteNumber, GitCommandError, GlobShortfall, GoalAbandonedEvent, GoalAddedEvent, GoalCompletedEvent, GoalDetail, GoalNotFoundError, GoalRow, GoalStartedEvent, GoalStatus, GoalsReadyEvent, HistoryRecord, HookFirePayload, HookStatus, HookType, HostKind, HostMetadataParseError, HumanConsoleMode, HypothesisPayload, IdempotencyHit, IllegalStatusTransitionError, MetricThresholds, ModuleRecord, ModuleReport, NON_DISCOVERABLE_DIRS, NotePayload, PackageManager, PathResolutionError, PatternMetricThresholds, PatternThresholds, PerFileThresholds, PhaseTransitionEvent, ProbeMissError, ProjectIdentityNotResolvableError, ProjectIdentitySourceError, ProjectKey, RUN_REPORT_FILE_SCHEMA_URL, RegistrationConflictError, RenderState, RenderTotals, ReportError, ReportOption, ReportSettings, ReportSummary, ResolvedThresholds, RetentionConfig, RunEvent, RunReportFile, RunRetentionPolicy, SRC_DIR, STRAY_OUTPUT_SOURCE, SessionCompleteEvent, SessionNotFoundError, SessionOutcome, SidecarTimeoutError, StrayOutput, StrayOutputSample, SuggestedActionRecord, TEST_DIR, TEST_FILE_GLOB_SUFFIX, TEST_HELPER_DIRS, TagCountEntry, TddTaskAlreadyEndedError, TddTaskId, TddTaskNotFoundError, TestAnnotation, TestArtifact, TestArtifactLocation, TestAttachment, TestClassification, TestHistory, TestRecord, TestReport, TestRun, TestRunReason, TestState, ToolCallPayload, ToolResultPayload, Transport, TrendEntry, TrendRecord, TurnPayload, UserPromptPayload, VitestAgentConfig, ansi, basenamePosix, buildAgentReport, buildConsoleLeaks, buildEnvPrefix, canonicalizeGitUrl, classifyTest, classifyTestPath, coerceErrorField, coerceErrorText, collectConsoleLeakEntries, compressLines, computeTrend, countSuiteFailures, detectNonDefaultDiscoverStrategy, detectPackageManager, detectVitestScripts, determineTier, extractSqlReason, findFunctionBoundary, findOwningWorkspace, formatConsoleLeaksNote, formatConsoleMarkdown, formatFatalError, formatGfm, formatScopedCoverageNote, formatStrayOutputNote, getRecentDirection, getRunCommand, getWorstMetric, gitUrlToProjectKey, hashTargets, initialRenderState, isEscapeOnly, isTestFileName, isTimeoutError, isVitestInvocation, joinPosix, makeStrayOutputRecorder, normalizeWorkspaceKey, probeHostMetadataFromEnv, readStrayOutput, relativePath, relativePosix, requiredArtifactForTransition, resolveCoverageInput, rewriteBashCommand, safeFilename, stripAnsi, toPosix, transitionEnforcesBehaviorMatch, validateCoverageConfig, validateCoverageTargetsShape, validatePhaseTransition };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitest-agent/sdk",
3
- "version": "7.0.5",
3
+ "version": "8.0.0",
4
4
  "private": false,
5
5
  "description": "Platform-free core for the vitest-agent package family: Effect Schema definitions, reporter and dispatcher contracts, errors, and pure utilities.",
6
6
  "keywords": [
@@ -16,69 +16,25 @@
16
16
  "type": "object",
17
17
  "properties": {
18
18
  "total": {
19
- "anyOf": [
20
- {
21
- "type": "number"
22
- },
23
- {
24
- "type": "string",
25
- "enum": ["Infinity", "-Infinity", "NaN"]
26
- }
27
- ]
19
+ "type": "number"
28
20
  },
29
21
  "passed": {
30
- "anyOf": [
31
- {
32
- "type": "number"
33
- },
34
- {
35
- "type": "string",
36
- "enum": ["Infinity", "-Infinity", "NaN"]
37
- }
38
- ]
22
+ "type": "number"
39
23
  },
40
24
  "failed": {
41
- "anyOf": [
42
- {
43
- "type": "number"
44
- },
45
- {
46
- "type": "string",
47
- "enum": ["Infinity", "-Infinity", "NaN"]
48
- }
49
- ]
25
+ "type": "number"
50
26
  },
51
27
  "skipped": {
52
- "anyOf": [
53
- {
54
- "type": "number"
55
- },
56
- {
57
- "type": "string",
58
- "enum": ["Infinity", "-Infinity", "NaN"]
59
- }
60
- ]
28
+ "type": "number"
61
29
  },
62
30
  "duration": {
63
- "anyOf": [
64
- {
65
- "type": "number"
66
- },
67
- {
68
- "type": "string",
69
- "enum": ["Infinity", "-Infinity", "NaN"]
70
- }
71
- ]
31
+ "type": "number"
72
32
  },
73
33
  "modules": {
74
34
  "anyOf": [
75
35
  {
76
36
  "type": "number"
77
37
  },
78
- {
79
- "type": "string",
80
- "enum": ["Infinity", "-Infinity", "NaN"]
81
- },
82
38
  {
83
39
  "type": "null"
84
40
  }
@@ -163,10 +119,6 @@
163
119
  {
164
120
  "type": "number"
165
121
  },
166
- {
167
- "type": "string",
168
- "enum": ["Infinity", "-Infinity", "NaN"]
169
- },
170
122
  {
171
123
  "type": "null"
172
124
  }
@@ -233,10 +185,6 @@
233
185
  {
234
186
  "type": "number"
235
187
  },
236
- {
237
- "type": "string",
238
- "enum": ["Infinity", "-Infinity", "NaN"]
239
- },
240
188
  {
241
189
  "type": "null"
242
190
  }
@@ -269,48 +217,16 @@
269
217
  "type": "object",
270
218
  "properties": {
271
219
  "statements": {
272
- "anyOf": [
273
- {
274
- "type": "number"
275
- },
276
- {
277
- "type": "string",
278
- "enum": ["Infinity", "-Infinity", "NaN"]
279
- }
280
- ]
220
+ "type": "number"
281
221
  },
282
222
  "branches": {
283
- "anyOf": [
284
- {
285
- "type": "number"
286
- },
287
- {
288
- "type": "string",
289
- "enum": ["Infinity", "-Infinity", "NaN"]
290
- }
291
- ]
223
+ "type": "number"
292
224
  },
293
225
  "functions": {
294
- "anyOf": [
295
- {
296
- "type": "number"
297
- },
298
- {
299
- "type": "string",
300
- "enum": ["Infinity", "-Infinity", "NaN"]
301
- }
302
- ]
226
+ "type": "number"
303
227
  },
304
228
  "lines": {
305
- "anyOf": [
306
- {
307
- "type": "number"
308
- },
309
- {
310
- "type": "string",
311
- "enum": ["Infinity", "-Infinity", "NaN"]
312
- }
313
- ]
229
+ "type": "number"
314
230
  }
315
231
  },
316
232
  "required": ["statements", "branches", "functions", "lines"],
@@ -324,10 +240,6 @@
324
240
  {
325
241
  "type": "number"
326
242
  },
327
- {
328
- "type": "string",
329
- "enum": ["Infinity", "-Infinity", "NaN"]
330
- },
331
243
  {
332
244
  "type": "null"
333
245
  }
@@ -338,10 +250,6 @@
338
250
  {
339
251
  "type": "number"
340
252
  },
341
- {
342
- "type": "string",
343
- "enum": ["Infinity", "-Infinity", "NaN"]
344
- },
345
253
  {
346
254
  "type": "null"
347
255
  }
@@ -352,10 +260,6 @@
352
260
  {
353
261
  "type": "number"
354
262
  },
355
- {
356
- "type": "string",
357
- "enum": ["Infinity", "-Infinity", "NaN"]
358
- },
359
263
  {
360
264
  "type": "null"
361
265
  }
@@ -366,10 +270,6 @@
366
270
  {
367
271
  "type": "number"
368
272
  },
369
- {
370
- "type": "string",
371
- "enum": ["Infinity", "-Infinity", "NaN"]
372
- },
373
273
  {
374
274
  "type": "null"
375
275
  }
@@ -396,10 +296,6 @@
396
296
  {
397
297
  "type": "number"
398
298
  },
399
- {
400
- "type": "string",
401
- "enum": ["Infinity", "-Infinity", "NaN"]
402
- },
403
299
  {
404
300
  "type": "null"
405
301
  }
@@ -410,10 +306,6 @@
410
306
  {
411
307
  "type": "number"
412
308
  },
413
- {
414
- "type": "string",
415
- "enum": ["Infinity", "-Infinity", "NaN"]
416
- },
417
309
  {
418
310
  "type": "null"
419
311
  }
@@ -424,10 +316,6 @@
424
316
  {
425
317
  "type": "number"
426
318
  },
427
- {
428
- "type": "string",
429
- "enum": ["Infinity", "-Infinity", "NaN"]
430
- },
431
319
  {
432
320
  "type": "null"
433
321
  }
@@ -438,10 +326,6 @@
438
326
  {
439
327
  "type": "number"
440
328
  },
441
- {
442
- "type": "string",
443
- "enum": ["Infinity", "-Infinity", "NaN"]
444
- },
445
329
  {
446
330
  "type": "null"
447
331
  }
@@ -587,10 +471,6 @@
587
471
  {
588
472
  "type": "number"
589
473
  },
590
- {
591
- "type": "string",
592
- "enum": ["Infinity", "-Infinity", "NaN"]
593
- },
594
474
  {
595
475
  "type": "null"
596
476
  }
@@ -659,10 +539,6 @@
659
539
  {
660
540
  "type": "number"
661
541
  },
662
- {
663
- "type": "string",
664
- "enum": ["Infinity", "-Infinity", "NaN"]
665
- },
666
542
  {
667
543
  "type": "null"
668
544
  }
@@ -673,10 +549,6 @@
673
549
  {
674
550
  "type": "number"
675
551
  },
676
- {
677
- "type": "string",
678
- "enum": ["Infinity", "-Infinity", "NaN"]
679
- },
680
552
  {
681
553
  "type": "null"
682
554
  }
@@ -687,10 +559,6 @@
687
559
  {
688
560
  "type": "number"
689
561
  },
690
- {
691
- "type": "string",
692
- "enum": ["Infinity", "-Infinity", "NaN"]
693
- },
694
562
  {
695
563
  "type": "null"
696
564
  }
@@ -706,26 +574,10 @@
706
574
  "type": "string"
707
575
  },
708
576
  "stdout": {
709
- "anyOf": [
710
- {
711
- "type": "number"
712
- },
713
- {
714
- "type": "string",
715
- "enum": ["Infinity", "-Infinity", "NaN"]
716
- }
717
- ]
577
+ "type": "number"
718
578
  },
719
579
  "stderr": {
720
- "anyOf": [
721
- {
722
- "type": "number"
723
- },
724
- {
725
- "type": "string",
726
- "enum": ["Infinity", "-Infinity", "NaN"]
727
- }
728
- ]
580
+ "type": "number"
729
581
  },
730
582
  "tests": {
731
583
  "anyOf": [
@@ -758,26 +610,10 @@
758
610
  "type": "object",
759
611
  "properties": {
760
612
  "total": {
761
- "anyOf": [
762
- {
763
- "type": "number"
764
- },
765
- {
766
- "type": "string",
767
- "enum": ["Infinity", "-Infinity", "NaN"]
768
- }
769
- ]
613
+ "type": "number"
770
614
  },
771
615
  "files": {
772
- "anyOf": [
773
- {
774
- "type": "number"
775
- },
776
- {
777
- "type": "string",
778
- "enum": ["Infinity", "-Infinity", "NaN"]
779
- }
780
- ]
616
+ "type": "number"
781
617
  }
782
618
  },
783
619
  "required": ["total", "files"],
@@ -787,15 +623,7 @@
787
623
  "type": "object",
788
624
  "properties": {
789
625
  "total": {
790
- "anyOf": [
791
- {
792
- "type": "number"
793
- },
794
- {
795
- "type": "string",
796
- "enum": ["Infinity", "-Infinity", "NaN"]
797
- }
798
- ]
626
+ "type": "number"
799
627
  },
800
628
  "byFile": {
801
629
  "type": "array",
@@ -845,48 +673,16 @@
845
673
  "type": "object",
846
674
  "properties": {
847
675
  "total": {
848
- "anyOf": [
849
- {
850
- "type": "number"
851
- },
852
- {
853
- "type": "string",
854
- "enum": ["Infinity", "-Infinity", "NaN"]
855
- }
856
- ]
676
+ "type": "number"
857
677
  },
858
678
  "stdout": {
859
- "anyOf": [
860
- {
861
- "type": "number"
862
- },
863
- {
864
- "type": "string",
865
- "enum": ["Infinity", "-Infinity", "NaN"]
866
- }
867
- ]
679
+ "type": "number"
868
680
  },
869
681
  "stderr": {
870
- "anyOf": [
871
- {
872
- "type": "number"
873
- },
874
- {
875
- "type": "string",
876
- "enum": ["Infinity", "-Infinity", "NaN"]
877
- }
878
- ]
682
+ "type": "number"
879
683
  },
880
684
  "bytes": {
881
- "anyOf": [
882
- {
883
- "type": "number"
884
- },
885
- {
886
- "type": "string",
887
- "enum": ["Infinity", "-Infinity", "NaN"]
888
- }
889
- ]
685
+ "type": "number"
890
686
  },
891
687
  "samples": {
892
688
  "type": "array",
@@ -1,4 +1,4 @@
1
- import { ReportError, TestClassification, TestRunReason, TestState } from "./Common.js";
1
+ import { FiniteNumber, ReportError, TestClassification, TestRunReason, TestState } from "./Common.js";
2
2
  import { ConsoleLeaks } from "./ConsoleLeaks.js";
3
3
  import { CoverageReport } from "./Coverage.js";
4
4
  import { StrayOutput } from "./StrayOutput.js";
@@ -10,11 +10,11 @@ import { Schema } from "effect";
10
10
  * @public
11
11
  */
12
12
  const ReportSummary = Schema.Struct({
13
- total: Schema.Number,
14
- passed: Schema.Number,
15
- failed: Schema.Number,
16
- skipped: Schema.Number,
17
- duration: Schema.Number,
13
+ total: FiniteNumber,
14
+ passed: FiniteNumber,
15
+ failed: FiniteNumber,
16
+ skipped: FiniteNumber,
17
+ duration: FiniteNumber,
18
18
  /**
19
19
  * Count of every collected module, passing modules included.
20
20
  * `AgentReport.failed` only carries failing modules, so a green run
@@ -22,7 +22,7 @@ const ReportSummary = Schema.Struct({
22
22
  * this a fully-passing replay reads as "0 modules all-passed"
23
23
  * (issue #204). Optional to keep existing fixtures/reports valid.
24
24
  */
25
- modules: Schema.optional(Schema.Number)
25
+ modules: Schema.optional(FiniteNumber)
26
26
  }).annotate({ identifier: "ReportSummary" });
27
27
  /**
28
28
  * An individual test case result.
@@ -32,7 +32,7 @@ const TestReport = Schema.Struct({
32
32
  name: Schema.String,
33
33
  fullName: Schema.String,
34
34
  state: TestState,
35
- duration: Schema.optional(Schema.Number),
35
+ duration: Schema.optional(FiniteNumber),
36
36
  flaky: Schema.optional(Schema.Boolean),
37
37
  slow: Schema.optional(Schema.Boolean),
38
38
  errors: Schema.optional(Schema.Array(ReportError)),
@@ -45,7 +45,7 @@ const TestReport = Schema.Struct({
45
45
  const ModuleReport = Schema.Struct({
46
46
  file: Schema.String,
47
47
  state: TestState,
48
- duration: Schema.optional(Schema.Number),
48
+ duration: Schema.optional(FiniteNumber),
49
49
  errors: Schema.optional(Schema.Array(ReportError)),
50
50
  tests: Schema.Array(TestReport)
51
51
  }).annotate({ identifier: "ModuleReport" });
@@ -54,9 +54,9 @@ const ModuleReport = Schema.Struct({
54
54
  * @public
55
55
  */
56
56
  const TagCountEntry = Schema.Struct({
57
- passed: Schema.optional(Schema.Number),
58
- failed: Schema.optional(Schema.Number),
59
- skipped: Schema.optional(Schema.Number)
57
+ passed: Schema.optional(FiniteNumber),
58
+ failed: Schema.optional(FiniteNumber),
59
+ skipped: Schema.optional(FiniteNumber)
60
60
  }).annotate({ identifier: "TagCountEntry" });
61
61
  /**
62
62
  * Complete per-project test report written to disk as JSON.
package/schemas/Common.js CHANGED
@@ -2,6 +2,27 @@ import { Schema } from "effect";
2
2
 
3
3
  // src/schemas/Common.ts
4
4
  /**
5
+ * A finite JSON number: the numeric field type for every schema that
6
+ * reaches a published document (`RunReportFile` and the `schemas/5.0/run.json`
7
+ * it generates). The `Type` is still `number`, and a finite value decodes
8
+ * exactly as it did under `Schema.Number`; only `NaN`, `Infinity` and
9
+ * `-Infinity` are rejected.
10
+ *
11
+ * @remarks
12
+ * `Schema.Number` lowers to JSON Schema as
13
+ * `anyOf: [{ type: "number" }, { type: "string", enum: ["Infinity", "-Infinity", "NaN"] }]`
14
+ * so the JSON codec can round-trip the non-finite values JSON has no
15
+ * literal for. The reporter writes those fields with `JSON.stringify`,
16
+ * which never produces the string arms, so the published schema was
17
+ * looser than the data and a type generator read every count and
18
+ * duration as `number | "Infinity" | "-Infinity" | "NaN"` (issue #392).
19
+ * `Schema.Finite`'s check carries a `{ type: "number" }` JSON Schema
20
+ * annotation that the emitter folds into the bare number type.
21
+ *
22
+ * @public
23
+ */
24
+ const FiniteNumber = Schema.Finite;
25
+ /**
5
26
  * Possible states for an individual test case.
6
27
  * @public
7
28
  */
@@ -145,4 +166,4 @@ const ReportError = Schema.Struct({
145
166
  received: Schema.optional(Schema.String)
146
167
  }).annotate({ identifier: "ReportError" });
147
168
 
148
- export { AgentConsoleMode, CiConsoleMode, ConsoleMode, ConsoleOutputMode, DetailLevel, Environment, Executor, HumanConsoleMode, PackageManager, ReportError, TestClassification, TestRunReason, TestState };
169
+ export { AgentConsoleMode, CiConsoleMode, ConsoleMode, ConsoleOutputMode, DetailLevel, Environment, Executor, FiniteNumber, HumanConsoleMode, PackageManager, ReportError, TestClassification, TestRunReason, TestState };
package/schemas/Config.js CHANGED
@@ -1,12 +1,42 @@
1
- import { Schema } from "effect";
1
+ import { Option, Schema } from "effect";
2
2
 
3
3
  // src/schemas/Config.ts
4
+ /** A whole number of runs or days, at least one. */
5
+ const PositiveInt = Schema.Int.check(Schema.isGreaterThanOrEqualTo(1));
6
+ /**
7
+ * The optional `[retention]` table of `vitest-agent.config.toml`: how many
8
+ * `test_runs` rows (and their cascaded modules, cases, errors, coverage
9
+ * rows) the per-project `data.db` keeps.
10
+ *
11
+ * Every field is optional. An absent table means the default policy
12
+ * (`RunRetentionPolicy.DEFAULT_KEEP_RUNS` newest runs per project, no age
13
+ * limit); `enabled = false` turns run pruning off entirely.
14
+ *
15
+ * Fields:
16
+ * - `enabled` — `false` disables run retention. Defaults to `true`.
17
+ * - `keepRuns` — the newest N runs per project to keep. A positive integer;
18
+ * defaults to `RunRetentionPolicy.DEFAULT_KEEP_RUNS`.
19
+ * - `maxAgeDays` — additionally drop any run older than this many days,
20
+ * even inside the newest N. A positive integer; no age limit by default.
21
+ *
22
+ * @remarks
23
+ * `keepRuns = 0` is rejected rather than read as "keep nothing": the run
24
+ * being written is always kept, and `enabled = false` is the explicit
25
+ * off switch, so a zero would have two readings.
26
+ * @public
27
+ */
28
+ var RetentionConfig = class extends Schema.Class("RetentionConfig")({
29
+ enabled: Schema.optionalKey(Schema.Boolean),
30
+ keepRuns: Schema.optionalKey(PositiveInt),
31
+ maxAgeDays: Schema.optionalKey(PositiveInt)
32
+ }) {};
4
33
  /**
5
34
  * Schema for the optional `vitest-agent.config.toml` file.
6
35
  *
7
- * Both fields are optional. When the file is absent or these fields are
36
+ * Every field is optional. When the file is absent or these fields are
8
37
  * unset, `resolveDataPath` falls back to deriving the path from the
9
- * workspace's `package.json` `name` under the XDG data directory.
38
+ * workspace's `package.json` `name` under the XDG data directory, and run
39
+ * retention uses the default policy.
10
40
  *
11
41
  * Fields:
12
42
  * - `cacheDir` — absolute path overriding the entire data directory. Highest
@@ -17,11 +47,48 @@ import { Schema } from "effect";
17
47
  * directory. Use this when two unrelated projects on the same machine
18
48
  * share a `package.json` `name` (the collision case for workspace-name
19
49
  * keying), or when you want a stable key independent of `name` changes.
50
+ * - `retention` — the `[retention]` table; see `RetentionConfig`.
20
51
  * @public
21
52
  */
22
53
  var VitestAgentConfig = class extends Schema.Class("VitestAgentConfig")({
23
54
  cacheDir: Schema.optional(Schema.String),
24
- projectKey: Schema.optional(Schema.String)
55
+ projectKey: Schema.optional(Schema.String),
56
+ retention: Schema.optionalKey(RetentionConfig)
25
57
  }) {};
58
+ /**
59
+ * The resolved run-retention policy a `data.db` prune applies: keep the
60
+ * newest `keepRuns` runs of every project, and drop any run older than
61
+ * `maxAgeDays` days when set. The run being persisted is never pruned.
62
+ *
63
+ * @remarks
64
+ * The default of 200 runs per project is sized against what reads the
65
+ * data: failure classification reads the newest 10 `test_history` rows per
66
+ * test and coverage trends keep 50 entries, so 200 leaves both a wide
67
+ * margin while bounding a 7k-test suite (about 3 MB per run) to a few
68
+ * hundred megabytes instead of growing without bound (issue 623, where an
69
+ * unpruned database reached 880 MB over 4,484 runs). `maxAgeDays` is the
70
+ * lever for a project that runs rarely but wants a calendar bound.
71
+ * @public
72
+ */
73
+ var RunRetentionPolicy = class RunRetentionPolicy extends Schema.Class("RunRetentionPolicy")({
74
+ keepRuns: PositiveInt,
75
+ maxAgeDays: Schema.optionalKey(PositiveInt)
76
+ }) {
77
+ /** Newest runs per project kept when the config names no `keepRuns`. */
78
+ static DEFAULT_KEEP_RUNS = 200;
79
+ /**
80
+ * Resolve the policy a loaded config asks for: `Option.none()` when
81
+ * `retention.enabled` is `false`, otherwise the configured values over
82
+ * the defaults.
83
+ */
84
+ static fromConfig(config) {
85
+ const retention = config.retention;
86
+ if (retention?.enabled === false) return Option.none();
87
+ return Option.some(RunRetentionPolicy.make({
88
+ keepRuns: retention?.keepRuns ?? RunRetentionPolicy.DEFAULT_KEEP_RUNS,
89
+ ...retention?.maxAgeDays !== void 0 && { maxAgeDays: retention.maxAgeDays }
90
+ }));
91
+ }
92
+ };
26
93
 
27
- export { VitestAgentConfig };
94
+ export { RetentionConfig, RunRetentionPolicy, VitestAgentConfig };