@adhisang/minecraft-modding-mcp 1.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.
Files changed (106) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +765 -0
  4. package/dist/access-widener-parser.d.ts +24 -0
  5. package/dist/access-widener-parser.js +77 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +4 -0
  8. package/dist/config.d.ts +27 -0
  9. package/dist/config.js +178 -0
  10. package/dist/decompiler/vineflower.d.ts +15 -0
  11. package/dist/decompiler/vineflower.js +185 -0
  12. package/dist/errors.d.ts +50 -0
  13. package/dist/errors.js +49 -0
  14. package/dist/hash.d.ts +1 -0
  15. package/dist/hash.js +12 -0
  16. package/dist/index.d.ts +7 -0
  17. package/dist/index.js +1447 -0
  18. package/dist/java-process.d.ts +16 -0
  19. package/dist/java-process.js +120 -0
  20. package/dist/logger.d.ts +3 -0
  21. package/dist/logger.js +21 -0
  22. package/dist/mapping-pipeline-service.d.ts +18 -0
  23. package/dist/mapping-pipeline-service.js +60 -0
  24. package/dist/mapping-service.d.ts +161 -0
  25. package/dist/mapping-service.js +1706 -0
  26. package/dist/maven-resolver.d.ts +22 -0
  27. package/dist/maven-resolver.js +122 -0
  28. package/dist/minecraft-explorer-service.d.ts +43 -0
  29. package/dist/minecraft-explorer-service.js +562 -0
  30. package/dist/mixin-parser.d.ts +34 -0
  31. package/dist/mixin-parser.js +194 -0
  32. package/dist/mixin-validator.d.ts +59 -0
  33. package/dist/mixin-validator.js +274 -0
  34. package/dist/mod-analyzer.d.ts +23 -0
  35. package/dist/mod-analyzer.js +346 -0
  36. package/dist/mod-decompile-service.d.ts +39 -0
  37. package/dist/mod-decompile-service.js +136 -0
  38. package/dist/mod-remap-service.d.ts +17 -0
  39. package/dist/mod-remap-service.js +186 -0
  40. package/dist/mod-search-service.d.ts +28 -0
  41. package/dist/mod-search-service.js +174 -0
  42. package/dist/mojang-tiny-mapping-service.d.ts +13 -0
  43. package/dist/mojang-tiny-mapping-service.js +351 -0
  44. package/dist/nbt/java-nbt-codec.d.ts +3 -0
  45. package/dist/nbt/java-nbt-codec.js +385 -0
  46. package/dist/nbt/json-patch.d.ts +3 -0
  47. package/dist/nbt/json-patch.js +352 -0
  48. package/dist/nbt/pipeline.d.ts +39 -0
  49. package/dist/nbt/pipeline.js +173 -0
  50. package/dist/nbt/typed-json.d.ts +10 -0
  51. package/dist/nbt/typed-json.js +205 -0
  52. package/dist/nbt/types.d.ts +66 -0
  53. package/dist/nbt/types.js +2 -0
  54. package/dist/observability.d.ts +88 -0
  55. package/dist/observability.js +165 -0
  56. package/dist/path-converter.d.ts +12 -0
  57. package/dist/path-converter.js +161 -0
  58. package/dist/path-resolver.d.ts +19 -0
  59. package/dist/path-resolver.js +78 -0
  60. package/dist/registry-service.d.ts +29 -0
  61. package/dist/registry-service.js +214 -0
  62. package/dist/repo-downloader.d.ts +15 -0
  63. package/dist/repo-downloader.js +111 -0
  64. package/dist/resources.d.ts +3 -0
  65. package/dist/resources.js +154 -0
  66. package/dist/search-hit-accumulator.d.ts +38 -0
  67. package/dist/search-hit-accumulator.js +153 -0
  68. package/dist/source-jar-reader.d.ts +13 -0
  69. package/dist/source-jar-reader.js +216 -0
  70. package/dist/source-resolver.d.ts +14 -0
  71. package/dist/source-resolver.js +274 -0
  72. package/dist/source-service.d.ts +404 -0
  73. package/dist/source-service.js +2881 -0
  74. package/dist/storage/artifacts-repo.d.ts +45 -0
  75. package/dist/storage/artifacts-repo.js +209 -0
  76. package/dist/storage/db.d.ts +14 -0
  77. package/dist/storage/db.js +132 -0
  78. package/dist/storage/files-repo.d.ts +78 -0
  79. package/dist/storage/files-repo.js +437 -0
  80. package/dist/storage/index-meta-repo.d.ts +35 -0
  81. package/dist/storage/index-meta-repo.js +97 -0
  82. package/dist/storage/migrations.d.ts +11 -0
  83. package/dist/storage/migrations.js +71 -0
  84. package/dist/storage/schema.d.ts +1 -0
  85. package/dist/storage/schema.js +160 -0
  86. package/dist/storage/sqlite.d.ts +20 -0
  87. package/dist/storage/sqlite.js +111 -0
  88. package/dist/storage/symbols-repo.d.ts +63 -0
  89. package/dist/storage/symbols-repo.js +401 -0
  90. package/dist/symbols/symbol-extractor.d.ts +7 -0
  91. package/dist/symbols/symbol-extractor.js +64 -0
  92. package/dist/tiny-remapper-resolver.d.ts +1 -0
  93. package/dist/tiny-remapper-resolver.js +62 -0
  94. package/dist/tiny-remapper-service.d.ts +16 -0
  95. package/dist/tiny-remapper-service.js +73 -0
  96. package/dist/types.d.ts +120 -0
  97. package/dist/types.js +2 -0
  98. package/dist/version-diff-service.d.ts +41 -0
  99. package/dist/version-diff-service.js +222 -0
  100. package/dist/version-service.d.ts +70 -0
  101. package/dist/version-service.js +411 -0
  102. package/dist/vineflower-resolver.d.ts +1 -0
  103. package/dist/vineflower-resolver.js +62 -0
  104. package/dist/workspace-mapping-service.d.ts +18 -0
  105. package/dist/workspace-mapping-service.js +89 -0
  106. package/package.json +61 -0
