@adhisang/minecraft-modding-mcp 3.2.0 → 4.1.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 (194) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +52 -32
  3. package/dist/build-suggested-call.d.ts +29 -0
  4. package/dist/build-suggested-call.js +58 -0
  5. package/dist/cache-registry.d.ts +3 -1
  6. package/dist/cache-registry.js +59 -7
  7. package/dist/config.d.ts +10 -1
  8. package/dist/config.js +52 -1
  9. package/dist/entry-tools/analyze-symbol-service.d.ts +18 -18
  10. package/dist/entry-tools/analyze-symbol-service.js +13 -2
  11. package/dist/entry-tools/batch-class-members-service.d.ts +34 -0
  12. package/dist/entry-tools/batch-class-members-service.js +97 -0
  13. package/dist/entry-tools/batch-class-source-service.d.ts +37 -0
  14. package/dist/entry-tools/batch-class-source-service.js +100 -0
  15. package/dist/entry-tools/batch-mappings-service.d.ts +36 -0
  16. package/dist/entry-tools/batch-mappings-service.js +66 -0
  17. package/dist/entry-tools/batch-runner.d.ts +72 -0
  18. package/dist/entry-tools/batch-runner.js +90 -0
  19. package/dist/entry-tools/batch-symbol-exists-service.d.ts +46 -0
  20. package/dist/entry-tools/batch-symbol-exists-service.js +113 -0
  21. package/dist/entry-tools/compare-minecraft-service.d.ts +6 -6
  22. package/dist/entry-tools/inspect-minecraft/handlers/artifact.d.ts +5 -0
  23. package/dist/entry-tools/inspect-minecraft/handlers/artifact.js +83 -0
  24. package/dist/entry-tools/inspect-minecraft/handlers/class-members.d.ts +6 -0
  25. package/dist/entry-tools/inspect-minecraft/handlers/class-members.js +80 -0
  26. package/dist/entry-tools/inspect-minecraft/handlers/class-overview.d.ts +5 -0
  27. package/dist/entry-tools/inspect-minecraft/handlers/class-overview.js +248 -0
  28. package/dist/entry-tools/inspect-minecraft/handlers/class-source.d.ts +5 -0
  29. package/dist/entry-tools/inspect-minecraft/handlers/class-source.js +60 -0
  30. package/dist/entry-tools/inspect-minecraft/handlers/file.d.ts +5 -0
  31. package/dist/entry-tools/inspect-minecraft/handlers/file.js +54 -0
  32. package/dist/entry-tools/inspect-minecraft/handlers/list-files.d.ts +5 -0
  33. package/dist/entry-tools/inspect-minecraft/handlers/list-files.js +100 -0
  34. package/dist/entry-tools/inspect-minecraft/handlers/search.d.ts +5 -0
  35. package/dist/entry-tools/inspect-minecraft/handlers/search.js +155 -0
  36. package/dist/entry-tools/inspect-minecraft/handlers/versions.d.ts +6 -0
  37. package/dist/entry-tools/inspect-minecraft/handlers/versions.js +49 -0
  38. package/dist/entry-tools/inspect-minecraft/internal.d.ts +1042 -0
  39. package/dist/entry-tools/inspect-minecraft/internal.js +448 -0
  40. package/dist/entry-tools/inspect-minecraft-service.d.ts +213 -328
  41. package/dist/entry-tools/inspect-minecraft-service.js +20 -1238
  42. package/dist/entry-tools/manage-cache-service.d.ts +16 -16
  43. package/dist/entry-tools/validate-project/cases/access-transformer.d.ts +6 -0
  44. package/dist/entry-tools/validate-project/cases/access-transformer.js +106 -0
  45. package/dist/entry-tools/validate-project/cases/access-widener.d.ts +6 -0
  46. package/dist/entry-tools/validate-project/cases/access-widener.js +86 -0
  47. package/dist/entry-tools/validate-project/cases/mixin.d.ts +6 -0
  48. package/dist/entry-tools/validate-project/cases/mixin.js +90 -0
  49. package/dist/entry-tools/validate-project/cases/project-summary.d.ts +97 -0
  50. package/dist/entry-tools/validate-project/cases/project-summary.js +346 -0
  51. package/dist/entry-tools/validate-project/internal.d.ts +135 -0
  52. package/dist/entry-tools/validate-project/internal.js +287 -0
  53. package/dist/entry-tools/validate-project-service.d.ts +63 -47
  54. package/dist/entry-tools/validate-project-service.js +12 -482
  55. package/dist/entry-tools/verify-mixin-target-service.d.ts +133 -0
  56. package/dist/entry-tools/verify-mixin-target-service.js +323 -0
  57. package/dist/error-mapping.d.ts +40 -0
  58. package/dist/error-mapping.js +139 -0
  59. package/dist/errors.d.ts +6 -0
  60. package/dist/errors.js +6 -0
  61. package/dist/index.d.ts +2 -0
  62. package/dist/index.js +170 -1314
  63. package/dist/lru-list.d.ts +31 -0
  64. package/dist/lru-list.js +102 -0
  65. package/dist/mapping/internal-types.d.ts +54 -0
  66. package/dist/mapping/internal-types.js +14 -0
  67. package/dist/mapping/loaders/mojang.d.ts +2 -0
  68. package/dist/mapping/loaders/mojang.js +64 -0
  69. package/dist/mapping/loaders/tiny-loom.d.ts +2 -0
  70. package/dist/mapping/loaders/tiny-loom.js +73 -0
  71. package/dist/mapping/loaders/tiny-maven.d.ts +2 -0
  72. package/dist/mapping/loaders/tiny-maven.js +104 -0
  73. package/dist/mapping/loaders/types.d.ts +14 -0
  74. package/dist/mapping/loaders/types.js +2 -0
  75. package/dist/mapping/lookup.d.ts +52 -0
  76. package/dist/mapping/lookup.js +496 -0
  77. package/dist/mapping/parsers/normalize.d.ts +10 -0
  78. package/dist/mapping/parsers/normalize.js +52 -0
  79. package/dist/mapping/parsers/proguard.d.ts +20 -0
  80. package/dist/mapping/parsers/proguard.js +138 -0
  81. package/dist/mapping/parsers/symbol-records.d.ts +27 -0
  82. package/dist/mapping/parsers/symbol-records.js +216 -0
  83. package/dist/mapping/parsers/tiny.d.ts +9 -0
  84. package/dist/mapping/parsers/tiny.js +96 -0
  85. package/dist/mapping/types.d.ts +147 -0
  86. package/dist/mapping/types.js +2 -0
  87. package/dist/mapping-pipeline-service.d.ts +10 -1
  88. package/dist/mapping-pipeline-service.js +16 -3
  89. package/dist/mapping-service.d.ts +15 -144
  90. package/dist/mapping-service.js +179 -1119
  91. package/dist/mixin/access-validators.d.ts +9 -0
  92. package/dist/mixin/access-validators.js +257 -0
  93. package/dist/mixin/annotation-validators.d.ts +5 -0
  94. package/dist/mixin/annotation-validators.js +162 -0
  95. package/dist/mixin/helpers.d.ts +28 -0
  96. package/dist/mixin/helpers.js +315 -0
  97. package/dist/mixin/parsed-validator.d.ts +8 -0
  98. package/dist/mixin/parsed-validator.js +337 -0
  99. package/dist/mixin/types.d.ts +208 -0
  100. package/dist/mixin/types.js +28 -0
  101. package/dist/mixin-validator.d.ts +9 -201
  102. package/dist/mixin-validator.js +8 -1005
  103. package/dist/observability.d.ts +18 -1
  104. package/dist/observability.js +44 -1
  105. package/dist/response-utils.d.ts +44 -10
  106. package/dist/response-utils.js +131 -17
  107. package/dist/source/access-validate.d.ts +4 -0
  108. package/dist/source/access-validate.js +254 -0
  109. package/dist/source/artifact-resolver.d.ts +110 -0
  110. package/dist/source/artifact-resolver.js +1174 -0
  111. package/dist/source/cache-metrics.d.ts +26 -0
  112. package/dist/source/cache-metrics.js +172 -0
  113. package/dist/source/class-source/members-builder.d.ts +34 -0
  114. package/dist/source/class-source/members-builder.js +46 -0
  115. package/dist/source/class-source/snippet-builder.d.ts +19 -0
  116. package/dist/source/class-source/snippet-builder.js +46 -0
  117. package/dist/source/class-source-helpers.d.ts +34 -0
  118. package/dist/source/class-source-helpers.js +140 -0
  119. package/dist/source/class-source.d.ts +42 -0
  120. package/dist/source/class-source.js +883 -0
  121. package/dist/source/descriptor-utils.d.ts +6 -0
  122. package/dist/source/descriptor-utils.js +37 -0
  123. package/dist/source/file-access.d.ts +4 -0
  124. package/dist/source/file-access.js +102 -0
  125. package/dist/source/indexer.d.ts +82 -0
  126. package/dist/source/indexer.js +505 -0
  127. package/dist/source/lifecycle/diff-utils.d.ts +9 -0
  128. package/dist/source/lifecycle/diff-utils.js +107 -0
  129. package/dist/source/lifecycle/diff.d.ts +2 -0
  130. package/dist/source/lifecycle/diff.js +265 -0
  131. package/dist/source/lifecycle/mapping-helpers.d.ts +22 -0
  132. package/dist/source/lifecycle/mapping-helpers.js +327 -0
  133. package/dist/source/lifecycle/runtime-check.d.ts +2 -0
  134. package/dist/source/lifecycle/runtime-check.js +142 -0
  135. package/dist/source/lifecycle/trace.d.ts +2 -0
  136. package/dist/source/lifecycle/trace.js +231 -0
  137. package/dist/source/lifecycle.d.ts +4 -0
  138. package/dist/source/lifecycle.js +5 -0
  139. package/dist/source/search.d.ts +51 -0
  140. package/dist/source/search.js +676 -0
  141. package/dist/source/shared-utils.d.ts +6 -0
  142. package/dist/source/shared-utils.js +55 -0
  143. package/dist/source/state.d.ts +21 -0
  144. package/dist/source/state.js +19 -0
  145. package/dist/source/symbol-resolver.d.ts +3 -0
  146. package/dist/source/symbol-resolver.js +212 -0
  147. package/dist/source/validate-mixin/pipeline/mapping-health.d.ts +3 -0
  148. package/dist/source/validate-mixin/pipeline/mapping-health.js +41 -0
  149. package/dist/source/validate-mixin/pipeline/parse.d.ts +2 -0
  150. package/dist/source/validate-mixin/pipeline/parse.js +10 -0
  151. package/dist/source/validate-mixin/pipeline/resolve.d.ts +3 -0
  152. package/dist/source/validate-mixin/pipeline/resolve.js +78 -0
  153. package/dist/source/validate-mixin/pipeline/target-lookup.d.ts +6 -0
  154. package/dist/source/validate-mixin/pipeline/target-lookup.js +260 -0
  155. package/dist/source/validate-mixin/pipeline-context.d.ts +72 -0
  156. package/dist/source/validate-mixin/pipeline-context.js +93 -0
  157. package/dist/source/validate-mixin.d.ts +22 -0
  158. package/dist/source/validate-mixin.js +799 -0
  159. package/dist/source/workspace-target.d.ts +18 -0
  160. package/dist/source/workspace-target.js +305 -0
  161. package/dist/source-resolver.d.ts +9 -1
  162. package/dist/source-resolver.js +14 -6
  163. package/dist/source-service.d.ts +178 -105
  164. package/dist/source-service.js +72 -5312
  165. package/dist/stage-emitter.d.ts +13 -0
  166. package/dist/stage-emitter.js +30 -0
  167. package/dist/stdio-supervisor.d.ts +61 -0
  168. package/dist/stdio-supervisor.js +326 -9
  169. package/dist/storage/artifacts-repo.d.ts +4 -1
  170. package/dist/storage/artifacts-repo.js +33 -5
  171. package/dist/storage/files-repo.d.ts +0 -2
  172. package/dist/storage/files-repo.js +0 -11
  173. package/dist/storage/migrations.d.ts +1 -1
  174. package/dist/storage/migrations.js +10 -2
  175. package/dist/storage/schema.d.ts +2 -0
  176. package/dist/storage/schema.js +25 -0
  177. package/dist/tool-contract-manifest.d.ts +1 -1
  178. package/dist/tool-contract-manifest.js +23 -6
  179. package/dist/tool-guidance.d.ts +82 -0
  180. package/dist/tool-guidance.js +734 -0
  181. package/dist/tool-schema-registry.d.ts +16 -0
  182. package/dist/tool-schema-registry.js +37 -0
  183. package/dist/tool-schemas.d.ts +3518 -0
  184. package/dist/tool-schemas.js +813 -0
  185. package/dist/types.d.ts +39 -0
  186. package/dist/version-service.js +7 -6
  187. package/dist/workspace-context-cache.d.ts +32 -0
  188. package/dist/workspace-context-cache.js +66 -0
  189. package/dist/workspace-mapping-service.d.ts +16 -0
  190. package/dist/workspace-mapping-service.js +173 -1
  191. package/docs/README-ja.md +414 -0
  192. package/docs/examples.md +483 -0
  193. package/docs/tool-reference.md +459 -0
  194. package/package.json +5 -2
