@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.
Files changed (101) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +13 -3
  3. package/dist/cache-policy.d.ts +71 -0
  4. package/dist/cache-policy.js +83 -0
  5. package/dist/cache-registry.js +45 -8
  6. package/dist/cli.js +74 -3
  7. package/dist/compat-stdio-transport.d.ts +1 -1
  8. package/dist/compat-stdio-transport.js +13 -1
  9. package/dist/config.d.ts +3 -0
  10. package/dist/config.js +8 -2
  11. package/dist/decompiler/vineflower.d.ts +1 -0
  12. package/dist/decompiler/vineflower.js +8 -5
  13. package/dist/entry-tools/analyze-mod-service.d.ts +70 -136
  14. package/dist/entry-tools/analyze-symbol-service.d.ts +112 -150
  15. package/dist/entry-tools/compare-minecraft-service.d.ts +59 -145
  16. package/dist/entry-tools/entry-tool-schema.d.ts +38 -4
  17. package/dist/entry-tools/entry-tool-schema.js +4 -1
  18. package/dist/entry-tools/inspect-minecraft/internal.d.ts +235 -799
  19. package/dist/entry-tools/inspect-minecraft/internal.js +50 -13
  20. package/dist/entry-tools/inspect-minecraft-service.d.ts +372 -1736
  21. package/dist/entry-tools/manage-cache-service.d.ts +81 -91
  22. package/dist/entry-tools/validate-project/cases/mixin.js +26 -6
  23. package/dist/entry-tools/validate-project/cases/project-summary.d.ts +7 -7
  24. package/dist/entry-tools/validate-project-service.d.ts +164 -592
  25. package/dist/entry-tools/verify-mixin-target-service.d.ts +3 -19
  26. package/dist/entry-tools/verify-mixin-target-service.js +19 -1
  27. package/dist/era-classifier.d.ts +161 -0
  28. package/dist/era-classifier.js +292 -0
  29. package/dist/error-mapping.d.ts +76 -0
  30. package/dist/error-mapping.js +116 -8
  31. package/dist/index.d.ts +42 -4
  32. package/dist/index.js +636 -473
  33. package/dist/java-process.d.ts +2 -0
  34. package/dist/java-process.js +22 -2
  35. package/dist/json-rpc-framing.d.ts +77 -1
  36. package/dist/json-rpc-framing.js +249 -13
  37. package/dist/mapping/loaders/tiny-loom-selection.d.ts +88 -0
  38. package/dist/mapping/loaders/tiny-loom-selection.js +223 -0
  39. package/dist/mapping/loaders/tiny-loom.js +45 -33
  40. package/dist/mapping/loaders/tiny-maven.js +6 -11
  41. package/dist/mapping/parsers/tiny.d.ts +57 -0
  42. package/dist/mapping/parsers/tiny.js +99 -22
  43. package/dist/mapping-service.d.ts +19 -0
  44. package/dist/mapping-service.js +93 -9
  45. package/dist/maven-resolver.d.ts +18 -0
  46. package/dist/maven-resolver.js +20 -0
  47. package/dist/mcp-helpers.d.ts +19 -2
  48. package/dist/mcp-helpers.js +58 -9
  49. package/dist/minecraft-explorer-service.d.ts +1 -1
  50. package/dist/mixin/types.d.ts +8 -0
  51. package/dist/mod-analyzer.js +7 -7
  52. package/dist/mod-decompile-service.js +1 -0
  53. package/dist/nbt/java-nbt-codec.js +12 -2
  54. package/dist/nbt/json-patch.js +14 -3
  55. package/dist/nbt/pipeline.js +40 -3
  56. package/dist/nbt/typed-json.js +26 -1
  57. package/dist/registration-adapter.d.ts +32 -0
  58. package/dist/registration-adapter.js +52 -0
  59. package/dist/repo-downloader.d.ts +165 -0
  60. package/dist/repo-downloader.js +568 -10
  61. package/dist/request-context.d.ts +7 -0
  62. package/dist/request-context.js +9 -0
  63. package/dist/resources.d.ts +1 -1
  64. package/dist/resources.js +25 -19
  65. package/dist/server-identity.d.ts +27 -0
  66. package/dist/server-identity.js +26 -0
  67. package/dist/source/access-validate.js +53 -0
  68. package/dist/source/artifact-resolver.d.ts +81 -2
  69. package/dist/source/artifact-resolver.js +227 -15
  70. package/dist/source/class-source.d.ts +36 -0
  71. package/dist/source/class-source.js +222 -38
  72. package/dist/source/did-you-mean.d.ts +12 -1
  73. package/dist/source/did-you-mean.js +6 -2
  74. package/dist/source/file-access.js +150 -46
  75. package/dist/source/indexer.js +1 -0
  76. package/dist/source/shared-utils.d.ts +21 -0
  77. package/dist/source/shared-utils.js +23 -0
  78. package/dist/source-resolver.js +224 -57
  79. package/dist/source-service.d.ts +12 -1
  80. package/dist/stdio-supervisor.d.ts +357 -2
  81. package/dist/stdio-supervisor.js +1031 -80
  82. package/dist/storage/db.d.ts +2 -1
  83. package/dist/storage/db.js +15 -8
  84. package/dist/synthetic-decorator.d.ts +24 -0
  85. package/dist/synthetic-decorator.js +48 -0
  86. package/dist/tool-guidance.d.ts +17 -1
  87. package/dist/tool-guidance.js +323 -18
  88. package/dist/tool-schema-registry.d.ts +2 -0
  89. package/dist/tool-schema-registry.js +4 -0
  90. package/dist/tool-schemas.d.ts +2212 -3919
  91. package/dist/tool-schemas.js +33 -7
  92. package/dist/types.d.ts +35 -0
  93. package/dist/v1-parity-schemas.d.ts +7 -0
  94. package/dist/v1-parity-schemas.js +5584 -0
  95. package/dist/version-diff-service.d.ts +33 -0
  96. package/dist/version-diff-service.js +148 -3
  97. package/dist/version-service.js +36 -14
  98. package/dist/warning-details.js +18 -1
  99. package/docs/README-ja.md +5 -3
  100. package/docs/tool-reference.md +196 -19
  101. 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;