@vitest-agent/sdk 2.5.1 → 3.1.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,8 +1,15 @@
1
1
  import { Context } from "effect";
2
2
 
3
3
  //#region src/services/DataStore.ts
4
+ /**
5
+ * Ceiling on an inline attachment body. Vitest has already copied file
6
+ * attachments into `.vitest/attachments/`, so a large body is referenced
7
+ * by `path` rather than duplicated into `data.db`.
8
+ * @public
9
+ */
10
+ const INLINE_ATTACHMENT_BODY_CAP_BYTES = 65536;
4
11
  /** @public */
5
12
  var DataStore = class extends Context.Service()("vitest-agent/DataStore") {};
6
13
 
7
14
  //#endregion
8
- export { DataStore };
15
+ export { DataStore, INLINE_ATTACHMENT_BODY_CAP_BYTES };
package/testing/layers.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { DataReaderLive } from "../layers/DataReaderLive.js";
2
2
  import { DataStoreLive } from "../layers/DataStoreLive.js";
3
- import migration from "../migrations/0001_initial.js";
3
+ import { PROJECT_MIGRATIONS } from "../migrations/index.js";
4
4
  import { Layer } from "effect";
5
5
  import * as NodeServices from "@effect/platform-node/NodeServices";
6
6
  import { layer } from "@effect/sql-sqlite-node/SqliteClient";
@@ -11,7 +11,7 @@ import * as SqliteMigrator from "@effect/sql-sqlite-node/SqliteMigrator";
11
11
  function makeTestLayer(filename) {
12
12
  const SqliteLayer = layer({ filename });
13
13
  const PlatformLayer = NodeServices.layer;
14
- const MigratorLayer = SqliteMigrator.layer({ loader: SqliteMigrator.fromRecord({ "0001_initial": migration }) }).pipe(Layer.provide(Layer.merge(SqliteLayer, PlatformLayer)));
14
+ const MigratorLayer = SqliteMigrator.layer({ loader: SqliteMigrator.fromRecord(PROJECT_MIGRATIONS) }).pipe(Layer.provide(Layer.merge(SqliteLayer, PlatformLayer)));
15
15
  return Layer.mergeAll(DataStoreLive.pipe(Layer.provide(SqliteLayer)), DataReaderLive.pipe(Layer.provide(SqliteLayer)), MigratorLayer, SqliteLayer, PlatformLayer);
16
16
  }
17
17
  /** @public */
package/testing.d.ts CHANGED
@@ -100,6 +100,12 @@ export declare const AgentReport: Schema.Struct<{
100
100
  readonly functions: Schema.optional<Schema.Number>;
101
101
  readonly branches: Schema.optional<Schema.Number>;
102
102
  readonly statements: Schema.optional<Schema.Number>;
103
+ readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
104
+ readonly lines: Schema.optional<Schema.Number>;
105
+ readonly functions: Schema.optional<Schema.Number>;
106
+ readonly branches: Schema.optional<Schema.Number>;
107
+ readonly statements: Schema.optional<Schema.Number>;
108
+ }>]>>;
103
109
  }>]>>, never>;
104
110
  }>;
105
111
  readonly targets: Schema.optional<Schema.Struct<{
@@ -114,6 +120,12 @@ export declare const AgentReport: Schema.Struct<{
114
120
  readonly functions: Schema.optional<Schema.Number>;
115
121
  readonly branches: Schema.optional<Schema.Number>;
116
122
  readonly statements: Schema.optional<Schema.Number>;
123
+ readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
124
+ readonly lines: Schema.optional<Schema.Number>;
125
+ readonly functions: Schema.optional<Schema.Number>;
126
+ readonly branches: Schema.optional<Schema.Number>;
127
+ readonly statements: Schema.optional<Schema.Number>;
128
+ }>]>>;
117
129
  }>]>>, never>;
118
130
  }>>;