@@ -0,0 +1,260 @@
1
+ import { performance } from "node:perf_hooks";
2
+ function findValidateMixinClassMapping(svc, input) {
3
+ const cache = input.batchCaches?.classMappings;
4
+ if (!cache) {
5
+ return svc.mappingService.findMapping({
6
+ version: input.version,
7
+ kind: "class",
8
+ name: input.className,
9
+ sourceMapping: input.sourceMapping,
10
+ targetMapping: input.targetMapping,
11
+ sourcePriority: input.sourcePriority,
12
+ projectPath: input.projectPath
13
+ });
14
+ }
15
+ const cacheKey = [
16
+ input.version,
17
+ input.className,
18
+ input.sourceMapping,
19
+ input.targetMapping,
20
+ input.sourcePriority,
21
+ input.projectPath ?? ""
22
+ ].join("\0");
23
+ const cached = cache.get(cacheKey);
24
+ if (cached) {
25
+ return cached;
26
+ }
27
+ const pending = svc.mappingService.findMapping({
28
+ version: input.version,
29
+ kind: "class",
30
+ name: input.className,
31
+ sourceMapping: input.sourceMapping,
32
+ targetMapping: input.targetMapping,
33
+ sourcePriority: input.sourcePriority,
34
+ projectPath: input.projectPath
35
+ }).catch((error) => {
36
+ cache.delete(cacheKey);
37
+ throw error;
38
+ });
39
+ cache.set(cacheKey, pending);
40
+ return pending;
41
+ }
42
+ export async function processSingleMixinTarget(svc, ctx, target, targetIndex) {
43
+ const totalTargets = ctx.parsed.targets.length;
44
+ await ctx.stageEmitter("target-lookup", {
45
+ targetIndex,
46
+ targetTotal: totalTargets,
47
+ targetClass: target.className,
48
+ memberCount: ctx.parsed.injections.length + ctx.parsed.shadows.length + ctx.parsed.accessors.length
49
+ });
50
+ const targetStartedAt = performance.now();
51
+ if (ctx.testHooks?.beforeTargetIter) {
52
+ await ctx.testHooks.beforeTargetIter(targetIndex);
53
+ }
54
+ let resolvedClassName = target.className;
55
+ if (!resolvedClassName.includes(".")) {
56
+ const fqcn = ctx.parsed.imports.get(resolvedClassName);
57
+ if (fqcn) {
58
+ resolvedClassName = fqcn;
59
+ }
60
+ }
61
+ else {
62
+ const segments = resolvedClassName.split(".");
63
+ const firstSegment = segments[0];
64
+ if (firstSegment && /^[A-Z]/.test(firstSegment)) {
65
+ const outerFqcn = ctx.parsed.imports.get(firstSegment);
66
+ if (outerFqcn) {
67
+ resolvedClassName = outerFqcn + "$" + segments.slice(1).join("$");
68
+ }
69
+ }
70
+ }
71
+ let obfuscatedName = resolvedClassName;
72
+ if (ctx.requestedMapping !== ctx.signatureLookupMapping) {
73
+ try {
74
+ const mapped = await findValidateMixinClassMapping(svc, {
75
+ version: ctx.version,
76
+ className: resolvedClassName,
77
+ sourceMapping: ctx.requestedMapping,
78
+ targetMapping: ctx.signatureLookupMapping,
79
+ sourcePriority: ctx.currentSourcePriority,
80
+ projectPath: ctx.input.projectPath,
81
+ batchCaches: ctx.input.batchCaches
82
+ });
83
+ if (mapped.resolved && mapped.resolvedSymbol) {
84
+ obfuscatedName = mapped.resolvedSymbol.name;
85
+ ctx.resolutionTrace?.push({ target: target.className, step: "mapping", input: resolvedClassName, output: obfuscatedName, success: true });
86
+ }
87
+ else {
88
+ ctx.warnings.push(`Could not map class "${resolvedClassName}" from ${ctx.requestedMapping} to ${ctx.signatureLookupMapping}; using "${obfuscatedName}" for lookup.`);
89
+ ctx.mappingFailedTargets.add(target.className);
90
+ ctx.resolutionTrace?.push({ target: target.className, step: "mapping", input: resolvedClassName, output: obfuscatedName, success: false, detail: "No mapping found" });
91
+ }
92
+ }
93
+ catch (mapErr) {
94
+ ctx.warnings.push(`Mapping lookup failed for class "${resolvedClassName}" while preparing ${ctx.signatureLookupMapping} lookup; using "${obfuscatedName}" for lookup.`);
95
+ ctx.mappingFailedTargets.add(target.className);
96
+ ctx.resolutionTrace?.push({ target: target.className, step: "mapping", input: resolvedClassName, output: obfuscatedName, success: false, detail: mapErr instanceof Error ? mapErr.message : String(mapErr) });
97
+ }
98
+ }
99
+ try {
100
+ const sig = await svc.explorerService.getSignature({
101
+ fqn: obfuscatedName,
102
+ jarPath: ctx.jarPath,
103
+ access: "all"
104
+ });
105
+ ctx.warnings.push(...sig.warnings);
106
+ ctx.resolutionTrace?.push({ target: target.className, step: "signature", input: obfuscatedName, output: `${sig.methods.length} methods, ${sig.fields.length} fields`, success: true });
107
+ let constructors = sig.constructors;
108
+ let methods = sig.methods;
109
+ let fields = sig.fields;
110
+ if (ctx.requestedMapping !== ctx.signatureLookupMapping) {
111
+ try {
112
+ const [ctorResult, methodResult, fieldResult] = await Promise.all([
113
+ svc.remapSignatureMembers(sig.constructors, "method", ctx.version, ctx.signatureLookupMapping, ctx.requestedMapping, ctx.currentSourcePriority, ctx.warnings, ctx.input.projectPath),
114
+ svc.remapSignatureMembers(sig.methods, "method", ctx.version, ctx.signatureLookupMapping, ctx.requestedMapping, ctx.currentSourcePriority, ctx.warnings, ctx.input.projectPath),
115
+ svc.remapSignatureMembers(sig.fields, "field", ctx.version, ctx.signatureLookupMapping, ctx.requestedMapping, ctx.currentSourcePriority, ctx.warnings, ctx.input.projectPath)
116
+ ]);
117
+ constructors = ctorResult.members;
118
+ methods = methodResult.members;
119
+ fields = fieldResult.members;
120
+ const targetFailed = new Set();
121
+ for (const n of ctorResult.failedNames)
122
+ targetFailed.add(n);
123
+ for (const n of methodResult.failedNames)
124
+ targetFailed.add(n);
125
+ for (const n of fieldResult.failedNames)
126
+ targetFailed.add(n);
127
+ if (targetFailed.size > 0) {
128
+ ctx.remapFailedMembers.set(target.className, targetFailed);
129
+ ctx.resolutionTrace?.push({ target: target.className, step: "remap", input: `${targetFailed.size} members`, output: "failed", success: false });
130
+ }
131
+ else {
132
+ ctx.resolutionTrace?.push({ target: target.className, step: "remap", input: `${methods.length + fields.length} members`, output: "remapped", success: true });
133
+ }
134
+ }
135
+ catch (remapErr) {
136
+ ctx.warnings.push(`Member remapping failed for "${resolvedClassName}"; falling back to ${ctx.signatureLookupMapping} names. ` +
137
+ `Member names shown may be in the ${ctx.signatureLookupMapping} runtime namespace.`);
138
+ ctx.mappingApplied = ctx.signatureLookupMapping;
139
+ ctx.wholeRemapFailedTargets.add(target.className);
140
+ ctx.resolutionTrace?.push({
141
+ target: target.className,
142
+ step: "remap",
143
+ input: resolvedClassName,
144
+ output: `${ctx.signatureLookupMapping} fallback`,
145
+ success: false,
146
+ detail: remapErr instanceof Error ? remapErr.message : String(remapErr)
147
+ });
148
+ }
149
+ }
150
+ ctx.targetMembers.set(target.className, {
151
+ className: target.className,
152
+ constructors,
153
+ methods,
154
+ fields
155
+ });
156
+ }
157
+ catch (sigErr) {
158
+ ctx.warnings.push(`Could not load signature for class "${resolvedClassName}" (obfuscated: "${obfuscatedName}").`);
159
+ ctx.resolutionTrace?.push({ target: target.className, step: "signature", input: obfuscatedName, output: "CLASS_NOT_FOUND", success: false, detail: sigErr instanceof Error ? sigErr.message : String(sigErr) });
160
+ try {
161
+ const existenceCheck = await svc.mappingService.checkSymbolExists({
162
+ version: ctx.version, kind: "class", name: resolvedClassName,
163
+ sourceMapping: ctx.requestedMapping, nameMode: "auto", sourcePriority: ctx.currentSourcePriority
164
+ });
165
+ if (existenceCheck.resolved) {
166
+ ctx.symbolExistsButSignatureFailed.add(target.className);
167
+ ctx.resolutionTrace?.push({ target: target.className, step: "fallback-check", input: resolvedClassName, output: "exists in mapping graph", success: true });
168
+ }
169
+ else {
170
+ ctx.resolutionTrace?.push({ target: target.className, step: "fallback-check", input: resolvedClassName, output: "not found", success: false });
171
+ }
172
+ }
173
+ catch {
174
+ ctx.signatureFailedTargets.add(target.className);
175
+ ctx.resolutionTrace?.push({ target: target.className, step: "fallback-check", input: resolvedClassName, output: "check failed", success: false });
176
+ }
177
+ }
178
+ const targetElapsed = performance.now() - targetStartedAt;
179
+ const hadToolIssue = ctx.mappingFailedTargets.has(target.className) ||
180
+ ctx.signatureFailedTargets.has(target.className) ||
181
+ ctx.symbolExistsButSignatureFailed.has(target.className) ||
182
+ ctx.remapFailedMembers.has(target.className) ||
183
+ ctx.wholeRemapFailedTargets.has(target.className);
184
+ const completedOutcome = hadToolIssue
185
+ ? {
186
+ targetClass: target.className,
187
+ status: "tool-issue",
188
+ elapsedMs: targetElapsed,
189
+ reason: ctx.signatureFailedTargets.has(target.className)
190
+ ? "signature-load-failed"
191
+ : ctx.symbolExistsButSignatureFailed.has(target.className)
192
+ ? "signature-load-failed-symbol-exists"
193
+ : ctx.mappingFailedTargets.has(target.className)
194
+ ? "mapping-failed"
195
+ : ctx.wholeRemapFailedTargets.has(target.className)
196
+ ? "member-remap-failed-whole"
197
+ : "member-remap-failed"
198
+ }
199
+ : {
200
+ targetClass: target.className,
201
+ status: "ok",
202
+ elapsedMs: targetElapsed
203
+ };
204
+ if (targetElapsed > ctx.stageBudgets.perTarget) {
205
+ completedOutcome.slowTarget = true;
206
+ completedOutcome.budgetMs = ctx.stageBudgets.perTarget;
207
+ }
208
+ return completedOutcome;
209
+ }
210
+ export async function runTargetLookupStage(svc, ctx) {
211
+ const targetLookupStartedAt = await ctx.enterStage("target-lookup");
212
+ if (ctx.testHooks?.beforeTargetLoop) {
213
+ await ctx.testHooks.beforeTargetLoop();
214
+ }
215
+ const totalTargets = ctx.parsed.targets.length;
216
+ for (let targetIndex = 0; targetIndex < totalTargets; targetIndex++) {
217
+ const stageElapsed = performance.now() - targetLookupStartedAt;
218
+ if (stageElapsed > ctx.stageBudgets.targetLookup) {
219
+ ctx.stageBudgetExhausted = true;
220
+ ctx.nextTargetIndex = targetIndex;
221
+ break;
222
+ }
223
+ const target = ctx.parsed.targets[targetIndex];
224
+ const outcome = await processSingleMixinTarget(svc, ctx, target, targetIndex);
225
+ ctx.targetOutcomes.push(outcome);
226
+ ctx.processedTargetCount += 1;
227
+ }
228
+ if (ctx.stageBudgetExhausted) {
229
+ if (ctx.processedTargetCount === 0) {
230
+ ctx.degradedReason = "stage-budget-pre-target";
231
+ for (const remaining of ctx.parsed.targets) {
232
+ ctx.skippedForValidator.add(remaining.className);
233
+ }
234
+ }
235
+ else {
236
+ ctx.degradedReason = "stage-budget";
237
+ for (let j = ctx.nextTargetIndex; j < totalTargets; j++) {
238
+ const remaining = ctx.parsed.targets[j];
239
+ ctx.deferredTargetClasses.add(remaining.className);
240
+ ctx.skippedForValidator.add(remaining.className);
241
+ ctx.targetOutcomes.push({
242
+ targetClass: remaining.className,
243
+ status: "deferred-budget",
244
+ reason: "stage-budget",
245
+ budgetMs: ctx.stageBudgets.targetLookup
246
+ });
247
+ }
248
+ }
249
+ }
250
+ if (ctx.healthReport) {
251
+ const hasFailures = ctx.signatureFailedTargets.size > 0 ||
252
+ ctx.mappingFailedTargets.size > 0 ||
253
+ ctx.symbolExistsButSignatureFailed.size > 0;
254
+ if (hasFailures && ctx.healthReport.overallHealthy) {
255
+ ctx.healthReport.overallHealthy = false;
256
+ ctx.healthReport.degradations.push(`${ctx.mappingFailedTargets.size} mapping failure(s), ${ctx.signatureFailedTargets.size} signature failure(s), ${ctx.symbolExistsButSignatureFailed.size} partial validation target(s).`);
257
+ }
258
+ }
259
+ }
260
+ //# sourceMappingURL=target-lookup.js.map
@@ -0,0 +1,72 @@
1
+ import type { ParsedMixin } from "../../mixin-parser.js";
2
+ import type { MappingHealthReport, MixinValidationProvenance, MixinStageBudgets, ResolvedTargetMembers, TargetOutcome as MixinTargetOutcome } from "../../mixin-validator.js";
3
+ import type { ResolveArtifactOutput, ValidateMixinOptions } from "../../source-service.js";
4
+ import type { StageEmitter } from "../../stage-emitter.js";
5
+ import type { ArtifactScope, MappingSourcePriority, SourceMapping } from "../../types.js";
6
+ import type { ValidateMixinSingleInput } from "../validate-mixin.js";
7
+ /**
8
+ * Diagnostic tag attached to every AppError thrown out of validate-mixin.
9
+ * - "input-validation": required field missing or sourcePath unreadable
10
+ * - "resolve": jar / artifact resolution
11
+ * - "mapping-health": mapping infrastructure probe
12
+ * - "parse": parseMixinSource failure
13
+ * - "target-lookup": per-target symbol/signature/remap loop
14
+ */
15
+ export type ValidateMixinStage = "input-validation" | "resolve" | "mapping-health" | "parse" | "target-lookup";
16
+ export type MixinPipelineScopeFallback = {
17
+ requested: string;
18
+ applied: string;
19
+ reason: string;
20
+ };
21
+ export interface MutableMixinPipelineContext {
22
+ readonly input: ValidateMixinSingleInput;
23
+ readonly source: string;
24
+ readonly requestedScope: ArtifactScope;
25
+ readonly currentSourcePriority: MappingSourcePriority;
26
+ readonly initialSourcePriority: MappingSourcePriority;
27
+ readonly stageEmitter: StageEmitter;
28
+ readonly stageBudgets: MixinStageBudgets;
29
+ readonly testHooks: ValidateMixinOptions["__testHooks"];
30
+ readonly onStage: (stage: ValidateMixinStage) => void;
31
+ warnings: string[];
32
+ version: string;
33
+ mappingAutoDetected: boolean;
34
+ requestedMapping: SourceMapping;
35
+ mappingApplied: SourceMapping;
36
+ jarPath: string;
37
+ resolvedArtifact?: ResolveArtifactOutput;
38
+ signatureLookupMapping: SourceMapping;
39
+ scopeFallback?: MixinPipelineScopeFallback;
40
+ healthReport?: MappingHealthReport;
41
+ parsed: ParsedMixin;
42
+ targetOutcomes: MixinTargetOutcome[];
43
+ degradedReason?: "stage-budget" | "stage-budget-pre-target";
44
+ deferredTargetClasses: Set<string>;
45
+ targetMembers: Map<string, ResolvedTargetMembers>;
46
+ mappingFailedTargets: Set<string>;
47
+ remapFailedMembers: Map<string, Set<string>>;
48
+ wholeRemapFailedTargets: Set<string>;
49
+ signatureFailedTargets: Set<string>;
50
+ symbolExistsButSignatureFailed: Set<string>;
51
+ resolutionTrace?: NonNullable<MixinValidationProvenance["resolutionTrace"]>;
52
+ processedTargetCount: number;
53
+ stageBudgetExhausted: boolean;
54
+ nextTargetIndex: number;
55
+ skippedForValidator: Set<string>;
56
+ enterStage(stage: ValidateMixinStage): Promise<number>;
57
+ checkPreParseBudget(stage: ValidateMixinStage, startedAt: number, budgetMs: number): void;
58
+ }
59
+ export type MixinPipelineSeed = {
60
+ input: ValidateMixinSingleInput;
61
+ version: string;
62
+ source: string;
63
+ requestedScope: ArtifactScope;
64
+ currentSourcePriority: MappingSourcePriority;
65
+ initialSourcePriority: MappingSourcePriority;
66
+ stageEmitter: StageEmitter;
67
+ stageBudgets: MixinStageBudgets;
68
+ testHooks: ValidateMixinOptions["__testHooks"];
69
+ onStage: (stage: ValidateMixinStage) => void;
70
+ };
71
+ export declare function createMixinPipelineContext(seed: MixinPipelineSeed): MutableMixinPipelineContext;
72
+ export declare function normalizeMapping(mapping: SourceMapping | undefined): SourceMapping;
@@ -0,0 +1,93 @@
1
+ import { performance } from "node:perf_hooks";
2
+ import { buildSuggestedCall } from "../../build-suggested-call.js";
3
+ import { ERROR_CODES, createError } from "../../errors.js";
4
+ const EMPTY_PARSED = {
5
+ className: "",
6
+ targets: [],
7
+ imports: new Map(),
8
+ injections: [],
9
+ shadows: [],
10
+ accessors: [],
11
+ parseWarnings: []
12
+ };
13
+ export function createMixinPipelineContext(seed) {
14
+ const ctx = {
15
+ input: seed.input,
16
+ source: seed.source,
17
+ requestedScope: seed.requestedScope,
18
+ currentSourcePriority: seed.currentSourcePriority,
19
+ initialSourcePriority: seed.initialSourcePriority,
20
+ stageEmitter: seed.stageEmitter,
21
+ stageBudgets: seed.stageBudgets,
22
+ testHooks: seed.testHooks,
23
+ onStage: seed.onStage,
24
+ warnings: [],
25
+ version: seed.version,
26
+ mappingAutoDetected: false,
27
+ requestedMapping: "obfuscated",
28
+ mappingApplied: "obfuscated",
29
+ jarPath: "",
30
+ resolvedArtifact: undefined,
31
+ signatureLookupMapping: "obfuscated",
32
+ scopeFallback: undefined,
33
+ healthReport: undefined,
34
+ parsed: EMPTY_PARSED,
35
+ targetOutcomes: [],
36
+ degradedReason: undefined,
37
+ deferredTargetClasses: new Set(),
38
+ targetMembers: new Map(),
39
+ mappingFailedTargets: new Set(),
40
+ remapFailedMembers: new Map(),
41
+ wholeRemapFailedTargets: new Set(),
42
+ signatureFailedTargets: new Set(),
43
+ symbolExistsButSignatureFailed: new Set(),
44
+ resolutionTrace: seed.input.explain ? [] : undefined,
45
+ processedTargetCount: 0,
46
+ stageBudgetExhausted: false,
47
+ nextTargetIndex: 0,
48
+ skippedForValidator: new Set(),
49
+ enterStage: async (stage) => {
50
+ ctx.onStage(stage);
51
+ const startedAt = performance.now();
52
+ await ctx.stageEmitter(stage);
53
+ return startedAt;
54
+ },
55
+ checkPreParseBudget: (stage, stageStartedAt, budgetMs) => {
56
+ const elapsed = performance.now() - stageStartedAt;
57
+ if (elapsed > budgetMs) {
58
+ throw createError({
59
+ code: ERROR_CODES.STAGE_BUDGET_PRE_PARSE,
60
+ message: `Stage ${stage} exhausted budget before parse completed.`,
61
+ details: {
62
+ failedStage: stage,
63
+ stageBudgetExhausted: true,
64
+ budgetMs,
65
+ elapsedMs: elapsed
66
+ }
67
+ });
68
+ }
69
+ }
70
+ };
71
+ return ctx;
72
+ }
73
+ export function normalizeMapping(mapping) {
74
+ if (mapping == null) {
75
+ return "obfuscated";
76
+ }
77
+ if (mapping === "obfuscated" ||
78
+ mapping === "mojang" ||
79
+ mapping === "intermediary" ||
80
+ mapping === "yarn") {
81
+ return mapping;
82
+ }
83
+ throw createError({
84
+ code: ERROR_CODES.MAPPING_UNAVAILABLE,
85
+ message: `Unsupported mapping "${mapping}".`,
86
+ details: {
87
+ mapping,
88
+ nextAction: "Try mapping=obfuscated which is always available.",
89
+ ...buildSuggestedCall({ tool: "resolve-artifact", params: { mapping: "obfuscated" } })
90
+ }
91
+ });
92
+ }
93
+ //# sourceMappingURL=pipeline-context.js.map
@@ -0,0 +1,22 @@
1
+ import { type MixinValidationResult, type MixinStageBudgets } from "../mixin-validator.js";
2
+ import type { SourceService } from "../source-service.js";
3
+ import type { ValidateMixinInput, ValidateMixinOptions, ValidateMixinOutput } from "../source-service.js";
4
+ import { type StageEmitter } from "../stage-emitter.js";
5
+ import type { MappingSourcePriority } from "../types.js";
6
+ import type { FindMappingOutput as MappingFindMappingOutput } from "../mapping-service.js";
7
+ export type ValidateMixinSingleInput = Omit<ValidateMixinInput, "input"> & {
8
+ source?: string;
9
+ sourcePath?: string;
10
+ batchCaches?: {
11
+ classMappings: Map<string, Promise<MappingFindMappingOutput>>;
12
+ };
13
+ retryState?: {
14
+ attempted: boolean;
15
+ initialSourcePriority: MappingSourcePriority;
16
+ };
17
+ stageEmitter?: StageEmitter;
18
+ __stageBudgets?: Partial<MixinStageBudgets>;
19
+ __testHooks?: ValidateMixinOptions["__testHooks"];
20
+ };
21
+ export declare function validateMixin(svc: SourceService, input: ValidateMixinInput, options?: ValidateMixinOptions): Promise<ValidateMixinOutput>;
22
+ export declare function validateMixinSingle(svc: SourceService, input: ValidateMixinSingleInput): Promise<MixinValidationResult>;