@adhisang/minecraft-modding-mcp 3.2.0 → 4.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +25 -18
  3. package/dist/cache-registry.d.ts +1 -1
  4. package/dist/cache-registry.js +10 -2
  5. package/dist/config.d.ts +10 -1
  6. package/dist/config.js +52 -1
  7. package/dist/entry-tools/analyze-symbol-service.d.ts +2 -2
  8. package/dist/entry-tools/analyze-symbol-service.js +13 -2
  9. package/dist/entry-tools/inspect-minecraft-service.d.ts +20 -20
  10. package/dist/entry-tools/inspect-minecraft-service.js +8 -2
  11. package/dist/entry-tools/manage-cache-service.d.ts +4 -4
  12. package/dist/entry-tools/validate-project-service.js +84 -4
  13. package/dist/index.js +99 -33
  14. package/dist/lru-list.d.ts +31 -0
  15. package/dist/lru-list.js +102 -0
  16. package/dist/mapping-pipeline-service.d.ts +10 -1
  17. package/dist/mapping-pipeline-service.js +13 -1
  18. package/dist/mapping-service.d.ts +12 -0
  19. package/dist/mapping-service.js +252 -10
  20. package/dist/mixin-validator.js +22 -7
  21. package/dist/observability.d.ts +18 -1
  22. package/dist/observability.js +44 -1
  23. package/dist/response-utils.d.ts +44 -10
  24. package/dist/response-utils.js +131 -17
  25. package/dist/source-resolver.d.ts +9 -1
  26. package/dist/source-resolver.js +14 -6
  27. package/dist/source-service.d.ts +97 -1
  28. package/dist/source-service.js +922 -113
  29. package/dist/storage/artifacts-repo.d.ts +4 -1
  30. package/dist/storage/artifacts-repo.js +33 -5
  31. package/dist/storage/files-repo.d.ts +0 -2
  32. package/dist/storage/files-repo.js +0 -11
  33. package/dist/storage/migrations.d.ts +1 -1
  34. package/dist/storage/migrations.js +10 -2
  35. package/dist/storage/schema.d.ts +2 -0
  36. package/dist/storage/schema.js +25 -0
  37. package/dist/types.d.ts +3 -0
  38. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,31 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project aims to follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [4.0.0] - 2026-04-18
9
+
10
+ ### Changed
11
+ - BREAKING: `resolve-artifact`, `find-mapping`, `resolve-method-mapping-exact`, `resolve-workspace-symbol`, and `check-symbol-exists` now default `compact` to `true` (was `false`). Pass `compact: false` to restore the full diagnostic shape.
12
+ - BREAKING: `find-mapping`, `resolve-method-mapping-exact`, `resolve-workspace-symbol`, `check-symbol-exists`, and `analyze-symbol` now default `maxCandidates` to `5` (was `200`; `200` is still the upper bound).
13
+ - BREAKING: `find-mapping` now defaults `signatureMode` to `"name-only"` (was effectively `"exact"`). `kind="method"` lookups without a `descriptor` no longer fail; pass `signatureMode: "exact"` explicitly for strict descriptor matching.
14
+ - BREAKING: `resolve-artifact` with `mapping="mojang"` and `target.kind="version"` against a still-obfuscated Minecraft version now succeeds by tiny-remapping the binary jar and decompiling the result, tagged `qualityFlags: ["binary-remapped", "decompiled"]` and `provenance.transformChain: ["binary-remap:obf->mojang", "decompile:vineflower"]`. The remapped jar is cached at `<cacheDir>/remapped/<artifactId>.jar`. Coordinate and jar targets are not eligible. `ERR_MAPPING_NOT_APPLIED` is still raised when tiny-remapper, the Mojang tiny mapping file, or the version's Mojang mappings are missing.
15
+ - `find-mapping` and `check-symbol-exists` accept an empty `descriptor` as equivalent to omitting it.
16
+ - Compact mode on mapping tools keeps the top three unresolved candidates with full metadata and slims the tail to `{kind, symbol, owner, name, descriptor, confidence, matchKind}`. A new `candidateDetailsTruncated` flag signals this slim, distinct from the existing `candidatesTruncated` (upstream truncation).
17
+
18
+ ### Added
19
+ - `find-mapping` exposes `signatureMode` as a first-class input. `"exact"` matches `owner + name + descriptor`; `"name-only"` matches by `owner + name` and ranks overloads by confidence. `resolve-method-mapping-exact` retains strict exact-triple semantics.
20
+ - `get-class-source`, `get-class-members`, `search-class-source`, and `list-artifact-files` accept an opt-in `compact` parameter (default `false`). It strips diagnostic envelopes (`provenance`, `artifactContents`, `qualityFlags`, plus `context` for `get-class-members`) while preserving primary payloads (`sourceText`, `members`/`counts`, `hits`, `items`).
21
+ - `manage-cache` exposes the Mojang remapped jar under a new `binary-remap` cache kind with `selector.artifactId` filtering. LRU eviction unlinks the matching remapped jar so cache accounting stays consistent.
22
+ - `validate-mixin` top-level errors now carry `failedStage` on the `ProblemDetails` envelope (one of `input-validation | resolve | mapping-health | parse | target-lookup`), so callers can branch without parsing `message`.
23
+ - `validate-mixin` `quickSummary` appends notes when `provenance.scopeFallback` fires or `toolHealth.overallHealthy` is false.
24
+ - Ambiguous mapping responses in `find-mapping`, `resolve-method-mapping-exact`, and `check-symbol-exists` include recovery guidance in `warnings` (descriptor hints, `signatureMode="exact"` retries, `disambiguation.ownerHint`, raising `maxCandidates`).
25
+ - `docs/tool-reference.md` includes a "Which Tool for Which Question" decision table; `README.md` links to it from the Documentation section.
26
+
27
+ ### Fixed
28
+ - `check-symbol-exists` projects the caller's JVM descriptor to the obfuscated namespace before filtering method overloads, so `signatureMode="exact"` retries work with descriptors that reference remapped Minecraft classes. Mixed descriptors such as `(Lnet/minecraft/world/item/ItemStack;Ljava/lang/String;)V` resolve via partial projection instead of falling back to the unprojected source descriptor.
29
+ - `find-mapping` with `signatureMode="exact"` and `kind="method"` filters resolved candidates by the (projected) requested descriptor. A caller who supplied `foo(Z)V` is no longer told that `foo(I)V` is the exact mapping.
30
+ - Compact mode slim candidate projection retains `kind` and `symbol` alongside `owner`, `name`, `descriptor`, `confidence`, and `matchKind`, so clients keying off `kind` or `symbol` are no longer silently broken.
31
+ - `normalizeMethodDescriptor` rejects descriptors with more than 255 leading `[` (JVM §4.3.2) and rejects malformed shapes such as `()`, `(I)`, and `(L;)V` with `ERR_INVALID_INPUT`.
32
+
8
33
  ## [3.2.0] - 2026-04-12