119
131
  readonly baselines: Schema.optional<Schema.Struct<{
@@ -128,6 +140,12 @@ export declare const AgentReport: Schema.Struct<{
128
140
  readonly functions: Schema.optional<Schema.Number>;
129
141
  readonly branches: Schema.optional<Schema.Number>;
130
142
  readonly statements: Schema.optional<Schema.Number>;
143
+ readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
144
+ readonly lines: Schema.optional<Schema.Number>;
145
+ readonly functions: Schema.optional<Schema.Number>;
146
+ readonly branches: Schema.optional<Schema.Number>;
147
+ readonly statements: Schema.optional<Schema.Number>;
148
+ }>]>>;
131
149
  }>]>>, never>;
132
150
  }>>;
133
151
  readonly scoped: Schema.withDecodingDefaultKey<Schema.Boolean, never>;
@@ -198,6 +216,12 @@ export declare const CoverageBaselines: Schema.Struct<{
198
216
  readonly functions: Schema.optional<Schema.Number>;
199
217
  readonly branches: Schema.optional<Schema.Number>;
200
218
  readonly statements: Schema.optional<Schema.Number>;
219
+ readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
220
+ readonly lines: Schema.optional<Schema.Number>;
221
+ readonly functions: Schema.optional<Schema.Number>;
222
+ readonly branches: Schema.optional<Schema.Number>;
223
+ readonly statements: Schema.optional<Schema.Number>;
224
+ }>]>>;
201
225
  }>]>>, never>;
202
226
  }>;
203
227
  /** @public */
@@ -262,6 +286,12 @@ export declare const CoverageReport: Schema.Struct<{
262
286
  readonly functions: Schema.optional<Schema.Number>;
263
287
  readonly branches: Schema.optional<Schema.Number>;
264
288
  readonly statements: Schema.optional<Schema.Number>;
289
+ readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
290
+ readonly lines: Schema.optional<Schema.Number>;
291
+ readonly functions: Schema.optional<Schema.Number>;
292
+ readonly branches: Schema.optional<Schema.Number>;
293
+ readonly statements: Schema.optional<Schema.Number>;
294
+ }>]>>;
265
295
  }>]>>, never>;
266
296
  }>;
267
297
  readonly targets: Schema.optional<Schema.Struct<{
@@ -276,6 +306,12 @@ export declare const CoverageReport: Schema.Struct<{
276
306
  readonly functions: Schema.optional<Schema.Number>;
277
307
  readonly branches: Schema.optional<Schema.Number>;
278
308
  readonly statements: Schema.optional<Schema.Number>;
309
+ readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
310
+ readonly lines: Schema.optional<Schema.Number>;
311
+ readonly functions: Schema.optional<Schema.Number>;
312
+ readonly branches: Schema.optional<Schema.Number>;
313
+ readonly statements: Schema.optional<Schema.Number>;
314
+ }>]>>;
279
315
  }>]>>, never>;
280
316
  }>>;
281
317
  readonly baselines: Schema.optional<Schema.Struct<{
@@ -290,6 +326,12 @@ export declare const CoverageReport: Schema.Struct<{
290
326
  readonly functions: Schema.optional<Schema.Number>;
291
327
  readonly branches: Schema.optional<Schema.Number>;
292
328
  readonly statements: Schema.optional<Schema.Number>;
329
+ readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
330
+ readonly lines: Schema.optional<Schema.Number>;
331
+ readonly functions: Schema.optional<Schema.Number>;
332
+ readonly branches: Schema.optional<Schema.Number>;
333
+ readonly statements: Schema.optional<Schema.Number>;
334
+ }>]>>;
293
335
  }>]>>, never>;
294
336
  }>>;
295
337
  readonly scoped: Schema.withDecodingDefaultKey<Schema.Boolean, never>;
@@ -698,12 +740,23 @@ declare const ResolvedThresholds: Schema.Struct<{
698
740
  readonly branches: Schema.optional<Schema.Number>;
699
741
  readonly statements: Schema.optional<Schema.Number>;
700
742
  }>;
