@adhisang/minecraft-modding-mcp 4.1.1 → 4.2.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 (73) hide show
  1. package/CHANGELOG.md +14 -2
  2. package/README.md +6 -2
  3. package/dist/cache-registry.js +84 -5
  4. package/dist/entry-tools/analyze-symbol-service.d.ts +12 -0
  5. package/dist/entry-tools/analyze-symbol-service.js +7 -0
  6. package/dist/entry-tools/batch-class-members-service.d.ts +1 -0
  7. package/dist/entry-tools/batch-class-members-service.js +2 -0
  8. package/dist/entry-tools/batch-class-source-service.d.ts +1 -0
  9. package/dist/entry-tools/batch-class-source-service.js +2 -0
  10. package/dist/entry-tools/batch-mappings-service.d.ts +1 -0
  11. package/dist/entry-tools/batch-mappings-service.js +1 -0
  12. package/dist/entry-tools/batch-symbol-exists-service.d.ts +1 -0
  13. package/dist/entry-tools/batch-symbol-exists-service.js +2 -0
  14. package/dist/entry-tools/compare-minecraft-service.d.ts +9 -0
  15. package/dist/entry-tools/compare-minecraft-service.js +3 -1
  16. package/dist/entry-tools/inspect-minecraft/handlers/class-members.js +1 -0
  17. package/dist/entry-tools/inspect-minecraft/handlers/class-overview.js +3 -1
  18. package/dist/entry-tools/inspect-minecraft/handlers/class-source.js +1 -0
  19. package/dist/entry-tools/inspect-minecraft/handlers/list-files.js +1 -0
  20. package/dist/entry-tools/inspect-minecraft/handlers/search.js +2 -1
  21. package/dist/entry-tools/inspect-minecraft/internal.d.ts +17 -0
  22. package/dist/entry-tools/inspect-minecraft/internal.js +10 -0
  23. package/dist/entry-tools/inspect-minecraft-service.d.ts +40 -0
  24. package/dist/entry-tools/validate-project/cases/project-summary.js +8 -3
  25. package/dist/entry-tools/validate-project/internal.d.ts +6 -2
  26. package/dist/entry-tools/validate-project/internal.js +9 -7
  27. package/dist/entry-tools/validate-project-service.d.ts +10 -0
  28. package/dist/entry-tools/validate-project-service.js +1 -0
  29. package/dist/entry-tools/verify-mixin-target-service.d.ts +2 -0
  30. package/dist/entry-tools/verify-mixin-target-service.js +1 -0
  31. package/dist/errors.js +4 -1
  32. package/dist/gradle-paths.d.ts +8 -3
  33. package/dist/gradle-paths.js +34 -5
  34. package/dist/index.js +24 -7
  35. package/dist/java-process.d.ts +9 -0
  36. package/dist/java-process.js +11 -5
  37. package/dist/mapping/loaders/tiny-loom.d.ts +1 -1
  38. package/dist/mapping/loaders/tiny-loom.js +5 -2
  39. package/dist/mapping/types.d.ts +5 -0
  40. package/dist/mapping-service.d.ts +1 -0
  41. package/dist/mapping-service.js +16 -13
  42. package/dist/mixin-validator.d.ts +1 -1
  43. package/dist/mixin-validator.js +1 -1
  44. package/dist/nbt/java-nbt-codec.js +81 -2
  45. package/dist/source/access-validate.js +12 -8
  46. package/dist/source/artifact-resolver.d.ts +5 -0
  47. package/dist/source/artifact-resolver.js +23 -7
  48. package/dist/source/cache-metrics.js +2 -2
  49. package/dist/source/class-source/members-builder.d.ts +1 -0
  50. package/dist/source/class-source/members-builder.js +1 -1
  51. package/dist/source/class-source.d.ts +1 -0
  52. package/dist/source/class-source.js +9 -1
  53. package/dist/source/indexer.d.ts +31 -6
  54. package/dist/source/indexer.js +90 -23
  55. package/dist/source/lifecycle/diff.js +6 -6
  56. package/dist/source/lifecycle/mapping-helpers.d.ts +3 -3
  57. package/dist/source/lifecycle/mapping-helpers.js +17 -9
  58. package/dist/source/lifecycle/trace.js +2 -2
  59. package/dist/source/search.js +1 -0
  60. package/dist/source/symbol-resolver.js +4 -1
  61. package/dist/source/validate-mixin/pipeline/mapping-health.js +2 -1
  62. package/dist/source/validate-mixin/pipeline/resolve.js +1 -0
  63. package/dist/source/validate-mixin/pipeline/target-lookup.js +12 -7
  64. package/dist/source-service.d.ts +18 -1
  65. package/dist/source-service.js +2 -2
  66. package/dist/tiny-remapper-service.js +3 -3
  67. package/dist/tool-contract-manifest.d.ts +1 -1
  68. package/dist/tool-contract-manifest.js +2 -2
  69. package/dist/tool-schemas.d.ts +91 -0
  70. package/dist/tool-schemas.js +20 -0
  71. package/docs/README-ja.md +2 -2
  72. package/docs/tool-reference.md +5 -1
  73. package/package.json +1 -1
