@adhisang/minecraft-modding-mcp 4.2.1 → 5.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 +33 -0
- package/README.md +5 -4
- package/dist/access-transformer-parser.d.ts +2 -1
- package/dist/access-transformer-parser.js +10 -1
- package/dist/build-suggested-call.js +31 -10
- package/dist/cache-registry.d.ts +8 -0
- package/dist/cache-registry.js +15 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +4 -0
- package/dist/entry-tools/analyze-mod-service.d.ts +24 -24
- package/dist/entry-tools/analyze-symbol-service.d.ts +57 -22
- package/dist/entry-tools/analyze-symbol-service.js +124 -28
- package/dist/entry-tools/batch-class-members-service.d.ts +3 -1
- package/dist/entry-tools/batch-class-members-service.js +6 -6
- package/dist/entry-tools/batch-class-source-service.d.ts +3 -1
- package/dist/entry-tools/batch-class-source-service.js +5 -6
- package/dist/entry-tools/batch-mappings-service.d.ts +3 -1
- package/dist/entry-tools/batch-mappings-service.js +4 -5
- package/dist/entry-tools/batch-symbol-exists-service.d.ts +3 -1
- package/dist/entry-tools/batch-symbol-exists-service.js +4 -5
- package/dist/entry-tools/compare-minecraft-service.d.ts +10 -10
- package/dist/entry-tools/entry-tool-schema.d.ts +1 -1
- package/dist/entry-tools/inspect-minecraft/handlers/artifact.js +1 -3
- package/dist/entry-tools/inspect-minecraft/handlers/class-members.js +2 -2
- package/dist/entry-tools/inspect-minecraft/handlers/class-overview.js +0 -5
- package/dist/entry-tools/inspect-minecraft/handlers/class-source.js +0 -1
- package/dist/entry-tools/inspect-minecraft/handlers/file.js +0 -1
- package/dist/entry-tools/inspect-minecraft/handlers/list-files.js +0 -1
- package/dist/entry-tools/inspect-minecraft/handlers/search.d.ts +8 -0
- package/dist/entry-tools/inspect-minecraft/handlers/search.js +13 -2
- package/dist/entry-tools/inspect-minecraft/handlers/versions.d.ts +1 -1
- package/dist/entry-tools/inspect-minecraft/handlers/versions.js +1 -1
- package/dist/entry-tools/inspect-minecraft/internal.d.ts +90 -89
- package/dist/entry-tools/inspect-minecraft/internal.js +30 -14
- package/dist/entry-tools/inspect-minecraft-service.d.ts +218 -218
- package/dist/entry-tools/inspect-minecraft-service.js +1 -1
- package/dist/entry-tools/manage-cache-service.d.ts +4 -4
- package/dist/entry-tools/response-contract.d.ts +1 -1
- package/dist/entry-tools/response-contract.js +1 -0
- package/dist/entry-tools/validate-project/cases/mixin.js +2 -1
- package/dist/entry-tools/validate-project/cases/project-summary.js +5 -3
- package/dist/entry-tools/validate-project-service.d.ts +42 -36
- package/dist/entry-tools/validate-project-service.js +3 -1
- package/dist/entry-tools/verify-mixin-target-service.d.ts +30 -0
- package/dist/entry-tools/verify-mixin-target-service.js +113 -22
- package/dist/error-mapping.d.ts +51 -0
- package/dist/error-mapping.js +157 -2
- package/dist/index.js +138 -71
- package/dist/mapping/internal-types.d.ts +7 -0
- package/dist/mapping/lookup.d.ts +1 -1
- package/dist/mapping/lookup.js +7 -1
- package/dist/mapping/types.d.ts +6 -0
- package/dist/mapping-service.d.ts +26 -2
- package/dist/mapping-service.js +178 -36
- package/dist/mcp-helpers.d.ts +1 -0
- package/dist/mcp-helpers.js +25 -3
- package/dist/minecraft-explorer-service.js +24 -11
- package/dist/mixin/access-validators.js +33 -1
- package/dist/mixin/annotation-validators.js +53 -7
- package/dist/mixin/parsed-validator.js +2 -2
- package/dist/mixin-parser.js +48 -4
- package/dist/mod-decompile-service.js +2 -1
- package/dist/mod-remap-service.d.ts +20 -1
- package/dist/mod-remap-service.js +95 -40
- package/dist/nbt/java-nbt-codec.js +6 -0
- package/dist/observability.d.ts +6 -0
- package/dist/observability.js +10 -0
- package/dist/page-cursor.d.ts +17 -0
- package/dist/page-cursor.js +0 -0
- package/dist/registry-service.js +25 -1
- package/dist/resources.js +45 -9
- package/dist/response-utils.d.ts +29 -4
- package/dist/response-utils.js +95 -5
- package/dist/source/access-validate.js +12 -2
- package/dist/source/artifact-resolver.js +1 -1
- package/dist/source/class-source/members-builder.d.ts +44 -1
- package/dist/source/class-source/members-builder.js +51 -4
- package/dist/source/class-source/snippet-builder.d.ts +13 -0
- package/dist/source/class-source/snippet-builder.js +48 -4
- package/dist/source/class-source-helpers.js +67 -11
- package/dist/source/class-source.js +97 -20
- package/dist/source/indexer.js +5 -2
- package/dist/source/search.d.ts +1 -1
- package/dist/source/search.js +94 -22
- package/dist/source/validate-mixin.d.ts +2 -1
- package/dist/source/validate-mixin.js +45 -4
- package/dist/source/workspace-target.js +15 -9
- package/dist/source-jar-reader.d.ts +54 -1
- package/dist/source-jar-reader.js +121 -10
- package/dist/source-service.d.ts +28 -7
- package/dist/storage/files-repo.d.ts +12 -0
- package/dist/storage/files-repo.js +24 -0
- package/dist/storage/symbols-repo.d.ts +6 -0
- package/dist/storage/symbols-repo.js +6 -0
- package/dist/symbols/symbol-extractor.js +35 -6
- package/dist/text-truncate.d.ts +7 -0
- package/dist/text-truncate.js +21 -0
- package/dist/tiny-remapper-resolver.js +10 -0
- package/dist/tool-contract-manifest.js +2 -2
- package/dist/tool-execution-gate.js +12 -1
- package/dist/tool-guidance.d.ts +4 -1
- package/dist/tool-guidance.js +37 -12
- package/dist/tool-schemas.d.ts +559 -494
- package/dist/tool-schemas.js +99 -63
- package/dist/types.d.ts +1 -0
- package/dist/version-diff-service.js +5 -0
- package/dist/version-service.d.ts +3 -0
- package/dist/version-service.js +18 -2
- package/dist/warning-details.d.ts +18 -0
- package/dist/warning-details.js +63 -0
- package/docs/README-ja.md +2 -2
- package/docs/examples.md +26 -2
- package/docs/tool-reference.md +22 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { ZodError, z } from "zod";
|
|
|
5
5
|
import { CompatStdioServerTransport } from "./compat-stdio-transport.js";
|
|
6
6
|
import { objectResult } from "./mcp-helpers.js";
|
|
7
7
|
import { prepareToolInput } from "./tool-input.js";
|
|
8
|
-
import {
|
|
8
|
+
import { DETAIL_ENABLED_TOOL_NAMES, DEFAULT_DETAIL_BY_TOOL, projectByDetail } from "./response-utils.js";
|
|
9
9
|
import { loadConfig } from "./config.js";
|
|
10
10
|
import { createError, ERROR_CODES, isAppError } from "./errors.js";
|
|
11
11
|
import { log } from "./logger.js";
|
|
@@ -15,6 +15,7 @@ import { remapModJar } from "./mod-remap-service.js";
|
|
|
15
15
|
import { registerResources } from "./resources.js";
|
|
16
16
|
import { SourceService } from "./source-service.js";
|
|
17
17
|
import { ToolExecutionGate } from "./tool-execution-gate.js";
|
|
18
|
+
import { classifyWarnings } from "./warning-details.js";
|
|
18
19
|
import { WorkspaceMappingService } from "./workspace-mapping-service.js";
|
|
19
20
|
import { InspectMinecraftService, inspectMinecraftSchema, inspectMinecraftShape } from "./entry-tools/inspect-minecraft-service.js";
|
|
20
21
|
import { AnalyzeSymbolService, analyzeSymbolSchema, analyzeSymbolShape } from "./entry-tools/analyze-symbol-service.js";
|
|
@@ -55,6 +56,13 @@ const ENTRY_TOOL_NAMES = new Set([
|
|
|
55
56
|
"validate-project",
|
|
56
57
|
"manage-cache"
|
|
57
58
|
]);
|
|
59
|
+
// Batch tools self-project per entry but report the applied detail at the top level.
|
|
60
|
+
const BATCH_DETAIL_TOOL_NAMES = new Set([
|
|
61
|
+
"batch-class-source",
|
|
62
|
+
"batch-class-members",
|
|
63
|
+
"batch-symbol-exists",
|
|
64
|
+
"batch-mappings"
|
|
65
|
+
]);
|
|
58
66
|
const heavyToolExecutionGate = new ToolExecutionGate({ maxConcurrent: 1, maxQueue: 2 });
|
|
59
67
|
function getServerVersionFromPackageJson() {
|
|
60
68
|
try {
|
|
@@ -77,6 +85,13 @@ const server = new McpServer({
|
|
|
77
85
|
// The SDK validates tool args before invoking handlers and returns generic InvalidParams text.
|
|
78
86
|
// Bypass that layer so runTool() remains the single source of truth for validation and error envelopes.
|
|
79
87
|
server.validateToolInput = async (_tool, args) => args;
|
|
88
|
+
// Low-level/expert tools duplicate capability that the six entry tools expose
|
|
89
|
+
// in a single resolve+fetch call. expertTool() registers them exactly like
|
|
90
|
+
// server.tool() but appends a note steering agents to the entry tools first.
|
|
91
|
+
// Entry tools, batch tools, and the NBT/runtime utilities (which have no entry
|
|
92
|
+
// equivalent) keep their plain descriptions via server.tool().
|
|
93
|
+
const EXPERT_TOOL_NOTE = " Expert/follow-up tool: prefer the entry tools (inspect-minecraft, analyze-symbol, compare-minecraft, analyze-mod, validate-project) first; reach for this only for the narrow operation it names.";
|
|
94
|
+
const expertTool = ((name, description, ...rest) => server.tool(name, description + EXPERT_TOOL_NOTE, ...rest));
|
|
80
95
|
const config = loadConfig();
|
|
81
96
|
const nbtLimits = {
|
|
82
97
|
maxInputBytes: config.maxNbtInputBytes,
|
|
@@ -176,10 +191,32 @@ const verifyMixinTargetService = new VerifyMixinTargetService({
|
|
|
176
191
|
artifactId: output.artifactId,
|
|
177
192
|
mappingApplied: output.mappingApplied,
|
|
178
193
|
binaryJarPath: output.binaryJarPath,
|
|
194
|
+
version: output.version,
|
|
179
195
|
provenance: output.provenance,
|
|
180
196
|
warnings: output.warnings
|
|
181
197
|
};
|
|
182
198
|
},
|
|
199
|
+
findMapping: async (input) => {
|
|
200
|
+
const output = await sourceService.findMapping({
|
|
201
|
+
version: input.version,
|
|
202
|
+
kind: input.kind,
|
|
203
|
+
name: input.name,
|
|
204
|
+
owner: input.owner,
|
|
205
|
+
descriptor: input.descriptor,
|
|
206
|
+
sourceMapping: input.sourceMapping,
|
|
207
|
+
targetMapping: input.targetMapping
|
|
208
|
+
});
|
|
209
|
+
return {
|
|
210
|
+
resolved: output.resolved,
|
|
211
|
+
resolvedSymbol: output.resolvedSymbol
|
|
212
|
+
? {
|
|
213
|
+
name: output.resolvedSymbol.name,
|
|
214
|
+
owner: output.resolvedSymbol.owner,
|
|
215
|
+
descriptor: output.resolvedSymbol.descriptor
|
|
216
|
+
}
|
|
217
|
+
: undefined
|
|
218
|
+
};
|
|
219
|
+
},
|
|
183
220
|
getSignature: (input) => sourceService.explorerService.getSignature(input)
|
|
184
221
|
});
|
|
185
222
|
const batchClassSourceService = new BatchClassSourceService({
|
|
@@ -226,11 +263,10 @@ function buildRequestId() {
|
|
|
226
263
|
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
227
264
|
}
|
|
228
265
|
function normalizeSourceLookupTarget(target) {
|
|
229
|
-
if (target.
|
|
266
|
+
if (target.kind === "artifact") {
|
|
230
267
|
return { artifactId: target.artifactId };
|
|
231
268
|
}
|
|
232
|
-
|
|
233
|
-
return { target: rest };
|
|
269
|
+
return { target: target };
|
|
234
270
|
}
|
|
235
271
|
function parseClassApiKinds(value) {
|
|
236
272
|
if (value == null) {
|
|
@@ -270,6 +306,33 @@ function splitWarnings(data) {
|
|
|
270
306
|
meta
|
|
271
307
|
};
|
|
272
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Read the detail/include response-shape controls from a parsed tool input.
|
|
311
|
+
* Folds the legacy includeProvenance/includeDescriptors flags into the include
|
|
312
|
+
* set as aliases so the migration off `compact` preserves Phase-4 behavior.
|
|
313
|
+
*/
|
|
314
|
+
function readResponseShapeInput(parsedInput) {
|
|
315
|
+
const include = new Set();
|
|
316
|
+
if (parsedInput === null || typeof parsedInput !== "object" || Array.isArray(parsedInput)) {
|
|
317
|
+
return { include };
|
|
318
|
+
}
|
|
319
|
+
const record = parsedInput;
|
|
320
|
+
if (Array.isArray(record.include)) {
|
|
321
|
+
for (const group of record.include) {
|
|
322
|
+
if (typeof group === "string")
|
|
323
|
+
include.add(group);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
if (record.includeProvenance === true)
|
|
327
|
+
include.add("provenance");
|
|
328
|
+
if (record.includeDescriptors === true)
|
|
329
|
+
include.add("descriptors");
|
|
330
|
+
const detail = typeof record.detail === "string" &&
|
|
331
|
+
(record.detail === "summary" || record.detail === "standard" || record.detail === "full")
|
|
332
|
+
? record.detail
|
|
333
|
+
: undefined;
|
|
334
|
+
return { detail, include };
|
|
335
|
+
}
|
|
273
336
|
async function runTool(tool, rawInput, schema, action) {
|
|
274
337
|
const requestId = buildRequestId();
|
|
275
338
|
const startedAt = Date.now();
|
|
@@ -289,6 +352,11 @@ async function runTool(tool, rawInput, schema, action) {
|
|
|
289
352
|
code: "invalid_enum_value"
|
|
290
353
|
})),
|
|
291
354
|
nextAction: `Replace "official" with "obfuscated" in mapping-related fields and retry.`,
|
|
355
|
+
// Route construction through buildSuggestedCall to satisfy the D12
|
|
356
|
+
// invariant (tests/suggested-call-invariant.test.ts): every emitted
|
|
357
|
+
// suggestedCall must be built by the helper. The downstream
|
|
358
|
+
// mapErrorToProblem gate re-validates on emission; that second pass is
|
|
359
|
+
// the intentional, cheap cost of the two complementary safety gates.
|
|
292
360
|
...(suggestedReplacementInput
|
|
293
361
|
? buildSuggestedCall({
|
|
294
362
|
tool,
|
|
@@ -303,44 +371,32 @@ async function runTool(tool, rawInput, schema, action) {
|
|
|
303
371
|
? heavyToolExecutionGate.run(tool, () => action(parsedInput))
|
|
304
372
|
: action(parsedInput));
|
|
305
373
|
const { result, warnings, meta: resultMeta } = splitWarnings(payload);
|
|
306
|
-
|
|
374
|
+
// Expert tools share the entry-tool detail/include response contract (the old
|
|
375
|
+
// per-tool `compact` boolean is gone). projectByDetail reproduces the previous
|
|
376
|
+
// compact defaults byte-identically: resolution tools default detail=summary
|
|
377
|
+
// (old compact:true), source/file tools default detail=standard (old compact:false).
|
|
378
|
+
// The legacy includeProvenance/includeDescriptors flags are folded into the
|
|
379
|
+
// include set as aliases so Phase-4 behavior is preserved.
|
|
380
|
+
const shapeInput = readResponseShapeInput(parsedInput);
|
|
381
|
+
const effectiveDetail = ENTRY_TOOL_NAMES.has(tool)
|
|
382
|
+
? (shapeInput.detail ?? "summary")
|
|
383
|
+
: (shapeInput.detail ?? DEFAULT_DETAIL_BY_TOOL[tool] ?? "summary");
|
|
307
384
|
let projectedResult = result;
|
|
308
|
-
if (
|
|
309
|
-
|
|
310
|
-
projectedResult = compactArtifactResponse(projectedResult);
|
|
311
|
-
}
|
|
312
|
-
if (COMPACT_MAPPING_TOOL_NAMES.has(tool)) {
|
|
313
|
-
projectedResult = compactMappingResponse(projectedResult);
|
|
314
|
-
}
|
|
315
|
-
if (COMPACT_SOURCE_TOOL_NAMES.has(tool)) {
|
|
316
|
-
projectedResult = compactSourceResponse(projectedResult);
|
|
317
|
-
}
|
|
318
|
-
if (COMPACT_MEMBERS_TOOL_NAMES.has(tool)) {
|
|
319
|
-
projectedResult = compactMembersResponse(projectedResult);
|
|
320
|
-
}
|
|
321
|
-
if (COMPACT_LIGHT_TOOL_NAMES.has(tool)) {
|
|
322
|
-
projectedResult = compactLightResponse(projectedResult);
|
|
323
|
-
}
|
|
324
|
-
projectedResult = compactResponse(projectedResult, TOOL_PRESERVE_PAYLOAD_KEYS[tool]);
|
|
385
|
+
if (DETAIL_ENABLED_TOOL_NAMES.has(tool)) {
|
|
386
|
+
projectedResult = projectByDetail(tool, projectedResult, effectiveDetail, shapeInput.include);
|
|
325
387
|
}
|
|
326
|
-
|
|
388
|
+
// Entry, expert, and batch tools all report the applied detail/include shape in meta.
|
|
389
|
+
const entryMeta = ENTRY_TOOL_NAMES.has(tool) ||
|
|
390
|
+
DETAIL_ENABLED_TOOL_NAMES.has(tool) ||
|
|
391
|
+
BATCH_DETAIL_TOOL_NAMES.has(tool)
|
|
327
392
|
? buildEntryToolMeta({
|
|
328
|
-
detail:
|
|
329
|
-
|
|
330
|
-
!Array.isArray(normalizedInput) &&
|
|
331
|
-
typeof normalizedInput.detail === "string"
|
|
332
|
-
? normalizedInput.detail ?? "summary"
|
|
333
|
-
: "summary",
|
|
334
|
-
include: normalizedInput &&
|
|
335
|
-
typeof normalizedInput === "object" &&
|
|
336
|
-
!Array.isArray(normalizedInput) &&
|
|
337
|
-
Array.isArray(normalizedInput.include)
|
|
338
|
-
? normalizedInput.include
|
|
339
|
-
: undefined
|
|
393
|
+
detail: effectiveDetail,
|
|
394
|
+
include: shapeInput.include.size > 0 ? [...shapeInput.include] : undefined
|
|
340
395
|
})
|
|
341
396
|
: undefined;
|
|
342
397
|
const durationMs = Date.now() - startedAt;
|
|
343
398
|
sourceService.recordToolCall(tool, durationMs);
|
|
399
|
+
const warningDetails = classifyWarnings(warnings);
|
|
344
400
|
return objectResult({
|
|
345
401
|
result: projectedResult,
|
|
346
402
|
meta: {
|
|
@@ -349,7 +405,8 @@ async function runTool(tool, rawInput, schema, action) {
|
|
|
349
405
|
requestId,
|
|
350
406
|
tool,
|
|
351
407
|
durationMs,
|
|
352
|
-
warnings
|
|
408
|
+
warnings,
|
|
409
|
+
...(warningDetails.length > 0 ? { warningDetails } : {})
|
|
353
410
|
}
|
|
354
411
|
});
|
|
355
412
|
}
|
|
@@ -403,14 +460,14 @@ async function runTool(tool, rawInput, schema, action) {
|
|
|
403
460
|
}, { isError: true });
|
|
404
461
|
}
|
|
405
462
|
}
|
|
406
|
-
|
|
463
|
+
expertTool("list-versions", "List available Minecraft versions from Mojang manifest and locally cached version jars.", listVersionsShape, { readOnlyHint: true }, async (args) => runTool("list-versions", args, listVersionsSchema, async (input) => sourceService.listVersions({
|
|
407
464
|
includeSnapshots: input.includeSnapshots,
|
|
408
465
|
limit: input.limit
|
|
409
466
|
})));
|
|
410
467
|
registerToolSchema("list-versions", listVersionsSchema);
|
|
411
468
|
server.tool("inspect-minecraft", "Top-level workflow tool for version discovery, artifact resolution, class inspection, source search, file reads, and file listings.", inspectMinecraftShape, { readOnlyHint: true }, async (args) => runTool("inspect-minecraft", args, inspectMinecraftSchema, async (input) => inspectMinecraftService.execute(input)));
|
|
412
469
|
registerToolSchema("inspect-minecraft", inspectMinecraftSchema);
|
|
413
|
-
server.tool("analyze-symbol", "Top-level workflow tool for symbol existence, mapping, lifecycle, workspace analysis, and API overview.", analyzeSymbolShape, { readOnlyHint: true }, async (args) => runTool("analyze-symbol", args, analyzeSymbolSchema, async (input) => analyzeSymbolService.execute(input)));
|
|
470
|
+
server.tool("analyze-symbol", "Top-level workflow tool for symbol existence, mapping, lifecycle (with fromVersion/toVersion/maxVersions/includeTimeline range controls), workspace analysis, and API overview. subject.kind accepts 'symbol' to auto-detect class/field/method from the selector (inferred kind is returned as a warning).", analyzeSymbolShape, { readOnlyHint: true }, async (args) => runTool("analyze-symbol", args, analyzeSymbolSchema, async (input) => analyzeSymbolService.execute(input)));
|
|
414
471
|
registerToolSchema("analyze-symbol", analyzeSymbolSchema);
|
|
415
472
|
server.tool("compare-minecraft", "Top-level workflow tool for version comparisons, class diffs, registry diffs, and migration overviews.", compareMinecraftShape, { readOnlyHint: true }, async (args) => runTool("compare-minecraft", args, compareMinecraftSchema, async (input) => compareMinecraftService.execute(input)));
|
|
416
473
|
registerToolSchema("compare-minecraft", compareMinecraftSchema);
|
|
@@ -428,6 +485,7 @@ if (!VERIFY_MIXIN_TARGET_OFF) {
|
|
|
428
485
|
member: input.member,
|
|
429
486
|
mixinMemberName: input.mixinMemberName,
|
|
430
487
|
mapping: input.mapping,
|
|
488
|
+
autoRemap: input.autoRemap,
|
|
431
489
|
sourcePriority: input.sourcePriority,
|
|
432
490
|
projectPath: input.projectPath,
|
|
433
491
|
gradleUserHome: input.gradleUserHome,
|
|
@@ -439,7 +497,7 @@ if (!VERIFY_MIXIN_TARGET_OFF) {
|
|
|
439
497
|
registerToolSchema("verify-mixin-target", verifyMixinTargetSchema);
|
|
440
498
|
}
|
|
441
499
|
if (!BATCH_TOOLS_OFF) {
|
|
442
|
-
server.tool("batch-class-source", "Batch lookup: read source for many classes in one call, sharing a single resolved artifact. Returns per-entry { status, result?, error? } plus aggregate summary. Per-entry retry suggestions point at get-class-source.", batchClassSourceShape, { readOnlyHint:
|
|
500
|
+
server.tool("batch-class-source", "Batch lookup: read source for many classes in one call, sharing a single resolved artifact. Returns per-entry { status, result?, error? } plus aggregate summary. Per-entry retry suggestions point at get-class-source. Not read-only: per-entry outputFile writes source files to disk.", batchClassSourceShape, { readOnlyHint: false }, async (args) => runTool("batch-class-source", args, batchClassSourceSchema, async (input) => batchClassSourceService.execute(input)));
|
|
443
501
|
registerToolSchema("batch-class-source", batchClassSourceSchema);
|
|
444
502
|
server.tool("batch-class-members", "Batch lookup: list members for many classes in one call, sharing a single resolved artifact. Returns per-entry { status, result?, error? } plus aggregate summary. Per-entry retry suggestions point at get-class-members.", batchClassMembersShape, { readOnlyHint: true }, async (args) => runTool("batch-class-members", args, batchClassMembersSchema, async (input) => batchClassMembersService.execute(input)));
|
|
445
503
|
registerToolSchema("batch-class-members", batchClassMembersSchema);
|
|
@@ -448,7 +506,7 @@ if (!BATCH_TOOLS_OFF) {
|
|
|
448
506
|
server.tool("batch-mappings", "Batch mapping translation: resolve many symbols across mapping namespaces with one shared Minecraft version. Per-entry retry suggestions point at find-mapping.", batchMappingsShape, { readOnlyHint: true }, async (args) => runTool("batch-mappings", args, batchMappingsSchema, async (input) => batchMappingsService.execute(input)));
|
|
449
507
|
registerToolSchema("batch-mappings", batchMappingsSchema);
|
|
450
508
|
}
|
|
451
|
-
|
|
509
|
+
expertTool("resolve-artifact", "Resolve source artifact from a target object ({ kind, value }) and return artifact metadata. For target.kind=jar, only <basename>-sources.jar is auto-adopted; other adjacent *-sources.jar files are informational.", resolveArtifactShape, { readOnlyHint: true }, async (args) => runTool("resolve-artifact", args, resolveArtifactSchema, async (input) => sourceService.resolveArtifact({
|
|
452
510
|
target: input.target,
|
|
453
511
|
mapping: input.mapping,
|
|
454
512
|
sourcePriority: input.sourcePriority,
|
|
@@ -458,7 +516,8 @@ server.tool("resolve-artifact", "Resolve source artifact from a target object ({
|
|
|
458
516
|
scope: input.scope,
|
|
459
517
|
preferProjectVersion: input.preferProjectVersion,
|
|
460
518
|
strictVersion: input.strictVersion,
|
|
461
|
-
|
|
519
|
+
includeSampleEntries: input.detail === "full" ||
|
|
520
|
+
(Array.isArray(input.include) && input.include.includes("samples"))
|
|
462
521
|
})));
|
|
463
522
|
registerToolSchema("resolve-artifact", resolveArtifactSchema);
|
|
464
523
|
const findClassShape = {
|
|
@@ -467,13 +526,13 @@ const findClassShape = {
|
|
|
467
526
|
limit: optionalPositiveInt.describe("default 20, max 200")
|
|
468
527
|
};
|
|
469
528
|
const findClassSchema = z.object(findClassShape);
|
|
470
|
-
|
|
529
|
+
expertTool("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({
|
|
471
530
|
className: input.className,
|
|
472
531
|
artifactId: input.artifactId,
|
|
473
532
|
limit: input.limit
|
|
474
533
|
})));
|
|
475
534
|
registerToolSchema("find-class", findClassSchema);
|
|
476
|
-
|
|
535
|
+
expertTool("get-class-source", "Get Java source for a class by target ({ kind: 'artifact', artifactId } or { kind: 'version'|'jar'|'coordinate'|'workspace'|'dependency', ... } — same shape as resolve-artifact). To read source text, pass mode=snippet (bounded excerpt) or mode=full (entire source); the default mode=metadata returns a symbol outline only, not the body. Not read-only: outputFile writes the source to disk.", getClassSourceShape, { readOnlyHint: false }, async (args) => runTool("get-class-source", args, getClassSourceSchema, async (input) => {
|
|
477
536
|
const normalizedTarget = normalizeSourceLookupTarget(input.target);
|
|
478
537
|
return sourceService.getClassSource({
|
|
479
538
|
className: input.className,
|
|
@@ -496,7 +555,7 @@ server.tool("get-class-source", "Get Java source for a class by target ({ type:
|
|
|
496
555
|
});
|
|
497
556
|
}));
|
|
498
557
|
registerToolSchema("get-class-source", getClassSourceSchema);
|
|
499
|
-
|
|
558
|
+
expertTool("get-class-members", "Get fields/methods/constructors for one class from binary bytecode by target ({ kind: 'artifact', artifactId } or { kind: 'version'|'jar'|'coordinate'|'workspace'|'dependency', ... } — same shape as resolve-artifact).", getClassMembersShape, { readOnlyHint: true }, async (args) => runTool("get-class-members", args, getClassMembersSchema, async (input) => {
|
|
500
559
|
const normalizedTarget = normalizeSourceLookupTarget(input.target);
|
|
501
560
|
return sourceService.getClassMembers({
|
|
502
561
|
className: input.className,
|
|
@@ -510,15 +569,20 @@ server.tool("get-class-members", "Get fields/methods/constructors for one class
|
|
|
510
569
|
includeInherited: input.includeInherited,
|
|
511
570
|
memberPattern: input.memberPattern,
|
|
512
571
|
maxMembers: input.maxMembers,
|
|
572
|
+
cursor: input.cursor,
|
|
513
573
|
projectPath: input.projectPath,
|
|
514
574
|
gradleUserHome: input.gradleUserHome,
|
|
515
575
|
scope: input.scope,
|
|
516
576
|
preferProjectVersion: input.preferProjectVersion,
|
|
517
|
-
strictVersion: input.strictVersion
|
|
577
|
+
strictVersion: input.strictVersion,
|
|
578
|
+
// includeDescriptors is the documented alias for include:["descriptors"]; honor both
|
|
579
|
+
// (mirror batch-class-members-service / inspect-minecraft class-members handler).
|
|
580
|
+
includeDescriptors: input.includeDescriptors === true ||
|
|
581
|
+
(Array.isArray(input.include) && input.include.includes("descriptors"))
|
|
518
582
|
});
|
|
519
583
|
}));
|
|
520
584
|
registerToolSchema("get-class-members", getClassMembersSchema);
|
|
521
|
-
|
|
585
|
+
expertTool("search-class-source", "Search indexed class source files for one artifact with symbol/text/path intent and compact hit output.", searchClassSourceShape, { readOnlyHint: true }, async (args) => runTool("search-class-source", args, searchClassSourceSchema, async (input) => {
|
|
522
586
|
const scope = input.packagePrefix || input.fileGlob || input.symbolKind
|
|
523
587
|
? {
|
|
524
588
|
packagePrefix: input.packagePrefix,
|
|
@@ -541,20 +605,20 @@ server.tool("search-class-source", "Search indexed class source files for one ar
|
|
|
541
605
|
});
|
|
542
606
|
}));
|
|
543
607
|
registerToolSchema("search-class-source", searchClassSourceSchema);
|
|
544
|
-
|
|
608
|
+
expertTool("get-artifact-file", "Get full source file content by artifactId and file path.", getArtifactFileShape, { readOnlyHint: true }, async (args) => runTool("get-artifact-file", args, getArtifactFileSchema, async (input) => sourceService.getArtifactFile({
|
|
545
609
|
artifactId: input.artifactId,
|
|
546
610
|
filePath: input.filePath,
|
|
547
611
|
maxBytes: input.maxBytes
|
|
548
612
|
})));
|
|
549
613
|
registerToolSchema("get-artifact-file", getArtifactFileSchema);
|
|
550
|
-
|
|
614
|
+
expertTool("list-artifact-files", "List source file paths in an artifact with optional prefix filter and cursor-based pagination.", listArtifactFilesShape, { readOnlyHint: true }, async (args) => runTool("list-artifact-files", args, listArtifactFilesSchema, async (input) => sourceService.listArtifactFiles({
|
|
551
615
|
artifactId: input.artifactId,
|
|
552
616
|
prefix: input.prefix,
|
|
553
617
|
limit: input.limit,
|
|
554
618
|
cursor: input.cursor
|
|
555
619
|
})));
|
|
556
620
|
registerToolSchema("list-artifact-files", listArtifactFilesSchema);
|
|
557
|
-
|
|
621
|
+
expertTool("trace-symbol-lifecycle", "Trace which Minecraft versions contain a specific class method and report first/last seen versions.", traceSymbolLifecycleShape, { readOnlyHint: true }, async (args) => runTool("trace-symbol-lifecycle", args, traceSymbolLifecycleSchema, async (input) => sourceService.traceSymbolLifecycle({
|
|
558
622
|
symbol: input.symbol,
|
|
559
623
|
descriptor: input.descriptor,
|
|
560
624
|
fromVersion: input.fromVersion,
|
|
@@ -567,7 +631,7 @@ server.tool("trace-symbol-lifecycle", "Trace which Minecraft versions contain a
|
|
|
567
631
|
includeTimeline: input.includeTimeline
|
|
568
632
|
})));
|
|
569
633
|
registerToolSchema("trace-symbol-lifecycle", traceSymbolLifecycleSchema);
|
|
570
|
-
|
|
634
|
+
expertTool("diff-class-signatures", "Compare one class signature between two Minecraft versions and report added/removed/modified constructors, methods, and fields.", diffClassSignaturesShape, { readOnlyHint: true }, async (args) => runTool("diff-class-signatures", args, diffClassSignaturesSchema, async (input) => sourceService.diffClassSignatures({
|
|
571
635
|
className: input.className,
|
|
572
636
|
fromVersion: input.fromVersion,
|
|
573
637
|
toVersion: input.toVersion,
|
|
@@ -577,7 +641,7 @@ server.tool("diff-class-signatures", "Compare one class signature between two Mi
|
|
|
577
641
|
includeFullDiff: input.includeFullDiff
|
|
578
642
|
})));
|
|
579
643
|
registerToolSchema("diff-class-signatures", diffClassSignaturesSchema);
|
|
580
|
-
|
|
644
|
+
expertTool("find-mapping", "Find symbol mapping candidates between namespaces using structured symbol inputs for a specific Minecraft version.", findMappingShape, { readOnlyHint: true }, async (args) => runTool("find-mapping", args, findMappingSchema, async (input) => sourceService.findMapping({
|
|
581
645
|
version: input.version,
|
|
582
646
|
kind: input.kind,
|
|
583
647
|
name: input.name,
|
|
@@ -587,12 +651,13 @@ server.tool("find-mapping", "Find symbol mapping candidates between namespaces u
|
|
|
587
651
|
targetMapping: input.targetMapping,
|
|
588
652
|
sourcePriority: input.sourcePriority,
|
|
589
653
|
gradleUserHome: input.gradleUserHome,
|
|
654
|
+
nameMode: input.nameMode,
|
|
590
655
|
signatureMode: input.signatureMode,
|
|
591
656
|
disambiguation: input.disambiguation,
|
|
592
657
|
maxCandidates: input.maxCandidates
|
|
593
658
|
})));
|
|
594
659
|
registerToolSchema("find-mapping", findMappingSchema);
|
|
595
|
-
|
|
660
|
+
expertTool("resolve-method-mapping-exact", "Strict shortcut for find-mapping(kind=method, signatureMode=exact): resolve one method mapping by owner+name+descriptor between namespaces and report resolved/not_found/ambiguous. Stricter than find-mapping's exact mode — it requires a COMPLETE descriptor projection and returns mapping_unavailable when the descriptor's class references cannot all be projected to the target namespace (find-mapping is more lenient there). Use find-mapping kind=method signatureMode=exact unless you specifically need that strict-completeness guarantee.", resolveMethodMappingExactShape, { readOnlyHint: true }, async (args) => runTool("resolve-method-mapping-exact", args, resolveMethodMappingExactSchema, async (input) => sourceService.resolveMethodMappingExact({
|
|
596
661
|
version: input.version,
|
|
597
662
|
name: input.name,
|
|
598
663
|
owner: input.owner,
|
|
@@ -604,17 +669,18 @@ server.tool("resolve-method-mapping-exact", "Resolve one method mapping exactly
|
|
|
604
669
|
maxCandidates: input.maxCandidates
|
|
605
670
|
})));
|
|
606
671
|
registerToolSchema("resolve-method-mapping-exact", resolveMethodMappingExactSchema);
|
|
607
|
-
|
|
672
|
+
expertTool("get-class-api-matrix", "List class/member API rows across obfuscated/mojang/intermediary/yarn mappings for one class and Minecraft version.", getClassApiMatrixShape, { readOnlyHint: true }, async (args) => runTool("get-class-api-matrix", args, getClassApiMatrixSchema, async (input) => sourceService.getClassApiMatrix({
|
|
608
673
|
version: input.version,
|
|
609
674
|
className: input.className,
|
|
610
675
|
classNameMapping: input.classNameMapping,
|
|
611
676
|
includeKinds: parseClassApiKinds(input.includeKinds),
|
|
612
677
|
sourcePriority: input.sourcePriority,
|
|
613
678
|
gradleUserHome: input.gradleUserHome,
|
|
614
|
-
maxRows: input.maxRows
|
|
679
|
+
maxRows: input.maxRows,
|
|
680
|
+
cursor: input.cursor
|
|
615
681
|
})));
|
|
616
682
|
registerToolSchema("get-class-api-matrix", getClassApiMatrixSchema);
|
|
617
|
-
|
|
683
|
+
expertTool("resolve-workspace-symbol", "Resolve class/field/method names as seen at compile time for a workspace by reading Gradle Loom mapping settings.", resolveWorkspaceSymbolShape, { readOnlyHint: true }, async (args) => runTool("resolve-workspace-symbol", args, resolveWorkspaceSymbolSchema, async (input) => sourceService.resolveWorkspaceSymbol({
|
|
618
684
|
projectPath: input.projectPath,
|
|
619
685
|
version: input.version,
|
|
620
686
|
kind: input.kind,
|
|
@@ -627,7 +693,7 @@ server.tool("resolve-workspace-symbol", "Resolve class/field/method names as see
|
|
|
627
693
|
maxCandidates: input.maxCandidates
|
|
628
694
|
})));
|
|
629
695
|
registerToolSchema("resolve-workspace-symbol", resolveWorkspaceSymbolSchema);
|
|
630
|
-
|
|
696
|
+
expertTool("check-symbol-exists", "Check whether a class/field/method symbol exists in a specific mapping namespace for one Minecraft version.", checkSymbolExistsShape, { readOnlyHint: true }, async (args) => runTool("check-symbol-exists", args, checkSymbolExistsSchema, async (input) => sourceService.checkSymbolExists({
|
|
631
697
|
version: input.version,
|
|
632
698
|
kind: input.kind,
|
|
633
699
|
owner: input.owner,
|
|
@@ -641,29 +707,29 @@ server.tool("check-symbol-exists", "Check whether a class/field/method symbol ex
|
|
|
641
707
|
maxCandidates: input.maxCandidates
|
|
642
708
|
})));
|
|
643
709
|
registerToolSchema("check-symbol-exists", checkSymbolExistsSchema);
|
|
644
|
-
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({
|
|
710
|
+
server.tool("nbt-to-json", "Decode Java Edition NBT binary payload (base64) into typed JSON.", nbtToJsonShape, { readOnlyHint: true, openWorldHint: false }, async (args) => runTool("nbt-to-json", args, nbtToJsonSchema, async (input) => Promise.resolve(nbtBase64ToTypedJson({
|
|
645
711
|
nbtBase64: input.nbtBase64,
|
|
646
712
|
compression: input.compression
|
|
647
713
|
}, nbtLimits))));
|
|
648
714
|
registerToolSchema("nbt-to-json", nbtToJsonSchema);
|
|
649
|
-
server.tool("nbt-apply-json-patch", "Apply RFC6902 add/remove/replace/test operations to typed NBT JSON.", nbtApplyJsonPatchShape, { readOnlyHint: true }, async (args) => runTool("nbt-apply-json-patch", args, nbtApplyJsonPatchSchema, async (input) => Promise.resolve(applyNbtJsonPatch({
|
|
715
|
+
server.tool("nbt-apply-json-patch", "Apply RFC6902 add/remove/replace/test operations to typed NBT JSON.", nbtApplyJsonPatchShape, { readOnlyHint: true, openWorldHint: false }, async (args) => runTool("nbt-apply-json-patch", args, nbtApplyJsonPatchSchema, async (input) => Promise.resolve(applyNbtJsonPatch({
|
|
650
716
|
typedJson: input.typedJson,
|
|
651
717
|
patch: input.patch
|
|
652
718
|
}, nbtLimits))));
|
|
653
719
|
registerToolSchema("nbt-apply-json-patch", nbtApplyJsonPatchSchema);
|
|
654
|
-
server.tool("json-to-nbt", "Encode typed NBT JSON to Java Edition NBT binary payload (base64).", jsonToNbtShape, { readOnlyHint: true }, async (args) => runTool("json-to-nbt", args, jsonToNbtSchema, async (input) => Promise.resolve(typedJsonToNbtBase64({
|
|
720
|
+
server.tool("json-to-nbt", "Encode typed NBT JSON to Java Edition NBT binary payload (base64).", jsonToNbtShape, { readOnlyHint: true, openWorldHint: false }, async (args) => runTool("json-to-nbt", args, jsonToNbtSchema, async (input) => Promise.resolve(typedJsonToNbtBase64({
|
|
655
721
|
typedJson: input.typedJson,
|
|
656
722
|
compression: input.compression
|
|
657
723
|
}, nbtLimits))));
|
|
658
724
|
registerToolSchema("json-to-nbt", jsonToNbtSchema);
|
|
659
|
-
|
|
725
|
+
expertTool("index-artifact", "Rebuild indexed files/symbols metadata for an existing artifactId. Does not resolve new artifacts.", indexArtifactShape, { readOnlyHint: false, idempotentHint: true }, async (args) => runTool("index-artifact", args, indexArtifactSchema, async (input) => sourceService.indexArtifact({
|
|
660
726
|
artifactId: input.artifactId,
|
|
661
727
|
force: input.force
|
|
662
728
|
})));
|
|
663
729
|
registerToolSchema("index-artifact", indexArtifactSchema);
|
|
664
|
-
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())));
|
|
730
|
+
server.tool("get-runtime-metrics", "Get runtime service counters and latency snapshots for cache/search/index diagnostics.", { readOnlyHint: true, openWorldHint: false }, async (args) => runTool("get-runtime-metrics", args, emptySchema, async () => Promise.resolve(sourceService.getRuntimeMetrics())));
|
|
665
731
|
registerToolSchema("get-runtime-metrics", emptySchema);
|
|
666
|
-
|
|
732
|
+
expertTool("validate-mixin", "Validate Mixin source against Minecraft bytecode signatures for a given version.", validateMixinShape, { readOnlyHint: true }, async (args, extra) => runTool("validate-mixin", args, validateMixinSchema, async (input) => sourceService.validateMixin({
|
|
667
733
|
input: input.input,
|
|
668
734
|
sourceRoots: input.sourceRoots,
|
|
669
735
|
version: input.version,
|
|
@@ -686,7 +752,7 @@ server.tool("validate-mixin", "Validate Mixin source against Minecraft bytecode
|
|
|
686
752
|
stageEmitter: makeStageEmitter(extra)
|
|
687
753
|
})));
|
|
688
754
|
registerToolSchema("validate-mixin", validateMixinSchema);
|
|
689
|
-
|
|
755
|
+
expertTool("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({
|
|
690
756
|
content: input.content,
|
|
691
757
|
version: input.version,
|
|
692
758
|
mapping: input.mapping,
|
|
@@ -697,7 +763,7 @@ server.tool("validate-access-widener", "Validate Access Widener file entries aga
|
|
|
697
763
|
preferProjectVersion: input.preferProjectVersion
|
|
698
764
|
})));
|
|
699
765
|
registerToolSchema("validate-access-widener", validateAccessWidenerSchema);
|
|
700
|
-
|
|
766
|
+
expertTool("validate-access-transformer", "Validate Access Transformer file entries against Minecraft bytecode signatures for a given version.", validateAccessTransformerShape, { readOnlyHint: true }, async (args) => runTool("validate-access-transformer", args, validateAccessTransformerSchema, async (input) => sourceService.validateAccessTransformer({
|
|
701
767
|
content: input.content,
|
|
702
768
|
version: input.version,
|
|
703
769
|
atNamespace: input.atNamespace,
|
|
@@ -708,7 +774,7 @@ server.tool("validate-access-transformer", "Validate Access Transformer file ent
|
|
|
708
774
|
preferProjectVersion: input.preferProjectVersion
|
|
709
775
|
})));
|
|
710
776
|
registerToolSchema("validate-access-transformer", validateAccessTransformerSchema);
|
|
711
|
-
|
|
777
|
+
expertTool("analyze-mod-jar", "Analyze a Minecraft mod JAR to extract loader type, metadata, entrypoints, mixins, and dependencies.", analyzeModJarShape, { readOnlyHint: true }, async (args) => runTool("analyze-mod-jar", args, analyzeModJarSchema, async (input) => {
|
|
712
778
|
const result = await analyzeModJar(input.jarPath, {
|
|
713
779
|
includeClasses: input.includeClasses ?? false
|
|
714
780
|
});
|
|
@@ -722,7 +788,7 @@ server.tool("get-registry-data", "Get Minecraft registry data (blocks, items, bi
|
|
|
722
788
|
maxEntriesPerRegistry: input.maxEntriesPerRegistry
|
|
723
789
|
})));
|
|
724
790
|
registerToolSchema("get-registry-data", getRegistryDataSchema);
|
|
725
|
-
|
|
791
|
+
expertTool("compare-versions", "Compare two Minecraft versions to find added/removed classes and registry entry changes.", compareVersionsShape, { readOnlyHint: true }, async (args) => runTool("compare-versions", args, compareVersionsSchema, async (input) => sourceService.compareVersions({
|
|
726
792
|
fromVersion: input.fromVersion,
|
|
727
793
|
toVersion: input.toVersion,
|
|
728
794
|
category: input.category,
|
|
@@ -730,14 +796,14 @@ server.tool("compare-versions", "Compare two Minecraft versions to find added/re
|
|
|
730
796
|
maxClassResults: input.maxClassResults
|
|
731
797
|
})));
|
|
732
798
|
registerToolSchema("compare-versions", compareVersionsSchema);
|
|
733
|
-
|
|
799
|
+
expertTool("decompile-mod-jar", "Decompile a Minecraft mod JAR using Vineflower and list available classes, or view a specific class source. Builds on analyze-mod-jar.", decompileModJarShape, { readOnlyHint: true }, async (args) => runTool("decompile-mod-jar", args, decompileModJarSchema, async (input) => sourceService.decompileModJar({
|
|
734
800
|
jarPath: input.jarPath,
|
|
735
801
|
className: input.className,
|
|
736
802
|
includeFiles: input.includeFiles,
|
|
737
803
|
maxFiles: input.maxFiles
|
|
738
804
|
})));
|
|
739
805
|
registerToolSchema("decompile-mod-jar", decompileModJarSchema);
|
|
740
|
-
|
|
806
|
+
expertTool("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. Not read-only: outputFile writes the source to disk.", getModClassSourceShape, { readOnlyHint: false }, async (args) => runTool("get-mod-class-source", args, getModClassSourceSchema, async (input) => sourceService.getModClassSource({
|
|
741
807
|
jarPath: input.jarPath,
|
|
742
808
|
className: input.className,
|
|
743
809
|
maxLines: input.maxLines,
|
|
@@ -745,19 +811,20 @@ server.tool("get-mod-class-source", "Get decompiled source code for a specific c
|
|
|
745
811
|
outputFile: input.outputFile
|
|
746
812
|
})));
|
|
747
813
|
registerToolSchema("get-mod-class-source", getModClassSourceSchema);
|
|
748
|
-
|
|
814
|
+
expertTool("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({
|
|
749
815
|
jarPath: input.jarPath,
|
|
750
816
|
query: input.query,
|
|
751
817
|
searchType: input.searchType,
|
|
752
818
|
limit: input.limit
|
|
753
819
|
})));
|
|
754
820
|
registerToolSchema("search-mod-source", searchModSourceSchema);
|
|
755
|
-
|
|
821
|
+
expertTool("remap-mod-jar", "Remap a Fabric mod JAR from intermediary to yarn/mojang names. Requires Java to be installed.", remapModJarShape, { readOnlyHint: false }, async (args) => runTool("remap-mod-jar", args, remapModJarSchema, async (input) => {
|
|
756
822
|
const result = await remapModJar({
|
|
757
823
|
inputJar: input.inputJar,
|
|
758
824
|
outputJar: input.outputJar,
|
|
759
825
|
mcVersion: input.mcVersion,
|
|
760
|
-
targetMapping: input.targetMapping
|
|
826
|
+
targetMapping: input.targetMapping,
|
|
827
|
+
forceRemap: input.forceRemap
|
|
761
828
|
}, config);
|
|
762
829
|
return result;
|
|
763
830
|
}));
|
|
@@ -50,5 +50,12 @@ export type LoadedGraph = {
|
|
|
50
50
|
adjacency: Map<import("../types.js").SourceMapping, import("../types.js").SourceMapping[]>;
|
|
51
51
|
pathCache: Map<PairKey, import("../types.js").SourceMapping[] | undefined>;
|
|
52
52
|
recordsByTarget: Map<import("../types.js").SourceMapping, MappingSymbolRecord[]>;
|
|
53
|
+
/**
|
|
54
|
+
* Graph-scoped cache of class-to-class descriptor projections, keyed by
|
|
55
|
+
* `path.join(">") + NUL + internalName`. Value is the projected internal name,
|
|
56
|
+
* or `null` to memoize an unmapped/ambiguous class. Shared across all member
|
|
57
|
+
* lookups on this graph; dies with graph eviction.
|
|
58
|
+
*/
|
|
59
|
+
classProjectionCache: Map<string, string | null>;
|
|
53
60
|
warnings: string[];
|
|
54
61
|
};
|
package/dist/mapping/lookup.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export declare function normalizeDescriptorHint(descriptorHint: string | undefin
|
|
|
37
37
|
export declare function applyDisambiguationHints(candidates: MappingLookupCandidate[], disambiguation: {
|
|
38
38
|
ownerHint?: string;
|
|
39
39
|
descriptorHint?: string;
|
|
40
|
-
} | undefined): MappingLookupCandidate[];
|
|
40
|
+
} | undefined, warnings?: string[]): MappingLookupCandidate[];
|
|
41
41
|
export declare function projectLookupCandidateDescriptor(candidate: MappingLookupCandidate, sourceDescriptor: string, targetDescriptor: string | undefined): MappingLookupCandidate;
|
|
42
42
|
export declare function effectiveLoomSearchProjectPath(projectPath: string | undefined): string | undefined;
|
|
43
43
|
export declare function collectTargetRecords(graph: LoadedGraph, targetMapping: SourceMapping): MappingSymbolRecord[];
|
package/dist/mapping/lookup.js
CHANGED
|
@@ -376,7 +376,7 @@ export function normalizeDescriptorHint(descriptorHint) {
|
|
|
376
376
|
const normalized = descriptorHint?.trim();
|
|
377
377
|
return normalized || undefined;
|
|
378
378
|
}
|
|
379
|
-
export function applyDisambiguationHints(candidates, disambiguation) {
|
|
379
|
+
export function applyDisambiguationHints(candidates, disambiguation, warnings) {
|
|
380
380
|
if (!disambiguation || candidates.length <= 1) {
|
|
381
381
|
return candidates;
|
|
382
382
|
}
|
|
@@ -400,6 +400,12 @@ export function applyDisambiguationHints(candidates, disambiguation) {
|
|
|
400
400
|
if (descriptorMatched.length > 0) {
|
|
401
401
|
filtered = descriptorMatched;
|
|
402
402
|
}
|
|
403
|
+
else {
|
|
404
|
+
// Candidate descriptors are projected toward the target namespace, so a hint
|
|
405
|
+
// written in another namespace silently matches nothing. Surface that instead
|
|
406
|
+
// of leaving the ambiguity unexplained.
|
|
407
|
+
warnings?.push(`descriptorHint "${descriptorHint}" matched none of the ${filtered.length} candidate descriptor(s); it may be in a different mapping namespace. Hint ignored.`);
|
|
408
|
+
}
|
|
403
409
|
}
|
|
404
410
|
return filtered;
|
|
405
411
|
}
|
package/dist/mapping/types.d.ts
CHANGED
|
@@ -55,6 +55,7 @@ export type FindMappingInput = {
|
|
|
55
55
|
name: string;
|
|
56
56
|
owner?: string;
|
|
57
57
|
descriptor?: string;
|
|
58
|
+
nameMode?: "fqcn" | "auto";
|
|
58
59
|
signatureMode?: "exact" | "name-only";
|
|
59
60
|
sourceMapping: SourceMapping;
|
|
60
61
|
targetMapping: SourceMapping;
|
|
@@ -103,6 +104,7 @@ export type ClassApiMatrixInput = {
|
|
|
103
104
|
gradleUserHome?: string;
|
|
104
105
|
includeKinds?: ClassApiMatrixKind[];
|
|
105
106
|
maxRows?: number;
|
|
107
|
+
cursor?: string;
|
|
106
108
|
};
|
|
107
109
|
export type ClassApiMatrixEntry = {
|
|
108
110
|
symbol: string;
|
|
@@ -127,6 +129,10 @@ export type ClassApiMatrixOutput = {
|
|
|
127
129
|
rows: ClassApiMatrixRow[];
|
|
128
130
|
rowCount: number;
|
|
129
131
|
rowsTruncated?: boolean;
|
|
132
|
+
/** Continuation cursor when more rows remain; pass back as cursor for the next page. */
|
|
133
|
+
nextCursor?: string;
|
|
134
|
+
/** True when a provided cursor was malformed or belonged to a different query and was ignored. */
|
|
135
|
+
cursorIgnored?: boolean;
|
|
130
136
|
warnings: string[];
|
|
131
137
|
ambiguousRowCount?: number;
|
|
132
138
|
};
|