701
- readonly perFile: Schema.withDecodingDefaultKey<Schema.Boolean, never>;
743
+ readonly perFile: Schema.withDecodingDefaultKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
744
+ readonly lines: Schema.optional<Schema.Number>;
745
+ readonly functions: Schema.optional<Schema.Number>;
746
+ readonly branches: Schema.optional<Schema.Number>;
747
+ readonly statements: Schema.optional<Schema.Number>;
748
+ }>]>, never>;
702
749
  readonly patterns: Schema.withDecodingDefaultKey<Schema.$Array<Schema.Tuple<readonly [Schema.String, Schema.Struct<{
703
750
  readonly lines: Schema.optional<Schema.Number>;
704
751
  readonly functions: Schema.optional<Schema.Number>;
705
752
  readonly branches: Schema.optional<Schema.Number>;
706
753
  readonly statements: Schema.optional<Schema.Number>;
754
+ readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
755
+ readonly lines: Schema.optional<Schema.Number>;
756
+ readonly functions: Schema.optional<Schema.Number>;
757
+ readonly branches: Schema.optional<Schema.Number>;
758
+ readonly statements: Schema.optional<Schema.Number>;
759
+ }>]>>;
707
760
  }>]>>, never>;
708
761
  }>;
709
762
  /** @public */
@@ -877,6 +930,41 @@ interface TestErrorInput {
877
930
  readonly ordinal?: number;
878
931
  }
879
932
  /** @public */
