@adhisang/minecraft-modding-mcp 2.1.0 → 3.1.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 (32) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/README.md +224 -802
  3. package/dist/cache-registry.d.ts +95 -0
  4. package/dist/cache-registry.js +541 -0
  5. package/dist/entry-tools/analyze-mod-service.d.ts +207 -0
  6. package/dist/entry-tools/analyze-mod-service.js +309 -0
  7. package/dist/entry-tools/analyze-symbol-service.d.ts +209 -0
  8. package/dist/entry-tools/analyze-symbol-service.js +359 -0
  9. package/dist/entry-tools/compare-minecraft-service.d.ts +210 -0
  10. package/dist/entry-tools/compare-minecraft-service.js +429 -0
  11. package/dist/entry-tools/entry-tool-schema.d.ts +6 -0
  12. package/dist/entry-tools/entry-tool-schema.js +10 -0
  13. package/dist/entry-tools/inspect-minecraft-service.d.ts +1954 -0
  14. package/dist/entry-tools/inspect-minecraft-service.js +1030 -0
  15. package/dist/entry-tools/manage-cache-service.d.ts +130 -0
  16. package/dist/entry-tools/manage-cache-service.js +264 -0
  17. package/dist/entry-tools/request-normalizers.d.ts +10 -0
  18. package/dist/entry-tools/request-normalizers.js +36 -0
  19. package/dist/entry-tools/response-contract.d.ts +45 -0
  20. package/dist/entry-tools/response-contract.js +99 -0
  21. package/dist/entry-tools/validate-project-service.d.ts +543 -0
  22. package/dist/entry-tools/validate-project-service.js +414 -0
  23. package/dist/index.js +183 -59
  24. package/dist/observability.d.ts +18 -2
  25. package/dist/observability.js +47 -10
  26. package/dist/source-service.d.ts +0 -1
  27. package/dist/source-service.js +44 -54
  28. package/dist/storage/files-repo.d.ts +1 -0
  29. package/dist/storage/files-repo.js +29 -5
  30. package/dist/tool-contract-manifest.d.ts +4 -0
  31. package/dist/tool-contract-manifest.js +139 -0
  32. package/package.json +1 -1
