@vitest-agent/plugin 1.1.9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +4 -4
- package/layers/CoverageAnalyzerLive.js +1 -1
- package/layers/ReporterLive.js +2 -2
- package/package.json +12 -17
- package/plugin.js +2 -2
- package/reporter.js +9 -9
- package/services/ConfigValidation.js +1 -1
- package/services/CoverageAnalyzer.js +1 -1
- package/tsdoc-metadata.json +1 -1
- package/utils/discover-projects.js +7 -3
package/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { Context, Effect, Layer, LogLevel, Option } from "effect";
|
|
|
4
4
|
import { TestProjectInlineConfiguration } from "vitest/config";
|
|
5
5
|
import { ResolvedConfig, VitestPluginContext } from "vitest/node";
|
|
6
6
|
import { SourceMap } from "magic-string";
|
|
7
|
-
import * as
|
|
7
|
+
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
8
8
|
import * as SqliteMigrator from "@effect/sql-sqlite-node/SqliteMigrator";
|
|
9
9
|
//#region src/utils/tag.d.ts
|
|
10
10
|
/**
|
|
@@ -992,7 +992,7 @@ declare function findTestFiles(dir: string, patterns: ReadonlyArray<string>): Pr
|
|
|
992
992
|
* Composition layer for a single `AgentReporter` run. Wires SQLite, migrations, and all service layers.
|
|
993
993
|
* @public
|
|
994
994
|
*/
|
|
995
|
-
declare const ReporterLive: (dbPath: string, logLevel?: LogLevel.LogLevel, logFile?: string) => Layer.Layer<CoverageAnalyzer | import("@vitest-agent/sdk").DataReader | import("@vitest-agent/sdk").DataStore | import("@vitest-agent/sdk").DetailResolver | import("@vitest-agent/sdk").EnvironmentDetector | import("@vitest-agent/sdk").ExecutorResolver | import("@vitest-agent/sdk").FormatSelector | import("@vitest-agent/sdk").HistoryTracker | import("@vitest-agent/sdk").OutputRenderer | import("
|
|
995
|
+
declare const ReporterLive: (dbPath: string, logLevel?: LogLevel.LogLevel, logFile?: string) => Layer.Layer<CoverageAnalyzer | import("@vitest-agent/sdk").DataReader | import("@vitest-agent/sdk").DataStore | import("@vitest-agent/sdk").DetailResolver | import("@vitest-agent/sdk").EnvironmentDetector | import("@vitest-agent/sdk").ExecutorResolver | import("@vitest-agent/sdk").FormatSelector | import("@vitest-agent/sdk").HistoryTracker | import("@vitest-agent/sdk").OutputRenderer | import("effect/unstable/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | NodeServices.NodeServices, SqliteMigrator.MigrationError | import("effect/unstable/sql/SqlError").SqlError, never>;
|
|
996
996
|
//#endregion
|
|
997
997
|
//#region src/services/CoverageAnalyzer.d.ts
|
|
998
998
|
/**
|
|
@@ -1010,7 +1010,7 @@ interface CoverageOptions {
|
|
|
1010
1010
|
/** When true, include files with zero coverage rather than omitting them. */
|
|
1011
1011
|
readonly includeBareZero: boolean;
|
|
1012
1012
|
}
|
|
1013
|
-
declare const CoverageAnalyzer_base: Context.
|
|
1013
|
+
declare const CoverageAnalyzer_base: Context.ServiceClass<CoverageAnalyzer, "vitest-agent/CoverageAnalyzer", {
|
|
1014
1014
|
readonly process: (coverage: unknown, options: CoverageOptions) => Effect.Effect<Option.Option<CoverageReport>>;
|
|
1015
1015
|
readonly processScoped: (coverage: unknown, options: CoverageOptions, testedFiles: ReadonlyArray<string>) => Effect.Effect<Option.Option<CoverageReport>>;
|
|
1016
1016
|
}>;
|
|
@@ -1082,7 +1082,7 @@ interface ValidationInput {
|
|
|
1082
1082
|
readonly vitestConfig: ResolvedConfig;
|
|
1083
1083
|
readonly pluginOptions: AgentPluginOptions;
|
|
1084
1084
|
}
|
|
1085
|
-
declare const ConfigValidation_base: Context.
|
|
1085
|
+
declare const ConfigValidation_base: Context.ServiceClass<ConfigValidation, "vitest-agent/ConfigValidation", {
|
|
1086
1086
|
readonly validate: (input: ValidationInput) => Effect.Effect<ValidationResult, never, never>;
|
|
1087
1087
|
}>;
|
|
1088
1088
|
/**
|
|
@@ -35,7 +35,7 @@ function matchGlob(filePath, pattern) {
|
|
|
35
35
|
* overrides first, falling back to global thresholds.
|
|
36
36
|
*/
|
|
37
37
|
function resolveEffectiveThresholds(filePath, resolved) {
|
|
38
|
-
for (const [pattern, metrics] of resolved.patterns) if (matchGlob(filePath, pattern)) return metrics;
|
|
38
|
+
for (const [pattern, metrics] of resolved.patterns ?? []) if (matchGlob(filePath, pattern)) return metrics;
|
|
39
39
|
return resolved.global;
|
|
40
40
|
}
|
|
41
41
|
/**
|
package/layers/ReporterLive.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CoverageAnalyzerLive } from "./CoverageAnalyzerLive.js";
|
|
2
2
|
import { DataReaderLive, DataStoreLive, HistoryTrackerLive, LoggerLive, OutputPipelineLive, migration0001 } from "@vitest-agent/sdk";
|
|
3
3
|
import { Layer } from "effect";
|
|
4
|
-
import * as
|
|
4
|
+
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
5
5
|
import { layer } from "@effect/sql-sqlite-node/SqliteClient";
|
|
6
6
|
import * as SqliteMigrator from "@effect/sql-sqlite-node/SqliteMigrator";
|
|
7
7
|
|
|
@@ -12,7 +12,7 @@ import * as SqliteMigrator from "@effect/sql-sqlite-node/SqliteMigrator";
|
|
|
12
12
|
*/
|
|
13
13
|
const ReporterLive = (dbPath, logLevel, logFile) => {
|
|
14
14
|
const SqliteLayer = layer({ filename: dbPath });
|
|
15
|
-
const PlatformLayer =
|
|
15
|
+
const PlatformLayer = NodeServices.layer;
|
|
16
16
|
const MigratorLayer = SqliteMigrator.layer({ loader: SqliteMigrator.fromRecord({ "0001_initial": migration0001 }) }).pipe(Layer.provide(Layer.merge(SqliteLayer, PlatformLayer)));
|
|
17
17
|
return Layer.mergeAll(DataStoreLive, CoverageAnalyzerLive, HistoryTrackerLive, OutputPipelineLive).pipe(Layer.provideMerge(DataReaderLive), Layer.provideMerge(MigratorLayer), Layer.provideMerge(SqliteLayer), Layer.provideMerge(PlatformLayer), Layer.provideMerge(LoggerLive(logLevel, logFile)));
|
|
18
18
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest-agent/plugin",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Vitest plugin for the vitest-agent ecosystem: owns persistence, classification, baselines, trends, and dispatches rendering to a configurable reporter.",
|
|
6
6
|
"keywords": [
|
|
@@ -33,26 +33,21 @@
|
|
|
33
33
|
"exports": {
|
|
34
34
|
".": {
|
|
35
35
|
"types": "./index.d.ts",
|
|
36
|
-
"import": "./index.js"
|
|
36
|
+
"import": "./index.js",
|
|
37
|
+
"default": "./index.js"
|
|
37
38
|
},
|
|
38
39
|
"./package.json": "./package.json"
|
|
39
40
|
},
|
|
40
41
|
"dependencies": {
|
|
41
|
-
"@effect/
|
|
42
|
-
"@effect/
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"@vitest-agent/mcp": "1.3.6",
|
|
51
|
-
"@vitest-agent/reporter": "1.0.8",
|
|
52
|
-
"@vitest-agent/sdk": "1.3.4",
|
|
53
|
-
"effect": "^3.21.4",
|
|
54
|
-
"magic-string": "^0.30.21",
|
|
55
|
-
"workspaces-effect": "^2.1.0"
|
|
42
|
+
"@effect/platform-node": "4.0.0-beta.98",
|
|
43
|
+
"@effect/sql-sqlite-node": "4.0.0-beta.98",
|
|
44
|
+
"@effected/workspaces": "^0.3.1",
|
|
45
|
+
"@vitest-agent/cli": "2.0.0",
|
|
46
|
+
"@vitest-agent/mcp": "2.0.0",
|
|
47
|
+
"@vitest-agent/reporter": "2.0.0",
|
|
48
|
+
"@vitest-agent/sdk": "2.0.0",
|
|
49
|
+
"effect": "4.0.0-beta.98",
|
|
50
|
+
"magic-string": "^1.0.0"
|
|
56
51
|
},
|
|
57
52
|
"peerDependencies": {
|
|
58
53
|
"@vitest/coverage-istanbul": "^4.1.0",
|
package/plugin.js
CHANGED
|
@@ -98,7 +98,7 @@ const aggregatedReporterByVitest = /* @__PURE__ */ new WeakSet();
|
|
|
98
98
|
*
|
|
99
99
|
* @public
|
|
100
100
|
*/
|
|
101
|
-
const CURRENT_PLUGIN_VERSION = "
|
|
101
|
+
const CURRENT_PLUGIN_VERSION = "2.0.0";
|
|
102
102
|
const TEST_FILE_SUFFIX_RE = /\.(?:test|spec)\.(?:ts|tsx|js|jsx)$/;
|
|
103
103
|
const TEST_FILE_DIR_RE = /\/(?:src|__test__)\//;
|
|
104
104
|
const isTestFile = (id) => TEST_FILE_SUFFIX_RE.test(id) && TEST_FILE_DIR_RE.test(id);
|
|
@@ -152,7 +152,7 @@ function installViteSourceMapWarningFilter(resolvedConfig) {
|
|
|
152
152
|
function AgentPlugin(options = {}, _layer) {
|
|
153
153
|
const layer = _layer ?? EnvironmentDetectorLive;
|
|
154
154
|
const logLevel = resolveLogLevel();
|
|
155
|
-
const log = logLevel !== void 0 && logLevel
|
|
155
|
+
const log = logLevel !== void 0 && logLevel !== "None" ? (...args) => process.stderr.write(`[vitest-agent:plugin] ${args.map(String).join(" ")}\n`) : (..._args) => {};
|
|
156
156
|
const discoverStrategyResolved = options.discoverStrategy === false ? null : options.discoverStrategy ?? new DefaultDiscoverStrategy();
|
|
157
157
|
const pluginObj = {
|
|
158
158
|
name: "vitest-agent",
|
package/reporter.js
CHANGED
|
@@ -12,7 +12,7 @@ import { Effect, Option, PubSub } from "effect";
|
|
|
12
12
|
import { randomUUID } from "node:crypto";
|
|
13
13
|
import { mkdirSync } from "node:fs";
|
|
14
14
|
import { dirname } from "node:path";
|
|
15
|
-
import {
|
|
15
|
+
import { NodeServices } from "@effect/platform-node";
|
|
16
16
|
import { DefaultVitestAgentReporter } from "@vitest-agent/reporter";
|
|
17
17
|
|
|
18
18
|
//#region src/reporter.ts
|
|
@@ -39,7 +39,7 @@ const dbPathCache = /* @__PURE__ */ new Map();
|
|
|
39
39
|
function resolveDataPathCached(projectDir) {
|
|
40
40
|
const cached = dbPathCache.get(projectDir);
|
|
41
41
|
if (cached !== void 0) return cached;
|
|
42
|
-
const promise = Effect.runPromise(resolveDataPath(projectDir).pipe(Effect.provide(PathResolutionLive(projectDir)), Effect.provide(
|
|
42
|
+
const promise = Effect.runPromise(resolveDataPath(projectDir).pipe(Effect.provide(PathResolutionLive(projectDir)), Effect.provide(NodeServices.layer)));
|
|
43
43
|
dbPathCache.set(projectDir, promise);
|
|
44
44
|
promise.catch(() => void 0);
|
|
45
45
|
return promise;
|
|
@@ -303,7 +303,7 @@ var AgentReporter = class {
|
|
|
303
303
|
}, opts.detail)
|
|
304
304
|
};
|
|
305
305
|
});
|
|
306
|
-
const { env, executor, format, detail } = await Effect.runPromise(initProgram.pipe(Effect.provide(OutputPipelineLive), Effect.provide(
|
|
306
|
+
const { env, executor, format, detail } = await Effect.runPromise(initProgram.pipe(Effect.provide(OutputPipelineLive), Effect.provide(NodeServices.layer)));
|
|
307
307
|
const kit = buildReporterKit({
|
|
308
308
|
env,
|
|
309
309
|
executor,
|
|
@@ -849,7 +849,7 @@ var AgentReporter = class {
|
|
|
849
849
|
const executor = yield* executorResolver.resolve(env);
|
|
850
850
|
const format = yield* formatSelector.select(executor, opts.format, env);
|
|
851
851
|
const health = {
|
|
852
|
-
hasFailures: uiReports.some((r) => r.
|
|
852
|
+
hasFailures: uiReports.some((r) => r.failedFiles.length > 0 || r.unhandledErrors.length > 0),
|
|
853
853
|
belowTargets: false,
|
|
854
854
|
hasTargets: !!opts.coverageTargets
|
|
855
855
|
};
|
|
@@ -881,7 +881,7 @@ var AgentReporter = class {
|
|
|
881
881
|
const allOutputs = reporters.flatMap((r) => r.render(renderInput, kit));
|
|
882
882
|
for (const output of allOutputs) routeRenderedOutput(output, { ...githubSummaryFile !== void 0 && { githubSummaryFile } });
|
|
883
883
|
});
|
|
884
|
-
await Effect.runPromise(uiProgram.pipe(Effect.provide(OutputPipelineLive), Effect.provide(
|
|
884
|
+
await Effect.runPromise(uiProgram.pipe(Effect.provide(OutputPipelineLive), Effect.provide(NodeServices.layer))).catch((err) => {
|
|
885
885
|
process.stderr.write(`vitest-agent: ${formatFatalError(err)}\n`);
|
|
886
886
|
});
|
|
887
887
|
return;
|
|
@@ -911,7 +911,7 @@ var AgentReporter = class {
|
|
|
911
911
|
if (existing) existing.push(mod);
|
|
912
912
|
else projectGroups.set(key, [mod]);
|
|
913
913
|
}
|
|
914
|
-
const baselinesOpt = yield* reader.getBaselines("__global__").pipe(Effect.
|
|
914
|
+
const baselinesOpt = yield* reader.getBaselines("__global__").pipe(Effect.catch(() => Effect.succeed(Option.none())));
|
|
915
915
|
const baselines = Option.getOrUndefined(baselinesOpt);
|
|
916
916
|
const projectModuleCounts = /* @__PURE__ */ new Map();
|
|
917
917
|
for (const m of modules) {
|
|
@@ -1232,7 +1232,7 @@ var AgentReporter = class {
|
|
|
1232
1232
|
}
|
|
1233
1233
|
}
|
|
1234
1234
|
if (coverageReport && !coverageReport.scoped) {
|
|
1235
|
-
const existingTrends = yield* reader.getTrends(project).pipe(Effect.map((opt) => Option.getOrUndefined(opt)), Effect.
|
|
1235
|
+
const existingTrends = yield* reader.getTrends(project).pipe(Effect.map((opt) => Option.getOrUndefined(opt)), Effect.catch(() => Effect.succeed(void 0)));
|
|
1236
1236
|
const updatedTrends = computeTrend(coverageReport.totals, existingTrends, opts.coverageTargets);
|
|
1237
1237
|
const latestEntry = updatedTrends.entries[updatedTrends.entries.length - 1];
|
|
1238
1238
|
if (latestEntry) yield* store.writeTrends(project, runId, latestEntry);
|
|
@@ -1247,7 +1247,7 @@ var AgentReporter = class {
|
|
|
1247
1247
|
const firstProjectKey = Array.from(projectGroups.keys())[0];
|
|
1248
1248
|
if (firstProjectKey) {
|
|
1249
1249
|
const tp = firstProjectKey === "default" ? "default" : firstProjectKey;
|
|
1250
|
-
const trendsOpt = yield* reader.getTrends(tp).pipe(Effect.
|
|
1250
|
+
const trendsOpt = yield* reader.getTrends(tp).pipe(Effect.catch(() => Effect.succeed(Option.none())));
|
|
1251
1251
|
if (Option.isSome(trendsOpt)) {
|
|
1252
1252
|
const entries = trendsOpt.value.entries;
|
|
1253
1253
|
if (entries.length >= 2) {
|
|
@@ -1301,7 +1301,7 @@ var AgentReporter = class {
|
|
|
1301
1301
|
const executor = yield* executorResolver.resolve(env);
|
|
1302
1302
|
const format = yield* formatSelector.select(executor, opts.format, env);
|
|
1303
1303
|
const health = {
|
|
1304
|
-
hasFailures: reports.some((r) => r.
|
|
1304
|
+
hasFailures: reports.some((r) => r.failedFiles.length > 0 || r.unhandledErrors.length > 0),
|
|
1305
1305
|
belowTargets: reports.some((r) => {
|
|
1306
1306
|
return (r.coverage?.belowTarget?.length ?? 0) > 0;
|
|
1307
1307
|
}),
|
|
@@ -5,7 +5,7 @@ import { Context } from "effect";
|
|
|
5
5
|
* Effect service for validating Vitest + plugin coverage configuration.
|
|
6
6
|
* @public
|
|
7
7
|
*/
|
|
8
|
-
var ConfigValidation = class extends Context.
|
|
8
|
+
var ConfigValidation = class extends Context.Service()("vitest-agent/ConfigValidation") {};
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
11
|
export { ConfigValidation };
|
|
@@ -5,7 +5,7 @@ import { Context } from "effect";
|
|
|
5
5
|
* Effect service for processing istanbul coverage maps into structured reports.
|
|
6
6
|
* @public
|
|
7
7
|
*/
|
|
8
|
-
var CoverageAnalyzer = class extends Context.
|
|
8
|
+
var CoverageAnalyzer = class extends Context.Service()("vitest-agent/CoverageAnalyzer") {};
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
11
|
export { CoverageAnalyzer };
|
package/tsdoc-metadata.json
CHANGED
|
@@ -2,7 +2,8 @@ import { toPosixPath } from "./to-posix-path.js";
|
|
|
2
2
|
import { DefaultDiscoverStrategy } from "./discover-strategy.js";
|
|
3
3
|
import { isAbsolute, join, normalize, relative } from "node:path";
|
|
4
4
|
import { readdir, stat } from "node:fs/promises";
|
|
5
|
-
import { findWorkspaceRootSync, getWorkspacePackagesSync } from "workspaces
|
|
5
|
+
import { findWorkspaceRootSync, getWorkspacePackagesSync } from "@effected/workspaces";
|
|
6
|
+
import { nodeSyncOps } from "@effected/workspaces/node-sync";
|
|
6
7
|
|
|
7
8
|
//#region src/utils/discover-projects.ts
|
|
8
9
|
const DISCOVERY_LAST_SCAN_SYMBOL = Symbol.for("vitest-agent:discovery:last-scan-at");
|
|
@@ -69,11 +70,14 @@ async function discoverProjects(options) {
|
|
|
69
70
|
const strategy = options?.strategy;
|
|
70
71
|
const cwd = options?.cwd;
|
|
71
72
|
const additionalEntries = options?.additionalEntries ?? [];
|
|
72
|
-
const root = findWorkspaceRootSync(
|
|
73
|
+
const root = findWorkspaceRootSync({
|
|
74
|
+
...nodeSyncOps,
|
|
75
|
+
cwd: cwd ?? process.cwd()
|
|
76
|
+
});
|
|
73
77
|
if (!root) throw new Error(`[vitest-agent] Could not find workspace root from ${cwd ?? process.cwd()}. Ensure a pnpm-workspace.yaml or package.json with "workspaces" exists.`);
|
|
74
78
|
const useCache = strategy === void 0 && additionalEntries.length === 0;
|
|
75
79
|
const resolvedStrategy = strategy ?? new DefaultDiscoverStrategy();
|
|
76
|
-
const packages = getWorkspacePackagesSync(root);
|
|
80
|
+
const packages = getWorkspacePackagesSync(root, nodeSyncOps);
|
|
77
81
|
let signature;
|
|
78
82
|
if (useCache) {
|
|
79
83
|
signature = await computeWorkspaceSignature(packages);
|