933
+ interface TestAttachmentInput {
934
+ readonly contentType?: string;
935
+ /** Post-resolution path under `.vitest/attachments/`, or an http(s) URL. */
936
+ readonly path?: string;
937
+ /** Inline body; persisted only when `byteSize` is under the 64 KiB cap. */
938
+ readonly body?: string;
939
+ /** How to read `body`. Vitest treats a string body as base64 unless `"utf-8"`. */
940
+ readonly bodyEncoding?: "base64" | "utf-8";
941
+ readonly byteSize: number;
942
+ }
943
+ /** @public */
944
+ interface TestAnnotationInput {
945
+ readonly testCaseId: number;
946
+ /** Arbitrary Vitest annotation type -- not an enum. */
947
+ readonly type: string;
948
+ readonly message: string;
949
+ readonly locationFile?: string;
950
+ readonly locationLine?: number;
951
+ readonly locationColumn?: number;
952
+ readonly attachments?: ReadonlyArray<TestAttachmentInput>;
953
+ }
954
+ /** @public */
955
+ interface TestArtifactInput {
956
+ readonly testCaseId: number;
957
+ /** `pkg:name`; `internal:` types are Vitest's own and are never written. */
958
+ readonly type: string;
959
+ readonly message?: string;
960
+ /** JSON of the artifact's custom fields, minus attachments and location. */
961
+ readonly data?: string;
962
+ readonly locationFile?: string;
963
+ readonly locationLine?: number;
964
+ readonly locationColumn?: number;
965
+ readonly attachments?: ReadonlyArray<TestAttachmentInput>;
966
+ }
967
+ /** @public */
880
968
  interface FileCoverageInput {
881
969
  readonly fileId: number;
882
970
  readonly statements: number;
@@ -1090,6 +1178,17 @@ declare const DataStore_base: Context.ServiceClass<DataStore, "vitest-agent/Data
1090
1178
  readonly writeSuites: (moduleId: number, suites: ReadonlyArray<SuiteInput>) => Effect.Effect<ReadonlyArray<number>, DataStoreError>;
1091
1179
  readonly writeTestCases: (moduleId: number, tests: ReadonlyArray<TestCaseInput>) => Effect.Effect<ReadonlyArray<number>, DataStoreError>;
1092
1180
  readonly writeErrors: (runId: number, errors: ReadonlyArray<TestErrorInput>) => Effect.Effect<void, DataStoreError>;
1181
+ /**
1182
+ * Persist `context.annotate` notes and their attachment descriptors.
1183
+ * `runId` is carried for log correlation only -- `test_annotations`
1184
+ * rows are reachable through `test_cases`.
1185
+ */
1186
+ readonly writeAnnotations: (runId: number, annotations: ReadonlyArray<TestAnnotationInput>) => Effect.Effect<void, DataStoreError>;
1187
+ /**
1188
+ * Persist `recordArtifact` payloads and their attachment
1189
+ * descriptors. `runId` is carried for log correlation only.
1190
+ */
1191
+ readonly writeArtifacts: (runId: number, artifacts: ReadonlyArray<TestArtifactInput>) => Effect.Effect<void, DataStoreError>;
1093
1192
  readonly writeCoverage: (runId: number, coverage: ReadonlyArray<FileCoverageInput>) => Effect.Effect<void, DataStoreError>;
1094
1193
  readonly writeHistory: (project: string, fullName: string, modulePath: string, runId: number, timestamp: string, state: string, duration: number | null, flaky: boolean, retryCount: number, errorMessage: string | null) => Effect.Effect<void, DataStoreError>;
1095
1194
  readonly writeBaselines: (baselines: CoverageBaselines) => Effect.Effect<void, DataStoreError>;
@@ -1515,6 +1614,45 @@ interface TagInventoryRow {
1515
1614
  */
1516
1615
  readonly testCount: number;
1517
1616
  }
1617
+ /** @public */
1618
+ interface TestArtifactQueryOptions {
1619
+ /** Disambiguates a fullName that exists in more than one module. */
1620
+ readonly modulePath?: string;
1621
+ }
1622
+ /** @public */
1623
+ interface PersistedAttachment {
1624
+ readonly contentType?: string;
1625
+ readonly path?: string;
1626
+ readonly body?: string;
1627
+ /** How to read `body`. Absent when nothing was stored inline. */
1628
+ readonly bodyEncoding?: "base64" | "utf-8";
1629
+ readonly byteSize: number | null;
1630
+ }
1631
+ /** @public */
1632
+ interface TestAnnotationRow {
1633
+ readonly id: number;
1634
+ readonly type: string;
1635
+ readonly message: string;
1636
+ readonly location?: {
1637
+ readonly file: string;
1638
+ readonly line: number;
1639
+ readonly column: number;
1640
+ };
1641
+ readonly attachments: ReadonlyArray<PersistedAttachment>;
1642
+ }
1643
+ /** @public */
1644
+ interface TestArtifactRow {
1645
+ readonly id: number;
1646
+ readonly type: string;
1647
+ readonly message: string | null;
1648
+ readonly data: string | null;
1649
+ readonly location?: {
1650
+ readonly file: string;
1651
+ readonly line: number;
1652
+ readonly column: number;
1653
+ };
1654
+ readonly attachments: ReadonlyArray<PersistedAttachment>;
1655
+ }
1518
1656
  declare const DataReader_base: Context.ServiceClass<DataReader, "vitest-agent/DataReader", {
1519
1657
  readonly getLatestRun: (project: string) => Effect.Effect<Option.Option<AgentReport>, DataStoreError>;
1520
1658
  readonly getRunsByProject: () => Effect.Effect<ReadonlyArray<ProjectRunSummary>, DataStoreError>;
@@ -1527,6 +1665,10 @@ declare const DataReader_base: Context.ServiceClass<DataReader, "vitest-agent/Da
1527
1665
  readonly getCoverage: (project: string) => Effect.Effect<Option.Option<CoverageReport>, DataStoreError>;
1528
1666
  readonly getTestsForFile: (filePath: string) => Effect.Effect<ReadonlyArray<string>, DataStoreError>;
1529
1667
  readonly getErrors: (project: string, errorName?: string) => Effect.Effect<ReadonlyArray<TestError>, DataStoreError>;
1668
+ /** Annotations recorded for a test in the project's latest run. */
1669
+ readonly getAnnotationsForTest: (project: string, fullName: string, options?: TestArtifactQueryOptions) => Effect.Effect<ReadonlyArray<TestAnnotationRow>, DataStoreError>;
1670
+ /** Artifacts recorded for a test in the project's latest run. */
1671
+ readonly getArtifactsForTest: (project: string, fullName: string, options?: TestArtifactQueryOptions) => Effect.Effect<ReadonlyArray<TestArtifactRow>, DataStoreError>;
1530
1672
  readonly getNotes: (scope?: string, project?: string, testFullName?: string) => Effect.Effect<ReadonlyArray<NoteRow>, DataStoreError>;
1531
1673
  readonly getNoteById: (id: number) => Effect.Effect<Option.Option<NoteRow>, DataStoreError>;
1532
1674
  readonly searchNotes: (query: string) => Effect.Effect<ReadonlyArray<NoteRow>, DataStoreError>;
@@ -1677,6 +1819,27 @@ declare const DataReader_base: Context.ServiceClass<DataReader, "vitest-agent/Da
1677
1819
  /** @public */
1678
1820
  export declare class DataReader extends DataReader_base {}
1679
1821
  //#endregion
1822
+ //#region src/migrations/index.d.ts
1823
+ /**
1824
+ * Every migration that must run against a per-project `data.db`, keyed by
1825
+ * migration id in application order.
1826
+ *
1827
+ * This is the single source of truth for the project database's migration
1828
+ * set: `ensureMigrated`, the sdk testing layer, `ReporterLive`, `McpLive`,
1829
+ * `CliLive` and `SidecarLive` all pass it straight to
1830
+ * `SqliteMigrator.fromRecord`, so adding a migration file and registering it
1831
+ * here is enough to reach every process that opens a project database.
1832
+ *
1833
+ * The session-map and discovery-registry databases are separate schemas with
1834
+ * their own migrations and are deliberately not listed here.
1835
+ *
1836
+ * @public
1837
+ */
1838
+ export declare const PROJECT_MIGRATIONS: {
1839
+ readonly "0001_initial": import("effect/Effect").Effect<void, import("effect/unstable/sql/SqlError").SqlError, import("effect/unstable/sql/SqlClient").SqlClient>;
1840
+ readonly "0002_test_artifacts": import("effect/Effect").Effect<void, import("effect/unstable/sql/SqlError").SqlError, import("effect/unstable/sql/SqlClient").SqlClient>;
1841
+ };
1842
+ //#endregion
1680
1843
  //#region src/testing/layers.d.ts
1681
1844
  /** @public */
1682
1845
  export declare function makeTestLayer(filename: string): Layer.Layer<DataReader | DataStore | import("effect/unstable/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | NodeServices.NodeServices, SqliteMigrator.MigrationError | import("effect/unstable/sql/SqlError").SqlError, never>;
@@ -1695,5 +1858,5 @@ export declare function flaky(filename: string): Layer.Layer<DataReader | DataSt
1695
1858
  /** @public */
1696
1859
  export declare function withTddTask(filename: string): Layer.Layer<DataReader | DataStore | import("effect/unstable/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, BehaviorNotFoundError | DataStoreError | GoalNotFoundError | IllegalStatusTransitionError | import("@effect/sql-sqlite-node/SqliteMigrator").MigrationError | import("effect/unstable/sql/SqlError").SqlError | TddTaskAlreadyEndedError | TddTaskNotFoundError, never>;
1697
1860
  //#endregion
1698
- export type { AcceptanceMetrics, ArtifactKind, ArtifactSuite, AssociateRunSessionInput, ChangeKind, CitedArtifact, CitedArtifactRow, ClassificationQueryOptions, CommitChangesEntry, CreateBehaviorInput, CreateGoalInput, CurrentTddPhase, EndTddTaskInput, FailureSignatureDetail, FailureSignatureWriteInput, FileCoverageInput, FlakyTest, HistoryQueryOptions, HypothesisDetail, HypothesisInput, IdempotentResponseInput, IllegalStatusTransitionEntity, ModuleInput, ModuleListEntry, NoteInput, NoteRow, PersistentFailure, Phase, ProjectRunSummary, RegisterAgentInput, ResolvedThresholds, RunChangedFile, RunInvocationMethod, SessionDetail, SessionInput, SettingsInput, SettingsListEntry, SettingsRow, StackFrameInput, SuiteInput, SuiteListEntry, TagInventoryRow, TddArtifactDetail, TddArtifactRow, TddPhaseDetail, TddTaskDetail, TddTaskEndOutcome, TddTaskInput, TddTaskSummary, TestCaseInput, TestError, TestErrorInput, TestListEntry, TestLookupOptions, TestRunInput, TurnInput, TurnSearchOptions, TurnSummary, UpdateBehaviorInput, UpdateGoalInput, ValidateHypothesisInput, WriteCommitInput, WriteRunChangedFilesInput, WriteTddArtifactInput, WriteTddPhaseInput, WriteTddPhaseOutput };
1861
+ export type { AcceptanceMetrics, ArtifactKind, ArtifactSuite, AssociateRunSessionInput, ChangeKind, CitedArtifact, CitedArtifactRow, ClassificationQueryOptions, CommitChangesEntry, CreateBehaviorInput, CreateGoalInput, CurrentTddPhase, EndTddTaskInput, FailureSignatureDetail, FailureSignatureWriteInput, FileCoverageInput, FlakyTest, HistoryQueryOptions, HypothesisDetail, HypothesisInput, IdempotentResponseInput, IllegalStatusTransitionEntity, ModuleInput, ModuleListEntry, NoteInput, NoteRow, PersistedAttachment, PersistentFailure, Phase, ProjectRunSummary, RegisterAgentInput, ResolvedThresholds, RunChangedFile, RunInvocationMethod, SessionDetail, SessionInput, SettingsInput, SettingsListEntry, SettingsRow, StackFrameInput, SuiteInput, SuiteListEntry, TagInventoryRow, TddArtifactDetail, TddArtifactRow, TddPhaseDetail, TddTaskDetail, TddTaskEndOutcome, TddTaskInput, TddTaskSummary, TestAnnotationInput, TestAnnotationRow, TestArtifactInput, TestArtifactQueryOptions, TestArtifactRow, TestAttachmentInput, TestCaseInput, TestError, TestErrorInput, TestListEntry, TestLookupOptions, TestRunInput, TurnInput, TurnSearchOptions, TurnSummary, UpdateBehaviorInput, UpdateGoalInput, ValidateHypothesisInput, WriteCommitInput, WriteRunChangedFilesInput, WriteTddArtifactInput, WriteTddPhaseInput, WriteTddPhaseOutput };
1699
1862
  //# sourceMappingURL=testing.d.ts.map
package/testing.js CHANGED
@@ -5,6 +5,7 @@ import { DataReader } from "./services/DataReader.js";
5
5
  import { AgentId, ChatId } from "./schemas/Identity.js";
6
6
  import { Agent, IdempotencyHit } from "./schemas/Agent.js";
7
7
  import { DataStore } from "./services/DataStore.js";
8
+ import { PROJECT_MIGRATIONS } from "./migrations/index.js";
8
9
  import { CoverageReport, FileCoverageReport } from "./schemas/Coverage.js";
9
10
  import { AgentReport } from "./schemas/AgentReport.js";
10
11
  import { CoverageBaselines } from "./schemas/Baselines.js";
@@ -26,7 +27,7 @@ function singlePassingRun(filename) {
26
27
  const seed = Effect.gen(function* () {
27
28
  const store = yield* DataStore;
28
29
  yield* store.writeSettings("hash-preset-spr", {
29
- vitestVersion: "4.1.5",
30
+ vitestVersion: "5.0.0",
30
31
  pool: "forks"
31
32
  }, {});
32
33
  const runId = yield* store.writeRun({
@@ -80,7 +81,7 @@ function withFailures(filename) {
80
81
  const seed = Effect.gen(function* () {
81
82
  const store = yield* DataStore;
82
83
  yield* store.writeSettings("hash-preset-wf", {
83
- vitestVersion: "4.1.5",
84
+ vitestVersion: "5.0.0",
84
85
  pool: "forks"
85
86
  }, {});
86
87
  const runId = yield* store.writeRun({
@@ -140,7 +141,7 @@ function flaky(filename) {
140
141
  const seed = Effect.gen(function* () {
141
142
  const store = yield* DataStore;
142
143
  yield* store.writeSettings("hash-preset-flaky", {
143
- vitestVersion: "4.1.5",
144
+ vitestVersion: "5.0.0",
144
145
  pool: "forks"
145
146
  }, {});
146
147
  const runId1 = yield* store.writeRun({
@@ -250,4 +251,4 @@ function withTddTask(filename) {
250
251
  }
251
252
 
252
253
  //#endregion
253
- export { Agent, AgentId, AgentNotFoundError, AgentReport, BehaviorDetail, BehaviorNotFoundError, BehaviorRow, BehaviorStatus, CacheManifest, ChatId, CoverageBaselines, CoverageReport, DataReader, DataStore, DataStoreError, DataStoreTestLayer, FileCoverageReport, GoalDetail, GoalNotFoundError, GoalRow, GoalStatus, HistoryRecord, IdempotencyHit, IllegalStatusTransitionError, RegistrationConflictError, TddTaskAlreadyEndedError, TddTaskNotFoundError, TrendEntry, TrendRecord, empty, flaky, makeTestLayer, singlePassingRun, withFailures, withTddTask };
254
+ export { Agent, AgentId, AgentNotFoundError, AgentReport, BehaviorDetail, BehaviorNotFoundError, BehaviorRow, BehaviorStatus, CacheManifest, ChatId, CoverageBaselines, CoverageReport, DataReader, DataStore, DataStoreError, DataStoreTestLayer, FileCoverageReport, GoalDetail, GoalNotFoundError, GoalRow, GoalStatus, HistoryRecord, IdempotencyHit, IllegalStatusTransitionError, PROJECT_MIGRATIONS, RegistrationConflictError, TddTaskAlreadyEndedError, TddTaskNotFoundError, TrendEntry, TrendRecord, empty, flaky, makeTestLayer, singlePassingRun, withFailures, withTddTask };
@@ -1,5 +1,5 @@
1
1
  import { LoggerLive } from "../layers/LoggerLive.js";
2
- import migration from "../migrations/0001_initial.js";
2
+ import { PROJECT_MIGRATIONS } from "../migrations/index.js";
3
3
  import { Effect, Layer } from "effect";
4
4
  import { SqlClient } from "effect/unstable/sql/SqlClient";
5
5
  import * as NodeServices from "@effect/platform-node/NodeServices";
@@ -30,7 +30,7 @@ function ensureMigrated(dbPath, logLevel, logFile) {
30
30
  if (cached) return cached;
31
31
  const SqliteLayer = layer({ filename: dbPath });
32
32
  const PlatformLayer = NodeServices.layer;
33
- const MigratorLayer = SqliteMigrator.layer({ loader: SqliteMigrator.fromRecord({ "0001_initial": migration }) }).pipe(Layer.provide(Layer.merge(SqliteLayer, PlatformLayer)));
33
+ const MigratorLayer = SqliteMigrator.layer({ loader: SqliteMigrator.fromRecord(PROJECT_MIGRATIONS) }).pipe(Layer.provide(Layer.merge(SqliteLayer, PlatformLayer)));
34
34
  const program = Effect.gen(function* () {
35
35
  yield* SqlClient;
36
36
  }).pipe(Effect.provide(MigratorLayer), Effect.provide(Layer.merge(SqliteLayer, PlatformLayer)), Effect.provide(LoggerLive(logLevel, logFile)));
@@ -14,6 +14,16 @@ const TEST_HELPER_DIRS = [
14
14
  /** Glob suffix matching every discoverable test file. @public */
15
15
  const TEST_FILE_GLOB_SUFFIX = "*.{test,spec}.{ts,tsx,js,jsx}";
16
16
  /**
17
+ * Glob suffix matching every Bats shell test file. Bats tests are run by
18
+ * `bats`, not Vitest — a package whose `__test__/` directory holds only
19
+ * `.bats` files (plus any of {@link TEST_HELPER_DIRS}) is a fully supported,
20
+ * intentional layout, not an orphaned test directory. Paired with
21
+ * {@link TEST_FILE_GLOB_SUFFIX} by `@vitest-agent/plugin`'s
22
+ * `isTestShapedPackage` to decide whether a package without a discoverable
23
+ * Vitest project still warrants a warning. @public
24
+ */
25
+ const BATS_FILE_GLOB_SUFFIX = "*.bats";
26
+ /**
17
27
  * Directory names discovery never walks into, and therefore never collects
18
28
  * tests from. Keep in step with {@link TEST_FILE_GLOB_SUFFIX}'s extension set:
19
29
  * this is the directory half of the same "what can Vitest reach" question.
@@ -114,4 +124,4 @@ function classifyTestPath(workspaces, filePath) {
114
124
  }
115
125
 
116
126
  //#endregion
117
- export { NON_DISCOVERABLE_DIRS, SRC_DIR, TEST_DIR, TEST_FILE_GLOB_SUFFIX, TEST_HELPER_DIRS, classifyTestPath, findOwningWorkspace, isTestFileName };
127
+ export { BATS_FILE_GLOB_SUFFIX, NON_DISCOVERABLE_DIRS, SRC_DIR, TEST_DIR, TEST_FILE_GLOB_SUFFIX, TEST_HELPER_DIRS, classifyTestPath, findOwningWorkspace, isTestFileName };
@@ -24,9 +24,15 @@ function checkBooleanShortcut(key, path, errors) {
24
24
  message: `Coverage target at "${path}" cannot be true. The "true" shorthand is only valid at key "100" (meaning 100% across all metrics).`
25
25
  });
26
26
  }
27
- /** Checks all values inside a nested per-metric object (glob-pattern entry). */
27
+ /**
28
+ * Checks all values inside a nested per-metric object (glob-pattern entry).
29
+ * `perFile` is a legal key inside a glob entry under Vitest 5 — a glob entry
30
+ * no longer inherits the top-level setting — so it is skipped here rather
31
+ * than run through the boolean-shortcut check.
32
+ */
28
33
  function checkNestedMetrics(nested, prefix, errors) {
29
34
  for (const [metricKey, metricValue] of Object.entries(nested)) {
35
+ if (metricKey === "perFile") continue;
30
36
  const path = `${prefix}.${metricKey}`;
31
37
  if (typeof metricValue === "number") checkNumericValue(metricValue, path, errors);
32
38
  else if (metricValue === true) checkBooleanShortcut(metricKey, path, errors);
@@ -41,8 +47,10 @@ function checkNestedMetrics(nested, prefix, errors) {
41
47
  * OR a literal `true` appears at any key other than `"100"`. The
42
48
  * offending `path` is included (e.g. `"lines"`, `"src/**.ts.lines"`,
43
49
  * or `"statements"` when misused as a boolean shortcut).
44
- * - `PERFILE_ON_TARGETS` — the `perFile` key appears inside coverageTargets;
45
- * it should be set on `coverage.thresholds.perFile` instead.
50
+ * - `PERFILE_ON_TARGETS` — a top-level `perFile` key appears in
51
+ * coverageTargets; the top-level setting belongs on
52
+ * `coverage.thresholds.perFile`. A `perFile` inside a glob-pattern entry
53
+ * is legal and is not reported.
46
54
  *
47
55
  * @param input - The raw value passed as coverageTargets.
48
56
  * @returns A result object with errors, warnings, and info arrays.
@@ -62,7 +70,7 @@ function validateCoverageTargetsShape(input) {
62
70
  warnings.push({
63
71
  code: "PERFILE_ON_TARGETS",
64
72
  path: key,
65
- message: "The \"perFile\" key is not valid inside coverageTargets. Set coverage.thresholds.perFile instead."
73
+ message: "A top-level \"perFile\" key is not valid inside coverageTargets. Set coverage.thresholds.perFile instead, or move it inside a glob-pattern entry — under Vitest 5 a glob-pattern entry carries its own perFile and no longer inherits the top-level one."
66
74
  });
67
75
  continue;
68
76
  }