@adhisang/minecraft-modding-mcp 4.0.0 → 4.1.1

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.
Files changed (176) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +40 -23
  3. package/dist/build-suggested-call.d.ts +29 -0
  4. package/dist/build-suggested-call.js +58 -0
  5. package/dist/cache-registry.d.ts +3 -1
  6. package/dist/cache-registry.js +50 -6
  7. package/dist/entry-tools/analyze-symbol-service.d.ts +16 -16
  8. package/dist/entry-tools/batch-class-members-service.d.ts +34 -0
  9. package/dist/entry-tools/batch-class-members-service.js +97 -0
  10. package/dist/entry-tools/batch-class-source-service.d.ts +37 -0
  11. package/dist/entry-tools/batch-class-source-service.js +100 -0
  12. package/dist/entry-tools/batch-mappings-service.d.ts +36 -0
  13. package/dist/entry-tools/batch-mappings-service.js +66 -0
  14. package/dist/entry-tools/batch-runner.d.ts +72 -0
  15. package/dist/entry-tools/batch-runner.js +90 -0
  16. package/dist/entry-tools/batch-symbol-exists-service.d.ts +46 -0
  17. package/dist/entry-tools/batch-symbol-exists-service.js +113 -0
  18. package/dist/entry-tools/compare-minecraft-service.d.ts +6 -6
  19. package/dist/entry-tools/inspect-minecraft/handlers/artifact.d.ts +5 -0
  20. package/dist/entry-tools/inspect-minecraft/handlers/artifact.js +83 -0
  21. package/dist/entry-tools/inspect-minecraft/handlers/class-members.d.ts +6 -0
  22. package/dist/entry-tools/inspect-minecraft/handlers/class-members.js +80 -0
  23. package/dist/entry-tools/inspect-minecraft/handlers/class-overview.d.ts +5 -0
  24. package/dist/entry-tools/inspect-minecraft/handlers/class-overview.js +248 -0
  25. package/dist/entry-tools/inspect-minecraft/handlers/class-source.d.ts +5 -0
  26. package/dist/entry-tools/inspect-minecraft/handlers/class-source.js +60 -0
  27. package/dist/entry-tools/inspect-minecraft/handlers/file.d.ts +5 -0
  28. package/dist/entry-tools/inspect-minecraft/handlers/file.js +54 -0
  29. package/dist/entry-tools/inspect-minecraft/handlers/list-files.d.ts +5 -0
  30. package/dist/entry-tools/inspect-minecraft/handlers/list-files.js +100 -0
  31. package/dist/entry-tools/inspect-minecraft/handlers/search.d.ts +5 -0
  32. package/dist/entry-tools/inspect-minecraft/handlers/search.js +155 -0
  33. package/dist/entry-tools/inspect-minecraft/handlers/versions.d.ts +6 -0
  34. package/dist/entry-tools/inspect-minecraft/handlers/versions.js +49 -0
  35. package/dist/entry-tools/inspect-minecraft/internal.d.ts +1042 -0
  36. package/dist/entry-tools/inspect-minecraft/internal.js +448 -0
  37. package/dist/entry-tools/inspect-minecraft-service.d.ts +193 -308
  38. package/dist/entry-tools/inspect-minecraft-service.js +20 -1244
  39. package/dist/entry-tools/manage-cache-service.d.ts +16 -16
  40. package/dist/entry-tools/validate-project/cases/access-transformer.d.ts +6 -0
  41. package/dist/entry-tools/validate-project/cases/access-transformer.js +106 -0
  42. package/dist/entry-tools/validate-project/cases/access-widener.d.ts +6 -0
  43. package/dist/entry-tools/validate-project/cases/access-widener.js +86 -0
  44. package/dist/entry-tools/validate-project/cases/mixin.d.ts +6 -0
  45. package/dist/entry-tools/validate-project/cases/mixin.js +90 -0
  46. package/dist/entry-tools/validate-project/cases/project-summary.d.ts +102 -0
  47. package/dist/entry-tools/validate-project/cases/project-summary.js +415 -0
  48. package/dist/entry-tools/validate-project/internal.d.ts +142 -0
  49. package/dist/entry-tools/validate-project/internal.js +303 -0
  50. package/dist/entry-tools/validate-project-service.d.ts +67 -47
  51. package/dist/entry-tools/validate-project-service.js +13 -563
  52. package/dist/entry-tools/verify-mixin-target-service.d.ts +133 -0
  53. package/dist/entry-tools/verify-mixin-target-service.js +323 -0
  54. package/dist/error-mapping.d.ts +40 -0
  55. package/dist/error-mapping.js +139 -0
  56. package/dist/errors.d.ts +6 -0
  57. package/dist/errors.js +6 -0
  58. package/dist/index.d.ts +2 -0
  59. package/dist/index.js +147 -1354
  60. package/dist/mapping/internal-types.d.ts +54 -0
  61. package/dist/mapping/internal-types.js +14 -0
  62. package/dist/mapping/loaders/mojang.d.ts +2 -0
  63. package/dist/mapping/loaders/mojang.js +64 -0
  64. package/dist/mapping/loaders/tiny-loom.d.ts +2 -0
  65. package/dist/mapping/loaders/tiny-loom.js +73 -0
  66. package/dist/mapping/loaders/tiny-maven.d.ts +2 -0
  67. package/dist/mapping/loaders/tiny-maven.js +104 -0
  68. package/dist/mapping/loaders/types.d.ts +14 -0
  69. package/dist/mapping/loaders/types.js +2 -0
  70. package/dist/mapping/lookup.d.ts +52 -0
  71. package/dist/mapping/lookup.js +496 -0
  72. package/dist/mapping/parsers/normalize.d.ts +10 -0
  73. package/dist/mapping/parsers/normalize.js +52 -0
  74. package/dist/mapping/parsers/proguard.d.ts +20 -0
  75. package/dist/mapping/parsers/proguard.js +138 -0
  76. package/dist/mapping/parsers/symbol-records.d.ts +27 -0
  77. package/dist/mapping/parsers/symbol-records.js +216 -0
  78. package/dist/mapping/parsers/tiny.d.ts +9 -0
  79. package/dist/mapping/parsers/tiny.js +96 -0
  80. package/dist/mapping/types.d.ts +147 -0
  81. package/dist/mapping/types.js +2 -0
  82. package/dist/mapping-pipeline-service.js +3 -2
  83. package/dist/mapping-service.d.ts +8 -145
  84. package/dist/mapping-service.js +30 -1207
  85. package/dist/mixin/access-validators.d.ts +9 -0
  86. package/dist/mixin/access-validators.js +257 -0
  87. package/dist/mixin/annotation-validators.d.ts +5 -0
  88. package/dist/mixin/annotation-validators.js +162 -0
  89. package/dist/mixin/helpers.d.ts +28 -0
  90. package/dist/mixin/helpers.js +315 -0
  91. package/dist/mixin/parsed-validator.d.ts +8 -0
  92. package/dist/mixin/parsed-validator.js +337 -0
  93. package/dist/mixin/types.d.ts +208 -0
  94. package/dist/mixin/types.js +28 -0
  95. package/dist/mixin-validator.d.ts +9 -201
  96. package/dist/mixin-validator.js +8 -1020
  97. package/dist/source/access-validate.d.ts +4 -0
  98. package/dist/source/access-validate.js +254 -0
  99. package/dist/source/artifact-resolver.d.ts +111 -0
  100. package/dist/source/artifact-resolver.js +1271 -0
  101. package/dist/source/cache-metrics.d.ts +26 -0
  102. package/dist/source/cache-metrics.js +172 -0
  103. package/dist/source/class-source/members-builder.d.ts +34 -0
  104. package/dist/source/class-source/members-builder.js +46 -0
  105. package/dist/source/class-source/snippet-builder.d.ts +19 -0
  106. package/dist/source/class-source/snippet-builder.js +46 -0
  107. package/dist/source/class-source-helpers.d.ts +34 -0
  108. package/dist/source/class-source-helpers.js +140 -0
  109. package/dist/source/class-source.d.ts +42 -0
  110. package/dist/source/class-source.js +883 -0
  111. package/dist/source/descriptor-utils.d.ts +6 -0
  112. package/dist/source/descriptor-utils.js +37 -0
  113. package/dist/source/file-access.d.ts +4 -0
  114. package/dist/source/file-access.js +102 -0
  115. package/dist/source/indexer.d.ts +82 -0
  116. package/dist/source/indexer.js +522 -0
  117. package/dist/source/lifecycle/diff-utils.d.ts +9 -0
  118. package/dist/source/lifecycle/diff-utils.js +107 -0
  119. package/dist/source/lifecycle/diff.d.ts +2 -0
  120. package/dist/source/lifecycle/diff.js +265 -0
  121. package/dist/source/lifecycle/mapping-helpers.d.ts +22 -0
  122. package/dist/source/lifecycle/mapping-helpers.js +327 -0
  123. package/dist/source/lifecycle/runtime-check.d.ts +2 -0
  124. package/dist/source/lifecycle/runtime-check.js +142 -0
  125. package/dist/source/lifecycle/trace.d.ts +2 -0
  126. package/dist/source/lifecycle/trace.js +231 -0
  127. package/dist/source/lifecycle.d.ts +4 -0
  128. package/dist/source/lifecycle.js +5 -0
  129. package/dist/source/search.d.ts +51 -0
  130. package/dist/source/search.js +676 -0
  131. package/dist/source/shared-utils.d.ts +6 -0
  132. package/dist/source/shared-utils.js +55 -0
  133. package/dist/source/state.d.ts +26 -0
  134. package/dist/source/state.js +24 -0
  135. package/dist/source/symbol-resolver.d.ts +3 -0
  136. package/dist/source/symbol-resolver.js +212 -0
  137. package/dist/source/validate-mixin/pipeline/mapping-health.d.ts +3 -0
  138. package/dist/source/validate-mixin/pipeline/mapping-health.js +41 -0
  139. package/dist/source/validate-mixin/pipeline/parse.d.ts +2 -0
  140. package/dist/source/validate-mixin/pipeline/parse.js +10 -0
  141. package/dist/source/validate-mixin/pipeline/resolve.d.ts +3 -0
  142. package/dist/source/validate-mixin/pipeline/resolve.js +78 -0
  143. package/dist/source/validate-mixin/pipeline/target-lookup.d.ts +6 -0
  144. package/dist/source/validate-mixin/pipeline/target-lookup.js +260 -0
  145. package/dist/source/validate-mixin/pipeline-context.d.ts +72 -0
  146. package/dist/source/validate-mixin/pipeline-context.js +93 -0
  147. package/dist/source/validate-mixin.d.ts +22 -0
  148. package/dist/source/validate-mixin.js +799 -0
  149. package/dist/source/workspace-target.d.ts +18 -0
  150. package/dist/source/workspace-target.js +305 -0
  151. package/dist/source-resolver.d.ts +1 -0
  152. package/dist/source-resolver.js +1 -1
  153. package/dist/source-service.d.ts +164 -170
  154. package/dist/source-service.js +70 -6116
  155. package/dist/stage-emitter.d.ts +13 -0
  156. package/dist/stage-emitter.js +30 -0
  157. package/dist/stdio-supervisor.d.ts +61 -0
  158. package/dist/stdio-supervisor.js +326 -9
  159. package/dist/tool-contract-manifest.d.ts +1 -1
  160. package/dist/tool-contract-manifest.js +23 -6
  161. package/dist/tool-guidance.d.ts +82 -0
  162. package/dist/tool-guidance.js +734 -0
  163. package/dist/tool-schema-registry.d.ts +16 -0
  164. package/dist/tool-schema-registry.js +37 -0
  165. package/dist/tool-schemas.d.ts +3518 -0
  166. package/dist/tool-schemas.js +813 -0
  167. package/dist/types.d.ts +36 -0
  168. package/dist/version-service.js +7 -6
  169. package/dist/workspace-context-cache.d.ts +32 -0
  170. package/dist/workspace-context-cache.js +66 -0
  171. package/dist/workspace-mapping-service.d.ts +16 -0
  172. package/dist/workspace-mapping-service.js +173 -1
  173. package/docs/README-ja.md +416 -0
  174. package/docs/examples.md +483 -0
  175. package/docs/tool-reference.md +462 -0
  176. package/package.json +17 -4
