@adhisang/minecraft-modding-mcp 1.2.1 → 2.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.
@@ -7,7 +7,7 @@ import { defaultDownloadPath, downloadToCache } from "./repo-downloader.js";
7
7
  import { listJarEntries, readJarEntryAsUtf8 } from "./source-jar-reader.js";
8
8
  import { VersionService, isUnobfuscatedVersion } from "./version-service.js";
9
9
  const SUPPORTED_MAPPINGS = new Set([
10
- "official",
10
+ "obfuscated",
11
11
  "mojang",
12
12
  "intermediary",
13
13
  "yarn"
@@ -254,7 +254,7 @@ const PROGUARD_PRIMITIVES = {
254
254
  /**
255
255
  * Convert a single proguard type (e.g. "int", "net.minecraft.Foo", "int[][]")
256
256
  * to JVM notation (e.g. "I", "Lnet/minecraft/Foo;", "[[I").
257
- * `classLookup` maps mojang class names → official class names (for the official descriptor).
257
+ * `classLookup` maps mojang class names → obfuscated class names (for the obfuscated descriptor).
258
258
  * Pass `undefined` to skip class name translation (for mojang descriptors).
259
259
  */
260
260
  function proguardTypeToJvm(type, classLookup) {
@@ -294,12 +294,12 @@ function parseProguardMethod(value, classLookup) {
294
294
  return { name, descriptor: `(${paramDescriptor})${returnDescriptor}` };
295
295
  }
296
296
  function parseClientMappings(text) {
297
- const officialToMojang = createDirectionIndex();
298
- const mojangToOfficial = createDirectionIndex();
297
+ const obfuscatedToMojang = createDirectionIndex();
298
+ const mojangToObfuscated = createDirectionIndex();
299
299
  // Two-pass parsing: first collect class name mappings, then parse members with descriptors.
300
300
  const lines = text.split(/\r?\n/);
301
- // Pass 1: collect class name mappings (mojang → official)
302
- const mojangToOfficialClass = new Map();
301
+ // Pass 1: collect class name mappings (mojang → obfuscated)
302
+ const mojangToObfuscatedClass = new Map();
303
303
  let classCount = 0;
304
304
  for (const rawLine of lines) {
305
305
  const line = rawLine.trim();
@@ -309,9 +309,9 @@ function parseClientMappings(text) {
309
309
  const classMatch = /^(.+?)\s+->\s+(.+):$/.exec(line);
310
310
  if (classMatch) {
311
311
  const mojangClass = classMatch[1]?.trim() ?? "";
312
- const officialClass = classMatch[2]?.trim() ?? "";
313
- if (mojangClass && officialClass) {
314
- mojangToOfficialClass.set(mojangClass, officialClass);
312
+ const obfuscatedClass = classMatch[2]?.trim() ?? "";
313
+ if (mojangClass && obfuscatedClass) {
314
+ mojangToObfuscatedClass.set(mojangClass, obfuscatedClass);
315
315
  classCount += 1;
316
316
  }
317
317
  }
@@ -332,17 +332,17 @@ function parseClientMappings(text) {
332
332
  const classMatch = /^(.+?)\s+->\s+(.+):$/.exec(line);
333
333
  if (classMatch) {
334
334
  const mojangClass = classMatch[1]?.trim() ?? "";
335
- const officialClass = classMatch[2]?.trim() ?? "";
336
- if (!mojangClass || !officialClass) {
335
+ const obfuscatedClass = classMatch[2]?.trim() ?? "";
336
+ if (!mojangClass || !obfuscatedClass) {
337
337
  currentClass = undefined;
338
338
  continue;
339
339
  }
340
340
  currentClass = {
341
- official: officialClass,
341
+ obfuscated: obfuscatedClass,
342
342
  mojang: mojangClass
343
343
  };
344
- addLookupEntries(officialToMojang, createClassSymbolRecord(officialClass), createClassSymbolRecord(mojangClass));
345
- addLookupEntries(mojangToOfficial, createClassSymbolRecord(mojangClass), createClassSymbolRecord(officialClass));
344
+ addLookupEntries(obfuscatedToMojang, createClassSymbolRecord(obfuscatedClass), createClassSymbolRecord(mojangClass));
345
+ addLookupEntries(mojangToObfuscated, createClassSymbolRecord(mojangClass), createClassSymbolRecord(obfuscatedClass));
346
346
  continue;
347
347
  }
348
348
  if (!currentClass) {
@@ -359,31 +359,31 @@ function parseClientMappings(text) {
359
359
  }
360
360
  const mojangMemberSignature = stripLineInfo(leftRaw);
361
361
  // Try method parsing with JVM descriptor
362
- const officialMethod = parseProguardMethod(mojangMemberSignature, mojangToOfficialClass);
363
- if (officialMethod) {
362
+ const obfuscatedMethod = parseProguardMethod(mojangMemberSignature, mojangToObfuscatedClass);
363
+ if (obfuscatedMethod) {
364
364
  const mojangMethod = parseProguardMethod(mojangMemberSignature, undefined);
365
- const officialDescriptor = officialMethod.descriptor;
365
+ const obfuscatedDescriptor = obfuscatedMethod.descriptor;
366
366
  const mojangDescriptor = mojangMethod?.descriptor;
367
- addLookupEntries(officialToMojang, createMethodSymbolRecord(currentClass.official, rightRaw, officialDescriptor), createMethodSymbolRecord(currentClass.mojang, officialMethod.name, mojangDescriptor));
368
- addLookupEntries(mojangToOfficial, createMethodSymbolRecord(currentClass.mojang, officialMethod.name, mojangDescriptor), createMethodSymbolRecord(currentClass.official, rightRaw, officialDescriptor));
367
+ addLookupEntries(obfuscatedToMojang, createMethodSymbolRecord(currentClass.obfuscated, rightRaw, obfuscatedDescriptor), createMethodSymbolRecord(currentClass.mojang, obfuscatedMethod.name, mojangDescriptor));
368
+ addLookupEntries(mojangToObfuscated, createMethodSymbolRecord(currentClass.mojang, obfuscatedMethod.name, mojangDescriptor), createMethodSymbolRecord(currentClass.obfuscated, rightRaw, obfuscatedDescriptor));
369
369
  continue;
370
370
  }
371
371
  const fieldName = parseFieldName(mojangMemberSignature);
372
372
  if (!fieldName) {
373
373
  continue;
374
374
  }
375
- addLookupEntries(officialToMojang, createFieldSymbolRecord(currentClass.official, rightRaw), createFieldSymbolRecord(currentClass.mojang, fieldName));
376
- addLookupEntries(mojangToOfficial, createFieldSymbolRecord(currentClass.mojang, fieldName), createFieldSymbolRecord(currentClass.official, rightRaw));
375
+ addLookupEntries(obfuscatedToMojang, createFieldSymbolRecord(currentClass.obfuscated, rightRaw), createFieldSymbolRecord(currentClass.mojang, fieldName));
376
+ addLookupEntries(mojangToObfuscated, createFieldSymbolRecord(currentClass.mojang, fieldName), createFieldSymbolRecord(currentClass.obfuscated, rightRaw));
377
377
  }
378
378
  const result = new Map();
379
- result.set(pairKey("official", "mojang"), officialToMojang);
380
- result.set(pairKey("mojang", "official"), mojangToOfficial);
379
+ result.set(pairKey("obfuscated", "mojang"), obfuscatedToMojang);
380
+ result.set(pairKey("mojang", "obfuscated"), mojangToObfuscated);
381
381
  return result;
382
382
  }
383
383
  function normalizeTinyNamespace(namespace) {
384
384
  const normalized = namespace.trim().toLowerCase();
385
- if (normalized === "official") {
386
- return "official";
385
+ if (normalized === "obfuscated") {
386
+ return "obfuscated";
387
387
  }
388
388
  if (normalized === "mojang") {
389
389
  return "mojang";
@@ -973,8 +973,8 @@ export class MappingService {
973
973
  sourceMapping,
974
974
  targetMapping,
975
975
  sourcePriority: priority,
976
- nextAction: "Try mapping=official which is always available.",
977
- suggestedCall: { tool: "resolve-artifact", params: { mapping: "official" } }
976
+ nextAction: "Try mapping=obfuscated which is always available.",
977
+ suggestedCall: { tool: "resolve-artifact", params: { mapping: "obfuscated" } }
978
978
  }
979
979
  });
980
980
  }
@@ -1000,16 +1000,10 @@ export class MappingService {
1000
1000
  }
1001
1001
  });
1002
1002
  }
1003
- if (input.kind !== "method") {
1004
- throw createError({
1005
- code: ERROR_CODES.INVALID_INPUT,
1006
- message: 'resolveMethodMappingExact requires kind="method".',
1007
- details: {
1008
- kind: input.kind
1009
- }
1010
- });
1011
- }
1012
- const { record: queryRecord, querySymbol } = normalizeQuerySymbol(input);
1003
+ const { record: queryRecord, querySymbol } = normalizeQuerySymbol({
1004
+ ...input,
1005
+ kind: "method"
1006
+ });
1013
1007
  const owner = queryRecord.owner;
1014
1008
  const method = queryRecord.name;
1015
1009
  const descriptor = queryRecord.descriptor;
@@ -1159,7 +1153,7 @@ export class MappingService {
1159
1153
  classByMapping[mapping] = mapped[0];
1160
1154
  }
1161
1155
  }
1162
- const baseMapping = classByMapping.official ? "official" : classNameMapping;
1156
+ const baseMapping = classByMapping.obfuscated ? "obfuscated" : classNameMapping;
1163
1157
  const baseClass = classByMapping[baseMapping];
1164
1158
  if (!baseClass) {
1165
1159
  return {
@@ -1167,7 +1161,7 @@ export class MappingService {
1167
1161
  className,
1168
1162
  classNameMapping,
1169
1163
  classIdentity: {
1170
- official: classByMapping.official?.symbol,
1164
+ obfuscated: classByMapping.obfuscated?.symbol,
1171
1165
  mojang: classByMapping.mojang?.symbol,
1172
1166
  intermediary: classByMapping.intermediary?.symbol,
1173
1167
  yarn: classByMapping.yarn?.symbol
@@ -1255,7 +1249,7 @@ export class MappingService {
1255
1249
  };
1256
1250
  row[mapping] = entry;
1257
1251
  }
1258
- row.completeness = Boolean(row.official && row.mojang && row.intermediary && row.yarn);
1252
+ row.completeness = Boolean(row.obfuscated && row.mojang && row.intermediary && row.yarn);
1259
1253
  rows.push(row);
1260
1254
  if (rowHadAmbiguity) {
1261
1255
  ambiguousRowCount += 1;
@@ -1266,7 +1260,7 @@ export class MappingService {
1266
1260
  className,
1267
1261
  classNameMapping,
1268
1262
  classIdentity: {
1269
- official: classByMapping.official?.symbol,
1263
+ obfuscated: classByMapping.obfuscated?.symbol,
1270
1264
  mojang: classByMapping.mojang?.symbol,
1271
1265
  intermediary: classByMapping.intermediary?.symbol,
1272
1266
  yarn: classByMapping.yarn?.symbol
@@ -1568,16 +1562,16 @@ export class MappingService {
1568
1562
  if (!tinyAvailable) {
1569
1563
  degradations.push("No intermediary/yarn tiny mappings were found for this version.");
1570
1564
  }
1571
- // Check if member remap path exists (requestedMapping → official)
1565
+ // Check if member remap path exists (requestedMapping → obfuscated)
1572
1566
  let memberRemapAvailable = false;
1573
- if (input.requestedMapping === "official") {
1567
+ if (input.requestedMapping === "obfuscated") {
1574
1568
  memberRemapAvailable = true;
1575
1569
  }
1576
1570
  else {
1577
- const path = namespacePath(graph.pairs, input.requestedMapping, "official");
1571
+ const path = namespacePath(graph.pairs, input.requestedMapping, "obfuscated");
1578
1572
  memberRemapAvailable = path != null && path.length > 1;
1579
1573
  if (!memberRemapAvailable) {
1580
- degradations.push(`No mapping path from ${input.requestedMapping} to official; member remap will fail.`);
1574
+ degradations.push(`No mapping path from ${input.requestedMapping} to obfuscated; member remap will fail.`);
1581
1575
  }
1582
1576
  }
1583
1577
  return {
@@ -1618,7 +1612,7 @@ export class MappingService {
1618
1612
  priority,
1619
1613
  pairs: new Map(),
1620
1614
  warnings: [
1621
- `Version ${version} is unobfuscated; mapping graph is empty (official names are final).`
1615
+ `Version ${version} is unobfuscated; mapping graph is empty because the runtime already uses deobfuscated names.`
1622
1616
  ]
1623
1617
  };
1624
1618
  }
@@ -1,5 +1,13 @@
1
1
  import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
2
- export declare function objectResult<T extends Record<string, unknown>>(data: T): CallToolResult;
2
+ import { type ErrorCode } from "./errors.js";
3
+ type ObjectResultOptions = {
4
+ isError?: boolean;
5
+ };
6
+ export declare function objectResult<T extends Record<string, unknown>>(data: T, options?: ObjectResultOptions): CallToolResult;
3
7
  export declare function textResource(uri: string, value: string): ReadResourceResult;
4
8
  export declare function objectResource(uri: string, data: Record<string, unknown>): ReadResourceResult;
5
- export declare function errorResource(uri: string, message: string): ReadResourceResult;
9
+ export declare function errorResource(uri: string, error: string | {
10
+ message: string;
11
+ code?: ErrorCode;
12
+ }): ReadResourceResult;
13
+ export {};
@@ -1,13 +1,67 @@
1
- export function objectResult(data) {
2
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
1
+ import { ERROR_CODES } from "./errors.js";
2
+ export function objectResult(data, options = {}) {
3
+ return {
4
+ content: [{ type: "text", text: JSON.stringify(data) }],
5
+ structuredContent: data,
6
+ ...(options.isError ? { isError: true } : {})
7
+ };
3
8
  }
4
9
  export function textResource(uri, value) {
5
10
  return { contents: [{ uri, text: value }] };
6
11
  }
7
12
  export function objectResource(uri, data) {
8
- return { contents: [{ uri, text: JSON.stringify(data) }] };
13
+ return {
14
+ contents: [
15
+ {
16
+ uri,
17
+ mimeType: "application/json",
18
+ text: JSON.stringify({
19
+ result: data,
20
+ meta: { uri }
21
+ })
22
+ }
23
+ ]
24
+ };
9
25
  }
10
- export function errorResource(uri, message) {
11
- return { contents: [{ uri, text: JSON.stringify({ error: message }) }] };
26
+ function statusForResourceErrorCode(code) {
27
+ if (code === ERROR_CODES.INVALID_INPUT) {
28
+ return 400;
29
+ }
30
+ if (code === ERROR_CODES.FILE_NOT_FOUND ||
31
+ code === ERROR_CODES.SOURCE_NOT_FOUND ||
32
+ code === ERROR_CODES.CLASS_NOT_FOUND ||
33
+ code === ERROR_CODES.VERSION_NOT_FOUND ||
34
+ code === ERROR_CODES.JAR_NOT_FOUND) {
35
+ return 404;
36
+ }
37
+ if (code === ERROR_CODES.MAPPING_UNAVAILABLE ||
38
+ code === ERROR_CODES.MAPPING_NOT_APPLIED ||
39
+ code === ERROR_CODES.NAMESPACE_MISMATCH) {
40
+ return 422;
41
+ }
42
+ return 500;
43
+ }
44
+ export function errorResource(uri, error) {
45
+ const detail = typeof error === "string" ? error : error.message;
46
+ const code = typeof error === "string" ? ERROR_CODES.INVALID_INPUT : error.code ?? ERROR_CODES.INTERNAL;
47
+ return {
48
+ contents: [
49
+ {
50
+ uri,
51
+ mimeType: "application/json",
52
+ text: JSON.stringify({
53
+ error: {
54
+ type: "https://minecraft-modding-mcp.dev/problems/resource",
55
+ title: "Resource read failed",
56
+ detail,
57
+ status: statusForResourceErrorCode(code),
58
+ code,
59
+ instance: uri
60
+ },
61
+ meta: { uri }
62
+ })
63
+ }
64
+ ]
65
+ };
12
66
  }
13
67
  //# sourceMappingURL=mcp-helpers.js.map
@@ -1,5 +1,5 @@
1
1
  import type { Config } from "./types.js";
2
- export type MappingNamespace = "official" | "mojang" | "yarn";
2
+ export type MappingNamespace = "obfuscated" | "mojang" | "yarn";
3
3
  type SignatureAccess = "public" | "all";
4
4
  export interface ResponseContext {
5
5
  minecraftVersion: string;
@@ -531,7 +531,7 @@ export class MinecraftExplorerService {
531
531
  return {
532
532
  minecraftVersion: extractVersionFromPath(jarPath) ?? "unknown",
533
533
  mappingType: "unknown",
534
- mappingNamespace: "official",
534
+ mappingNamespace: "obfuscated",
535
535
  jarHash: artifactSignatureFromFile(jarPath).sourceArtifactId,
536
536
  generatedAt: new Date().toISOString()
537
537
  };
@@ -161,7 +161,7 @@ function validateInjection(inj, targetMembers, targetNames, issues, resolvedMemb
161
161
  const isSigFailed = signatureFailedTargets?.has(targetName);
162
162
  const issueConfidence = isRemapFailed ? "uncertain" : confidence;
163
163
  const issueConfidenceReason = isRemapFailed
164
- ? `Member remap from official→mapping failed; name mismatch may be a remap artifact, not a true missing member.`
164
+ ? `Member remap from obfuscated→mapping failed; name mismatch may be a remap artifact, not a true missing member.`
165
165
  : confidenceReason;
166
166
  const resolutionPath = isRemapFailed
167
167
  ? "member-remap-failed"
@@ -207,7 +207,7 @@ function validateShadow(shadow, targetMembers, targetNames, issues, resolvedMemb
207
207
  const isSigFailed = signatureFailedTargets?.has(targetName);
208
208
  const issueConfidence = isRemapFailed ? "uncertain" : confidence;
209
209
  const issueConfidenceReason = isRemapFailed
210
- ? `Member remap from official→mapping failed; name mismatch may be a remap artifact, not a true missing member.`
210
+ ? `Member remap from obfuscated→mapping failed; name mismatch may be a remap artifact, not a true missing member.`
211
211
  : confidenceReason;
212
212
  const resolutionPath = isRemapFailed
213
213
  ? "member-remap-failed"
@@ -274,7 +274,7 @@ function validateAccessor(accessor, targetMembers, targetNames, issues, resolved
274
274
  const isSigFailed = signatureFailedTargets?.has(targetName);
275
275
  const issueConfidence = isRemapFailed ? "uncertain" : confidence;
276
276
  const issueConfidenceReason = isRemapFailed
277
- ? `Member remap from official→mapping failed; name mismatch may be a remap artifact, not a true missing member.`
277
+ ? `Member remap from obfuscated→mapping failed; name mismatch may be a remap artifact, not a true missing member.`
278
278
  : confidenceReason;
279
279
  const resolutionPath = isRemapFailed
280
280
  ? "member-remap-failed"
@@ -323,9 +323,9 @@ export function validateParsedMixin(parsed, targetMembers, warnings, provenance,
323
323
  kind: "target-mapping-failed",
324
324
  annotation: "@Mixin",
325
325
  target: target.className,
326
- message: `Could not map target class "${target.className}" to official namespace; class may still exist under a different mapping.`,
326
+ message: `Could not map target class "${target.className}" to obfuscated namespace; class may still exist under a different mapping.`,
327
327
  confidence: "uncertain",
328
- confidenceReason: `Mapping from "${provenance?.requestedMapping}" to official failed for this class.`,
328
+ confidenceReason: `Mapping from "${provenance?.requestedMapping}" to obfuscated failed for this class.`,
329
329
  category: "mapping",
330
330
  resolutionPath: "target-mapping-failed",
331
331
  falsePositiveRisk: healthReport?.overallHealthy === false ? "high" : "medium"
@@ -30,13 +30,13 @@ function parseProguardMappings(text) {
30
30
  const classMatch = /^(.+?)\s+->\s+(.+):$/.exec(line);
31
31
  if (classMatch) {
32
32
  const mojangFqn = normalizeFqn(classMatch[1] ?? "");
33
- const officialInternal = normalizeInternalName(classMatch[2] ?? "");
34
- if (!mojangFqn || !officialInternal) {
33
+ const obfuscatedInternal = normalizeInternalName(classMatch[2] ?? "");
34
+ if (!mojangFqn || !obfuscatedInternal) {
35
35
  currentClass = undefined;
36
36
  continue;
37
37
  }
38
38
  currentClass = mojangFqn;
39
- classes.push({ mojangFqn, officialInternal });
39
+ classes.push({ mojangFqn, obfuscatedInternal });
40
40
  continue;
41
41
  }
42
42
  if (!currentClass) {
@@ -47,14 +47,14 @@ function parseProguardMappings(text) {
47
47
  continue;
48
48
  }
49
49
  const leftRaw = stripLineInfo(line.slice(0, arrowIndex));
50
- const officialName = line.slice(arrowIndex + 4).trim();
51
- if (!leftRaw || !officialName) {
50
+ const obfuscatedName = line.slice(arrowIndex + 4).trim();
51
+ if (!leftRaw || !obfuscatedName) {
52
52
  continue;
53
53
  }
54
54
  members.push({
55
55
  ownerMojangFqn: currentClass,
56
56
  leftSignature: leftRaw,
57
- officialName
57
+ obfuscatedName
58
58
  });
59
59
  }
60
60
  return { classes, members };
@@ -164,8 +164,8 @@ function normalizeMemberMappings(rawMappings, classMap, warnings) {
164
164
  const seen = new Set();
165
165
  for (const mapping of rawMappings) {
166
166
  for (const member of mapping.members) {
167
- const ownerOfficial = classMap.get(normalizeFqn(member.ownerMojangFqn));
168
- if (!ownerOfficial) {
167
+ const ownerObfuscated = classMap.get(normalizeFqn(member.ownerMojangFqn));
168
+ if (!ownerObfuscated) {
169
169
  warnings.push(`Skipping member mapping for "${member.ownerMojangFqn}" because class mapping is missing.`);
170
170
  continue;
171
171
  }
@@ -183,7 +183,7 @@ function normalizeMemberMappings(rawMappings, classMap, warnings) {
183
183
  record = {
184
184
  kind: "m",
185
185
  descriptor,
186
- officialName: member.officialName,
186
+ obfuscatedName: member.obfuscatedName,
187
187
  mojangName
188
188
  };
189
189
  }
@@ -203,19 +203,19 @@ function normalizeMemberMappings(rawMappings, classMap, warnings) {
203
203
  record = {
204
204
  kind: "f",
205
205
  descriptor,
206
- officialName: member.officialName,
206
+ obfuscatedName: member.obfuscatedName,
207
207
  mojangName
208
208
  };
209
209
  }
210
- const dedupeKey = `${ownerOfficial}|${record.kind}|${record.officialName}|` +
210
+ const dedupeKey = `${ownerObfuscated}|${record.kind}|${record.obfuscatedName}|` +
211
211
  `${record.mojangName}|${record.descriptor}`;
212
212
  if (seen.has(dedupeKey)) {
213
213
  continue;
214
214
  }
215
215
  seen.add(dedupeKey);
216
- const list = membersByOwner.get(ownerOfficial) ?? [];
216
+ const list = membersByOwner.get(ownerObfuscated) ?? [];
217
217
  list.push(record);
218
- membersByOwner.set(ownerOfficial, list);
218
+ membersByOwner.set(ownerObfuscated, list);
219
219
  }
220
220
  }
221
221
  return membersByOwner;
@@ -225,38 +225,38 @@ function mergeClasses(rawMappings, warnings) {
225
225
  for (const mapping of rawMappings) {
226
226
  for (const clazz of mapping.classes) {
227
227
  const mojang = normalizeFqn(clazz.mojangFqn);
228
- const official = normalizeInternalName(clazz.officialInternal);
228
+ const obfuscated = normalizeInternalName(clazz.obfuscatedInternal);
229
229
  const existing = classMap.get(mojang);
230
- if (existing && existing !== official) {
231
- warnings.push(`Conflicting class mapping for "${mojang}" (${existing} vs ${official}); keeping first.`);
230
+ if (existing && existing !== obfuscated) {
231
+ warnings.push(`Conflicting class mapping for "${mojang}" (${existing} vs ${obfuscated}); keeping first.`);
232
232
  continue;
233
233
  }
234
- classMap.set(mojang, official);
234
+ classMap.set(mojang, obfuscated);
235
235
  }
236
236
  }
237
237
  return classMap;
238
238
  }
239
239
  function renderTinyV2(classMap, membersByOwner) {
240
240
  const classEntries = [...classMap.entries()]
241
- .map(([mojangFqn, officialInternal]) => ({
242
- officialInternal,
241
+ .map(([mojangFqn, obfuscatedInternal]) => ({
242
+ obfuscatedInternal,
243
243
  mojangInternal: mojangFqn.replace(/\./g, "/")
244
244
  }))
245
- .sort((left, right) => left.officialInternal.localeCompare(right.officialInternal));
246
- const lines = ["tiny\t2\t0\tofficial\tmojang"];
245
+ .sort((left, right) => left.obfuscatedInternal.localeCompare(right.obfuscatedInternal));
246
+ const lines = ["tiny\t2\t0\tobfuscated\tmojang"];
247
247
  for (const entry of classEntries) {
248
- lines.push(`c\t${entry.officialInternal}\t${entry.mojangInternal}`);
249
- const members = [...(membersByOwner.get(entry.officialInternal) ?? [])].sort((left, right) => {
248
+ lines.push(`c\t${entry.obfuscatedInternal}\t${entry.mojangInternal}`);
249
+ const members = [...(membersByOwner.get(entry.obfuscatedInternal) ?? [])].sort((left, right) => {
250
250
  if (left.kind !== right.kind) {
251
251
  return left.kind.localeCompare(right.kind);
252
252
  }
253
- if (left.officialName !== right.officialName) {
254
- return left.officialName.localeCompare(right.officialName);
253
+ if (left.obfuscatedName !== right.obfuscatedName) {
254
+ return left.obfuscatedName.localeCompare(right.obfuscatedName);
255
255
  }
256
256
  return left.descriptor.localeCompare(right.descriptor);
257
257
  });
258
258
  for (const member of members) {
259
- lines.push(`\t${member.kind}\t${member.descriptor}\t${member.officialName}\t${member.mojangName}`);
259
+ lines.push(`\t${member.kind}\t${member.descriptor}\t${member.obfuscatedName}\t${member.mojangName}`);
260
260
  }
261
261
  }
262
262
  return `${lines.join("\n")}\n`;
package/dist/resources.js CHANGED
@@ -30,7 +30,7 @@ export function registerResources(server, sourceService) {
30
30
  }
31
31
  catch (e) {
32
32
  if (isAppError(e))
33
- return errorResource(uri.href, e.message);
33
+ return errorResource(uri.href, { message: e.message, code: e.code });
34
34
  throw e;
35
35
  }
36
36
  });
@@ -41,7 +41,7 @@ export function registerResources(server, sourceService) {
41
41
  }
42
42
  catch (e) {
43
43
  if (isAppError(e))
44
- return errorResource(uri.href, e.message);
44
+ return errorResource(uri.href, { message: e.message, code: e.code });
45
45
  throw e;
46
46
  }
47
47
  });
@@ -56,7 +56,7 @@ export function registerResources(server, sourceService) {
56
56
  }
57
57
  catch (e) {
58
58
  if (isAppError(e))
59
- return errorResource(uri.href, e.message);
59
+ return errorResource(uri.href, { message: e.message, code: e.code });
60
60
  throw e;
61
61
  }
62
62
  });
@@ -70,7 +70,7 @@ export function registerResources(server, sourceService) {
70
70
  }
71
71
  catch (e) {
72
72
  if (isAppError(e))
73
- return errorResource(uri.href, e.message);
73
+ return errorResource(uri.href, { message: e.message, code: e.code });
74
74
  throw e;
75
75
  }
76
76
  });
@@ -87,7 +87,7 @@ export function registerResources(server, sourceService) {
87
87
  }
88
88
  catch (e) {
89
89
  if (isAppError(e))
90
- return errorResource(uri.href, e.message);
90
+ return errorResource(uri.href, { message: e.message, code: e.code });
91
91
  throw e;
92
92
  }
93
93
  });
@@ -101,7 +101,7 @@ export function registerResources(server, sourceService) {
101
101
  }
102
102
  catch (e) {
103
103
  if (isAppError(e))
104
- return errorResource(uri.href, e.message);
104
+ return errorResource(uri.href, { message: e.message, code: e.code });
105
105
  throw e;
106
106
  }
107
107
  });
@@ -112,7 +112,7 @@ export function registerResources(server, sourceService) {
112
112
  }
113
113
  catch (e) {
114
114
  if (isAppError(e))
115
- return errorResource(uri.href, e.message);
115
+ return errorResource(uri.href, { message: e.message, code: e.code });
116
116
  throw e;
117
117
  }
118
118
  });
@@ -9,9 +9,6 @@ export type SearchSourceHit = {
9
9
  filePath: string;
10
10
  score: number;
11
11
  matchedIn: "symbol" | "path" | "content";
12
- startLine: number;
13
- endLine: number;
14
- snippet: string;
15
12
  reasonCodes: string[];
16
13
  symbol?: SearchResultSymbol;
17
14
  };
@@ -12,8 +12,8 @@ export function scoreHitOrder(left, right) {
12
12
  if (symbolCompare !== 0) {
13
13
  return symbolCompare;
14
14
  }
15
- const leftLine = left.symbol?.line ?? left.startLine;
16
- const rightLine = right.symbol?.line ?? right.startLine;
15
+ const leftLine = left.symbol?.line ?? 0;
16
+ const rightLine = right.symbol?.line ?? 0;
17
17
  return leftLine - rightLine;
18
18
  }
19
19
  export function encodeSearchCursor(hit, contextKey) {
@@ -21,7 +21,7 @@ export function encodeSearchCursor(hit, contextKey) {
21
21
  score: hit.score,
22
22
  filePath: hit.filePath,
23
23
  symbolName: hit.symbol?.symbolName ?? "",
24
- line: hit.symbol?.line ?? hit.startLine,
24
+ line: hit.symbol?.line ?? 0,
25
25
  contextKey
26
26
  }), "utf8").toString("base64");
27
27
  }
@@ -66,7 +66,7 @@ export function isAfterSearchCursor(hit, cursor) {
66
66
  if (symbolCompare < 0) {
67
67
  return false;
68
68
  }
69
- const hitLine = hit.symbol?.line ?? hit.startLine;
69
+ const hitLine = hit.symbol?.line ?? 0;
70
70
  return hitLine > cursor.line;
71
71
  }
72
72
  /**
@@ -1,6 +1,7 @@
1
1
  import type { Config, ResolvedSourceArtifact, SourceTargetInput } from "./types.js";
2
2
  export interface ResolveSourceTargetOptions {
3
3
  allowDecompile: boolean;
4
+ preferBinaryOnly?: boolean;
4
5
  preferredRepos?: string[];
5
6
  onRepoFailover?: (event: {
6
7
  stage: "source" | "binary";