@vitest-agent/plugin 5.5.0 → 5.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 +12 -1
- package/package.json +6 -6
- package/plugin.js +13 -5
- package/reporter.js +7 -3
- package/utils/build-reporter-kit.js +23 -28
- package/utils/config-suggested-actions.js +42 -0
- package/version.js +1 -1
package/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "@effected/env";
|
|
2
2
|
import { EnvironmentDetector, PlatformLiveError, PlatformOptions, PlatformServices, SettingsInput, StackFrameInput } from "@vitest-agent/engine";
|
|
3
|
-
import { AgentPluginOptions, AgentReporterOptions, ConsoleMode, CoverageBaselines, CoverageInput, CoverageLevel, CoverageLevelName, CoverageLevelName as CoverageLevelName$1, CoverageReport, ResolvedReporterConfig, ResolvedThresholds, RunEvent, RunRetentionPolicy, Transport, VitestAgentReporterFactory, resolveCoverageInput, validateCoverageConfig } from "@vitest-agent/sdk";
|
|
3
|
+
import { AgentPluginOptions, AgentReporterOptions, ConsoleMode, CoverageBaselines, CoverageInput, CoverageLevel, CoverageLevelName, CoverageLevelName as CoverageLevelName$1, CoverageReport, ResolvedReporterConfig, ResolvedThresholds, RunEvent, RunRetentionPolicy, SuggestedActionRecord, Transport, VitestAgentReporterFactory, resolveCoverageInput, validateCoverageConfig } from "@vitest-agent/sdk";
|
|
4
4
|
import { Context, Effect, Layer, Option } from "effect";
|
|
5
5
|
import { TestProjectInlineConfiguration, TestTagDefinition } from "vitest/config";
|
|
6
6
|
import { ResolvedConfig, VitestPluginContext } from "vitest/node";
|
|
@@ -631,6 +631,17 @@ interface AgentReporterConstructorOptions extends AgentReporterOptions {
|
|
|
631
631
|
* `run_tests` tool.
|
|
632
632
|
*/
|
|
633
633
|
passWithNoTests?: boolean;
|
|
634
|
+
/**
|
|
635
|
+
* Run-level suggested actions the plugin resolved at config time — the
|
|
636
|
+
* `ConfigValidation` warnings and info entries, mapped onto
|
|
637
|
+
* `SuggestedActionRecord`s (issue #544). Forwarded verbatim onto
|
|
638
|
+
* `ReporterRenderInput.suggestedActions` for every render, so the
|
|
639
|
+
* `Actions:` trailer repeats them in watch mode. Absent when the config
|
|
640
|
+
* validated clean.
|
|
641
|
+
*
|
|
642
|
+
* @internal
|
|
643
|
+
*/
|
|
644
|
+
suggestedActions?: ReadonlyArray<SuggestedActionRecord>;
|
|
634
645
|
coverageThresholds?: ResolvedThresholds | Record<string, unknown>;
|
|
635
646
|
coverageTargets?: ResolvedThresholds | Record<string, unknown>;
|
|
636
647
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest-agent/plugin",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.6.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": [
|
|
@@ -49,11 +49,11 @@
|
|
|
49
49
|
"@effected/glob": "^0.14.0",
|
|
50
50
|
"@effected/walker": "^0.19.0",
|
|
51
51
|
"@effected/workspaces": "^0.38.0",
|
|
52
|
-
"@vitest-agent/cli": "4.1.
|
|
53
|
-
"@vitest-agent/engine": "
|
|
54
|
-
"@vitest-agent/mcp": "5.
|
|
55
|
-
"@vitest-agent/reporter": "
|
|
56
|
-
"@vitest-agent/sdk": "
|
|
52
|
+
"@vitest-agent/cli": "4.1.1",
|
|
53
|
+
"@vitest-agent/engine": "2.0.0",
|
|
54
|
+
"@vitest-agent/mcp": "5.3.0",
|
|
55
|
+
"@vitest-agent/reporter": "6.0.0",
|
|
56
|
+
"@vitest-agent/sdk": "8.0.0",
|
|
57
57
|
"effect": "^4.0.6",
|
|
58
58
|
"magic-string": "^1.4.3"
|
|
59
59
|
},
|
package/plugin.js
CHANGED
|
@@ -6,6 +6,7 @@ import { assertFlatScope } from "./utils/report-writer.js";
|
|
|
6
6
|
import { installStrayOutputCapture } from "./utils/stray-output-capture.js";
|
|
7
7
|
import { AgentReporter } from "./reporter.js";
|
|
8
8
|
import { buildModuleInfo } from "./utils/build-module-info.js";
|
|
9
|
+
import { publishConfigSuggestedActions, suggestedActionsFromValidation } from "./utils/config-suggested-actions.js";
|
|
9
10
|
import { DefaultDiscoverStrategy } from "./utils/discover-strategy.js";
|
|
10
11
|
import { discoverProjects } from "./utils/discover-projects.js";
|
|
11
12
|
import { ensureGithubActionsReporter } from "./utils/ensure-github-reporter.js";
|
|
@@ -216,11 +217,15 @@ function AgentPlugin(options = {}, _layer) {
|
|
|
216
217
|
ctx.defineCacheKeyGenerator(makeTagCacheKeyGenerator(classifyForCache));
|
|
217
218
|
log("registered fsModuleCache tag cache-key generator");
|
|
218
219
|
}
|
|
219
|
-
const { env, executor } = await Effect.runPromise(Effect.gen(function* () {
|
|
220
|
-
const
|
|
220
|
+
const { env, executor, inGithubActions } = await Effect.runPromise(Effect.gen(function* () {
|
|
221
|
+
const detector = yield* EnvironmentDetector;
|
|
222
|
+
const env = yield* detector.detect();
|
|
223
|
+
const executor = yield* (yield* ExecutorResolver).resolve(env);
|
|
224
|
+
const ci = yield* detector.ci;
|
|
221
225
|
return {
|
|
222
226
|
env,
|
|
223
|
-
executor
|
|
227
|
+
executor,
|
|
228
|
+
inGithubActions: Option.contains(ci, "github-actions")
|
|
224
229
|
};
|
|
225
230
|
}).pipe(Effect.provide(Layer.merge(layer, ExecutorResolverLive))));
|
|
226
231
|
const reportOption = options.report;
|
|
@@ -254,17 +259,19 @@ function AgentPlugin(options = {}, _layer) {
|
|
|
254
259
|
stderr: process.stderr
|
|
255
260
|
});
|
|
256
261
|
}
|
|
257
|
-
|
|
262
|
+
const githubActions = inGithubActions && consoleMode !== "silent";
|
|
263
|
+
if (githubActions) {
|
|
258
264
|
log("normalizing the github-actions reporter entry");
|
|
259
265
|
const withGithubActions = ensureGithubActionsReporter(vitest.config.reporters);
|
|
260
266
|
vitest.config.reporters = withGithubActions;
|
|
261
267
|
}
|
|
262
|
-
const githubActions = env === "ci-github" && consoleMode !== "silent";
|
|
263
268
|
log("githubActions (auto):", githubActions);
|
|
264
269
|
const validation = await Effect.runPromise(Effect.provide(Effect.flatMap(ConfigValidation, (cv) => cv.validate({
|
|
265
270
|
vitestConfig: vitest.config,
|
|
266
271
|
pluginOptions: options
|
|
267
272
|
})), ConfigValidationLive));
|
|
273
|
+
const configSuggestedActions = suggestedActionsFromValidation(validation);
|
|
274
|
+
publishConfigSuggestedActions(vitest, configSuggestedActions);
|
|
268
275
|
for (const w of validation.warnings) reportOnce(`[vitest-agent:plugin] warning ${w.code}: ${w.message}` + (w.remediation ? `\n ${w.remediation}` : "") + "\n");
|
|
269
276
|
for (const i of validation.info) reportOnce(`[vitest-agent:plugin] info ${i.code}: ${i.message}\n`);
|
|
270
277
|
if (validation.errors.length > 0) {
|
|
@@ -328,6 +335,7 @@ function AgentPlugin(options = {}, _layer) {
|
|
|
328
335
|
...reportScope !== void 0 && { reportScope },
|
|
329
336
|
transport,
|
|
330
337
|
...passWithNoTests !== void 0 ? { passWithNoTests } : {},
|
|
338
|
+
...configSuggestedActions.length > 0 ? { suggestedActions: configSuggestedActions } : {},
|
|
331
339
|
...options.reporter !== void 0 && { reporter: options.reporter },
|
|
332
340
|
...options.onRunEvent !== void 0 ? { onRunEvent: options.onRunEvent } : {}
|
|
333
341
|
});
|
package/reporter.js
CHANGED
|
@@ -495,7 +495,8 @@ var AgentReporter = class {
|
|
|
495
495
|
coverageMode: options.coverageMode ?? "full",
|
|
496
496
|
persist: options.persist ?? true,
|
|
497
497
|
transport: options.transport ?? { kind: "local" },
|
|
498
|
-
...options.passWithNoTests !== void 0 ? { passWithNoTests: options.passWithNoTests } : {}
|
|
498
|
+
...options.passWithNoTests !== void 0 ? { passWithNoTests: options.passWithNoTests } : {},
|
|
499
|
+
...options.suggestedActions !== void 0 && options.suggestedActions.length > 0 ? { suggestedActions: options.suggestedActions } : {}
|
|
499
500
|
};
|
|
500
501
|
this.options = resolvedTargets ? {
|
|
501
502
|
...base,
|
|
@@ -1343,7 +1344,8 @@ var AgentReporter = class {
|
|
|
1343
1344
|
const reporters = preBuiltReporters ?? normalizeReporters(opts.reporter(kit));
|
|
1344
1345
|
const renderInput = {
|
|
1345
1346
|
reports: withStrayOutput(reports, strayOutput),
|
|
1346
|
-
classifications: /* @__PURE__ */ new Map()
|
|
1347
|
+
classifications: /* @__PURE__ */ new Map(),
|
|
1348
|
+
...opts.suggestedActions !== void 0 && { suggestedActions: opts.suggestedActions }
|
|
1347
1349
|
};
|
|
1348
1350
|
const allOutputs = reporters.flatMap((r) => r.render(renderInput, kit));
|
|
1349
1351
|
for (const output of allOutputs) routeRenderedOutput(output, {
|
|
@@ -1448,7 +1450,8 @@ var AgentReporter = class {
|
|
|
1448
1450
|
gitCommitSha: process.env.GITHUB_SHA ?? null,
|
|
1449
1451
|
hostSource: hostProbe.source,
|
|
1450
1452
|
hostValue: hostProbe.value,
|
|
1451
|
-
hostMetadata: hostProbe.metadata
|
|
1453
|
+
hostMetadata: hostProbe.metadata,
|
|
1454
|
+
strayOutput: strayOutput ?? null
|
|
1452
1455
|
});
|
|
1453
1456
|
for (const mod of projectModules) {
|
|
1454
1457
|
const fileId = yield* store.ensureFile(mod.relativeModuleId);
|
|
@@ -1852,6 +1855,7 @@ var AgentReporter = class {
|
|
|
1852
1855
|
const renderInput = {
|
|
1853
1856
|
reports: withStrayOutput(reports, strayOutput),
|
|
1854
1857
|
classifications,
|
|
1858
|
+
...opts.suggestedActions !== void 0 && { suggestedActions: opts.suggestedActions },
|
|
1855
1859
|
...trendSummary !== void 0 && { trendSummary }
|
|
1856
1860
|
};
|
|
1857
1861
|
const allOutputs = reporters.flatMap((r) => r.render(renderInput, kit));
|
|
@@ -1,38 +1,33 @@
|
|
|
1
|
-
import { osc8 } from "@vitest-agent/sdk";
|
|
2
|
-
|
|
3
1
|
// src/utils/build-reporter-kit.ts
|
|
4
2
|
const buildReporterKit = (input) => {
|
|
5
3
|
const consoleOutput = input.consoleMode === "silent" ? "silent" : "failures";
|
|
6
4
|
const githubSummary = input.githubActions;
|
|
7
5
|
const githubSummaryFile = process.env.GITHUB_STEP_SUMMARY;
|
|
8
|
-
const config = {
|
|
9
|
-
executor: input.executor,
|
|
10
|
-
consoleMode: input.consoleMode,
|
|
11
|
-
mcp: input.mcp,
|
|
12
|
-
consoleOutput,
|
|
13
|
-
omitPassingTests: true,
|
|
14
|
-
coverageConsoleLimit: 10,
|
|
15
|
-
includeBareZero: false,
|
|
16
|
-
githubActions: input.githubActions,
|
|
17
|
-
githubSummary,
|
|
18
|
-
detail: input.detail,
|
|
19
|
-
noColor: input.noColor,
|
|
20
|
-
coverageMode: input.coverageMode,
|
|
21
|
-
persist: input.persist,
|
|
22
|
-
transport: input.transport,
|
|
23
|
-
...input.dbPath !== void 0 && { dbPath: input.dbPath },
|
|
24
|
-
...input.projectFilter !== void 0 && { projectFilter: input.projectFilter },
|
|
25
|
-
...githubSummaryFile !== void 0 && { githubSummaryFile },
|
|
26
|
-
...input.runCommand !== void 0 && { runCommand: input.runCommand },
|
|
27
|
-
...input.coverageThresholds !== void 0 && { coverageThresholds: input.coverageThresholds },
|
|
28
|
-
...input.coverageTargets !== void 0 && { coverageTargets: input.coverageTargets },
|
|
29
|
-
...input.passWithNoTests !== void 0 && { passWithNoTests: input.passWithNoTests }
|
|
30
|
-
};
|
|
31
|
-
const osc8Enabled = !input.noColor && (input.env === "terminal" || input.env === "agent-shell");
|
|
32
6
|
return {
|
|
33
|
-
config
|
|
7
|
+
config: {
|
|
8
|
+
executor: input.executor,
|
|
9
|
+
consoleMode: input.consoleMode,
|
|
10
|
+
mcp: input.mcp,
|
|
11
|
+
consoleOutput,
|
|
12
|
+
omitPassingTests: true,
|
|
13
|
+
coverageConsoleLimit: 10,
|
|
14
|
+
includeBareZero: false,
|
|
15
|
+
githubActions: input.githubActions,
|
|
16
|
+
githubSummary,
|
|
17
|
+
detail: input.detail,
|
|
18
|
+
noColor: input.noColor,
|
|
19
|
+
coverageMode: input.coverageMode,
|
|
20
|
+
persist: input.persist,
|
|
21
|
+
transport: input.transport,
|
|
22
|
+
...input.dbPath !== void 0 && { dbPath: input.dbPath },
|
|
23
|
+
...input.projectFilter !== void 0 && { projectFilter: input.projectFilter },
|
|
24
|
+
...githubSummaryFile !== void 0 && { githubSummaryFile },
|
|
25
|
+
...input.runCommand !== void 0 && { runCommand: input.runCommand },
|
|
26
|
+
...input.coverageThresholds !== void 0 && { coverageThresholds: input.coverageThresholds },
|
|
27
|
+
...input.coverageTargets !== void 0 && { coverageTargets: input.coverageTargets },
|
|
28
|
+
...input.passWithNoTests !== void 0 && { passWithNoTests: input.passWithNoTests }
|
|
29
|
+
},
|
|
34
30
|
stdEnv: input.env,
|
|
35
|
-
stdOsc8: (url, label) => osc8(url, label, { enabled: osc8Enabled }),
|
|
36
31
|
...input.runEvents !== void 0 && { runEvents: input.runEvents }
|
|
37
32
|
};
|
|
38
33
|
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// src/utils/config-suggested-actions.ts
|
|
2
|
+
/**
|
|
3
|
+
* The `Symbol.for` key under which `configureVitest` publishes the run's
|
|
4
|
+
* config-derived suggested actions on the Vitest instance. `Symbol.for`
|
|
5
|
+
* resolves to the identical symbol across module copies in one process, so
|
|
6
|
+
* the MCP `run_tests` tool reads the same slot off the Vitest instance it
|
|
7
|
+
* created (mirrors the discovery last-scan slot).
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
const CONFIG_SUGGESTED_ACTIONS_SYMBOL = Symbol.for("vitest-agent:config-suggested-actions");
|
|
12
|
+
/**
|
|
13
|
+
* Map a `ValidationResult`'s warnings and info entries onto suggested
|
|
14
|
+
* actions, in the order the validator produced them. A warning becomes a
|
|
15
|
+
* `warn` action and an info entry an `info` action; the title names the
|
|
16
|
+
* rule code, the detail carries the message followed by the remediation
|
|
17
|
+
* when the rule has one. No `targetTool` — there is no MCP tool that edits
|
|
18
|
+
* the Vitest config.
|
|
19
|
+
*
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
const suggestedActionsFromValidation = (result) => [...result.warnings.map((w) => ({
|
|
23
|
+
severity: "warn",
|
|
24
|
+
title: `Coverage config: ${w.code}`,
|
|
25
|
+
detail: w.remediation !== void 0 ? `${w.message} ${w.remediation}` : w.message
|
|
26
|
+
})), ...result.info.map((i) => ({
|
|
27
|
+
severity: "info",
|
|
28
|
+
title: `Coverage config: ${i.code}`,
|
|
29
|
+
detail: i.message
|
|
30
|
+
}))];
|
|
31
|
+
/**
|
|
32
|
+
* Publish the run's config-derived suggested actions on the Vitest instance
|
|
33
|
+
* for readers in the same process (the MCP `run_tests` tool). An empty list
|
|
34
|
+
* clears the slot so a watch-mode rerun after a config fix reports nothing.
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
const publishConfigSuggestedActions = (vitest, actions) => {
|
|
39
|
+
vitest[CONFIG_SUGGESTED_ACTIONS_SYMBOL] = actions.length > 0 ? actions : void 0;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { CONFIG_SUGGESTED_ACTIONS_SYMBOL, publishConfigSuggestedActions, suggestedActionsFromValidation };
|