@vitest-agent/mcp 3.0.4 → 4.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/README.md +7 -6
- package/annotations.js +18 -0
- package/bin/vitest-agent-mcp.js +5 -140
- package/{middleware/idempotency.js → idempotency.js} +48 -49
- package/index.d.ts +5610 -1549
- package/index.js +35 -17
- package/main.d.ts +31 -0
- package/main.js +144 -0
- package/package.json +9 -6
- package/prompts/layer.js +108 -0
- package/register-toolkit.js +311 -0
- package/server.js +24 -894
- package/{context.js → session.js} +38 -22
- package/toolkit.js +86 -0
- package/tools/acceptance-metrics.js +26 -14
- package/tools/cache-health.js +28 -17
- package/tools/commit-changes.js +33 -10
- package/tools/configure.js +33 -10
- package/tools/coverage.js +34 -5
- package/tools/errors.js +36 -26
- package/tools/failure-signature-get.js +33 -10
- package/tools/file-coverage.js +37 -13
- package/tools/help.js +45 -4
- package/tools/history.js +39 -19
- package/tools/hypothesis.js +118 -102
- package/tools/inventory.js +149 -146
- package/tools/note.js +131 -113
- package/tools/overview.js +33 -10
- package/tools/ping.js +22 -10
- package/tools/register-agent.js +88 -62
- package/tools/run-tests.js +76 -23
- package/tools/settings-list.js +27 -10
- package/tools/status.js +35 -10
- package/tools/tdd-artifact.js +37 -22
- package/tools/tdd-behavior.js +120 -108
- package/tools/tdd-goal.js +98 -85
- package/tools/tdd-phase-transition-request.js +201 -166
- package/tools/tdd-progress-push.js +102 -0
- package/tools/tdd-task.js +140 -138
- package/tools/test.js +152 -138
- package/tools/trends.js +37 -18
- package/tools/triage-brief.js +34 -15
- package/tools/turn-search.js +39 -16
- package/tools/wrapup-prompt.js +37 -17
- package/utils/crash-guards.js +0 -22
- package/utils/replay-marker.js +12 -0
- package/utils/safe-format-fatal-error.js +0 -16
- package/utils/tool-error-envelope.js +3 -3
- package/version.js +13 -0
- package/layers/McpLive.js +0 -29
- package/prompts/index.js +0 -89
- package/router.js +0 -74
- package/session-env.js +0 -112
- package/utils/effect-to-zod.js +0 -158
package/index.js
CHANGED
|
@@ -1,18 +1,36 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { RenderText } from "./annotations.js";
|
|
2
|
+
import { withIdempotency } from "./idempotency.js";
|
|
3
|
+
import { McpSession, createCurrentSessionIdRef, createSessionContextRef, sessionContextFromEnv } from "./session.js";
|
|
4
|
+
import { PromptsLayer } from "./prompts/layer.js";
|
|
5
|
+
import { registerStrictToolkit } from "./register-toolkit.js";
|
|
6
|
+
import { AcceptanceMetricsResult } from "./tools/acceptance-metrics.js";
|
|
7
|
+
import { CacheHealthResult } from "./tools/cache-health.js";
|
|
8
|
+
import { CommitChangesInput, CommitChangesResult } from "./tools/commit-changes.js";
|
|
9
|
+
import { ConfigureInput, ConfigureResult } from "./tools/configure.js";
|
|
10
|
+
import { TestCoverageInput, TestCoverageResult } from "./tools/coverage.js";
|
|
11
|
+
import { TestErrorsInput, TestErrorsResult } from "./tools/errors.js";
|
|
12
|
+
import { FailureSignatureGetInput, FailureSignatureGetResult } from "./tools/failure-signature-get.js";
|
|
13
|
+
import { FileCoverageInput, FileCoverageResult } from "./tools/file-coverage.js";
|
|
14
|
+
import { HelpResult } from "./tools/help.js";
|
|
15
|
+
import { TestHistoryInput, TestHistoryResult } from "./tools/history.js";
|
|
16
|
+
import { InventoryInput, InventoryResult } from "./tools/inventory.js";
|
|
17
|
+
import { NoteParams, NoteResult } from "./tools/note.js";
|
|
18
|
+
import { TestOverviewInput, TestOverviewResult } from "./tools/overview.js";
|
|
19
|
+
import { PingResult } from "./tools/ping.js";
|
|
20
|
+
import { RegisterAgentInput, RegisterAgentResult } from "./tools/register-agent.js";
|
|
21
|
+
import { RunTestsInput, RunTestsResult } from "./tools/run-tests.js";
|
|
22
|
+
import { SettingsListResult } from "./tools/settings-list.js";
|
|
23
|
+
import { TestStatusInput, TestStatusResult } from "./tools/status.js";
|
|
24
|
+
import { TddArtifactListInput, TddArtifactListResult } from "./tools/tdd-artifact.js";
|
|
25
|
+
import { PhaseTransitionInput, PhaseTransitionResult } from "./tools/tdd-phase-transition-request.js";
|
|
26
|
+
import { TddProgressPushInput, TddProgressPushResult } from "./tools/tdd-progress-push.js";
|
|
27
|
+
import { TestInput, TestResult } from "./tools/test.js";
|
|
28
|
+
import { TestTrendsInput, TestTrendsResult } from "./tools/trends.js";
|
|
29
|
+
import { TriageBriefInput, TriageBriefResult } from "./tools/triage-brief.js";
|
|
30
|
+
import { TurnSearchInput, TurnSearchResult } from "./tools/turn-search.js";
|
|
31
|
+
import { WrapupPromptInput, WrapupPromptResult } from "./tools/wrapup-prompt.js";
|
|
32
|
+
import { Kit, ToolsLayer, toolHandlers } from "./toolkit.js";
|
|
33
|
+
import { ServerLayer } from "./server.js";
|
|
34
|
+
import { CURRENT_MCP_VERSION } from "./version.js";
|
|
6
35
|
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The version of this package, inlined at build time from
|
|
10
|
-
* package.json#version via rslib-builder's __PACKAGE_VERSION__ substitution.
|
|
11
|
-
* Exported for version introspection by downstream tooling.
|
|
12
|
-
*
|
|
13
|
-
* @public
|
|
14
|
-
*/
|
|
15
|
-
const CURRENT_MCP_VERSION = "3.0.4";
|
|
16
|
-
|
|
17
|
-
//#endregion
|
|
18
|
-
export { CURRENT_MCP_VERSION, McpLive, appRouter, buildMcpServer, createCallerFactory, createCurrentSessionIdRef, createSessionContextRef, parseSessionEnvExports, recoverSessionContextFromSessionEnv, startMcpServer };
|
|
36
|
+
export { AcceptanceMetricsResult, CURRENT_MCP_VERSION, CacheHealthResult, CommitChangesInput, CommitChangesResult, ConfigureInput, ConfigureResult, FailureSignatureGetInput, FailureSignatureGetResult, FileCoverageInput, FileCoverageResult, HelpResult, InventoryInput, InventoryResult, Kit, McpSession, NoteParams, NoteResult, PhaseTransitionInput, PhaseTransitionResult, PingResult, PromptsLayer, RegisterAgentInput, RegisterAgentResult, RenderText, RunTestsInput, RunTestsResult, ServerLayer, SettingsListResult, TddArtifactListInput, TddArtifactListResult, TddProgressPushInput, TddProgressPushResult, TestCoverageInput, TestCoverageResult, TestErrorsInput, TestErrorsResult, TestHistoryInput, TestHistoryResult, TestInput, TestOverviewInput, TestOverviewResult, TestResult, TestStatusInput, TestStatusResult, TestTrendsInput, TestTrendsResult, ToolsLayer, TriageBriefInput, TriageBriefResult, TurnSearchInput, TurnSearchResult, WrapupPromptInput, WrapupPromptResult, createCurrentSessionIdRef, createSessionContextRef, registerStrictToolkit, sessionContextFromEnv, toolHandlers, withIdempotency };
|
package/main.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/main.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The assembled vitest-agent MCP server program over stdio. Owns the process.
|
|
4
|
+
*
|
|
5
|
+
* This module deliberately carries NO static imports of the server graph:
|
|
6
|
+
* the `unhandledRejection` and `uncaughtException` guards are registered
|
|
7
|
+
* before `NodeRuntime`, the engine platform and `ServerLayer` are ever
|
|
8
|
+
* evaluated, so a throw during module evaluation is still reported on stderr
|
|
9
|
+
* rather than crashing silently. Adding a static import here would defeat
|
|
10
|
+
* that. `bin.ts` is the published bin shim; this module is also published as
|
|
11
|
+
* the `./main` subpath so the carrier (`@vitest-agent/plugin`) can ship its
|
|
12
|
+
* own `vitest-agent-mcp` bin over it.
|
|
13
|
+
*
|
|
14
|
+
* Every `process` read lives here, not in the server layer or the tools.
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Run the vitest-agent MCP server over stdio. Owns the process: registers
|
|
20
|
+
* the crash guards, resolves the project directory and `data.db` path,
|
|
21
|
+
* recovers the host session context, and launches the server layer under
|
|
22
|
+
* `NodeRuntime.runMain`.
|
|
23
|
+
*
|
|
24
|
+
* Not re-exported from `index.ts` — a library consumer's import graph must
|
|
25
|
+
* not pull in the process-owning module.
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
export declare const main: () => Promise<void>;
|
|
30
|
+
//#endregion
|
|
31
|
+
//# sourceMappingURL=main.d.ts.map
|
package/main.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { shouldExitOnUncaughtException } from "./utils/crash-guards.js";
|
|
2
|
+
|
|
3
|
+
//#region src/main.ts
|
|
4
|
+
/**
|
|
5
|
+
* The assembled vitest-agent MCP server program over stdio. Owns the process.
|
|
6
|
+
*
|
|
7
|
+
* This module deliberately carries NO static imports of the server graph:
|
|
8
|
+
* the `unhandledRejection` and `uncaughtException` guards are registered
|
|
9
|
+
* before `NodeRuntime`, the engine platform and `ServerLayer` are ever
|
|
10
|
+
* evaluated, so a throw during module evaluation is still reported on stderr
|
|
11
|
+
* rather than crashing silently. Adding a static import here would defeat
|
|
12
|
+
* that. `bin.ts` is the published bin shim; this module is also published as
|
|
13
|
+
* the `./main` subpath so the carrier (`@vitest-agent/plugin`) can ship its
|
|
14
|
+
* own `vitest-agent-mcp` bin over it.
|
|
15
|
+
*
|
|
16
|
+
* Every `process` read lives here, not in the server layer or the tools.
|
|
17
|
+
*
|
|
18
|
+
* @packageDocumentation
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Whether the stdio transport is live for this process — set once the
|
|
22
|
+
* whole server layer graph (the stdio protocol included) has been built.
|
|
23
|
+
* Read by the `uncaughtException` guard via `shouldExitOnUncaughtException`;
|
|
24
|
+
* see that function's doc comment for the judgment call this flag backs
|
|
25
|
+
* (issue #191).
|
|
26
|
+
*/
|
|
27
|
+
let transportConnected = false;
|
|
28
|
+
/**
|
|
29
|
+
* Formatter for the crash guards. Starts as a dependency-free fallback so a
|
|
30
|
+
* throw during module evaluation of the server graph is still described,
|
|
31
|
+
* and is swapped for the SDK's `safeFormatFatalError` once that import
|
|
32
|
+
* has resolved.
|
|
33
|
+
*/
|
|
34
|
+
let formatFatal = (error) => {
|
|
35
|
+
try {
|
|
36
|
+
return error instanceof Error ? error.stack ?? error.message : String(error);
|
|
37
|
+
} catch {
|
|
38
|
+
return "<unformattable error value>";
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Test-only crash injection, gated by an env var so it can never fire in a
|
|
43
|
+
* normal install. Exists so `__test__/bin-crash-resilience.e2e.test.ts` can
|
|
44
|
+
* exercise the guards against a *real* child process. Fires exactly once,
|
|
45
|
+
* on the next event-loop turn after the transport is known to be connected,
|
|
46
|
+
* so ordering relative to `transportConnected` is deterministic regardless
|
|
47
|
+
* of client-side handshake timing.
|
|
48
|
+
*/
|
|
49
|
+
const scheduleTestCrashInjection = () => {
|
|
50
|
+
const kind = process.env.VITEST_AGENT_MCP_TEST_INJECT_CRASH;
|
|
51
|
+
if (kind !== "unhandledRejection" && kind !== "uncaughtException") return;
|
|
52
|
+
setImmediate(() => {
|
|
53
|
+
if (kind === "unhandledRejection") Promise.reject(/* @__PURE__ */ new Error("[test-injected] unhandledRejection"));
|
|
54
|
+
else throw new Error("[test-injected] uncaughtException");
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Optional first positional argument: an initial Claude Code chat UUID (the
|
|
59
|
+
* host's `chatId`) to seed the MCP server's session association. Claude Code
|
|
60
|
+
* substitutes unknown `${...}` variables to literal text in some surfaces, so
|
|
61
|
+
* a literal substitution is treated as absent rather than seeding garbage.
|
|
62
|
+
*
|
|
63
|
+
* @param argv - the raw `process.argv`
|
|
64
|
+
* @returns the trimmed seed, or `null` when absent, empty, or a literal `${...}`
|
|
65
|
+
*/
|
|
66
|
+
const resolveInitialSessionId = (argv) => {
|
|
67
|
+
const first = argv[2];
|
|
68
|
+
if (first === void 0) return null;
|
|
69
|
+
const trimmed = first.trim();
|
|
70
|
+
if (trimmed.length === 0) return null;
|
|
71
|
+
if (trimmed.startsWith("${") && trimmed.endsWith("}")) return null;
|
|
72
|
+
return trimmed;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Run the vitest-agent MCP server over stdio. Owns the process: registers
|
|
76
|
+
* the crash guards, resolves the project directory and `data.db` path,
|
|
77
|
+
* recovers the host session context, and launches the server layer under
|
|
78
|
+
* `NodeRuntime.runMain`.
|
|
79
|
+
*
|
|
80
|
+
* Not re-exported from `index.ts` — a library consumer's import graph must
|
|
81
|
+
* not pull in the process-owning module.
|
|
82
|
+
*
|
|
83
|
+
* @public
|
|
84
|
+
*/
|
|
85
|
+
const main = async () => {
|
|
86
|
+
process.on("unhandledRejection", (reason) => {
|
|
87
|
+
process.stderr.write(`vitest-agent-mcp: unhandledRejection: ${formatFatal(reason)}\n`);
|
|
88
|
+
});
|
|
89
|
+
process.on("uncaughtException", (err, origin) => {
|
|
90
|
+
process.stderr.write(`vitest-agent-mcp: uncaughtException (${origin}): ${formatFatal(err)}\n`);
|
|
91
|
+
if (shouldExitOnUncaughtException(transportConnected)) {
|
|
92
|
+
process.exitCode = 1;
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
try {
|
|
97
|
+
const { safeFormatFatalError } = await import("./utils/safe-format-fatal-error.js");
|
|
98
|
+
formatFatal = safeFormatFatalError;
|
|
99
|
+
const NodeRuntime = await import("@effect/platform-node/NodeRuntime");
|
|
100
|
+
const NodeServices = await import("@effect/platform-node/NodeServices");
|
|
101
|
+
const NodeStdio = await import("@effect/platform-node/NodeStdio");
|
|
102
|
+
const { Cause, Effect, Exit, Layer, Logger, Runtime } = await import("effect");
|
|
103
|
+
const { PathResolutionLive, PlatformLive, recoverSessionContextFromSessionEnv, resolveDataPath, resolveLogFile, resolveLogLevel, resolveProjectDir } = await import("@vitest-agent/engine");
|
|
104
|
+
const { McpSession, sessionContextFromEnv } = await import("./session.js");
|
|
105
|
+
const { ServerLayer } = await import("./server.js");
|
|
106
|
+
const { CURRENT_MCP_VERSION } = await import("./version.js");
|
|
107
|
+
const env = process.env;
|
|
108
|
+
const projectDir = resolveProjectDir({
|
|
109
|
+
env,
|
|
110
|
+
cwd: process.cwd()
|
|
111
|
+
});
|
|
112
|
+
const initialSessionId = resolveInitialSessionId(process.argv);
|
|
113
|
+
const dbPath = await Effect.runPromise(resolveDataPath(projectDir).pipe(Effect.provide(PathResolutionLive(projectDir)), Effect.provide(NodeServices.layer)));
|
|
114
|
+
const recovered = sessionContextFromEnv(env);
|
|
115
|
+
const homeDir = env.HOME ?? env.USERPROFILE ?? "";
|
|
116
|
+
const Session = McpSession.layer({
|
|
117
|
+
cwd: projectDir,
|
|
118
|
+
initialSessionId: initialSessionId ?? recovered?.chatId ?? null,
|
|
119
|
+
initialContext: recovered,
|
|
120
|
+
recover: () => recoverSessionContextFromSessionEnv({
|
|
121
|
+
projectDir,
|
|
122
|
+
homeDir
|
|
123
|
+
})
|
|
124
|
+
});
|
|
125
|
+
const Main = ServerLayer({ version: CURRENT_MCP_VERSION }).pipe(Layer.provide(Session), Layer.provide(PlatformLive({
|
|
126
|
+
dbPath,
|
|
127
|
+
env,
|
|
128
|
+
logLevel: resolveLogLevel(env),
|
|
129
|
+
logFile: resolveLogFile(env)
|
|
130
|
+
})), Layer.provide(NodeStdio.layer), Layer.provide(Layer.succeed(Logger.LogToStderr, true)));
|
|
131
|
+
const Connected = Layer.effectDiscard(Effect.sync(() => {
|
|
132
|
+
transportConnected = true;
|
|
133
|
+
scheduleTestCrashInjection();
|
|
134
|
+
})).pipe(Layer.provide(Main));
|
|
135
|
+
const program = Layer.launch(Connected).pipe(Effect.provideService(Logger.LogToStderr, true));
|
|
136
|
+
NodeRuntime.runMain(program, { teardown: (exit, onExit) => Exit.isSuccess(exit) || Cause.hasInterruptsOnly(exit.cause) ? onExit(0) : Runtime.defaultTeardown(exit, onExit) });
|
|
137
|
+
} catch (err) {
|
|
138
|
+
process.stderr.write(`vitest-agent-mcp: startup failed: ${formatFatal(err)}\n`);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
//#endregion
|
|
144
|
+
export { main };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest-agent/mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
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": [
|
|
@@ -32,6 +32,11 @@
|
|
|
32
32
|
"import": "./index.js",
|
|
33
33
|
"default": "./index.js"
|
|
34
34
|
},
|
|
35
|
+
"./main": {
|
|
36
|
+
"types": "./main.d.ts",
|
|
37
|
+
"import": "./main.js",
|
|
38
|
+
"default": "./main.js"
|
|
39
|
+
},
|
|
35
40
|
"./package.json": "./package.json"
|
|
36
41
|
},
|
|
37
42
|
"bin": {
|
|
@@ -40,11 +45,9 @@
|
|
|
40
45
|
"dependencies": {
|
|
41
46
|
"@effect/platform-node": "4.0.0-rc.115",
|
|
42
47
|
"@effect/sql-sqlite-node": "4.0.0-rc.115",
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"
|
|
46
|
-
"effect": "4.0.0-rc.115",
|
|
47
|
-
"zod": "^4.6.2"
|
|
48
|
+
"@vitest-agent/engine": "0.1.0",
|
|
49
|
+
"@vitest-agent/sdk": "4.0.0",
|
|
50
|
+
"effect": "4.0.0-rc.115"
|
|
48
51
|
},
|
|
49
52
|
"peerDependencies": {
|
|
50
53
|
"vitest": "^5.0.0"
|
package/prompts/layer.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { McpSession } from "../session.js";
|
|
2
|
+
import { explainFailurePrompt } from "./explain-failure.js";
|
|
3
|
+
import { regressionSincePassPrompt } from "./regression-since-pass.js";
|
|
4
|
+
import { tddResumePrompt } from "./tdd-resume.js";
|
|
5
|
+
import { triagePrompt } from "./triage.js";
|
|
6
|
+
import { whyFlakyPrompt } from "./why-flaky.js";
|
|
7
|
+
import { wrapupPrompt } from "./wrapup.js";
|
|
8
|
+
import { Effect, Layer, Schema } from "effect";
|
|
9
|
+
import { McpSchema, McpServer } from "effect/unstable/ai";
|
|
10
|
+
|
|
11
|
+
//#region src/prompts/layer.ts
|
|
12
|
+
/**
|
|
13
|
+
* The six prompt names `PromptsLayer` registers, in registration order.
|
|
14
|
+
* Pinned against the `help` text by `__test__/help-drift.test.ts`.
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
const PROMPT_NAMES = [
|
|
19
|
+
"triage",
|
|
20
|
+
"why-flaky",
|
|
21
|
+
"regression-since-pass",
|
|
22
|
+
"explain-failure",
|
|
23
|
+
"tdd-resume",
|
|
24
|
+
"wrapup"
|
|
25
|
+
];
|
|
26
|
+
/** The `wrapup.kind` literal set, served as the argument's closed vocabulary. */
|
|
27
|
+
const WRAPUP_KINDS = [
|
|
28
|
+
"stop",
|
|
29
|
+
"session_end",
|
|
30
|
+
"pre_compact",
|
|
31
|
+
"tdd_handoff",
|
|
32
|
+
"user_prompt_nudge"
|
|
33
|
+
];
|
|
34
|
+
const toMessages = (result) => result.messages.map((m) => ({
|
|
35
|
+
role: m.role,
|
|
36
|
+
content: McpSchema.TextContent.make({ text: m.content.text })
|
|
37
|
+
}));
|
|
38
|
+
const projectArg = Schema.optionalKey(Schema.String.annotate({ description: "Filter to a specific project" }));
|
|
39
|
+
const Triage = McpServer.prompt({
|
|
40
|
+
name: PROMPT_NAMES[0],
|
|
41
|
+
description: "Orient toward a triage workflow over the most recent test run; compose triage_brief, failure_signature_get, hypothesis_record.",
|
|
42
|
+
parameters: { project: projectArg },
|
|
43
|
+
content: (args) => Effect.succeed(toMessages(triagePrompt(args.project !== void 0 ? { project: args.project } : {})))
|
|
44
|
+
});
|
|
45
|
+
const WhyFlaky = McpServer.prompt({
|
|
46
|
+
name: PROMPT_NAMES[1],
|
|
47
|
+
description: "Diagnose why a named test is flaky; compose test_history and failure_signature_get with timing/shared-state framing.",
|
|
48
|
+
parameters: {
|
|
49
|
+
test: Schema.String.annotate({ description: "Full hierarchical test name (e.g. 'Suite > nested > test')" }),
|
|
50
|
+
project: projectArg
|
|
51
|
+
},
|
|
52
|
+
content: (args) => Effect.succeed(toMessages(whyFlakyPrompt(args.project !== void 0 ? {
|
|
53
|
+
test: args.test,
|
|
54
|
+
project: args.project
|
|
55
|
+
} : { test: args.test })))
|
|
56
|
+
});
|
|
57
|
+
const RegressionSincePass = McpServer.prompt({
|
|
58
|
+
name: PROMPT_NAMES[2],
|
|
59
|
+
description: "Walk back from the test's most recent passing run to identify the change that broke it; compose test_history, commit_changes, turn_search.",
|
|
60
|
+
parameters: {
|
|
61
|
+
test: Schema.String.annotate({ description: "Full hierarchical test name" }),
|
|
62
|
+
project: projectArg
|
|
63
|
+
},
|
|
64
|
+
content: (args) => Effect.succeed(toMessages(regressionSincePassPrompt(args.project !== void 0 ? {
|
|
65
|
+
test: args.test,
|
|
66
|
+
project: args.project
|
|
67
|
+
} : { test: args.test })))
|
|
68
|
+
});
|
|
69
|
+
const ExplainFailure = McpServer.prompt({
|
|
70
|
+
name: PROMPT_NAMES[3],
|
|
71
|
+
description: "Synthesize a root-cause explanation from the recurrence history of a failure signature.",
|
|
72
|
+
parameters: { signature: Schema.String.annotate({ description: "16-char failure signature hex" }) },
|
|
73
|
+
content: (args) => Effect.succeed(toMessages(explainFailurePrompt({ signature: args.signature })))
|
|
74
|
+
});
|
|
75
|
+
const TddResume = McpServer.prompt({
|
|
76
|
+
name: PROMPT_NAMES[4],
|
|
77
|
+
description: "Resume the active TDD task from its current phase; iron-law reminder for evidence-bound transitions.",
|
|
78
|
+
parameters: { sessionId: Schema.optionalKey(Schema.String.annotate({ description: "Host session id (defaults to MCP server's recovered SessionContext)" })) },
|
|
79
|
+
content: (args) => Effect.gen(function* () {
|
|
80
|
+
const session = yield* McpSession;
|
|
81
|
+
const sessionId = args.sessionId ?? session.sessionContext.get()?.chatId ?? session.currentSessionId.get();
|
|
82
|
+
return toMessages(tddResumePrompt(sessionId === null ? {} : { sessionId }));
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
const Wrapup = McpServer.prompt({
|
|
86
|
+
name: PROMPT_NAMES[5],
|
|
87
|
+
description: "Surface the same wrapup content the post-hooks emit automatically.",
|
|
88
|
+
parameters: {
|
|
89
|
+
kind: Schema.optionalKey(Schema.Literals(WRAPUP_KINDS).annotate({ description: "Wrapup variant (default: user_prompt_nudge)" })),
|
|
90
|
+
since: Schema.optionalKey(Schema.String.annotate({ description: "ISO 8601 timestamp lower bound for activity to summarize" }))
|
|
91
|
+
},
|
|
92
|
+
content: (args) => {
|
|
93
|
+
const wrapupArgs = {};
|
|
94
|
+
if (args.kind !== void 0) wrapupArgs.kind = args.kind;
|
|
95
|
+
if (args.since !== void 0) wrapupArgs.since = args.since;
|
|
96
|
+
return Effect.succeed(toMessages(wrapupPrompt(wrapupArgs)));
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
/**
|
|
100
|
+
* Every framing prompt as one layer; merged into `ServerLayer` beside the
|
|
101
|
+
* toolkit registration. Requires `McpSession` for `tdd-resume`'s default.
|
|
102
|
+
*
|
|
103
|
+
* @public
|
|
104
|
+
*/
|
|
105
|
+
const PromptsLayer = Layer.mergeAll(Triage, WhyFlaky, RegressionSincePass, ExplainFailure, TddResume, Wrapup);
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
export { PROMPT_NAMES, PromptsLayer, WRAPUP_KINDS };
|