@@ -100,10 +100,10 @@ async function probeGradleReadable(projectPath) {
100
100
  };
101
101
  }
102
102
  }
103
- async function probeLoomCacheFound(projectPath) {
103
+ async function probeLoomCacheFound(projectPath, gradleUserHome) {
104
104
  const startedAt = Date.now();
105
105
  try {
106
- const roots = buildVersionSourceSearchRoots(projectPath);
106
+ const roots = buildVersionSourceSearchRoots({ projectPath, gradleUserHome });
107
107
  for (const root of roots) {
108
108
  if (await pathExists(root)) {
109
109
  return {
@@ -147,6 +147,7 @@ async function probeMinecraftArtifactResolved(artifactProbe, args, stageEmitter)
147
147
  mapping: args.mapping,
148
148
  sourcePriority: args.sourcePriority,
149
149
  projectPath: args.projectPath,
150
+ gradleUserHome: args.gradleUserHome,
150
151
  scope: args.scope,
151
152
  preferProjectVersion: args.preferProjectVersion
152
153
  });
@@ -215,9 +216,9 @@ function projectTaskStatusReport(report, detail, include) {
215
216
  }
216
217
  return projected;
217
218
  }
218
- export async function runUpstreamProbes(projectPath) {
219
+ export async function runUpstreamProbes(projectPath, gradleUserHome) {
219
220
  const workspace = await probeWorkspaceDetected(projectPath);
220
- const loom = await probeLoomCacheFound(projectPath);
221
+ const loom = await probeLoomCacheFound(projectPath, gradleUserHome);
221
222
  let gradle;
222
223
  if (workspace.status !== "ok") {
223
224
  gradle = { status: "skipped" };
@@ -227,11 +228,11 @@ export async function runUpstreamProbes(projectPath) {
227
228
  }
228
229
  return { workspace, gradle, loom };
229
230
  }
230
- export async function buildEarlyTasksForBlocked(projectPath, detail, include, discovery) {
231
+ export async function buildEarlyTasksForBlocked(projectPath, detail, include, discovery, gradleUserHome) {
231
232
  if (VALIDATE_PROJECT_TASKS_OFF) {
232
233
  return undefined;
233
234
  }
234
- const { workspace, gradle, loom } = await runUpstreamProbes(projectPath);
235
+ const { workspace, gradle, loom } = await runUpstreamProbes(projectPath, gradleUserHome);
235
236
  const minecraftArtifactResolved = {
236
237
  status: "skipped"
237
238
  };
@@ -262,7 +263,7 @@ export async function buildFullTaskStatusReport(deps, args) {
262
263
  if (VALIDATE_PROJECT_TASKS_OFF) {
263
264
  return undefined;
264
265
  }
265
- const { workspace, gradle, loom } = await runUpstreamProbes(args.projectPath);
266
+ const { workspace, gradle, loom } = await runUpstreamProbes(args.projectPath, args.gradleUserHome);
266
267
  let minecraftArtifactResolved;
267
268
  if (workspace.status !== "ok" || gradle.status !== "ok") {
268
269
  minecraftArtifactResolved = { status: "skipped" };
@@ -274,6 +275,7 @@ export async function buildFullTaskStatusReport(deps, args) {
274
275
  mapping: args.mapping,
275
276
  sourcePriority: args.sourcePriority,
276
277
  projectPath: args.projectPath,
278
+ gradleUserHome: args.gradleUserHome,
277
279
  scope: args.scope,
278
280
  preferProjectVersion: args.preferProjectVersion
279
281
  }, args.stageEmitter);
@@ -52,14 +52,17 @@ export declare const validateProjectShape: {
52
52
  subject: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
53
53
  kind: z.ZodLiteral<"workspace">;
54
54
  projectPath: z.ZodString;
55
+ gradleUserHome: z.ZodOptional<z.ZodString>;
55
56
  discover: z.ZodOptional<z.ZodArray<z.ZodEnum<["mixins", "access-wideners", "access-transformers"]>, "many">>;
56
57
  }, "strip", z.ZodTypeAny, {
57
58
  kind: "workspace";
58
59
  projectPath: string;
60
+ gradleUserHome?: string | undefined;
59
61
  discover?: ("mixins" | "access-wideners" | "access-transformers")[] | undefined;
60
62
  }, {
61
63
  kind: "workspace";
62
64
  projectPath: string;
65
+ gradleUserHome?: string | undefined;
63
66
  discover?: ("mixins" | "access-wideners" | "access-transformers")[] | undefined;
64
67
  }>, z.ZodObject<{
65
68
  kind: z.ZodLiteral<"mixin">;
@@ -248,14 +251,17 @@ export declare const validateProjectSchema: z.ZodEffects<z.ZodObject<{
248
251
  subject: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
249
252
  kind: z.ZodLiteral<"workspace">;
250
253
  projectPath: z.ZodString;
254
+ gradleUserHome: z.ZodOptional<z.ZodString>;
251
255
  discover: z.ZodOptional<z.ZodArray<z.ZodEnum<["mixins", "access-wideners", "access-transformers"]>, "many">>;
252
256
  }, "strip", z.ZodTypeAny, {
253
257
  kind: "workspace";
254
258
  projectPath: string;
259
+ gradleUserHome?: string | undefined;
255
260
  discover?: ("mixins" | "access-wideners" | "access-transformers")[] | undefined;
256
261
  }, {
257
262
  kind: "workspace";
258
263
  projectPath: string;
264
+ gradleUserHome?: string | undefined;
259
265
  discover?: ("mixins" | "access-wideners" | "access-transformers")[] | undefined;
260
266
  }>, z.ZodObject<{
261
267
  kind: z.ZodLiteral<"mixin">;
@@ -449,6 +455,7 @@ export declare const validateProjectSchema: z.ZodEffects<z.ZodObject<{
449
455
  subject: {
450
456
  kind: "workspace";
451
457
  projectPath: string;
458
+ gradleUserHome?: string | undefined;
452
459
  discover?: ("mixins" | "access-wideners" | "access-transformers")[] | undefined;
453
460
  } | {
454
461
  kind: "mixin";
@@ -504,6 +511,7 @@ export declare const validateProjectSchema: z.ZodEffects<z.ZodObject<{
504
511
  subject: {
505
512
  kind: "workspace";
506
513
  projectPath: string;
514
+ gradleUserHome?: string | undefined;
507
515
  discover?: ("mixins" | "access-wideners" | "access-transformers")[] | undefined;
508
516
  } | {
509
517
  kind: "mixin";
@@ -571,6 +579,7 @@ export declare const validateProjectSchema: z.ZodEffects<z.ZodObject<{
571
579
  subject: {
572
580
  kind: "workspace";
573
581
  projectPath: string;
582
+ gradleUserHome?: string | undefined;
574
583
  discover?: ("mixins" | "access-wideners" | "access-transformers")[] | undefined;
575
584
  } | {
576
585
  kind: "mixin";
@@ -626,6 +635,7 @@ export declare const validateProjectSchema: z.ZodEffects<z.ZodObject<{
626
635
  subject: {
627
636
  kind: "workspace";
628
637
  projectPath: string;
638
+ gradleUserHome?: string | undefined;
629
639
  discover?: ("mixins" | "access-wideners" | "access-transformers")[] | undefined;
630
640
  } | {
631
641
  kind: "mixin";
@@ -31,6 +31,7 @@ const subjectSchema = z.discriminatedUnion("kind", [
31
31
  z.object({
32
32
  kind: z.literal("workspace"),
33
33
  projectPath: nonEmptyString,
34
+ gradleUserHome: nonEmptyString.optional(),
34
35
  discover: z.array(z.enum(["mixins", "access-wideners", "access-transformers"])).optional()
35
36
  }),
36
37
  z.object({
@@ -16,6 +16,7 @@ export type VerifyMixinTargetInput = {
16
16
  mapping?: SourceMapping;
17
17
  sourcePriority?: MappingSourcePriority;
18
18
  projectPath?: string;
19
+ gradleUserHome?: string;
19
20
  target?: ResolveArtifactTargetInput;
20
21
  scope?: ArtifactScope;
21
22
  preferProjectVersion?: boolean;
@@ -82,6 +83,7 @@ export type VerifyMixinTargetDeps = {
82
83
  mapping?: SourceMapping;
83
84
  sourcePriority?: MappingSourcePriority;
84
85
  projectPath?: string;
86
+ gradleUserHome?: string;
85
87
  scope?: ArtifactScope;
86
88
  preferProjectVersion?: boolean;
87
89
  strictVersion?: boolean;
@@ -185,6 +185,7 @@ export class VerifyMixinTargetService {
185
185
  mapping: input.mapping,
186
186
  sourcePriority: input.sourcePriority,
187
187
  projectPath: input.projectPath,
188
+ gradleUserHome: input.gradleUserHome,
188
189
  scope: input.scope,
189
190
  preferProjectVersion: input.preferProjectVersion,
190
191
  strictVersion: input.strictVersion
package/dist/errors.js CHANGED
@@ -49,7 +49,10 @@ export class AppError extends Error {
49
49
  }
50
50
  }
51
51
  export const createError = (payload) => new AppError(payload);
52
+ // Narrow strictly by class identity. Duck-typing on `code` would also accept
53
+ // arbitrary Errors whose `details` may leak unsanitised context (paths, tokens)
54
+ // into AppError handling paths.
52
55
  export const isAppError = (value) => {
53
- return value instanceof Error && value.code !== undefined;
56
+ return value instanceof AppError;
54
57
  };
55
58
  //# sourceMappingURL=errors.js.map
@@ -1,4 +1,9 @@
1
1
  export declare function normalizeOptionalProjectPath(projectPath: string | undefined): string | undefined;
2
- export declare function resolveGradleUserHomePath(): string;
3
- export declare function buildVersionSourceSearchRoots(projectPath: string | undefined): string[];
4
- export declare function buildLoaderRuntimeSearchRoots(projectPath: string | undefined): string[];
2
+ export declare function normalizeOptionalGradleUserHomePath(gradleUserHome: string | undefined): string | undefined;
3
+ export declare function resolveGradleUserHomePath(gradleUserHome?: string): string;
4
+ export type GradleCacheSearchInput = string | {
5
+ projectPath?: string;
6
+ gradleUserHome?: string;
7
+ } | undefined;
8
+ export declare function buildVersionSourceSearchRoots(input: GradleCacheSearchInput): string[];
9
+ export declare function buildLoaderRuntimeSearchRoots(input: GradleCacheSearchInput): string[];
@@ -12,7 +12,22 @@ export function normalizeOptionalProjectPath(projectPath) {
12
12
  const normalized = normalizePathForHost(trimmed, undefined, "projectPath");
13
13
  return isAbsolute(normalized) ? normalized : resolvePath(process.cwd(), normalized);
14
14
  }
15
- export function resolveGradleUserHomePath() {
15
+ export function normalizeOptionalGradleUserHomePath(gradleUserHome) {
16
+ if (!gradleUserHome) {
17
+ return undefined;
18
+ }
19
+ const trimmed = gradleUserHome.trim();
20
+ if (!trimmed) {
21
+ return undefined;
22
+ }
23
+ const normalized = normalizePathForHost(trimmed, undefined, "gradleUserHome");
24
+ return isAbsolute(normalized) ? normalized : resolvePath(process.cwd(), normalized);
25
+ }
26
+ export function resolveGradleUserHomePath(gradleUserHome) {
27
+ const explicit = normalizeOptionalGradleUserHomePath(gradleUserHome);
28
+ if (explicit) {
29
+ return explicit;
30
+ }
16
31
  const configured = process.env.GRADLE_USER_HOME?.trim();
17
32
  if (!configured) {
18
33
  return resolvePath(homedir(), ".gradle");
@@ -20,7 +35,20 @@ export function resolveGradleUserHomePath() {
20
35
  const normalized = normalizePathForHost(configured, undefined, "GRADLE_USER_HOME");
21
36
  return isAbsolute(normalized) ? normalized : resolvePath(process.cwd(), normalized);
22
37
  }
23
- export function buildVersionSourceSearchRoots(projectPath) {
38
+ function normalizeGradleCacheSearchInput(input) {
39
+ if (typeof input === "string" || input === undefined) {
40
+ return {
41
+ projectPath: normalizeOptionalProjectPath(input)
42
+ };
43
+ }
44
+ const gradleUserHome = normalizeOptionalGradleUserHomePath(input.gradleUserHome);
45
+ return {
46
+ projectPath: normalizeOptionalProjectPath(input.projectPath),
47
+ gradleUserHome
48
+ };
49
+ }
50
+ export function buildVersionSourceSearchRoots(input) {
51
+ const { projectPath, gradleUserHome } = normalizeGradleCacheSearchInput(input);
24
52
  const roots = new Set();
25
53
  if (projectPath) {
26
54
  roots.add(resolvePath(projectPath, ".gradle", "loom-cache"));
@@ -30,12 +58,13 @@ export function buildVersionSourceSearchRoots(projectPath) {
30
58
  roots.add(resolvePath(projectParent, ".gradle-user-home", "loom-cache"));
31
59
  roots.add(resolvePath(projectParent, ".gradle-user-home", "caches", "fabric-loom"));
32
60
  }
33
- const homeGradle = resolveGradleUserHomePath();
61
+ const homeGradle = resolveGradleUserHomePath(gradleUserHome);
34
62
  roots.add(resolvePath(homeGradle, "loom-cache"));
35
63
  roots.add(resolvePath(homeGradle, "caches", "fabric-loom"));
36
64
  return [...roots];
37
65
  }
38
- export function buildLoaderRuntimeSearchRoots(projectPath) {
66
+ export function buildLoaderRuntimeSearchRoots(input) {
67
+ const { projectPath, gradleUserHome } = normalizeGradleCacheSearchInput(input);
39
68
  const roots = new Set();
40
69
  if (projectPath) {
41
70
  roots.add(resolvePath(projectPath, "build"));
@@ -47,7 +76,7 @@ export function buildLoaderRuntimeSearchRoots(projectPath) {
47
76
  roots.add(resolvePath(projectPath, ".gradle", "caches", "neoformruntime"));
48
77
  roots.add(resolvePath(projectPath, ".gradle", "caches", "moddev"));
49
78
  }
50
- const homeGradle = resolveGradleUserHomePath();
79
+ const homeGradle = resolveGradleUserHomePath(gradleUserHome);
51
80
  roots.add(resolvePath(homeGradle, "caches", "forge_gradle"));
52
81
  roots.add(resolvePath(homeGradle, "caches", "neogradle"));
53
82
  roots.add(resolvePath(homeGradle, "caches", "neoformruntime"));
package/dist/index.js CHANGED
@@ -142,6 +142,7 @@ const validateProjectService = new ValidateProjectService({
142
142
  mapping: input.mapping,
143
143
  sourcePriority: input.sourcePriority,
144
144
  projectPath: input.projectPath,
145
+ gradleUserHome: input.gradleUserHome,
145
146
  scope: input.scope,
146
147
  preferProjectVersion: input.preferProjectVersion
147
148
  });
@@ -166,6 +167,7 @@ const verifyMixinTargetService = new VerifyMixinTargetService({
166
167
  mapping: input.mapping,
167
168
  sourcePriority: input.sourcePriority,
168
169
  projectPath: input.projectPath,
170
+ gradleUserHome: input.gradleUserHome,
169
171
  scope: input.scope,
170
172
  preferProjectVersion: input.preferProjectVersion,
171
173
  strictVersion: input.strictVersion
@@ -406,19 +408,19 @@ server.tool("list-versions", "List available Minecraft versions from Mojang mani
406
408
  limit: input.limit
407
409
  })));
408
410
  registerToolSchema("list-versions", listVersionsSchema);
409
- server.tool("inspect-minecraft", "High-level v3 entry tool for version discovery, artifact resolution, class inspection, source search, file reads, and file listings.", inspectMinecraftShape, { readOnlyHint: true }, async (args) => runTool("inspect-minecraft", args, inspectMinecraftSchema, async (input) => inspectMinecraftService.execute(input)));
411
+ server.tool("inspect-minecraft", "Top-level workflow tool for version discovery, artifact resolution, class inspection, source search, file reads, and file listings.", inspectMinecraftShape, { readOnlyHint: true }, async (args) => runTool("inspect-minecraft", args, inspectMinecraftSchema, async (input) => inspectMinecraftService.execute(input)));
410
412
  registerToolSchema("inspect-minecraft", inspectMinecraftSchema);
411
- server.tool("analyze-symbol", "High-level v3 entry tool for symbol existence, mapping, lifecycle, workspace analysis, and API overview.", analyzeSymbolShape, { readOnlyHint: true }, async (args) => runTool("analyze-symbol", args, analyzeSymbolSchema, async (input) => analyzeSymbolService.execute(input)));
413
+ server.tool("analyze-symbol", "Top-level workflow tool for symbol existence, mapping, lifecycle, workspace analysis, and API overview.", analyzeSymbolShape, { readOnlyHint: true }, async (args) => runTool("analyze-symbol", args, analyzeSymbolSchema, async (input) => analyzeSymbolService.execute(input)));
412
414
  registerToolSchema("analyze-symbol", analyzeSymbolSchema);
413
- server.tool("compare-minecraft", "High-level v3 entry tool for version comparisons, class diffs, registry diffs, and migration overviews.", compareMinecraftShape, { readOnlyHint: true }, async (args) => runTool("compare-minecraft", args, compareMinecraftSchema, async (input) => compareMinecraftService.execute(input)));
415
+ server.tool("compare-minecraft", "Top-level workflow tool for version comparisons, class diffs, registry diffs, and migration overviews.", compareMinecraftShape, { readOnlyHint: true }, async (args) => runTool("compare-minecraft", args, compareMinecraftSchema, async (input) => compareMinecraftService.execute(input)));
414
416
  registerToolSchema("compare-minecraft", compareMinecraftSchema);
415
- server.tool("analyze-mod", "High-level v3 entry tool for mod metadata inspection, decompile/search flows, class source, and safe remap previews/applies.", analyzeModShape, { readOnlyHint: false }, async (args) => runTool("analyze-mod", args, analyzeModSchema, async (input) => analyzeModService.execute(input)));
417
+ server.tool("analyze-mod", "Top-level workflow tool for mod metadata inspection, decompile/search flows, class source, and safe remap previews/applies.", analyzeModShape, { readOnlyHint: false }, async (args) => runTool("analyze-mod", args, analyzeModSchema, async (input) => analyzeModService.execute(input)));
416
418
  registerToolSchema("analyze-mod", analyzeModSchema);
417
- server.tool("validate-project", "High-level v3 entry tool for project summary, direct mixin validation, and access widener/access transformer validation.", validateProjectShape, { readOnlyHint: true }, async (args, extra) => runTool("validate-project", args, validateProjectSchema, async (input) => validateProjectService.execute(input, {
419
+ server.tool("validate-project", "Top-level workflow tool for project summary, direct mixin validation, and access widener/access transformer validation.", validateProjectShape, { readOnlyHint: true }, async (args, extra) => runTool("validate-project", args, validateProjectSchema, async (input) => validateProjectService.execute(input, {
418
420
  stageEmitter: makeStageEmitter(extra)
419
421
  })));
420
422
  registerToolSchema("validate-project", validateProjectSchema);
421
- server.tool("manage-cache", "High-level v3 entry tool for cache summaries, listing, verification, previewed mutation, and explicit apply operations.", manageCacheShape, { readOnlyHint: false }, async (args) => runTool("manage-cache", args, manageCacheSchema, async (input) => manageCacheService.execute(input)));
423
+ server.tool("manage-cache", "Top-level workflow tool for cache summaries, listing, verification, previewed mutation, and explicit apply operations.", manageCacheShape, { readOnlyHint: false }, async (args) => runTool("manage-cache", args, manageCacheSchema, async (input) => manageCacheService.execute(input)));
422
424
  registerToolSchema("manage-cache", manageCacheSchema);
423
425
  if (!VERIFY_MIXIN_TARGET_OFF) {
424
426
  server.tool("verify-mixin-target", "Single-call probe: does this target owner / member exist and which @Shadow / @Accessor / @Invoker should the mixin use? Reuses target.kind workspace/version/coordinate/dependency/jar.", verifyMixinTargetShape, { readOnlyHint: true }, async (args) => runTool("verify-mixin-target", args, verifyMixinTargetSchema, async (input) => verifyMixinTargetService.execute({
@@ -428,6 +430,7 @@ if (!VERIFY_MIXIN_TARGET_OFF) {
428
430
  mapping: input.mapping,
429
431
  sourcePriority: input.sourcePriority,
430
432
  projectPath: input.projectPath,
433
+ gradleUserHome: input.gradleUserHome,
431
434
  target: input.target,
432
435
  scope: input.scope,
433
436
  preferProjectVersion: input.preferProjectVersion,
@@ -451,6 +454,7 @@ server.tool("resolve-artifact", "Resolve source artifact from a target object ({
451
454
  sourcePriority: input.sourcePriority,
452
455
  allowDecompile: input.allowDecompile,
453
456
  projectPath: input.projectPath,
457
+ gradleUserHome: input.gradleUserHome,
454
458
  scope: input.scope,
455
459
  preferProjectVersion: input.preferProjectVersion,
456
460
  strictVersion: input.strictVersion,
@@ -480,6 +484,7 @@ server.tool("get-class-source", "Get Java source for a class by target ({ type:
480
484
  sourcePriority: input.sourcePriority,
481
485
  allowDecompile: input.allowDecompile,
482
486
  projectPath: input.projectPath,
487
+ gradleUserHome: input.gradleUserHome,
483
488
  scope: input.scope,
484
489
  preferProjectVersion: input.preferProjectVersion,
485
490
  strictVersion: input.strictVersion,
@@ -506,6 +511,7 @@ server.tool("get-class-members", "Get fields/methods/constructors for one class
506
511
  memberPattern: input.memberPattern,
507
512
  maxMembers: input.maxMembers,
508
513
  projectPath: input.projectPath,
514
+ gradleUserHome: input.gradleUserHome,
509
515
  scope: input.scope,
510
516
  preferProjectVersion: input.preferProjectVersion,
511
517
  strictVersion: input.strictVersion
@@ -530,7 +536,8 @@ server.tool("search-class-source", "Search indexed class source files for one ar
530
536
  limit: input.limit,
531
537
  cursor: input.cursor,
532
538
  queryNamespace: input.queryNamespace,
533
- sourcePriority: input.sourcePriority
539
+ sourcePriority: input.sourcePriority,
540
+ gradleUserHome: input.gradleUserHome
534
541
  });
535
542
  }));
536
543
  registerToolSchema("search-class-source", searchClassSourceSchema);
@@ -554,6 +561,7 @@ server.tool("trace-symbol-lifecycle", "Trace which Minecraft versions contain a
554
561
  toVersion: input.toVersion,
555
562
  mapping: input.mapping,
556
563
  sourcePriority: input.sourcePriority,
564
+ gradleUserHome: input.gradleUserHome,
557
565
  includeSnapshots: input.includeSnapshots,
558
566
  maxVersions: input.maxVersions,
559
567
  includeTimeline: input.includeTimeline
@@ -565,6 +573,7 @@ server.tool("diff-class-signatures", "Compare one class signature between two Mi
565
573
  toVersion: input.toVersion,
566
574
  mapping: input.mapping,
567
575
  sourcePriority: input.sourcePriority,
576
+ gradleUserHome: input.gradleUserHome,
568
577
  includeFullDiff: input.includeFullDiff
569
578
  })));
570
579
  registerToolSchema("diff-class-signatures", diffClassSignaturesSchema);
@@ -577,6 +586,7 @@ server.tool("find-mapping", "Find symbol mapping candidates between namespaces u
577
586
  sourceMapping: input.sourceMapping,
578
587
  targetMapping: input.targetMapping,
579
588
  sourcePriority: input.sourcePriority,
589
+ gradleUserHome: input.gradleUserHome,
580
590
  signatureMode: input.signatureMode,
581
591
  disambiguation: input.disambiguation,
582
592
  maxCandidates: input.maxCandidates
@@ -590,6 +600,7 @@ server.tool("resolve-method-mapping-exact", "Resolve one method mapping exactly
590
600
  sourceMapping: input.sourceMapping,
591
601
  targetMapping: input.targetMapping,
592
602
  sourcePriority: input.sourcePriority,
603
+ gradleUserHome: input.gradleUserHome,
593
604
  maxCandidates: input.maxCandidates
594
605
  })));
595
606
  registerToolSchema("resolve-method-mapping-exact", resolveMethodMappingExactSchema);
@@ -599,6 +610,7 @@ server.tool("get-class-api-matrix", "List class/member API rows across obfuscate
599
610
  classNameMapping: input.classNameMapping,
600
611
  includeKinds: parseClassApiKinds(input.includeKinds),
601
612
  sourcePriority: input.sourcePriority,
613
+ gradleUserHome: input.gradleUserHome,
602
614
  maxRows: input.maxRows
603
615
  })));
604
616
  registerToolSchema("get-class-api-matrix", getClassApiMatrixSchema);
@@ -611,6 +623,7 @@ server.tool("resolve-workspace-symbol", "Resolve class/field/method names as see
611
623
  descriptor: input.descriptor,
612
624
  sourceMapping: input.sourceMapping,
613
625
  sourcePriority: input.sourcePriority,
626
+ gradleUserHome: input.gradleUserHome,
614
627
  maxCandidates: input.maxCandidates
615
628
  })));
616
629
  registerToolSchema("resolve-workspace-symbol", resolveWorkspaceSymbolSchema);
@@ -622,6 +635,7 @@ server.tool("check-symbol-exists", "Check whether a class/field/method symbol ex
622
635
  descriptor: input.descriptor,
623
636
  sourceMapping: input.sourceMapping,
624
637
  sourcePriority: input.sourcePriority,
638
+ gradleUserHome: input.gradleUserHome,
625
639
  nameMode: input.nameMode,
626
640
  signatureMode: input.signatureMode,
627
641
  maxCandidates: input.maxCandidates
@@ -657,6 +671,7 @@ server.tool("validate-mixin", "Validate Mixin source against Minecraft bytecode
657
671
  sourcePriority: input.sourcePriority,
658
672
  scope: input.scope,
659
673
  projectPath: input.projectPath,
674
+ gradleUserHome: input.gradleUserHome,
660
675
  preferProjectVersion: input.preferProjectVersion,
661
676
  minSeverity: input.minSeverity,
662
677
  hideUncertain: input.hideUncertain,
@@ -677,6 +692,7 @@ server.tool("validate-access-widener", "Validate Access Widener file entries aga
677
692
  mapping: input.mapping,
678
693
  sourcePriority: input.sourcePriority,
679
694
  projectPath: input.projectPath,
695
+ gradleUserHome: input.gradleUserHome,
680
696
  scope: input.scope,
681
697
  preferProjectVersion: input.preferProjectVersion
682
698
  })));
@@ -687,6 +703,7 @@ server.tool("validate-access-transformer", "Validate Access Transformer file ent
687
703
  atNamespace: input.atNamespace,
688
704
  sourcePriority: input.sourcePriority,
689
705
  projectPath: input.projectPath,
706
+ gradleUserHome: input.gradleUserHome,
690
707
  scope: input.scope,
691
708
  preferProjectVersion: input.preferProjectVersion
692
709
  })));
@@ -1,3 +1,4 @@
1
+ export declare const MAX_STDIO_SNAPSHOT = 6240;
1
2
  export interface JavaProcessOptions {
2
3
  jarPath: string;
3
4
  args: string[];
@@ -12,5 +13,13 @@ export interface JavaProcessResult {
12
13
  stdoutTail: string;
13
14
  stderrTail: string;
14
15
  }
16
+ export declare function limitStdio(text: string): string;
17
+ export declare function isAbsolutePath(value: string): boolean;
18
+ export declare function isOptionArg(value: string): boolean;
19
+ export declare function normalizeArgs(args: string[]): string[];
15
20
  export declare function assertJavaAvailable(): Promise<void>;
16
21
  export declare function runJavaProcess(options: JavaProcessOptions): Promise<JavaProcessResult>;
22
+ export declare const javaRunner: {
23
+ run: (options: JavaProcessOptions) => Promise<JavaProcessResult>;
24
+ assertAvailable: () => Promise<void>;
25
+ };
@@ -2,20 +2,20 @@ import { spawn } from "node:child_process";
2
2
  import { createError, ERROR_CODES } from "./errors.js";
3
3
  import { normalizePathForHost } from "./path-converter.js";
4
4
  const JAVA_CHECK_TIMEOUT_MS = 2_000;
5
- const MAX_STDIO_SNAPSHOT = 6_240;
6
- function limitStdio(text) {
5
+ export const MAX_STDIO_SNAPSHOT = 6_240;
6
+ export function limitStdio(text) {
7
7
  if (text.length <= MAX_STDIO_SNAPSHOT) {
8
8
  return text;
9
9
  }
10
10
  return text.slice(-MAX_STDIO_SNAPSHOT);
11
11
  }
12
- function isAbsolutePath(value) {
12
+ export function isAbsolutePath(value) {
13
13
  return value.startsWith("/") || /^[A-Za-z]:[\\/]/.test(value);
14
14
  }
15
- function isOptionArg(value) {
15
+ export function isOptionArg(value) {
16
16
  return value.startsWith("-");
17
17
  }
18
- function normalizeArgs(args) {
18
+ export function normalizeArgs(args) {
19
19
  return args.map((arg) => {
20
20
  if (isOptionArg(arg)) {
21
21
  return arg;
@@ -117,4 +117,10 @@ export function runJavaProcess(options) {
117
117
  });
118
118
  });
119
119
  }
120
+ // Mutable container that lets tests stub the Java subprocess boundary via
121
+ // `mock.method(javaRunner, "run", ...)` without rewriting ESM named imports.
122
+ export const javaRunner = {
123
+ run: runJavaProcess,
124
+ assertAvailable: assertJavaAvailable
125
+ };
120
126
  //# sourceMappingURL=java-process.js.map
@@ -1,2 +1,2 @@
1
1
  import type { MappingLoaderResult } from "./types.js";
2
- export declare function loadTinyPairsFromLoom(version: string, projectPath?: string): Promise<MappingLoaderResult>;
2
+ export declare function loadTinyPairsFromLoom(version: string, projectPath?: string, gradleUserHome?: string): Promise<MappingLoaderResult>;
@@ -7,8 +7,11 @@ import { effectiveLoomSearchProjectPath } from "../lookup.js";
7
7
  import { mergeDirectionIndexes } from "../parsers/symbol-records.js";
8
8
  import { parseTinyMappings } from "../parsers/tiny.js";
9
9
  const GLOB_SPECIAL_CHARS = /[\\!*+?()[\]{}@|]/g;
10
- export async function loadTinyPairsFromLoom(version, projectPath) {
11
- const searchRoots = buildVersionSourceSearchRoots(effectiveLoomSearchProjectPath(projectPath));
10
+ export async function loadTinyPairsFromLoom(version, projectPath, gradleUserHome) {
11
+ const searchRoots = buildVersionSourceSearchRoots({
12
+ projectPath: effectiveLoomSearchProjectPath(projectPath),
13
+ gradleUserHome
14
+ });
12
15
  const merged = new Map();
13
16
  const discoveredPaths = new Set();
14
17
  for (const root of searchRoots) {
@@ -60,6 +60,7 @@ export type FindMappingInput = {
60
60
  targetMapping: SourceMapping;
61
61
  sourcePriority?: MappingSourcePriority;
62
62
  projectPath?: string;
63
+ gradleUserHome?: string;
63
64
  disambiguation?: {
64
65
  ownerHint?: string;
65
66
  descriptorHint?: string;
@@ -73,6 +74,7 @@ export type EnsureMappingAvailableInput = {
73
74
  targetMapping: SourceMapping;
74
75
  sourcePriority?: MappingSourcePriority;
75
76
  projectPath?: string;
77
+ gradleUserHome?: string;
76
78
  };
77
79
  export type EnsureMappingAvailableOutput = {
78
80
  transformChain: string[];
@@ -88,6 +90,7 @@ export type ResolveMethodMappingExactInput = {
88
90
  targetMapping: SourceMapping;
89
91
  sourcePriority?: MappingSourcePriority;
90
92
  projectPath?: string;
93
+ gradleUserHome?: string;
91
94
  maxCandidates?: number;
92
95
  };
93
96
  export type ResolveMethodMappingExactOutput = SymbolResolutionOutput;
@@ -97,6 +100,7 @@ export type ClassApiMatrixInput = {
97
100
  className: string;
98
101
  classNameMapping: SourceMapping;
99
102
  sourcePriority?: MappingSourcePriority;
103
+ gradleUserHome?: string;
100
104
  includeKinds?: ClassApiMatrixKind[];
101
105
  maxRows?: number;
102
106
  };
@@ -134,6 +138,7 @@ export type SymbolExistenceInput = {
134
138
  descriptor?: string;
135
139
  sourceMapping: SourceMapping;
136
140
  sourcePriority?: MappingSourcePriority;
141
+ gradleUserHome?: string;
137
142
  nameMode?: "fqcn" | "auto";
138
143
  signatureMode?: "exact" | "name-only";
139
144
  maxCandidates?: number;
@@ -41,6 +41,7 @@ export declare class MappingService {
41
41
  version: string;
42
42
  requestedMapping: SourceMapping;
43
43
  sourcePriority?: MappingSourcePriority;
44
+ gradleUserHome?: string;
44
45
  }): Promise<{
45
46
  mojangMappingsAvailable: boolean;
46
47
  tinyMappingsAvailable: boolean;