@vitest-agent/engine 0.5.0 → 0.6.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.d.ts CHANGED
@@ -8,7 +8,7 @@ import { AppDirs, AppDirsError, XdgEnvError } from "@effected/xdg";
8
8
  import { ChildProcessSpawner } from "effect/process";
9
9
  import * as NodeServices from "@effect/platform-node/NodeServices";
10
10
  import { SqliteClient } from "@effect/sql-sqlite-node/SqliteClient";
11
- import { MigrationError } from "effect/sql/Migrator";
11
+ import { StoreError, StoreMigrationError } from "@effected/store";
12
12
  import { SqlError } from "effect/sql/SqlError";
13
13
  import { PlatformError } from "effect/PlatformError";
14
14
  //#region src/services/Config.d.ts
@@ -1765,8 +1765,9 @@ declare const migration$1: Effect.Effect<void, import("effect/sql/SqlError").Sql
1765
1765
  *
1766
1766
  * This is the single source of truth for the project database's migration
1767
1767
  * set: `makeSqliteStack` (and through it `PlatformLive`, `ensureMigrated`,
1768
- * the testing layers, `ReporterLive` and `SidecarLive`) defaults to it when
1769
- * calling `SqliteMigrator.fromRecord`, so adding a migration file and
1768
+ * the testing layers, `ReporterLive` and `SidecarLive`) defaults to it and
1769
+ * runs it through `@effected/store` (keys parsed as effect/sql's
1770
+ * `fromRecord` parses them, so 2.x ledgers adopt), so adding a migration file and
1770
1771
  * registering it here is enough to reach every process that opens a project
1771
1772
  * database.
1772
1773
  *
@@ -1801,13 +1802,16 @@ declare const migration$2: Effect.Effect<void, import("effect/sql/SqlError").Sql
1801
1802
  /** @internal */
1802
1803
  declare const migration$3: Effect.Effect<void, import("effect/sql/SqlError").SqlError, SqlClient>;
1803
1804
  //#endregion
1804
- //#region src/platform.d.ts
1805
+ //#region src/stores.d.ts
1805
1806
  /**
1806
- * A migration set in the shape `SqliteMigrator.fromRecord` accepts: migration
1807
- * id → loader.
1807
+ * A migration set in the effect/sql record shape: `"<id>_<name>"` →
1808
+ * migration. The keys are the ones a 2.x `SqliteMigrator.fromRecord` recorded
1809
+ * in `effect_sql_migrations`, which is what ledger adoption matches against.
1808
1810
  * @public
1809
1811
  */
1810
- export type MigrationRecord = Record<string, Effect.Effect<void, unknown, SqlClient>>;
1812
+ type MigrationRecord = Record<string, Effect.Effect<void, SqlError, SqlClient>>;
1813
+ //#endregion
1814
+ //#region src/platform.d.ts
1811
1815
  /**
1812
1816
  * A SQLite connection plus the migrator that brings it to the head of a
1813
1817
  * migration set. Returned by {@link makeSqliteStack}.
@@ -1818,10 +1822,13 @@ export interface SqliteStack {
1818
1822
  readonly SqliteLayer: Layer.Layer<SqliteClient | SqlClient>;
1819
1823
  /**
1820
1824
  * `Layer.effectDiscard`-shaped: provides nothing, runs the migrations as a
1821
- * side effect of layer acquisition. Already fed its `SqlClient` and the
1822
- * Node platform services.
1825
+ * side effect of layer acquisition. Already fed its `SqlClient`. Backed by
1826
+ * `@effected/store`'s `Store.layer` with the engine's ledger options
1827
+ * (adopt and mirror effect/sql's ledger), so a database a 2.x
1828
+ * `SqliteMigrator` migrated keeps its history and a 2.x install can still
1829
+ * open it.
1823
1830
  */
1824
- readonly MigratorLayer: Layer.Layer<never, MigrationError | SqlError>;
1831
+ readonly MigratorLayer: Layer.Layer<never, PlatformLiveError>;
1825
1832
  }
1826
1833
  /**
1827
1834
  * The Node platform services every SQLite stack and every Live layer share.
@@ -1842,6 +1849,12 @@ export declare const NodePlatformLayer: Layer.Layer<NodeServices.NodeServices, n
1842
1849
  * @public
1843
1850
  */
1844
1851
  export declare const makeSqliteStack: (filename: string, migrations?: MigrationRecord) => SqliteStack;
1852
+ /**
1853
+ * What building a SQLite stack, and so `PlatformLive`, can fail with:
1854
+ * `@effected/store`'s setup / ledger-adoption failure or a failing migration.
1855
+ * @public
1856
+ */
1857
+ export type PlatformLiveError = StoreError | StoreMigrationError;
1845
1858
  /**
1846
1859
  * Options for {@link PlatformLive}.
1847
1860
  * @public
@@ -1883,7 +1896,7 @@ export type PlatformServices = DataReader | DataStore | ProjectDiscovery | Histo
1883
1896
  * @param options - database path, env map and optional logging overrides
1884
1897
  * @public
1885
1898
  */
1886
- export declare const PlatformLive: (options: PlatformOptions) => Layer.Layer<PlatformServices, MigrationError | SqlError>;
1899
+ export declare const PlatformLive: (options: PlatformOptions) => Layer.Layer<PlatformServices, PlatformLiveError>;
1887
1900
  //#endregion
