@adhisang/minecraft-modding-mcp 1.1.1 → 1.2.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/CHANGELOG.md +49 -0
- package/README.md +83 -16
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/decompiler/vineflower.d.ts +1 -0
- package/dist/decompiler/vineflower.js +78 -29
- package/dist/index.js +167 -23
- package/dist/mapping-service.d.ts +22 -0
- package/dist/mapping-service.js +309 -30
- package/dist/mixin-parser.d.ts +1 -0
- package/dist/mixin-parser.js +134 -16
- package/dist/mixin-validator.d.ts +93 -2
- package/dist/mixin-validator.js +464 -41
- package/dist/mod-analyzer.d.ts +2 -0
- package/dist/mod-analyzer.js +7 -0
- package/dist/mod-decompile-service.d.ts +6 -0
- package/dist/mod-decompile-service.js +36 -4
- package/dist/mod-search-service.d.ts +1 -0
- package/dist/mod-search-service.js +96 -0
- package/dist/search-hit-accumulator.d.ts +1 -0
- package/dist/search-hit-accumulator.js +3 -0
- package/dist/source-resolver.js +0 -4
- package/dist/source-service.d.ts +91 -4
- package/dist/source-service.js +1153 -112
- package/dist/storage/files-repo.js +35 -8
- package/dist/types.d.ts +1 -0
- package/dist/version-service.js +30 -6
- package/dist/workspace-mapping-service.d.ts +1 -0
- package/dist/workspace-mapping-service.js +24 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22,6 +22,9 @@ const SEARCH_MATCHES = ["exact", "prefix", "contains", "regex"];
|
|
|
22
22
|
const SEARCH_SYMBOL_KINDS = ["class", "interface", "enum", "record", "method", "field"];
|
|
23
23
|
const MEMBER_ACCESS = ["public", "all"];
|
|
24
24
|
const WORKSPACE_SYMBOL_KINDS = ["class", "field", "method"];
|
|
25
|
+
const CLASS_NAME_MODES = ["fqcn", "auto"];
|
|
26
|
+
const SOURCE_MODES = ["metadata", "snippet", "full"];
|
|
27
|
+
const ARTIFACT_SCOPES = ["vanilla", "merged", "loader"];
|
|
25
28
|
const DECODE_COMPRESSIONS = ["none", "gzip", "auto"];
|
|
26
29
|
const ENCODE_COMPRESSIONS = ["none", "gzip"];
|
|
27
30
|
const nonEmptyString = z.string().trim().min(1);
|
|
@@ -35,6 +38,9 @@ const searchMatchSchema = z.enum(SEARCH_MATCHES);
|
|
|
35
38
|
const searchSymbolKindSchema = z.enum(SEARCH_SYMBOL_KINDS);
|
|
36
39
|
const memberAccessSchema = z.enum(MEMBER_ACCESS);
|
|
37
40
|
const workspaceSymbolKindSchema = z.enum(WORKSPACE_SYMBOL_KINDS);
|
|
41
|
+
const classNameModeSchema = z.enum(CLASS_NAME_MODES);
|
|
42
|
+
const sourceModeSchema = z.enum(SOURCE_MODES);
|
|
43
|
+
const artifactScopeSchema = z.enum(ARTIFACT_SCOPES);
|
|
38
44
|
const decodeCompressionSchema = z.enum(DECODE_COMPRESSIONS);
|
|
39
45
|
const encodeCompressionSchema = z.enum(ENCODE_COMPRESSIONS);
|
|
40
46
|
function validateTargetPair(value, ctx) {
|
|
@@ -75,20 +81,31 @@ const resolveArtifactShape = {
|
|
|
75
81
|
targetValue: nonEmptyString,
|
|
76
82
|
mapping: sourceMappingSchema.optional().describe("official | mojang | intermediary | yarn"),
|
|
77
83
|
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
78
|
-
allowDecompile: z.boolean().optional().describe("default true")
|
|
84
|
+
allowDecompile: z.boolean().optional().describe("default true"),
|
|
85
|
+
projectPath: optionalNonEmptyString.describe("Optional workspace root path for Loom cache-assisted source resolution"),
|
|
86
|
+
scope: artifactScopeSchema.optional().describe("vanilla = Mojang client jar only; merged = Loom cache discovery (default); loader = loader-specific"),
|
|
87
|
+
preferProjectVersion: z.boolean().optional().describe("When true, detect MC version from gradle.properties and override targetValue"),
|
|
88
|
+
strictVersion: z.boolean().optional().describe("When true, reject version-approximated results instead of returning them. Default false.")
|
|
79
89
|
};
|
|
80
90
|
const resolveArtifactSchema = z.object(resolveArtifactShape);
|
|
81
91
|
const getClassSourceShape = {
|
|
82
92
|
className: nonEmptyString,
|
|
93
|
+
mode: sourceModeSchema.optional().describe("metadata (default) = symbol outline only; snippet = source with default maxLines=200; full = entire source"),
|
|
83
94
|
artifactId: optionalNonEmptyString,
|
|
84
95
|
targetKind: targetKindSchema.optional().describe("version | jar | coordinate"),
|
|
85
96
|
targetValue: optionalNonEmptyString,
|
|
86
97
|
mapping: sourceMappingSchema.optional().describe("official | mojang | intermediary | yarn"),
|
|
87
98
|
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
88
99
|
allowDecompile: z.boolean().optional().describe("default true"),
|
|
100
|
+
projectPath: optionalNonEmptyString.describe("Optional workspace root path for Loom cache-assisted source resolution"),
|
|
101
|
+
scope: artifactScopeSchema.optional().describe("vanilla = Mojang client jar only; merged = Loom cache discovery (default); loader = loader-specific"),
|
|
102
|
+
preferProjectVersion: z.boolean().optional().describe("When true, detect MC version from gradle.properties and override targetValue"),
|
|
103
|
+
strictVersion: z.boolean().optional().describe("When true, reject version-approximated results instead of returning them. Default false."),
|
|
89
104
|
startLine: optionalPositiveInt,
|
|
90
105
|
endLine: optionalPositiveInt,
|
|
91
|
-
maxLines: optionalPositiveInt
|
|
106
|
+
maxLines: optionalPositiveInt,
|
|
107
|
+
maxChars: optionalPositiveInt.describe("Hard character limit on sourceText; truncates if exceeded"),
|
|
108
|
+
outputFile: optionalNonEmptyString.describe("Write source to this file path and return metadata-only response")
|
|
92
109
|
};
|
|
93
110
|
const getClassSourceSchema = z
|
|
94
111
|
.object(getClassSourceShape)
|
|
@@ -120,7 +137,11 @@ const getClassMembersShape = {
|
|
|
120
137
|
includeSynthetic: z.boolean().optional().describe("default false"),
|
|
121
138
|
includeInherited: z.boolean().optional().describe("default false"),
|
|
122
139
|
memberPattern: optionalNonEmptyString,
|
|
123
|
-
maxMembers: optionalPositiveInt.describe("default 500, max 5000")
|
|
140
|
+
maxMembers: optionalPositiveInt.describe("default 500, max 5000"),
|
|
141
|
+
projectPath: optionalNonEmptyString,
|
|
142
|
+
scope: artifactScopeSchema.optional().describe("vanilla | merged | loader"),
|
|
143
|
+
preferProjectVersion: z.boolean().optional().describe("When true, detect MC version from gradle.properties and override version"),
|
|
144
|
+
strictVersion: z.boolean().optional().describe("When true, reject version-approximated results instead of returning them. Default false.")
|
|
124
145
|
};
|
|
125
146
|
const getClassMembersSchema = z
|
|
126
147
|
.object(getClassMembersShape)
|
|
@@ -142,6 +163,7 @@ const searchClassSourceShape = {
|
|
|
142
163
|
snippetLines: optionalPositiveInt.describe("default 8, clamp 1..80"),
|
|
143
164
|
includeDefinition: z.boolean().optional().describe("default false"),
|
|
144
165
|
includeOneHop: z.boolean().optional().describe("default false"),
|
|
166
|
+
queryMode: z.enum(["auto", "token", "literal"]).optional().describe("auto (default): FTS5 with literal fallback for separator queries; token: FTS5 only; literal: substring scan only"),
|
|
145
167
|
limit: optionalPositiveInt.describe("default 20"),
|
|
146
168
|
cursor: optionalNonEmptyString
|
|
147
169
|
};
|
|
@@ -187,7 +209,14 @@ const findMappingShape = {
|
|
|
187
209
|
descriptor: optionalNonEmptyString,
|
|
188
210
|
sourceMapping: sourceMappingSchema.describe("official | mojang | intermediary | yarn"),
|
|
189
211
|
targetMapping: sourceMappingSchema.describe("official | mojang | intermediary | yarn"),
|
|
190
|
-
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first")
|
|
212
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
213
|
+
disambiguation: z
|
|
214
|
+
.object({
|
|
215
|
+
ownerHint: optionalNonEmptyString,
|
|
216
|
+
descriptorHint: optionalNonEmptyString
|
|
217
|
+
})
|
|
218
|
+
.partial()
|
|
219
|
+
.optional()
|
|
191
220
|
};
|
|
192
221
|
const findMappingSchema = z.object(findMappingShape).superRefine((value, ctx) => {
|
|
193
222
|
if (value.kind === "class") {
|
|
@@ -390,9 +419,12 @@ const checkSymbolExistsShape = {
|
|
|
390
419
|
kind: workspaceSymbolKindSchema.describe("class | field | method"),
|
|
391
420
|
owner: optionalNonEmptyString,
|
|
392
421
|
name: nonEmptyString,
|
|
393
|
-
descriptor: optionalNonEmptyString.describe("required for kind=method"),
|
|
422
|
+
descriptor: optionalNonEmptyString.describe("required for kind=method unless signatureMode=name-only"),
|
|
394
423
|
sourceMapping: sourceMappingSchema.describe("official | mojang | intermediary | yarn"),
|
|
395
|
-
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first")
|
|
424
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
425
|
+
nameMode: classNameModeSchema.optional().describe("fqcn | auto (default fqcn)"),
|
|
426
|
+
signatureMode: z.enum(["exact", "name-only"]).optional()
|
|
427
|
+
.describe("exact (default): require descriptor for methods; name-only: match by owner+name only")
|
|
396
428
|
};
|
|
397
429
|
const checkSymbolExistsSchema = z.object(checkSymbolExistsShape).superRefine((value, ctx) => {
|
|
398
430
|
if (value.kind === "class") {
|
|
@@ -410,7 +442,7 @@ const checkSymbolExistsSchema = z.object(checkSymbolExistsShape).superRefine((va
|
|
|
410
442
|
path: ["descriptor"]
|
|
411
443
|
});
|
|
412
444
|
}
|
|
413
|
-
if (!value.name.includes(".")) {
|
|
445
|
+
if (value.nameMode !== "auto" && !value.name.includes(".")) {
|
|
414
446
|
ctx.addIssue({
|
|
415
447
|
code: z.ZodIssueCode.custom,
|
|
416
448
|
message: "name must be fully-qualified class name when kind=class.",
|
|
@@ -443,10 +475,10 @@ const checkSymbolExistsSchema = z.object(checkSymbolExistsShape).superRefine((va
|
|
|
443
475
|
}
|
|
444
476
|
return;
|
|
445
477
|
}
|
|
446
|
-
if (!value.descriptor) {
|
|
478
|
+
if (!value.descriptor && value.signatureMode !== "name-only") {
|
|
447
479
|
ctx.addIssue({
|
|
448
480
|
code: z.ZodIssueCode.custom,
|
|
449
|
-
message: "descriptor is required when kind=method.",
|
|
481
|
+
message: "descriptor is required when kind=method (use signatureMode='name-only' to match by name only).",
|
|
450
482
|
path: ["descriptor"]
|
|
451
483
|
});
|
|
452
484
|
}
|
|
@@ -479,12 +511,44 @@ const indexArtifactShape = {
|
|
|
479
511
|
};
|
|
480
512
|
const indexArtifactSchema = z.object(indexArtifactShape);
|
|
481
513
|
const validateMixinShape = {
|
|
482
|
-
source:
|
|
514
|
+
source: optionalNonEmptyString.describe("Mixin Java source text (mutually exclusive with sourcePath/sourcePaths/mixinConfigPath)"),
|
|
515
|
+
sourcePath: optionalNonEmptyString.describe("Path to Mixin .java file (alternative to source/sourcePaths/mixinConfigPath)"),
|
|
516
|
+
sourcePaths: z.array(z.string().min(1)).optional().describe("Array of Mixin .java file paths for batch validation"),
|
|
517
|
+
mixinConfigPath: z.union([nonEmptyString, z.array(nonEmptyString).min(1)]).optional().describe("Path (or array of paths) to mixin config JSON (e.g. modid.mixins.json); auto-discovers and batch-validates all listed classes"),
|
|
518
|
+
sourceRoot: optionalNonEmptyString.describe("Source root relative to projectPath (default 'src/main/java')"),
|
|
519
|
+
sourceRoots: z.array(z.string().min(1)).optional()
|
|
520
|
+
.describe("Array of source roots for multi-module projects (e.g. ['common/src/main/java', 'neoforge/src/main/java'])"),
|
|
483
521
|
version: nonEmptyString.describe("Minecraft version"),
|
|
484
522
|
mapping: sourceMappingSchema.optional().describe("official | mojang | intermediary | yarn"),
|
|
485
|
-
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first")
|
|
523
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
524
|
+
scope: artifactScopeSchema.optional().describe("vanilla | merged | loader"),
|
|
525
|
+
projectPath: optionalNonEmptyString.describe("Optional workspace root path for Loom cache-assisted source resolution"),
|
|
526
|
+
preferProjectVersion: z.boolean().optional().describe("When true, detect MC version from gradle.properties and override version"),
|
|
527
|
+
minSeverity: z.enum(["error", "warning", "all"]).optional()
|
|
528
|
+
.describe("'error'=errors only, 'warning'=errors+warnings, 'all'=everything (default 'all')"),
|
|
529
|
+
hideUncertain: z.boolean().optional()
|
|
530
|
+
.describe("Omit issues with confidence='uncertain' (default false)"),
|
|
531
|
+
explain: z.boolean().optional()
|
|
532
|
+
.describe("When true, enrich each issue with explanation and suggestedCall for agent recovery (default false)"),
|
|
533
|
+
warningMode: z.enum(["full", "aggregated"]).optional()
|
|
534
|
+
.describe("'full'=all warnings (default), 'aggregated'=group warnings by category with counts and samples"),
|
|
535
|
+
preferProjectMapping: z.boolean().optional()
|
|
536
|
+
.describe("When true, auto-detect mapping from project config even if mapping is explicitly provided"),
|
|
537
|
+
reportMode: z.enum(["compact", "full"]).optional()
|
|
538
|
+
.describe("'compact' omits resolvedMembers/structuredWarnings/toolHealth details, 'full'=everything (default)"),
|
|
539
|
+
warningCategoryFilter: z.array(z.enum(["mapping", "configuration", "validation", "resolution", "parse"])).optional()
|
|
540
|
+
.describe("Only include warnings/issues matching these categories (default: all)"),
|
|
541
|
+
treatInfoAsWarning: z.boolean().optional()
|
|
542
|
+
.describe("When false, suppress info-severity structured warnings from output (default true)")
|
|
486
543
|
};
|
|
487
|
-
const validateMixinSchema = z.object(validateMixinShape)
|
|
544
|
+
const validateMixinSchema = z.object(validateMixinShape).refine((d) => {
|
|
545
|
+
const hasSource = d.source != null;
|
|
546
|
+
const hasSourcePath = d.sourcePath != null;
|
|
547
|
+
const hasSourcePaths = d.sourcePaths != null && d.sourcePaths.length > 0;
|
|
548
|
+
const hasMixinConfig = d.mixinConfigPath != null && (typeof d.mixinConfigPath === "string" || (Array.isArray(d.mixinConfigPath) && d.mixinConfigPath.length > 0));
|
|
549
|
+
// Exactly one of the four must be provided
|
|
550
|
+
return [hasSource, hasSourcePath, hasSourcePaths, hasMixinConfig].filter(Boolean).length === 1;
|
|
551
|
+
}, { message: "Exactly one of 'source', 'sourcePath', 'sourcePaths', or 'mixinConfigPath' must be provided." });
|
|
488
552
|
const validateAccessWidenerShape = {
|
|
489
553
|
content: nonEmptyString.describe("Access Widener file content"),
|
|
490
554
|
version: nonEmptyString.describe("Minecraft version"),
|
|
@@ -519,7 +583,10 @@ const decompileModJarShape = {
|
|
|
519
583
|
const decompileModJarSchema = z.object(decompileModJarShape);
|
|
520
584
|
const getModClassSourceShape = {
|
|
521
585
|
jarPath: nonEmptyString.describe("Local path to the mod JAR file"),
|
|
522
|
-
className: nonEmptyString.describe("Fully-qualified class name (e.g. com.example.MyMixin)")
|
|
586
|
+
className: nonEmptyString.describe("Fully-qualified class name (e.g. com.example.MyMixin)"),
|
|
587
|
+
maxLines: optionalPositiveInt.describe("Max lines to return"),
|
|
588
|
+
maxChars: optionalPositiveInt.describe("Hard character limit; truncates if exceeded"),
|
|
589
|
+
outputFile: optionalNonEmptyString.describe("Write full source to file, return placeholder in content")
|
|
523
590
|
};
|
|
524
591
|
const getModClassSourceSchema = z.object(getModClassSourceShape);
|
|
525
592
|
const MOD_SEARCH_TYPES = ["class", "method", "field", "content", "all"];
|
|
@@ -565,7 +632,18 @@ const nbtLimits = {
|
|
|
565
632
|
maxInflatedBytes: config.maxNbtInflatedBytes,
|
|
566
633
|
maxResponseBytes: config.maxNbtResponseBytes
|
|
567
634
|
};
|
|
568
|
-
|
|
635
|
+
let sourceServiceInstance;
|
|
636
|
+
function getSourceService() {
|
|
637
|
+
sourceServiceInstance ??= new SourceService(config);
|
|
638
|
+
return sourceServiceInstance;
|
|
639
|
+
}
|
|
640
|
+
const sourceService = new Proxy({}, {
|
|
641
|
+
get(_target, property, _receiver) {
|
|
642
|
+
const service = getSourceService();
|
|
643
|
+
const value = Reflect.get(service, property, service);
|
|
644
|
+
return typeof value === "function" ? value.bind(service) : value;
|
|
645
|
+
}
|
|
646
|
+
});
|
|
569
647
|
registerResources(server, sourceService);
|
|
570
648
|
let processHandlersAttached = false;
|
|
571
649
|
let serverStarted = false;
|
|
@@ -634,6 +712,20 @@ function toHints(details) {
|
|
|
634
712
|
}
|
|
635
713
|
return hints;
|
|
636
714
|
}
|
|
715
|
+
function toSuggestedCall(details) {
|
|
716
|
+
if (typeof details !== "object" || details == null) {
|
|
717
|
+
return undefined;
|
|
718
|
+
}
|
|
719
|
+
const maybe = details.suggestedCall;
|
|
720
|
+
if (typeof maybe !== "object" || maybe == null) {
|
|
721
|
+
return undefined;
|
|
722
|
+
}
|
|
723
|
+
const call = maybe;
|
|
724
|
+
if (typeof call.tool !== "string" || typeof call.params !== "object" || call.params == null) {
|
|
725
|
+
return undefined;
|
|
726
|
+
}
|
|
727
|
+
return { tool: call.tool, params: call.params };
|
|
728
|
+
}
|
|
637
729
|
function statusForErrorCode(code) {
|
|
638
730
|
if (code === ERROR_CODES.INVALID_INPUT ||
|
|
639
731
|
code === ERROR_CODES.COORDINATE_PARSE_FAILED ||
|
|
@@ -723,6 +815,7 @@ function mapErrorToProblem(caughtError, requestId) {
|
|
|
723
815
|
};
|
|
724
816
|
}
|
|
725
817
|
if (isAppError(caughtError)) {
|
|
818
|
+
const suggestedCall = toSuggestedCall(caughtError.details);
|
|
726
819
|
return {
|
|
727
820
|
type: `https://minecraft-modding-mcp.dev/problems/${caughtError.code.toLowerCase()}`,
|
|
728
821
|
title: "Tool execution error",
|
|
@@ -731,7 +824,8 @@ function mapErrorToProblem(caughtError, requestId) {
|
|
|
731
824
|
code: caughtError.code,
|
|
732
825
|
instance: requestId,
|
|
733
826
|
fieldErrors: extractFieldErrorsFromDetails(caughtError.details),
|
|
734
|
-
hints: toHints(caughtError.details)
|
|
827
|
+
hints: toHints(caughtError.details),
|
|
828
|
+
...(suggestedCall ? { suggestedCall } : {})
|
|
735
829
|
};
|
|
736
830
|
}
|
|
737
831
|
return {
|
|
@@ -830,18 +924,40 @@ server.tool("resolve-artifact", "Resolve source artifact from version, jar path,
|
|
|
830
924
|
},
|
|
831
925
|
mapping: input.mapping,
|
|
832
926
|
sourcePriority: input.sourcePriority,
|
|
833
|
-
allowDecompile: input.allowDecompile
|
|
927
|
+
allowDecompile: input.allowDecompile,
|
|
928
|
+
projectPath: input.projectPath,
|
|
929
|
+
scope: input.scope,
|
|
930
|
+
preferProjectVersion: input.preferProjectVersion,
|
|
931
|
+
strictVersion: input.strictVersion
|
|
834
932
|
})));
|
|
835
|
-
|
|
933
|
+
const findClassShape = {
|
|
934
|
+
className: nonEmptyString.describe("Simple name (e.g. Blocks) or fully-qualified name (e.g. net.minecraft.world.level.block.Blocks)"),
|
|
935
|
+
artifactId: nonEmptyString,
|
|
936
|
+
limit: optionalPositiveInt.describe("default 20, max 200")
|
|
937
|
+
};
|
|
938
|
+
const findClassSchema = z.object(findClassShape);
|
|
939
|
+
server.tool("find-class", "Resolve a simple or qualified class name to fully-qualified class names within an artifact. Use this before get-class-source when you only have a simple name.", findClassShape, { readOnlyHint: true }, async (args) => runTool("find-class", args, findClassSchema, async (input) => sourceService.findClass({
|
|
836
940
|
className: input.className,
|
|
837
941
|
artifactId: input.artifactId,
|
|
942
|
+
limit: input.limit
|
|
943
|
+
})));
|
|
944
|
+
server.tool("get-class-source", "Get Java source for a class by artifactId or by resolving target (version/jar/coordinate). Default mode=metadata returns symbol outline only; use mode=snippet for bounded excerpts or mode=full for entire source.", getClassSourceShape, { readOnlyHint: true }, async (args) => runTool("get-class-source", args, getClassSourceSchema, async (input) => sourceService.getClassSource({
|
|
945
|
+
className: input.className,
|
|
946
|
+
mode: input.mode,
|
|
947
|
+
artifactId: input.artifactId,
|
|
838
948
|
target: buildTarget(input.targetKind, input.targetValue),
|
|
839
949
|
mapping: input.mapping,
|
|
840
950
|
sourcePriority: input.sourcePriority,
|
|
841
951
|
allowDecompile: input.allowDecompile,
|
|
952
|
+
projectPath: input.projectPath,
|
|
953
|
+
scope: input.scope,
|
|
954
|
+
preferProjectVersion: input.preferProjectVersion,
|
|
955
|
+
strictVersion: input.strictVersion,
|
|
842
956
|
startLine: input.startLine,
|
|
843
957
|
endLine: input.endLine,
|
|
844
|
-
maxLines: input.maxLines
|
|
958
|
+
maxLines: input.maxLines,
|
|
959
|
+
maxChars: input.maxChars,
|
|
960
|
+
outputFile: input.outputFile
|
|
845
961
|
})));
|
|
846
962
|
server.tool("get-class-members", "Get fields/methods/constructors for one class from binary bytecode by artifactId or by resolving target (version/jar/coordinate).", getClassMembersShape, { readOnlyHint: true }, async (args) => runTool("get-class-members", args, getClassMembersSchema, async (input) => sourceService.getClassMembers({
|
|
847
963
|
className: input.className,
|
|
@@ -854,7 +970,11 @@ server.tool("get-class-members", "Get fields/methods/constructors for one class
|
|
|
854
970
|
includeSynthetic: input.includeSynthetic,
|
|
855
971
|
includeInherited: input.includeInherited,
|
|
856
972
|
memberPattern: input.memberPattern,
|
|
857
|
-
maxMembers: input.maxMembers
|
|
973
|
+
maxMembers: input.maxMembers,
|
|
974
|
+
projectPath: input.projectPath,
|
|
975
|
+
scope: input.scope,
|
|
976
|
+
preferProjectVersion: input.preferProjectVersion,
|
|
977
|
+
strictVersion: input.strictVersion
|
|
858
978
|
})));
|
|
859
979
|
server.tool("search-class-source", "Search indexed class source files for one artifact with symbol/text/path intent and optional one-hop relation expansion.", searchClassSourceShape, { readOnlyHint: true }, async (args) => runTool("search-class-source", args, searchClassSourceSchema, async (input) => {
|
|
860
980
|
const scope = input.packagePrefix || input.fileGlob || input.symbolKind
|
|
@@ -880,6 +1000,7 @@ server.tool("search-class-source", "Search indexed class source files for one ar
|
|
|
880
1000
|
match: input.match,
|
|
881
1001
|
scope: scope,
|
|
882
1002
|
include,
|
|
1003
|
+
queryMode: input.queryMode,
|
|
883
1004
|
limit: input.limit,
|
|
884
1005
|
cursor: input.cursor
|
|
885
1006
|
});
|
|
@@ -916,7 +1037,8 @@ server.tool("find-mapping", "Find symbol mapping candidates between namespaces u
|
|
|
916
1037
|
descriptor: input.descriptor,
|
|
917
1038
|
sourceMapping: input.sourceMapping,
|
|
918
1039
|
targetMapping: input.targetMapping,
|
|
919
|
-
sourcePriority: input.sourcePriority
|
|
1040
|
+
sourcePriority: input.sourcePriority,
|
|
1041
|
+
disambiguation: input.disambiguation
|
|
920
1042
|
})));
|
|
921
1043
|
server.tool("resolve-method-mapping-exact", "Resolve one method mapping exactly by owner+name+descriptor between namespaces and report resolved/not_found/ambiguous.", resolveMethodMappingExactShape, { readOnlyHint: true }, async (args) => runTool("resolve-method-mapping-exact", args, resolveMethodMappingExactSchema, async (input) => sourceService.resolveMethodMappingExact({
|
|
922
1044
|
version: input.version,
|
|
@@ -952,7 +1074,9 @@ server.tool("check-symbol-exists", "Check whether a class/field/method symbol ex
|
|
|
952
1074
|
name: input.name,
|
|
953
1075
|
descriptor: input.descriptor,
|
|
954
1076
|
sourceMapping: input.sourceMapping,
|
|
955
|
-
sourcePriority: input.sourcePriority
|
|
1077
|
+
sourcePriority: input.sourcePriority,
|
|
1078
|
+
nameMode: input.nameMode,
|
|
1079
|
+
signatureMode: input.signatureMode
|
|
956
1080
|
})));
|
|
957
1081
|
server.tool("nbt-to-json", "Decode Java Edition NBT binary payload (base64) into typed JSON.", nbtToJsonShape, { readOnlyHint: true }, async (args) => runTool("nbt-to-json", args, nbtToJsonSchema, async (input) => Promise.resolve(nbtBase64ToTypedJson({
|
|
958
1082
|
nbtBase64: input.nbtBase64,
|
|
@@ -973,9 +1097,25 @@ server.tool("index-artifact", "Rebuild indexed files/symbols metadata for an exi
|
|
|
973
1097
|
server.tool("get-runtime-metrics", "Get runtime service counters and latency snapshots for cache/search/index diagnostics.", { readOnlyHint: true }, async (args) => runTool("get-runtime-metrics", args, emptySchema, async () => Promise.resolve(sourceService.getRuntimeMetrics())));
|
|
974
1098
|
server.tool("validate-mixin", "Validate Mixin source against Minecraft bytecode signatures for a given version.", validateMixinShape, { readOnlyHint: true }, async (args) => runTool("validate-mixin", args, validateMixinSchema, async (input) => sourceService.validateMixin({
|
|
975
1099
|
source: input.source,
|
|
1100
|
+
sourcePath: input.sourcePath,
|
|
1101
|
+
sourcePaths: input.sourcePaths,
|
|
1102
|
+
mixinConfigPath: input.mixinConfigPath,
|
|
1103
|
+
sourceRoot: input.sourceRoot,
|
|
1104
|
+
sourceRoots: input.sourceRoots,
|
|
976
1105
|
version: input.version,
|
|
977
1106
|
mapping: input.mapping,
|
|
978
|
-
sourcePriority: input.sourcePriority
|
|
1107
|
+
sourcePriority: input.sourcePriority,
|
|
1108
|
+
scope: input.scope,
|
|
1109
|
+
projectPath: input.projectPath,
|
|
1110
|
+
preferProjectVersion: input.preferProjectVersion,
|
|
1111
|
+
minSeverity: input.minSeverity,
|
|
1112
|
+
hideUncertain: input.hideUncertain,
|
|
1113
|
+
explain: input.explain,
|
|
1114
|
+
warningMode: input.warningMode,
|
|
1115
|
+
preferProjectMapping: input.preferProjectMapping,
|
|
1116
|
+
reportMode: input.reportMode,
|
|
1117
|
+
warningCategoryFilter: input.warningCategoryFilter,
|
|
1118
|
+
treatInfoAsWarning: input.treatInfoAsWarning
|
|
979
1119
|
})));
|
|
980
1120
|
server.tool("validate-access-widener", "Validate Access Widener file entries against Minecraft bytecode signatures for a given version.", validateAccessWidenerShape, { readOnlyHint: true }, async (args) => runTool("validate-access-widener", args, validateAccessWidenerSchema, async (input) => sourceService.validateAccessWidener({
|
|
981
1121
|
content: input.content,
|
|
@@ -1006,7 +1146,10 @@ server.tool("decompile-mod-jar", "Decompile a Minecraft mod JAR using Vineflower
|
|
|
1006
1146
|
})));
|
|
1007
1147
|
server.tool("get-mod-class-source", "Get decompiled source code for a specific class in a mod JAR. The mod JAR will be decompiled if not already cached.", getModClassSourceShape, { readOnlyHint: true }, async (args) => runTool("get-mod-class-source", args, getModClassSourceSchema, async (input) => sourceService.getModClassSource({
|
|
1008
1148
|
jarPath: input.jarPath,
|
|
1009
|
-
className: input.className
|
|
1149
|
+
className: input.className,
|
|
1150
|
+
maxLines: input.maxLines,
|
|
1151
|
+
maxChars: input.maxChars,
|
|
1152
|
+
outputFile: input.outputFile
|
|
1010
1153
|
})));
|
|
1011
1154
|
server.tool("search-mod-source", "Search through decompiled mod JAR source code by class name, method, field, or content pattern. The mod JAR will be decompiled automatically if not already cached.", searchModSourceShape, { readOnlyHint: true }, async (args) => runTool("search-mod-source", args, searchModSourceSchema, async (input) => sourceService.searchModSource({
|
|
1012
1155
|
jarPath: input.jarPath,
|
|
@@ -1039,6 +1182,7 @@ export async function startServer() {
|
|
|
1039
1182
|
// In stdio mode, explicitly resume stdin so JSON-RPC lines are consumed.
|
|
1040
1183
|
process.stdin.resume();
|
|
1041
1184
|
serverStarted = true;
|
|
1185
|
+
setImmediate(getSourceService); // Eagerly init SourceService during MCP handshake
|
|
1042
1186
|
}
|
|
1043
1187
|
export { server, sourceService, config, SERVER_VERSION };
|
|
1044
1188
|
//# sourceMappingURL=index.js.map
|
|
@@ -48,6 +48,7 @@ export type SymbolResolutionOutput = {
|
|
|
48
48
|
candidates: Array<SymbolReference & Pick<MappingLookupCandidate, "matchKind" | "confidence">>;
|
|
49
49
|
warnings: string[];
|
|
50
50
|
provenance?: MappingLookupProvenance;
|
|
51
|
+
ambiguityReasons?: string[];
|
|
51
52
|
};
|
|
52
53
|
export type FindMappingInput = {
|
|
53
54
|
version: string;
|
|
@@ -58,6 +59,10 @@ export type FindMappingInput = {
|
|
|
58
59
|
sourceMapping: SourceMapping;
|
|
59
60
|
targetMapping: SourceMapping;
|
|
60
61
|
sourcePriority?: MappingSourcePriority;
|
|
62
|
+
disambiguation?: {
|
|
63
|
+
ownerHint?: string;
|
|
64
|
+
descriptorHint?: string;
|
|
65
|
+
};
|
|
61
66
|
};
|
|
62
67
|
export type FindMappingOutput = SymbolResolutionOutput;
|
|
63
68
|
export type EnsureMappingAvailableInput = {
|
|
@@ -112,6 +117,7 @@ export type ClassApiMatrixOutput = {
|
|
|
112
117
|
classIdentity: Partial<Record<SourceMapping, string>>;
|
|
113
118
|
rows: ClassApiMatrixRow[];
|
|
114
119
|
warnings: string[];
|
|
120
|
+
ambiguousRowCount?: number;
|
|
115
121
|
};
|
|
116
122
|
export type SymbolExistenceInput = {
|
|
117
123
|
version: string;
|
|
@@ -121,6 +127,8 @@ export type SymbolExistenceInput = {
|
|
|
121
127
|
descriptor?: string;
|
|
122
128
|
sourceMapping: SourceMapping;
|
|
123
129
|
sourcePriority?: MappingSourcePriority;
|
|
130
|
+
nameMode?: "fqcn" | "auto";
|
|
131
|
+
signatureMode?: "exact" | "name-only";
|
|
124
132
|
};
|
|
125
133
|
export type SymbolExistenceOutput = SymbolResolutionOutput;
|
|
126
134
|
export declare class MappingService {
|
|
@@ -138,6 +146,20 @@ export declare class MappingService {
|
|
|
138
146
|
private mapRecordBetweenMappings;
|
|
139
147
|
private mapCandidatesAlongPath;
|
|
140
148
|
private provenanceForPath;
|
|
149
|
+
/**
|
|
150
|
+
* Probe the mapping graph health for a given version.
|
|
151
|
+
* Returns availability of mojang mappings, tiny mappings, and member remap paths.
|
|
152
|
+
*/
|
|
153
|
+
checkMappingHealth(input: {
|
|
154
|
+
version: string;
|
|
155
|
+
requestedMapping: SourceMapping;
|
|
156
|
+
sourcePriority?: MappingSourcePriority;
|
|
157
|
+
}): Promise<{
|
|
158
|
+
mojangMappingsAvailable: boolean;
|
|
159
|
+
tinyMappingsAvailable: boolean;
|
|
160
|
+
memberRemapAvailable: boolean;
|
|
161
|
+
degradations: string[];
|
|
162
|
+
}>;
|
|
141
163
|
private loadGraph;
|
|
142
164
|
private buildGraph;
|
|
143
165
|
private mergePairs;
|