@@ -3,10 +3,12 @@ import { resolve } from "node:path";
3
3
  import fastGlob from "fast-glob";
4
4
  import { z } from "zod";
5
5
  import { mapWithConcurrencyLimit } from "../concurrency.js";
6
- import { createError, ERROR_CODES } from "../errors.js";
7
6
  import { buildIncludeSchema, detailSchema } from "./entry-tool-schema.js";
8
- import { buildEntryToolResult, createSummarySubject } from "./response-contract.js";
9
7
  import { resolveDetail, resolveInclude } from "./request-normalizers.js";
8
+ import { handleMixin } from "./validate-project/cases/mixin.js";
9
+ import { handleAccessWidener } from "./validate-project/cases/access-widener.js";
10
+ import { handleAccessTransformer } from "./validate-project/cases/access-transformer.js";
11
+ import { handleProjectSummary } from "./validate-project/cases/project-summary.js";
10
12
  const nonEmptyString = z.string().trim().min(1);
11
13
  const INCLUDE_GROUPS = ["warnings", "issues", "workspace", "recovery"];
12
14
  const WORKSPACE_TEXT_FILE_READ_CONCURRENCY = 4;
@@ -261,570 +263,18 @@ export class ValidateProjectService {
261
263
  constructor(deps) {
262
264
  this.deps = deps;
263
265
  }
264
- async execute(input) {
266
+ async execute(input, options = {}) {
265
267
  const detail = resolveDetail(input.detail);
266
268
  const include = resolveInclude(input.include);
267
269
  switch (input.task) {
268
- case "mixin": {
269
- if (input.subject.kind !== "mixin") {
270
- throw createError({
271
- code: ERROR_CODES.INVALID_INPUT,
272
- message: "task=mixin requires subject.kind=mixin.",
273
- details: {
274
- task: input.task,
275
- subjectKind: input.subject.kind,
276
- failedStage: "input-validation",
277
- nextAction: "Set subject.kind to \"mixin\" for task=\"mixin\"."
278
- }
279
- });
280
- }
281
- if (!input.version) {
282
- throw createError({
283
- code: ERROR_CODES.INVALID_INPUT,
284
- message: "task=mixin requires version.",
285
- details: {
286
- task: "mixin",
287
- failedStage: "input-validation",
288
- nextAction: "Pass version explicitly (e.g. \"1.21.10\"). task=\"project-summary\" supports preferProjectVersion for auto-detection from gradle.properties, but direct task=\"mixin\" requires an explicit version.",
289
- suggestedCall: {
290
- tool: "validate-project",
291
- params: {
292
- task: "mixin",
293
- subject: input.subject,
294
- version: "1.21.10"
295
- }
296
- }
297
- }
298
- });
299
- }
300
- const output = await this.deps.validateMixin({
301
- input: input.subject.input,
302
- version: input.version,
303
- mapping: input.mapping,
304
- sourcePriority: input.sourcePriority,
305
- scope: input.scope,
306
- preferProjectVersion: input.preferProjectVersion,
307
- preferProjectMapping: input.preferProjectMapping,
308
- sourceRoots: input.sourceRoots,
309
- minSeverity: input.minSeverity,
310
- hideUncertain: input.hideUncertain,
311
- explain: input.explain,
312
- warningMode: input.warningMode,
313
- warningCategoryFilter: input.warningCategoryFilter,
314
- treatInfoAsWarning: input.treatInfoAsWarning,
315
- includeIssues: input.includeIssues
316
- });
317
- const summary = output.summary;
318
- const invalidCount = summary?.invalid ?? 0;
319
- const partialCount = summary?.partial ?? 0;
320
- return {
321
- ...buildEntryToolResult({
322
- task: "mixin",
323
- detail,
324
- include,
325
- summary: {
326
- status: invalidCount > 0 ? "invalid" : partialCount > 0 ? "partial" : "ok",
327
- headline: `Validated ${summary?.total ?? 0} mixin input(s).`,
328
- subject: createSummarySubject({
329
- task: "mixin",
330
- kind: input.subject.kind,
331
- input: input.subject.input,
332
- version: input.version,
333
- mapping: input.mapping,
334
- sourcePriority: input.sourcePriority,
335
- scope: input.scope
336
- }),
337
- counts: {
338
- valid: summary?.valid ?? 0,
339
- partial: partialCount,
340
- invalid: invalidCount
341
- }
342
- },
343
- blocks: {
344
- project: {
345
- summary
346
- },
347
- issues: include.includes("issues") || detail !== "summary" ? output.results : undefined
348
- },
349
- alwaysBlocks: ["project"]
350
- }),
351
- warnings: Array.isArray(output.warnings) ? output.warnings : []
352
- };
353
- }
354
- case "access-widener": {
355
- if (input.subject.kind !== "access-widener") {
356
- throw createError({
357
- code: ERROR_CODES.INVALID_INPUT,
358
- message: "task=access-widener requires subject.kind=access-widener.",
359
- details: {
360
- task: input.task,
361
- subjectKind: input.subject.kind,
362
- failedStage: "input-validation",
363
- nextAction: "Set subject.kind to \"access-widener\" for task=\"access-widener\"."
364
- }
365
- });
366
- }
367
- if (!input.version) {
368
- throw createError({
369
- code: ERROR_CODES.INVALID_INPUT,
370
- message: "task=access-widener requires version.",
371
- details: {
372
- task: "access-widener",
373
- failedStage: "input-validation",
374
- nextAction: "Pass version explicitly (e.g. \"1.21.10\"). Access Widener validation resolves class names against a specific Minecraft version.",
375
- suggestedCall: {
376
- tool: "validate-project",
377
- params: {
378
- task: "access-widener",
379
- subject: input.subject,
380
- version: "1.21.10"
381
- }
382
- }
383
- }
384
- });
385
- }
386
- const content = input.subject.input.mode === "inline"
387
- ? input.subject.input.content
388
- : await readFile(input.subject.input.path, "utf8");
389
- const output = await this.deps.validateAccessWidener({
390
- content,
391
- version: input.version,
392
- mapping: input.mapping,
393
- sourcePriority: input.sourcePriority,
394
- scope: input.scope,
395
- preferProjectVersion: input.preferProjectVersion
396
- });
397
- return {
398
- ...buildEntryToolResult({
399
- task: "access-widener",
400
- detail,
401
- include,
402
- summary: {
403
- status: output.valid ? "ok" : "invalid",
404
- headline: output.valid
405
- ? "Access Widener is valid."
406
- : "Access Widener contains validation issues.",
407
- subject: createSummarySubject({
408
- task: "access-widener",
409
- kind: input.subject.kind,
410
- input: input.subject.input,
411
- version: input.version,
412
- mapping: input.mapping,
413
- sourcePriority: input.sourcePriority
414
- }),
415
- counts: {
416
- valid: output.valid ? 1 : 0,
417
- invalid: output.valid ? 0 : 1
418
- }
419
- },
420
- blocks: {
421
- project: {
422
- summary: {
423
- total: 1,
424
- valid: output.valid ? 1 : 0,
425
- invalid: output.valid ? 0 : 1
426
- }
427
- },
428
- issues: include.includes("issues") || detail !== "summary" ? output.issues : undefined
429
- },
430
- alwaysBlocks: ["project"]
431
- }),
432
- warnings: Array.isArray(output.warnings) ? output.warnings : []
433
- };
434
- }
435
- case "access-transformer": {
436
- if (input.subject.kind !== "access-transformer") {
437
- throw createError({
438
- code: ERROR_CODES.INVALID_INPUT,
439
- message: "task=access-transformer requires subject.kind=access-transformer.",
440
- details: {
441
- task: input.task,
442
- subjectKind: input.subject.kind,
443
- failedStage: "input-validation",
444
- nextAction: "Set subject.kind to \"access-transformer\" for task=\"access-transformer\"."
445
- }
446
- });
447
- }
448
- if (!input.version) {
449
- throw createError({
450
- code: ERROR_CODES.INVALID_INPUT,
451
- message: "task=access-transformer requires version.",
452
- details: {
453
- task: "access-transformer",
454
- failedStage: "input-validation",
455
- nextAction: "Pass version explicitly (e.g. \"1.21.10\"). Access Transformer validation resolves class names against a specific Minecraft version.",
456
- suggestedCall: {
457
- tool: "validate-project",
458
- params: {
459
- task: "access-transformer",
460
- subject: input.subject,
461
- version: "1.21.10"
462
- }
463
- }
464
- }
465
- });
466
- }
467
- const content = input.subject.input.mode === "inline"
468
- ? input.subject.input.content
469
- : await readFile(input.subject.input.path, "utf8");
470
- if (!this.deps.validateAccessTransformer) {
471
- throw createError({
472
- code: ERROR_CODES.CONTEXT_UNRESOLVED,
473
- message: "Access Transformer validation is not configured.",
474
- details: {
475
- task: "access-transformer",
476
- failedStage: "dependency-resolution",
477
- nextAction: "The current runtime was built without an Access Transformer validator. Rebuild the MCP server with validateAccessTransformer configured, or use task=\"access-widener\" if the workspace uses Fabric AccessWideners."
478
- }
479
- });
480
- }
481
- const output = await this.deps.validateAccessTransformer({
482
- content,
483
- version: input.version,
484
- atNamespace: input.atNamespace,
485
- sourcePriority: input.sourcePriority,
486
- scope: input.scope,
487
- preferProjectVersion: input.preferProjectVersion
488
- });
489
- const issueEntries = Array.isArray(output.entries)
490
- ? output.entries.filter((entry) => {
491
- if (!entry || typeof entry !== "object" || !("valid" in entry)) {
492
- return true;
493
- }
494
- return entry.valid !== true;
495
- })
496
- : undefined;
497
- return {
498
- ...buildEntryToolResult({
499
- task: "access-transformer",
500
- detail,
501
- include,
502
- summary: {
503
- status: output.valid ? "ok" : "invalid",
504
- headline: output.valid
505
- ? "Access Transformer is valid."
506
- : "Access Transformer contains validation issues.",
507
- subject: createSummarySubject({
508
- task: "access-transformer",
509
- kind: input.subject.kind,
510
- input: input.subject.input,
511
- version: input.version,
512
- sourcePriority: input.sourcePriority,
513
- scope: input.scope,
514
- atNamespace: input.atNamespace
515
- }),
516
- counts: {
517
- valid: output.valid ? 1 : 0,
518
- invalid: output.valid ? 0 : 1
519
- }
520
- },
521
- blocks: {
522
- project: {
523
- summary: {
524
- total: 1,
525
- valid: output.valid ? 1 : 0,
526
- invalid: output.valid ? 0 : 1
527
- }
528
- },
529
- issues: include.includes("issues") || detail !== "summary" ? issueEntries : undefined
530
- },
531
- alwaysBlocks: ["project"]
532
- }),
533
- warnings: Array.isArray(output.warnings) ? output.warnings : []
534
- };
535
- }
536
- case "project-summary": {
537
- if (input.subject.kind !== "workspace") {
538
- throw createError({
539
- code: ERROR_CODES.INVALID_INPUT,
540
- message: "task=project-summary requires subject.kind=workspace."
541
- });
542
- }
543
- if (!input.version && !input.preferProjectVersion) {
544
- return {
545
- ...buildEntryToolResult({
546
- task: "project-summary",
547
- detail,
548
- include,
549
- summary: {
550
- status: "blocked",
551
- headline: "project-summary requires version or preferProjectVersion=true.",
552
- subject: createSummarySubject({
553
- task: "project-summary",
554
- kind: input.subject.kind,
555
- projectPath: input.subject.projectPath,
556
- discover: input.subject.discover
557
- }),
558
- nextActions: [
559
- {
560
- tool: "validate-project",
561
- params: {
562
- task: "project-summary",
563
- subject: input.subject
564
- }
565
- }
566
- ],
567
- notes: [
568
- "Pass version explicitly, or retry with preferProjectVersion=true when gradle.properties declares the Minecraft version."
569
- ]
570
- },
571
- blocks: {
572
- workspace: {
573
- projectPath: input.subject.projectPath
574
- }
575
- }
576
- }),
577
- warnings: []
578
- };
579
- }
580
- const projectPath = input.subject.projectPath;
581
- const detectedProjectVersion = input.preferProjectVersion
582
- ? await this.deps.detectProjectMinecraftVersion?.(projectPath)
583
- : undefined;
584
- const resolvedVersion = detectedProjectVersion ?? input.version;
585
- const discover = input.subject.discover ?? ["mixins", "access-wideners"];
586
- const [mixinConfigs, accessWideners, accessTransformers] = await Promise.all([
587
- discover.includes("mixins")
588
- ? this.deps.discoverMixins(projectPath, input.configPaths)
589
- : Promise.resolve([]),
590
- discover.includes("access-wideners")
591
- ? this.deps.discoverAccessWideners(projectPath)
592
- : Promise.resolve([]),
593
- discover.includes("access-transformers")
594
- ? this.deps.discoverAccessTransformers?.(projectPath) ?? Promise.resolve([])
595
- : Promise.resolve([])
596
- ]);
597
- if (!resolvedVersion && (mixinConfigs.length > 0 || accessWideners.length > 0 || accessTransformers.length > 0)) {
598
- return {
599
- ...buildEntryToolResult({
600
- task: "project-summary",
601
- detail,
602
- include,
603
- summary: {
604
- status: "blocked",
605
- headline: "Could not resolve Minecraft version for discovered workspace validators.",
606
- subject: createSummarySubject({
607
- task: "project-summary",
608
- kind: input.subject.kind,
609
- projectPath,
610
- discover: input.subject.discover,
611
- mapping: input.mapping,
612
- sourcePriority: input.sourcePriority,
613
- scope: input.scope
614
- }),
615
- nextActions: [
616
- {
617
- tool: "validate-project",
618
- params: {
619
- task: "project-summary",
620
- subject: input.subject
621
- }
622
- }
623
- ],
624
- notes: [
625
- "Pass version explicitly, or make sure gradle.properties declares the Minecraft version before using preferProjectVersion=true."
626
- ]
627
- },
628
- blocks: {
629
- workspace: {
630
- projectPath
631
- }
632
- }
633
- }),
634
- warnings: [
635
- "Could not resolve Minecraft version from gradle.properties for discovered workspace validators."
636
- ]
637
- };
638
- }
639
- if (!resolvedVersion) {
640
- return {
641
- ...buildEntryToolResult({
642
- task: "project-summary",
643
- detail,
644
- include,
645
- summary: {
646
- status: "ok",
647
- headline: `Validated ${mixinConfigs.length} mixin config(s), ${accessWideners.length} access widener(s), and ${accessTransformers.length} access transformer(s).`,
648
- subject: createSummarySubject({
649
- task: "project-summary",
650
- kind: input.subject.kind,
651
- projectPath,
652
- discover: input.subject.discover,
653
- mapping: input.mapping,
654
- sourcePriority: input.sourcePriority,
655
- scope: input.scope
656
- }),
657
- counts: {
658
- valid: 0,
659
- partial: 0,
660
- invalid: 0
661
- }
662
- },
663
- blocks: {
664
- workspace: {
665
- projectPath
666
- }
667
- }
668
- }),
669
- warnings: []
670
- };
671
- }
672
- const validationVersion = resolvedVersion;
673
- const warnings = [];
674
- let validMixins = 0;
675
- let partialMixins = 0;
676
- let invalidMixins = 0;
677
- for (const configPath of mixinConfigs) {
678
- try {
679
- const mixinResult = await this.deps.validateMixin({
680
- input: {
681
- mode: "config",
682
- configPaths: [configPath]
683
- },
684
- version: validationVersion,
685
- mapping: input.mapping,
686
- sourcePriority: input.sourcePriority,
687
- scope: input.scope,
688
- projectPath,
689
- preferProjectVersion: false,
690
- preferProjectMapping: input.preferProjectMapping,
691
- sourceRoots: input.sourceRoots,
692
- minSeverity: input.minSeverity,
693
- hideUncertain: input.hideUncertain,
694
- explain: input.explain,
695
- warningMode: input.warningMode,
696
- warningCategoryFilter: input.warningCategoryFilter,
697
- treatInfoAsWarning: input.treatInfoAsWarning,
698
- includeIssues: input.includeIssues
699
- });
700
- const summary = mixinResult.summary;
701
- validMixins += summary?.valid ?? 0;
702
- partialMixins += summary?.partial ?? 0;
703
- invalidMixins += summary?.invalid ?? 0;
704
- if (Array.isArray(mixinResult.warnings)) {
705
- warnings.push(...mixinResult.warnings);
706
- }
707
- }
708
- catch (error) {
709
- invalidMixins += 1;
710
- if (error instanceof Error) {
711
- warnings.push(`${configPath}: ${error.message}`);
712
- }
713
- }
714
- }
715
- let validAw = 0;
716
- let invalidAw = 0;
717
- for (const awPath of accessWideners) {
718
- try {
719
- const output = await this.deps.validateAccessWidener({
720
- content: await readFile(awPath, "utf8"),
721
- version: validationVersion,
722
- mapping: input.mapping,
723
- sourcePriority: input.sourcePriority,
724
- projectPath,
725
- scope: input.scope,
726
- preferProjectVersion: input.preferProjectVersion
727
- });
728
- if (output.valid) {
729
- validAw += 1;
730
- }
731
- else {
732
- invalidAw += 1;
733
- }
734
- if (Array.isArray(output.warnings)) {
735
- warnings.push(...output.warnings);
736
- }
737
- }
738
- catch (error) {
739
- invalidAw += 1;
740
- if (error instanceof Error) {
741
- warnings.push(error.message);
742
- }
743
- }
744
- }
745
- let validAt = 0;
746
- let invalidAt = 0;
747
- for (const atPath of accessTransformers) {
748
- try {
749
- if (!this.deps.validateAccessTransformer) {
750
- throw createError({
751
- code: ERROR_CODES.CONTEXT_UNRESOLVED,
752
- message: "Access Transformer validation is not configured."
753
- });
754
- }
755
- const output = await this.deps.validateAccessTransformer({
756
- content: await readFile(atPath, "utf8"),
757
- version: validationVersion,
758
- atNamespace: input.atNamespace,
759
- sourcePriority: input.sourcePriority,
760
- projectPath,
761
- scope: input.scope,
762
- preferProjectVersion: input.preferProjectVersion
763
- });
764
- if (output.valid) {
765
- validAt += 1;
766
- }
767
- else {
768
- invalidAt += 1;
769
- }
770
- if (Array.isArray(output.warnings)) {
771
- warnings.push(...output.warnings);
772
- }
773
- }
774
- catch (error) {
775
- invalidAt += 1;
776
- if (error instanceof Error) {
777
- warnings.push(error.message);
778
- }
779
- }
780
- }
781
- const invalidCount = invalidMixins + invalidAw + invalidAt;
782
- const partialCount = partialMixins;
783
- const status = invalidCount > 0 ? "invalid" : partialCount > 0 ? "partial" : "ok";
784
- return {
785
- ...buildEntryToolResult({
786
- task: "project-summary",
787
- detail,
788
- include,
789
- summary: {
790
- status,
791
- headline: `Validated ${mixinConfigs.length} mixin config(s), ${accessWideners.length} access widener(s), and ${accessTransformers.length} access transformer(s).`,
792
- subject: createSummarySubject({
793
- task: "project-summary",
794
- kind: input.subject.kind,
795
- projectPath,
796
- discover: input.subject.discover,
797
- version: resolvedVersion,
798
- mapping: input.mapping,
799
- sourcePriority: input.sourcePriority,
800
- scope: input.scope
801
- }),
802
- counts: {
803
- valid: validMixins + validAw + validAt,
804
- partial: partialCount,
805
- invalid: invalidCount
806
- }
807
- },
808
- blocks: {
809
- project: {
810
- summary: {
811
- valid: validMixins + validAw + validAt,
812
- partial: partialCount,
813
- invalid: invalidCount
814
- }
815
- },
816
- workspace: {
817
- projectPath,
818
- mixinConfigs,
819
- accessWideners,
820
- accessTransformers
821
- }
822
- },
823
- alwaysBlocks: ["project"]
824
- }),
825
- warnings
826
- };
827
- }
270
+ case "mixin":
271
+ return handleMixin(this.deps, input, detail, include);
272
+ case "access-widener":
273
+ return handleAccessWidener(this.deps, input, detail, include);
274
+ case "access-transformer":
275
+ return handleAccessTransformer(this.deps, input, detail, include);
276
+ case "project-summary":
277
+ return handleProjectSummary(this.deps, input, detail, include, options);
828
278
  }
829
279
  }
830
280
  }