1888
1901
  //#region src/programs/end-agent.d.ts
1889
1902
  /**
@@ -1930,6 +1943,20 @@ export declare const SESSIONS_DB_FILENAME = "sessions.db";
1930
1943
  * @public
1931
1944
  */
1932
1945
  export declare const REGISTRY_DB_FILENAME = "registry.db";
1946
+ /**
1947
+ * The global discovery registry's store options: `registry.db` at the app's
1948
+ * XDG data root. `resolveHookPaths` resolves `registryDbPath` from them with
1949
+ * `AppStore.location`; `SidecarPlatformLive` opens that path with their
1950
+ * migrations.
1951
+ *
1952
+ * @internal
1953
+ */
1954
+ export declare const REGISTRY_STORE_OPTIONS: {
1955
+ readonly adoptMigratorLedger: true;
1956
+ readonly filename: "registry.db";
1957
+ readonly directory: "data";
1958
+ readonly migrations: readonly import("@effected/store").StoreMigration[];
1959
+ };
1933
1960
  /**
1934
1961
  * The environment map every hook-path resolver reads from. The front end
1935
1962
  * passes `process.env`; the engine never reads `process` itself.
@@ -2011,17 +2038,17 @@ export interface SidecarPaths {
2011
2038
  /**
2012
2039
  * Build the sidecar Live layer for the supplied SQLite paths.
2013
2040
  *
2014
- * Each store gets its own `SqlClient` connection (separate scopes,
2015
- * independent migrators, all built through the engine's shared
2016
- * `makeSqliteStack`) so concurrent operations on the three stores
2017
- * don't share lock state.
2041
+ * Each store gets its own `SqlClient` connection and its own migration
2042
+ * ledger (`makeSqliteStack` for `data.db`, `Store.layerSqliteAs` for the
2043
+ * session map and the registry), so concurrent operations on the three
2044
+ * stores don't share lock state. Every path in `paths` is opened as given.
2018
2045
  *
2019
2046
  * @param paths - the three SQLite database paths to open
2020
2047
  * @param env - the environment map `RunContextLive` probes for host
2021
2048
  * metadata (the bin passes `process.env`)
2022
2049
  * @public
2023
2050
  */
2024
- export declare const SidecarPlatformLive: (paths: SidecarPaths, env: Record<string, string | undefined>) => Layer.Layer<DataReader | DataStore | DiscoveryRegistry | PerClientSessionMapReader | PerClientSessionMapWriter | RunContext$ | import("@effect/platform-node/NodeServices").NodeServices, import("effect/sql/Migrator").MigrationError | import("effect/sql/SqlError").SqlError, never>;
2051
+ export declare const SidecarPlatformLive: (paths: SidecarPaths, env: Record<string, string | undefined>) => Layer.Layer<DataReader | DataStore | DiscoveryRegistry | PerClientSessionMapReader | PerClientSessionMapWriter | RunContext$ | import("@effect/platform-node/NodeServices").NodeServices, PlatformLiveError, never>;
2025
2052
  //#endregion
2026
2053
  //#region src/programs/record-session.d.ts
2027
2054
  /**
@@ -2756,5 +2783,5 @@ export declare const resolveWorkspaceKey: (projectDir: string) => Effect.Effect<
2756
2783
  /** Build-time injected package version (see architecture.md D36). @public */
2757
2784
  export declare const CURRENT_ENGINE_VERSION: string;
2758
2785
  //#endregion
2759
- export { type ArtifactKind, type ArtifactSuite, type FormatTriageOptions, type FormatWrapupOptions, type Phase, type WrapupKind, migration as migration0001, migration$1 as migration0002, migration$2 as registryMigration0001, migration$3 as sessionMapMigration0001 };
2786
+ export { type ArtifactKind, type ArtifactSuite, type FormatTriageOptions, type FormatWrapupOptions, type MigrationRecord, type Phase, type WrapupKind, migration as migration0001, migration$1 as migration0002, migration$2 as registryMigration0001, migration$3 as sessionMapMigration0001 };
2760
2787
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -39,7 +39,7 @@ import migration$2 from "./migrations/registry_0001_initial.js";
39
39
  import migration$3 from "./migrations/session_map_0001_initial.js";
40
40
  import { NodePlatformLayer, PlatformLive, makeSqliteStack } from "./platform.js";
41
41
  import { endAgentEffect } from "./programs/end-agent.js";
42
- import { DATA_DB_FILENAME, REGISTRY_DB_FILENAME, SESSIONS_DB_FILENAME, resolveHookPaths, resolveSessionMapPath } from "./programs/hook-paths.js";
42
+ import { DATA_DB_FILENAME, REGISTRY_DB_FILENAME, REGISTRY_STORE_OPTIONS, SESSIONS_DB_FILENAME, resolveHookPaths, resolveSessionMapPath } from "./programs/hook-paths.js";
43
43
  import { SidecarPlatformLive } from "./programs/platform-sidecar.js";
44
44
  import { recordSessionEnd, recordSessionStart } from "./programs/record-session.js";
45
45
  import { resolveSessionForRecording } from "./programs/resolve-session-for-recording.js";
