@adhisang/minecraft-modding-mcp 6.3.0 → 7.0.0-rc.1
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 +90 -0
- package/README.md +13 -3
- package/dist/cache-policy.d.ts +71 -0
- package/dist/cache-policy.js +83 -0
- package/dist/cache-registry.js +45 -8
- package/dist/cli.js +74 -3
- package/dist/compat-stdio-transport.d.ts +1 -1
- package/dist/compat-stdio-transport.js +13 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.js +8 -2
- package/dist/decompiler/vineflower.d.ts +1 -0
- package/dist/decompiler/vineflower.js +8 -5
- package/dist/entry-tools/analyze-mod-service.d.ts +70 -136
- package/dist/entry-tools/analyze-symbol-service.d.ts +112 -150
- package/dist/entry-tools/compare-minecraft-service.d.ts +59 -145
- package/dist/entry-tools/entry-tool-schema.d.ts +38 -4
- package/dist/entry-tools/entry-tool-schema.js +4 -1
- package/dist/entry-tools/inspect-minecraft/internal.d.ts +235 -799
- package/dist/entry-tools/inspect-minecraft/internal.js +50 -13
- package/dist/entry-tools/inspect-minecraft-service.d.ts +372 -1736
- package/dist/entry-tools/manage-cache-service.d.ts +81 -91
- package/dist/entry-tools/validate-project/cases/mixin.js +26 -6
- package/dist/entry-tools/validate-project/cases/project-summary.d.ts +7 -7
- package/dist/entry-tools/validate-project-service.d.ts +164 -592
- package/dist/entry-tools/verify-mixin-target-service.d.ts +3 -19
- package/dist/entry-tools/verify-mixin-target-service.js +19 -1
- package/dist/era-classifier.d.ts +161 -0
- package/dist/era-classifier.js +292 -0
- package/dist/error-mapping.d.ts +76 -0
- package/dist/error-mapping.js +116 -8
- package/dist/index.d.ts +42 -4
- package/dist/index.js +636 -473
- package/dist/java-process.d.ts +2 -0
- package/dist/java-process.js +22 -2
- package/dist/json-rpc-framing.d.ts +77 -1
- package/dist/json-rpc-framing.js +249 -13
- package/dist/mapping/loaders/tiny-loom-selection.d.ts +88 -0
- package/dist/mapping/loaders/tiny-loom-selection.js +223 -0
- package/dist/mapping/loaders/tiny-loom.js +45 -33
- package/dist/mapping/loaders/tiny-maven.js +6 -11
- package/dist/mapping/parsers/tiny.d.ts +57 -0
- package/dist/mapping/parsers/tiny.js +99 -22
- package/dist/mapping-service.d.ts +19 -0
- package/dist/mapping-service.js +93 -9
- package/dist/maven-resolver.d.ts +18 -0
- package/dist/maven-resolver.js +20 -0
- package/dist/mcp-helpers.d.ts +19 -2
- package/dist/mcp-helpers.js +58 -9
- package/dist/minecraft-explorer-service.d.ts +1 -1
- package/dist/mixin/types.d.ts +8 -0
- package/dist/mod-analyzer.js +7 -7
- package/dist/mod-decompile-service.js +1 -0
- package/dist/nbt/java-nbt-codec.js +12 -2
- package/dist/nbt/json-patch.js +14 -3
- package/dist/nbt/pipeline.js +40 -3
- package/dist/nbt/typed-json.js +26 -1
- package/dist/registration-adapter.d.ts +32 -0
- package/dist/registration-adapter.js +52 -0
- package/dist/repo-downloader.d.ts +165 -0
- package/dist/repo-downloader.js +568 -10
- package/dist/request-context.d.ts +7 -0
- package/dist/request-context.js +9 -0
- package/dist/resources.d.ts +1 -1
- package/dist/resources.js +25 -19
- package/dist/server-identity.d.ts +27 -0
- package/dist/server-identity.js +26 -0
- package/dist/source/access-validate.js +53 -0
- package/dist/source/artifact-resolver.d.ts +81 -2
- package/dist/source/artifact-resolver.js +227 -15
- package/dist/source/class-source.d.ts +36 -0
- package/dist/source/class-source.js +222 -38
- package/dist/source/did-you-mean.d.ts +12 -1
- package/dist/source/did-you-mean.js +6 -2
- package/dist/source/file-access.js +150 -46
- package/dist/source/indexer.js +1 -0
- package/dist/source/shared-utils.d.ts +21 -0
- package/dist/source/shared-utils.js +23 -0
- package/dist/source-resolver.js +224 -57
- package/dist/source-service.d.ts +12 -1
- package/dist/stdio-supervisor.d.ts +357 -2
- package/dist/stdio-supervisor.js +1031 -80
- package/dist/storage/db.d.ts +2 -1
- package/dist/storage/db.js +15 -8
- package/dist/synthetic-decorator.d.ts +24 -0
- package/dist/synthetic-decorator.js +48 -0
- package/dist/tool-guidance.d.ts +17 -1
- package/dist/tool-guidance.js +323 -18
- package/dist/tool-schema-registry.d.ts +2 -0
- package/dist/tool-schema-registry.js +4 -0
- package/dist/tool-schemas.d.ts +2212 -3919
- package/dist/tool-schemas.js +33 -7
- package/dist/types.d.ts +35 -0
- package/dist/v1-parity-schemas.d.ts +7 -0
- package/dist/v1-parity-schemas.js +5584 -0
- package/dist/version-diff-service.d.ts +33 -0
- package/dist/version-diff-service.js +148 -3
- package/dist/version-service.js +36 -14
- package/dist/warning-details.js +18 -1
- package/docs/README-ja.md +5 -3
- package/docs/tool-reference.md +196 -19
- package/package.json +13 -8
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { V1_PARITY_SCHEMAS } from "./v1-parity-schemas.js";
|
|
3
|
+
/**
|
|
4
|
+
* Validation-bypassing Standard Schema adapter for MCP SDK v2 tool
|
|
5
|
+
* registration.
|
|
6
|
+
*
|
|
7
|
+
* The v2 SDK validates tool arguments through `schema["~standard"].validate`
|
|
8
|
+
* before invoking the handler and returns generic InvalidParams text on
|
|
9
|
+
* failure. This adapter's identity `validate` passes ALL object args through
|
|
10
|
+
* raw so runTool() remains the single source of truth for validation and
|
|
11
|
+
* error envelopes (matching pre-migration behavior, where the equivalent v1
|
|
12
|
+
* layer was bypassed).
|
|
13
|
+
*
|
|
14
|
+
* `jsonSchema` is a Converter object whose `input()` serves the pinned
|
|
15
|
+
* pre-migration wire schema for the tool (V1_PARITY_SCHEMAS), advertised
|
|
16
|
+
* VERBATIM in tools/list. The zod fallback only applies to tools without a
|
|
17
|
+
* frozen fixture (none today).
|
|
18
|
+
*/
|
|
19
|
+
export function appValidated(name, schema) {
|
|
20
|
+
return {
|
|
21
|
+
"~standard": {
|
|
22
|
+
version: 1,
|
|
23
|
+
vendor: "app",
|
|
24
|
+
validate: (value) => ({ value: value }),
|
|
25
|
+
jsonSchema: {
|
|
26
|
+
input: () => V1_PARITY_SCHEMAS[name] ?? z.toJSONSchema(schema, { io: "input" })
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Registers a tool through the v2 `registerTool` API with the
|
|
33
|
+
* validation-bypassing adapter, preserving the v1 registration surface
|
|
34
|
+
* (name, description, zod raw shape, annotations, handler).
|
|
35
|
+
*/
|
|
36
|
+
export function registerAppTool(server, name, description, shape, annotations, handler) {
|
|
37
|
+
server.registerTool(name, {
|
|
38
|
+
description,
|
|
39
|
+
inputSchema: appValidated(name, z.object(shape)),
|
|
40
|
+
annotations
|
|
41
|
+
}, handler);
|
|
42
|
+
}
|
|
43
|
+
// Low-level/expert tools duplicate capability that the six entry tools expose
|
|
44
|
+
// in a single resolve+fetch call. registerExpertTool() registers them exactly
|
|
45
|
+
// like registerAppTool() but appends a note steering agents to the entry tools
|
|
46
|
+
// first. Entry tools, batch tools, and the NBT/runtime utilities (which have no
|
|
47
|
+
// entry equivalent) keep their plain descriptions via registerAppTool().
|
|
48
|
+
export const EXPERT_TOOL_NOTE = " Expert tool: prefer the entry tools (inspect-minecraft, analyze-symbol, compare-minecraft, analyze-mod, validate-project) first.";
|
|
49
|
+
export function registerExpertTool(server, name, description, shape, annotations, handler) {
|
|
50
|
+
registerAppTool(server, name, description + EXPERT_TOOL_NOTE, shape, annotations, handler);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=registration-adapter.js.map
|
|
@@ -1,6 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity versus freshness.
|
|
3
|
+
*
|
|
4
|
+
* Everything {@link resolveCachedDownload} parks in the URL-keyed downloads
|
|
5
|
+
* cache is identified by a sha256 of its bytes, recorded in the `.cache.json`
|
|
6
|
+
* sidecar beside the file. HTTP validators (ETag / Last-Modified) are
|
|
7
|
+
* *freshness* data only: a CDN swap or a repository migration rotates them
|
|
8
|
+
* while the bytes stay byte-identical, so a validator must never leak into an
|
|
9
|
+
* artifact id.
|
|
10
|
+
*
|
|
11
|
+
* That claim is scoped to this entry point, not to the `downloads/` directory.
|
|
12
|
+
* Callers that reach for raw {@link downloadToCache} - the version service's
|
|
13
|
+
* Mojang jars, the mapping service's mapping archives - park files under the
|
|
14
|
+
* same root, write no sidecar, and keep their own identity on purpose: a Mojang
|
|
15
|
+
* artifact already carries an upstream SHA-1 contract, and a version jar keeps
|
|
16
|
+
* an `mtimeMs:size` signature. They are a different cache layer, not a
|
|
17
|
+
* migration this module is waiting on. Artifacts on local disk outside the
|
|
18
|
+
* cache entirely (`~/.m2`, the Gradle module cache) likewise keep their own
|
|
19
|
+
* stat signature.
|
|
20
|
+
*/
|
|
1
21
|
export interface DownloadResult {
|
|
2
22
|
ok: boolean;
|
|
3
23
|
statusCode?: number;
|
|
24
|
+
/**
|
|
25
|
+
* True only for an HTTP 304 answer to a conditional request. `ok` stays false
|
|
26
|
+
* because no bytes were written; callers that send no validators can never
|
|
27
|
+
* observe it.
|
|
28
|
+
*/
|
|
29
|
+
notModified?: boolean;
|
|
4
30
|
etag?: string;
|
|
5
31
|
lastModified?: string;
|
|
6
32
|
contentLength?: number;
|
|
@@ -10,6 +36,145 @@ export interface DownloadOptions {
|
|
|
10
36
|
timeoutMs?: number;
|
|
11
37
|
retries?: number;
|
|
12
38
|
fetchFn?: typeof fetch;
|
|
39
|
+
/** Extra request headers, e.g. the conditional validators of a revalidation. */
|
|
40
|
+
requestHeaders?: Record<string, string>;
|
|
13
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* How a cached download may be reused.
|
|
44
|
+
*
|
|
45
|
+
* - `"immutable"`: the bytes behind the URL can never change, so a cached file
|
|
46
|
+
* is authoritative and no request is made.
|
|
47
|
+
* - `"revalidate"`: the bytes may change, so a cached file is confirmed with a
|
|
48
|
+
* conditional request before it is reused.
|
|
49
|
+
*/
|
|
50
|
+
export type CacheFreshness = "immutable" | "revalidate";
|
|
51
|
+
/**
|
|
52
|
+
* Where the bytes of a successful {@link resolveCachedDownload} came from.
|
|
53
|
+
*
|
|
54
|
+
* - `"downloaded"`: written by this call.
|
|
55
|
+
* - `"hit"`: served from cache with no request at all (an immutable url).
|
|
56
|
+
* - `"revalidated"`: the repository confirmed the cached bytes with a 304.
|
|
57
|
+
* - `"stale"`: revalidation failed *transiently* - the request threw, the
|
|
58
|
+
* repository answered 5xx, or we were rate limited - and the cached bytes
|
|
59
|
+
* were served anyway. Byte for byte they are as good as a `"hit"`, but
|
|
60
|
+
* nothing confirmed them on this call, which is exactly the difference a
|
|
61
|
+
* caller reporting freshness (or a test pinning the fallback) needs to see.
|
|
62
|
+
* A *definitive* rejection never lands here: see
|
|
63
|
+
* {@link DEFINITIVE_REJECTION_STATUS_CODES}.
|
|
64
|
+
*/
|
|
65
|
+
export type DownloadCacheStatus = "downloaded" | "hit" | "revalidated" | "stale";
|
|
66
|
+
export interface CachedDownloadSuccess {
|
|
67
|
+
ok: true;
|
|
68
|
+
cacheStatus: DownloadCacheStatus;
|
|
69
|
+
statusCode?: number;
|
|
70
|
+
/** The cached file. Always present on success, cache hit or not. */
|
|
71
|
+
path: string;
|
|
72
|
+
/** The real on-disk byte count. Never a Content-Length header value. */
|
|
73
|
+
contentLength: number;
|
|
74
|
+
/** sha256 of the bytes on disk. The identity of this artifact. */
|
|
75
|
+
contentSha256: string;
|
|
76
|
+
/** Freshness data only. Never feed this into an identity hash. */
|
|
77
|
+
etag?: string;
|
|
78
|
+
/** Freshness data only. Never feed this into an identity hash. */
|
|
79
|
+
lastModified?: string;
|
|
80
|
+
}
|
|
81
|
+
export interface CachedDownloadFailure {
|
|
82
|
+
ok: false;
|
|
83
|
+
statusCode?: number;
|
|
84
|
+
etag?: string;
|
|
85
|
+
lastModified?: string;
|
|
86
|
+
contentLength?: number;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The result of a cache-aware download. The success arm carries `path`,
|
|
90
|
+
* `contentLength` and `contentSha256` no matter which leg produced it, so a
|
|
91
|
+
* caller cannot accidentally derive a different identity for a cache hit than
|
|
92
|
+
* for a fresh download.
|
|
93
|
+
*/
|
|
94
|
+
export type CachedDownloadResult = CachedDownloadSuccess | CachedDownloadFailure;
|
|
95
|
+
/** The persisted identity and freshness record for one cached download. */
|
|
96
|
+
export interface DownloadSidecar {
|
|
97
|
+
version: number;
|
|
98
|
+
url: string;
|
|
99
|
+
contentSha256: string;
|
|
100
|
+
contentLength: number;
|
|
101
|
+
/**
|
|
102
|
+
* `mtimeMs` of the described file when the record was written. Together with
|
|
103
|
+
* `contentLength` this is what binds the digest to a specific set of bytes, so
|
|
104
|
+
* a replacement - accidental or racing - retires the record instead of
|
|
105
|
+
* outliving the bytes it describes.
|
|
106
|
+
*/
|
|
107
|
+
contentMtimeMs: number;
|
|
108
|
+
etag?: string;
|
|
109
|
+
lastModified?: string;
|
|
110
|
+
}
|
|
111
|
+
/** Location of the sidecar describing `destinationPath`. Destination-adjacent. */
|
|
112
|
+
export declare function downloadSidecarPath(destinationPath: string): string;
|
|
113
|
+
/**
|
|
114
|
+
* Whether `filePath` is a download sidecar - finished or half-written - rather
|
|
115
|
+
* than a downloaded artifact.
|
|
116
|
+
*
|
|
117
|
+
* This module owns the sidecar naming scheme, so consumers that walk the
|
|
118
|
+
* download cache (the cache registry inventory) ask here instead of matching
|
|
119
|
+
* the suffix themselves. The in-flight form counts: a process killed inside
|
|
120
|
+
* {@link writeDownloadSidecar} leaves `<jar>.cache.json.<hex>.tmp`, which is
|
|
121
|
+
* still a description of a jar and must never be inventoried as a cached
|
|
122
|
+
* artifact in its own right. Widening the predicate rather than renaming the
|
|
123
|
+
* temp into the plain suffix is what also covers the leftovers already sitting
|
|
124
|
+
* in caches written by earlier builds - the only leftovers that exist today.
|
|
125
|
+
*
|
|
126
|
+
* The jar temps {@link downloadToCache} writes (`<jar>.<hex>.tmp`, no sidecar
|
|
127
|
+
* suffix) are deliberately not matched: those are truncated *artifacts*, and
|
|
128
|
+
* the inventory has always listed them as such.
|
|
129
|
+
*/
|
|
130
|
+
export declare function isDownloadSidecarPath(filePath: string): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Evict a cached download and its identity record.
|
|
133
|
+
*
|
|
134
|
+
* For a caller that got its bytes and then found them unusable - a 200 carrying
|
|
135
|
+
* an HTML error page instead of a jar, say. The transfer succeeded, so nothing
|
|
136
|
+
* in here can tell it apart from a real artifact, and for an immutable url the
|
|
137
|
+
* entry would otherwise be served straight back on every later run with no
|
|
138
|
+
* request made at all: the poison would outlive the outage that produced it.
|
|
139
|
+
*
|
|
140
|
+
* Record first, bytes second, matching {@link writeDownloadSidecar}'s ordering
|
|
141
|
+
* in reverse: no window ever holds a record describing bytes that are gone. Both
|
|
142
|
+
* steps are best-effort - a file we could not remove is at worst re-validated
|
|
143
|
+
* and re-evicted next time.
|
|
144
|
+
*/
|
|
145
|
+
export declare function discardCachedDownload(destinationPath: string): void;
|
|
146
|
+
/**
|
|
147
|
+
* Resolve a URL into a cached file, deciding here - inside the module that owns
|
|
148
|
+
* the download cache - whether the network is needed at all.
|
|
149
|
+
*
|
|
150
|
+
* `freshness: "immutable"` never asks the network once the file exists.
|
|
151
|
+
* `freshness: "revalidate"` confirms known validators with a conditional
|
|
152
|
+
* request and keeps the cached bytes on a 304. When revalidation fails
|
|
153
|
+
* *transiently* (offline repo, 5xx, rate limiting) the cached bytes are still
|
|
154
|
+
* served - they are a byte-exact copy of what the repository handed out before,
|
|
155
|
+
* and losing them to a passing failure would be a regression over the previous
|
|
156
|
+
* unconditional "file exists -> reuse it" behaviour - but they are reported as
|
|
157
|
+
* `cacheStatus: "stale"`, never as a confirmed hit. A definitive rejection
|
|
158
|
+
* ({@link DEFINITIVE_REJECTION_STATUS_CODES}) is reported as the failure it is,
|
|
159
|
+
* so the caller can fail over to another repository.
|
|
160
|
+
*
|
|
161
|
+
* A zero-byte answer is refused rather than cached: see {@link cachedByteCount}.
|
|
162
|
+
*
|
|
163
|
+
* @param url - The artifact URL; also the identity the sidecar is bound to.
|
|
164
|
+
* @param destinationPath - Where the bytes live; the sidecar sits next to it.
|
|
165
|
+
* @param options - Download options plus the required freshness policy.
|
|
166
|
+
* @returns A result whose success arm always carries `path`, the real on-disk
|
|
167
|
+
* `contentLength`, and `contentSha256`, regardless of which leg produced it.
|
|
168
|
+
*/
|
|
169
|
+
export declare function resolveCachedDownload(url: string, destinationPath: string, options: DownloadOptions & {
|
|
170
|
+
freshness: CacheFreshness;
|
|
171
|
+
}): Promise<CachedDownloadResult>;
|
|
172
|
+
/**
|
|
173
|
+
* Fetch `url` unconditionally and stream it into `destinationPath`.
|
|
174
|
+
*
|
|
175
|
+
* This is the raw transfer: it knows nothing about what is already cached.
|
|
176
|
+
* Prefer {@link resolveCachedDownload} for anything keyed by URL in the
|
|
177
|
+
* downloads cache.
|
|
178
|
+
*/
|
|
14
179
|
export declare function downloadToCache(url: string, destinationPath: string, opts?: DownloadOptions): Promise<DownloadResult>;
|
|
15
180
|
export declare function defaultDownloadPath(cacheDir: string, url: string): string;
|