@@ -0,0 +1,210 @@
1
+ import { z } from "zod";
2
+ import type { DiffClassSignaturesOutput } from "../source-service.js";
3
+ import type { CompareVersionsOutput } from "../version-diff-service.js";
4
+ import type { GetRegistryDataOutput } from "../registry-service.js";
5
+ export declare const compareMinecraftShape: {
6
+ task: z.ZodOptional<z.ZodEnum<["auto", "versions", "class-diff", "registry-diff", "migration-overview"]>>;
7
+ subject: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
8
+ kind: z.ZodLiteral<"version-pair">;
9
+ fromVersion: z.ZodString;
10
+ toVersion: z.ZodString;
11
+ packageFilter: z.ZodOptional<z.ZodString>;
12
+ }, "strip", z.ZodTypeAny, {
13
+ kind: "version-pair";
14
+ fromVersion: string;
15
+ toVersion: string;
16
+ packageFilter?: string | undefined;
17
+ }, {
18
+ kind: "version-pair";
19
+ fromVersion: string;
20
+ toVersion: string;
21
+ packageFilter?: string | undefined;
22
+ }>, z.ZodObject<{
23
+ kind: z.ZodLiteral<"class">;
24
+ className: z.ZodString;
25
+ fromVersion: z.ZodString;
26
+ toVersion: z.ZodString;
27
+ mapping: z.ZodOptional<z.ZodEnum<["obfuscated", "mojang", "intermediary", "yarn"]>>;
28
+ sourcePriority: z.ZodOptional<z.ZodEnum<["loom-first", "maven-first"]>>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ kind: "class";
31
+ className: string;
32
+ fromVersion: string;
33
+ toVersion: string;
34
+ mapping?: "intermediary" | "mojang" | "yarn" | "obfuscated" | undefined;
35
+ sourcePriority?: "loom-first" | "maven-first" | undefined;
36
+ }, {
37
+ kind: "class";
38
+ className: string;
39
+ fromVersion: string;
40
+ toVersion: string;
41
+ mapping?: "intermediary" | "mojang" | "yarn" | "obfuscated" | undefined;
42
+ sourcePriority?: "loom-first" | "maven-first" | undefined;
43
+ }>, z.ZodObject<{
44
+ kind: z.ZodLiteral<"registry">;
45
+ fromVersion: z.ZodString;
46
+ toVersion: z.ZodString;
47
+ registry: z.ZodOptional<z.ZodString>;
48
+ }, "strip", z.ZodTypeAny, {
49
+ kind: "registry";
50
+ fromVersion: string;
51
+ toVersion: string;
52
+ registry?: string | undefined;
53
+ }, {
54
+ kind: "registry";
55
+ fromVersion: string;
56
+ toVersion: string;
57
+ registry?: string | undefined;
58
+ }>]>;
59
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
60
+ include: z.ZodOptional<z.ZodArray<z.ZodEnum<[string, ...string[]]>, "many">>;
61
+ limit: z.ZodOptional<z.ZodNumber>;
62
+ maxClassResults: z.ZodDefault<z.ZodNumber>;
63
+ maxEntriesPerRegistry: z.ZodOptional<z.ZodNumber>;
64
+ includeFullDiff: z.ZodDefault<z.ZodBoolean>;
65
+ };
66
+ export declare const compareMinecraftSchema: z.ZodObject<{
67
+ task: z.ZodOptional<z.ZodEnum<["auto", "versions", "class-diff", "registry-diff", "migration-overview"]>>;
68
+ subject: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
69
+ kind: z.ZodLiteral<"version-pair">;
70
+ fromVersion: z.ZodString;
71
+ toVersion: z.ZodString;
72
+ packageFilter: z.ZodOptional<z.ZodString>;
73
+ }, "strip", z.ZodTypeAny, {
74
+ kind: "version-pair";
75
+ fromVersion: string;
76
+ toVersion: string;
77
+ packageFilter?: string | undefined;
78
+ }, {
79
+ kind: "version-pair";
80
+ fromVersion: string;
81
+ toVersion: string;
82
+ packageFilter?: string | undefined;
83
+ }>, z.ZodObject<{
84
+ kind: z.ZodLiteral<"class">;
85
+ className: z.ZodString;
86
+ fromVersion: z.ZodString;
87
+ toVersion: z.ZodString;
88
+ mapping: z.ZodOptional<z.ZodEnum<["obfuscated", "mojang", "intermediary", "yarn"]>>;
89
+ sourcePriority: z.ZodOptional<z.ZodEnum<["loom-first", "maven-first"]>>;
90
+ }, "strip", z.ZodTypeAny, {
91
+ kind: "class";
92
+ className: string;
93
+ fromVersion: string;
94
+ toVersion: string;
95
+ mapping?: "intermediary" | "mojang" | "yarn" | "obfuscated" | undefined;
96
+ sourcePriority?: "loom-first" | "maven-first" | undefined;
97
+ }, {
98
+ kind: "class";
99
+ className: string;
100
+ fromVersion: string;
101
+ toVersion: string;
102
+ mapping?: "intermediary" | "mojang" | "yarn" | "obfuscated" | undefined;
103
+ sourcePriority?: "loom-first" | "maven-first" | undefined;
104
+ }>, z.ZodObject<{
105
+ kind: z.ZodLiteral<"registry">;
106
+ fromVersion: z.ZodString;
107
+ toVersion: z.ZodString;
108
+ registry: z.ZodOptional<z.ZodString>;
109
+ }, "strip", z.ZodTypeAny, {
110
+ kind: "registry";
111
+ fromVersion: string;
112
+ toVersion: string;
113
+ registry?: string | undefined;
114
+ }, {
115
+ kind: "registry";
116
+ fromVersion: string;
117
+ toVersion: string;
118
+ registry?: string | undefined;
119
+ }>]>;
120
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
121
+ include: z.ZodOptional<z.ZodArray<z.ZodEnum<[string, ...string[]]>, "many">>;
122
+ limit: z.ZodOptional<z.ZodNumber>;
123
+ maxClassResults: z.ZodDefault<z.ZodNumber>;
124
+ maxEntriesPerRegistry: z.ZodOptional<z.ZodNumber>;
125
+ includeFullDiff: z.ZodDefault<z.ZodBoolean>;
126
+ }, "strip", z.ZodTypeAny, {
127
+ maxClassResults: number;
128
+ subject: {
129
+ kind: "version-pair";
130
+ fromVersion: string;
131
+ toVersion: string;
132
+ packageFilter?: string | undefined;
133
+ } | {
134
+ kind: "class";
135
+ className: string;
136
+ fromVersion: string;
137
+ toVersion: string;
138
+ mapping?: "intermediary" | "mojang" | "yarn" | "obfuscated" | undefined;
139
+ sourcePriority?: "loom-first" | "maven-first" | undefined;
140
+ } | {
141
+ kind: "registry";
142
+ fromVersion: string;
143
+ toVersion: string;
144
+ registry?: string | undefined;
145
+ };
146
+ includeFullDiff: boolean;
147
+ limit?: number | undefined;
148
+ task?: "auto" | "versions" | "class-diff" | "registry-diff" | "migration-overview" | undefined;
149
+ detail?: "full" | "summary" | "standard" | undefined;
150
+ include?: string[] | undefined;
151
+ maxEntriesPerRegistry?: number | undefined;
152
+ }, {
153
+ subject: {
154
+ kind: "version-pair";
155
+ fromVersion: string;
156
+ toVersion: string;
157
+ packageFilter?: string | undefined;
158
+ } | {
159
+ kind: "class";
160
+ className: string;
161
+ fromVersion: string;
162
+ toVersion: string;
163
+ mapping?: "intermediary" | "mojang" | "yarn" | "obfuscated" | undefined;
164
+ sourcePriority?: "loom-first" | "maven-first" | undefined;
165
+ } | {
166
+ kind: "registry";
167
+ fromVersion: string;
168
+ toVersion: string;
169
+ registry?: string | undefined;
170
+ };
171
+ limit?: number | undefined;
172
+ maxClassResults?: number | undefined;
173
+ task?: "auto" | "versions" | "class-diff" | "registry-diff" | "migration-overview" | undefined;
174
+ detail?: "full" | "summary" | "standard" | undefined;
175
+ include?: string[] | undefined;
176
+ maxEntriesPerRegistry?: number | undefined;
177
+ includeFullDiff?: boolean | undefined;
178
+ }>;
179
+ export type CompareMinecraftInput = z.infer<typeof compareMinecraftSchema>;
180
+ type CompareMinecraftDeps = {
181
+ compareVersions: (input: {
182
+ fromVersion: string;
183
+ toVersion: string;
184
+ category?: "classes" | "registry" | "all";
185
+ packageFilter?: string;
186
+ maxClassResults?: number;
187
+ }) => Promise<CompareVersionsOutput>;
188
+ diffClassSignatures: (input: {
189
+ className: string;
190
+ fromVersion: string;
191
+ toVersion: string;
192
+ mapping?: "obfuscated" | "mojang" | "intermediary" | "yarn";
193
+ sourcePriority?: "loom-first" | "maven-first";
194
+ includeFullDiff?: boolean;
195
+ }) => Promise<DiffClassSignaturesOutput>;
196
+ getRegistryData: (input: {
197
+ version: string;
198
+ registry?: string;
199
+ includeData?: boolean;
200
+ maxEntriesPerRegistry?: number;
201
+ }) => Promise<GetRegistryDataOutput>;
202
+ };
203
+ export declare class CompareMinecraftService {
204
+ private readonly deps;
205
+ constructor(deps: CompareMinecraftDeps);
206
+ execute(input: CompareMinecraftInput): Promise<Record<string, unknown> & {
207
+ warnings?: string[];
208
+ }>;
209
+ }
210
+ export {};
@@ -0,0 +1,429 @@
1
+ import { z } from "zod";
2
+ import { createError, ERROR_CODES } from "../errors.js";
3
+ import { buildIncludeSchema, detailSchema, positiveIntSchema } from "./entry-tool-schema.js";
4
+ import { buildEntryToolMeta, buildEntryToolResult, createNextAction, createSummarySubject, createTruncationMeta } from "./response-contract.js";
5
+ import { capArray, resolveDetail, resolveInclude } from "./request-normalizers.js";
6
+ const nonEmptyString = z.string().trim().min(1);
7
+ const INCLUDE_GROUPS = ["warnings", "classes", "registry", "diff", "samples", "timings"];
8
+ const subjectSchema = z.discriminatedUnion("kind", [
9
+ z.object({
10
+ kind: z.literal("version-pair"),
11
+ fromVersion: nonEmptyString,
12
+ toVersion: nonEmptyString,
13
+ packageFilter: nonEmptyString.optional()
14
+ }),
15
+ z.object({
16
+ kind: z.literal("class"),
17
+ className: nonEmptyString,
18
+ fromVersion: nonEmptyString,
19
+ toVersion: nonEmptyString,
20
+ mapping: z.enum(["obfuscated", "mojang", "intermediary", "yarn"]).optional(),
21
+ sourcePriority: z.enum(["loom-first", "maven-first"]).optional()
22
+ }),
23
+ z.object({
24
+ kind: z.literal("registry"),
25
+ fromVersion: nonEmptyString,
26
+ toVersion: nonEmptyString,
27
+ registry: nonEmptyString.optional()
28
+ })
29
+ ]);
30
+ export const compareMinecraftShape = {
31
+ task: z.enum(["auto", "versions", "class-diff", "registry-diff", "migration-overview"]).optional(),
32
+ subject: subjectSchema,
33
+ detail: detailSchema.optional(),
34
+ include: buildIncludeSchema(INCLUDE_GROUPS),
35
+ limit: positiveIntSchema.optional(),
36
+ maxClassResults: positiveIntSchema.default(500),
37
+ maxEntriesPerRegistry: positiveIntSchema.optional(),
38
+ includeFullDiff: z.boolean().default(true)
39
+ };
40
+ export const compareMinecraftSchema = z.object(compareMinecraftShape);
41
+ function compareStatusFromCounts(changedCount) {
42
+ return changedCount > 0 ? "changed" : "unchanged";
43
+ }
44
+ export class CompareMinecraftService {
45
+ deps;
46
+ constructor(deps) {
47
+ this.deps = deps;
48
+ }
49
+ async execute(input) {
50
+ const task = input.task && input.task !== "auto"
51
+ ? input.task
52
+ : input.subject.kind === "class"
53
+ ? "class-diff"
54
+ : input.subject.kind === "registry"
55
+ ? "registry-diff"
56
+ : "versions";
57
+ const detail = resolveDetail(input.detail);
58
+ const include = resolveInclude(input.include);
59
+ switch (task) {
60
+ case "versions": {
61
+ const subject = input.subject.kind === "version-pair"
62
+ ? input.subject
63
+ : {
64
+ fromVersion: input.subject.fromVersion,
65
+ toVersion: input.subject.toVersion,
66
+ packageFilter: input.subject.kind === "class" ? undefined : input.subject.registry
67
+ };
68
+ const output = await this.deps.compareVersions({
69
+ fromVersion: subject.fromVersion,
70
+ toVersion: subject.toVersion,
71
+ category: "all",
72
+ packageFilter: subject.packageFilter,
73
+ maxClassResults: input.maxClassResults
74
+ });
75
+ const changedCount = (output.classes?.addedCount ?? 0) +
76
+ (output.classes?.removedCount ?? 0) +
77
+ (output.registry?.summary.registriesChanged ?? 0);
78
+ const classSamples = capArray(output.classes?.added ?? [], 5);
79
+ const newRegistries = capArray(output.registry?.newRegistries ?? [], 5);
80
+ const removedRegistries = capArray(output.registry?.removedRegistries ?? [], 5);
81
+ const truncatedGroups = [
82
+ ...(classSamples.truncated ? ["classes"] : []),
83
+ ...(newRegistries.truncated || removedRegistries.truncated ? ["registry"] : [])
84
+ ];
85
+ const summaryTruncatedGroups = detail === "summary"
86
+ ? truncatedGroups.filter((group) => !include.includes(group))
87
+ : [];
88
+ return {
89
+ ...buildEntryToolResult({
90
+ task: "versions",
91
+ detail,
92
+ include,
93
+ summary: {
94
+ status: compareStatusFromCounts(changedCount),
95
+ headline: `Compared ${output.fromVersion} to ${output.toVersion}.`,
96
+ subject: createSummarySubject({
97
+ task: "versions",
98
+ kind: input.subject.kind,
99
+ fromVersion: input.subject.fromVersion,
100
+ toVersion: input.subject.toVersion,
101
+ packageFilter: "packageFilter" in input.subject ? input.subject.packageFilter : undefined,
102
+ registry: input.subject.kind === "registry" ? input.subject.registry : undefined
103
+ }),
104
+ counts: {
105
+ addedClasses: output.classes?.addedCount ?? 0,
106
+ removedClasses: output.classes?.removedCount ?? 0,
107
+ changedRegistries: output.registry?.summary.registriesChanged ?? 0
108
+ }
109
+ },
110
+ blocks: {
111
+ comparison: {
112
+ fromVersion: output.fromVersion,
113
+ toVersion: output.toVersion
114
+ },
115
+ classes: include.includes("classes") || detail !== "summary"
116
+ ? {
117
+ addedCount: output.classes?.addedCount ?? 0,
118
+ removedCount: output.classes?.removedCount ?? 0,
119
+ unchanged: output.classes?.unchanged ?? 0,
120
+ added: output.classes?.added ?? [],
121
+ removed: output.classes?.removed ?? []
122
+ }
123
+ : {
124
+ addedCount: output.classes?.addedCount ?? 0,
125
+ removedCount: output.classes?.removedCount ?? 0,
126
+ unchanged: output.classes?.unchanged ?? 0,
127
+ sampleAdded: classSamples.items
128
+ },
129
+ registry: output.registry
130
+ ? {
131
+ summary: output.registry.summary,
132
+ newRegistries: include.includes("registry") || detail !== "summary"
133
+ ? output.registry.newRegistries
134
+ : newRegistries.items,
135
+ removedRegistries: include.includes("registry") || detail !== "summary"
136
+ ? output.registry.removedRegistries
137
+ : removedRegistries.items
138
+ }
139
+ : undefined
140
+ }
141
+ }),
142
+ warnings: output.warnings,
143
+ ...(summaryTruncatedGroups.length > 0
144
+ ? {
145
+ meta: buildEntryToolMeta({
146
+ detail,
147
+ include,
148
+ warnings: output.warnings,
149
+ truncated: createTruncationMeta({
150
+ omittedGroups: summaryTruncatedGroups,
151
+ nextActions: [
152
+ createNextAction("compare-minecraft", {
153
+ task: "versions",
154
+ detail: "standard",
155
+ include: resolveInclude([...include, ...summaryTruncatedGroups]),
156
+ subject: input.subject
157
+ })
158
+ ]
159
+ })
160
+ })
161
+ }
162
+ : {})
163
+ };
164
+ }
165
+ case "class-diff": {
166
+ if (input.subject.kind !== "class") {
167
+ throw createError({
168
+ code: ERROR_CODES.INVALID_INPUT,
169
+ message: "task=class-diff requires subject.kind=class."
170
+ });
171
+ }
172
+ const output = await this.deps.diffClassSignatures({
173
+ className: input.subject.className,
174
+ fromVersion: input.subject.fromVersion,
175
+ toVersion: input.subject.toVersion,
176
+ mapping: input.subject.mapping,
177
+ sourcePriority: input.subject.sourcePriority,
178
+ includeFullDiff: input.includeFullDiff
179
+ });
180
+ const changedCount = output.summary.total.added +
181
+ output.summary.total.removed +
182
+ output.summary.total.modified;
183
+ return {
184
+ ...buildEntryToolResult({
185
+ task: "class-diff",
186
+ detail,
187
+ include,
188
+ summary: {
189
+ status: compareStatusFromCounts(changedCount),
190
+ headline: `Compared ${output.query.className} between ${output.range.fromVersion} and ${output.range.toVersion}.`,
191
+ subject: createSummarySubject({
192
+ task: "class-diff",
193
+ kind: "class",
194
+ className: input.subject.className,
195
+ fromVersion: input.subject.fromVersion,
196
+ toVersion: input.subject.toVersion,
197
+ mapping: input.subject.mapping,
198
+ sourcePriority: input.subject.sourcePriority
199
+ }),
200
+ counts: output.summary.total
201
+ },
202
+ blocks: {
203
+ comparison: output.query,
204
+ classDiff: include.includes("diff") || detail !== "summary"
205
+ ? {
206
+ classChange: output.classChange,
207
+ summary: output.summary,
208
+ constructors: output.constructors,
209
+ methods: output.methods,
210
+ fields: output.fields
211
+ }
212
+ : {
213
+ classChange: output.classChange,
214
+ summary: output.summary
215
+ }
216
+ }
217
+ }),
218
+ warnings: output.warnings
219
+ };
220
+ }
221
+ case "registry-diff": {
222
+ const subject = input.subject.kind === "registry"
223
+ ? input.subject
224
+ : {
225
+ fromVersion: input.subject.fromVersion,
226
+ toVersion: input.subject.toVersion,
227
+ registry: undefined
228
+ };
229
+ const compare = await this.deps.compareVersions({
230
+ fromVersion: subject.fromVersion,
231
+ toVersion: subject.toVersion,
232
+ category: "registry"
233
+ });
234
+ const warnings = [...compare.warnings];
235
+ const registrySummary = compare.registry?.summary ?? {
236
+ registriesChanged: 0,
237
+ totalAdded: 0,
238
+ totalRemoved: 0
239
+ };
240
+ let entries;
241
+ if ((include.includes("registry") || detail === "full") && subject.registry) {
242
+ const [fromData, toData] = await Promise.allSettled([
243
+ this.deps.getRegistryData({
244
+ version: subject.fromVersion,
245
+ registry: subject.registry,
246
+ includeData: true,
247
+ maxEntriesPerRegistry: input.maxEntriesPerRegistry
248
+ }),
249
+ this.deps.getRegistryData({
250
+ version: subject.toVersion,
251
+ registry: subject.registry,
252
+ includeData: true,
253
+ maxEntriesPerRegistry: input.maxEntriesPerRegistry
254
+ })
255
+ ]);
256
+ entries = {
257
+ from: fromData.status === "fulfilled" ? fromData.value : undefined,
258
+ to: toData.status === "fulfilled" ? toData.value : undefined
259
+ };
260
+ if (fromData.status === "fulfilled") {
261
+ warnings.push(...fromData.value.warnings);
262
+ }
263
+ else {
264
+ warnings.push(`Could not load ${subject.registry} registry details for ${subject.fromVersion}: ${fromData.reason instanceof Error ? fromData.reason.message : String(fromData.reason)}`);
265
+ }
266
+ if (toData.status === "fulfilled") {
267
+ warnings.push(...toData.value.warnings);
268
+ }
269
+ else {
270
+ warnings.push(`Could not load ${subject.registry} registry details for ${subject.toVersion}: ${toData.reason instanceof Error ? toData.reason.message : String(toData.reason)}`);
271
+ }
272
+ }
273
+ const partialDetail = Boolean(subject.registry) &&
274
+ (include.includes("registry") || detail === "full") &&
275
+ entries !== undefined &&
276
+ (!entries.from || !entries.to);
277
+ const missingFromDetail = partialDetail && entries != null && !entries.from;
278
+ const missingToDetail = partialDetail && entries != null && !entries.to;
279
+ const summary = {
280
+ status: partialDetail ? "partial" : compareStatusFromCounts(registrySummary.registriesChanged),
281
+ headline: partialDetail
282
+ ? `Compared registry changes between ${subject.fromVersion} and ${subject.toVersion} with partial detail.`
283
+ : `Compared registry changes between ${subject.fromVersion} and ${subject.toVersion}.`,
284
+ subject: createSummarySubject({
285
+ task: "registry-diff",
286
+ kind: "registry",
287
+ fromVersion: subject.fromVersion,
288
+ toVersion: subject.toVersion,
289
+ registry: subject.registry
290
+ }),
291
+ counts: {
292
+ changedRegistries: registrySummary.registriesChanged,
293
+ addedEntries: registrySummary.totalAdded,
294
+ removedEntries: registrySummary.totalRemoved
295
+ },
296
+ ...(partialDetail
297
+ ? {
298
+ nextActions: [
299
+ ...(missingFromDetail
300
+ ? [{
301
+ tool: "get-registry-data",
302
+ params: {
303
+ version: subject.fromVersion,
304
+ registry: subject.registry,
305
+ includeData: true,
306
+ maxEntriesPerRegistry: input.maxEntriesPerRegistry
307
+ }
308
+ }]
309
+ : []),
310
+ ...(missingToDetail
311
+ ? [{
312
+ tool: "get-registry-data",
313
+ params: {
314
+ version: subject.toVersion,
315
+ registry: subject.registry,
316
+ includeData: true,
317
+ maxEntriesPerRegistry: input.maxEntriesPerRegistry
318
+ }
319
+ }]
320
+ : [])
321
+ ]
322
+ }
323
+ : {})
324
+ };
325
+ return {
326
+ ...buildEntryToolResult({
327
+ task: "registry-diff",
328
+ detail,
329
+ include,
330
+ summary,
331
+ blocks: {
332
+ comparison: {
333
+ fromVersion: subject.fromVersion,
334
+ toVersion: subject.toVersion,
335
+ registry: subject.registry
336
+ },
337
+ registry: {
338
+ summary: registrySummary,
339
+ entries
340
+ }
341
+ }
342
+ }),
343
+ warnings
344
+ };
345
+ }
346
+ case "migration-overview": {
347
+ const subject = input.subject.kind === "version-pair"
348
+ ? input.subject
349
+ : {
350
+ fromVersion: input.subject.fromVersion,
351
+ toVersion: input.subject.toVersion
352
+ };
353
+ const compare = await this.deps.compareVersions({
354
+ fromVersion: subject.fromVersion,
355
+ toVersion: subject.toVersion,
356
+ category: "all",
357
+ maxClassResults: input.maxClassResults
358
+ });
359
+ const classSignals = (compare.classes?.addedCount ?? 0) + (compare.classes?.removedCount ?? 0);
360
+ const registrySignals = compare.registry?.summary.registriesChanged ?? 0;
361
+ const status = compareStatusFromCounts(classSignals + registrySignals);
362
+ const representativeClassName = compare.classes?.added[0] ?? compare.classes?.removed[0];
363
+ const nextActions = representativeClassName
364
+ ? [
365
+ createNextAction("compare-minecraft", {
366
+ task: "class-diff",
367
+ subject: {
368
+ kind: "class",
369
+ className: representativeClassName,
370
+ fromVersion: subject.fromVersion,
371
+ toVersion: subject.toVersion
372
+ }
373
+ })
374
+ ]
375
+ : [
376
+ createNextAction("inspect-minecraft", {
377
+ task: "artifact",
378
+ subject: {
379
+ kind: "version",
380
+ version: subject.toVersion
381
+ }
382
+ })
383
+ ];
384
+ return {
385
+ ...buildEntryToolResult({
386
+ task: "migration-overview",
387
+ detail,
388
+ include,
389
+ summary: {
390
+ status,
391
+ headline: `Summarized migration impact from ${subject.fromVersion} to ${subject.toVersion}.`,
392
+ subject: createSummarySubject({
393
+ task: "migration-overview",
394
+ kind: "version-pair",
395
+ fromVersion: subject.fromVersion,
396
+ toVersion: subject.toVersion
397
+ }),
398
+ counts: {
399
+ classSignals,
400
+ registrySignals
401
+ },
402
+ nextActions
403
+ },
404
+ blocks: {
405
+ comparison: subject,
406
+ migration: {
407
+ impact: classSignals > 0 && registrySignals > 0
408
+ ? "classes-and-registry"
409
+ : classSignals > 0
410
+ ? "classes"
411
+ : registrySignals > 0
412
+ ? "registry"
413
+ : "minimal",
414
+ nextActions
415
+ }
416
+ }
417
+ }),
418
+ warnings: compare.warnings
419
+ };
420
+ }
421
+ default:
422
+ throw createError({
423
+ code: ERROR_CODES.INVALID_INPUT,
424
+ message: `Unsupported compare-minecraft task "${task}".`
425
+ });
426
+ }
427
+ }
428
+ }
429
+ //# sourceMappingURL=compare-minecraft-service.js.map
@@ -0,0 +1,6 @@
1
+ import { z } from "zod";
2
+ export declare const detailSchema: z.ZodEnum<["summary", "standard", "full"]>;
3
+ export declare const includeGroupSchema: z.ZodEnum<["warnings", "provenance", "candidates", "members", "source", "files", "samples", "diff", "issues", "timeline", "matrix", "entries", "workspace", "health", "recovery", "paths", "owners", "preview", "cacheEntries", "timings", "artifact", "classes", "registry"]>;
4
+ export declare const executionModeSchema: z.ZodEnum<["preview", "apply"]>;
5
+ export declare const positiveIntSchema: z.ZodNumber;
6
+ export declare function buildIncludeSchema(allowed: readonly string[]): z.ZodOptional<z.ZodArray<z.ZodEnum<[string, ...string[]]>, "many">>;
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+ import { CANONICAL_INCLUDE_GROUPS, DETAIL_LEVELS } from "./response-contract.js";
3
+ export const detailSchema = z.enum(DETAIL_LEVELS);
4
+ export const includeGroupSchema = z.enum(CANONICAL_INCLUDE_GROUPS);
5
+ export const executionModeSchema = z.enum(["preview", "apply"]);
6
+ export const positiveIntSchema = z.number().int().positive();
7
+ export function buildIncludeSchema(allowed) {
8
+ return z.array(z.enum(allowed)).optional();
9
+ }
10
+ //# sourceMappingURL=entry-tool-schema.js.map