@@ -58,4 +58,4 @@ import { DATABASE_FILENAME, resolveDataPath } from "./utils/resolve-data-path.js
58
58
  import { resolveWorkspaceKey } from "./utils/resolve-workspace-key.js";
59
59
  import { CURRENT_ENGINE_VERSION } from "./version.js";
60
60
 
61
- export { APP_NAMESPACE, AgentContext, CURRENT_ENGINE_VERSION, ConfigLive, DATABASE_FILENAME, DATA_DB_FILENAME, DATA_FALLBACK_DIR, DataReader, DataReaderLive, DataStore, DataStoreLive, DetailResolver, DetailResolverLive, DiscoveryRegistry, DiscoveryRegistryLive, EnvironmentDetector, EnvironmentDetectorLive, EnvironmentDetectorTest, ExecutorResolver, ExecutorResolverLive, FormatSelector, FormatSelectorLive, HistoryTracker, HistoryTrackerLive, HistoryTrackerTest, IDEMPOTENCY_ROOT_SENTINEL, INLINE_ATTACHMENT_BODY_CAP_BYTES, LoggerLive, NodePlatformLayer, OutputPipelineLive, PROJECT_MIGRATIONS, PathResolutionLive, PerClientSessionMapReader, PerClientSessionMapReaderLive, PerClientSessionMapWriter, PerClientSessionMapWriterLive, PlatformLive, ProjectDiscovery, ProjectDiscoveryLive, ProjectDiscoveryTest, ProjectIdentity, ProjectIdentityLive, ProjectIdentityTest, REGISTRY_DB_FILENAME, RunContext, RunContext$, RunContextLive, RunContextService, RunContextTest, SESSIONS_DB_FILENAME, SidecarPlatformLive, VitestAgentConfigFile, _resetMigrationCacheForTesting, assembleHistoryRecord, assembleManifest, classifyEnvironment, computeFailureSignature, deriveIdempotencyKey, dispatchRecordTddArtifactEffect, endAgentEffect, ensureMigrated, formatTriageEffect, formatWrapupEffect, historyKey, makeSqliteStack, migration as migration0001, migration$1 as migration0002, normalizeAssertionShape, parseAndValidateTurnPayload, parseSessionEnvExports, recordRunWorkspaceChangesEffect, recordSessionEnd, recordSessionStart, recordTddArtifactByTaskIdEffect, recordTddArtifactEffect, recordTurnEffect, recoverSessionContextFromSessionEnv, registerAgentEffect, migration$2 as registryMigration0001, resolveDataPath, resolveHookPaths, resolveLogFile, resolveLogLevel, resolveProjectDir, resolveProjectIdentityFromCandidates, resolveProjectKeyFromCwd, resolveProjectKeyFromCwdEffect, resolveSessionForRecording, resolveSessionMapPath, resolveWorkspaceKey, migration$3 as sessionMapMigration0001 };
61
+ export { APP_NAMESPACE, AgentContext, CURRENT_ENGINE_VERSION, ConfigLive, DATABASE_FILENAME, DATA_DB_FILENAME, DATA_FALLBACK_DIR, DataReader, DataReaderLive, DataStore, DataStoreLive, DetailResolver, DetailResolverLive, DiscoveryRegistry, DiscoveryRegistryLive, EnvironmentDetector, EnvironmentDetectorLive, EnvironmentDetectorTest, ExecutorResolver, ExecutorResolverLive, FormatSelector, FormatSelectorLive, HistoryTracker, HistoryTrackerLive, HistoryTrackerTest, IDEMPOTENCY_ROOT_SENTINEL, INLINE_ATTACHMENT_BODY_CAP_BYTES, LoggerLive, NodePlatformLayer, OutputPipelineLive, PROJECT_MIGRATIONS, PathResolutionLive, PerClientSessionMapReader, PerClientSessionMapReaderLive, PerClientSessionMapWriter, PerClientSessionMapWriterLive, PlatformLive, ProjectDiscovery, ProjectDiscoveryLive, ProjectDiscoveryTest, ProjectIdentity, ProjectIdentityLive, ProjectIdentityTest, REGISTRY_DB_FILENAME, REGISTRY_STORE_OPTIONS, RunContext, RunContext$, RunContextLive, RunContextService, RunContextTest, SESSIONS_DB_FILENAME, SidecarPlatformLive, VitestAgentConfigFile, _resetMigrationCacheForTesting, assembleHistoryRecord, assembleManifest, classifyEnvironment, computeFailureSignature, deriveIdempotencyKey, dispatchRecordTddArtifactEffect, endAgentEffect, ensureMigrated, formatTriageEffect, formatWrapupEffect, historyKey, makeSqliteStack, migration as migration0001, migration$1 as migration0002, normalizeAssertionShape, parseAndValidateTurnPayload, parseSessionEnvExports, recordRunWorkspaceChangesEffect, recordSessionEnd, recordSessionStart, recordTddArtifactByTaskIdEffect, recordTddArtifactEffect, recordTurnEffect, recoverSessionContextFromSessionEnv, registerAgentEffect, migration$2 as registryMigration0001, resolveDataPath, resolveHookPaths, resolveLogFile, resolveLogLevel, resolveProjectDir, resolveProjectIdentityFromCandidates, resolveProjectKeyFromCwd, resolveProjectKeyFromCwdEffect, resolveSessionForRecording, resolveSessionMapPath, resolveWorkspaceKey, migration$3 as sessionMapMigration0001 };
@@ -8,8 +8,9 @@ import migration$1 from "./0002_test_artifacts.js";
8
8
  *
