@systemfsoftware/stryker-js 13.1.0 → 15.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/dist/index.mjs CHANGED
@@ -1,7 +1,35 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
- import { $ as ConfigDocumentSchema, A as metricsResultFromFiles, B as initialExtendsStepState, C as readConfig, D as RunEvents, E as IdGenerator, F as WorkerLauncher, G as ExtendsStepResolve, H as ExtendsStepDone, I as make, J as ConfigFileNotFoundError, K as ConfigError, L as FileMatcher, M as reporterWorkerFactory, N as spawnReporterWorker, O as RunIdentity, P as makeWorkerClient, Q as defaultOptions, R as decideExtendsStep, S as loadConfigCell, T as RunEnvironment, U as ExtendsStepRead, V as StrykerError, W as ExtendsStepRefused, X as ConfigFileUnsupportedError, Y as ConfigFileUnreadableError, Z as createDefaultOptions, _ as ClassifyWorkerExitCommand, a as isVmRunner, at as ReadConfigCommand, b as describeErrors, c as vmTestRunnerConfig, ct as survivorsPriorReport, d as RunEventDrainLive, dt as OutOfMemoryError, et as ExtendsStepDocumentSchema, f as makeRunEventStream, ft as WorkerBootTimeoutError, g as layerWorkerProtocol, h as nodePlatformLayer, i as makeChildProcessTestRunner, it as MergeResult, j as MetricsResultFromReport, k as VerdictEnvelope, l as isCommandRunner, lt as checkGroupedPlans, m as IncrementalReportSchema, mt as CheckerSkippedRequested, n as strykerCell, nt as ImportedModuleSchema, o as testRunnerConfigOf, ot as extendsPropertySchema, p as RunEventWireLine, pt as CheckerAnsweredUnrequested, q as ConfigFileInvalidError, r as buildTestRunner, rt as MergeCommand, s as vmRunnerPluginUrl, st as forkOptionsSchema, t as mutationTestCell, tt as ExtendsStepStateSchema, u as RunEventDrain, ut as ChildProcessCrashedError, v as ClassifyWorkerExitDecision, w as validateOptions, x as forkCoreSchema, y as classifyWorkerExit, z as importModule } from "./run-stages.cell-rdoY0cVH.mjs";
3
- import { n as mergeConfigs } from "./merge-config-DZHwEkGY.mjs";
4
- import { C as SkippedFileRow, E as VerdictReached, S as RunStarted, T as VerdictMutant, _ as RunFailed, a as FormatRegistryRow, b as RunPhase, c as Heartbeat, d as PhaseEntered, f as PlanKnown, g as RunEvent, i as FormatRegistryResolved, k as PluginLoadFailureReason, l as HelpRendered, m as PluginsReported, n as StageError, o as FrameworkContributionRow, r as FormatClaimShadowingRow, s as FrameworkModuleRow, w as SkippedReported, y as RunMutantTested } from "./Run.schema-Cv2_Kup0.mjs";
2
+ import { i as Mutant_exports, l as Report_exports, n as mergeConfigs } from "./merge-config-zsGl1aWc.mjs";
3
+ import { $ as WorkerLauncher, A as classifyWorkerExit, At as OutOfMemoryError, B as SurvivorRef, C as nodePlatformLayer, Ct as MergeResult, D as git_diff_schema_exports, Dt as survivorsPriorReport, E as git_diff_service_exports, Et as forkOptionsSchema, F as readConfig, Ft as CheckerAnsweredUnrequested, G as generateRunId, H as RunEvents, I as RunEnvironment, It as CheckerSkippedRequested, J as metricsResultFromFiles, K as VerdictEnvelope, L as IdGenerator, M as loadConfigCell, Mt as OutputMode_exports, N as describeErrors, Nt as RunEvent_exports$1, O as ClassifyWorkerExitCommand, Ot as checkGroupedPlans, P as forkCoreSchema, Pt as SpanTaxonomy_exports, Q as makeWorkerClient, R as surfacedSurvivorsOf, S as IncrementalReportSchema, St as MergeCommand, T as GitDiff, Tt as extendsPropertySchema, U as RunIdentity, V as StrykerPackage, W as buildVerdictEnvelope, X as reporterWorkerFactory, Y as MetricsResultFromReport, Z as spawnReporterWorker, _ as isCommandRunner, _t as defaultOptions, a as MachineConsole, at as initialExtendsStepState, b as readProjectCell, bt as ExtendsStepStateSchema, c as prepareCell, ct as ExtendsStepRead, d as buildTestRunner, dt as ConfigError, et as make, f as makeChildProcessTestRunner, ft as ConfigFileInvalidError, g as vmTestRunnerConfig, gt as createDefaultOptions, h as vmRunnerPluginUrl, ht as ConfigFileUnsupportedError, i as makeRunEventStream, it as importModule, j as validateOptions, jt as WorkerBootTimeoutError, k as ClassifyWorkerExitDecision, kt as ChildProcessCrashedError, l as mutantDetailEventsOf, lt as ExtendsStepRefused, m as testRunnerConfigOf, mt as ConfigFileUnreadableError, n as RunEventDrain, nt as FileMatcher, o as HtmlReporter_exports, ot as StrykerError, p as isVmRunner, pt as ConfigFileNotFoundError, q as staticVerdictOf, r as RunEventDrainLive, rt as decideExtendsStep, s as mutationTestCell, st as ExtendsStepDone, t as strykerCell, tt as ReproducerSchema, u as instrumentCell, ut as ExtendsStepResolve, v as import_closure_cell_exports, vt as ConfigDocumentSchema, w as layerWorkerProtocol, wt as ReadConfigCommand, x as concurrencyCell, xt as ImportedModuleSchema, y as relativeNormalizedFileName, yt as ExtendsStepDocumentSchema, z as SurfacingFields } from "./run-stages-aBT_QAfO.mjs";
4
+ import { n as StageError } from "./Run.schema-DuaneDGd.mjs";
5
+ import { Cell, Sandwich, Workflow } from "@systemfsoftware/effect-cell-types";
6
+ import * as S from "effect/Schema";
7
+ import * as Option from "effect/Option";
8
+ import * as Context from "effect/Context";
9
+ import * as Effect from "effect/Effect";
10
+ import * as Boolean from "effect/Boolean";
11
+ import * as Arr from "effect/Array";
12
+ import * as Match from "effect/Match";
13
+ import * as Result from "effect/Result";
14
+ import { dual } from "effect/Function";
15
+ import "effect/Cause";
16
+ import * as FileSystem from "effect/FileSystem";
17
+ import * as Path from "effect/Path";
18
+ import * as Stream from "effect/Stream";
19
+ import * as Clock from "effect/Clock";
20
+ import * as Layer from "effect/Layer";
21
+ import * as Queue from "effect/Queue";
22
+ import "effect/Scope";
23
+ import * as SocketServer from "effect/socket/SocketServer";
24
+ import * as Fiber from "effect/Fiber";
25
+ import * as DateTime from "effect/DateTime";
26
+ import * as Ref from "effect/Ref";
27
+ import * as Stdio from "effect/Stdio";
28
+ import { NodeSocketServer } from "@effect/platform-node";
29
+ import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
30
+ import * as FiberSet from "effect/FiberSet";
31
+ import * as Socket from "effect/socket/Socket";
32
+ import { McpProtocol, McpServer, Tool, Toolkit } from "effect/ai";
5
33
  //#region src/Checker/mod.ts
