@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 +44 -17
- package/index.js +2 -2
- package/migrations/index.js +3 -2
- package/package.json +5 -3
- package/platform.js +7 -3
- package/programs/hook-paths.js +20 -2
- package/programs/platform-sidecar.js +18 -10
- package/stores.js +43 -0
- package/testing.d.ts +24 -10
- package/version.js +1 -1
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 {
|
|
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
|
|
1769
|
-
*
|
|
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/
|
|
1805
|
+
//#region src/stores.d.ts
|
|
1805
1806
|
/**
|
|
1806
|
-
* A migration set in the shape `
|
|
1807
|
-
*
|
|
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
|
-
|
|
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
|
|
1822
|
-
*
|
|
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,
|
|
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,
|
|
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
|
|
2015
|
-
*
|
|
2016
|
-
*
|
|
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,
|
|
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 };
|
package/migrations/index.js
CHANGED
|
@@ -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
|
|
12
|
-
*
|
|
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.
|
|
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/
|
|
46
|
-
"@effected/
|
|
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 {
|
|
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
|
|
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:
|
|
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
|
/**
|
package/programs/hook-paths.js
CHANGED
|
@@ -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:
|
|
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/
|
|
8
|
-
import
|
|
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
|
|
17
|
-
*
|
|
18
|
-
*
|
|
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
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
1068
|
-
*
|
|
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,
|
|
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,
|
|
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,
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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("
|
|
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