9
9
  * This is the single source of truth for the project database's migration
10
10
  * set: `makeSqliteStack` (and through it `PlatformLive`, `ensureMigrated`,
11
- * the testing layers, `ReporterLive` and `SidecarLive`) defaults to it when
12
- * calling `SqliteMigrator.fromRecord`, so adding a migration file and
11
+ * the testing layers, `ReporterLive` and `SidecarLive`) defaults to it and
12
+ * runs it through `@effected/store` (keys parsed as effect/sql's
13
+ * `fromRecord` parses them, so 2.x ledgers adopt), so adding a migration file and
13
14
  * registering it here is enough to reach every process that opens a project
14
15
  * database.
15
16
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitest-agent/engine",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "private": false,
5
5
  "description": "Shared services, layers, SQLite data layer, migrations and platform resolution for the vitest-agent CLI and MCP server.",
6
6
  "keywords": [
@@ -42,12 +42,14 @@
42
42
  "dependencies": {
43
43
  "@effect/platform-node": "^4.0.0",
44
44
  "@effect/sql-sqlite-node": "^4.0.0",
45
- "@effected/cli": "^0.11.0",
46
- "@effected/config-file": "^0.14.0",
45
+ "@effected/app": "^0.21.1",
46
+ "@effected/cli": "^0.12.0",
47
+ "@effected/config-file": "^0.14.2",
47
48
  "@effected/engine": "^0.3.0",
48
49
  "@effected/env": "^0.1.0",
49
50
  "@effected/glob": "^0.10.0",
50
51
  "@effected/jsonc": "^0.15.0",
52
+ "@effected/store": "^0.13.0",
51
53
  "@effected/toml": "^0.11.0",
52
54
  "@effected/walker": "^0.15.0",
53
55
  "@effected/workspaces": "^0.31.0",
package/platform.js CHANGED
@@ -5,10 +5,11 @@ import { LoggerLive } from "./layers/LoggerLive.js";
5
5
  import { OutputPipelineLive } from "./layers/OutputPipelineLive.js";
6
6
  import { ProjectDiscoveryLive } from "./layers/ProjectDiscoveryLive.js";
7
7
  import { PROJECT_MIGRATIONS } from "./migrations/index.js";
8
- import { Layer } from "effect";
8
+ import { LEDGER_OPTIONS, toStoreMigrations } from "./stores.js";
9
+ import { Effect, Layer } from "effect";
9
10
  import * as NodeServices from "@effect/platform-node/NodeServices";
10
11
  import { layer } from "@effect/sql-sqlite-node/SqliteClient";
11
- import * as SqliteMigrator from "@effect/sql-sqlite-node/SqliteMigrator";
12
+ import { Store } from "@effected/store";
12
13
 
13
14
  //#region src/platform.ts
14
15
  /**
@@ -33,7 +34,10 @@ const makeSqliteStack = (filename, migrations = PROJECT_MIGRATIONS) => {
33
34
  const SqliteLayer = layer({ filename });
34
35
  return {
35
36
  SqliteLayer,
36
- MigratorLayer: SqliteMigrator.layer({ loader: SqliteMigrator.fromRecord(migrations) }).pipe(Layer.provide(Layer.merge(SqliteLayer, NodePlatformLayer)))
37
+ MigratorLayer: Layer.effectDiscard(Effect.void).pipe(Layer.provide(Store.layer({
38
+ migrations: toStoreMigrations(migrations),
39
+ ...LEDGER_OPTIONS
40
+ }).pipe(Layer.provide(SqliteLayer))))
37
41
  };
38
42
  };
39
43
  /**
@@ -1,7 +1,10 @@
1
1
  import { APP_NAMESPACE, DATA_FALLBACK_DIR } from "../layers/PathResolutionLive.js";
2
+ import migration from "../migrations/registry_0001_initial.js";
3
+ import { LEDGER_OPTIONS, toStoreMigrations } from "../stores.js";
2
4
  import { ProjectIdentityNotResolvableError } from "@vitest-agent/sdk";
3
5
  import { ConfigProvider, Effect, FileSystem, Layer, Path } from "effect";
4
6
  import { AppDirs, Xdg } from "@effected/xdg";
7
+ import { AppStore } from "@effected/app";
5
8
 
6
9
  //#region src/programs/hook-paths.ts
7
10
  /**
@@ -22,6 +25,20 @@ const SESSIONS_DB_FILENAME = "sessions.db";
22
25
  * @public
23
26
  */
24
27
  const REGISTRY_DB_FILENAME = "registry.db";
28
+ /**
29
+ * The global discovery registry's store options: `registry.db` at the app's
30
+ * XDG data root. `resolveHookPaths` resolves `registryDbPath` from them with
31
+ * `AppStore.location`; `SidecarPlatformLive` opens that path with their
32
+ * migrations.
33
+ *
34
+ * @internal
35
+ */
36
+ const REGISTRY_STORE_OPTIONS = {
37
+ filename: REGISTRY_DB_FILENAME,
38
+ directory: "data",
39
+ migrations: toStoreMigrations({ "0001_initial": migration }),
40
+ ...LEDGER_OPTIONS
41
+ };
25
42
  /** Directory under the home dir that holds the per-client `sessions.db` fallback. */
26
43
  const SESSION_MAP_HOME_DIR = `.${APP_NAMESPACE}`;
27
44
  const nonEmpty = (value) => value !== void 0 && value.length > 0 ? value : void 0;
@@ -32,6 +49,7 @@ const nonEmpty = (value) => value !== void 0 && value.length > 0 ? value : void
32
49
  * `ConfigProvider`, so the env map is installed as that provider — no
33
50
  * `process.env` read. `USERPROFILE` stands in for `HOME` when the latter is
34
51
  * unset (Windows), matching the session-map fallback order below.
52
+ *
35
53
  */
36
54
  const hookAppDirs = (env) => {
37
55
  const home = nonEmpty(env.HOME) ?? nonEmpty(env.USERPROFILE);
@@ -100,10 +118,10 @@ const resolveHookPaths = (input) => Effect.gen(function* () {
100
118
  dataRoot,
101
119
  projectDataDir,
102
120
  perProjectDbPath: path.join(projectDataDir, DATA_DB_FILENAME),
103
- registryDbPath: path.join(dataRoot, REGISTRY_DB_FILENAME),
121
+ registryDbPath: yield* AppStore.location(REGISTRY_STORE_OPTIONS),
104
122
  sessionMapDbPath
105
123
  };
106
124
  }).pipe(Effect.provide(hookAppDirs(input.env)));
107
125
 
108
126
  //#endregion
109
- export { DATA_DB_FILENAME, REGISTRY_DB_FILENAME, SESSIONS_DB_FILENAME, resolveHookPaths, resolveSessionMapPath };
127
+ export { DATA_DB_FILENAME, REGISTRY_DB_FILENAME, REGISTRY_STORE_OPTIONS, SESSIONS_DB_FILENAME, resolveHookPaths, resolveSessionMapPath };
@@ -4,19 +4,21 @@ import { DiscoveryRegistryLive } from "../layers/DiscoveryRegistryLive.js";
4
4
  import { LoggerLive } from "../layers/LoggerLive.js";
5
5
  import { PerClientSessionMapWriterLive } from "../layers/PerClientSessionMapLive.js";
6
6
  import { RunContextLive } from "../layers/RunContextLive.js";
7
- import migration from "../migrations/registry_0001_initial.js";
8
- import migration$1 from "../migrations/session_map_0001_initial.js";
7
+ import migration from "../migrations/session_map_0001_initial.js";
8
+ import { LEDGER_OPTIONS, RegistryStore, SessionMapStore, toStoreMigrations } from "../stores.js";
9
9
  import { NodePlatformLayer, makeSqliteStack } from "../platform.js";
10
+ import { REGISTRY_STORE_OPTIONS } from "./hook-paths.js";
10
11
  import { Layer } from "effect";
12
+ import { Store } from "@effected/store";
11
13
 
12
14
  //#region src/programs/platform-sidecar.ts
13
15
  /**
14
16
  * Build the sidecar Live layer for the supplied SQLite paths.
15
17
  *
16
- * Each store gets its own `SqlClient` connection (separate scopes,
17
- * independent migrators, all built through the engine's shared
18
- * `makeSqliteStack`) so concurrent operations on the three stores
19
- * don't share lock state.
18
+ * Each store gets its own `SqlClient` connection and its own migration
19
+ * ledger (`makeSqliteStack` for `data.db`, `Store.layerSqliteAs` for the
20
+ * session map and the registry), so concurrent operations on the three
21
+ * stores don't share lock state. Every path in `paths` is opened as given.
20
22
  *
21
23
  * @param paths - the three SQLite database paths to open
22
24
  * @param env - the environment map `RunContextLive` probes for host
@@ -26,10 +28,16 @@ import { Layer } from "effect";
26
28
  const SidecarPlatformLive = (paths, env) => {
27
29
  const project = makeSqliteStack(paths.perProjectDbPath);
28
30
  const ProjectStoreLayer = Layer.mergeAll(DataStoreLive.pipe(Layer.provide(project.SqliteLayer)), DataReaderLive.pipe(Layer.provide(project.SqliteLayer)), project.MigratorLayer);
29
- const sessionMap = makeSqliteStack(paths.sessionMapDbPath, { "0001_initial": migration$1 });
30
- const SessionMapLayer = Layer.mergeAll(PerClientSessionMapWriterLive.pipe(Layer.provide(sessionMap.SqliteLayer)), sessionMap.MigratorLayer);
31
- const registry = makeSqliteStack(paths.registryDbPath, { "0001_initial": migration });
32
- const RegistryLayer = Layer.mergeAll(DiscoveryRegistryLive.pipe(Layer.provide(registry.SqliteLayer)), registry.MigratorLayer);
31
+ const SessionMapLayer = PerClientSessionMapWriterLive.pipe(Layer.provide(Store.sqlClient(SessionMapStore)), Layer.provide(Store.layerSqliteAs(SessionMapStore, {
32
+ filename: paths.sessionMapDbPath,
33
+ migrations: toStoreMigrations({ "0001_initial": migration }),
34
+ ...LEDGER_OPTIONS
35
+ })));
36
+ const RegistryLayer = DiscoveryRegistryLive.pipe(Layer.provide(Store.sqlClient(RegistryStore)), Layer.provide(Store.layerSqliteAs(RegistryStore, {
37
+ filename: paths.registryDbPath,
38
+ migrations: REGISTRY_STORE_OPTIONS.migrations,
39
+ ...LEDGER_OPTIONS
40
+ })));
33
41
  return Layer.mergeAll(ProjectStoreLayer, SessionMapLayer, RegistryLayer, RunContextLive(env)).pipe(Layer.provideMerge(NodePlatformLayer), Layer.provideMerge(LoggerLive()));
34
42
  };
35
43
 
package/stores.js ADDED
@@ -0,0 +1,43 @@
1
+ import { Context, Effect } from "effect";
2
+ import { SqlClient } from "effect/sql/SqlClient";
3
+
4
+ //#region src/stores.ts
5
+ /**
6
+ * The ledger options every store opens with: adopt a 2.x effect/sql ledger
7
+ * once, on the first open.
8
+ *
9
+ * @internal
10
+ */
11
+ const LEDGER_OPTIONS = { adoptMigratorLedger: true };
12
+ /**
13
+ * Convert a {@link MigrationRecord} to the `StoreMigration` list `Store` runs,
14
+ * parsing each key exactly as effect/sql's `Migrator.fromRecord` does
15
+ * (`/^(\d+)_(.+)$/`: `"0001_initial"` → id `1`, name `"initial"`), so the ids
16
+ * and names line up with an adopted `effect_sql_migrations` ledger. A key that
17
+ * does not match is skipped, as effect/sql skips it.
18
+ *
19
+ * @internal
20
+ */
21
+ const toStoreMigrations = (migrations) => Object.entries(migrations).flatMap(([key, migration]) => {
22
+ const match = key.match(/^(\d+)_(.+)$/);
23
+ if (match === null) return [];
24
+ const [, id, name] = match;
25
+ return [{
26
+ id: Number(id),
27
+ name,
28
+ up: (sql) => Effect.provideService(migration, SqlClient, sql)
29
+ }];
30
+ }).sort((a, b) => a.id - b.id);
31
+ /**
32
+ * The global discovery registry (`<XDG data>/vitest-agent/registry.db`).
33
+ * @internal
34
+ */
35
+ var RegistryStore = class extends Context.Service()("vitest-agent/RegistryStore") {};
36
+ /**
37
+ * The per-client session map (`sessions.db`, under the host's plugin data dir).
38
+ * @internal
39
+ */
40
+ var SessionMapStore = class extends Context.Service()("vitest-agent/SessionMapStore") {};
41
+
42
+ //#endregion
43
+ export { LEDGER_OPTIONS, RegistryStore, SessionMapStore, toStoreMigrations };
package/testing.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import { Agent, Agent as Agent$1, AgentId, AgentNotFoundError, AgentNotFoundError as AgentNotFoundError$1, AgentReport, AgentReport as AgentReport$1, ArtifactKind, ArtifactKind as ArtifactKind$1, ArtifactKind as ArtifactKind$2, ArtifactSuite, ArtifactSuite as ArtifactSuite$1, ArtifactSuite as ArtifactSuite$2, BehaviorDetail, BehaviorDetail as BehaviorDetail$1, BehaviorNotFoundError, BehaviorNotFoundError as BehaviorNotFoundError$1, BehaviorRow, BehaviorRow as BehaviorRow$1, BehaviorStatus, BehaviorStatus as BehaviorStatus$1, CacheManifest, CacheManifest as CacheManifest$1, ChatId, CitedArtifact, CitedArtifact as CitedArtifact$1, CoverageBaselines, CoverageBaselines as CoverageBaselines$1, CoverageReport, CoverageReport as CoverageReport$1, DataStoreError, DataStoreError as DataStoreError$1, FileCoverageReport, FileCoverageReport as FileCoverageReport$1, GoalDetail, GoalDetail as GoalDetail$1, GoalNotFoundError, GoalNotFoundError as GoalNotFoundError$1, GoalRow, GoalRow as GoalRow$1, GoalStatus, GoalStatus as GoalStatus$1, HistoryRecord, HistoryRecord as HistoryRecord$1, IdempotencyHit, IdempotencyHit as IdempotencyHit$1, IllegalStatusTransitionEntity, IllegalStatusTransitionError, IllegalStatusTransitionError as IllegalStatusTransitionError$1, Phase, Phase as Phase$1, RegistrationConflictError, RegistrationConflictError as RegistrationConflictError$1, ResolvedThresholds, ResolvedThresholds as ResolvedThresholds$1, TddTaskAlreadyEndedError, TddTaskAlreadyEndedError as TddTaskAlreadyEndedError$1, TddTaskEndOutcome, TddTaskNotFoundError, TddTaskNotFoundError as TddTaskNotFoundError$1, TrendEntry, TrendEntry as TrendEntry$1, TrendRecord, TrendRecord as TrendRecord$1 } from "@vitest-agent/sdk";
2
2
  import { Context, Effect, Layer, Option } from "effect";
3
+ import "@effect/platform-node/NodeServices";
4
+ import "@effect/sql-sqlite-node/SqliteClient";
5
+ import { StoreError, StoreMigrationError } from "@effected/store";
6
+ import "effect/sql/SqlClient";
7
+ import "effect/sql/SqlError";
3
8
  //#region src/services/DataStore.d.ts
4
9
  /** @public */
5
10
  interface CreateGoalInput {
@@ -1057,6 +1062,14 @@ declare const DataReader_base: Context.ServiceClass<DataReader, "vitest-agent/Da
1057
1062
  /** @public */
1058
1063
  export declare class DataReader extends DataReader_base {}
1059
1064
  //#endregion
1065
+ //#region src/platform.d.ts
1066
+ /**
1067
+ * What building a SQLite stack, and so `PlatformLive`, can fail with:
1068
+ * `@effected/store`'s setup / ledger-adoption failure or a failing migration.
1069
+ * @public
1070
+ */
1071
+ type PlatformLiveError = StoreError | StoreMigrationError;
1072
+ //#endregion
1060
1073
  //#region src/migrations/index.d.ts
1061
1074
  /**
1062
1075
  * Every migration that must run against a per-project `data.db`, keyed by
@@ -1064,8 +1077,9 @@ export declare class DataReader extends DataReader_base {}
1064
1077
  *
1065
1078
  * This is the single source of truth for the project database's migration
1066
1079
  * set: `makeSqliteStack` (and through it `PlatformLive`, `ensureMigrated`,
1067
- * the testing layers, `ReporterLive` and `SidecarLive`) defaults to it when
1068
- * calling `SqliteMigrator.fromRecord`, so adding a migration file and
1080
+ * the testing layers, `ReporterLive` and `SidecarLive`) defaults to it and
1081
+ * runs it through `@effected/store` (keys parsed as effect/sql's
1082
+ * `fromRecord` parses them, so 2.x ledgers adopt), so adding a migration file and
1069
1083
  * registering it here is enough to reach every process that opens a project
1070
1084
  * database.
1071
1085
  *
@@ -1081,21 +1095,21 @@ export declare const PROJECT_MIGRATIONS: {
1081
1095
  //#endregion
1082
1096
  //#region src/testing/layers.d.ts
1083
1097
  /** @public */
1084
- export declare function makeTestLayer(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, import("effect/sql/Migrator").MigrationError | import("effect/sql/SqlError").SqlError, never>;
1098
+ export declare function makeTestLayer(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, PlatformLiveError, never>;
1085
1099
  /** @public */
1086
- export declare const DataStoreTestLayer: Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, import("effect/sql/Migrator").MigrationError | import("effect/sql/SqlError").SqlError, never>;
1100
+ export declare const DataStoreTestLayer: Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, PlatformLiveError, never>;
1087
1101
  //#endregion
1088
1102
  //#region src/testing/index.d.ts
1089
1103
  /** @public */
1090
- export declare function empty(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, import("effect/sql/Migrator").MigrationError | import("effect/sql/SqlError").SqlError, never>;
1104
+ export declare function empty(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, PlatformLiveError, never>;
1091
1105
  /** @public */
1092
- export declare function singlePassingRun(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, import("@vitest-agent/sdk").DataStoreError | import("effect/sql/Migrator").MigrationError | import("effect/sql/SqlError").SqlError, never>;
1106
+ export declare function singlePassingRun(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, import("@vitest-agent/sdk").DataStoreError | PlatformLiveError, never>;
1093
1107
  /** @public */
1094
- export declare function withFailures(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, import("@vitest-agent/sdk").DataStoreError | import("effect/sql/Migrator").MigrationError | import("effect/sql/SqlError").SqlError, never>;
1108
+ export declare function withFailures(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, import("@vitest-agent/sdk").DataStoreError | PlatformLiveError, never>;
1095
1109
  /** @public */
1096
- export declare function flaky(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, import("@vitest-agent/sdk").DataStoreError | import("effect/sql/Migrator").MigrationError | import("effect/sql/SqlError").SqlError, never>;
1110
+ export declare function flaky(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, import("@vitest-agent/sdk").DataStoreError | PlatformLiveError, never>;
1097
1111
  /** @public */
1098
- export declare function withTddTask(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, import("@vitest-agent/sdk").BehaviorNotFoundError | import("@vitest-agent/sdk").DataStoreError | import("@vitest-agent/sdk").GoalNotFoundError | import("@vitest-agent/sdk").IllegalStatusTransitionError | import("effect/sql/Migrator").MigrationError | import("effect/sql/SqlError").SqlError | import("@vitest-agent/sdk").TddTaskAlreadyEndedError | import("@vitest-agent/sdk").TddTaskNotFoundError, never>;
1112
+ export declare function withTddTask(filename: string): Layer.Layer<DataReader | DataStore | import("effect/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, import("@vitest-agent/sdk").BehaviorNotFoundError | import("@vitest-agent/sdk").DataStoreError | import("@vitest-agent/sdk").GoalNotFoundError | import("@vitest-agent/sdk").IllegalStatusTransitionError | import("@vitest-agent/sdk").TddTaskAlreadyEndedError | import("@vitest-agent/sdk").TddTaskNotFoundError | PlatformLiveError, never>;
1099
1113
  //#endregion
1100
- export { type AcceptanceMetrics, Agent, AgentId, AgentNotFoundError, AgentReport, type ArtifactKind, type ArtifactSuite, type AssociateRunSessionInput, BehaviorDetail, BehaviorNotFoundError, BehaviorRow, BehaviorStatus, CacheManifest, type ChangeKind, ChatId, type CitedArtifact, type CitedArtifactRow, type ClassificationQueryOptions, type CommitChangesEntry, CoverageBaselines, CoverageReport, type CreateBehaviorInput, type CreateGoalInput, type CurrentTddPhase, DataStoreError, type EndTddTaskInput, type FailureSignatureDetail, type FailureSignatureWriteInput, type FileCoverageInput, FileCoverageReport, type FlakyTest, GoalDetail, GoalNotFoundError, GoalRow, GoalStatus, type HistoryQueryOptions, HistoryRecord, type HypothesisDetail, type HypothesisInput, IdempotencyHit, type IdempotentResponseInput, type IllegalStatusTransitionEntity, IllegalStatusTransitionError, type ModuleInput, type ModuleListEntry, type NoteInput, type NoteRow, type PersistedAttachment, type PersistentFailure, type Phase, type ProjectRunSummary, type RegisterAgentInput, RegistrationConflictError, type ResolvedThresholds, type RunChangedFile, type RunInvocationMethod, type SessionDetail, type SessionInput, type SettingsInput, type SettingsListEntry, type SettingsRow, type StackFrameInput, type SuiteInput, type SuiteListEntry, type TagInventoryRow, type TddArtifactDetail, type TddArtifactRow, type TddPhaseDetail, TddTaskAlreadyEndedError, type TddTaskDetail, type TddTaskEndOutcome, type TddTaskInput, TddTaskNotFoundError, type TddTaskSummary, type TestAnnotationInput, type TestAnnotationRow, type TestArtifactInput, type TestArtifactQueryOptions, type TestArtifactRow, type TestAttachmentInput, type TestCaseInput, type TestError, type TestErrorInput, type TestListEntry, type TestLookupOptions, type TestRunInput, TrendEntry, TrendRecord, type TurnInput, type TurnSearchOptions, type TurnSummary, type UpdateBehaviorInput, type UpdateGoalInput, type ValidateHypothesisInput, type WriteCommitInput, type WriteRunChangedFilesInput, type WriteTddArtifactInput, type WriteTddPhaseInput, type WriteTddPhaseOutput };
1114
+ export { type AcceptanceMetrics, Agent, AgentId, AgentNotFoundError, AgentReport, type ArtifactKind, type ArtifactSuite, type AssociateRunSessionInput, BehaviorDetail, BehaviorNotFoundError, BehaviorRow, BehaviorStatus, CacheManifest, type ChangeKind, ChatId, type CitedArtifact, type CitedArtifactRow, type ClassificationQueryOptions, type CommitChangesEntry, CoverageBaselines, CoverageReport, type CreateBehaviorInput, type CreateGoalInput, type CurrentTddPhase, DataStoreError, type EndTddTaskInput, type FailureSignatureDetail, type FailureSignatureWriteInput, type FileCoverageInput, FileCoverageReport, type FlakyTest, GoalDetail, GoalNotFoundError, GoalRow, GoalStatus, type HistoryQueryOptions, HistoryRecord, type HypothesisDetail, type HypothesisInput, IdempotencyHit, type IdempotentResponseInput, type IllegalStatusTransitionEntity, IllegalStatusTransitionError, type ModuleInput, type ModuleListEntry, type NoteInput, type NoteRow, type PersistedAttachment, type PersistentFailure, type Phase, type PlatformLiveError, type ProjectRunSummary, type RegisterAgentInput, RegistrationConflictError, type ResolvedThresholds, type RunChangedFile, type RunInvocationMethod, type SessionDetail, type SessionInput, type SettingsInput, type SettingsListEntry, type SettingsRow, type StackFrameInput, type SuiteInput, type SuiteListEntry, type TagInventoryRow, type TddArtifactDetail, type TddArtifactRow, type TddPhaseDetail, TddTaskAlreadyEndedError, type TddTaskDetail, type TddTaskEndOutcome, type TddTaskInput, TddTaskNotFoundError, type TddTaskSummary, type TestAnnotationInput, type TestAnnotationRow, type TestArtifactInput, type TestArtifactQueryOptions, type TestArtifactRow, type TestAttachmentInput, type TestCaseInput, type TestError, type TestErrorInput, type TestListEntry, type TestLookupOptions, type TestRunInput, TrendEntry, TrendRecord, type TurnInput, type TurnSearchOptions, type TurnSummary, type UpdateBehaviorInput, type UpdateGoalInput, type ValidateHypothesisInput, type WriteCommitInput, type WriteRunChangedFilesInput, type WriteTddArtifactInput, type WriteTddPhaseInput, type WriteTddPhaseOutput };
1101
1115
  //# sourceMappingURL=testing.d.ts.map
package/version.js CHANGED
@@ -1,6 +1,6 @@
1
1
  //#region src/version.ts
2
2
  /** Build-time injected package version (see architecture.md D36). @public */
3
- const CURRENT_ENGINE_VERSION = "0.5.0";
3
+ const CURRENT_ENGINE_VERSION = "0.6.0";
4
4
 
5
5
  //#endregion
6
6
  export { CURRENT_ENGINE_VERSION };