6
34
  var Checker_exports = /* @__PURE__ */ __exportAll({
7
35
  CheckerAnsweredUnrequested: () => CheckerAnsweredUnrequested,
@@ -56,6 +84,423 @@ var Engine_exports = /* @__PURE__ */ __exportAll({
56
84
  strykerCell: () => strykerCell
57
85
  });
58
86
  //#endregion
87
+ //#region src/Feedback/Feedback.schema.ts
88
+ var FeedbackUnusable = class extends S.TaggedError()("FeedbackUnusable", { reason: S.String }) {
89
+ get message() {
90
+ return `Cannot record feedback: ${this.reason}`;
91
+ }
92
+ };
93
+ //#endregion
94
+ //#region src/Feedback/read-report.ts
95
+ const MUTATION_REPORT_FILE = "reports/mutation/mutation.json";
96
+ const FEEDBACK_FILE = "reports/mutation/feedback.jsonl";
97
+ const SURFACING_DEFAULTS = {
98
+ perLine: 1,
99
+ perFile: 7
100
+ };
101
+ const capsOf = (fields) => ({
102
+ perLine: Option.getOrElse(Option.fromNullishOr(fields.perLine), () => SURFACING_DEFAULTS.perLine),
103
+ perFile: Option.getOrElse(Option.fromNullishOr(fields.perFile), () => SURFACING_DEFAULTS.perFile)
104
+ });
105
+ const surfacingCapsOf = (report) => Option.getOrElse(Option.map(S.decodeUnknownOption(SurfacingFields)(report.config?.["surfacing"]), capsOf), () => SURFACING_DEFAULTS);
106
+ const readMutationReport = (basePath) => Effect.gen(function* () {
107
+ const fs = yield* FileSystem.FileSystem;
108
+ const file = (yield* Path.Path).resolve(basePath, MUTATION_REPORT_FILE);
109
+ const text = yield* fs.readFileString(file).pipe(Effect.mapError(() => FeedbackUnusable.make({ reason: `cannot read the finished mutation report at ${file}; run \`stryker run\` first` })));
110
+ return yield* Effect.fromResult(Result.mapError(S.decodeResult(S.fromJsonString(Report_exports.MutationTestResult))(text), (error) => FeedbackUnusable.make({ reason: `cannot decode the finished mutation report at ${file}: ${error.message}` })));
111
+ });
112
+ const readSurfacedSurvivors = (basePath) => Effect.map(readMutationReport(basePath), (report) => surfacedSurvivorsOf(report, surfacingCapsOf(report)));
113
+ //#endregion
114
+ //#region src/Feedback/record-feedback.workflow.ts
115
+ const RecordFeedbackTypeId = Symbol.for("@systemfsoftware/stryker-js/RecordFeedbackDecision");
116
+ var FeedbackRecorded = class extends S.TaggedClass()("FeedbackRecorded", {
117
+ id: Mutant_exports.MutantId,
118
+ judgment: RunEvent_exports$1.FeedbackJudgment,
119
+ reason: S.NullOr(S.String)
120
+ }) {
121
+ [RecordFeedbackTypeId] = RecordFeedbackTypeId;
122
+ };
123
+ var FeedbackRefused = class extends S.TaggedClass()("FeedbackRefused", { id: Mutant_exports.MutantId }) {
124
+ [RecordFeedbackTypeId] = RecordFeedbackTypeId;
125
+ };
126
+ const RecordFeedbackDecision = S.Union([FeedbackRecorded, FeedbackRefused]);
127
+ var RecordFeedbackCommand = class extends S.Class("RecordFeedbackCommand")({
128
+ id: Mutant_exports.MutantId,
129
+ judgment: RunEvent_exports$1.FeedbackJudgment,
130
+ reason: S.NullOr(S.String),
131
+ knownIds: S.Array(Mutant_exports.MutantId)
132
+ }) {
133
+ static [Workflow.InstrumentationBrand] = {};
134
+ };
135
+ const recordedOf = (command) => FeedbackRecorded.make({
136
+ id: command.id,
137
+ judgment: command.judgment,
138
+ reason: command.reason
139
+ });
140
+ const refusedOf = (command) => FeedbackRefused.make({ id: command.id });
141
+ const decidedOf$1 = (command) => Match.value(Arr.contains(command.knownIds, command.id)).pipe(Match.when(true, () => recordedOf(command)), Match.when(false, () => refusedOf(command)), Match.exhaustive);
142
+ const recordFeedback = Workflow.make({
143
+ command: RecordFeedbackCommand,
144
+ decision: RecordFeedbackDecision,
145
+ error: S.Never,
146
+ decide: (command) => Result.succeed(decidedOf$1(command))
147
+ });
148
+ //#endregion
149
+ //#region src/Feedback/Feedback.cell.ts
150
+ const appendLine = (basePath, line) => Effect.gen(function* () {
151
+ const fs = yield* FileSystem.FileSystem;
152
+ const path = yield* Path.Path;
153
+ const file = path.resolve(basePath, FEEDBACK_FILE);
154
+ yield* fs.makeDirectory(path.dirname(file), { recursive: true }).pipe(Effect.orDie);
155
+ yield* fs.writeFileString(file, `${line}\n`, { flag: "a" }).pipe(Effect.orDie);
156
+ });
157
+ const encodeLine = (line) => Effect.orDie(S.encodeEffect(S.fromJsonString(RunEvent_exports$1.FeedbackReported))(line));
158
+ const mutantIdOf = (id) => Effect.fromResult(Result.mapError(S.decodeResult(Mutant_exports.MutantId)(id), () => FeedbackUnusable.make({ reason: `${id} is not a 16-character lowercase hexadecimal mutant id` })));
159
+ const recordFeedbackCell = (request) => Effect.gen(function* () {
160
+ const id = yield* mutantIdOf(request.id);
161
+ const survivors = yield* readSurfacedSurvivors(request.basePath);
162
+ const decision = Result.getOrThrow(recordFeedback(RecordFeedbackCommand.make({
163
+ id,
164
+ judgment: request.judgment,
165
+ reason: request.reason,
166
+ knownIds: survivors.map((survivor) => survivor.id)
167
+ })));
168
+ return yield* Match.value(decision).pipe(Match.tag("FeedbackRecorded", (recorded) => encodeLine(RunEvent_exports$1.FeedbackReported.make({
169
+ id: recorded.id,
170
+ judgment: recorded.judgment,
171
+ reason: recorded.reason
172
+ })).pipe(Effect.flatMap((line) => appendLine(request.basePath, line)), Effect.as(RunEvent_exports$1.FeedbackReported.make({
173
+ id: recorded.id,
174
+ judgment: recorded.judgment,
175
+ reason: recorded.reason
176
+ })))), Match.tag("FeedbackRefused", () => Effect.fail(FeedbackUnusable.make({ reason: `no surfaced survivor ${request.id} in the mutation report; run \`stryker run\` first, or read the ids from list_survivors` }))), Match.exhaustive);
177
+ });
178
+ //#endregion
179
+ //#region src/output-mode.schema.ts
180
+ const ResolvedMode = S.Struct({
181
+ mode: OutputMode_exports.OutputMode,
182
+ signal: OutputMode_exports.ModeSignal,
183
+ stdoutIsTTY: S.Boolean
184
+ });
185
+ //#endregion
186
+ //#region src/Rerun/admit-mutant-rerun.workflow.ts
187
+ const MutantRerunTypeId = Symbol.for("@systemfsoftware/stryker-js/MutantRerunAdmission");
188
+ const PriorMutantShape = S.Struct({
189
+ ...Mutant_exports.Mutant.fields,
190
+ relativeFileName: S.String
191
+ });
192
+ var AdmitMutantRerunCommand = class extends S.Class("AdmitMutantRerunCommand")({
193
+ ids: S.Array(Mutant_exports.MutantId),
194
+ priorMutants: S.Array(PriorMutantShape),
195
+ priorReportPath: S.String
196
+ }) {
197
+ static [Workflow.InstrumentationBrand] = {};
198
+ };
199
+ var RerunAdmitted = class extends S.TaggedClass()("RerunAdmitted", {
200
+ ids: S.Array(Mutant_exports.MutantId),
201
+ mutateSpans: S.Array(S.String)
202
+ }) {
203
+ [MutantRerunTypeId] = MutantRerunTypeId;
204
+ };
205
+ var RerunRefused = class extends S.TaggedClass()("RerunRefused", {
206
+ exitClass: S.Literal("ConfigError"),
207
+ unknownIds: S.Array(Mutant_exports.MutantId),
208
+ reason: S.String
209
+ }) {
210
+ [MutantRerunTypeId] = MutantRerunTypeId;
211
+ };
212
+ const MutantRerunAdmission = S.Union([RerunAdmitted, RerunRefused]);
213
+ const spanOf = (mutant) => `${mutant.relativeFileName}:${mutant.location.start.line}:${mutant.location.start.column}-${mutant.location.end.line}:${mutant.location.end.column}`;
214
+ const requestedIdsOf = (command) => Arr.dedupe(command.ids);
215
+ const priorMutantOf = (command, id) => Arr.findFirst(command.priorMutants, (mutant) => mutant.id === id);
216
+ const unknownIdsOf = (command) => Arr.filter(requestedIdsOf(command), (id) => Option.isNone(priorMutantOf(command, id)));
217
+ const mutateSpansOf = (command) => Arr.dedupe(Arr.getSomes(Arr.map(requestedIdsOf(command), (id) => Option.map(priorMutantOf(command, id), spanOf))));
218
+ const refusalOf = (command, unknownIds) => RerunRefused.make({
219
+ exitClass: "ConfigError",
220
+ unknownIds,
221
+ reason: `Unknown mutant id(s): ${Arr.join(unknownIds, ", ")}. None of them appears in the prior mutation report at ${command.priorReportPath}; run \`stryker run\` to write a report that lists the ids you can re-run.`
222
+ });
223
+ const admittedOf = (command) => RerunAdmitted.make({
224
+ ids: requestedIdsOf(command),
225
+ mutateSpans: mutateSpansOf(command)
226
+ });
227
+ const decidedOf = (command) => {
228
+ const unknownIds = unknownIdsOf(command);
229
+ return Option.match(Arr.head(unknownIds), {
230
+ onNone: () => admittedOf(command),
231
+ onSome: () => refusalOf(command, unknownIds)
232
+ });
233
+ };
234
+ const admitMutantRerun = Workflow.make({
235
+ command: AdmitMutantRerunCommand,
236
+ decision: MutantRerunAdmission,
237
+ error: S.Never,
238
+ decide: (command) => Result.succeed(decidedOf(command))
239
+ });
240
+ //#endregion
241
+ //#region src/Survivors/Survivors.schema.ts
242
+ const PriorReportDocument = S.Struct({
243
+ config: S.optional(S.Record(S.String, S.Unknown)),
244
+ framework: S.optional(S.Struct({ version: S.optional(S.String) })),
245
+ files: S.Record(S.String, S.Struct({
246
+ source: S.String,
247
+ mutants: S.Array(S.Struct({
248
+ id: Mutant_exports.MutantId,
249
+ mutatorName: S.String,
250
+ replacement: S.optional(S.String),
251
+ status: Mutant_exports.MutantStatusSchema,
252
+ location: Mutant_exports.Location
253
+ }))
254
+ }))
255
+ });
256
+ //#endregion
257
+ //#region src/Rerun/Rerun.cell.ts
258
+ const DEFAULT_PRIOR_REPORT = "reports/mutation/mutation.json";
259
+ const resolveRerunOptions = Effect.fnUntraced(function* (input) {
260
+ return yield* readConfig(input.cliOptions, {
261
+ command: "run",
262
+ mode: input.mode
263
+ });
264
+ });
265
+ const priorReportText = Effect.fnUntraced(function* (priorReportPath) {
266
+ return yield* (yield* FileSystem.FileSystem).readFileString(priorReportPath).pipe(Effect.option, Effect.map(Option.getOrElse(() => "")));
267
+ });
268
+ const priorMutantsOf = (text, basePath) => Option.match(S.decodeOption(S.fromJsonString(PriorReportDocument))(text), {
269
+ onNone: () => [],
270
+ onSome: (document) => Object.entries(document.files).flatMap(([file, fileResult]) => {
271
+ const fileName = `${basePath}/${file}`;
272
+ const relativeFileName = relativeNormalizedFileName(fileName, basePath);
273
+ return fileResult.mutants.map((mutant) => ({
274
+ _tag: "Mutant",
275
+ id: mutant.id,
276
+ fileName: Mutant_exports.CanonicalFileName.make(fileName),
277
+ mutatorName: Mutant_exports.MutatorName.make(mutant.mutatorName),
278
+ replacement: mutant.replacement ?? mutant.mutatorName,
279
+ location: mutant.location,
280
+ relativeFileName
281
+ }));
282
+ })
283
+ });
284
+ const readMutantRerun = Effect.fnUntraced(function* (input) {
285
+ const resolvedOptions = yield* resolveRerunOptions({
286
+ cliOptions: input.cliOptions,
287
+ mode: input.mode
288
+ });
289
+ const priorReportPath = DEFAULT_PRIOR_REPORT;
290
+ const text = yield* priorReportText(priorReportPath);
291
+ return {
292
+ ids: [...input.ids],
293
+ priorMutants: priorMutantsOf(text, input.basePath),
294
+ priorReportPath,
295
+ resolvedOptions,
296
+ settle: input.settle
297
+ };
298
+ });
299
+ const mutantRerunAdmissionCell = Sandwich.named(SpanTaxonomy_exports.Spans.rerun.name)(readMutantRerun).decide(admitMutantRerun).write({
300
+ RerunAdmitted: (admitted, raw) => raw.settle.runAdmitted({
301
+ ids: admitted.ids,
302
+ mutateSpans: admitted.mutateSpans,
303
+ resolvedOptions: raw.resolvedOptions
304
+ }),
305
+ RerunRefused: (refused) => Effect.flatMap(S.decodeEffect(RerunRefused)(refused), (decoded) => Effect.fail(decoded)),
306
+ CommandRejected: ({ issue }) => Effect.fail(RerunRefused.make({
307
+ exitClass: "ConfigError",
308
+ unknownIds: [],
309
+ reason: issue
310
+ }))
311
+ });
312
+ //#endregion
313
+ //#region src/Mcp/mcp-tools.schema.ts
314
+ const MutantDetail = S.Struct({
315
+ id: Mutant_exports.MutantId,
316
+ status: Mutant_exports.MutantStatusSchema,
317
+ coveringTests: S.Array(S.String),
318
+ killedBy: S.NullOr(S.String),
319
+ reproducer: S.String,
320
+ diff: S.NullOr(S.String)
321
+ });
322
+ var MutantUnusable = class extends S.TaggedError()("MutantUnusable", { id: Mutant_exports.MutantId }) {
323
+ get message() {
324
+ return `No mutant ${this.id} in the finished mutation report; run \`stryker run\` first, or read a known id from list_survivors.`;
325
+ }
326
+ };
327
+ var RerunUnusable = class extends S.TaggedError()("RerunUnusable", {
328
+ id: Mutant_exports.MutantId,
329
+ reason: S.String
330
+ }) {
331
+ get message() {
332
+ return this.reason;
333
+ }
334
+ };
335
+ const ShowMutantFailure = S.Union([MutantUnusable, FeedbackUnusable]);
336
+ const RerunMutantFailure = S.Union([MutantUnusable, RerunUnusable]);
337
+ //#endregion
338
+ //#region src/Mcp/mcp-tools.ts
339
+ const reportDependencies = [FileSystem.FileSystem, Path.Path];
340
+ const engineDependencies = [
341
+ FileSystem.FileSystem,
342
+ Path.Path,
343
+ Stdio.Stdio,
344
+ ChildProcessSpawner.ChildProcessSpawner,
345
+ GitDiff,
346
+ WorkerLauncher
347
+ ];
348
+ const ListSurvivors = Tool.make("list_survivors", {
349
+ description: "List the surfaced survivors of the finished mutation report, capped exactly as the CLI caps them: at most one per line and seven per file.",
350
+ success: S.Array(SurvivorRef),
351
+ failure: FeedbackUnusable,
352
+ dependencies: reportDependencies
353
+ });
354
+ const ShowMutant = Tool.make("show_mutant", {
355
+ description: "Show one mutant's status, covering tests, killing test, reproducer command, and diff against the finished mutation report.",
356
+ parameters: S.Struct({ id: Mutant_exports.MutantId }),
357
+ success: MutantDetail,
358
+ failure: ShowMutantFailure,
359
+ dependencies: reportDependencies
360
+ });
361
+ const RerunMutant = Tool.make("rerun_mutant", {
362
+ description: "Re-run one mutant by id through the run pipeline, restricted to that mutant, and report its fresh status, covering tests, killing test, and reproducer.",
363
+ parameters: S.Struct({ id: Mutant_exports.MutantId }),
364
+ success: MutantDetail,
365
+ failure: RerunMutantFailure,
366
+ dependencies: engineDependencies
367
+ });
368
+ const ReportUsefulness = Tool.make("report_usefulness", {
369
+ description: "Record a useful or not-useful judgment for one surfaced survivor. The judgment is appended to reports/mutation/feedback.jsonl as a `feedback` stream line.",
370
+ parameters: S.Struct({
371
+ id: Mutant_exports.MutantId,
372
+ judgment: RunEvent_exports$1.FeedbackJudgment,
373
+ reason: S.String.pipe(S.NullOr, S.optional)
374
+ }),
375
+ success: RunEvent_exports$1.FeedbackReported,
376
+ failure: FeedbackUnusable,
377
+ dependencies: reportDependencies
378
+ });
379
+ const mcpToolkit = Toolkit.make(ListSurvivors, ShowMutant, RerunMutant, ReportUsefulness);
380
+ //#endregion
381
+ //#region src/Mcp/mcp-server.cell.ts
382
+ const MCP_RUN_ID = RunEvent_exports$1.RunId.make("01ARZ3NDEKTSV4RRFFQ69G5FAM");
383
+ const REPRODUCERS_FILE = "reports/mutation/reproducers.json";
384
+ const MCP_SERVER_INSTRUCTIONS = "Stryker mutation testing. Use list_survivors to read the surfaced survivors of the finished report, show_mutant to inspect one, rerun_mutant to re-run one through the run pipeline, and report_usefulness to record whether a survivor was worth acting on.";
385
+ const MCP_MODE = ResolvedMode.make({
386
+ mode: "machine",
387
+ signal: "tool",
388
+ stdoutIsTTY: false
389
+ });
390
+ const readReproducers = (basePath) => Effect.gen(function* () {
391
+ const fs = yield* FileSystem.FileSystem;
392
+ const path = yield* Path.Path;
393
+ const reproducerList = S.Array(ReproducerSchema).pipe(S.fromJsonString);
394
+ const text = yield* fs.readFileString(path.resolve(basePath, REPRODUCERS_FILE)).pipe(Effect.orElseSucceed(() => ""));
395
+ return Option.getOrElse(S.decodeOption(reproducerList)(text), () => []);
396
+ });
397
+ const diffOf = (reproducers, id) => Option.getOrElse(Option.map(Arr.findFirst(reproducers, (reproducer) => reproducer.id === id), (reproducer) => reproducer.diff), () => null);
398
+ const readDiff = (basePath, id) => Effect.map(readReproducers(basePath), (reproducers) => diffOf(reproducers, id));
399
+ const mutantsOf = (report) => Arr.flatMap(Object.values(report.files), (file) => file.mutants);
400
+ const mutantAt = (report, id) => Arr.findFirst(mutantsOf(report), (mutant) => mutant.id === id);
401
+ const coveringTestsOf = (mutant) => [...mutant.coveredBy ?? []];
402
+ const killedByOf = (mutant) => Option.getOrNull(Arr.head([...mutant.killedBy ?? []]));
403
+ const detailOf = (id, mutant, diff) => ({
404
+ id,
405
+ status: mutant.status,
406
+ coveringTests: coveringTestsOf(mutant),
407
+ killedBy: killedByOf(mutant),
408
+ reproducer: `stryker run --mutant ${id}`,
409
+ diff
410
+ });
411
+ const showMutant = (basePath, id) => Effect.gen(function* () {
412
+ const report = yield* readMutationReport(basePath);
413
+ const found = yield* Effect.fromOption(mutantAt(report, id)).pipe(Effect.mapError(() => MutantUnusable.make({ id })));
414
+ const diff = yield* readDiff(basePath, id);
415
+ return detailOf(id, found, diff);
416
+ });
417
+ const restrictedOptionsOf = ({ ids, mutateSpans, resolvedOptions }) => ({
418
+ ...resolvedOptions,
419
+ mutate: [...mutateSpans],
420
+ mutantIds: [...ids],
421
+ incremental: true
422
+ });
423
+ const runRestricted = (basePath, options) => Effect.gen(function* () {
424
+ const queue = yield* Queue.bounded(RunEvent_exports$1.RunEvent.QUEUE_BOUND);
425
+ const environment = {
426
+ runId: MCP_RUN_ID,
427
+ resolvedMode: MCP_MODE,
428
+ runStartedAt: 0,
429
+ basePath,
430
+ builtinReporters: {},
431
+ allowConsoleColors: false
432
+ };
433
+ const runLayer = Layer.merge(RunEnvironment.stage(environment, queue), MachineConsole.captureLayer.pipe(Layer.provide(MachineConsole.layer)));
434
+ return yield* mutationTestCell.run({
435
+ cliOptions: options,
436
+ targetMutatePatterns: void 0
437
+ }).pipe(Effect.provide(runLayer), Effect.scoped, Effect.orDie);
438
+ });
439
+ const NO_RESULTS = {
440
+ results: [],
441
+ verdict: null
442
+ };
443
+ const resultsOf = (settled) => (settled ?? NO_RESULTS).results;
444
+ const reportedOf = (results, id) => Effect.fromOption(Arr.head(mutantDetailEventsOf({
445
+ requested: Option.some([id]),
446
+ results
447
+ }))).pipe(Effect.mapError(() => MutantUnusable.make({ id })));
448
+ const reasonOfRerun = (error) => S.is(RerunRefused)(error) ? error.reason : error.message;
449
+ const rerunFailureOf = (id) => (error) => S.is(MutantUnusable)(error) ? error : RerunUnusable.make({
450
+ id,
451
+ reason: reasonOfRerun(error)
452
+ });
453
+ const rerunMutant = (basePath, id) => Effect.gen(function* () {
454
+ const settled = yield* mutantRerunAdmissionCell.run({
455
+ ids: [id],
456
+ cliOptions: {},
457
+ mode: MCP_MODE.mode,
458
+ basePath,
459
+ settle: { runAdmitted: ({ ids, mutateSpans, resolvedOptions }) => runRestricted(basePath, restrictedOptionsOf({
460
+ ids,
461
+ mutateSpans,
462
+ resolvedOptions
463
+ })) }
464
+ }).pipe(Effect.catchTag("SchemaError", Effect.die), Effect.mapError(rerunFailureOf(id)));
465
+ const reported = yield* reportedOf(resultsOf(settled), id);
466
+ const diff = yield* readDiff(basePath, id);
467
+ return {
468
+ id: reported.id,
469
+ status: reported.status,
470
+ coveringTests: [...reported.coveringTests],
471
+ killedBy: reported.killedBy,
472
+ reproducer: reported.reproducer ?? `stryker run --mutant ${id}`,
473
+ diff
474
+ };
475
+ });
476
+ const handlers = (basePath) => mcpToolkit.toLayer({
477
+ list_survivors: () => readSurfacedSurvivors(basePath),
478
+ show_mutant: ({ id }) => showMutant(basePath, id),
479
+ rerun_mutant: ({ id }) => rerunMutant(basePath, id),
480
+ report_usefulness: ({ id, judgment, reason }) => recordFeedbackCell({
481
+ basePath,
482
+ id,
483
+ judgment,
484
+ reason: reason ?? null
485
+ })
486
+ });
487
+ const mcpServerLayer = ({ basePath }) => Layer.merge(McpServer.layerStdio({
488
+ name: "stryker",
489
+ version: StrykerPackage.version,
490
+ instructions: MCP_SERVER_INSTRUCTIONS,
491
+ protocols: [McpProtocol.v2025_06_18]
492
+ }), McpServer.toolkit(mcpToolkit)).pipe(Layer.provide(handlers(basePath)), Layer.provide(MachineConsole.layer));
493
+ //#endregion
494
+ //#region src/Mcp/mod.ts
495
+ var Mcp_exports = /* @__PURE__ */ __exportAll({
496
+ MutantDetail: () => MutantDetail,
497
+ MutantUnusable: () => MutantUnusable,
498
+ RerunMutantFailure: () => RerunMutantFailure,
499
+ ShowMutantFailure: () => ShowMutantFailure,
500
+ mcpServerLayer: () => mcpServerLayer,
501
+ mcpToolkit: () => mcpToolkit
502
+ });
503
+ //#endregion
59
504
  //#region src/Plugin/mod.ts
60
505
  var Plugin_exports = /* @__PURE__ */ __exportAll({
61
506
  REPORTER_EVENT_BATCH_BOUND: () => 128,
@@ -72,35 +517,668 @@ var Plugin_exports = /* @__PURE__ */ __exportAll({
72
517
  //#endregion
73
518
  //#region src/RunEvent/mod.ts
74
519
  var RunEvent_exports = /* @__PURE__ */ __exportAll({
75
- FormatClaimShadowingRow: () => FormatClaimShadowingRow,
76
- FormatRegistryResolved: () => FormatRegistryResolved,
77
- FormatRegistryRow: () => FormatRegistryRow,
78
- FrameworkContributionRow: () => FrameworkContributionRow,
79
- FrameworkModuleRow: () => FrameworkModuleRow,
80
- Heartbeat: () => Heartbeat,
81
- HelpRendered: () => HelpRendered,
82
520
  MetricsResultFromReport: () => MetricsResultFromReport,
83
- PhaseEntered: () => PhaseEntered,
84
- PlanKnown: () => PlanKnown,
85
- PluginLoadFailureReason: () => PluginLoadFailureReason,
86
- PluginsReported: () => PluginsReported,
87
- RunEvent: () => RunEvent,
88
521
  RunEventDrain: () => RunEventDrain,
89
522
  RunEventDrainLive: () => RunEventDrainLive,
90
- RunEventWireLine: () => RunEventWireLine,
91
523
  RunEvents: () => RunEvents,
92
- RunFailed: () => RunFailed,
93
524
  RunIdentity: () => RunIdentity,
94
- RunMutantTested: () => RunMutantTested,
95
- RunPhase: () => RunPhase,
96
- RunStarted: () => RunStarted,
97
- SkippedFileRow: () => SkippedFileRow,
98
- SkippedReported: () => SkippedReported,
99
525
  VerdictEnvelope: () => VerdictEnvelope,
100
- VerdictMutant: () => VerdictMutant,
101
- VerdictReached: () => VerdictReached,
526
+ buildVerdictEnvelope: () => buildVerdictEnvelope,
102
527
  makeRunEventStream: () => makeRunEventStream,
103
- metricsResultFromFiles: () => metricsResultFromFiles
528
+ metricsResultFromFiles: () => metricsResultFromFiles,
529
+ staticVerdictOf: () => staticVerdictOf
530
+ });
531
+ //#endregion
532
+ //#region src/Serve/msp-framing.schema.ts
533
+ var msp_framing_schema_exports = /* @__PURE__ */ __exportAll({
534
+ CONTENT_LENGTH_HEADER: () => CONTENT_LENGTH_HEADER,
535
+ FrameAction: () => FrameAction,
536
+ FramingBuffer: () => FramingBuffer,
537
+ FramingStep: () => FramingStep,
538
+ HeaderlessAction: () => HeaderlessAction,
539
+ IncompleteAction: () => IncompleteAction,
540
+ decodeUtf8: () => decodeUtf8,
541
+ emptyFraming: () => emptyFraming,
542
+ encodeUtf8: () => encodeUtf8,
543
+ frameOf: () => frameOf,
544
+ readFrames: () => readFrames
545
+ });
546
+ const CONTENT_LENGTH_HEADER = /content-length:\s*(\d+)/iu;
547
+ const textEncoder = new TextEncoder();
548
+ const textDecoder = new TextDecoder();
549
+ const encodeUtf8 = (text) => textEncoder.encode(text);
550
+ const decodeUtf8 = (bytes) => textDecoder.decode(bytes);
551
+ const FramingBuffer = S.Struct({ bytes: S.Uint8Array });
552
+ const emptyFraming = { bytes: /* @__PURE__ */ new Uint8Array(0) };
553
+ const FramingStep = S.Struct({
554
+ buffer: FramingBuffer,
555
+ frames: S.Array(S.String),
556
+ errors: S.Array(S.String)
557
+ });
558
+ const HEADER_END_BYTES = new Uint8Array([
559
+ 13,
560
+ 10,
561
+ 13,
562
+ 10
563
+ ]);
564
+ const HEADERLESS = "a Content-Length header was expected before the message body";
565
+ const concat = (left, right) => {
566
+ if (left.length === 0) return right;
567
+ const joined = new Uint8Array(left.length + right.length);
568
+ joined.set(left, 0);
569
+ joined.set(right, left.length);
570
+ return joined;
571
+ };
572
+ const isHeaderEndAt = (bytes, index) => HEADER_END_BYTES.every((byte, offset) => bytes[index + offset] === byte);
573
+ const headerEndOf = (bytes) => Option.map(Option.filter(Option.fromUndefinedOr(bytes.findIndex((_byte, index) => isHeaderEndAt(bytes, index))), (found) => found >= 0), (found) => found + HEADER_END_BYTES.length);
574
+ const declaredLengthOf = (header) => Option.filter(Option.map(Option.fromNullishOr(CONTENT_LENGTH_HEADER.exec(header)), (match) => Number(match[1])), (size) => Number.isSafeInteger(size) && size >= 0);
575
+ const IncompleteAction = S.TaggedStruct("Incomplete", { rest: S.Uint8Array });
576
+ const FrameAction = S.TaggedStruct("Frame", {
577
+ rest: S.Uint8Array,
578
+ frame: S.String
579
+ });
580
+ const HeaderlessAction = S.TaggedStruct("Headerless", { rest: S.Uint8Array });
581
+ const bodyActionOf = (bytes, headerEnd, size) => Match.value(bytes.length - headerEnd < size).pipe(Match.when(true, () => IncompleteAction.make({ rest: bytes })), Match.when(false, () => FrameAction.make({
582
+ rest: bytes.subarray(headerEnd + size),
583
+ frame: decodeUtf8(bytes.subarray(headerEnd, headerEnd + size))
584
+ })), Match.exhaustive);
585
+ const withinHeader = (bytes, headerEnd) => Option.match(declaredLengthOf(decodeUtf8(bytes.subarray(0, headerEnd))), {
586
+ onNone: () => HeaderlessAction.make({ rest: bytes.subarray(headerEnd) }),
587
+ onSome: (size) => bodyActionOf(bytes, headerEnd, size)
588
+ });
589
+ const actionOf = (bytes) => Option.match(headerEndOf(bytes), {
590
+ onNone: () => IncompleteAction.make({ rest: bytes }),
591
+ onSome: (headerEnd) => withinHeader(bytes, headerEnd)
592
+ });
593
+ const readStep = (state) => Match.value(actionOf(state.rest)).pipe(Match.tag("Incomplete", () => ({
594
+ buffer: { bytes: state.rest },
595
+ frames: state.frames,
596
+ errors: state.errors
597
+ })), Match.tag("Frame", (frame) => {
598
+ state.frames.push(frame.frame);
599
+ return readStep({
600
+ ...state,
601
+ rest: frame.rest
602
+ });
603
+ }), Match.tag("Headerless", (headerless) => {
604
+ state.errors.push(HEADERLESS);
605
+ return readStep({
606
+ ...state,
607
+ rest: headerless.rest
608
+ });
609
+ }), Match.exhaustive);
610
+ const readFrames = dual(2, (buffer, chunk) => readStep({
611
+ rest: concat(buffer.bytes, chunk),
612
+ frames: [],
613
+ errors: []
614
+ }));
615
+ const frameOf = (payload) => {
616
+ const body = encodeUtf8(payload);
617
+ return concat(encodeUtf8(`Content-Length: ${body.length}\r\n\r\n`), body);
618
+ };
619
+ //#endregion
620
+ //#region src/Serve/msp.schema.ts
621
+ /**
622
+ * The Mutation Server Protocol payloads this server speaks, as Effect schemas.
623
+ *
624
+ * The shapes are the published ones from `mutation-server-protocol`
625
+ * (stryker-mutator/editor-plugins, `packages/mutation-server-protocol`,
626
+ * published 0.4.1 at commit 47c1ee72b6238620474ec23082369491473d03dd —
627
+ * https://cdn.jsdelivr.net/npm/mutation-server-protocol@0.4.1/README.md):
628
+ * `ConfigureParams`/`ConfigureResult`, `DiscoverParams`/`DiscoverResult`,
629
+ * `MutationTestParams`/`MutationTestResult`, and the
630
+ * `reportMutationTestProgress` notification. Locations reuse the
631
+ * mutation-testing-report schema's 1-based, end-exclusive `Position`/`Location`
632
+ * through `Report`, which is the same base this engine already emits.
633
+ *
634
+ * `MSP_PROTOCOL_VERSION` is the version StrykerJS v10 answers `configure` with
635
+ * (its `StrykerServer.configure` returns `{ version: '0.4.0' }`); the protocol
636
+ * asks the server to name the version it supports, so the answer follows the
637
+ * implementation clients were written against rather than the npm release.
638
+ *
639
+ * The base protocol is JSON-RPC 2.0: a request with an `id` is answered with a
640
+ * matching result or error, a request without one is a notification, and the
641
+ * server may push the progress notification at any time.
642
+ */
643
+ var msp_schema_exports = /* @__PURE__ */ __exportAll({
644
+ ConfigureParams: () => ConfigureParams,
645
+ ConfigureResult: () => ConfigureResult,
646
+ DiscoverParams: () => DiscoverParams,
647
+ DiscoverResult: () => DiscoverResult,
648
+ DiscoveredFile: () => DiscoveredFile,
649
+ DiscoveredFiles: () => DiscoveredFiles,
650
+ DiscoveredMutant: () => DiscoveredMutant,
651
+ FileRange: () => FileRange,
652
+ JsonRpcErrorObject: () => JsonRpcErrorObject,
653
+ JsonRpcErrorResponse: () => JsonRpcErrorResponse,
654
+ JsonRpcId: () => JsonRpcId,
655
+ JsonRpcRequest: () => JsonRpcRequest,
656
+ JsonRpcResponse: () => JsonRpcResponse,
657
+ JsonRpcResultResponse: () => JsonRpcResultResponse,
658
+ JsonRpcVersion: () => JsonRpcVersion,
659
+ MSP_INTERNAL_ERROR: () => MSP_INTERNAL_ERROR,
660
+ MSP_INVALID_PARAMS: () => MSP_INVALID_PARAMS,
661
+ MSP_INVALID_REQUEST: () => MSP_INVALID_REQUEST,
662
+ MSP_METHODS: () => MSP_METHODS,
663
+ MSP_METHOD_NOT_FOUND: () => MSP_METHOD_NOT_FOUND,
664
+ MSP_PARSE_ERROR: () => MSP_PARSE_ERROR,
665
+ MSP_PROTOCOL_VERSION: () => MSP_PROTOCOL_VERSION,
666
+ MSP_SERVER_BUSY: () => MSP_SERVER_BUSY,
667
+ MspMethod: () => MspMethod,
668
+ MutationTestParams: () => MutationTestParams,
669
+ MutationTestResult: () => MutationTestResult,
670
+ ReportMutationTestProgress: () => ReportMutationTestProgress,
671
+ ServeError: () => ServeError,
672
+ decodeConfigureParams: () => decodeConfigureParams,
673
+ decodeDiscoverParams: () => decodeDiscoverParams,
674
+ decodeJsonRpcRequest: () => decodeJsonRpcRequest,
675
+ decodeMutationTestParams: () => decodeMutationTestParams,
676
+ encodeJsonRpcResponse: () => encodeJsonRpcResponse,
677
+ encodeProgressNotification: () => encodeProgressNotification,
678
+ restrictPatternsOf: () => restrictPatternsOf
679
+ });
680
+ var ServeError = class extends S.TaggedError()("ServeError", {
681
+ reason: S.String,
682
+ cause: S.optionalKey(S.Unknown)
683
+ }) {
684
+ get message() {
685
+ return this.reason;
686
+ }
687
+ };
688
+ const MSP_PROTOCOL_VERSION = "0.4.0";
689
+ const MSP_METHODS = {
690
+ configure: "configure",
691
+ discover: "discover",
692
+ mutationTest: "mutationTest",
693
+ reportMutationTestProgress: "reportMutationTestProgress"
694
+ };
695
+ const MspMethod = S.Literals([
696
+ MSP_METHODS.configure,
697
+ MSP_METHODS.discover,
698
+ MSP_METHODS.mutationTest,
699
+ MSP_METHODS.reportMutationTestProgress
700
+ ]);
701
+ const JsonRpcVersion = S.Literal("2.0");
702
+ const JsonRpcId = S.Union([
703
+ S.String,
704
+ S.Finite,
705
+ S.Null
706
+ ]);
707
+ const JsonRpcRequest = S.Struct({
708
+ jsonrpc: JsonRpcVersion,
709
+ id: S.optionalKey(JsonRpcId),
710
+ method: S.String,
711
+ params: S.optionalKey(S.Json)
712
+ });
713
+ const JsonRpcErrorObject = S.Struct({
714
+ code: S.Int,
715
+ message: S.String,
716
+ data: S.optionalKey(S.Json)
717
+ });
718
+ const MSP_PARSE_ERROR = -32700;
719
+ const MSP_INVALID_REQUEST = -32600;
720
+ const MSP_METHOD_NOT_FOUND = -32601;
721
+ const MSP_INVALID_PARAMS = -32602;
722
+ const MSP_INTERNAL_ERROR = -32603;
723
+ const MSP_SERVER_BUSY = -32e3;
724
+ const JsonRpcErrorResponse = S.Struct({
725
+ jsonrpc: JsonRpcVersion,
726
+ id: S.NullOr(JsonRpcId),
727
+ error: JsonRpcErrorObject
728
+ });
729
+ const JsonRpcResultResponse = S.Struct({
730
+ jsonrpc: JsonRpcVersion,
731
+ id: JsonRpcId,
732
+ result: S.Unknown
733
+ });
734
+ const JsonRpcResponse = S.Union([JsonRpcResultResponse, JsonRpcErrorResponse]);
735
+ const FileRange = S.Struct({
736
+ path: S.String,
737
+ range: S.optionalKey(Report_exports.Location)
738
+ });
739
+ const ConfigureParams = S.Struct({ configFilePath: S.optionalKey(S.String) });
740
+ const ConfigureResult = S.Struct({ version: S.String });
741
+ const DiscoveredMutant = S.Struct({
742
+ id: S.String,
743
+ location: Report_exports.Location,
744
+ description: S.optionalKey(S.String),
745
+ mutatorName: S.String,
746
+ replacement: S.optionalKey(S.String)
747
+ });
748
+ const DiscoveredFile = S.Struct({ mutants: S.Array(DiscoveredMutant) });
749
+ const DiscoveredFiles = S.Record(S.String, DiscoveredFile);
750
+ const FileRanges = S.Array(FileRange);
751
+ const DiscoverParams = S.Struct({ files: FileRanges.pipe(S.optionalKey) });
752
+ const DiscoverResult = S.Struct({ files: DiscoveredFiles });
753
+ const MutationTestParams = S.Struct({
754
+ files: FileRanges.pipe(S.optionalKey),
755
+ mutants: S.optionalKey(DiscoveredFiles)
756
+ });
757
+ const MutationTestResult = S.Struct({ files: S.Record(S.String, S.Struct({ mutants: S.Array(Report_exports.MutantResult) })) });
758
+ const ReportMutationTestProgress = S.Struct({
759
+ jsonrpc: JsonRpcVersion,
760
+ method: S.Literal(MSP_METHODS.reportMutationTestProgress),
761
+ params: MutationTestResult
762
+ });
763
+ const encodeJsonRpcResponse = S.encodeResult(S.fromJsonString(JsonRpcResponse));
764
+ const encodeProgressNotification = S.encodeResult(S.fromJsonString(ReportMutationTestProgress));
765
+ const decodeJsonRpcRequest = S.decodeUnknownResult(S.fromJsonString(JsonRpcRequest));
766
+ const decodeConfigureParams = S.decodeUnknownResult(ConfigureParams);
767
+ const decodeDiscoverParams = S.decodeUnknownResult(DiscoverParams);
768
+ const decodeMutationTestParams = S.decodeUnknownResult(MutationTestParams);
769
+ /**
770
+ * The `targetMutatePatterns` this engine takes for a `FileRange` list, or
771
+ * `undefined` when no restriction was asked for. A trailing slash means a
772
+ * directory, matching the protocol.
773
+ *
774
+ * The positions pass through verbatim. This engine compares a range's `end`
775
+ * against a mutant location's `end`, and both of those ends are the report
776
+ * schema's 1-based, exclusive end — the same coordinate space MSP defines for
777
+ * `Location` — so MSP's start-inclusive, end-exclusive range needs no
778
+ * arithmetic here. (StrykerJS v10 subtracts one from both columns instead,
779
+ * because its own mutate ranges are exclusive at the start; copying that would
780
+ * shift this engine's start by a character.)
781
+ */
782
+ const restrictPatternsOf = (files) => Option.getOrUndefined(Option.map(Option.filter(Option.fromUndefinedOr(files), (scopes) => scopes.length > 0), (scopes) => scopes.map(patternOf)));
783
+ const patternOf = (file) => Option.match(Option.fromUndefinedOr(file.range), {
784
+ onNone: () => basePatternOf(file.path),
785
+ onSome: (range) => `${basePatternOf(file.path)}:${rangeTextOf(range)}`
786
+ });
787
+ const basePatternOf = (path) => Match.value(path.endsWith("/")).pipe(Match.when(true, () => `${path}**/*`), Match.when(false, () => path), Match.exhaustive);
788
+ const rangeTextOf = (range) => `${range.start.line}:${range.start.column}-${range.end.line}:${range.end.column}`;
789
+ //#endregion
790
+ //#region src/Serve/msp-protocol.workflow.ts
791
+ const MspDecisionTypeId = Symbol.for("@systemfsoftware/stryker-js/MspDecision");
792
+ var MspConfigureRequested = class extends S.TaggedClass()("MspConfigureRequested", {
793
+ id: JsonRpcId,
794
+ configFilePath: S.optionalKey(S.String)
795
+ }) {
796
+ [MspDecisionTypeId] = MspDecisionTypeId;
797
+ };
798
+ var MspDiscoverRequested = class extends S.TaggedClass()("MspDiscoverRequested", {
799
+ id: JsonRpcId,
800
+ params: DiscoverParams
801
+ }) {
802
+ [MspDecisionTypeId] = MspDecisionTypeId;
803
+ };
804
+ var MspMutationTestRequested = class extends S.TaggedClass()("MspMutationTestRequested", {
805
+ id: JsonRpcId,
806
+ params: MutationTestParams
807
+ }) {
808
+ [MspDecisionTypeId] = MspDecisionTypeId;
809
+ };
810
+ var MspMethodNotFound = class extends S.TaggedClass()("MspMethodNotFound", {
811
+ id: JsonRpcId,
812
+ method: S.String
813
+ }) {
814
+ [MspDecisionTypeId] = MspDecisionTypeId;
815
+ };
816
+ var MspInvalidParams = class extends S.TaggedClass()("MspInvalidParams", {
817
+ id: JsonRpcId,
818
+ method: S.String,
819
+ issue: S.String
820
+ }) {
821
+ [MspDecisionTypeId] = MspDecisionTypeId;
822
+ };
823
+ var MspRequestBusy = class extends S.TaggedClass()("MspRequestBusy", {
824
+ id: JsonRpcId,
825
+ method: S.String
826
+ }) {
827
+ [MspDecisionTypeId] = MspDecisionTypeId;
828
+ };
829
+ var MspNotificationIgnored = class extends S.TaggedClass()("MspNotificationIgnored", { method: S.String }) {
830
+ [MspDecisionTypeId] = MspDecisionTypeId;
831
+ };
832
+ var MspRequestCommand = class extends S.TaggedClass()("MspRequestCommand", {
833
+ id: S.optionalKey(JsonRpcId),
834
+ method: S.String,
835
+ params: S.optionalKey(S.Json),
836
+ busy: S.Boolean
837
+ }) {
838
+ static [Workflow.InstrumentationBrand] = {};
839
+ };
840
+ const refusedParams = (id, method, issue) => MspInvalidParams.make({
841
+ id,
842
+ method,
843
+ issue: issue.message
844
+ });
845
+ const configured = (id, params) => Result.match(decodeConfigureParams(params), {
846
+ onFailure: (issue) => Result.succeed(refusedParams(id, MSP_METHODS.configure, issue)),
847
+ onSuccess: (decoded) => Result.succeed(MspConfigureRequested.make({
848
+ id,
849
+ ...configFieldsOf(decoded.configFilePath)
850
+ }))
851
+ });
852
+ const configFieldsOf = (configFilePath) => Option.match(Option.fromUndefinedOr(configFilePath), {
853
+ onNone: () => ({}),
854
+ onSome: (path) => ({ configFilePath: path })
855
+ });
856
+ const discovered = (id, params) => Result.match(decodeDiscoverParams(params), {
857
+ onFailure: (issue) => Result.succeed(refusedParams(id, MSP_METHODS.discover, issue)),
858
+ onSuccess: (decoded) => Result.succeed(MspDiscoverRequested.make({
859
+ id,
860
+ params: decoded
861
+ }))
862
+ });
863
+ const mutationTest = (id, params) => Result.match(decodeMutationTestParams(params), {
864
+ onFailure: (issue) => Result.succeed(refusedParams(id, MSP_METHODS.mutationTest, issue)),
865
+ onSuccess: (decoded) => Result.succeed(MspMutationTestRequested.make({
866
+ id,
867
+ params: decoded
868
+ }))
869
+ });
870
+ const methodOf = (name) => S.decodeUnknownOption(MspMethod)(name);
871
+ const dispatchMethod = (method, command, id) => Match.value(method).pipe(Match.when(MSP_METHODS.configure, () => configured(id, command.params)), Match.when(MSP_METHODS.discover, () => discovered(id, command.params)), Match.when(MSP_METHODS.mutationTest, () => mutationTest(id, command.params)), Match.when(MSP_METHODS.reportMutationTestProgress, () => Result.succeed(MspMethodNotFound.make({
872
+ id,
873
+ method: command.method
874
+ }))), Match.exhaustive);
875
+ const decidedForMethod = (command, id) => Option.match(methodOf(command.method), {
876
+ onNone: () => Result.succeed(MspMethodNotFound.make({
877
+ id,
878
+ method: command.method
879
+ })),
880
+ onSome: (method) => dispatchMethod(method, command, id)
881
+ });
882
+ const whileRunning = (command, id) => Boolean.match(command.busy, {
883
+ onTrue: () => Result.succeed(MspRequestBusy.make({
884
+ id,
885
+ method: command.method
886
+ })),
887
+ onFalse: () => decidedForMethod(command, id)
888
+ });
889
+ const decideMspRequest = (command) => Option.match(Option.fromUndefinedOr(command.id), {
890
+ onNone: () => Result.succeed(MspNotificationIgnored.make({ method: command.method })),
891
+ onSome: (id) => whileRunning(command, id)
892
+ });
893
+ const mspProtocol = Workflow.make({
894
+ command: MspRequestCommand,
895
+ decision: S.Union([
896
+ MspConfigureRequested,
897
+ MspDiscoverRequested,
898
+ MspMutationTestRequested,
899
+ MspMethodNotFound,
900
+ MspInvalidParams,
901
+ MspRequestBusy,
902
+ MspNotificationIgnored
903
+ ]),
904
+ error: S.Never,
905
+ decide: decideMspRequest
906
+ });
907
+ //#endregion
908
+ //#region src/Serve/Serve.cell.ts
909
+ /**
910
+ * The Mutation Server Protocol server: stdio and socket transports, one run at
911
+ * a time.
912
+ *
913
+ * Each decoded request runs the same engine the CLI runs, restricted by the
914
+ * `mutate` ranges or mutant ids the request named. The socket transport binds
915
+ * loopback unless an explicit `--address` names another interface: the protocol
916
+ * has no authentication and `mutationTest` executes the project's own test
917
+ * code.
918
+ *
919
+ * Only framed JSON-RPC reaches stdout. Engine logging goes to stderr and the
920
+ * protocol run disables reporters, because a reporter would otherwise write
921
+ * human text onto the stream the client is parsing.
922
+ */
923
+ const HEADLESS_MODE = {
924
+ mode: "human",
925
+ signal: "flag",
926
+ stdoutIsTTY: false
927
+ };
928
+ const PROTOCOL_CLI_OPTIONS = {
929
+ logLevel: "warn",
930
+ reporters: []
931
+ };
932
+ const LOOPBACK = "localhost";
933
+ const LOOPBACK_NAMES = [
934
+ LOOPBACK,
935
+ "127.0.0.1",
936
+ "::1",
937
+ "[::1]"
938
+ ];
939
+ const serveEnvironment = (basePath, startedAt) => ({
940
+ runId: generateRunId(DateTime.makeUnsafe(startedAt)),
941
+ resolvedMode: HEADLESS_MODE,
942
+ runStartedAt: startedAt,
943
+ basePath,
944
+ builtinReporters: { html: HtmlReporter_exports.makeHtmlReporter },
945
+ allowConsoleColors: false
946
+ });
947
+ const describe = (failure, fallback) => Option.getOrElse(Option.filter(Option.fromUndefinedOr(failure.message), S.is(S.NonEmptyString)), () => fallback);
948
+ const optionalFieldsOf = (entries) => entries.reduce((fields, [key, value]) => {
949
+ if (value !== void 0) fields[key] = value;
950
+ return fields;
951
+ }, {});
952
+ const copiedOrUndefined = (tests) => Option.getOrUndefined(Option.map(Option.fromUndefinedOr(tests), (present) => [...present]));
953
+ const withoutUndefined = (value) => value;
954
+ const bucketOf = (grouped, key) => Option.getOrElse(Option.fromUndefinedOr(grouped.get(key)), () => {
955
+ const fresh = [];
956
+ grouped.set(key, fresh);
957
+ return fresh;
958
+ });
959
+ const withEngine = (consume, use) => Effect.gen(function* () {
960
+ const basePath = yield* (yield* FileSystem.FileSystem).realPath(".").pipe(Effect.mapError(() => ServeError.make({ reason: "cannot resolve the working directory" })));
961
+ const startedAt = yield* Clock.currentTimeMillis;
962
+ const env = serveEnvironment(basePath, startedAt);
963
+ const events = yield* Queue.bounded(RunEvent_exports$1.RunEvent.QUEUE_BOUND);
964
+ const consumer = yield* Stream.fromQueue(events).pipe(Stream.runForEach(consume), Effect.forkChild);
965
+ return yield* Effect.scoped(Effect.gen(function* () {
966
+ const context = yield* Layer.build(RunEnvironment.stage(env, events));
967
+ return yield* use({
968
+ env,
969
+ context
970
+ });
971
+ })).pipe(Effect.ensuring(Queue.end(events).pipe(Effect.andThen(Fiber.join(consumer)), Effect.ignore)));
972
+ });
973
+ const discoverStageCell = Cell.andThen(Cell.andThen(Cell.andThen(loadConfigCell, readProjectCell), prepareCell), Cell.andThen(concurrencyCell, instrumentCell));
974
+ const discoveredFilesOf = (mutants, relativeFileName) => {
975
+ const grouped = /* @__PURE__ */ new Map();
976
+ for (const mutant of mutants) bucketOf(grouped, relativeFileName(mutant.fileName)).push({
977
+ id: mutant.id,
978
+ location: mutant.location,
979
+ mutatorName: mutant.mutatorName,
980
+ ...optionalFieldsOf([["replacement", mutant.replacement], ["description", withoutUndefined(mutant.description)]])
981
+ });
982
+ return Object.fromEntries([...grouped].map(([fileName, groupedMutants]) => [fileName, { mutants: groupedMutants }]));
983
+ };
984
+ const reportedMutantOf = (result) => Object.assign({
985
+ id: result.id,
986
+ location: result.location,
987
+ mutatorName: result.mutatorName,
988
+ replacement: result.replacement,
989
+ status: result.status
990
+ }, optionalFieldsOf([
991
+ ["static", withoutUndefined(result.static)],
992
+ ["coveredBy", copiedOrUndefined(result.coveredBy)],
993
+ ["killedBy", copiedOrUndefined(result.killedBy)],
994
+ ["statusReason", withoutUndefined(result.statusReason)],
995
+ ["testsCompleted", withoutUndefined(result.testsCompleted)],
996
+ ["duration", Option.getOrUndefined(Option.map(Option.fromNullishOr(result.cost), (cost) => cost.testBodyMs))]
997
+ ]));
998
+ const mutationTestFilesOf = (results, relativeFileName) => {
999
+ const grouped = /* @__PURE__ */ new Map();
1000
+ for (const result of results) bucketOf(grouped, relativeFileName(result.fileName)).push(reportedMutantOf(result));
1001
+ return Object.fromEntries([...grouped].map(([fileName, groupedMutants]) => [fileName, { mutants: groupedMutants }]));
1002
+ };
1003
+ const progressOf = (tested) => ({
1004
+ jsonrpc: "2.0",
1005
+ method: MSP_METHODS.reportMutationTestProgress,
1006
+ params: { files: { [tested.fileName]: { mutants: [Object.assign({
1007
+ id: tested.id,
1008
+ location: tested.location,
1009
+ mutatorName: tested.mutatorName,
1010
+ status: tested.status,
1011
+ static: tested.static
1012
+ }, optionalFieldsOf([
1013
+ ["replacement", withoutUndefined(tested.replacement)],
1014
+ ["duration", Option.getOrUndefined(Option.map(Option.fromNullishOr(tested.cost), (cost) => cost.testBodyMs))],
1015
+ ["testsCompleted", Option.getOrUndefined(Option.map(Option.fromNullishOr(tested.cost), (cost) => cost.testsExecuted))]
1016
+ ]))] } } }
1017
+ });
1018
+ const encodedOr = (encoded, what) => Result.match(encoded, {
1019
+ onFailure: (issue) => ServeError.make({
1020
+ reason: `cannot encode ${what}`,
1021
+ cause: issue
1022
+ }),
1023
+ onSuccess: Effect.succeed
1024
+ });
1025
+ const optionsOf = (invocation, configFilePath) => Object.assign({
1026
+ ...invocation.cliOptions,
1027
+ ...PROTOCOL_CLI_OPTIONS
1028
+ }, optionalFieldsOf([["configFile", withoutUndefined(configFilePath)]]));
1029
+ const mutantIdsOf = (mutants) => Object.values(mutants).flatMap((file) => file.mutants.map((mutant) => mutant.id));
1030
+ const withPatterns = (options, patterns) => Option.getOrElse(Option.map(Option.fromUndefinedOr(patterns), (present) => ({
1031
+ ...options,
1032
+ mutate: [...present]
1033
+ })), () => options);
1034
+ const mutationTestOptionsOf = (invocation, configFilePath, params) => Option.match(Option.fromUndefinedOr(params.mutants), {
1035
+ onNone: () => withPatterns(optionsOf(invocation, configFilePath), restrictPatternsOf(params.files)),
1036
+ onSome: (mutants) => ({
1037
+ ...optionsOf(invocation, configFilePath),
1038
+ mutate: Object.keys(mutants),
1039
+ mutantIds: mutantIdsOf(mutants)
1040
+ })
1041
+ });
1042
+ const runDiscover = (options, targetMutatePatterns) => withEngine(() => Effect.void, ({ env, context }) => Effect.gen(function* () {
1043
+ const path = yield* Path.Path;
1044
+ const done = yield* Cell.provideContext(discoverStageCell, context).run({
1045
+ cliOptions: options,
1046
+ targetMutatePatterns: targetMutatePatterns === void 0 ? void 0 : [...targetMutatePatterns]
1047
+ });
1048
+ return { files: discoveredFilesOf(done.mutants, (fileName) => path.relative(env.basePath, fileName)) };
1049
+ }).pipe(Effect.mapError((failure) => ServeError.make({
1050
+ reason: describe(failure, "discovery failed"),
1051
+ cause: failure
1052
+ }))));
1053
+ const runMutationTest = (options, targetMutatePatterns, notify) => withEngine((event) => Match.value(event).pipe(Match.tag("mutantTested", (tested) => notify(tested)), Match.orElse(() => Effect.void)), ({ env, context }) => Effect.gen(function* () {
1054
+ const path = yield* Path.Path;
1055
+ const done = yield* Cell.provideContext(mutationTestCell, context).run({
1056
+ cliOptions: options,
1057
+ targetMutatePatterns: targetMutatePatterns === void 0 ? void 0 : [...targetMutatePatterns]
1058
+ });
1059
+ return { files: mutationTestFilesOf(done.results, (fileName) => path.relative(env.basePath, fileName)) };
1060
+ }).pipe(Effect.mapError((failure) => ServeError.make({
1061
+ reason: describe(failure, "the mutation test failed"),
1062
+ cause: failure
1063
+ }))));
1064
+ const respond = (connection, id, result) => Effect.flatMap(encodedOr(encodeJsonRpcResponse({
1065
+ jsonrpc: "2.0",
1066
+ id,
1067
+ result
1068
+ }), "a response"), (payload) => connection.write(payload));
1069
+ const respondError = (connection, id, code, message) => Effect.flatMap(encodedOr(encodeJsonRpcResponse({
1070
+ jsonrpc: "2.0",
1071
+ id,
1072
+ error: {
1073
+ code,
1074
+ message
1075
+ }
1076
+ }), "an error response"), (payload) => connection.write(payload));
1077
+ const notifyProgress = (connection, notification) => Effect.flatMap(encodedOr(encodeProgressNotification(notification), "a progress notification"), (payload) => connection.write(payload));
1078
+ const runRequested = (decision, connection, stateRef, invocation) => {
1079
+ const state = Effect.map(Ref.get(stateRef), (current) => current.configFilePath);
1080
+ return Match.value(decision).pipe(Match.tag("MspConfigureRequested", ({ id, configFilePath }) => Effect.andThen(Ref.set(stateRef, { configFilePath }), respond(connection, id, { version: MSP_PROTOCOL_VERSION }))), Match.tag("MspDiscoverRequested", ({ id, params }) => Effect.gen(function* () {
1081
+ const result = yield* Effect.result(runDiscover(optionsOf(invocation, yield* state), restrictPatternsOf(params.files)));
1082
+ yield* Result.match(result, {
1083
+ onFailure: (failure) => respondError(connection, id, MSP_INTERNAL_ERROR, failure.reason),
1084
+ onSuccess: (files) => respond(connection, id, files)
1085
+ });
1086
+ })), Match.tag("MspMutationTestRequested", ({ id, params }) => Effect.gen(function* () {
1087
+ const result = yield* Effect.result(runMutationTest(mutationTestOptionsOf(invocation, yield* state, params), void 0, (tested) => notifyProgress(connection, progressOf(tested))));
1088
+ yield* Result.match(result, {
1089
+ onFailure: (failure) => respondError(connection, id, MSP_INTERNAL_ERROR, failure.reason),
1090
+ onSuccess: (files) => respond(connection, id, files)
1091
+ });
1092
+ })), Match.tag("MspMethodNotFound", ({ id, method }) => respondError(connection, id, MSP_METHOD_NOT_FOUND, `unknown method "${method}"`)), Match.tag("MspInvalidParams", ({ id, method, issue }) => respondError(connection, id, MSP_INVALID_PARAMS, `invalid params for "${method}": ${issue}`)), Match.tag("MspRequestBusy", ({ id }) => respondError(connection, id, MSP_SERVER_BUSY, "a mutation test is already running")), Match.tag("MspNotificationIgnored", () => Effect.void), Match.exhaustive);
1093
+ };
1094
+ const startsRunOf = (decision) => Match.value(decision).pipe(Match.tag("MspMutationTestRequested", () => true), Match.tag("MspConfigureRequested", () => false), Match.tag("MspDiscoverRequested", () => false), Match.tag("MspMethodNotFound", () => false), Match.tag("MspInvalidParams", () => false), Match.tag("MspRequestBusy", () => false), Match.tag("MspNotificationIgnored", () => false), Match.exhaustive);
1095
+ const releaseRun = (busy, startsRun) => Match.value(startsRun).pipe(Match.when(true, () => Ref.set(busy, false)), Match.when(false, () => Effect.void), Match.exhaustive);
1096
+ const dispatchRequest = (request, id, connection, stateRef, busy, invocation) => Effect.gen(function* () {
1097
+ const running = yield* Ref.get(busy);
1098
+ const decision = Result.getOrThrow(mspProtocol(MspRequestCommand.make({
1099
+ id,
1100
+ method: request.method,
1101
+ params: request.params,
1102
+ busy: running
1103
+ })));
1104
+ const startsRun = startsRunOf(decision);
1105
+ const wasRunning = yield* Ref.modify(busy, (current) => [current, current || startsRun]);
1106
+ yield* Match.value(wasRunning && startsRun).pipe(Match.when(true, () => respondError(connection, id, MSP_SERVER_BUSY, "a mutation test is already running")), Match.when(false, () => runRequested(decision, connection, stateRef, invocation).pipe(Effect.ensuring(releaseRun(busy, startsRun)))), Match.exhaustive);
1107
+ });
1108
+ const handleFrame = (raw, connection, stateRef, busy, invocation) => Result.match(decodeJsonRpcRequest(raw), {
1109
+ onFailure: () => respondError(connection, null, MSP_PARSE_ERROR, "the message is not a JSON-RPC 2.0 request"),
1110
+ onSuccess: (request) => Option.match(Option.fromUndefinedOr(request.id), {
1111
+ onNone: () => Effect.void,
1112
+ onSome: (id) => dispatchRequest({
1113
+ method: request.method,
1114
+ params: request.params
1115
+ }, id, connection, stateRef, busy, invocation)
1116
+ })
1117
+ });
1118
+ const serveConnection = (connection, invocation) => Effect.gen(function* () {
1119
+ const stateRef = yield* Ref.make({ configFilePath: void 0 });
1120
+ const busy = yield* Ref.make(false);
1121
+ const decoder = yield* Ref.make(emptyFraming);
1122
+ const handlers = yield* FiberSet.make();
1123
+ yield* connection.chunks.pipe(Stream.runForEach((chunk) => Effect.gen(function* () {
1124
+ const step = yield* Ref.modify(decoder, (buffer) => {
1125
+ const read = readFrames(buffer, chunk);
1126
+ return [read, read.buffer];
1127
+ });
1128
+ yield* Effect.forEach(step.errors, (error) => respondError(connection, null, MSP_PARSE_ERROR, error), { discard: true });
1129
+ yield* Effect.forEach(step.frames, (frame) => FiberSet.run(handlers, handleFrame(frame, connection, stateRef, busy, invocation)), { discard: true });
1130
+ })));
1131
+ yield* FiberSet.join(handlers);
1132
+ });
1133
+ const stdioConnection = (stdio) => ({
1134
+ chunks: stdio.stdin.pipe(Stream.catch(() => Stream.empty)),
1135
+ write: (payload) => Stream.run(Stream.succeed(frameOf(payload)), stdio.stdout({ endOnDone: false })).pipe(Effect.mapError(() => ServeError.make({ reason: "cannot write to standard output" })))
1136
+ });
1137
+ const socketConnection = (socket) => Effect.gen(function* () {
1138
+ const writer = yield* socket.writer;
1139
+ const pull = yield* Socket.readerBytes(socket);
1140
+ return {
1141
+ chunks: Stream.fromEffectRepeat(pull).pipe(Stream.flatMap((batch) => Stream.fromIterable(batch)), Stream.catch(() => Stream.empty)),
1142
+ write: (payload) => writer.writeAll([frameOf(payload)]).pipe(Effect.mapError(() => ServeError.make({ reason: "cannot write to the socket" })))
1143
+ };
1144
+ }).pipe(Effect.orDie);
1145
+ const writeStderr = (stdio, line) => Stream.run(Stream.succeed(`${line}\n`), stdio.stderr({ endOnDone: false })).pipe(Effect.mapError(() => ServeError.make({ reason: "cannot write to standard error" })));
1146
+ const exposureWarning = (address) => `MSP socket mode is listening on ${address}, which is not loopback: the mutation server has no authentication and runs this project's test code, so anyone who can reach that interface can drive it.`;
1147
+ const portOf = (invocation) => Option.match(Option.fromUndefinedOr(invocation.port), {
1148
+ onNone: () => ServeError.make({ reason: "the socket channel needs --port" }),
1149
+ onSome: Effect.succeed
1150
+ });
1151
+ const exposureIfNeeded = (stdio, address) => Match.value(LOOPBACK_NAMES.includes(address)).pipe(Match.when(true, () => Effect.void), Match.when(false, () => writeStderr(stdio, exposureWarning(address))), Match.exhaustive);
1152
+ const bindListener = (address, port) => Layer.build(NodeSocketServer.layer({
1153
+ port,
1154
+ host: address
1155
+ })).pipe(Effect.mapError((failure) => ServeError.make({
1156
+ reason: `cannot bind ${address}:${port}: ${describe(failure, "the listener failed")}`,
1157
+ cause: failure
1158
+ })));
1159
+ const serveStdio = (invocation) => Effect.flatMap(Stdio.Stdio, (stdio) => serveConnection(stdioConnection(stdio), invocation));
1160
+ const serveSocket = (invocation) => Effect.gen(function* () {
1161
+ const stdio = yield* Stdio.Stdio;
1162
+ const address = Option.getOrElse(Option.fromUndefinedOr(invocation.address), () => LOOPBACK);
1163
+ const port = yield* portOf(invocation);
1164
+ yield* exposureIfNeeded(stdio, address);
1165
+ const serverContext = yield* bindListener(address, port);
1166
+ const server = Context.get(serverContext, SocketServer.SocketServer);
1167
+ yield* writeStderr(stdio, `msp:listening ${String(server.address)}`);
1168
+ const connections = yield* FiberSet.make();
1169
+ return yield* server.run((socket) => FiberSet.run(connections, Effect.scoped(Effect.flatMap(socketConnection(socket), (connection) => serveConnection(connection, invocation))))).pipe(Effect.onInterrupt(() => FiberSet.clear(connections)), Effect.ensuring(FiberSet.clear(connections)), Effect.mapError((failure) => ServeError.make({
1170
+ reason: `the listener failed: ${describe(failure, "unknown cause")}`,
1171
+ cause: failure
1172
+ })));
1173
+ });
1174
+ const serveMutationServer = (invocation) => Match.value(invocation.channel).pipe(Match.when("stdio", () => serveStdio(invocation)), Match.orElse(() => serveSocket(invocation)));
1175
+ //#endregion
1176
+ //#region src/Serve/mod.ts
1177
+ var Serve_exports = /* @__PURE__ */ __exportAll({
1178
+ Framing: () => msp_framing_schema_exports,
1179
+ Protocol: () => msp_schema_exports,
1180
+ ServeError: () => ServeError,
1181
+ serveMutationServer: () => serveMutationServer
104
1182
  });
105
1183
  //#endregion
106
1184
  //#region src/Worker/mod.ts
@@ -117,4 +1195,4 @@ var Worker_exports = /* @__PURE__ */ __exportAll({
117
1195
  makeWorkerClient: () => makeWorkerClient
118
1196
  });
119
1197
  //#endregion
120
- export { Checker_exports as Checker, Configuration_exports as Configuration, Engine_exports as Engine, Plugin_exports as Plugin, RunEvent_exports as RunEvent, Worker_exports as Worker };
1198
+ export { Checker_exports as Checker, Configuration_exports as Configuration, Engine_exports as Engine, git_diff_service_exports as GitDiff, git_diff_schema_exports as GitDiffSchema, import_closure_cell_exports as ImportClosure, Mcp_exports as Mcp, Plugin_exports as Plugin, RunEvent_exports as RunEvent, Serve_exports as Serve, Worker_exports as Worker };