@adhisang/minecraft-modding-mcp 6.1.0 → 6.2.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 +37 -0
- package/README.md +4 -2
- package/dist/cache-registry.d.ts +1 -1
- package/dist/cache-registry.js +3 -0
- package/dist/entry-tools/analyze-mod-service.d.ts +12 -6
- package/dist/entry-tools/analyze-mod-service.js +37 -3
- package/dist/entry-tools/analyze-symbol-service.d.ts +2 -0
- package/dist/entry-tools/analyze-symbol-service.js +37 -2
- package/dist/entry-tools/inspect-minecraft/internal.d.ts +4 -0
- package/dist/entry-tools/inspect-minecraft/internal.js +28 -0
- package/dist/entry-tools/manage-cache-service.d.ts +4 -4
- package/dist/error-mapping.d.ts +13 -0
- package/dist/error-mapping.js +35 -2
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +2 -0
- package/dist/index.js +37 -17
- package/dist/mapping/internal-types.d.ts +7 -0
- package/dist/mapping/types.d.ts +18 -0
- package/dist/mapping-service.js +16 -3
- package/dist/minecraft-explorer-service.d.ts +4 -0
- package/dist/minecraft-explorer-service.js +156 -17
- package/dist/mod-analyzer.d.ts +7 -0
- package/dist/mod-analyzer.js +28 -7
- package/dist/nbt/typed-json.js +4 -1
- package/dist/source/artifact-resolver.d.ts +2 -0
- package/dist/source/artifact-resolver.js +24 -1
- package/dist/source/class-source/members-builder.d.ts +4 -0
- package/dist/source/class-source/members-builder.js +3 -1
- package/dist/source/class-source.d.ts +2 -1
- package/dist/source/class-source.js +154 -17
- package/dist/source/did-you-mean.d.ts +14 -0
- package/dist/source/did-you-mean.js +79 -0
- package/dist/source/file-access.js +159 -3
- package/dist/source/indexer.js +72 -2
- package/dist/source/lifecycle/runtime-check.js +15 -7
- package/dist/source/nested-jars.d.ts +59 -0
- package/dist/source/nested-jars.js +198 -0
- package/dist/source/workspace-target.js +5 -2
- package/dist/source-jar-reader.d.ts +16 -0
- package/dist/source-jar-reader.js +82 -0
- package/dist/source-service.d.ts +36 -0
- package/dist/source-service.js +49 -6
- package/dist/stage-emitter.js +24 -8
- package/dist/stdio-supervisor.d.ts +92 -9
- package/dist/stdio-supervisor.js +915 -103
- package/dist/tool-contract-manifest.js +1 -1
- package/dist/tool-guidance.js +3 -1
- package/dist/tool-schemas.d.ts +1337 -149
- package/dist/tool-schemas.js +38 -7
- package/dist/types.d.ts +23 -0
- package/dist/workspace-mapping-service.d.ts +1 -0
- package/dist/workspace-mapping-service.js +120 -8
- package/docs/tool-reference.md +19 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,43 @@ and this project aims to follow [Semantic Versioning](https://semver.org/spec/v2
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [6.2.0] - 2026-07-11
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Workspace ergonomics for artifact addressing, all additive: (1) `find-class`, `get-artifact-file`, `list-artifact-files`, `search-class-source`, and `index-artifact` accept the shared `target` shape as an alternative to a flat `artifactId` (mutually exclusive — exactly one must be supplied; existing `artifactId` calls are unchanged). (2) `analyze-symbol` infers an omitted `version` from a supplied `projectPath` instead of rejecting at schema time; inferred runs always carry a `versionInference { version, source }` block plus a warning, an explicit `version` is never overridden, and an undetectable version fails with `ERR_WORKSPACE_VERSION_UNRESOLVED`. (3) `inspect-minecraft` direct subjects (`class`/`file`/`search`) without `subject.artifact` auto-resolve through the workspace only when exactly one workspace is known, always with a provenance warning; several known workspaces refuse with `workspaceCandidates`, and an explicit `subject.artifact` is never overridden.
|
|
15
|
+
|
|
16
|
+
- Bytecode member reads now surface annotation metadata: annotation-type classes (`@interface`) expose each member's default value as `annotationDefault` (rendered from the `AnnotationDefault` attribute, including string/enum/class/array/nested-annotation and numeric constants), and `get-class-members` gains an optional `includeAnnotations` flag that adds runtime-visible member annotations (e.g. `@java.lang.Deprecated`) to each member. Defaults are always present when the classfile carries them; member annotations appear only under the opt-in flag. `analyze-mod` `task="members"` includes both without a flag. No new dependencies — the existing classfile reader parses the attribute bodies.
|
|
17
|
+
|
|
18
|
+
- `analyze-mod` gains a `members` task (`subject: { kind: "class", jarPath, className }`) that reads a mod class's constructors, fields, and methods (all access levels, including private and protected) directly from bytecode — no decompiler invocation on this path, unlike `task: "class-source"`. Responses carry `extractionMethod: "bytecode-only"`. Additive: existing tasks and inputs are unchanged, and the tool count stays at 41.
|
|
19
|
+
|
|
20
|
+
- `get-artifact-file` serves `assets/**` and `data/**` text files (including vanilla `data/minecraft/dimension_type/*.json`, and resources in any jar-backed artifact such as mod jars) directly from the backing jar when the source index has no row for them — responses carry `deliveryMode: "jar-read-through"`. Delivery is text-only with a 512 KiB per-file cap and explicit `truncated` flag; binary entries answer with size metadata and a `contentOmittedReason` instead of content; traversal-shaped paths are rejected with `ERR_INVALID_INPUT`; misses return `ERR_FILE_NOT_FOUND` with `nearbyPaths` hints that surface directory relocations such as the `assets/minecraft/models/item/*` → `assets/minecraft/items/*` move. The `list-artifact-files` assets/data warning now points at this read-through path.
|
|
21
|
+
|
|
22
|
+
- Class-not-found errors (`ERR_CLASS_NOT_FOUND`) from `get-class-source`, `get-class-members`, and their batch variants now include a top-level `didYouMean` array with ranked near-miss candidates from the artifact's symbol index — `{ className, matchReason }` with reasons `exact-simple-name` (moved class, ranked first), `case-insensitive`, and `edit-distance:N`. A stale fully-qualified name like a pre-move `ItemTransform` package now names the current location instead of dead-ending. The array is empty when the index has no usable candidates, and candidates are phrased as hints, not assertions.
|
|
23
|
+
|
|
24
|
+
- Jar-in-Jar shell jars (near-zero own classes, content bundled under `META-INF/jars`, like the Fabric API umbrella jar) resolve instead of failing with `ERR_DECOMPILER_FAILED`. The resolved artifact carries `qualityFlags: ["shell-jar"]` and the nested-jar inventory in `provenance.nestedJars` (also surfaced by `analyze-mod-jar` as `nestedJars`); `get-class-source` and `get-class-members` redirect automatically to the single nested jar containing the requested class, marking the response with `provenance.nestedJar`. A class present in several nested jars returns the new `ERR_NESTED_JAR_AMBIGUOUS` error with `nestedJarCandidates` instead of a silent pick, and class-not-found errors on shells list the inventory. Extracted nested jars live in a content-addressed `nested-jars` cache directory, manageable via `manage-cache` `cacheKinds: ["nested-jar"]`.
|
|
25
|
+
|
|
26
|
+
- `validate-project` calls now have a supervisor-owned 120-second end-to-end deadline, configurable with `MCP_VALIDATE_PROJECT_TIMEOUT_MS` from 10,000 through 600,000 ms. Expiry returns the standard synthetic `{ error, meta }` tool-result envelope with `ERR_TOOL_TIMEOUT`, queue/running phase diagnostics, redacted progress context, and restart-initiation state. Queue expiry leaves the active worker untouched; running expiry replaces the isolated worker and preserves admitted later requests when initialization replay succeeds. Replacement startup/replay failure terminalizes queued work with existing restart errors. The supervisor FIFO holds at most two worker-bound requests and returns `ERR_LIMIT_EXCEEDED` (tool calls) or JSON-RPC `-32000` (non-tool requests) on overflow; cap-blocked requests fail immediately and undeliverable notifications are warning-dropped. POSIX process-group cleanup treats an already-gone process group as clean so stale cleanup tokens do not block later validation.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- The two constant per-response warning sentences on unobfuscated versions are replaced by structured flags on `mappingContext` — agents that pattern-matched the old strings should read the flags instead. `"Version X is unobfuscated; mapping graph is empty because the runtime already uses deobfuscated names."` is now `mappingContext.unobfuscatedRuntime: true`, and `"Version X is unobfuscated; validated symbol existence against runtime bytecode."` is now `mappingContext.runtimeValidated: true` (`get-class-api-matrix`, which has no `mappingContext`, reports a top-level `unobfuscatedRuntime: true`). No information is removed: the flags carry the same facts, the full former wording stays documented in `docs/tool-reference.md`, and all other warnings are untouched.
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- Loom split-source workspaces (a `minecraft-common` / `minecraft-clientOnly` sources-jar pair with no merged jar) no longer lose one half's classes to single-jar selection: version-target resolution with project Loom sources indexes the best-scored jar of the other half too (`provenance.companionSourceJars` names it), so client-only classes like `net.minecraft.client.renderer.block.model.ItemTransform` are indexed and findable via symbol search. Class-not-found errors for version targets additionally carry an `exampleCalls` retry using `scope: "vanilla"` (existing enum values only), whose client-jar decompilation also contains client-only classes.
|
|
35
|
+
- Inherited-member expansion no longer emits `Could not resolve super class ...` warnings for platform packages that are never inside a Minecraft jar (`java.*`, `javax.*`, `jdk.*`, `sun.*`, and the separately-shipped `com.mojang.serialization.*` — each verified against real 26.x and 1.21.10 jars). Suppression is allowlist-only: resolution failures for real Minecraft classes, including `com.mojang.blaze3d.*` client-jar content, stay visible.
|
|
36
|
+
- `check-symbol-exists` no longer reports false negatives for fields and classes on unobfuscated versions: the runtime-bytecode fallback introduced in 6.0.0 only re-checked `not_found` verdicts for methods, so a mapping graph lacking a record for a real field like `EntityType.ITEM` returned `not_found` without consulting the jar. Every `not_found` verdict is now runtime-checked (genuinely-missing symbols stay `not_found`), and bytecode-derived response contexts report `mappingNamespace: "mojang"` on unobfuscated versions instead of a hardcoded `"obfuscated"`.
|
|
37
|
+
- Dependency version detection probes the snake_case transforms of hyphenated artifact names (`fabric_api_version` and the compound `fabric_api_fabric_api_version` for `net.fabricmc.fabric-api:fabric-api`). Previously only submodules received a snake_case umbrella fallback key, so resolving the umbrella artifact itself against a standard Fabric template that declares `fabric_api_version` failed with `ERR_DEPENDENCY_VERSION_UNRESOLVED`.
|
|
38
|
+
- Umbrella submodule dependency targets (e.g. `net.fabricmc.fabric-api:fabric-gametest-api-v1`) no longer copy the umbrella's version into the submodule coordinate, which synthesized nonexistent coordinates like `fabric-gametest-api-v1:0.153.0+26.2` and failed downstream. Resolution now adopts the single cached modules-2 version, or — when several are cached — the version named by the cached umbrella POM's `<dependency>` entry (recorded as `provenance.submoduleVersionSource: "umbrella-pom"`). Anything still ambiguous fails closed with `ERR_DEPENDENCY_VERSION_UNRESOLVED` and `candidatesSeen` instead of guessing.
|
|
39
|
+
|
|
40
|
+
## [6.1.1] - 2026-07-04
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- `check-symbol-exists` no longer misreports an overridden method as unresolved in exact-signature mode. Requesting inherited methods surfaces the same name + descriptor from both the overriding and overridden owner, and the exact-signature branch treated that as an ambiguous match; it now treats any match as resolved and only zero matches as `not_found`.
|
|
45
|
+
- NBT JSON-patch validation rejects raw non-finite `float`/`double` numbers (`Infinity`, `-Infinity`, `NaN`) again. A prior fix for the `"NaN"`/`"Infinity"`/`"-Infinity"` sentinel-string round-trip had also stopped rejecting raw non-finite JS numbers, which cannot survive JSON serialization and would silently corrupt the document.
|
|
46
|
+
|
|
10
47
|
## [6.1.0] - 2026-06-28
|
|
11
48
|
|
|
12
49
|
### Added
|
package/README.md
CHANGED
|
@@ -147,7 +147,7 @@ All six return `result.summary` first and can include `summary.nextActions` when
|
|
|
147
147
|
| `inspect-minecraft` | versions, artifacts, classes, files, and source search |
|
|
148
148
|
| `analyze-symbol` | symbol existence checks, mapping conversion, lifecycle tracing, and workspace symbol resolution |
|
|
149
149
|
| `compare-minecraft` | version-pair diffs, class diffs, registry diffs, and migration-oriented overviews |
|
|
150
|
-
| `analyze-mod` | mod metadata, decompile/search flows, class source, and safe remap preview/apply |
|
|
150
|
+
| `analyze-mod` | mod metadata, decompile/search flows, class source, bytecode member queries, and safe remap preview/apply |
|
|
151
151
|
| `validate-project` | workspace summaries plus direct Mixin, Access Widener, and Access Transformer validation |
|
|
152
152
|
| `manage-cache` | cache inventory, verification, and preview/apply cleanup workflows |
|
|
153
153
|
|
|
@@ -163,6 +163,8 @@ These notes cover high-frequency decisions during onboarding. For the full pitfa
|
|
|
163
163
|
- `validate-project task="project-summary"` propagates `preferProjectVersion=true` across discovered Mixin, Access Widener, and Access Transformer checks. If no version can be resolved from the request or `gradle.properties`, the summary returns recovery guidance instead of guessing.
|
|
164
164
|
- `validate-mixin` and `validate-project` keep `mapping-health` lightweight for `obfuscated` and `mojang` validation, avoiding full Tiny mapping graph loads unless `intermediary` or `yarn` namespaces are requested.
|
|
165
165
|
- `validate-project task="project-summary"` uses a lightweight artifact probe for `tasks["minecraft.artifact.resolved"]`; it does not decompile Minecraft or rebuild the source index just to report per-probe status. Set `VALIDATE_PROJECT_TASKS_OFF=1` to omit the additive `tasks` field.
|
|
166
|
+
- `validate-project` has a supervisor-owned end-to-end deadline of 120 seconds, including queue time. Set `MCP_VALIDATE_PROJECT_TIMEOUT_MS` to an ASCII-decimal value from `10000` through `600000` to override it. A timeout returns `ERR_TOOL_TIMEOUT`; a running timeout restarts the isolated worker before queued calls resume, while a queue timeout leaves the current worker untouched.
|
|
167
|
+
- Queued calls resume only after the replacement worker completes initialization replay. If replacement startup or replay fails, queued tool calls terminate with `ERR_WORKER_RESTART` instead of waiting indefinitely. If unresolved process-tree cleanup fills the supervisor's two live-generation slots, new requests fail with the existing restart envelope and unavailable notifications are warning-dropped until cleanup or reconnect. On POSIX, an already-gone process group counts as cleaned up rather than leaving a stale cleanup token.
|
|
166
168
|
- If a workspace was built with `GRADLE_USER_HOME=/tmp/...` or another isolated Gradle home, pass that path as `gradleUserHome` so source, mapping, runtime, and project validation lookups use the same Loom cache instead of stale caches under the MCP process home.
|
|
167
169
|
- `manage-cache` reports corrupt Mojang binary-remap cache directories under `cacheKinds: ["binary-remap"]` with `status: "corrupt"`, and can delete them by `selector.artifactId` in preview/apply workflows.
|
|
168
170
|
|
|
@@ -262,7 +264,7 @@ Start with these top-level workflow tools unless you already know the exact spec
|
|
|
262
264
|
| `inspect-minecraft` | Inspect versions, artifacts, classes, files, source text, and workspace-aware lookup flows |
|
|
263
265
|
| `analyze-symbol` | Handle symbol existence checks, namespace mapping, lifecycle tracing, workspace symbol resolution, and API overviews |
|
|
264
266
|
| `compare-minecraft` | Compare version pairs, class diffs, registry diffs, and migration-oriented summaries |
|
|
265
|
-
| `analyze-mod` | Summarize mod metadata, decompile and search mod code, inspect class source, and preview or apply remaps |
|
|
267
|
+
| `analyze-mod` | Summarize mod metadata, decompile and search mod code, inspect class source, read class members from bytecode, and preview or apply remaps |
|
|
266
268
|
| `validate-project` | Summarize workspaces and run direct Mixin, Access Widener, or Access Transformer validation |
|
|
267
269
|
| `manage-cache` | List, verify, and preview or apply cache cleanup and rebuild operations |
|
|
268
270
|
<!-- END GENERATED TOOL TABLE: top-level-workflow-tools -->
|
package/dist/cache-registry.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type PathRuntimeInfo } from "./path-converter.js";
|
|
2
2
|
import { type WorkspaceContextCache } from "./workspace-context-cache.js";
|
|
3
|
-
export declare const PUBLIC_CACHE_KINDS: readonly ["artifact-index", "downloads", "mapping", "registry", "decompiled-source", "mod-remap", "binary-remap", "workspace"];
|
|
3
|
+
export declare const PUBLIC_CACHE_KINDS: readonly ["artifact-index", "downloads", "mapping", "registry", "decompiled-source", "mod-remap", "binary-remap", "nested-jar", "workspace"];
|
|
4
4
|
export type PublicCacheKind = (typeof PUBLIC_CACHE_KINDS)[number];
|
|
5
5
|
export declare const CACHE_HEALTH_STATES: readonly ["healthy", "partial", "stale", "orphaned", "corrupt", "in_use"];
|
|
6
6
|
export type CacheHealthState = (typeof CACHE_HEALTH_STATES)[number];
|
package/dist/cache-registry.js
CHANGED
|
@@ -14,6 +14,7 @@ export const PUBLIC_CACHE_KINDS = [
|
|
|
14
14
|
"decompiled-source",
|
|
15
15
|
"mod-remap",
|
|
16
16
|
"binary-remap",
|
|
17
|
+
"nested-jar",
|
|
17
18
|
"workspace"
|
|
18
19
|
];
|
|
19
20
|
export const CACHE_HEALTH_STATES = [
|
|
@@ -44,6 +45,8 @@ function kindRoot(config, cacheKind) {
|
|
|
44
45
|
return join(config.cacheDir, "remapped-mods");
|
|
45
46
|
case "binary-remap":
|
|
46
47
|
return join(config.cacheDir, "remapped");
|
|
48
|
+
case "nested-jar":
|
|
49
|
+
return join(config.cacheDir, "nested-jars");
|
|
47
50
|
case "workspace":
|
|
48
51
|
return "<in-memory:workspace-context-cache>";
|
|
49
52
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AnalyzeModOptions, ModAnalysisResult } from "../mod-analyzer.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
export declare const analyzeModShape: {
|
|
4
|
-
task: z.ZodEnum<["summary", "decompile", "search", "class-source", "remap"]>;
|
|
4
|
+
task: z.ZodEnum<["summary", "decompile", "search", "class-source", "members", "remap"]>;
|
|
5
5
|
subject: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
6
6
|
kind: z.ZodLiteral<"jar">;
|
|
7
7
|
jarPath: z.ZodString;
|
|
@@ -38,7 +38,7 @@ export declare const analyzeModShape: {
|
|
|
38
38
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<[string, ...string[]]>, "many">>;
|
|
39
39
|
};
|
|
40
40
|
export declare const analyzeModSchema: z.ZodEffects<z.ZodObject<{
|
|
41
|
-
task: z.ZodEnum<["summary", "decompile", "search", "class-source", "remap"]>;
|
|
41
|
+
task: z.ZodEnum<["summary", "decompile", "search", "class-source", "members", "remap"]>;
|
|
42
42
|
subject: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
43
43
|
kind: z.ZodLiteral<"jar">;
|
|
44
44
|
jarPath: z.ZodString;
|
|
@@ -75,7 +75,7 @@ export declare const analyzeModSchema: z.ZodEffects<z.ZodObject<{
|
|
|
75
75
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<[string, ...string[]]>, "many">>;
|
|
76
76
|
}, "strip", z.ZodTypeAny, {
|
|
77
77
|
limit: number;
|
|
78
|
-
task: "search" | "summary" | "class-source" | "remap" | "decompile";
|
|
78
|
+
task: "search" | "summary" | "class-source" | "members" | "remap" | "decompile";
|
|
79
79
|
subject: {
|
|
80
80
|
kind: "jar";
|
|
81
81
|
jarPath: string;
|
|
@@ -96,7 +96,7 @@ export declare const analyzeModSchema: z.ZodEffects<z.ZodObject<{
|
|
|
96
96
|
outputJar?: string | undefined;
|
|
97
97
|
maxFiles?: number | undefined;
|
|
98
98
|
}, {
|
|
99
|
-
task: "search" | "summary" | "class-source" | "remap" | "decompile";
|
|
99
|
+
task: "search" | "summary" | "class-source" | "members" | "remap" | "decompile";
|
|
100
100
|
subject: {
|
|
101
101
|
kind: "jar";
|
|
102
102
|
jarPath: string;
|
|
@@ -119,7 +119,7 @@ export declare const analyzeModSchema: z.ZodEffects<z.ZodObject<{
|
|
|
119
119
|
maxFiles?: number | undefined;
|
|
120
120
|
}>, {
|
|
121
121
|
limit: number;
|
|
122
|
-
task: "search" | "summary" | "class-source" | "remap" | "decompile";
|
|
122
|
+
task: "search" | "summary" | "class-source" | "members" | "remap" | "decompile";
|
|
123
123
|
subject: {
|
|
124
124
|
kind: "jar";
|
|
125
125
|
jarPath: string;
|
|
@@ -140,7 +140,7 @@ export declare const analyzeModSchema: z.ZodEffects<z.ZodObject<{
|
|
|
140
140
|
outputJar?: string | undefined;
|
|
141
141
|
maxFiles?: number | undefined;
|
|
142
142
|
}, {
|
|
143
|
-
task: "search" | "summary" | "class-source" | "remap" | "decompile";
|
|
143
|
+
task: "search" | "summary" | "class-source" | "members" | "remap" | "decompile";
|
|
144
144
|
subject: {
|
|
145
145
|
kind: "jar";
|
|
146
146
|
jarPath: string;
|
|
@@ -196,6 +196,12 @@ type AnalyzeModDeps = {
|
|
|
196
196
|
}) => Promise<Record<string, unknown> & {
|
|
197
197
|
warnings?: string[];
|
|
198
198
|
}>;
|
|
199
|
+
getModClassMembers: (input: {
|
|
200
|
+
jarPath: string;
|
|
201
|
+
className: string;
|
|
202
|
+
}) => Promise<Record<string, unknown> & {
|
|
203
|
+
warnings?: string[];
|
|
204
|
+
}>;
|
|
199
205
|
};
|
|
200
206
|
export declare class AnalyzeModService {
|
|
201
207
|
private readonly deps;
|
|
@@ -20,7 +20,7 @@ const subjectSchema = z.discriminatedUnion("kind", [
|
|
|
20
20
|
})
|
|
21
21
|
]);
|
|
22
22
|
export const analyzeModShape = {
|
|
23
|
-
task: z.enum(["summary", "decompile", "search", "class-source", "remap"]),
|
|
23
|
+
task: z.enum(["summary", "decompile", "search", "class-source", "members", "remap"]),
|
|
24
24
|
subject: subjectSchema,
|
|
25
25
|
query: nonEmptyString.optional(),
|
|
26
26
|
searchType: z.enum(["class", "method", "field", "content", "all"]).default("all"),
|
|
@@ -43,11 +43,11 @@ export const analyzeModSchema = z.object(analyzeModShape).superRefine((value, ct
|
|
|
43
43
|
message: `${value.task} requires subject.kind=jar.`
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
-
if (value.task === "class-source" && value.subject.kind !== "class") {
|
|
46
|
+
if ((value.task === "class-source" || value.task === "members") && value.subject.kind !== "class") {
|
|
47
47
|
ctx.addIssue({
|
|
48
48
|
code: z.ZodIssueCode.custom,
|
|
49
49
|
path: ["subject", "kind"],
|
|
50
|
-
message:
|
|
50
|
+
message: `${value.task} requires subject.kind=class.`
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
if (value.task === "search" && !value.query) {
|
|
@@ -206,6 +206,40 @@ export class AnalyzeModService {
|
|
|
206
206
|
warnings: Array.isArray(output.warnings) ? output.warnings : []
|
|
207
207
|
};
|
|
208
208
|
}
|
|
209
|
+
case "members": {
|
|
210
|
+
if (input.subject.kind !== "class") {
|
|
211
|
+
throw createError({
|
|
212
|
+
code: ERROR_CODES.INVALID_INPUT,
|
|
213
|
+
message: "members requires subject.kind=class."
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
const output = await this.deps.getModClassMembers({
|
|
217
|
+
jarPath: input.subject.jarPath,
|
|
218
|
+
className: input.subject.className
|
|
219
|
+
});
|
|
220
|
+
return {
|
|
221
|
+
...buildEntryToolResult({
|
|
222
|
+
task: "members",
|
|
223
|
+
detail,
|
|
224
|
+
include,
|
|
225
|
+
summary: {
|
|
226
|
+
status: "ok",
|
|
227
|
+
headline: `Read bytecode members of ${input.subject.className}.`,
|
|
228
|
+
subject: createSummarySubject({
|
|
229
|
+
task: "members",
|
|
230
|
+
kind: input.subject.kind,
|
|
231
|
+
jarPath: input.subject.jarPath,
|
|
232
|
+
className: input.subject.className
|
|
233
|
+
})
|
|
234
|
+
},
|
|
235
|
+
blocks: {
|
|
236
|
+
members: output
|
|
237
|
+
},
|
|
238
|
+
alwaysBlocks: ["members"]
|
|
239
|
+
}),
|
|
240
|
+
warnings: Array.isArray(output.warnings) ? output.warnings : []
|
|
241
|
+
};
|
|
242
|
+
}
|
|
209
243
|
case "remap": {
|
|
210
244
|
const normalizedInputJar = normalizePathForHost(input.subject.jarPath, undefined, "jarPath");
|
|
211
245
|
const analysis = await this.deps.analyzeModJar(normalizedInputJar);
|
|
@@ -180,6 +180,7 @@ export declare const analyzeSymbolSchema: z.ZodEffects<z.ZodObject<{
|
|
|
180
180
|
}>;
|
|
181
181
|
export type AnalyzeSymbolInput = z.infer<typeof analyzeSymbolSchema>;
|
|
182
182
|
type AnalyzeSymbolDeps = {
|
|
183
|
+
detectProjectMinecraftVersion: (projectPath: string) => Promise<string | undefined>;
|
|
183
184
|
checkSymbolExists: (input: {
|
|
184
185
|
version: string;
|
|
185
186
|
kind: "class" | "field" | "method";
|
|
@@ -254,5 +255,6 @@ export declare class AnalyzeSymbolService {
|
|
|
254
255
|
execute(input: AnalyzeSymbolInput): Promise<Record<string, unknown> & {
|
|
255
256
|
warnings?: string[];
|
|
256
257
|
}>;
|
|
258
|
+
private dispatch;
|
|
257
259
|
}
|
|
258
260
|
export {};
|
|
@@ -112,11 +112,11 @@ const LIFECYCLE_ONLY_FIELDS = [
|
|
|
112
112
|
"includeSnapshots"
|
|
113
113
|
];
|
|
114
114
|
export const analyzeSymbolSchema = z.object(analyzeSymbolShape).superRefine((value, ctx) => {
|
|
115
|
-
if (value.task !== "lifecycle" && !value.version) {
|
|
115
|
+
if (value.task !== "lifecycle" && !value.version && !value.projectPath) {
|
|
116
116
|
ctx.addIssue({
|
|
117
117
|
code: z.ZodIssueCode.custom,
|
|
118
118
|
path: ["version"],
|
|
119
|
-
message: "version is required for non-lifecycle tasks."
|
|
119
|
+
message: "version is required for non-lifecycle tasks (or pass projectPath so the version can be inferred from the workspace)."
|
|
120
120
|
});
|
|
121
121
|
}
|
|
122
122
|
if (value.task === "lifecycle" && !value.version && !value.toVersion) {
|
|
@@ -189,6 +189,41 @@ export class AnalyzeSymbolService {
|
|
|
189
189
|
const detail = resolveDetail(input.detail);
|
|
190
190
|
const include = resolveInclude(input.include);
|
|
191
191
|
const { kind: subjectKind, warning: inferenceWarning } = inferSubjectKind(input.subject);
|
|
192
|
+
// Omitted version with a supplied projectPath: infer from the workspace.
|
|
193
|
+
// Inference always carries provenance (versionInference block + warning);
|
|
194
|
+
// an explicit version is never overridden.
|
|
195
|
+
let versionInference;
|
|
196
|
+
if (input.task !== "lifecycle" && !input.version && input.projectPath) {
|
|
197
|
+
const detected = await this.deps.detectProjectMinecraftVersion(input.projectPath);
|
|
198
|
+
if (!detected) {
|
|
199
|
+
throw createError({
|
|
200
|
+
code: ERROR_CODES.WORKSPACE_VERSION_UNRESOLVED,
|
|
201
|
+
message: `Could not infer a Minecraft version from ${input.projectPath}.`,
|
|
202
|
+
details: {
|
|
203
|
+
projectPath: input.projectPath,
|
|
204
|
+
nextAction: "Declare minecraft_version (or mc_version) in gradle.properties, or pass version explicitly."
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
versionInference = {
|
|
209
|
+
version: detected,
|
|
210
|
+
source: `projectPath:gradle.properties (${input.projectPath})`
|
|
211
|
+
};
|
|
212
|
+
input = { ...input, version: detected };
|
|
213
|
+
}
|
|
214
|
+
const inferenceWarnings = versionInference
|
|
215
|
+
? [
|
|
216
|
+
`version was inferred from the workspace: ${versionInference.version} (source: ${versionInference.source}).`
|
|
217
|
+
]
|
|
218
|
+
: [];
|
|
219
|
+
const result = await this.dispatch(input, detail, include, subjectKind, inferenceWarning);
|
|
220
|
+
if (versionInference) {
|
|
221
|
+
result.versionInference = versionInference;
|
|
222
|
+
result.warnings = [...(result.warnings ?? []), ...inferenceWarnings];
|
|
223
|
+
}
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
async dispatch(input, detail, include, subjectKind, inferenceWarning) {
|
|
192
227
|
switch (input.task) {
|
|
193
228
|
case "exists": {
|
|
194
229
|
const output = await this.deps.checkSymbolExists({
|
|
@@ -1015,6 +1015,10 @@ export type InspectMinecraftDeps = {
|
|
|
1015
1015
|
cursor?: string;
|
|
1016
1016
|
}) => Promise<ListArtifactFilesOutput>;
|
|
1017
1017
|
detectProjectMinecraftVersion: (projectPath: string) => Promise<string | undefined>;
|
|
1018
|
+
listWorkspaceContexts: () => Array<{
|
|
1019
|
+
projectPath: string;
|
|
1020
|
+
minecraftVersion?: string;
|
|
1021
|
+
}>;
|
|
1018
1022
|
};
|
|
1019
1023
|
export declare function requireWorkspaceClassFocus(subject: Subject): WorkspaceClassFocus;
|
|
1020
1024
|
export declare function requireWorkspaceSearchFocus(subject: Subject): WorkspaceSearchFocus;
|
|
@@ -392,6 +392,31 @@ export async function resolveArtifactReference(deps, subject, task) {
|
|
|
392
392
|
}
|
|
393
393
|
if (subject.kind === "class" || subject.kind === "file" || subject.kind === "search") {
|
|
394
394
|
if (!subject.artifact) {
|
|
395
|
+
// Guardrailed auto-resolution: an omitted subject.artifact resolves
|
|
396
|
+
// through the workspace ONLY when exactly one workspace is known, and
|
|
397
|
+
// the response always carries a provenance warning. An explicit
|
|
398
|
+
// subject.artifact is never overridden (this branch requires absence).
|
|
399
|
+
const workspaces = deps.listWorkspaceContexts();
|
|
400
|
+
const unique = workspaces.length === 1 ? workspaces[0] : undefined;
|
|
401
|
+
if (unique) {
|
|
402
|
+
const version = unique.minecraftVersion ??
|
|
403
|
+
(await deps.detectProjectMinecraftVersion(unique.projectPath));
|
|
404
|
+
if (version) {
|
|
405
|
+
const artifact = await deps.resolveArtifact({
|
|
406
|
+
target: { kind: "version", value: version },
|
|
407
|
+
projectPath: unique.projectPath
|
|
408
|
+
});
|
|
409
|
+
return {
|
|
410
|
+
artifactId: artifact.artifactId,
|
|
411
|
+
artifact,
|
|
412
|
+
version,
|
|
413
|
+
warnings: [
|
|
414
|
+
`subject.artifact was omitted; auto-resolved through the unique known workspace ${unique.projectPath} (Minecraft ${version}). Pass subject.artifact to target a different artifact.`,
|
|
415
|
+
...artifact.warnings
|
|
416
|
+
]
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
}
|
|
395
420
|
const suggestedTask = task
|
|
396
421
|
?? (subject.kind === "class"
|
|
397
422
|
? "class-overview"
|
|
@@ -403,6 +428,9 @@ export async function resolveArtifactReference(deps, subject, task) {
|
|
|
403
428
|
message: `${subject.kind} subject requires artifact context.`,
|
|
404
429
|
details: {
|
|
405
430
|
nextAction: "Add subject.artifact or use subject.kind=workspace so inspect-minecraft can resolve the artifact first.",
|
|
431
|
+
...(workspaces.length > 1
|
|
432
|
+
? { workspaceCandidates: workspaces.map((workspace) => workspace.projectPath) }
|
|
433
|
+
: {}),
|
|
406
434
|
...(await buildArtifactContextSuggestedCall(deps, suggestedTask, subject))
|
|
407
435
|
}
|
|
408
436
|
});
|
|
@@ -2,7 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { type CacheRegistry } from "../cache-registry.js";
|
|
3
3
|
export declare const manageCacheShape: {
|
|
4
4
|
action: z.ZodEnum<["summary", "list", "inspect", "delete", "prune", "rebuild", "verify"]>;
|
|
5
|
-
cacheKinds: z.ZodOptional<z.ZodArray<z.ZodEnum<["artifact-index", "downloads", "mapping", "registry", "decompiled-source", "mod-remap", "binary-remap", "workspace"]>, "many">>;
|
|
5
|
+
cacheKinds: z.ZodOptional<z.ZodArray<z.ZodEnum<["artifact-index", "downloads", "mapping", "registry", "decompiled-source", "mod-remap", "binary-remap", "nested-jar", "workspace"]>, "many">>;
|
|
6
6
|
selector: z.ZodOptional<z.ZodObject<{
|
|
7
7
|
artifactId: z.ZodOptional<z.ZodString>;
|
|
8
8
|
version: z.ZodOptional<z.ZodString>;
|
|
@@ -42,7 +42,7 @@ export declare const manageCacheShape: {
|
|
|
42
42
|
};
|
|
43
43
|
export declare const manageCacheSchema: z.ZodObject<{
|
|
44
44
|
action: z.ZodEnum<["summary", "list", "inspect", "delete", "prune", "rebuild", "verify"]>;
|
|
45
|
-
cacheKinds: z.ZodOptional<z.ZodArray<z.ZodEnum<["artifact-index", "downloads", "mapping", "registry", "decompiled-source", "mod-remap", "binary-remap", "workspace"]>, "many">>;
|
|
45
|
+
cacheKinds: z.ZodOptional<z.ZodArray<z.ZodEnum<["artifact-index", "downloads", "mapping", "registry", "decompiled-source", "mod-remap", "binary-remap", "nested-jar", "workspace"]>, "many">>;
|
|
46
46
|
selector: z.ZodOptional<z.ZodObject<{
|
|
47
47
|
artifactId: z.ZodOptional<z.ZodString>;
|
|
48
48
|
version: z.ZodOptional<z.ZodString>;
|
|
@@ -86,7 +86,7 @@ export declare const manageCacheSchema: z.ZodObject<{
|
|
|
86
86
|
cursor?: string | undefined;
|
|
87
87
|
detail?: "summary" | "standard" | "full" | undefined;
|
|
88
88
|
include?: string[] | undefined;
|
|
89
|
-
cacheKinds?: ("workspace" | "artifact-index" | "downloads" | "mapping" | "registry" | "decompiled-source" | "mod-remap" | "binary-remap")[] | undefined;
|
|
89
|
+
cacheKinds?: ("workspace" | "artifact-index" | "downloads" | "mapping" | "registry" | "decompiled-source" | "mod-remap" | "binary-remap" | "nested-jar")[] | undefined;
|
|
90
90
|
selector?: {
|
|
91
91
|
version?: string | undefined;
|
|
92
92
|
projectPath?: string | undefined;
|
|
@@ -105,7 +105,7 @@ export declare const manageCacheSchema: z.ZodObject<{
|
|
|
105
105
|
detail?: "summary" | "standard" | "full" | undefined;
|
|
106
106
|
include?: string[] | undefined;
|
|
107
107
|
executionMode?: "preview" | "apply" | undefined;
|
|
108
|
-
cacheKinds?: ("workspace" | "artifact-index" | "downloads" | "mapping" | "registry" | "decompiled-source" | "mod-remap" | "binary-remap")[] | undefined;
|
|
108
|
+
cacheKinds?: ("workspace" | "artifact-index" | "downloads" | "mapping" | "registry" | "decompiled-source" | "mod-remap" | "binary-remap" | "nested-jar")[] | undefined;
|
|
109
109
|
selector?: {
|
|
110
110
|
version?: string | undefined;
|
|
111
111
|
projectPath?: string | undefined;
|
package/dist/error-mapping.d.ts
CHANGED
|
@@ -38,6 +38,10 @@ export type RetryClass = "transient" | "permanent" | "server" | "environment" |
|
|
|
38
38
|
* - `environment`: a server capability is missing (Java, decompiler, remapper).
|
|
39
39
|
*/
|
|
40
40
|
export type IssueOrigin = "code_issue" | "tool_issue" | "environment";
|
|
41
|
+
export type DidYouMeanCandidate = {
|
|
42
|
+
className: string;
|
|
43
|
+
matchReason: string;
|
|
44
|
+
};
|
|
41
45
|
export type ProblemDetails = {
|
|
42
46
|
type: string;
|
|
43
47
|
title: string;
|
|
@@ -51,9 +55,18 @@ export type ProblemDetails = {
|
|
|
51
55
|
hints?: string[];
|
|
52
56
|
suggestedCall?: SuggestedCall;
|
|
53
57
|
exampleCalls?: ExampleCall[];
|
|
58
|
+
/** Ranked near-miss candidates for a class/symbol that was not found. */
|
|
59
|
+
didYouMean?: DidYouMeanCandidate[];
|
|
54
60
|
failedStage?: string;
|
|
55
61
|
context?: Record<string, string | number | boolean>;
|
|
56
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Validates and extracts a `didYouMean` array from error details. Like
|
|
65
|
+
* `suggestedCall`, it travels as a dedicated typed field — the primitive-only
|
|
66
|
+
* context allowlist is not loosened for it. Malformed payloads are dropped
|
|
67
|
+
* whole rather than partially published.
|
|
68
|
+
*/
|
|
69
|
+
export declare function extractDidYouMean(details: unknown): DidYouMeanCandidate[] | undefined;
|
|
57
70
|
export declare function statusForErrorCode(code: string): number;
|
|
58
71
|
/**
|
|
59
72
|
* Single source of truth mapping an error code to its {@link RetryClass}. Used
|
package/dist/error-mapping.js
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import { ERROR_CODES, isAppError } from "./errors.js";
|
|
2
2
|
import { log } from "./logger.js";
|
|
3
|
+
const MAX_DID_YOU_MEAN_ENTRIES = 16;
|
|
4
|
+
/**
|
|
5
|
+
* Validates and extracts a `didYouMean` array from error details. Like
|
|
6
|
+
* `suggestedCall`, it travels as a dedicated typed field — the primitive-only
|
|
7
|
+
* context allowlist is not loosened for it. Malformed payloads are dropped
|
|
8
|
+
* whole rather than partially published.
|
|
9
|
+
*/
|
|
10
|
+
export function extractDidYouMean(details) {
|
|
11
|
+
const raw = details?.didYouMean;
|
|
12
|
+
if (!Array.isArray(raw)) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
const cleaned = [];
|
|
16
|
+
for (const entry of raw) {
|
|
17
|
+
if (!entry || typeof entry !== "object") {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const { className, matchReason } = entry;
|
|
21
|
+
if (typeof className !== "string" || typeof matchReason !== "string") {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
cleaned.push({ className, matchReason });
|
|
25
|
+
}
|
|
26
|
+
return cleaned.slice(0, MAX_DID_YOU_MEAN_ENTRIES);
|
|
27
|
+
}
|
|
3
28
|
export function statusForErrorCode(code) {
|
|
4
29
|
if (code === ERROR_CODES.BATCH_ABORTED) {
|
|
5
30
|
return 412;
|
|
@@ -9,6 +34,9 @@ export function statusForErrorCode(code) {
|
|
|
9
34
|
// not an internal server failure.
|
|
10
35
|
return 408;
|
|
11
36
|
}
|
|
37
|
+
if (code === ERROR_CODES.TOOL_TIMEOUT) {
|
|
38
|
+
return 408;
|
|
39
|
+
}
|
|
12
40
|
if (code === ERROR_CODES.INVALID_INPUT ||
|
|
13
41
|
code === ERROR_CODES.COORDINATE_PARSE_FAILED ||
|
|
14
42
|
code === ERROR_CODES.INVALID_LINE_RANGE ||
|
|
@@ -35,7 +63,8 @@ export function statusForErrorCode(code) {
|
|
|
35
63
|
code === ERROR_CODES.DECOMPILE_DISABLED ||
|
|
36
64
|
code === ERROR_CODES.REMAP_FAILED ||
|
|
37
65
|
code === ERROR_CODES.WORKSPACE_VERSION_UNRESOLVED ||
|
|
38
|
-
code === ERROR_CODES.DEPENDENCY_VERSION_UNRESOLVED
|
|
66
|
+
code === ERROR_CODES.DEPENDENCY_VERSION_UNRESOLVED ||
|
|
67
|
+
code === ERROR_CODES.NESTED_JAR_AMBIGUOUS) {
|
|
39
68
|
return 422;
|
|
40
69
|
}
|
|
41
70
|
if (code === ERROR_CODES.REMAPPER_UNAVAILABLE ||
|
|
@@ -82,6 +111,7 @@ const RETRY_CLASS_PERMANENT = new Set([
|
|
|
82
111
|
ERROR_CODES.REMAP_FAILED,
|
|
83
112
|
ERROR_CODES.WORKSPACE_VERSION_UNRESOLVED,
|
|
84
113
|
ERROR_CODES.DEPENDENCY_VERSION_UNRESOLVED,
|
|
114
|
+
ERROR_CODES.NESTED_JAR_AMBIGUOUS,
|
|
85
115
|
ERROR_CODES.PROVENANCE_INCOMPLETE,
|
|
86
116
|
ERROR_CODES.BATCH_ABORTED
|
|
87
117
|
]);
|
|
@@ -145,7 +175,8 @@ const ISSUE_ORIGIN_CODE = new Set([
|
|
|
145
175
|
ERROR_CODES.JAR_NOT_FOUND,
|
|
146
176
|
ERROR_CODES.VERSION_NOT_FOUND,
|
|
147
177
|
ERROR_CODES.WORKSPACE_VERSION_UNRESOLVED,
|
|
148
|
-
ERROR_CODES.DEPENDENCY_VERSION_UNRESOLVED
|
|
178
|
+
ERROR_CODES.DEPENDENCY_VERSION_UNRESOLVED,
|
|
179
|
+
ERROR_CODES.NESTED_JAR_AMBIGUOUS
|
|
149
180
|
]);
|
|
150
181
|
/**
|
|
151
182
|
* Single source of truth mapping an error code to its {@link IssueOrigin}.
|
|
@@ -243,6 +274,7 @@ export function errorToBatchEntryProblem(caughtError, instance, options) {
|
|
|
243
274
|
const baseHints = extractHints(caughtError.details);
|
|
244
275
|
const fieldErrors = extractFieldErrors(caughtError.details);
|
|
245
276
|
const context = extractAllowlistedContext(caughtError.details);
|
|
277
|
+
const didYouMean = extractDidYouMean(caughtError.details);
|
|
246
278
|
return {
|
|
247
279
|
type: `https://minecraft-modding-mcp.dev/problems/${caughtError.code.toLowerCase()}`,
|
|
248
280
|
title: "Tool execution error",
|
|
@@ -255,6 +287,7 @@ export function errorToBatchEntryProblem(caughtError, instance, options) {
|
|
|
255
287
|
...(fieldErrors ? { fieldErrors } : {}),
|
|
256
288
|
...(baseHints ? { hints: baseHints } : {}),
|
|
257
289
|
...(options?.suggestedCall ? { suggestedCall: options.suggestedCall } : {}),
|
|
290
|
+
...(didYouMean ? { didYouMean } : {}),
|
|
258
291
|
...(context ? { context } : {})
|
|
259
292
|
};
|
|
260
293
|
}
|
package/dist/errors.d.ts
CHANGED
|
@@ -31,10 +31,12 @@ export declare const ERROR_CODES: {
|
|
|
31
31
|
readonly REMAP_FAILED: "ERR_REMAP_FAILED";
|
|
32
32
|
readonly REMAPPER_UNAVAILABLE: "ERR_REMAPPER_UNAVAILABLE";
|
|
33
33
|
readonly WORKER_RESTART: "ERR_WORKER_RESTART";
|
|
34
|
+
readonly TOOL_TIMEOUT: "ERR_TOOL_TIMEOUT";
|
|
34
35
|
readonly MIXIN_PARSE_FAILED: "ERR_MIXIN_PARSE_FAILED";
|
|
35
36
|
readonly STAGE_BUDGET_PRE_PARSE: "ERR_STAGE_BUDGET_PRE_PARSE";
|
|
36
37
|
readonly WORKSPACE_VERSION_UNRESOLVED: "ERR_WORKSPACE_VERSION_UNRESOLVED";
|
|
37
38
|
readonly DEPENDENCY_VERSION_UNRESOLVED: "ERR_DEPENDENCY_VERSION_UNRESOLVED";
|
|
39
|
+
readonly NESTED_JAR_AMBIGUOUS: "ERR_NESTED_JAR_AMBIGUOUS";
|
|
38
40
|
readonly BATCH_ABORTED: "ERR_BATCH_ABORTED";
|
|
39
41
|
readonly INTERNAL: "ERR_INTERNAL";
|
|
40
42
|
};
|
package/dist/errors.js
CHANGED
|
@@ -31,10 +31,12 @@ export const ERROR_CODES = {
|
|
|
31
31
|
REMAP_FAILED: "ERR_REMAP_FAILED",
|
|
32
32
|
REMAPPER_UNAVAILABLE: "ERR_REMAPPER_UNAVAILABLE",
|
|
33
33
|
WORKER_RESTART: "ERR_WORKER_RESTART",
|
|
34
|
+
TOOL_TIMEOUT: "ERR_TOOL_TIMEOUT",
|
|
34
35
|
MIXIN_PARSE_FAILED: "ERR_MIXIN_PARSE_FAILED",
|
|
35
36
|
STAGE_BUDGET_PRE_PARSE: "ERR_STAGE_BUDGET_PRE_PARSE",
|
|
36
37
|
WORKSPACE_VERSION_UNRESOLVED: "ERR_WORKSPACE_VERSION_UNRESOLVED",
|
|
37
38
|
DEPENDENCY_VERSION_UNRESOLVED: "ERR_DEPENDENCY_VERSION_UNRESOLVED",
|
|
39
|
+
NESTED_JAR_AMBIGUOUS: "ERR_NESTED_JAR_AMBIGUOUS",
|
|
38
40
|
BATCH_ABORTED: "ERR_BATCH_ABORTED",
|
|
39
41
|
INTERNAL: "ERR_INTERNAL"
|
|
40
42
|
};
|