@adhisang/minecraft-modding-mcp 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -1
- package/README.md +87 -46
- package/dist/decompiler/vineflower.js +2 -2
- package/dist/index.js +150 -175
- package/dist/mapping-pipeline-service.d.ts +1 -1
- package/dist/mapping-pipeline-service.js +5 -5
- package/dist/mapping-service.d.ts +3 -4
- package/dist/mapping-service.js +40 -46
- package/dist/mcp-helpers.d.ts +10 -2
- package/dist/mcp-helpers.js +59 -5
- package/dist/minecraft-explorer-service.d.ts +1 -1
- package/dist/minecraft-explorer-service.js +1 -1
- package/dist/mixin-validator.js +5 -5
- package/dist/mojang-tiny-mapping-service.js +26 -26
- package/dist/resources.js +7 -7
- package/dist/search-hit-accumulator.d.ts +0 -3
- package/dist/search-hit-accumulator.js +4 -4
- package/dist/source-resolver.d.ts +1 -0
- package/dist/source-resolver.js +94 -2
- package/dist/source-service.d.ts +34 -43
- package/dist/source-service.js +597 -670
- package/dist/storage/files-repo.d.ts +9 -0
- package/dist/storage/files-repo.js +42 -0
- package/dist/storage/migrations.d.ts +1 -1
- package/dist/storage/migrations.js +6 -2
- package/dist/storage/schema.d.ts +1 -0
- package/dist/storage/schema.js +7 -0
- package/dist/tool-input.d.ts +6 -0
- package/dist/tool-input.js +64 -0
- package/dist/types.d.ts +1 -1
- package/package.json +4 -1
package/dist/source-resolver.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readdirSync } from "node:fs";
|
|
2
2
|
import { basename, dirname, join, resolve as resolvePath } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
3
4
|
import { createError, ERROR_CODES } from "./errors.js";
|
|
4
5
|
import { buildRemoteBinaryUrls, buildRemoteSourceUrls, hasExistingJar, parseCoordinate, normalizedCoordinateValue } from "./maven-resolver.js";
|
|
5
6
|
import { defaultDownloadPath, downloadToCache } from "./repo-downloader.js";
|
|
@@ -23,6 +24,16 @@ function resolveExactJarSourceCandidate(inputJarPath) {
|
|
|
23
24
|
const base = jarName.endsWith(".jar") ? jarName.slice(0, -4) : jarName;
|
|
24
25
|
return join(directory, `${base}-sources.jar`);
|
|
25
26
|
}
|
|
27
|
+
function resolveSiblingBinaryJarCandidate(inputJarPath) {
|
|
28
|
+
const directory = dirname(inputJarPath);
|
|
29
|
+
const jarName = basename(inputJarPath);
|
|
30
|
+
if (!jarName.endsWith("-sources.jar")) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const binaryName = `${jarName.slice(0, -"-sources.jar".length)}.jar`;
|
|
34
|
+
const candidate = join(directory, binaryName);
|
|
35
|
+
return hasExistingJar(candidate) ? candidate : undefined;
|
|
36
|
+
}
|
|
26
37
|
function listAdjacentJarSourceCandidates(inputJarPath) {
|
|
27
38
|
const directory = dirname(inputJarPath);
|
|
28
39
|
const exact = resolveExactJarSourceCandidate(inputJarPath);
|
|
@@ -59,6 +70,68 @@ function resolveLocalCoordinateCandidates(localM2Path, coordinate) {
|
|
|
59
70
|
}
|
|
60
71
|
return [...existing];
|
|
61
72
|
}
|
|
73
|
+
function resolveLocalCoordinateBinaryCandidate(localM2Path, coordinate) {
|
|
74
|
+
const parsed = parseCoordinate(coordinate);
|
|
75
|
+
const groupPath = parsed.groupId.replace(/\./g, "/");
|
|
76
|
+
const baseDir = resolvePath(localM2Path, groupPath, parsed.artifactId, parsed.version);
|
|
77
|
+
const base = `${parsed.artifactId}-${parsed.version}`;
|
|
78
|
+
const classifierSuffix = parsed.classifier ? `-${parsed.classifier}` : "";
|
|
79
|
+
const candidates = [
|
|
80
|
+
resolvePath(baseDir, `${base}${classifierSuffix}.jar`),
|
|
81
|
+
...(classifierSuffix ? [resolvePath(baseDir, `${base}.jar`)] : [])
|
|
82
|
+
];
|
|
83
|
+
return candidates.find((candidate) => hasExistingJar(candidate));
|
|
84
|
+
}
|
|
85
|
+
function resolveGradleUserHome() {
|
|
86
|
+
const configured = process.env.GRADLE_USER_HOME?.trim();
|
|
87
|
+
if (configured) {
|
|
88
|
+
return configured;
|
|
89
|
+
}
|
|
90
|
+
return resolvePath(homedir(), ".gradle");
|
|
91
|
+
}
|
|
92
|
+
function resolveGradleCacheCoordinateCandidate(coordinate) {
|
|
93
|
+
const parsed = parseCoordinate(coordinate);
|
|
94
|
+
const baseDir = resolvePath(resolveGradleUserHome(), "caches", "modules-2", "files-2.1", parsed.groupId, parsed.artifactId, parsed.version);
|
|
95
|
+
const base = `${parsed.artifactId}-${parsed.version}`;
|
|
96
|
+
const classifierSuffix = parsed.classifier ? `-${parsed.classifier}` : "";
|
|
97
|
+
const preferredSourceNames = [
|
|
98
|
+
`${base}${classifierSuffix}-sources.jar`,
|
|
99
|
+
...(classifierSuffix ? [`${base}-sources.jar`] : [])
|
|
100
|
+
];
|
|
101
|
+
const preferredBinaryNames = [
|
|
102
|
+
`${base}${classifierSuffix}.jar`,
|
|
103
|
+
...(classifierSuffix ? [`${base}.jar`] : [])
|
|
104
|
+
];
|
|
105
|
+
let discoveredFiles = [];
|
|
106
|
+
try {
|
|
107
|
+
const hashes = readdirSync(baseDir);
|
|
108
|
+
for (const hashDir of hashes) {
|
|
109
|
+
const fullDir = join(baseDir, hashDir);
|
|
110
|
+
for (const entry of readdirSync(fullDir)) {
|
|
111
|
+
discoveredFiles.push(join(fullDir, entry));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
discoveredFiles = discoveredFiles.filter((entry) => hasExistingJar(entry)).sort((left, right) => left.localeCompare(right));
|
|
119
|
+
const pickFirst = (candidates) => {
|
|
120
|
+
for (const fileName of candidates) {
|
|
121
|
+
const match = discoveredFiles.find((entry) => basename(entry) === fileName);
|
|
122
|
+
if (match) {
|
|
123
|
+
return match;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return undefined;
|
|
127
|
+
};
|
|
128
|
+
const sourceJarPath = pickFirst(preferredSourceNames);
|
|
129
|
+
const binaryJarPath = pickFirst(preferredBinaryNames);
|
|
130
|
+
if (!sourceJarPath && !binaryJarPath) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
return { sourceJarPath, binaryJarPath };
|
|
134
|
+
}
|
|
62
135
|
function resolveRemoteBinaryCandidate(coordinate, repos) {
|
|
63
136
|
return buildRemoteBinaryUrls(repos, coordinate);
|
|
64
137
|
}
|
|
@@ -80,19 +153,23 @@ export async function resolveSourceTarget(input, options, explicitConfig) {
|
|
|
80
153
|
const exactSourceJarPath = resolveExactJarSourceCandidate(resolvedJarPath);
|
|
81
154
|
const adjacentSourceCandidates = listAdjacentJarSourceCandidates(resolvedJarPath);
|
|
82
155
|
const maybeAdjacentSourceCandidates = adjacentSourceCandidates.length > 0 ? adjacentSourceCandidates : undefined;
|
|
156
|
+
const preferBinaryOnly = options.preferBinaryOnly ?? false;
|
|
83
157
|
if (await hasJavaSources(resolvedJarPath)) {
|
|
158
|
+
const siblingBinaryJarPath = resolveSiblingBinaryJarCandidate(resolvedJarPath);
|
|
159
|
+
const binaryJarPath = siblingBinaryJarPath ??
|
|
160
|
+
(basename(resolvedJarPath).endsWith("-sources.jar") ? undefined : resolvedJarPath);
|
|
84
161
|
return {
|
|
85
162
|
artifactId: artifactIdForJar("jar", resolvedJarPath, binarySignature),
|
|
86
163
|
artifactSignature: binarySignature,
|
|
87
164
|
origin: "local-jar",
|
|
88
|
-
binaryJarPath
|
|
165
|
+
binaryJarPath,
|
|
89
166
|
sourceJarPath: resolvedJarPath,
|
|
90
167
|
adjacentSourceCandidates: maybeAdjacentSourceCandidates,
|
|
91
168
|
isDecompiled: false,
|
|
92
169
|
resolvedAt: resolvedAtNow()
|
|
93
170
|
};
|
|
94
171
|
}
|
|
95
|
-
if (await hasJavaSources(exactSourceJarPath)) {
|
|
172
|
+
if (!preferBinaryOnly && await hasJavaSources(exactSourceJarPath)) {
|
|
96
173
|
const sourceSignature = readStatsSignature(exactSourceJarPath);
|
|
97
174
|
return {
|
|
98
175
|
artifactId: artifactIdForJar("jar", exactSourceJarPath, sourceSignature),
|
|
@@ -142,12 +219,27 @@ export async function resolveSourceTarget(input, options, explicitConfig) {
|
|
|
142
219
|
artifactSignature: signature,
|
|
143
220
|
origin: "local-m2",
|
|
144
221
|
sourceJarPath: candidate,
|
|
222
|
+
binaryJarPath: resolveLocalCoordinateBinaryCandidate(explicitConfig.localM2Path, coordinate),
|
|
145
223
|
coordinate,
|
|
146
224
|
isDecompiled: false,
|
|
147
225
|
resolvedAt: resolvedAtNow()
|
|
148
226
|
};
|
|
149
227
|
}
|
|
150
228
|
}
|
|
229
|
+
const gradleCacheCandidate = resolveGradleCacheCoordinateCandidate(coordinate);
|
|
230
|
+
if (gradleCacheCandidate?.sourceJarPath && (await hasJavaSources(gradleCacheCandidate.sourceJarPath))) {
|
|
231
|
+
const signature = readStatsSignature(gradleCacheCandidate.sourceJarPath);
|
|
232
|
+
return {
|
|
233
|
+
artifactId: artifactIdForCoordinate(coordinate, "local-m2", signature),
|
|
234
|
+
artifactSignature: signature,
|
|
235
|
+
origin: "local-m2",
|
|
236
|
+
sourceJarPath: gradleCacheCandidate.sourceJarPath,
|
|
237
|
+
binaryJarPath: gradleCacheCandidate.binaryJarPath,
|
|
238
|
+
coordinate,
|
|
239
|
+
isDecompiled: false,
|
|
240
|
+
resolvedAt: resolvedAtNow()
|
|
241
|
+
};
|
|
242
|
+
}
|
|
151
243
|
const remoteSourceUrls = buildRemoteSourceUrls(repos, coordinate);
|
|
152
244
|
for (let index = 0; index < remoteSourceUrls.length; index++) {
|
|
153
245
|
const sourceUrl = remoteSourceUrls[index];
|
package/dist/source-service.d.ts
CHANGED
|
@@ -44,11 +44,6 @@ export type SearchScope = {
|
|
|
44
44
|
fileGlob?: string;
|
|
45
45
|
symbolKind?: SymbolKind;
|
|
46
46
|
};
|
|
47
|
-
export type SearchInclude = {
|
|
48
|
-
snippetLines?: number;
|
|
49
|
-
includeDefinition?: boolean;
|
|
50
|
-
includeOneHop?: boolean;
|
|
51
|
-
};
|
|
52
47
|
export type SearchResultSymbol = {
|
|
53
48
|
symbolKind: SymbolKind;
|
|
54
49
|
symbolName: string;
|
|
@@ -59,27 +54,9 @@ export type SearchSourceHit = {
|
|
|
59
54
|
filePath: string;
|
|
60
55
|
score: number;
|
|
61
56
|
matchedIn: "symbol" | "path" | "content";
|
|
62
|
-
startLine: number;
|
|
63
|
-
endLine: number;
|
|
64
|
-
snippet: string;
|
|
65
57
|
reasonCodes: string[];
|
|
66
58
|
symbol?: SearchResultSymbol;
|
|
67
59
|
};
|
|
68
|
-
export type SearchRelation = {
|
|
69
|
-
fromSymbol: {
|
|
70
|
-
symbolKind: SymbolKind;
|
|
71
|
-
symbolName: string;
|
|
72
|
-
filePath: string;
|
|
73
|
-
line: number;
|
|
74
|
-
};
|
|
75
|
-
toSymbol: {
|
|
76
|
-
symbolKind: SymbolKind;
|
|
77
|
-
symbolName: string;
|
|
78
|
-
filePath: string;
|
|
79
|
-
line: number;
|
|
80
|
-
};
|
|
81
|
-
relation: "calls" | "uses-type" | "imports";
|
|
82
|
-
};
|
|
83
60
|
export type QueryMode = "auto" | "token" | "literal";
|
|
84
61
|
export type SearchClassSourceInput = {
|
|
85
62
|
artifactId: string;
|
|
@@ -87,16 +64,13 @@ export type SearchClassSourceInput = {
|
|
|
87
64
|
intent?: SearchIntent;
|
|
88
65
|
match?: SearchMatch;
|
|
89
66
|
scope?: SearchScope;
|
|
90
|
-
include?: SearchInclude;
|
|
91
67
|
queryMode?: QueryMode;
|
|
92
68
|
limit?: number;
|
|
93
69
|
cursor?: string;
|
|
94
70
|
};
|
|
95
71
|
export type SearchClassSourceOutput = {
|
|
96
72
|
hits: SearchSourceHit[];
|
|
97
|
-
relations?: SearchRelation[];
|
|
98
73
|
nextCursor?: string;
|
|
99
|
-
totalApprox: number;
|
|
100
74
|
mappingApplied: SourceMapping;
|
|
101
75
|
};
|
|
102
76
|
export type GetArtifactFileInput = {
|
|
@@ -356,11 +330,19 @@ export type IndexArtifactOutput = {
|
|
|
356
330
|
mappingApplied: SourceMapping;
|
|
357
331
|
};
|
|
358
332
|
export type ValidateMixinInput = {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
333
|
+
input: {
|
|
334
|
+
mode: "inline";
|
|
335
|
+
source: string;
|
|
336
|
+
} | {
|
|
337
|
+
mode: "path";
|
|
338
|
+
path: string;
|
|
339
|
+
} | {
|
|
340
|
+
mode: "paths";
|
|
341
|
+
paths: string[];
|
|
342
|
+
} | {
|
|
343
|
+
mode: "config";
|
|
344
|
+
configPaths: string[];
|
|
345
|
+
};
|
|
364
346
|
sourceRoots?: string[];
|
|
365
347
|
version: string;
|
|
366
348
|
mapping?: SourceMapping;
|
|
@@ -377,8 +359,14 @@ export type ValidateMixinInput = {
|
|
|
377
359
|
warningCategoryFilter?: ("mapping" | "configuration" | "validation" | "resolution" | "parse")[];
|
|
378
360
|
treatInfoAsWarning?: boolean;
|
|
379
361
|
};
|
|
362
|
+
export type ValidateMixinResultSource = {
|
|
363
|
+
kind: "inline" | "path" | "config";
|
|
364
|
+
label: string;
|
|
365
|
+
path?: string;
|
|
366
|
+
configPath?: string;
|
|
367
|
+
};
|
|
380
368
|
export type ValidateMixinBatchResult = {
|
|
381
|
-
|
|
369
|
+
source: ValidateMixinResultSource;
|
|
382
370
|
result?: MixinValidationResult;
|
|
383
371
|
error?: string;
|
|
384
372
|
};
|
|
@@ -389,23 +377,22 @@ export type ValidateMixinBatchIssueSummaryItem = {
|
|
|
389
377
|
count: number;
|
|
390
378
|
sampleTargets: string[];
|
|
391
379
|
};
|
|
392
|
-
export type
|
|
380
|
+
export type ValidateMixinOutput = {
|
|
381
|
+
mode: ValidateMixinInput["input"]["mode"];
|
|
393
382
|
results: ValidateMixinBatchResult[];
|
|
394
383
|
summary: {
|
|
395
384
|
total: number;
|
|
396
385
|
valid: number;
|
|
397
386
|
invalid: number;
|
|
398
|
-
/** @deprecated Use processingErrors instead */
|
|
399
|
-
errors: number;
|
|
400
387
|
processingErrors: number;
|
|
401
388
|
totalValidationErrors: number;
|
|
402
389
|
totalValidationWarnings: number;
|
|
403
|
-
confidenceScore?: number;
|
|
404
390
|
};
|
|
405
391
|
issueSummary?: ValidateMixinBatchIssueSummaryItem[];
|
|
406
392
|
toolHealth?: MappingHealthReport;
|
|
393
|
+
confidenceScore?: number;
|
|
394
|
+
warnings: string[];
|
|
407
395
|
};
|
|
408
|
-
export type ValidateMixinOutput = MixinValidationResult | ValidateMixinBatchOutput;
|
|
409
396
|
export type ValidateAccessWidenerInput = {
|
|
410
397
|
content: string;
|
|
411
398
|
version: string;
|
|
@@ -453,7 +440,11 @@ export declare class SourceService {
|
|
|
453
440
|
getClassSource(input: GetClassSourceInput): Promise<GetClassSourceOutput>;
|
|
454
441
|
getClassMembers(input: GetClassMembersInput): Promise<GetClassMembersOutput>;
|
|
455
442
|
validateMixin(input: ValidateMixinInput): Promise<ValidateMixinOutput>;
|
|
456
|
-
private
|
|
443
|
+
private validateMixinSingle;
|
|
444
|
+
private resolveMixinInputPath;
|
|
445
|
+
private resolveMixinConfigSources;
|
|
446
|
+
private validateMixinMany;
|
|
447
|
+
private buildValidateMixinOutput;
|
|
457
448
|
validateAccessWidener(input: ValidateAccessWidenerInput): Promise<ValidateAccessWidenerOutput>;
|
|
458
449
|
getRuntimeMetrics(): RuntimeMetricSnapshot;
|
|
459
450
|
indexArtifact(input: IndexArtifactInput): Promise<IndexArtifactOutput>;
|
|
@@ -468,13 +459,13 @@ export declare class SourceService {
|
|
|
468
459
|
private indexedCandidateLimitForMatch;
|
|
469
460
|
private extractClassMetadata;
|
|
470
461
|
private resolveClassFilePath;
|
|
471
|
-
private
|
|
472
|
-
private findNearestSymbolFromList;
|
|
473
|
-
private buildOneHopRelations;
|
|
462
|
+
private resolveBinaryFallbackArtifact;
|
|
474
463
|
private buildProvenance;
|
|
475
464
|
private buildFallbackProvenance;
|
|
476
|
-
private
|
|
477
|
-
private
|
|
465
|
+
private resolveClassNameForLookup;
|
|
466
|
+
private buildClassSourceNotFoundError;
|
|
467
|
+
private resolveToObfuscatedClassName;
|
|
468
|
+
private resolveToObfuscatedMemberName;
|
|
478
469
|
private remapSignatureMembers;
|
|
479
470
|
private fallbackArtifactSignature;
|
|
480
471
|
private resolveIndexRebuildReason;
|