@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.
@@ -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: resolvedJarPath,
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];
@@ -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
- source?: string;
360
- sourcePath?: string;
361
- sourcePaths?: string[];
362
- mixinConfigPath?: string | string[];
363
- sourceRoot?: string;
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
- sourcePath: string;
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 ValidateMixinBatchOutput = {
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 validateMixinBatch;
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 findNearestSymbolForLine;
472
- private findNearestSymbolFromList;
473
- private buildOneHopRelations;
462
+ private resolveBinaryFallbackArtifact;
474
463
  private buildProvenance;
475
464
  private buildFallbackProvenance;
476
- private resolveToOfficialClassName;
477
- private resolveToOfficialMemberName;
465
+ private resolveClassNameForLookup;
466
+ private buildClassSourceNotFoundError;
467
+ private resolveToObfuscatedClassName;
468
+ private resolveToObfuscatedMemberName;
478
469
  private remapSignatureMembers;
479
470
  private fallbackArtifactSignature;
480
471
  private resolveIndexRebuildReason;