@adhisang/minecraft-modding-mcp 5.0.0 → 6.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.
- package/CHANGELOG.md +55 -0
- package/dist/access-widener-parser.d.ts +1 -0
- package/dist/access-widener-parser.js +6 -3
- package/dist/cache-registry.js +35 -31
- package/dist/config.js +1 -1
- package/dist/decompiler/vineflower.js +8 -2
- package/dist/entry-tools/analyze-mod-service.js +2 -1
- package/dist/entry-tools/analyze-symbol-service.js +18 -9
- package/dist/entry-tools/batch-class-members-service.d.ts +2 -0
- package/dist/entry-tools/batch-class-members-service.js +1 -0
- package/dist/entry-tools/compare-minecraft-service.js +1 -1
- package/dist/entry-tools/inspect-minecraft/handlers/class-members.js +2 -1
- package/dist/entry-tools/inspect-minecraft/handlers/file.js +26 -1
- package/dist/entry-tools/inspect-minecraft/handlers/versions.js +2 -1
- package/dist/entry-tools/inspect-minecraft/internal.js +2 -0
- package/dist/entry-tools/response-contract.d.ts +2 -0
- package/dist/entry-tools/response-contract.js +2 -2
- package/dist/entry-tools/validate-project/cases/project-summary.js +30 -12
- package/dist/entry-tools/validate-project-service.d.ts +4 -4
- package/dist/entry-tools/verify-mixin-target-service.js +7 -7
- package/dist/index.js +21 -16
- package/dist/java-process.js +1 -1
- package/dist/json-rpc-framing.d.ts +4 -0
- package/dist/json-rpc-framing.js +23 -1
- package/dist/mapping/internal-types.d.ts +17 -0
- package/dist/mapping/loaders/tiny-maven.js +46 -20
- package/dist/mapping/lookup.d.ts +12 -1
- package/dist/mapping/lookup.js +53 -1
- package/dist/mapping-service.js +37 -22
- package/dist/minecraft-explorer-service.js +2 -1
- package/dist/mixin/annotation-validators.js +21 -3
- package/dist/mixin/parsed-validator.js +1 -0
- package/dist/mixin-parser.js +71 -3
- package/dist/mod-decompile-service.d.ts +2 -0
- package/dist/mod-decompile-service.js +19 -2
- package/dist/mod-remap-service.js +6 -5
- package/dist/mojang-tiny-mapping-service.js +5 -2
- package/dist/nbt/java-nbt-codec.js +40 -16
- package/dist/nbt/json-patch.js +51 -12
- package/dist/nbt/typed-json.d.ts +1 -0
- package/dist/nbt/typed-json.js +12 -2
- package/dist/nbt/types.d.ts +2 -2
- package/dist/path-converter.js +10 -3
- package/dist/registry-service.d.ts +2 -0
- package/dist/registry-service.js +16 -1
- package/dist/repo-downloader.js +4 -3
- package/dist/source/artifact-resolver.js +1 -1
- package/dist/source/class-source/members-builder.d.ts +26 -0
- package/dist/source/class-source/members-builder.js +31 -4
- package/dist/source/class-source/snippet-builder.js +6 -0
- package/dist/source/class-source-helpers.d.ts +4 -4
- package/dist/source/class-source-helpers.js +12 -11
- package/dist/source/class-source.d.ts +19 -0
- package/dist/source/class-source.js +87 -26
- package/dist/source/file-access.js +3 -2
- package/dist/source/indexer.js +24 -7
- package/dist/source/lifecycle/mapping-helpers.js +28 -3
- package/dist/source/lifecycle/runtime-check.js +20 -6
- package/dist/source/member-pattern.d.ts +16 -0
- package/dist/source/member-pattern.js +27 -0
- package/dist/source/search.js +23 -8
- package/dist/source/validate-mixin/pipeline/resolve.js +23 -3
- package/dist/source/workspace-target.js +2 -1
- package/dist/source-resolver.js +2 -2
- package/dist/source-service.d.ts +8 -4
- package/dist/source-service.js +9 -1
- package/dist/stdio-supervisor.d.ts +2 -2
- package/dist/stdio-supervisor.js +29 -9
- package/dist/storage/db.js +24 -1
- package/dist/storage/files-repo.d.ts +3 -0
- package/dist/storage/files-repo.js +43 -37
- package/dist/storage/symbols-repo.d.ts +9 -0
- package/dist/storage/symbols-repo.js +47 -19
- package/dist/symbols/symbol-extractor.js +1 -1
- package/dist/tool-guidance.d.ts +2 -1
- package/dist/tool-guidance.js +27 -2
- package/dist/tool-schemas.d.ts +15 -4
- package/dist/tool-schemas.js +102 -97
- package/dist/warning-details.d.ts +12 -0
- package/dist/warning-details.js +17 -0
- package/dist/workspace-mapping-service.js +9 -0
- package/docs/tool-reference.md +23 -0
- package/package.json +1 -1
package/dist/tool-schemas.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolve as pathResolve } from "node:path";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { DETAIL_LEVELS, CANONICAL_INCLUDE_GROUPS } from "./entry-tools/response-contract.js";
|
|
4
4
|
// Shared response-shape controls for the expert + batch tools (replacing the old
|
|
5
5
|
// per-tool `compact` boolean). detail: summary|standard|full + include[] mirrors the
|
|
6
6
|
// entry-tool contract. Defaults are per-tool (see DEFAULT_DETAIL_BY_TOOL in response-utils):
|
|
7
7
|
// resolution/mapping tools + batch default "summary"; source/file tools default "standard".
|
|
8
|
-
const DETAIL_DESCRIPTION = "
|
|
9
|
-
const RESPONSE_INCLUDE_DESCRIPTION =
|
|
8
|
+
const DETAIL_DESCRIPTION = "summary = terse (drops diagnostics/empties, slims candidates); standard = keeps fields, drops heavy diagnostics; full = everything.";
|
|
9
|
+
const RESPONSE_INCLUDE_DESCRIPTION = 'Field groups to include regardless of detail, e.g. ["provenance"].';
|
|
10
10
|
function detailParam(defaultLevel) {
|
|
11
11
|
return z.enum(DETAIL_LEVELS).default(defaultLevel).describe(DETAIL_DESCRIPTION);
|
|
12
12
|
}
|
|
@@ -30,7 +30,7 @@ export const ENCODE_COMPRESSIONS = ["none", "gzip"];
|
|
|
30
30
|
export const nonEmptyString = z.string().trim().min(1);
|
|
31
31
|
export const optionalNonEmptyString = z.string().trim().min(1).optional();
|
|
32
32
|
export const optionalPositiveInt = z.number().int().positive().optional();
|
|
33
|
-
export const gradleUserHomeSchema = optionalNonEmptyString.describe("Gradle
|
|
33
|
+
export const gradleUserHomeSchema = optionalNonEmptyString.describe("Gradle user home for Loom cache lookups (overrides GRADLE_USER_HOME).");
|
|
34
34
|
// Optional descriptor: "" and whitespace-only strings are normalized to undefined so that
|
|
35
35
|
// tools with signatureMode="name-only" can accept "caller omitted descriptor" inputs whether
|
|
36
36
|
// the caller passed an empty string or omitted the field entirely. Malformed descriptors are
|
|
@@ -64,10 +64,10 @@ export const workspaceTargetSchema = z.object({
|
|
|
64
64
|
});
|
|
65
65
|
export const dependencyTargetSchema = z.object({
|
|
66
66
|
kind: z.literal("dependency"),
|
|
67
|
-
group: nonEmptyString,
|
|
68
|
-
name: nonEmptyString,
|
|
69
|
-
version: z.string().trim().min(1).optional(),
|
|
70
|
-
versionFromProject: z.boolean().optional()
|
|
67
|
+
group: nonEmptyString.describe('Maven group, e.g. "net.fabricmc.fabric-api" or "dev.architectury".'),
|
|
68
|
+
name: nonEmptyString.describe('Maven artifact name, e.g. "fabric-api" or "architectury".'),
|
|
69
|
+
version: z.string().trim().min(1).optional().describe("Explicit version; omit and set versionFromProject to resolve it from the workspace."),
|
|
70
|
+
versionFromProject: z.boolean().optional().describe("Resolve the version from the project's gradle.properties / gradle cache (requires projectPath).")
|
|
71
71
|
});
|
|
72
72
|
export const resolveArtifactTargetSchema = z.discriminatedUnion("kind", [
|
|
73
73
|
z.object({ kind: z.literal("version"), value: nonEmptyString }),
|
|
@@ -89,13 +89,16 @@ export const sourceLookupTargetSchema = z.discriminatedUnion("kind", [
|
|
|
89
89
|
dependencyTargetSchema,
|
|
90
90
|
z.object({ kind: z.literal("artifact"), artifactId: nonEmptyString })
|
|
91
91
|
]);
|
|
92
|
-
export const RESOLVE_ARTIFACT_TARGET_DESCRIPTION = 'Object
|
|
93
|
-
export const SOURCE_LOOKUP_TARGET_DESCRIPTION = '
|
|
94
|
-
export const SOURCE_SCOPE_DESCRIPTION = "vanilla = Mojang client jar only; merged =
|
|
92
|
+
export const RESOLVE_ARTIFACT_TARGET_DESCRIPTION = 'Object, not string. e.g. {"kind":"version","value":"1.21.10"}, {"kind":"workspace"}, or to inspect a loader/Fabric dependency like vanilla: {"kind":"dependency","group":"net.fabricmc.fabric-api","name":"fabric-api","versionFromProject":true} (needs projectPath) or with an explicit "version".';
|
|
93
|
+
export const SOURCE_LOOKUP_TARGET_DESCRIPTION = 'Same shape as resolve-artifact target (incl. {"kind":"dependency",...} to read a Fabric/loader dependency class like vanilla), plus {"kind":"artifact","artifactId":"..."} to reuse a resolved artifact. Object, not string.';
|
|
94
|
+
export const SOURCE_SCOPE_DESCRIPTION = "vanilla = Mojang client jar only; merged = merged runtime discovery; loader = loader-transformed runtime jars.";
|
|
95
95
|
// Shared describe() text reused by every symbol-lookup tool so the contract reads
|
|
96
96
|
// identically on find-mapping and check-symbol-exists (and any future sibling).
|
|
97
|
+
export const MEMBER_PATTERN_DESCRIPTION = 'Case-insensitive substring filter on member names. Use "|" for OR alternatives, e.g. "getStateForPlacement|canSurvive|setPlacedBy" (each token is matched as a substring, not a regex).';
|
|
98
|
+
export const memberProjectionSchema = z.enum(["names", "signatures", "full"]);
|
|
99
|
+
export const MEMBER_PROJECTION_DESCRIPTION = 'Per-member field projection: "names" (member name only), "signatures" (name + javaSignature, no jvmDescriptor), or "full" (default; complete member shape). Use "names"/"signatures" to cut response tokens for existence/signature checks.';
|
|
97
100
|
export const SIGNATURE_MODE_DESCRIPTION = "exact: descriptor required for kind=method; name-only (default): match by owner+name only.";
|
|
98
|
-
export const NAME_MODE_DESCRIPTION = "auto (default):
|
|
101
|
+
export const NAME_MODE_DESCRIPTION = "auto (default): FQCN, or dotless name where allowed; fqcn: require FQCN.";
|
|
99
102
|
export const listVersionsShape = {
|
|
100
103
|
includeSnapshots: z.boolean().default(false),
|
|
101
104
|
limit: optionalPositiveInt.default(20).describe("max 200")
|
|
@@ -103,14 +106,14 @@ export const listVersionsShape = {
|
|
|
103
106
|
export const listVersionsSchema = z.object(listVersionsShape);
|
|
104
107
|
export const resolveArtifactShape = {
|
|
105
108
|
target: resolveArtifactTargetSchema.describe(RESOLVE_ARTIFACT_TARGET_DESCRIPTION),
|
|
106
|
-
mapping: sourceMappingSchema.optional()
|
|
107
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
109
|
+
mapping: sourceMappingSchema.optional(),
|
|
110
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
108
111
|
allowDecompile: z.boolean().default(true),
|
|
109
|
-
projectPath: optionalNonEmptyString.describe("
|
|
112
|
+
projectPath: optionalNonEmptyString.describe("Workspace root for Loom cache-assisted resolution"),
|
|
110
113
|
gradleUserHome: gradleUserHomeSchema,
|
|
111
114
|
scope: artifactScopeSchema.optional().describe(SOURCE_SCOPE_DESCRIPTION),
|
|
112
|
-
preferProjectVersion: z.boolean().optional().describe("
|
|
113
|
-
strictVersion: z.boolean().optional().describe("
|
|
115
|
+
preferProjectVersion: z.boolean().optional().describe("Detect MC version from gradle.properties and override target.value"),
|
|
116
|
+
strictVersion: z.boolean().optional().describe("Reject version-approximated results (default false)"),
|
|
114
117
|
detail: detailParam("summary"),
|
|
115
118
|
include: responseIncludeParam
|
|
116
119
|
};
|
|
@@ -119,14 +122,14 @@ export const getClassSourceShape = {
|
|
|
119
122
|
className: nonEmptyString,
|
|
120
123
|
mode: sourceModeSchema.default("metadata").describe("metadata = symbol outline only; snippet = source with default maxLines=200; full = entire source"),
|
|
121
124
|
target: sourceLookupTargetSchema.describe(SOURCE_LOOKUP_TARGET_DESCRIPTION),
|
|
122
|
-
mapping: sourceMappingSchema.optional()
|
|
123
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
125
|
+
mapping: sourceMappingSchema.optional(),
|
|
126
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
124
127
|
allowDecompile: z.boolean().default(true),
|
|
125
|
-
projectPath: optionalNonEmptyString.describe("
|
|
128
|
+
projectPath: optionalNonEmptyString.describe("Workspace root for Loom cache-assisted resolution"),
|
|
126
129
|
gradleUserHome: gradleUserHomeSchema,
|
|
127
130
|
scope: artifactScopeSchema.optional().describe(SOURCE_SCOPE_DESCRIPTION),
|
|
128
|
-
preferProjectVersion: z.boolean().optional().describe("
|
|
129
|
-
strictVersion: z.boolean().optional().describe("
|
|
131
|
+
preferProjectVersion: z.boolean().optional().describe("Detect MC version from gradle.properties and override target.value"),
|
|
132
|
+
strictVersion: z.boolean().optional().describe("Reject version-approximated results (default false)"),
|
|
130
133
|
startLine: optionalPositiveInt,
|
|
131
134
|
endLine: optionalPositiveInt,
|
|
132
135
|
maxLines: optionalPositiveInt,
|
|
@@ -134,7 +137,7 @@ export const getClassSourceShape = {
|
|
|
134
137
|
outputFile: optionalNonEmptyString.describe("Write source to this file path and return metadata-only response"),
|
|
135
138
|
detail: detailParam("standard"),
|
|
136
139
|
include: responseIncludeParam,
|
|
137
|
-
includeProvenance: z.boolean().default(false).describe(
|
|
140
|
+
includeProvenance: z.boolean().default(false).describe('Alias for include:["provenance"] (diagnostic metadata). Default false.')
|
|
138
141
|
};
|
|
139
142
|
export const getClassSourceSchema = z
|
|
140
143
|
.object(getClassSourceShape)
|
|
@@ -152,24 +155,25 @@ export const getClassSourceSchema = z
|
|
|
152
155
|
export const getClassMembersShape = {
|
|
153
156
|
className: nonEmptyString,
|
|
154
157
|
target: sourceLookupTargetSchema.describe(SOURCE_LOOKUP_TARGET_DESCRIPTION),
|
|
155
|
-
mapping: sourceMappingSchema.optional().describe("
|
|
156
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
158
|
+
mapping: sourceMappingSchema.optional().describe("default obfuscated"),
|
|
159
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
157
160
|
allowDecompile: z.boolean().default(true),
|
|
158
|
-
access: memberAccessSchema.default("public")
|
|
161
|
+
access: memberAccessSchema.default("public"),
|
|
159
162
|
includeSynthetic: z.boolean().default(false),
|
|
160
163
|
includeInherited: z.boolean().default(false),
|
|
161
|
-
memberPattern: optionalNonEmptyString,
|
|
164
|
+
memberPattern: optionalNonEmptyString.describe(MEMBER_PATTERN_DESCRIPTION),
|
|
165
|
+
projection: memberProjectionSchema.optional().describe(MEMBER_PROJECTION_DESCRIPTION),
|
|
162
166
|
maxMembers: optionalPositiveInt.describe("default 150, max 5000. Page beyond the first 150 with cursor."),
|
|
163
|
-
cursor: optionalNonEmptyString.describe("
|
|
167
|
+
cursor: optionalNonEmptyString.describe("nextCursor from the previous response."),
|
|
164
168
|
projectPath: optionalNonEmptyString,
|
|
165
169
|
gradleUserHome: gradleUserHomeSchema,
|
|
166
170
|
scope: artifactScopeSchema.optional().describe(SOURCE_SCOPE_DESCRIPTION),
|
|
167
|
-
preferProjectVersion: z.boolean().optional().describe("
|
|
168
|
-
strictVersion: z.boolean().optional().describe("
|
|
171
|
+
preferProjectVersion: z.boolean().optional().describe("Detect MC version from gradle.properties and override version"),
|
|
172
|
+
strictVersion: z.boolean().optional().describe("Reject version-approximated results (default false)"),
|
|
169
173
|
detail: detailParam("standard"),
|
|
170
174
|
include: responseIncludeParam,
|
|
171
|
-
includeProvenance: z.boolean().default(false).describe(
|
|
172
|
-
includeDescriptors: z.boolean().default(false).describe(
|
|
175
|
+
includeProvenance: z.boolean().default(false).describe('Alias for include:["provenance"] (diagnostic metadata). Default false.'),
|
|
176
|
+
includeDescriptors: z.boolean().default(false).describe('Alias for include:["descriptors"]: also emit jvmDescriptor on FIELD members (method/constructor descriptors are always present). Default false.')
|
|
173
177
|
};
|
|
174
178
|
export const getClassMembersSchema = z.object(getClassMembersShape);
|
|
175
179
|
export const verifyMixinTargetMemberSchema = z.discriminatedUnion("kind", [
|
|
@@ -185,18 +189,18 @@ export const verifyMixinTargetMemberSchema = z.discriminatedUnion("kind", [
|
|
|
185
189
|
})
|
|
186
190
|
]);
|
|
187
191
|
export const verifyMixinTargetShape = {
|
|
188
|
-
owner: nonEmptyString.describe("Fully-qualified
|
|
189
|
-
member: verifyMixinTargetMemberSchema.describe('
|
|
190
|
-
mixinMemberName: optionalNonEmptyString.describe("
|
|
191
|
-
mapping: sourceMappingSchema.optional()
|
|
192
|
-
autoRemap: z.boolean().optional().describe("
|
|
193
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
192
|
+
owner: nonEmptyString.describe("Fully-qualified target owner class name."),
|
|
193
|
+
member: verifyMixinTargetMemberSchema.describe('e.g. {"kind":"method","name":"tick","descriptor":"()V"} or {"kind":"field","name":"airSupply"}.'),
|
|
194
|
+
mixinMemberName: optionalNonEmptyString.describe("Caller-authored mixin member name; drives @Accessor/@Invoker advice when the target is private."),
|
|
195
|
+
mapping: sourceMappingSchema.optional(),
|
|
196
|
+
autoRemap: z.boolean().optional().describe("Translate owner+member via find-mapping when mapping differs from the artifact namespace (requires a version-based target)."),
|
|
197
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
194
198
|
projectPath: optionalNonEmptyString.describe("Workspace root path for target.kind=workspace and Loom cache assistance."),
|
|
195
199
|
gradleUserHome: gradleUserHomeSchema,
|
|
196
200
|
target: resolveArtifactTargetSchema.describe(RESOLVE_ARTIFACT_TARGET_DESCRIPTION),
|
|
197
201
|
scope: artifactScopeSchema.optional().describe(SOURCE_SCOPE_DESCRIPTION),
|
|
198
|
-
preferProjectVersion: z.boolean().optional().describe("
|
|
199
|
-
strictVersion: z.boolean().optional().describe("
|
|
202
|
+
preferProjectVersion: z.boolean().optional().describe("Detect MC version from gradle.properties and override target.value"),
|
|
203
|
+
strictVersion: z.boolean().optional().describe("Reject version-approximated results (default false)")
|
|
200
204
|
};
|
|
201
205
|
export const verifyMixinTargetSchema = z.object(verifyMixinTargetShape);
|
|
202
206
|
export const batchSymbolKindSchema = z.enum(["class", "field", "method"]);
|
|
@@ -211,7 +215,7 @@ export const batchClassSourceEntrySchema = z.object({
|
|
|
211
215
|
});
|
|
212
216
|
export const batchClassSourceShape = {
|
|
213
217
|
target: resolveArtifactTargetSchema.describe(RESOLVE_ARTIFACT_TARGET_DESCRIPTION),
|
|
214
|
-
mapping: sourceMappingSchema.optional()
|
|
218
|
+
mapping: sourceMappingSchema.optional(),
|
|
215
219
|
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
216
220
|
allowDecompile: z.boolean().optional(),
|
|
217
221
|
projectPath: optionalNonEmptyString,
|
|
@@ -233,8 +237,8 @@ export const batchClassSourceSchema = z.object(batchClassSourceShape).superRefin
|
|
|
233
237
|
// Per-entry `outputFile` is forwarded into the concurrently-dispatched
|
|
234
238
|
// `getClassSource` calls; two entries resolving to the same physical file
|
|
235
239
|
// would race on `writeFile`. Normalize via `path.resolve` so aliases like
|
|
236
|
-
// `out.java` / `./out.java` / `dir/../out.java`
|
|
237
|
-
//
|
|
240
|
+
// `out.java` / `./out.java` / `dir/../out.java` / `/tmp/dir/../out.java`
|
|
241
|
+
// collide as expected, covering relative and absolute spellings alike.
|
|
238
242
|
const seen = new Map();
|
|
239
243
|
for (let i = 0; i < value.entries.length; i += 1) {
|
|
240
244
|
const entry = value.entries[i];
|
|
@@ -243,7 +247,7 @@ export const batchClassSourceSchema = z.object(batchClassSourceShape).superRefin
|
|
|
243
247
|
const trimmed = entry.outputFile.trim();
|
|
244
248
|
if (trimmed.length === 0)
|
|
245
249
|
continue;
|
|
246
|
-
const canonical =
|
|
250
|
+
const canonical = pathResolve(trimmed);
|
|
247
251
|
const previous = seen.get(canonical);
|
|
248
252
|
if (previous !== undefined) {
|
|
249
253
|
ctx.addIssue({
|
|
@@ -262,7 +266,7 @@ export const batchClassMembersEntrySchema = z.object({
|
|
|
262
266
|
access: memberAccessSchema.optional(),
|
|
263
267
|
includeSynthetic: z.boolean().optional(),
|
|
264
268
|
includeInherited: z.boolean().optional(),
|
|
265
|
-
memberPattern: optionalNonEmptyString,
|
|
269
|
+
memberPattern: optionalNonEmptyString.describe(MEMBER_PATTERN_DESCRIPTION),
|
|
266
270
|
maxMembers: optionalPositiveInt
|
|
267
271
|
});
|
|
268
272
|
export const batchClassMembersShape = {
|
|
@@ -278,6 +282,7 @@ export const batchClassMembersShape = {
|
|
|
278
282
|
concurrency: z.number().int().min(1).max(8).optional(),
|
|
279
283
|
failFast: z.boolean().optional(),
|
|
280
284
|
detail: detailParam("summary"),
|
|
285
|
+
projection: memberProjectionSchema.optional().describe(MEMBER_PROJECTION_DESCRIPTION),
|
|
281
286
|
include: responseIncludeParam,
|
|
282
287
|
entries: z.array(batchClassMembersEntrySchema).min(1).max(50)
|
|
283
288
|
};
|
|
@@ -285,7 +290,7 @@ export const batchClassMembersSchema = z.object(batchClassMembersShape);
|
|
|
285
290
|
export const batchSymbolExistsTargetSchema = z.discriminatedUnion("kind", [
|
|
286
291
|
z.object({ kind: z.literal("version"), value: nonEmptyString }),
|
|
287
292
|
workspaceTargetSchema
|
|
288
|
-
]).describe('
|
|
293
|
+
]).describe('Only kind="version" or kind="workspace"; other kinds carry library versions, not MC versions.');
|
|
289
294
|
export const batchSymbolExistsEntrySchema = z.object({
|
|
290
295
|
kind: batchSymbolKindSchema,
|
|
291
296
|
name: nonEmptyString,
|
|
@@ -332,7 +337,7 @@ export const batchMappingsEntrySchema = z
|
|
|
332
337
|
})
|
|
333
338
|
.strict();
|
|
334
339
|
export const batchMappingsShape = {
|
|
335
|
-
version: nonEmptyString.describe("Minecraft version shared by every entry
|
|
340
|
+
version: nonEmptyString.describe("Minecraft version shared by every entry (single-version batch)."),
|
|
336
341
|
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
337
342
|
projectPath: optionalNonEmptyString,
|
|
338
343
|
gradleUserHome: gradleUserHomeSchema,
|
|
@@ -346,16 +351,16 @@ export const batchMappingsSchema = z.object(batchMappingsShape);
|
|
|
346
351
|
export const searchClassSourceShape = {
|
|
347
352
|
artifactId: nonEmptyString,
|
|
348
353
|
query: nonEmptyString,
|
|
349
|
-
intent: searchIntentSchema.optional()
|
|
350
|
-
match: searchMatchSchema.optional()
|
|
354
|
+
intent: searchIntentSchema.optional(),
|
|
355
|
+
match: searchMatchSchema.optional(),
|
|
351
356
|
packagePrefix: optionalNonEmptyString,
|
|
352
357
|
fileGlob: optionalNonEmptyString,
|
|
353
|
-
symbolKind: searchSymbolKindSchema.optional()
|
|
354
|
-
queryMode: z.enum(["auto", "token", "literal"]).default("auto").describe("auto: indexed search
|
|
358
|
+
symbolKind: searchSymbolKindSchema.optional(),
|
|
359
|
+
queryMode: z.enum(["auto", "token", "literal"]).default("auto").describe("auto: indexed search incl. separator queries like foo.bar; token: indexed-only; literal: substring scan only"),
|
|
355
360
|
limit: optionalPositiveInt.default(20),
|
|
356
361
|
cursor: optionalNonEmptyString,
|
|
357
|
-
queryNamespace: sourceMappingSchema.optional().describe("
|
|
358
|
-
sourcePriority: mappingSourcePrioritySchema.optional().describe("
|
|
362
|
+
queryNamespace: sourceMappingSchema.optional().describe("Query namespace; symbol-intent FQCN queries are translated via find-mapping first. Ignored for text/path intents."),
|
|
363
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("Used only when queryNamespace triggers translation."),
|
|
359
364
|
gradleUserHome: gradleUserHomeSchema,
|
|
360
365
|
detail: detailParam("standard"),
|
|
361
366
|
include: responseIncludeParam
|
|
@@ -389,8 +394,8 @@ export const traceSymbolLifecycleShape = {
|
|
|
389
394
|
descriptor: optionalDescriptorString.describe('optional JVM descriptor, e.g. "(I)V". Empty strings are treated as omitted.'),
|
|
390
395
|
fromVersion: optionalNonEmptyString,
|
|
391
396
|
toVersion: optionalNonEmptyString,
|
|
392
|
-
mapping: sourceMappingSchema.optional().describe("
|
|
393
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
397
|
+
mapping: sourceMappingSchema.optional().describe("default obfuscated"),
|
|
398
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
394
399
|
gradleUserHome: gradleUserHomeSchema,
|
|
395
400
|
includeSnapshots: z.boolean().default(false),
|
|
396
401
|
maxVersions: optionalPositiveInt.default(120).describe("max 400"),
|
|
@@ -401,21 +406,21 @@ export const diffClassSignaturesShape = {
|
|
|
401
406
|
className: nonEmptyString,
|
|
402
407
|
fromVersion: nonEmptyString,
|
|
403
408
|
toVersion: nonEmptyString,
|
|
404
|
-
mapping: sourceMappingSchema.optional().describe("
|
|
405
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
409
|
+
mapping: sourceMappingSchema.optional().describe("default obfuscated"),
|
|
410
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
406
411
|
gradleUserHome: gradleUserHomeSchema,
|
|
407
412
|
includeFullDiff: z.boolean().default(true).describe("When false, omit from/to snapshots from modified entries and keep only key+changed")
|
|
408
413
|
};
|
|
409
414
|
export const diffClassSignaturesSchema = z.object(diffClassSignaturesShape);
|
|
410
415
|
export const findMappingShape = {
|
|
411
416
|
version: nonEmptyString,
|
|
412
|
-
kind: workspaceSymbolKindSchema
|
|
417
|
+
kind: workspaceSymbolKindSchema,
|
|
413
418
|
name: nonEmptyString,
|
|
414
419
|
owner: optionalNonEmptyString,
|
|
415
|
-
descriptor: optionalDescriptorString.describe("JVM descriptor
|
|
416
|
-
sourceMapping: sourceMappingSchema
|
|
417
|
-
targetMapping: sourceMappingSchema
|
|
418
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
420
|
+
descriptor: optionalDescriptorString.describe("JVM descriptor; optional when signatureMode='name-only'. Empty = omitted."),
|
|
421
|
+
sourceMapping: sourceMappingSchema,
|
|
422
|
+
targetMapping: sourceMappingSchema,
|
|
423
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
419
424
|
gradleUserHome: gradleUserHomeSchema,
|
|
420
425
|
nameMode: classNameModeSchema.default("auto").describe(NAME_MODE_DESCRIPTION),
|
|
421
426
|
signatureMode: z.enum(["exact", "name-only"]).default("name-only").describe(SIGNATURE_MODE_DESCRIPTION),
|
|
@@ -426,7 +431,7 @@ export const findMappingShape = {
|
|
|
426
431
|
})
|
|
427
432
|
.partial()
|
|
428
433
|
.optional(),
|
|
429
|
-
maxCandidates: optionalPositiveInt.default(5).describe("
|
|
434
|
+
maxCandidates: optionalPositiveInt.default(5).describe("default 5, max 200"),
|
|
430
435
|
detail: detailParam("summary"),
|
|
431
436
|
include: responseIncludeParam
|
|
432
437
|
};
|
|
@@ -496,11 +501,11 @@ export const resolveMethodMappingExactShape = {
|
|
|
496
501
|
name: nonEmptyString,
|
|
497
502
|
owner: nonEmptyString,
|
|
498
503
|
descriptor: nonEmptyString.describe("required JVM descriptor"),
|
|
499
|
-
sourceMapping: sourceMappingSchema
|
|
500
|
-
targetMapping: sourceMappingSchema
|
|
501
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
504
|
+
sourceMapping: sourceMappingSchema,
|
|
505
|
+
targetMapping: sourceMappingSchema,
|
|
506
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
502
507
|
gradleUserHome: gradleUserHomeSchema,
|
|
503
|
-
maxCandidates: optionalPositiveInt.default(5).describe("
|
|
508
|
+
maxCandidates: optionalPositiveInt.default(5).describe("default 5, max 200"),
|
|
504
509
|
detail: detailParam("summary"),
|
|
505
510
|
include: responseIncludeParam
|
|
506
511
|
};
|
|
@@ -538,25 +543,25 @@ export const classApiKindsSchema = z.string().superRefine((value, ctx) => {
|
|
|
538
543
|
export const getClassApiMatrixShape = {
|
|
539
544
|
version: nonEmptyString,
|
|
540
545
|
className: nonEmptyString,
|
|
541
|
-
classNameMapping: sourceMappingSchema
|
|
546
|
+
classNameMapping: sourceMappingSchema,
|
|
542
547
|
includeKinds: classApiKindsSchema.optional().describe("comma-separated: class,field,method"),
|
|
543
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
548
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
544
549
|
gradleUserHome: gradleUserHomeSchema,
|
|
545
550
|
maxRows: optionalPositiveInt.describe("Limit returned rows (max 5000)"),
|
|
546
|
-
cursor: optionalNonEmptyString.describe("
|
|
551
|
+
cursor: optionalNonEmptyString.describe("nextCursor from the previous response.")
|
|
547
552
|
};
|
|
548
553
|
export const getClassApiMatrixSchema = z.object(getClassApiMatrixShape);
|
|
549
554
|
export const resolveWorkspaceSymbolShape = {
|
|
550
555
|
projectPath: nonEmptyString,
|
|
551
556
|
version: nonEmptyString,
|
|
552
|
-
kind: workspaceSymbolKindSchema
|
|
557
|
+
kind: workspaceSymbolKindSchema,
|
|
553
558
|
name: nonEmptyString,
|
|
554
559
|
owner: optionalNonEmptyString,
|
|
555
560
|
descriptor: optionalDescriptorString.describe("JVM descriptor. Empty strings are treated as omitted."),
|
|
556
|
-
sourceMapping: sourceMappingSchema
|
|
557
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
561
|
+
sourceMapping: sourceMappingSchema,
|
|
562
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
558
563
|
gradleUserHome: gradleUserHomeSchema,
|
|
559
|
-
maxCandidates: optionalPositiveInt.default(5).describe("
|
|
564
|
+
maxCandidates: optionalPositiveInt.default(5).describe("default 5, max 200 (field/method lookups)"),
|
|
560
565
|
detail: detailParam("summary"),
|
|
561
566
|
include: responseIncludeParam
|
|
562
567
|
};
|
|
@@ -621,16 +626,16 @@ export const resolveWorkspaceSymbolSchema = z
|
|
|
621
626
|
});
|
|
622
627
|
export const checkSymbolExistsShape = {
|
|
623
628
|
version: nonEmptyString,
|
|
624
|
-
kind: workspaceSymbolKindSchema
|
|
629
|
+
kind: workspaceSymbolKindSchema,
|
|
625
630
|
owner: optionalNonEmptyString,
|
|
626
631
|
name: nonEmptyString,
|
|
627
|
-
descriptor: optionalDescriptorString.describe("JVM descriptor
|
|
628
|
-
sourceMapping: sourceMappingSchema
|
|
629
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
632
|
+
descriptor: optionalDescriptorString.describe("JVM descriptor; optional when signatureMode='name-only'. Empty = omitted."),
|
|
633
|
+
sourceMapping: sourceMappingSchema,
|
|
634
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
630
635
|
gradleUserHome: gradleUserHomeSchema,
|
|
631
636
|
nameMode: classNameModeSchema.default("auto").describe(NAME_MODE_DESCRIPTION),
|
|
632
637
|
signatureMode: z.enum(["exact", "name-only"]).default("name-only").describe(SIGNATURE_MODE_DESCRIPTION),
|
|
633
|
-
maxCandidates: optionalPositiveInt.default(5).describe("
|
|
638
|
+
maxCandidates: optionalPositiveInt.default(5).describe("default 5, max 200"),
|
|
634
639
|
detail: detailParam("summary"),
|
|
635
640
|
include: responseIncludeParam
|
|
636
641
|
};
|
|
@@ -693,7 +698,7 @@ export const checkSymbolExistsSchema = z.object(checkSymbolExistsShape).superRef
|
|
|
693
698
|
});
|
|
694
699
|
export const nbtToJsonShape = {
|
|
695
700
|
nbtBase64: nonEmptyString,
|
|
696
|
-
compression: decodeCompressionSchema.default("auto")
|
|
701
|
+
compression: decodeCompressionSchema.default("auto")
|
|
697
702
|
};
|
|
698
703
|
export const nbtToJsonSchema = z.object(nbtToJsonShape);
|
|
699
704
|
const nbtPatchOperationSchema = z
|
|
@@ -710,7 +715,7 @@ export const nbtApplyJsonPatchShape = {
|
|
|
710
715
|
export const nbtApplyJsonPatchSchema = z.object(nbtApplyJsonPatchShape);
|
|
711
716
|
export const jsonToNbtShape = {
|
|
712
717
|
typedJson: z.unknown(),
|
|
713
|
-
compression: encodeCompressionSchema.default("none")
|
|
718
|
+
compression: encodeCompressionSchema.default("none")
|
|
714
719
|
};
|
|
715
720
|
export const jsonToNbtSchema = z.object(jsonToNbtShape);
|
|
716
721
|
export const indexArtifactShape = {
|
|
@@ -740,16 +745,16 @@ export const validateMixinShape = {
|
|
|
740
745
|
mode: z.literal("project"),
|
|
741
746
|
path: nonEmptyString.describe("Workspace root path used to discover *.mixins.json files automatically")
|
|
742
747
|
})
|
|
743
|
-
]).describe("
|
|
748
|
+
]).describe("mode = inline | path | paths | config | project"),
|
|
744
749
|
sourceRoots: z.array(z.string().min(1)).optional()
|
|
745
|
-
.describe("
|
|
746
|
-
version: optionalNonEmptyString.describe("Minecraft version. Optional when input.mode='project'
|
|
747
|
-
mapping: sourceMappingSchema.optional()
|
|
748
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
750
|
+
.describe("Source roots for multi-module projects (e.g. ['common/src/main/java'])"),
|
|
751
|
+
version: optionalNonEmptyString.describe("Minecraft version. Optional when input.mode='project' or preferProjectVersion=true with projectPath; required otherwise."),
|
|
752
|
+
mapping: sourceMappingSchema.optional(),
|
|
753
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
749
754
|
scope: artifactScopeSchema.optional().describe(SOURCE_SCOPE_DESCRIPTION),
|
|
750
|
-
projectPath: optionalNonEmptyString.describe("
|
|
755
|
+
projectPath: optionalNonEmptyString.describe("Workspace root for Loom cache-assisted resolution"),
|
|
751
756
|
gradleUserHome: gradleUserHomeSchema,
|
|
752
|
-
preferProjectVersion: z.boolean().optional().describe("
|
|
757
|
+
preferProjectVersion: z.boolean().optional().describe("Detect MC version from gradle.properties and override version"),
|
|
753
758
|
minSeverity: z.enum(["error", "warning", "all"]).default("all")
|
|
754
759
|
.describe("'error'=errors only, 'warning'=errors+warnings, 'all'=everything"),
|
|
755
760
|
hideUncertain: z.boolean().default(false)
|
|
@@ -761,7 +766,7 @@ export const validateMixinShape = {
|
|
|
761
766
|
preferProjectMapping: z.boolean().default(false)
|
|
762
767
|
.describe("When true, auto-detect mapping from project config even if mapping is explicitly provided"),
|
|
763
768
|
reportMode: z.enum(["compact", "full", "summary-first"]).default("summary-first")
|
|
764
|
-
.describe("
|
|
769
|
+
.describe("summary-first (default) hoists shared provenance/warnings, drops per-result heavy detail; compact omits heavy per-result detail; full = everything (required for resolvedMembers/toolHealth/resolutionTrace unless explain=true)."),
|
|
765
770
|
warningCategoryFilter: z.array(z.enum(["mapping", "configuration", "validation", "resolution", "parse"])).optional()
|
|
766
771
|
.describe("Only include warnings/issues matching these categories (default: all)"),
|
|
767
772
|
treatInfoAsWarning: z.boolean().default(true)
|
|
@@ -785,8 +790,8 @@ export const validateMixinSchema = z.object(validateMixinShape).superRefine((val
|
|
|
785
790
|
export const validateAccessWidenerShape = {
|
|
786
791
|
content: nonEmptyString.describe("Access Widener file content"),
|
|
787
792
|
version: nonEmptyString.describe("Minecraft version"),
|
|
788
|
-
mapping: sourceMappingSchema.optional()
|
|
789
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
793
|
+
mapping: sourceMappingSchema.optional(),
|
|
794
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
790
795
|
projectPath: optionalNonEmptyString.describe("Optional workspace root path for Loom cache-assisted runtime validation"),
|
|
791
796
|
gradleUserHome: gradleUserHomeSchema,
|
|
792
797
|
scope: artifactScopeSchema.optional().describe(SOURCE_SCOPE_DESCRIPTION),
|
|
@@ -797,8 +802,8 @@ export const validateAccessWidenerSchema = z.object(validateAccessWidenerShape);
|
|
|
797
802
|
export const validateAccessTransformerShape = {
|
|
798
803
|
content: nonEmptyString.describe("Access Transformer file content"),
|
|
799
804
|
version: nonEmptyString.describe("Minecraft version"),
|
|
800
|
-
atNamespace: z.enum(["srg", "mojang", "obfuscated"]).optional()
|
|
801
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
805
|
+
atNamespace: z.enum(["srg", "mojang", "obfuscated"]).optional(),
|
|
806
|
+
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
802
807
|
projectPath: optionalNonEmptyString.describe("Optional workspace root path for Forge/NeoForge runtime validation"),
|
|
803
808
|
gradleUserHome: gradleUserHomeSchema,
|
|
804
809
|
scope: artifactScopeSchema.optional().describe(SOURCE_SCOPE_DESCRIPTION),
|
|
@@ -814,7 +819,7 @@ export const analyzeModJarSchema = z.object(analyzeModJarShape);
|
|
|
814
819
|
export const getRegistryDataShape = {
|
|
815
820
|
version: nonEmptyString.describe("Minecraft version (e.g. 1.21)"),
|
|
816
821
|
registry: optionalNonEmptyString.describe('Optional registry name (e.g. "block", "item", "minecraft:biome"). Omit to list all registries.'),
|
|
817
|
-
includeData: z.boolean().default(true).describe("
|
|
822
|
+
includeData: z.boolean().default(true).describe("false = registry names/counts only (cheap discovery); true (default) = full entry bodies."),
|
|
818
823
|
maxEntriesPerRegistry: optionalPositiveInt.describe("Limit returned entries per registry body")
|
|
819
824
|
};
|
|
820
825
|
export const getRegistryDataSchema = z.object(getRegistryDataShape);
|
|
@@ -823,7 +828,7 @@ export const compareVersionsCategorySchema = z.enum(COMPARE_VERSIONS_CATEGORIES)
|
|
|
823
828
|
export const compareVersionsShape = {
|
|
824
829
|
fromVersion: nonEmptyString.describe("Older Minecraft version (e.g. 1.20.4)"),
|
|
825
830
|
toVersion: nonEmptyString.describe("Newer Minecraft version (e.g. 1.21)"),
|
|
826
|
-
category: compareVersionsCategorySchema.default("all")
|
|
831
|
+
category: compareVersionsCategorySchema.default("all"),
|
|
827
832
|
packageFilter: optionalNonEmptyString.describe("Filter classes to a package prefix (e.g. net.minecraft.world.item)"),
|
|
828
833
|
maxClassResults: optionalPositiveInt.default(500).describe("Max class results per direction (max 5000)")
|
|
829
834
|
};
|
|
@@ -848,7 +853,7 @@ export const modSearchTypeSchema = z.enum(MOD_SEARCH_TYPES);
|
|
|
848
853
|
export const searchModSourceShape = {
|
|
849
854
|
jarPath: nonEmptyString.describe("Local path to the mod JAR file"),
|
|
850
855
|
query: nonEmptyString.describe("Search pattern (regex or literal string)"),
|
|
851
|
-
searchType: modSearchTypeSchema.default("all")
|
|
856
|
+
searchType: modSearchTypeSchema.default("all"),
|
|
852
857
|
limit: optionalPositiveInt.default(50).describe("Max results (max 200)")
|
|
853
858
|
};
|
|
854
859
|
export const searchModSourceSchema = z.object(searchModSourceShape);
|
|
@@ -858,7 +863,7 @@ export const remapModJarShape = {
|
|
|
858
863
|
inputJar: nonEmptyString.describe("Path to the mod JAR file"),
|
|
859
864
|
outputJar: optionalNonEmptyString.describe("Output path for remapped JAR (auto-generated if omitted)"),
|
|
860
865
|
mcVersion: optionalNonEmptyString.describe("Minecraft version (auto-detected from mod metadata if omitted)"),
|
|
861
|
-
targetMapping: remapTargetSchema
|
|
866
|
+
targetMapping: remapTargetSchema,
|
|
862
867
|
forceRemap: z
|
|
863
868
|
.boolean()
|
|
864
869
|
.optional()
|
|
@@ -16,3 +16,15 @@ export type WarningDetail = {
|
|
|
16
16
|
* position and dereferences the text via `warnings[index]`.
|
|
17
17
|
*/
|
|
18
18
|
export declare function classifyWarnings(warnings: string[]): WarningDetail[];
|
|
19
|
+
/**
|
|
20
|
+
* Cap of structured warningDetails entries emitted at `detail:"summary"`.
|
|
21
|
+
*/
|
|
22
|
+
export declare const SUMMARY_WARNING_DETAIL_CAP = 5;
|
|
23
|
+
/**
|
|
24
|
+
* At `detail:"summary"` the structured warningDetails companion is capped to a small
|
|
25
|
+
* representative set to keep responses lean. The full human-readable text still lives
|
|
26
|
+
* in `meta.warnings[]`, and each kept entry's `index` continues to dereference it, so
|
|
27
|
+
* no information is lost — only the redundant structured duplicate is trimmed. Standard
|
|
28
|
+
* and full detail return the companion unchanged.
|
|
29
|
+
*/
|
|
30
|
+
export declare function capWarningDetailsForSummary(warningDetails: WarningDetail[], isSummary: boolean): WarningDetail[];
|
package/dist/warning-details.js
CHANGED
|
@@ -60,4 +60,21 @@ function classifyWarning(message, index) {
|
|
|
60
60
|
export function classifyWarnings(warnings) {
|
|
61
61
|
return warnings.map((message, index) => classifyWarning(message, index));
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Cap of structured warningDetails entries emitted at `detail:"summary"`.
|
|
65
|
+
*/
|
|
66
|
+
export const SUMMARY_WARNING_DETAIL_CAP = 5;
|
|
67
|
+
/**
|
|
68
|
+
* At `detail:"summary"` the structured warningDetails companion is capped to a small
|
|
69
|
+
* representative set to keep responses lean. The full human-readable text still lives
|
|
70
|
+
* in `meta.warnings[]`, and each kept entry's `index` continues to dereference it, so
|
|
71
|
+
* no information is lost — only the redundant structured duplicate is trimmed. Standard
|
|
72
|
+
* and full detail return the companion unchanged.
|
|
73
|
+
*/
|
|
74
|
+
export function capWarningDetailsForSummary(warningDetails, isSummary) {
|
|
75
|
+
if (!isSummary || warningDetails.length <= SUMMARY_WARNING_DETAIL_CAP) {
|
|
76
|
+
return warningDetails;
|
|
77
|
+
}
|
|
78
|
+
return warningDetails.slice(0, SUMMARY_WARNING_DETAIL_CAP);
|
|
79
|
+
}
|
|
63
80
|
//# sourceMappingURL=warning-details.js.map
|
|
@@ -65,6 +65,15 @@ function buildDependencyPropertyKeys(group, name) {
|
|
|
65
65
|
`${groupSegment}_${name}_version`,
|
|
66
66
|
`${camelGroupName}Version`
|
|
67
67
|
];
|
|
68
|
+
// Umbrella fallback: submodules of an umbrella package (e.g. Fabric API's
|
|
69
|
+
// net.fabricmc.fabric-api:fabric-screen-handler-api-v1) rarely declare their own
|
|
70
|
+
// version — the parent declares a single umbrella property (fabric_api_version /
|
|
71
|
+
// fabricApiVersion) that all submodules inherit. When the artifact name differs from
|
|
72
|
+
// the group's last segment, append the umbrella's keys as LOWER-priority candidates so
|
|
73
|
+
// submodule version detection no longer fails with ERR_DEPENDENCY_VERSION_UNRESOLVED.
|
|
74
|
+
if (groupSegment !== name) {
|
|
75
|
+
keys.push(`${groupSegment.replace(/-/g, "_")}_version`, `${camelCaseDependencyName(groupSegment)}Version`);
|
|
76
|
+
}
|
|
68
77
|
const seen = new Set();
|
|
69
78
|
const deduped = [];
|
|
70
79
|
for (const key of keys) {
|
package/docs/tool-reference.md
CHANGED
|
@@ -67,6 +67,29 @@ Start here when you are not sure which tool to reach for. In every row, the left
|
|
|
67
67
|
| `{ kind: "workspace", scope?, strict? }` | When the caller already passes a `projectPath` and wants the tool to detect Minecraft version, compile mapping, and loader from `gradle.properties` and `build.gradle(.kts)`. | `projectPath` | Synthesised to `{ kind: "version", value: <detected> }`. Scope precedence is `target.scope` → top-level `scope` → loader-derived default (`"merged"` when a loader is detected, `"vanilla"` otherwise). When the version is not detected, raises `ERR_WORKSPACE_VERSION_UNRESOLVED` regardless of `strict`. Detected facts surface on `provenance.workspaceResolution`. |
|
|
68
68
|
| `{ kind: "dependency", group, name, version?, versionFromProject? }` | When the caller wants to resolve a Maven-coordinate dependency (e.g. `dev.architectury:architectury`) without computing the exact version themselves. | `projectPath` (unless `version` is given) | Synthesised to `{ kind: "coordinate", value: "<group>:<name>:<version>" }`. The dependency JAR is treated as non-vanilla: binary remap is suppressed. When the caller asks for a non-obfuscated mapping the resolver returns the JAR with `mappingApplied: "obfuscated"` and `qualityFlags: ["dependency-mapping-unverified"]`, plus a warning that the caller must validate symbol availability. Resolution metadata appears on `provenance.dependencyResolution`. |
|
|
69
69
|
|
|
70
|
+
### Inspecting a Fabric / loader dependency like vanilla
|
|
71
|
+
|
|
72
|
+
To read members or source of a Fabric API (or any loader/Maven dependency) class
|
|
73
|
+
the same way you read vanilla, pass a `dependency` target straight to
|
|
74
|
+
`get-class-members` / `get-class-source` — no separate lookup tool is needed:
|
|
75
|
+
|
|
76
|
+
```jsonc
|
|
77
|
+
// members of a Fabric API class, version taken from the workspace
|
|
78
|
+
{
|
|
79
|
+
"tool": "get-class-members",
|
|
80
|
+
"className": "net.fabricmc.fabric.api.event.player.UseEntityCallback",
|
|
81
|
+
"target": { "kind": "dependency", "group": "net.fabricmc.fabric-api", "name": "fabric-api", "versionFromProject": true },
|
|
82
|
+
"projectPath": "/path/to/workspace"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Use an explicit `"version"` instead of `versionFromProject` when you already
|
|
87
|
+
know it. Because dependency JARs are not remapped, members come back in the
|
|
88
|
+
dependency's own namespace with `qualityFlags: ["dependency-mapping-unverified"]`;
|
|
89
|
+
treat the names as the JAR's compiled names. For repeated lookups against the
|
|
90
|
+
same dependency, call `resolve-artifact` once and reuse the returned
|
|
91
|
+
`artifactId` via `target: { kind: "artifact", artifactId }`.
|
|
92
|
+
|
|
70
93
|
Workspace detection is memoised in a process-resident `WorkspaceContextCache` (16-entry LRU, 5-minute TTL). The cache is observable through `manage-cache` with `cacheKinds: ["workspace"]`, and individual entries can be invalidated via `selector.projectPath`.
|
|
71
94
|
|
|
72
95
|
`target.kind="dependency"` resolution probes four de-duplicated `gradle.properties` keys in order — `name_version`, `camelCaseVersion`, `lastSegment(group)_name_version`, and `camelCase(lastSegment(group)_name)Version` — before falling back to the modules-2 cache layout `~/.gradle/caches/modules-2/files-2.1/<group>/<name>/`. Version tokens that contain path separators, `..`, NUL, control characters, or any character outside `[A-Za-z0-9._+-]` are rejected; in `gradle.properties` the rejection is recorded under `attempts[]` as `gradle.properties:<key>:rejected-unsafe-version` and the next key is tried. Snapshot and dev directories are excluded by default. The modules-2 fallback only resolves when exactly one valid entry remains; multiple entries raise `ERR_DEPENDENCY_VERSION_UNRESOLVED` so a global cache cannot supply a version the workspace did not declare.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhisang/minecraft-modding-mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "MCP server for AI-assisted Minecraft modding: inspect decompiled source, resolve Mojang/Yarn/Intermediary mappings, diff versions, analyze Fabric/Forge/NeoForge mod JARs, and validate Mixin, Access Widener, and Access Transformer files.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|