@@ -0,0 +1,120 @@
1
+ export type SourceOrigin = "local-jar" | "local-m2" | "remote-repo" | "decompiled";
2
+ export type SourceMapping = "official" | "mojang" | "intermediary" | "yarn";
3
+ export type MappingSourcePriority = "loom-first" | "maven-first";
4
+ export type ArtifactTargetKind = "version" | "jar" | "coordinate";
5
+ export interface SourceTargetInput {
6
+ kind: ArtifactTargetKind;
7
+ value: string;
8
+ }
9
+ export interface ResolvedSourceArtifact {
10
+ artifactId: string;
11
+ artifactSignature: string;
12
+ origin: SourceOrigin;
13
+ binaryJarPath?: string;
14
+ sourceJarPath?: string;
15
+ adjacentSourceCandidates?: string[];
16
+ coordinate?: string;
17
+ version?: string;
18
+ requestedMapping?: SourceMapping;
19
+ mappingApplied?: SourceMapping;
20
+ repoUrl?: string;
21
+ provenance?: ArtifactProvenance;
22
+ qualityFlags?: string[];
23
+ isDecompiled: boolean;
24
+ resolvedAt: string;
25
+ }
26
+ export interface ArtifactProvenance {
27
+ target: SourceTargetInput;
28
+ resolvedAt: string;
29
+ resolvedFrom: {
30
+ origin: SourceOrigin;
31
+ sourceJarPath?: string;
32
+ binaryJarPath?: string;
33
+ coordinate?: string;
34
+ version?: string;
35
+ repoUrl?: string;
36
+ };
37
+ transformChain: string[];
38
+ }
39
+ export interface ErrorEnvelope {
40
+ code: string;
41
+ message: string;
42
+ details?: Record<string, unknown>;
43
+ }
44
+ export interface Config {
45
+ cacheDir: string;
46
+ sqlitePath: string;
47
+ sourceRepos: string[];
48
+ localM2Path: string;
49
+ vineflowerJarPath: string | undefined;
50
+ indexedSearchEnabled: boolean;
51
+ mappingSourcePriority: MappingSourcePriority;
52
+ maxContentBytes: number;
53
+ maxSearchHits: number;
54
+ maxArtifacts: number;
55
+ maxCacheBytes: number;
56
+ fetchTimeoutMs: number;
57
+ fetchRetries: number;
58
+ searchScanPageSize: number;
59
+ indexInsertChunkSize: number;
60
+ maxMappingGraphCache: number;
61
+ maxSignatureCache: number;
62
+ maxVersionDetailCache: number;
63
+ maxNbtInputBytes: number;
64
+ maxNbtInflatedBytes: number;
65
+ maxNbtResponseBytes: number;
66
+ tinyRemapperJarPath: string | undefined;
67
+ remapTimeoutMs: number;
68
+ remapMaxMemoryMb: number;
69
+ }
70
+ export interface ArtifactSignature {
71
+ sourcePath: string;
72
+ sourceArtifactId: string;
73
+ signature: string;
74
+ signatureParts: {
75
+ mtimeMs: number;
76
+ size: number;
77
+ };
78
+ }
79
+ export interface SourceSearchHit {
80
+ filePath: string;
81
+ score: number;
82
+ matchedIn: "path" | "content" | "both";
83
+ preview: string;
84
+ }
85
+ export interface ArtifactRow {
86
+ artifactId: string;
87
+ origin: SourceOrigin;
88
+ coordinate: string | undefined;
89
+ version: string | undefined;
90
+ binaryJarPath: string | undefined;
91
+ sourceJarPath: string | undefined;
92
+ repoUrl: string | undefined;
93
+ requestedMapping: SourceMapping | undefined;
94
+ mappingApplied: SourceMapping | undefined;
95
+ provenance: ArtifactProvenance | undefined;
96
+ qualityFlags: string[];
97
+ artifactSignature: string | undefined;
98
+ isDecompiled: boolean;
99
+ createdAt: string;
100
+ updatedAt: string;
101
+ }
102
+ export interface FileRow {
103
+ artifactId: string;
104
+ filePath: string;
105
+ content: string;
106
+ contentBytes: number;
107
+ contentHash: string;
108
+ }
109
+ export interface SymbolRow {
110
+ artifactId: string;
111
+ filePath: string;
112
+ symbolKind: string;
113
+ symbolName: string;
114
+ qualifiedName: string | undefined;
115
+ line: number;
116
+ }
117
+ export interface PagedResult<T> {
118
+ items: T[];
119
+ nextCursor: string | undefined;
120
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,41 @@
1
+ import { VersionService } from "./version-service.js";
2
+ import { RegistryService } from "./registry-service.js";
3
+ import type { Config } from "./types.js";
4
+ export type CompareVersionsCategory = "classes" | "registry" | "all";
5
+ export type CompareVersionsInput = {
6
+ fromVersion: string;
7
+ toVersion: string;
8
+ category?: CompareVersionsCategory;
9
+ packageFilter?: string;
10
+ maxClassResults?: number;
11
+ };
12
+ export type CompareVersionsOutput = {
13
+ fromVersion: string;
14
+ toVersion: string;
15
+ classes?: {
16
+ added: string[];
17
+ removed: string[];
18
+ addedCount: number;
19
+ removedCount: number;
20
+ unchanged: number;
21
+ };
22
+ registry?: {
23
+ added: Record<string, string[]>;
24
+ removed: Record<string, string[]>;
25
+ newRegistries: string[];
26
+ removedRegistries: string[];
27
+ summary: {
28
+ registriesChanged: number;
29
+ totalAdded: number;
30
+ totalRemoved: number;
31
+ };
32
+ };
33
+ warnings: string[];
34
+ };
35
+ export declare class VersionDiffService {
36
+ private readonly config;
37
+ private readonly versionService;
38
+ private readonly registryService;
39
+ constructor(config: Config, versionService: VersionService, registryService: RegistryService);
40
+ compareVersions(input: CompareVersionsInput): Promise<CompareVersionsOutput>;
41
+ }
@@ -0,0 +1,222 @@
1
+ import { createError, ERROR_CODES } from "./errors.js";
2
+ import { log } from "./logger.js";
3
+ import { listJarEntries } from "./source-jar-reader.js";
4
+ const DEFAULT_MAX_CLASS_RESULTS = 500;
5
+ const MAX_CLASS_RESULTS_LIMIT = 5000;
6
+ function classInternalToFqn(internalPath) {
7
+ // Remove .class suffix and convert / to .
8
+ return internalPath.replace(/\.class$/, "").replaceAll("/", ".");
9
+ }
10
+ function extractClassEntries(entries) {
11
+ const classes = new Set();
12
+ for (const entry of entries) {
13
+ if (entry.endsWith(".class") &&
14
+ !entry.includes("META-INF/") &&
15
+ !entry.includes("$")) {
16
+ classes.add(classInternalToFqn(entry));
17
+ }
18
+ }
19
+ return classes;
20
+ }
21
+ function filterByPackage(classes, prefix) {
22
+ const normalized = prefix.endsWith(".") ? prefix : `${prefix}.`;
23
+ return classes.filter((fqn) => fqn.startsWith(normalized));
24
+ }
25
+ function diffSets(from, to) {
26
+ const added = [];
27
+ const removed = [];
28
+ let unchanged = 0;
29
+ for (const entry of to) {
30
+ if (!from.has(entry))
31
+ added.push(entry);
32
+ else
33
+ unchanged++;
34
+ }
35
+ for (const entry of from) {
36
+ if (!to.has(entry))
37
+ removed.push(entry);
38
+ }
39
+ added.sort();
40
+ removed.sort();
41
+ return { added, removed, unchanged };
42
+ }
43
+ function diffRegistries(fromRegistries, toRegistries) {
44
+ const fromKeys = new Set(Object.keys(fromRegistries));
45
+ const toKeys = new Set(Object.keys(toRegistries));
46
+ const newRegistries = [];
47
+ const removedRegistries = [];
48
+ for (const key of toKeys) {
49
+ if (!fromKeys.has(key))
50
+ newRegistries.push(key);
51
+ }
52
+ for (const key of fromKeys) {
53
+ if (!toKeys.has(key))
54
+ removedRegistries.push(key);
55
+ }
56
+ newRegistries.sort();
57
+ removedRegistries.sort();
58
+ const added = {};
59
+ const removed = {};
60
+ let totalAdded = 0;
61
+ let totalRemoved = 0;
62
+ let registriesChanged = 0;
63
+ // Compare entries in registries present in both versions
64
+ const commonRegistries = [...fromKeys].filter((key) => toKeys.has(key));
65
+ for (const registryName of commonRegistries) {
66
+ const fromEntries = new Set(Object.keys(fromRegistries[registryName].entries));
67
+ const toEntries = new Set(Object.keys(toRegistries[registryName].entries));
68
+ const addedEntries = [];
69
+ const removedEntries = [];
70
+ for (const entry of toEntries) {
71
+ if (!fromEntries.has(entry))
72
+ addedEntries.push(entry);
73
+ }
74
+ for (const entry of fromEntries) {
75
+ if (!toEntries.has(entry))
76
+ removedEntries.push(entry);
77
+ }
78
+ if (addedEntries.length > 0 || removedEntries.length > 0) {
79
+ registriesChanged++;
80
+ if (addedEntries.length > 0) {
81
+ addedEntries.sort();
82
+ added[registryName] = addedEntries;
83
+ totalAdded += addedEntries.length;
84
+ }
85
+ if (removedEntries.length > 0) {
86
+ removedEntries.sort();
87
+ removed[registryName] = removedEntries;
88
+ totalRemoved += removedEntries.length;
89
+ }
90
+ }
91
+ }
92
+ // Count new registries' entries as added
93
+ for (const regName of newRegistries) {
94
+ const entries = Object.keys(toRegistries[regName].entries);
95
+ if (entries.length > 0) {
96
+ entries.sort();
97
+ added[regName] = entries;
98
+ totalAdded += entries.length;
99
+ registriesChanged++;
100
+ }
101
+ }
102
+ // Count removed registries' entries as removed
103
+ for (const regName of removedRegistries) {
104
+ const entries = Object.keys(fromRegistries[regName].entries);
105
+ if (entries.length > 0) {
106
+ entries.sort();
107
+ removed[regName] = entries;
108
+ totalRemoved += entries.length;
109
+ registriesChanged++;
110
+ }
111
+ }
112
+ return {
113
+ added,
114
+ removed,
115
+ newRegistries,
116
+ removedRegistries,
117
+ summary: {
118
+ registriesChanged,
119
+ totalAdded,
120
+ totalRemoved
121
+ }
122
+ };
123
+ }
124
+ export class VersionDiffService {
125
+ config;
126
+ versionService;
127
+ registryService;
128
+ constructor(config, versionService, registryService) {
129
+ this.config = config;
130
+ this.versionService = versionService;
131
+ this.registryService = registryService;
132
+ }
133
+ async compareVersions(input) {
134
+ const fromVersion = input.fromVersion.trim();
135
+ const toVersion = input.toVersion.trim();
136
+ const category = input.category ?? "all";
137
+ const maxClassResults = Math.min(input.maxClassResults ?? DEFAULT_MAX_CLASS_RESULTS, MAX_CLASS_RESULTS_LIMIT);
138
+ if (!fromVersion || !toVersion) {
139
+ throw createError({
140
+ code: ERROR_CODES.INVALID_INPUT,
141
+ message: "fromVersion and toVersion must be non-empty."
142
+ });
143
+ }
144
+ const warnings = [];
145
+ const startedAt = Date.now();
146
+ log("info", "version-diff.start", { fromVersion, toVersion, category });
147
+ const includeClasses = category === "classes" || category === "all";
148
+ const includeRegistry = category === "registry" || category === "all";
149
+ let classesResult;
150
+ let registryResult;
151
+ // Run class and registry comparisons in parallel where possible
152
+ const tasks = [];
153
+ if (includeClasses) {
154
+ tasks.push((async () => {
155
+ const [fromJar, toJar] = await Promise.all([
156
+ this.versionService.resolveVersionJar(fromVersion),
157
+ this.versionService.resolveVersionJar(toVersion)
158
+ ]);
159
+ const [fromEntries, toEntries] = await Promise.all([
160
+ listJarEntries(fromJar.jarPath),
161
+ listJarEntries(toJar.jarPath)
162
+ ]);
163
+ const fromClasses = extractClassEntries(fromEntries);
164
+ const toClasses = extractClassEntries(toEntries);
165
+ let { added, removed, unchanged } = diffSets(fromClasses, toClasses);
166
+ if (input.packageFilter) {
167
+ added = filterByPackage(added, input.packageFilter);
168
+ removed = filterByPackage(removed, input.packageFilter);
169
+ }
170
+ const truncatedAdded = added.slice(0, maxClassResults);
171
+ const truncatedRemoved = removed.slice(0, maxClassResults);
172
+ if (added.length > maxClassResults) {
173
+ warnings.push(`Class additions truncated: showing ${maxClassResults} of ${added.length}. Use packageFilter to narrow results.`);
174
+ }
175
+ if (removed.length > maxClassResults) {
176
+ warnings.push(`Class removals truncated: showing ${maxClassResults} of ${removed.length}. Use packageFilter to narrow results.`);
177
+ }
178
+ classesResult = {
179
+ added: truncatedAdded,
180
+ removed: truncatedRemoved,
181
+ addedCount: added.length,
182
+ removedCount: removed.length,
183
+ unchanged
184
+ };
185
+ })());
186
+ }
187
+ if (includeRegistry) {
188
+ tasks.push((async () => {
189
+ try {
190
+ const [fromReg, toReg] = await Promise.all([
191
+ this.registryService.getRegistryData({ version: fromVersion }),
192
+ this.registryService.getRegistryData({ version: toVersion })
193
+ ]);
194
+ const fromData = fromReg.data;
195
+ const toData = toReg.data;
196
+ registryResult = diffRegistries(fromData, toData);
197
+ }
198
+ catch (error) {
199
+ if (category === "registry") {
200
+ throw error;
201
+ }
202
+ const msg = error instanceof Error ? error.message : String(error);
203
+ warnings.push(`Registry comparison failed: ${msg}`);
204
+ }
205
+ })());
206
+ }
207
+ await Promise.all(tasks);
208
+ log("info", "version-diff.done", {
209
+ fromVersion,
210
+ toVersion,
211
+ durationMs: Date.now() - startedAt
212
+ });
213
+ return {
214
+ fromVersion,
215
+ toVersion,
216
+ classes: classesResult,
217
+ registry: registryResult,
218
+ warnings
219
+ };
220
+ }
221
+ }
222
+ //# sourceMappingURL=version-diff-service.js.map
@@ -0,0 +1,70 @@
1
+ import type { Config } from "./types.js";
2
+ export type ListVersionsInput = {
3
+ includeSnapshots?: boolean;
4
+ limit?: number;
5
+ };
6
+ export type VersionEntry = {
7
+ id: string;
8
+ unobfuscated: boolean;
9
+ };
10
+ export type ListVersionsOutput = {
11
+ latest: {
12
+ release?: string;
13
+ snapshot?: string;
14
+ };
15
+ releases: VersionEntry[];
16
+ snapshots?: VersionEntry[];
17
+ cached: string[];
18
+ totalAvailable: number;
19
+ };
20
+ export type ResolvedVersionJar = {
21
+ version: string;
22
+ jarPath: string;
23
+ source: "downloaded";
24
+ clientJarUrl: string;
25
+ };
26
+ export type ResolvedServerJar = {
27
+ version: string;
28
+ jarPath: string;
29
+ source: "downloaded";
30
+ serverJarUrl: string;
31
+ };
32
+ export type ResolvedVersionMappings = {
33
+ version: string;
34
+ versionManifestUrl: string;
35
+ versionDetailUrl: string;
36
+ clientMappingsUrl?: string;
37
+ serverMappingsUrl?: string;
38
+ mappingsUrl?: string;
39
+ };
40
+ export type ListVersionIdsInput = {
41
+ includeSnapshots?: boolean;
42
+ };
43
+ export declare class VersionService {
44
+ private readonly config;
45
+ private readonly fetchFn;
46
+ private readonly manifestUrl;
47
+ private manifestCache;
48
+ private readonly versionDetailCache;
49
+ private readonly resolveLocks;
50
+ constructor(config: Config, fetchFn?: typeof fetch);
51
+ listVersions(input?: ListVersionsInput): Promise<ListVersionsOutput>;
52
+ listVersionIds(input?: ListVersionIdsInput): Promise<string[]>;
53
+ resolveVersionJar(version: string): Promise<ResolvedVersionJar>;
54
+ resolveVersionMappings(version: string): Promise<ResolvedVersionMappings>;
55
+ resolveServerJar(version: string): Promise<ResolvedServerJar>;
56
+ private fetchManifest;
57
+ private resolveVersionJarInternal;
58
+ private fetchVersionDetails;
59
+ private fetchJson;
60
+ private cacheIndexPath;
61
+ private loadCacheIndex;
62
+ private recordCacheEntry;
63
+ private trimVersionDetailCache;
64
+ }
65
+ /**
66
+ * MC 26.1+ uses new YY.N version format and ships unobfuscated source.
67
+ * Legacy 1.x.y versions remain obfuscated.
68
+ * Snapshots: "26w01a" (year >= 26) → unobfuscated, "24w01a" → obfuscated.
69
+ */
70
+ export declare function isUnobfuscatedVersion(version: string): boolean;