@adhisang/minecraft-modding-mcp 6.3.0 → 7.0.0-rc.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 +62 -0
- package/README.md +13 -3
- package/dist/cache-policy.d.ts +71 -0
- package/dist/cache-policy.js +83 -0
- package/dist/cache-registry.js +6 -6
- package/dist/cli.js +74 -3
- package/dist/compat-stdio-transport.d.ts +1 -1
- package/dist/compat-stdio-transport.js +13 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.js +8 -2
- package/dist/decompiler/vineflower.d.ts +1 -0
- package/dist/decompiler/vineflower.js +8 -5
- package/dist/entry-tools/analyze-mod-service.d.ts +70 -136
- package/dist/entry-tools/analyze-symbol-service.d.ts +112 -150
- package/dist/entry-tools/compare-minecraft-service.d.ts +59 -145
- package/dist/entry-tools/entry-tool-schema.d.ts +38 -4
- package/dist/entry-tools/entry-tool-schema.js +4 -1
- package/dist/entry-tools/inspect-minecraft/internal.d.ts +235 -799
- package/dist/entry-tools/inspect-minecraft/internal.js +50 -13
- package/dist/entry-tools/inspect-minecraft-service.d.ts +372 -1736
- package/dist/entry-tools/manage-cache-service.d.ts +81 -91
- package/dist/entry-tools/validate-project/cases/project-summary.d.ts +7 -7
- package/dist/entry-tools/validate-project-service.d.ts +164 -592
- package/dist/entry-tools/verify-mixin-target-service.d.ts +3 -19
- package/dist/era-classifier.d.ts +161 -0
- package/dist/era-classifier.js +292 -0
- package/dist/error-mapping.js +9 -2
- package/dist/index.d.ts +42 -4
- package/dist/index.js +636 -473
- package/dist/java-process.d.ts +2 -0
- package/dist/java-process.js +22 -2
- package/dist/json-rpc-framing.d.ts +77 -1
- package/dist/json-rpc-framing.js +249 -13
- package/dist/mapping/loaders/tiny-loom-selection.d.ts +88 -0
- package/dist/mapping/loaders/tiny-loom-selection.js +223 -0
- package/dist/mapping/loaders/tiny-loom.js +45 -33
- package/dist/mapping/loaders/tiny-maven.js +6 -11
- package/dist/mapping/parsers/tiny.d.ts +57 -0
- package/dist/mapping/parsers/tiny.js +99 -22
- package/dist/mapping-service.d.ts +19 -0
- package/dist/mapping-service.js +93 -9
- package/dist/mcp-helpers.d.ts +19 -2
- package/dist/mcp-helpers.js +48 -6
- package/dist/minecraft-explorer-service.d.ts +1 -1
- package/dist/mixin/types.d.ts +8 -0
- package/dist/mod-analyzer.js +7 -7
- package/dist/mod-decompile-service.js +1 -0
- package/dist/nbt/java-nbt-codec.js +12 -2
- package/dist/nbt/json-patch.js +14 -3
- package/dist/nbt/pipeline.js +40 -3
- package/dist/nbt/typed-json.js +26 -1
- package/dist/registration-adapter.d.ts +32 -0
- package/dist/registration-adapter.js +52 -0
- package/dist/request-context.d.ts +7 -0
- package/dist/request-context.js +9 -0
- package/dist/resources.d.ts +1 -1
- package/dist/resources.js +25 -19
- package/dist/server-identity.d.ts +27 -0
- package/dist/server-identity.js +26 -0
- package/dist/source/access-validate.js +53 -0
- package/dist/source/artifact-resolver.d.ts +69 -1
- package/dist/source/artifact-resolver.js +215 -14
- package/dist/source/class-source.d.ts +21 -0
- package/dist/source/class-source.js +125 -28
- package/dist/source/did-you-mean.d.ts +12 -1
- package/dist/source/did-you-mean.js +6 -2
- package/dist/source/file-access.js +150 -46
- package/dist/source/indexer.js +1 -0
- package/dist/source/shared-utils.d.ts +21 -0
- package/dist/source/shared-utils.js +23 -0
- package/dist/source-service.d.ts +11 -0
- package/dist/stdio-supervisor.d.ts +357 -2
- package/dist/stdio-supervisor.js +1031 -80
- package/dist/storage/db.d.ts +2 -1
- package/dist/storage/db.js +15 -8
- package/dist/synthetic-decorator.d.ts +24 -0
- package/dist/synthetic-decorator.js +48 -0
- package/dist/tool-guidance.d.ts +17 -1
- package/dist/tool-guidance.js +309 -11
- package/dist/tool-schema-registry.d.ts +2 -0
- package/dist/tool-schema-registry.js +4 -0
- package/dist/tool-schemas.d.ts +2212 -3919
- package/dist/tool-schemas.js +33 -7
- package/dist/types.d.ts +35 -0
- package/dist/v1-parity-schemas.d.ts +7 -0
- package/dist/v1-parity-schemas.js +5584 -0
- package/dist/version-diff-service.d.ts +33 -0
- package/dist/version-diff-service.js +148 -3
- package/dist/version-service.js +36 -14
- package/dist/warning-details.js +18 -1
- package/docs/README-ja.md +5 -3
- package/docs/tool-reference.md +194 -19
- package/package.json +8 -5
|
@@ -2,6 +2,13 @@ import type { SourceService } from "../source-service.js";
|
|
|
2
2
|
export interface DidYouMeanCandidate {
|
|
3
3
|
className: string;
|
|
4
4
|
matchReason: string;
|
|
5
|
+
/**
|
|
6
|
+
* Set only when the candidate was found in an artifact OTHER than the one the caller
|
|
7
|
+
* named — today, the internal binary fallback or nested-jar redirect the lookup ended
|
|
8
|
+
* on. An unattributed candidate always means "in the artifact you asked about", so the
|
|
9
|
+
* field marks the exception rather than restating the common case on every entry.
|
|
10
|
+
*/
|
|
11
|
+
artifactId?: string;
|
|
5
12
|
}
|
|
6
13
|
/**
|
|
7
14
|
* Collects ranked near-miss class candidates from the artifact's symbol
|
|
@@ -10,5 +17,9 @@ export interface DidYouMeanCandidate {
|
|
|
10
17
|
* edit-distance suggestions. Candidates are hints, never assertions that the
|
|
11
18
|
* class exists at the suggested location. Returns an empty array when the
|
|
12
19
|
* index has nothing usable.
|
|
20
|
+
*
|
|
21
|
+
* `attributeTo` stamps every produced candidate with that artifact id; pass it when
|
|
22
|
+
* collecting from an artifact the caller did not name, and leave it unset for the
|
|
23
|
+
* requested artifact.
|
|
13
24
|
*/
|
|
14
|
-
export declare function collectDidYouMeanCandidates(svc: SourceService, artifactId: string, className: string): DidYouMeanCandidate[];
|
|
25
|
+
export declare function collectDidYouMeanCandidates(svc: SourceService, artifactId: string, className: string, attributeTo?: string): DidYouMeanCandidate[];
|
|
@@ -15,8 +15,12 @@ function fqnOfRow(row) {
|
|
|
15
15
|
* edit-distance suggestions. Candidates are hints, never assertions that the
|
|
16
16
|
* class exists at the suggested location. Returns an empty array when the
|
|
17
17
|
* index has nothing usable.
|
|
18
|
+
*
|
|
19
|
+
* `attributeTo` stamps every produced candidate with that artifact id; pass it when
|
|
20
|
+
* collecting from an artifact the caller did not name, and leave it unset for the
|
|
21
|
+
* requested artifact.
|
|
18
22
|
*/
|
|
19
|
-
export function collectDidYouMeanCandidates(svc, artifactId, className) {
|
|
23
|
+
export function collectDidYouMeanCandidates(svc, artifactId, className, attributeTo) {
|
|
20
24
|
try {
|
|
21
25
|
const simpleName = className.split(/[.$]/).at(-1) ?? className;
|
|
22
26
|
if (!simpleName) {
|
|
@@ -29,7 +33,7 @@ export function collectDidYouMeanCandidates(svc, artifactId, className) {
|
|
|
29
33
|
return;
|
|
30
34
|
}
|
|
31
35
|
seen.add(fqn);
|
|
32
|
-
out.push({ className: fqn, matchReason });
|
|
36
|
+
out.push({ className: fqn, matchReason, ...(attributeTo ? { artifactId: attributeTo } : {}) });
|
|
33
37
|
};
|
|
34
38
|
const exact = svc.symbolsRepo.findScopedSymbols({
|
|
35
39
|
artifactId,
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { basename } from "node:path";
|
|
2
|
+
import { buildSuggestedCall } from "../build-suggested-call.js";
|
|
2
3
|
import { ERROR_CODES, createError, isAppError } from "../errors.js";
|
|
3
4
|
import { log } from "../logger.js";
|
|
4
5
|
import { decodeJarEntryUtf8OrThrow, listJarEntries, readJarEntryCapped } from "../source-jar-reader.js";
|
|
5
6
|
import { normalizeOptionalString, normalizePathStyle } from "./shared-utils.js";
|
|
6
|
-
// Read-through delivery for non-indexed jar resources:
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
|
|
7
|
+
// Read-through delivery for non-indexed jar resources: any entry of the
|
|
8
|
+
// backing jar is served directly when the source index has no row for it.
|
|
9
|
+
//
|
|
10
|
+
// Delivery used to be gated on an `assets/`+`data/` path prefix, which made the
|
|
11
|
+
// two entries an agent reaches for FIRST when inspecting a mod jar —
|
|
12
|
+
// `fabric.mod.json` at the archive root and `META-INF/MANIFEST.MF` — permanently
|
|
13
|
+
// unreachable (ERR_FILE_NOT_FOUND) even though `assets/**` read-through proved
|
|
14
|
+
// the mechanism worked. The prefix carries no safety value: the real guards are
|
|
15
|
+
// the traversal-shaped path rejection, the per-file byte cap, and the
|
|
16
|
+
// text/binary classification below, and all three apply to every entry alike.
|
|
11
17
|
const READ_THROUGH_MAX_BYTES = 512 * 1024;
|
|
12
18
|
const READ_THROUGH_TEXT_EXTENSIONS = new Set([
|
|
13
19
|
".json",
|
|
@@ -24,23 +30,104 @@ const READ_THROUGH_TEXT_EXTENSIONS = new Set([
|
|
|
24
30
|
".md",
|
|
25
31
|
".fsh",
|
|
26
32
|
".vsh",
|
|
27
|
-
".glsl"
|
|
33
|
+
".glsl",
|
|
34
|
+
// Loader metadata that lives outside assets/ and data/.
|
|
35
|
+
".mf",
|
|
36
|
+
".accesswidener",
|
|
37
|
+
".xml"
|
|
38
|
+
]);
|
|
39
|
+
/**
|
|
40
|
+
* Extensions known to hold non-text payloads. Listing them keeps the common
|
|
41
|
+
* case a metadata-only probe: no bytes are read at all.
|
|
42
|
+
*/
|
|
43
|
+
const READ_THROUGH_BINARY_EXTENSIONS = new Set([
|
|
44
|
+
".class",
|
|
45
|
+
".png",
|
|
46
|
+
".jpg",
|
|
47
|
+
".jpeg",
|
|
48
|
+
".gif",
|
|
49
|
+
".bmp",
|
|
50
|
+
".webp",
|
|
51
|
+
".ico",
|
|
52
|
+
".jar",
|
|
53
|
+
".zip",
|
|
54
|
+
".gz",
|
|
55
|
+
".tar",
|
|
56
|
+
".ogg",
|
|
57
|
+
".wav",
|
|
58
|
+
".mp3",
|
|
59
|
+
".nbt",
|
|
60
|
+
".dat",
|
|
61
|
+
".bin",
|
|
62
|
+
".so",
|
|
63
|
+
".dll",
|
|
64
|
+
".dylib",
|
|
65
|
+
".ttf",
|
|
66
|
+
".otf",
|
|
67
|
+
".woff",
|
|
68
|
+
".woff2",
|
|
69
|
+
".pack",
|
|
70
|
+
".mca",
|
|
71
|
+
".rsa",
|
|
72
|
+
".dsa"
|
|
28
73
|
]);
|
|
29
74
|
const NEARBY_PATH_HINT_LIMIT = 5;
|
|
75
|
+
/** Ratio of C0 control bytes above which a sniffed entry counts as binary. */
|
|
76
|
+
const SNIFF_MAX_CONTROL_RATIO = 0.05;
|
|
30
77
|
function isTraversalShapedPath(filePath) {
|
|
31
78
|
return (filePath.startsWith("/") ||
|
|
32
79
|
filePath.includes("\u0000") ||
|
|
33
80
|
filePath.split(/[\\/]/).includes(".."));
|
|
34
81
|
}
|
|
35
|
-
function
|
|
36
|
-
return READ_THROUGH_PREFIXES.some((prefix) => filePath.startsWith(prefix));
|
|
37
|
-
}
|
|
38
|
-
function readThroughTextExtension(filePath) {
|
|
82
|
+
function classifyReadThroughEntry(filePath) {
|
|
39
83
|
const dot = filePath.lastIndexOf(".");
|
|
40
|
-
|
|
41
|
-
|
|
84
|
+
const slash = filePath.lastIndexOf("/");
|
|
85
|
+
if (dot < 0 || dot < slash) {
|
|
86
|
+
return "unknown";
|
|
87
|
+
}
|
|
88
|
+
const extension = filePath.slice(dot).toLowerCase();
|
|
89
|
+
if (READ_THROUGH_TEXT_EXTENSIONS.has(extension)) {
|
|
90
|
+
return "text";
|
|
91
|
+
}
|
|
92
|
+
if (READ_THROUGH_BINARY_EXTENSIONS.has(extension)) {
|
|
93
|
+
return "binary";
|
|
94
|
+
}
|
|
95
|
+
return "unknown";
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Decodes a capped buffer when it really is UTF-8 text, else reports binary.
|
|
99
|
+
* A NUL byte, a strict-UTF-8 decode failure, or a high C0 control-byte ratio
|
|
100
|
+
* all mean "do not hand this back as text".
|
|
101
|
+
*/
|
|
102
|
+
function sniffUtf8Text(buffer) {
|
|
103
|
+
if (buffer.length === 0) {
|
|
104
|
+
return "";
|
|
105
|
+
}
|
|
106
|
+
if (buffer.includes(0)) {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
let decoded;
|
|
110
|
+
try {
|
|
111
|
+
decoded = new TextDecoder("utf-8", { fatal: true }).decode(buffer);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
let control = 0;
|
|
117
|
+
for (const byte of buffer) {
|
|
118
|
+
if (byte < 0x20 && byte !== 0x09 && byte !== 0x0a && byte !== 0x0d) {
|
|
119
|
+
control += 1;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return control / buffer.length > SNIFF_MAX_CONTROL_RATIO ? undefined : decoded;
|
|
123
|
+
}
|
|
124
|
+
/** Trims a capped buffer back to a UTF-8 character boundary at `limit`. */
|
|
125
|
+
function trimToUtf8Boundary(buffer, limit) {
|
|
126
|
+
let cut = Math.min(limit, buffer.length);
|
|
127
|
+
while (cut > 0 && ((buffer[cut] ?? 0) & 0xc0) === 0x80) {
|
|
128
|
+
cut -= 1;
|
|
42
129
|
}
|
|
43
|
-
return
|
|
130
|
+
return buffer.subarray(0, cut);
|
|
44
131
|
}
|
|
45
132
|
/**
|
|
46
133
|
* Same-basename entries elsewhere in the jar, for not-found hints. Covers
|
|
@@ -52,7 +139,7 @@ async function collectNearbyPaths(binaryJarPath, missingPath) {
|
|
|
52
139
|
const wanted = basename(missingPath);
|
|
53
140
|
const entries = await listJarEntries(binaryJarPath);
|
|
54
141
|
return entries
|
|
55
|
-
.filter((entry) =>
|
|
142
|
+
.filter((entry) => basename(entry) === wanted)
|
|
56
143
|
.slice(0, NEARBY_PATH_HINT_LIMIT);
|
|
57
144
|
}
|
|
58
145
|
catch {
|
|
@@ -95,7 +182,7 @@ export async function getArtifactFile(svc, input) {
|
|
|
95
182
|
const artifact = svc.getArtifact(input.artifactId);
|
|
96
183
|
const normalizedPath = normalizePathStyle(input.filePath);
|
|
97
184
|
const row = svc.filesRepo.getFileContent(artifact.artifactId, normalizedPath);
|
|
98
|
-
if (!row &&
|
|
185
|
+
if (!row && artifact.binaryJarPath) {
|
|
99
186
|
return await readFileThroughJar(svc, {
|
|
100
187
|
artifact,
|
|
101
188
|
binaryJarPath: artifact.binaryJarPath,
|
|
@@ -108,7 +195,15 @@ export async function getArtifactFile(svc, input) {
|
|
|
108
195
|
throw createError({
|
|
109
196
|
code: ERROR_CODES.FILE_NOT_FOUND,
|
|
110
197
|
message: `Source file "${input.filePath}" was not found.`,
|
|
111
|
-
details: {
|
|
198
|
+
details: {
|
|
199
|
+
artifactId: input.artifactId,
|
|
200
|
+
filePath: input.filePath,
|
|
201
|
+
nextAction: "This artifact has no backing binary jar, so only indexed source files are reachable. List what is indexed with list-artifact-files.",
|
|
202
|
+
...buildSuggestedCall({
|
|
203
|
+
tool: "list-artifact-files",
|
|
204
|
+
params: { artifactId: input.artifactId, limit: 50 }
|
|
205
|
+
})
|
|
206
|
+
}
|
|
112
207
|
});
|
|
113
208
|
}
|
|
114
209
|
const maxBytes = clampLimit(input.maxBytes, svc.config.maxContentBytes, Number.MAX_SAFE_INTEGER);
|
|
@@ -145,16 +240,16 @@ export async function getArtifactFile(svc, input) {
|
|
|
145
240
|
}
|
|
146
241
|
async function readFileThroughJar(svc, args) {
|
|
147
242
|
const { artifact, binaryJarPath, filePath, artifactId } = args;
|
|
148
|
-
const
|
|
149
|
-
const cap =
|
|
150
|
-
?
|
|
151
|
-
:
|
|
243
|
+
const kind = classifyReadThroughEntry(filePath);
|
|
244
|
+
const cap = kind === "binary"
|
|
245
|
+
? 0
|
|
246
|
+
: Math.min(clampLimit(args.maxBytes, svc.config.maxContentBytes, Number.MAX_SAFE_INTEGER), READ_THROUGH_MAX_BYTES);
|
|
152
247
|
let capped;
|
|
153
248
|
try {
|
|
154
249
|
// Read at most the cap (+ slack to trim back to a UTF-8 boundary); an
|
|
155
|
-
// oversized entry is never fully materialized in memory.
|
|
156
|
-
// are metadata-only probes (no content read at all).
|
|
157
|
-
capped = await readJarEntryCapped(binaryJarPath, filePath,
|
|
250
|
+
// oversized entry is never fully materialized in memory. Known-binary
|
|
251
|
+
// entries are metadata-only probes (no content read at all).
|
|
252
|
+
capped = await readJarEntryCapped(binaryJarPath, filePath, kind === "binary" ? 0 : cap + 4);
|
|
158
253
|
}
|
|
159
254
|
catch (error) {
|
|
160
255
|
if (!isAppError(error) || error.code !== ERROR_CODES.SOURCE_NOT_FOUND) {
|
|
@@ -190,30 +285,37 @@ async function readFileThroughJar(svc, args) {
|
|
|
190
285
|
}),
|
|
191
286
|
deliveryMode: "jar-read-through"
|
|
192
287
|
};
|
|
193
|
-
|
|
288
|
+
const omitBinary = (reason) => ({
|
|
289
|
+
...base,
|
|
290
|
+
content: "",
|
|
291
|
+
contentBytes: capped.entrySize,
|
|
292
|
+
truncated: false,
|
|
293
|
+
contentOmittedReason: reason
|
|
294
|
+
});
|
|
295
|
+
if (kind === "binary") {
|
|
296
|
+
return omitBinary("Entry is not a known text format; binary content is not delivered. Size and existence are reported instead.");
|
|
297
|
+
}
|
|
298
|
+
const truncated = capped.entrySize > cap;
|
|
299
|
+
// Trim the capped prefix back to a UTF-8 character boundary before decoding;
|
|
300
|
+
// the tail past the cap is dropped by design.
|
|
301
|
+
const trimmed = truncated ? trimToUtf8Boundary(capped.buffer, cap) : capped.buffer;
|
|
302
|
+
if (kind === "unknown") {
|
|
303
|
+
// No extension to go on: decide from the bytes rather than refuse a text
|
|
304
|
+
// entry (META-INF/services/*, LICENSE files) on the strength of its name.
|
|
305
|
+
const sniffed = sniffUtf8Text(trimmed);
|
|
306
|
+
if (sniffed === undefined) {
|
|
307
|
+
return omitBinary("Entry has no known text extension and its bytes are not UTF-8 text; binary content is not delivered. Size and existence are reported instead.");
|
|
308
|
+
}
|
|
194
309
|
return {
|
|
195
310
|
...base,
|
|
196
|
-
content:
|
|
311
|
+
content: sniffed,
|
|
197
312
|
contentBytes: capped.entrySize,
|
|
198
|
-
truncated
|
|
199
|
-
contentOmittedReason: "Entry is not a known text format; binary content is not delivered. Size and existence are reported instead."
|
|
313
|
+
truncated
|
|
200
314
|
};
|
|
201
315
|
}
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
// Trim the capped prefix back to a UTF-8 character boundary before
|
|
206
|
-
// decoding; the tail past the cap is dropped by design.
|
|
207
|
-
const buffer = capped.buffer;
|
|
208
|
-
let cut = Math.min(cap, buffer.length);
|
|
209
|
-
while (cut > 0 && ((buffer[cut] ?? 0) & 0xc0) === 0x80) {
|
|
210
|
-
cut -= 1;
|
|
211
|
-
}
|
|
212
|
-
content = buffer.slice(0, cut).toString("utf8");
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
content = decodeJarEntryUtf8OrThrow(capped.buffer, binaryJarPath, filePath);
|
|
216
|
-
}
|
|
316
|
+
const content = truncated
|
|
317
|
+
? trimmed.toString("utf8")
|
|
318
|
+
: decodeJarEntryUtf8OrThrow(capped.buffer, binaryJarPath, filePath);
|
|
217
319
|
return {
|
|
218
320
|
...base,
|
|
219
321
|
content,
|
|
@@ -234,10 +336,12 @@ export async function listArtifactFiles(svc, input) {
|
|
|
234
336
|
prefix
|
|
235
337
|
});
|
|
236
338
|
const normalizedPrefix = normalizeOptionalString(prefix);
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
339
|
+
// A prefix that matched nothing is the exact moment read-through is worth
|
|
340
|
+
// naming: the index holds Java source only, while EVERY jar entry —
|
|
341
|
+
// archive-root files such as fabric.mod.json and META-INF/** included — is
|
|
342
|
+
// reachable by exact path.
|
|
343
|
+
if (normalizedPrefix && page.items.length === 0 && artifact.binaryJarPath) {
|
|
344
|
+
warnings.push("Indexed artifacts currently include Java source only; non-Java resources are not indexed. Any text entry of the backing jar — including archive-root files such as fabric.mod.json and META-INF/** — is served directly by exact path with get-artifact-file (read-through delivery).");
|
|
241
345
|
}
|
|
242
346
|
return {
|
|
243
347
|
items: page.items,
|
package/dist/source/indexer.js
CHANGED
|
@@ -252,6 +252,7 @@ export async function buildRebuiltArtifactData(svc, resolved) {
|
|
|
252
252
|
vineflowerJarPath: vineflowerPath,
|
|
253
253
|
artifactIdCandidate: resolved.artifactId,
|
|
254
254
|
timeoutMs: 120_000,
|
|
255
|
+
maxMemoryMb: svc.config.decompileMaxMemoryMb,
|
|
255
256
|
signature: resolved.artifactId
|
|
256
257
|
});
|
|
257
258
|
files = decompileResult.javaFiles.map((entry) => ({
|
|
@@ -2,5 +2,26 @@ import type { SourceMapping } from "../types.js";
|
|
|
2
2
|
export declare function normalizePathStyle(path: string): string;
|
|
3
3
|
export declare function normalizeOptionalString(value: string | undefined): string | undefined;
|
|
4
4
|
export declare function normalizeMapping(mapping: SourceMapping | undefined): SourceMapping;
|
|
5
|
+
/**
|
|
6
|
+
* The mapping an artifact-targeted call runs in when the caller left `mapping`
|
|
7
|
+
* out.
|
|
8
|
+
*
|
|
9
|
+
* A stored artifact already carries the namespace it was resolved into, so a
|
|
10
|
+
* follow-up call that names it by `artifactId` must inherit that namespace
|
|
11
|
+
* instead of falling back to the version-target default ("obfuscated").
|
|
12
|
+
* Without this, `find-class` -> `get-class-source` -> `get-class-members`
|
|
13
|
+
* split across two namespaces: source came back in mojang names while members
|
|
14
|
+
* came back obfuscated (`ownerFqn: "dlp"`), for the same artifact and the same
|
|
15
|
+
* absent `mapping` argument.
|
|
16
|
+
*
|
|
17
|
+
* `requestedMapping` wins over `mappingApplied` so the echoed request keeps
|
|
18
|
+
* meaning "what was asked for" even on artifacts where the mapping could not
|
|
19
|
+
* be applied; `mappingApplied` is the fallback for rows stored before the
|
|
20
|
+
* requested namespace was persisted.
|
|
21
|
+
*/
|
|
22
|
+
export declare function inheritArtifactMapping(inputMapping: SourceMapping | undefined, artifact: {
|
|
23
|
+
requestedMapping?: SourceMapping;
|
|
24
|
+
mappingApplied?: SourceMapping;
|
|
25
|
+
}): SourceMapping;
|
|
5
26
|
export declare function pathExists(filePath: string): Promise<boolean>;
|
|
6
27
|
export declare function dedupeQualityFlags(qualityFlags: readonly string[]): string[];
|
|
@@ -31,6 +31,29 @@ export function normalizeMapping(mapping) {
|
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* The mapping an artifact-targeted call runs in when the caller left `mapping`
|
|
36
|
+
* out.
|
|
37
|
+
*
|
|
38
|
+
* A stored artifact already carries the namespace it was resolved into, so a
|
|
39
|
+
* follow-up call that names it by `artifactId` must inherit that namespace
|
|
40
|
+
* instead of falling back to the version-target default ("obfuscated").
|
|
41
|
+
* Without this, `find-class` -> `get-class-source` -> `get-class-members`
|
|
42
|
+
* split across two namespaces: source came back in mojang names while members
|
|
43
|
+
* came back obfuscated (`ownerFqn: "dlp"`), for the same artifact and the same
|
|
44
|
+
* absent `mapping` argument.
|
|
45
|
+
*
|
|
46
|
+
* `requestedMapping` wins over `mappingApplied` so the echoed request keeps
|
|
47
|
+
* meaning "what was asked for" even on artifacts where the mapping could not
|
|
48
|
+
* be applied; `mappingApplied` is the fallback for rows stored before the
|
|
49
|
+
* requested namespace was persisted.
|
|
50
|
+
*/
|
|
51
|
+
export function inheritArtifactMapping(inputMapping, artifact) {
|
|
52
|
+
if (inputMapping != null) {
|
|
53
|
+
return normalizeMapping(inputMapping);
|
|
54
|
+
}
|
|
55
|
+
return artifact.requestedMapping ?? artifact.mappingApplied ?? normalizeMapping(undefined);
|
|
56
|
+
}
|
|
34
57
|
export async function pathExists(filePath) {
|
|
35
58
|
try {
|
|
36
59
|
await access(filePath);
|
package/dist/source-service.d.ts
CHANGED
|
@@ -268,11 +268,20 @@ export type FindClassMatch = {
|
|
|
268
268
|
filePath: string;
|
|
269
269
|
line: number;
|
|
270
270
|
symbolKind: string;
|
|
271
|
+
/** Set when the match is a type declared INSIDE another type. */
|
|
272
|
+
nested?: boolean;
|
|
273
|
+
/** The enclosing top-level type, present only on a nested match. */
|
|
274
|
+
enclosingClass?: string;
|
|
271
275
|
};
|
|
272
276
|
export type FindClassOutput = {
|
|
273
277
|
matches: FindClassMatch[];
|
|
274
278
|
total: number;
|
|
275
279
|
warnings: string[];
|
|
280
|
+
/** Recovery route when the index legitimately cannot answer (partial coverage). */
|
|
281
|
+
suggestedCall?: {
|
|
282
|
+
tool: string;
|
|
283
|
+
params: Record<string, unknown>;
|
|
284
|
+
};
|
|
276
285
|
};
|
|
277
286
|
type MemberAccess = "public" | "all";
|
|
278
287
|
export type GetClassMembersInput = {
|
|
@@ -638,6 +647,7 @@ export declare class SourceService {
|
|
|
638
647
|
requestedScope: ArtifactScope;
|
|
639
648
|
atNamespace: AccessTransformerNamespace;
|
|
640
649
|
loader: import("./workspace-mapping-service.js").WorkspaceProjectLoader | "unknown";
|
|
650
|
+
projectMinecraftVersion?: string;
|
|
641
651
|
}): ReturnType<typeof artifactResolver.discoverAccessTransformerRuntimeCandidates>;
|
|
642
652
|
buildMappingFallbackSuggestedCall(args: {
|
|
643
653
|
input: ResolveArtifactInput;
|
|
@@ -702,6 +712,7 @@ export declare class SourceService {
|
|
|
702
712
|
mappingApplied: SourceMapping;
|
|
703
713
|
provenance?: ArtifactProvenance;
|
|
704
714
|
qualityFlags: string[];
|
|
715
|
+
allowDecompile?: boolean;
|
|
705
716
|
}): Promise<ResolvedSourceArtifact | undefined>;
|
|
706
717
|
getArtifact(artifactId: string): ArtifactRow;
|
|
707
718
|
ingestIfNeeded(resolved: ResolvedSourceArtifact): Promise<void>;
|