@vitest-agent/mcp 2.1.0 → 2.1.2
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 +1 -0
- package/index.js +1 -1
- package/package.json +2 -2
- package/tools/run-tests.js +53 -11
package/index.d.ts
CHANGED
|
@@ -533,6 +533,7 @@ declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
533
533
|
readonly failed: number;
|
|
534
534
|
readonly skipped: number;
|
|
535
535
|
readonly duration: number;
|
|
536
|
+
readonly modules?: number | undefined;
|
|
536
537
|
};
|
|
537
538
|
readonly failed: readonly {
|
|
538
539
|
readonly file: string;
|
package/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { parseSessionEnvExports, recoverSessionContextFromSessionEnv } from "./s
|
|
|
12
12
|
*
|
|
13
13
|
* @public
|
|
14
14
|
*/
|
|
15
|
-
const CURRENT_MCP_VERSION = "2.1.
|
|
15
|
+
const CURRENT_MCP_VERSION = "2.1.2";
|
|
16
16
|
|
|
17
17
|
//#endregion
|
|
18
18
|
export { CURRENT_MCP_VERSION, McpLive, appRouter, buildMcpServer, createCallerFactory, createCurrentSessionIdRef, createSessionContextRef, parseSessionEnvExports, recoverSessionContextFromSessionEnv, startMcpServer };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest-agent/mcp",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Model Context Protocol server for vitest-agent. Exposes 53 tools for agent access to test data, TDD lifecycle, and session management.",
|
|
6
6
|
"keywords": [
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@effect/sql-sqlite-node": "4.0.0-beta.107",
|
|
43
43
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
44
44
|
"@trpc/server": "^11.18.0",
|
|
45
|
-
"@vitest-agent/sdk": "2.0
|
|
45
|
+
"@vitest-agent/sdk": "2.1.0",
|
|
46
46
|
"effect": "4.0.0-beta.107",
|
|
47
47
|
"zod": "^4.4.3"
|
|
48
48
|
},
|
package/tools/run-tests.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { publicProcedure } from "../context.js";
|
|
2
|
-
import { AgentReport, DataReader, DataStore, buildAgentReport, buildConsoleLeaks, collectConsoleLeakEntries } from "@vitest-agent/sdk";
|
|
2
|
+
import { AgentReport, DataReader, DataStore, buildAgentReport, buildConsoleLeaks, coerceErrorField, collectConsoleLeakEntries } from "@vitest-agent/sdk";
|
|
3
3
|
import { Effect, Schema, SchemaGetter } from "effect";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
6
|
+
import { tmpdir } from "node:os";
|
|
7
|
+
import { join } from "node:path";
|
|
5
8
|
import { Writable } from "node:stream";
|
|
6
9
|
|
|
7
10
|
//#region src/tools/run-tests.ts
|
|
@@ -84,6 +87,27 @@ function readDiscoveryLastScannedAt() {
|
|
|
84
87
|
const value = globalThis[DISCOVERY_LAST_SCAN_SYMBOL];
|
|
85
88
|
return typeof value === "string" ? value : void 0;
|
|
86
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Per-invocation coverage temp directory. Vitest's v8 provider `rm -rf`s the
|
|
92
|
+
* shared `coverage/` reports directory at run start (`clean: true` default),
|
|
93
|
+
* so two concurrent runs in one checkout destroy each other's `.tmp` files
|
|
94
|
+
* (ENOENT coverage-N.json — issues #159/#191/#194). Each MCP run gets its own
|
|
95
|
+
* directory; coverage persistence is unaffected because the analyzer consumes
|
|
96
|
+
* the in-memory CoverageMap, never the disk artifacts. Consequence: final
|
|
97
|
+
* coverage artifacts (html/lcov) from MCP-driven runs land in the throwaway
|
|
98
|
+
* dir instead of `./coverage` — acceptable because MCP consumers read
|
|
99
|
+
* coverage from SQLite (`CoverageAnalyzer` consumes the in-memory map via
|
|
100
|
+
* `onCoverage`), not from disk artifacts.
|
|
101
|
+
*
|
|
102
|
+
* @internal exported for tests
|
|
103
|
+
*/
|
|
104
|
+
const makeCoverageDirOverride = () => {
|
|
105
|
+
const dir = mkdtempSync(join(tmpdir(), "vitest-agent-cov-"));
|
|
106
|
+
return {
|
|
107
|
+
dir,
|
|
108
|
+
coverage: { reportsDirectory: dir }
|
|
109
|
+
};
|
|
110
|
+
};
|
|
87
111
|
const stdoutSinkStorage = new AsyncLocalStorage();
|
|
88
112
|
const stderrSinkStorage = new AsyncLocalStorage();
|
|
89
113
|
let _stdioPatched = false;
|
|
@@ -305,10 +329,13 @@ const runTests = publicProcedure.input(Schema.toStandardSchemaV1(Schema.Struct({
|
|
|
305
329
|
} });
|
|
306
330
|
const { createVitest } = await import("vitest/node");
|
|
307
331
|
let vitest;
|
|
332
|
+
let covOverride;
|
|
308
333
|
try {
|
|
334
|
+
covOverride = makeCoverageDirOverride();
|
|
309
335
|
vitest = await createVitest("test", {
|
|
310
336
|
root: ctx.cwd,
|
|
311
337
|
run: true,
|
|
338
|
+
coverage: covOverride.coverage,
|
|
312
339
|
...project ? { project } : {},
|
|
313
340
|
...resolvedExpression !== null ? { tagsFilter: [resolvedExpression] } : {},
|
|
314
341
|
...input.passWithNoTests !== void 0 ? { passWithNoTests: input.passWithNoTests } : {}
|
|
@@ -334,8 +361,8 @@ const runTests = publicProcedure.input(Schema.toStandardSchemaV1(Schema.Struct({
|
|
|
334
361
|
resolvedExpression
|
|
335
362
|
}
|
|
336
363
|
};
|
|
337
|
-
const
|
|
338
|
-
const baseReport = buildAgentReport(testModules, unhandledErrors,
|
|
364
|
+
const preliminaryReason = unhandledErrors.length > 0 || result.testModules.some((m) => m.state() === "failed") ? "failed" : "passed";
|
|
365
|
+
const baseReport = buildAgentReport(testModules, unhandledErrors, preliminaryReason, { omitPassingTests: true });
|
|
339
366
|
const leaks = buildConsoleLeaks(collectConsoleLeakEntries(localVitest.state.getFiles()));
|
|
340
367
|
const report = leaks !== void 0 ? {
|
|
341
368
|
...baseReport,
|
|
@@ -369,19 +396,34 @@ const runTests = publicProcedure.input(Schema.toStandardSchemaV1(Schema.Struct({
|
|
|
369
396
|
discoveryLastScannedAt: readDiscoveryLastScannedAt() ?? null
|
|
370
397
|
};
|
|
371
398
|
} catch (err) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
399
|
+
let message;
|
|
400
|
+
try {
|
|
401
|
+
if (err instanceof Error && err.message === "VITEST_TIMEOUT") return {
|
|
402
|
+
kind: "timeout",
|
|
403
|
+
timeoutSeconds: input.timeout ?? 120
|
|
404
|
+
};
|
|
405
|
+
message = err instanceof Error ? err.message : String(err);
|
|
406
|
+
} catch {
|
|
407
|
+
message = coerceErrorField(err, "message") ?? "<unserializable error>";
|
|
408
|
+
}
|
|
376
409
|
return {
|
|
377
410
|
kind: "error",
|
|
378
|
-
message
|
|
411
|
+
message
|
|
379
412
|
};
|
|
380
413
|
} finally {
|
|
381
|
-
|
|
382
|
-
|
|
414
|
+
try {
|
|
415
|
+
await vitest?.close();
|
|
416
|
+
} finally {
|
|
417
|
+
nullStream.destroy();
|
|
418
|
+
if (covOverride !== void 0) try {
|
|
419
|
+
rmSync(covOverride.dir, {
|
|
420
|
+
recursive: true,
|
|
421
|
+
force: true
|
|
422
|
+
});
|
|
423
|
+
} catch {}
|
|
424
|
+
}
|
|
383
425
|
}
|
|
384
426
|
}));
|
|
385
427
|
|
|
386
428
|
//#endregion
|
|
387
|
-
export { RunTestsAsMarkdown, RunTestsResult, coerceErrors, composeTagExpression, formatNoMatchMarkdown, formatReportMarkdown, formatRunTestsMarkdown, readDiscoveryLastScannedAt, runTests, sanitizeTestArgs, withStdioCaptured };
|
|
429
|
+
export { RunTestsAsMarkdown, RunTestsResult, coerceErrors, composeTagExpression, formatNoMatchMarkdown, formatReportMarkdown, formatRunTestsMarkdown, makeCoverageDirOverride, readDiscoveryLastScannedAt, runTests, sanitizeTestArgs, withStdioCaptured };
|