9
34
 
10
35
  ### Added
package/README.md CHANGED
@@ -5,15 +5,15 @@
5
5
  [![Node.js >=22](https://img.shields.io/badge/node-%3E%3D22-brightgreen.svg)](https://nodejs.org/)
6
6
  [![CI](https://github.com/adhi-jp/minecraft-modding-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/adhi-jp/minecraft-modding-mcp/actions/workflows/ci.yml)
7
7
 
8
- **[日本語](docs/README-ja.md)** | English
8
+ **English** | [日本語](docs/README-ja.md)
9
9
 
10
- ---
10
+ > **Note**: This project is entirely vibe-coded — built with AI-assisted development without formal specs.
11
11
 
12
- `@adhisang/minecraft-modding-mcp` is an [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that gives AI assistants structured access to Minecraft source code, mappings, mod JARs, registry data, and validation workflows.
12
+ ---
13
13
 
14
- [MCP](https://modelcontextprotocol.io/) is an open protocol that lets AI assistants call external tools through a structured interface. This server works with Claude Desktop, Claude Code, VS Code, Codex CLI, Gemini CLI, and other MCP-capable clients.
14
+ `@adhisang/minecraft-modding-mcp` is an [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that gives AI assistants structured access to Minecraft source code, mappings, mod JARs, registry data, and validation workflows. It works with Claude Desktop, Claude Code, VS Code, Codex CLI, Gemini CLI, and other MCP-capable clients.
15
15
 
16
- **35 tools** (6 entry + 29 expert) | **7 resources** | **4 namespace mappings** | **SQLite-backed cache**
16
+ **36 tools** (6 entry + 30 expert) | **7 resources** | **4 namespace mappings** | **SQLite-backed cache**
17
17
 
18
18
  ## Features
19
19
 
@@ -47,8 +47,17 @@ If automatic JAR downloads are blocked in your environment, set `MCP_VINEFLOWER_
47
47
 
48
48
  CLI clients:
49
49
 
50
- - `Claude Code`: `claude mcp add minecraft-modding -- npx -y @adhisang/minecraft-modding-mcp`
51
- - `OpenAI Codex CLI`: `codex mcp add minecraft-modding -- npx -y @adhisang/minecraft-modding-mcp`
50
+ Claude Code:
51
+
52
+ ```bash
53
+ claude mcp add minecraft-modding -- npx -y @adhisang/minecraft-modding-mcp
54
+ ```
55
+
56
+ OpenAI Codex CLI:
57
+
58
+ ```bash
59
+ codex mcp add minecraft-modding -- npx -y @adhisang/minecraft-modding-mcp
60
+ ```
52
61
 
53
62
  Run `claude mcp list` or `codex mcp list` after registration to verify the server is available.
54
63
 
@@ -146,11 +155,9 @@ Keep only the high-frequency notes here. For the full pitfall list, exact contra
146
155
  - `search-class-source` defaults to `queryMode="auto"` and keeps separator queries such as `foo.bar`, `foo_bar`, and `foo$bar` on the indexed path. Use `queryMode="literal"` for an explicit full substring scan.
147
156
  - If you do not already have an artifact, prefer `subject.kind="workspace"` for `inspect-minecraft` instead of guessing artifact details. When artifact context is the only missing input, a retryable `suggestedCall` preserves the requested task.
148
157
  - `trace-symbol-lifecycle` expects `Class.method` in `symbol`. Keep exact overload matching in the separate `descriptor` field.
149
- - Workspace inspection can still confirm vanilla classes when source coverage is partial, and `inspect-minecraft task="list-files"` reports a partial result with follow-up guidance when that happens.
150
- - `check-symbol-exists` and `analyze-symbol task="exists"` now validate `mojang` lookups on unobfuscated releases such as `26.1+` against runtime bytecode when no mapping graph exists, preserve the original `mapping_unavailable` result if the runtime JAR itself cannot be resolved, and return a targeted warning when callers provide only a short class name.
151
- - `analyze-mod` and `validate-project` still require structured `subject` objects and canonical `include` groups, but stale string-subject or domain-include payloads now return `ERR_INVALID_INPUT` with a retryable `suggestedCall`.
152
- - `validate-project task="project-summary"` now pre-resolves `preferProjectVersion=true` consistently across discovered Access Widener, Access Transformer, and Mixin checks, and blocks with version-agnostic recovery guidance when discovered validators need a version but neither the request nor `gradle.properties` can supply one.
153
- - Local source-jar probing, decompiled mod source reads, and workspace discovery now avoid synchronous hot-path ZIP/file scans and use bounded concurrent reads where safe, so cold `resolve-artifact`, `analyze-mod`, and `validate-project` workflows stay more responsive on larger jars and multi-module workspaces.
158
+ - For unobfuscated releases such as `26.1+`, `check-symbol-exists` and `analyze-symbol task="exists"` validate `mojang` lookups against runtime bytecode when no mapping graph exists, and return `mapping_unavailable` when the runtime JAR itself is unreachable.
159
+ - `analyze-mod` and `validate-project` require structured `subject` objects and canonical `include` groups; stale string-subject or domain-include payloads return `ERR_INVALID_INPUT` with a retryable `suggestedCall`.
160
+ - `validate-project task="project-summary"` propagates `preferProjectVersion=true` across discovered Mixin, Access Widener, and Access Transformer checks. When no version can be resolved from the request or `gradle.properties`, the summary blocks with version-agnostic recovery guidance.
154
161
 
155
162
  ### Inspect Minecraft source from a version
156
163
 
@@ -232,7 +239,7 @@ Workspace summaries still default to discovering mixins and access wideners. Add
232
239
  ## Documentation
233
240
 
234
241
  - [Detailed example requests](docs/examples.md) for copyable payloads and common workflows
235
- - [Tool and configuration reference](docs/tool-reference.md) for exact inputs, outputs, resource behavior, environment variables, and migration notes
242
+ - [Tool and configuration reference](docs/tool-reference.md) for exact inputs, outputs, resource behavior, environment variables, and migration notes — start with the [Which Tool for Which Question](docs/tool-reference.md#which-tool-for-which-question) decision table when you are not sure which tool to call
236
243
  - [日本語 README](docs/README-ja.md) for a Japanese onboarding overview
237
244
 
238
245
  ## Tool Surface
@@ -270,7 +277,7 @@ Tools for browsing Minecraft versions, resolving source artifacts, and reading o
270
277
  | `index-artifact` | Rebuild indexed metadata for an existing artifact |
271
278
  <!-- END GENERATED TOOL TABLE: source-exploration -->
272
279
 
273
- For unobfuscated releases such as `26.1+`, `mapping="mojang"` now uses the runtime/decompile path directly for version and versioned-coordinate targets and skips Loom source-jar discovery entirely, while `intermediary` and `yarn` still fall back to `obfuscated` with a warning.
280
+ For unobfuscated releases such as `26.1+`, `mapping="mojang"` uses the runtime/decompile path directly and skips Loom source-jar discovery, while `intermediary` and `yarn` fall back to `obfuscated` with a warning.
274
281
 
275
282
  ### Version Comparison & Symbol Tracking
276
283
 
@@ -298,7 +305,9 @@ Tools for converting symbol names between namespaces and checking symbol existen
298
305
  | `check-symbol-exists` | Check whether a class, field, or method exists in a namespace |
299
306
  <!-- END GENERATED TOOL TABLE: mapping-symbols -->
300
307
 
301
- `resolve-artifact`, `find-mapping`, `resolve-method-mapping-exact`, `resolve-workspace-symbol`, and `check-symbol-exists` accept an optional `compact` parameter (default `false`). When `true`, empty arrays, null values, and empty objects are stripped from the top-level response to reduce token overhead. For `resolve-artifact`, compact mode additionally omits diagnostic fields (`provenance`, `artifactContents`, `sampleEntries`, `adjacentSourceCandidates`, `binaryJarPath`, `coordinate`, `repoUrl`, `resolvedSourceJarPath`), returning only the essential fields needed for downstream tool calls. For mapping tools, compact mode omits the redundant `candidates` array when the result is a single full-confidence exact-match resolution (`resolved=true`, `resolvedSymbol` present, `candidates.length=1`, `candidateCount=1`, `!candidatesTruncated`, `matchKind="exact"`, `confidence` missing or `1`).
308
+ `resolve-artifact`, `find-mapping`, `resolve-method-mapping-exact`, `resolve-workspace-symbol`, and `check-symbol-exists` default `compact` to `true`: empty fields are stripped, `resolve-artifact` omits diagnostic fields (`provenance`, `artifactContents`, etc.), and mapping tools omit the redundant `candidates` array on full-confidence exact matches and slim the tail to `{kind, symbol, owner, name, descriptor, confidence, matchKind}` (signalled by `candidateDetailsTruncated`) for unresolved results with more than three candidates. Pass `compact: false` for the full diagnostic shape.
309
+
310
+ `get-class-source`, `get-class-members`, `search-class-source`, and `list-artifact-files` accept the same `compact` parameter as opt-in (default `false`). When enabled it strips `provenance`, `artifactContents`, `qualityFlags`, and (for `get-class-members`) `context`, while preserving primary payloads (`sourceText`, `members`/`counts`, `hits`, `items`). See [docs/tool-reference.md](docs/tool-reference.md) for the full per-tool field list.
302
311
 
303
312
  ### NBT Utilities
304
313
 
@@ -328,9 +337,7 @@ Tools for extracting metadata from mod JARs, decompiling mod source, searching m
328
337
 
329
338
  ### Validation
330
339
 
331
- Tools for validating Mixin source, Access Widener files, and Forge/NeoForge Access Transformer files against a target Minecraft version.
332
- `validate-access-widener` keeps vanilla bytecode validation by default, and now also supports runtime-aware validation through `projectPath`, `scope`, and `preferProjectVersion`, returning runtime `provenance` plus per-entry `resolvedRuntimeAccess` evidence when that mode is used. Runtime-aware method validation now preserves remapped JVM descriptors across namespace changes, searches Loom tiny mappings from workspace and Gradle user-home caches, and prefers explicit `*merged-intermediary*` / `*merged-mojang*` jars over ambiguous `minecraft-merged.jar` candidates.
333
- `validate-access-transformer` infers `atNamespace` from Forge or NeoForge workspace context when `projectPath` is provided, validates packaged or inline AT content, and uses loader/runtime artifacts for `scope="loader"` instead of treating loader as a merged-only alias.
340
+ Tools for validating Mixin source, Access Widener files, and Forge/NeoForge Access Transformer files against a target Minecraft version. `validate-access-widener` defaults to vanilla bytecode validation; pass `projectPath`, `scope`, and `preferProjectVersion` for runtime-aware mode, which returns runtime `provenance` plus per-entry `resolvedRuntimeAccess` evidence. `validate-access-transformer` infers `atNamespace` from Forge/NeoForge workspace context when `projectPath` is provided and uses loader runtime artifacts for `scope="loader"`.
334
341
 
335
342
  <!-- BEGIN GENERATED TOOL TABLE: validation -->
336
343
  | Tool | Purpose |
@@ -1,5 +1,5 @@
1
1
  import { type PathRuntimeInfo } from "./path-converter.js";
2
- export declare const PUBLIC_CACHE_KINDS: readonly ["artifact-index", "downloads", "mapping", "registry", "decompiled-source", "mod-remap"];
2
+ export declare const PUBLIC_CACHE_KINDS: readonly ["artifact-index", "downloads", "mapping", "registry", "decompiled-source", "mod-remap", "binary-remap"];
3
3
  export type PublicCacheKind = (typeof PUBLIC_CACHE_KINDS)[number];
4
4
  export declare const CACHE_HEALTH_STATES: readonly ["healthy", "partial", "stale", "orphaned", "corrupt", "in_use"];
5
5
  export type CacheHealthState = (typeof CACHE_HEALTH_STATES)[number];
@@ -10,7 +10,8 @@ export const PUBLIC_CACHE_KINDS = [
10
10
  "mapping",
11
11
  "registry",
12
12
  "decompiled-source",
13
- "mod-remap"
13
+ "mod-remap",
14
+ "binary-remap"
14
15
  ];
15
16
  export const CACHE_HEALTH_STATES = [
16
17
  "healthy",
@@ -37,6 +38,8 @@ function kindRoot(config, cacheKind) {
37
38
  return join(config.cacheDir, "decompiled");
38
39
  case "mod-remap":
39
40
  return join(config.cacheDir, "remapped-mods");
41
+ case "binary-remap":
42
+ return join(config.cacheDir, "remapped");
40
43
  }
41
44
  }
42
45
  async function listFilesRecursive(root) {
@@ -439,7 +442,12 @@ async function fileBackedEntries(config, cacheKind) {
439
442
  inUse: filePath.endsWith(".lock") ||
440
443
  filePath.endsWith(".wal") ||
441
444
  filePath.endsWith(".journal"),
442
- ...(cacheKind === "downloads" || cacheKind === "mod-remap" ? { jarPath: filePath } : {})
445
+ ...(cacheKind === "downloads" || cacheKind === "mod-remap" || cacheKind === "binary-remap"
446
+ ? { jarPath: filePath }
447
+ : {}),
448
+ ...(cacheKind === "binary-remap"
449
+ ? { artifactId: normalizedEntryId.replace(/\.jar$/i, "") }
450
+ : {})
443
451
  }
444
452
  });
445
453
  }
package/dist/config.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Config } from "./types.js";
1
+ import type { ArtifactTargetKind, Config, MappingVariant } from "./types.js";
2
2
  declare const DEFAULTS: {
3
3
  readonly cacheDir: "~/.cache/minecraft-modding-mcp";
4
4
  readonly sourceRepos: readonly ["https://repo1.maven.org/maven2", "https://maven.fabricmc.net", "https://maven.minecraftforge.net", "https://maven.neoforged.net/releases"];
@@ -24,4 +24,13 @@ declare const DEFAULTS: {
24
24
  };
25
25
  export declare function loadConfig(): Config;
26
26
  export declare function stableArtifactId(parts: string[]): string;
27
+ export interface ArtifactAliasInput {
28
+ artifactId: string;
29
+ kind: ArtifactTargetKind;
30
+ value: string;
31
+ mappingVariant?: MappingVariant;
32
+ resolvedVersion?: string;
33
+ coordinate?: string;
34
+ }
35
+ export declare function buildArtifactAlias(input: ArtifactAliasInput): string;
27
36
  export { DEFAULTS };
package/dist/config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { homedir } from "node:os";
3
- import { isAbsolute, resolve } from "node:path";
3
+ import { basename, isAbsolute, resolve } from "node:path";
4
4
  import { normalizePathForHost } from "./path-converter.js";
5
5
  const DEFAULTS = {
6
6
  cacheDir: "~/.cache/minecraft-modding-mcp",
@@ -182,5 +182,56 @@ export function stableArtifactId(parts) {
182
182
  .join("|");
183
183
  return createHash("sha256").update(normalizer).digest("hex");
184
184
  }
185
+ // 12 hex chars (48 bits) of artifactId entropy keeps alias collisions astronomically
186
+ // unlikely while staying short enough to copy/paste. A shorter prefix would let two
187
+ // distinct artifacts whose readable tokens (kind, version, mapping, scope, variant)
188
+ // happen to match share an alias and trip the schema-v4 UNIQUE constraint.
189
+ const ARTIFACT_ALIAS_HASH_LEN = 12;
190
+ function slugifyAliasPart(value) {
191
+ return value
192
+ .toLowerCase()
193
+ .replace(/[^a-z0-9]+/g, "-")
194
+ .replace(/^-+|-+$/g, "");
195
+ }
196
+ function aliasJarBase(jarPath) {
197
+ const base = basename(jarPath);
198
+ return base.toLowerCase().endsWith(".jar") ? base.slice(0, -4) : base;
199
+ }
200
+ // Generates a deterministic, human-readable alias canonical to the artifact row.
201
+ // The alias is 1:1 with `artifactId`: only dimensions baked into `artifactId`
202
+ // itself (kind, value/version/coordinate, mappingVariant) appear in the alias,
203
+ // plus a 12-hex-char (48-bit) suffix taken from `artifactId`. Request-level
204
+ // dimensions like `mapping` and `scope` are intentionally excluded — including
205
+ // them would make resolveArtifact rotate the alias for the same row whenever
206
+ // a caller passed a different mapping/scope, breaking aliases already returned
207
+ // to earlier callers. Two distinct artifactIds whose readable tokens collide and
208
+ // whose first 48 hash bits also collide would trip the schema-v4 alias UNIQUE
209
+ // constraint at upsert time — a hard error, not silent drift.
210
+ // Phase 3.1a: display-only. Phase 3.1b stores it for lookup.
211
+ export function buildArtifactAlias(input) {
212
+ const tokens = [];
213
+ if (input.kind === "version") {
214
+ tokens.push("mc", input.resolvedVersion ?? input.value);
215
+ }
216
+ else if (input.kind === "coordinate") {
217
+ tokens.push("coord", input.coordinate ?? input.value);
218
+ }
219
+ else {
220
+ tokens.push("jar", aliasJarBase(input.value));
221
+ }
222
+ // mappingVariant is canonical — `artifactIdForJar` / `artifactIdForCoordinate`
223
+ // bake "mojang-remapped" into the artifactId, so the same artifactId always
224
+ // produces the same alias regardless of how many times resolveArtifact is
225
+ // called. The token here is purely a human-readable hint; the 12-char hash
226
+ // suffix would already separate remapped artifacts from pass-through ones.
227
+ if (input.mappingVariant === "mojang-remapped") {
228
+ tokens.push("remapped");
229
+ }
230
+ tokens.push(input.artifactId.slice(0, ARTIFACT_ALIAS_HASH_LEN));
231
+ return tokens
232
+ .map(slugifyAliasPart)
233
+ .filter(Boolean)
234
+ .join("-");
235
+ }
185
236
  export { DEFAULTS };
186
237
  //# sourceMappingURL=config.js.map
@@ -6,7 +6,7 @@ export declare const analyzeSymbolShape: {
6
6
  kind: z.ZodEnum<["class", "method", "field", "symbol"]>;
7
7
  name: z.ZodString;
8
8
  owner: z.ZodOptional<z.ZodString>;
9
- descriptor: z.ZodOptional<z.ZodString>;
9
+ descriptor: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
10
10
  }, "strip", z.ZodTypeAny, {
11
11
  name: string;
12
12
  kind: "symbol" | "class" | "field" | "method";
@@ -37,7 +37,7 @@ export declare const analyzeSymbolSchema: z.ZodEffects<z.ZodObject<{
37
37
  kind: z.ZodEnum<["class", "method", "field", "symbol"]>;
38
38
  name: z.ZodString;
39
39
  owner: z.ZodOptional<z.ZodString>;
40
- descriptor: z.ZodOptional<z.ZodString>;
40
+ descriptor: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
41
41
  }, "strip", z.ZodTypeAny, {
42
42
  name: string;
43
43
  kind: "symbol" | "class" | "field" | "method";
@@ -4,6 +4,17 @@ import { buildIncludeSchema, detailSchema, positiveIntSchema } from "./entry-too
4
4
  import { buildEntryToolResult, createSummarySubject } from "./response-contract.js";
5
5
  import { resolveDetail, resolveInclude } from "./request-normalizers.js";
6
6
  const nonEmptyString = z.string().trim().min(1);
7
+ // Descriptor field that treats empty/whitespace strings as omitted so callers can pass
8
+ // `descriptor: ""` interchangeably with omitting the field when signatureMode="name-only".
9
+ const optionalDescriptorString = z
10
+ .string()
11
+ .optional()
12
+ .transform((value) => {
13
+ if (value === undefined)
14
+ return undefined;
15
+ const trimmed = value.trim();
16
+ return trimmed.length === 0 ? undefined : trimmed;
17
+ });
7
18
  const INCLUDE_GROUPS = ["warnings", "candidates", "matrix", "workspace", "timings"];
8
19
  const TASKS = ["exists", "map", "exact-map", "lifecycle", "workspace", "api-overview"];
9
20
  export const analyzeSymbolShape = {
@@ -12,7 +23,7 @@ export const analyzeSymbolShape = {
12
23
  kind: z.enum(["class", "method", "field", "symbol"]),
13
24
  name: nonEmptyString,
14
25
  owner: nonEmptyString.optional(),
15
- descriptor: nonEmptyString.optional()
26
+ descriptor: optionalDescriptorString
16
27
  }),
17
28
  version: nonEmptyString.optional(),
18
29
  sourceMapping: z.enum(["obfuscated", "mojang", "intermediary", "yarn"]).optional(),
@@ -23,7 +34,7 @@ export const analyzeSymbolShape = {
23
34
  nameMode: z.enum(["fqcn", "auto"]).default("fqcn"),
24
35
  includeKinds: z.array(z.enum(["class", "field", "method"])).optional(),
25
36
  maxRows: positiveIntSchema.optional(),
26
- maxCandidates: positiveIntSchema.default(200),
37
+ maxCandidates: positiveIntSchema.default(5),
27
38
  detail: detailSchema.optional(),
28
39
  include: buildIncludeSchema(INCLUDE_GROUPS)
29
40
  };
@@ -292,6 +292,7 @@ export declare const inspectMinecraftShape: {
292
292
  queryMode: "auto" | "token" | "literal";
293
293
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
294
294
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
295
+ packagePrefix?: string | undefined;
295
296
  intent?: "symbol" | "path" | "text" | undefined;
296
297
  fileGlob?: string | undefined;
297
298
  artifact?: {
@@ -304,12 +305,12 @@ export declare const inspectMinecraftShape: {
304
305
  value: string;
305
306
  };
306
307
  } | undefined;
307
- packagePrefix?: string | undefined;
308
308
  }, {
309
309
  kind: "search";
310
310
  query: string;
311
311
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
312
312
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
313
+ packagePrefix?: string | undefined;
313
314
  intent?: "symbol" | "path" | "text" | undefined;
314
315
  fileGlob?: string | undefined;
315
316
  artifact?: {
@@ -322,7 +323,6 @@ export declare const inspectMinecraftShape: {
322
323
  value: string;
323
324
  };
324
325
  } | undefined;
325
- packagePrefix?: string | undefined;
326
326
  queryMode?: "auto" | "token" | "literal" | undefined;
327
327
  }>, z.ZodObject<{
328
328
  kind: z.ZodLiteral<"workspace">;
@@ -506,6 +506,7 @@ export declare const inspectMinecraftShape: {
506
506
  queryMode: "auto" | "token" | "literal";
507
507
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
508
508
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
509
+ packagePrefix?: string | undefined;
509
510
  intent?: "symbol" | "path" | "text" | undefined;
510
511
  fileGlob?: string | undefined;
511
512
  artifact?: {
@@ -518,12 +519,12 @@ export declare const inspectMinecraftShape: {
518
519
  value: string;
519
520
  };
520
521
  } | undefined;
521
- packagePrefix?: string | undefined;
522
522
  }, {
523
523
  kind: "search";
524
524
  query: string;
525
525
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
526
526
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
527
+ packagePrefix?: string | undefined;
527
528
  intent?: "symbol" | "path" | "text" | undefined;
528
529
  fileGlob?: string | undefined;
529
530
  artifact?: {
@@ -536,7 +537,6 @@ export declare const inspectMinecraftShape: {
536
537
  value: string;
537
538
  };
538
539
  } | undefined;
539
- packagePrefix?: string | undefined;
540
540
  queryMode?: "auto" | "token" | "literal" | undefined;
541
541
  }>]>>;
542
542
  }, "strip", z.ZodTypeAny, {
@@ -578,6 +578,7 @@ export declare const inspectMinecraftShape: {
578
578
  queryMode: "auto" | "token" | "literal";
579
579
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
580
580
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
581
+ packagePrefix?: string | undefined;
581
582
  intent?: "symbol" | "path" | "text" | undefined;
582
583
  fileGlob?: string | undefined;
583
584
  artifact?: {
@@ -590,7 +591,6 @@ export declare const inspectMinecraftShape: {
590
591
  value: string;
591
592
  };
592
593
  } | undefined;
593
- packagePrefix?: string | undefined;
594
594
  } | undefined;
595
595
  }, {
596
596
  kind: "workspace";
@@ -630,6 +630,7 @@ export declare const inspectMinecraftShape: {
630
630
  query: string;
631
631
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
632
632
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
633
+ packagePrefix?: string | undefined;
633
634
  intent?: "symbol" | "path" | "text" | undefined;
634
635
  fileGlob?: string | undefined;
635
636
  artifact?: {
@@ -642,7 +643,6 @@ export declare const inspectMinecraftShape: {
642
643
  value: string;
643
644
  };
644
645
  } | undefined;
645
- packagePrefix?: string | undefined;
646
646
  queryMode?: "auto" | "token" | "literal" | undefined;
647
647
  } | undefined;
648
648
  }>]>>;
@@ -943,6 +943,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
943
943
  queryMode: "auto" | "token" | "literal";
944
944
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
945
945
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
946
+ packagePrefix?: string | undefined;
946
947
  intent?: "symbol" | "path" | "text" | undefined;
947
948
  fileGlob?: string | undefined;
948
949
  artifact?: {
@@ -955,12 +956,12 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
955
956
  value: string;
956
957
  };
957
958
  } | undefined;
958
- packagePrefix?: string | undefined;
959
959
  }, {
960
960
  kind: "search";
961
961
  query: string;
962
962
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
963
963
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
964
+ packagePrefix?: string | undefined;
964
965
  intent?: "symbol" | "path" | "text" | undefined;
965
966
  fileGlob?: string | undefined;
966
967
  artifact?: {
@@ -973,7 +974,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
973
974
  value: string;
974
975
  };
975
976
  } | undefined;
976
- packagePrefix?: string | undefined;
977
977
  queryMode?: "auto" | "token" | "literal" | undefined;
978
978
  }>, z.ZodObject<{
979
979
  kind: z.ZodLiteral<"workspace">;
@@ -1157,6 +1157,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1157
1157
  queryMode: "auto" | "token" | "literal";
1158
1158
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1159
1159
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1160
+ packagePrefix?: string | undefined;
1160
1161
  intent?: "symbol" | "path" | "text" | undefined;
1161
1162
  fileGlob?: string | undefined;
1162
1163
  artifact?: {
@@ -1169,12 +1170,12 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1169
1170
  value: string;
1170
1171
  };
1171
1172
  } | undefined;
1172
- packagePrefix?: string | undefined;
1173
1173
  }, {
1174
1174
  kind: "search";
1175
1175
  query: string;
1176
1176
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1177
1177
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1178
+ packagePrefix?: string | undefined;
1178
1179
  intent?: "symbol" | "path" | "text" | undefined;
1179
1180
  fileGlob?: string | undefined;
1180
1181
  artifact?: {
@@ -1187,7 +1188,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1187
1188
  value: string;
1188
1189
  };
1189
1190
  } | undefined;
1190
- packagePrefix?: string | undefined;
1191
1191
  queryMode?: "auto" | "token" | "literal" | undefined;
1192
1192
  }>]>>;
1193
1193
  }, "strip", z.ZodTypeAny, {
@@ -1229,6 +1229,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1229
1229
  queryMode: "auto" | "token" | "literal";
1230
1230
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1231
1231
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1232
+ packagePrefix?: string | undefined;
1232
1233
  intent?: "symbol" | "path" | "text" | undefined;
1233
1234
  fileGlob?: string | undefined;
1234
1235
  artifact?: {
@@ -1241,7 +1242,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1241
1242
  value: string;
1242
1243
  };
1243
1244
  } | undefined;
1244
- packagePrefix?: string | undefined;
1245
1245
  } | undefined;
1246
1246
  }, {
1247
1247
  kind: "workspace";
@@ -1281,6 +1281,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1281
1281
  query: string;
1282
1282
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1283
1283
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1284
+ packagePrefix?: string | undefined;
1284
1285
  intent?: "symbol" | "path" | "text" | undefined;
1285
1286
  fileGlob?: string | undefined;
1286
1287
  artifact?: {
@@ -1293,7 +1294,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1293
1294
  value: string;
1294
1295
  };
1295
1296
  } | undefined;
1296
- packagePrefix?: string | undefined;
1297
1297
  queryMode?: "auto" | "token" | "literal" | undefined;
1298
1298
  } | undefined;
1299
1299
  }>]>>;
@@ -1369,6 +1369,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1369
1369
  queryMode: "auto" | "token" | "literal";
1370
1370
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1371
1371
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1372
+ packagePrefix?: string | undefined;
1372
1373
  intent?: "symbol" | "path" | "text" | undefined;
1373
1374
  fileGlob?: string | undefined;
1374
1375
  artifact?: {
@@ -1381,7 +1382,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1381
1382
  value: string;
1382
1383
  };
1383
1384
  } | undefined;
1384
- packagePrefix?: string | undefined;
1385
1385
  } | {
1386
1386
  kind: "workspace";
1387
1387
  projectPath: string;
@@ -1421,6 +1421,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1421
1421
  queryMode: "auto" | "token" | "literal";
1422
1422
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1423
1423
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1424
+ packagePrefix?: string | undefined;
1424
1425
  intent?: "symbol" | "path" | "text" | undefined;
1425
1426
  fileGlob?: string | undefined;
1426
1427
  artifact?: {
@@ -1433,7 +1434,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1433
1434
  value: string;
1434
1435
  };
1435
1436
  } | undefined;
1436
- packagePrefix?: string | undefined;
1437
1437
  } | undefined;
1438
1438
  } | undefined;
1439
1439
  detail?: "full" | "summary" | "standard" | undefined;
@@ -1504,6 +1504,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1504
1504
  query: string;
1505
1505
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1506
1506
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1507
+ packagePrefix?: string | undefined;
1507
1508
  intent?: "symbol" | "path" | "text" | undefined;
1508
1509
  fileGlob?: string | undefined;
1509
1510
  artifact?: {
@@ -1516,7 +1517,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1516
1517
  value: string;
1517
1518
  };
1518
1519
  } | undefined;
1519
- packagePrefix?: string | undefined;
1520
1520
  queryMode?: "auto" | "token" | "literal" | undefined;
1521
1521
  } | {
1522
1522
  kind: "workspace";
@@ -1556,6 +1556,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1556
1556
  query: string;
1557
1557
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1558
1558
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1559
+ packagePrefix?: string | undefined;
1559
1560
  intent?: "symbol" | "path" | "text" | undefined;
1560
1561
  fileGlob?: string | undefined;
1561
1562
  artifact?: {
@@ -1568,7 +1569,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1568
1569
  value: string;
1569
1570
  };
1570
1571
  } | undefined;
1571
- packagePrefix?: string | undefined;
1572
1572
  queryMode?: "auto" | "token" | "literal" | undefined;
1573
1573
  } | undefined;
1574
1574
  } | undefined;
@@ -1641,6 +1641,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1641
1641
  queryMode: "auto" | "token" | "literal";
1642
1642
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1643
1643
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1644
+ packagePrefix?: string | undefined;
1644
1645
  intent?: "symbol" | "path" | "text" | undefined;
1645
1646
  fileGlob?: string | undefined;
1646
1647
  artifact?: {
@@ -1653,7 +1654,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1653
1654
  value: string;
1654
1655
  };
1655
1656
  } | undefined;
1656
- packagePrefix?: string | undefined;
1657
1657
  } | {
1658
1658
  kind: "workspace";
1659
1659
  projectPath: string;
@@ -1693,6 +1693,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1693
1693
  queryMode: "auto" | "token" | "literal";
1694
1694
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1695
1695
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1696
+ packagePrefix?: string | undefined;
1696
1697
  intent?: "symbol" | "path" | "text" | undefined;
1697
1698
  fileGlob?: string | undefined;
1698
1699
  artifact?: {
@@ -1705,7 +1706,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1705
1706
  value: string;
1706
1707
  };
1707
1708
  } | undefined;
1708
- packagePrefix?: string | undefined;
1709
1709
  } | undefined;
1710
1710
  } | undefined;
1711
1711
  detail?: "full" | "summary" | "standard" | undefined;
@@ -1776,6 +1776,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1776
1776
  query: string;
1777
1777
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1778
1778
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1779
+ packagePrefix?: string | undefined;
1779
1780
  intent?: "symbol" | "path" | "text" | undefined;
1780
1781
  fileGlob?: string | undefined;
1781
1782
  artifact?: {
@@ -1788,7 +1789,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1788
1789
  value: string;
1789
1790
  };
1790
1791
  } | undefined;
1791
- packagePrefix?: string | undefined;
1792
1792
  queryMode?: "auto" | "token" | "literal" | undefined;
1793
1793
  } | {
1794
1794
  kind: "workspace";
@@ -1828,6 +1828,7 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1828
1828
  query: string;
1829
1829
  match?: "exact" | "prefix" | "contains" | "regex" | undefined;
1830
1830
  symbolKind?: "class" | "field" | "method" | "record" | "interface" | "enum" | undefined;
1831
+ packagePrefix?: string | undefined;
1831
1832
  intent?: "symbol" | "path" | "text" | undefined;
1832
1833
  fileGlob?: string | undefined;
1833
1834
  artifact?: {
@@ -1840,7 +1841,6 @@ export declare const inspectMinecraftSchema: z.ZodEffects<z.ZodObject<{
1840
1841
  value: string;
1841
1842
  };
1842
1843
  } | undefined;
1843
- packagePrefix?: string | undefined;
1844
1844
  queryMode?: "auto" | "token" | "literal" | undefined;
1845
1845
  } | undefined;
1846
1846
  } | undefined;