@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,130 @@
1
+ import { z } from "zod";
2
+ import { type CacheRegistry } from "../cache-registry.js";
3
+ export declare const manageCacheShape: {
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"]>, "many">>;
6
+ selector: z.ZodOptional<z.ZodObject<{
7
+ artifactId: z.ZodOptional<z.ZodString>;
8
+ version: z.ZodOptional<z.ZodString>;
9
+ jarPath: z.ZodOptional<z.ZodString>;
10
+ entryId: z.ZodOptional<z.ZodString>;
11
+ status: z.ZodOptional<z.ZodEnum<["healthy", "partial", "stale", "orphaned", "corrupt", "in_use"]>>;
12
+ olderThan: z.ZodOptional<z.ZodString>;
13
+ mapping: z.ZodOptional<z.ZodString>;
14
+ scope: z.ZodOptional<z.ZodString>;
15
+ projectPath: z.ZodOptional<z.ZodString>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ mapping?: string | undefined;
18
+ jarPath?: string | undefined;
19
+ projectPath?: string | undefined;
20
+ entryId?: string | undefined;
21
+ artifactId?: string | undefined;
22
+ status?: "healthy" | "partial" | "stale" | "orphaned" | "corrupt" | "in_use" | undefined;
23
+ version?: string | undefined;
24
+ scope?: string | undefined;
25
+ olderThan?: string | undefined;
26
+ }, {
27
+ mapping?: string | undefined;
28
+ jarPath?: string | undefined;
29
+ projectPath?: string | undefined;
30
+ entryId?: string | undefined;
31
+ artifactId?: string | undefined;
32
+ status?: "healthy" | "partial" | "stale" | "orphaned" | "corrupt" | "in_use" | undefined;
33
+ version?: string | undefined;
34
+ scope?: string | undefined;
35
+ olderThan?: string | undefined;
36
+ }>>;
37
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
38
+ include: z.ZodOptional<z.ZodArray<z.ZodEnum<[string, ...string[]]>, "many">>;
39
+ limit: z.ZodDefault<z.ZodNumber>;
40
+ cursor: z.ZodOptional<z.ZodString>;
41
+ executionMode: z.ZodDefault<z.ZodEnum<["preview", "apply"]>>;
42
+ };
43
+ export declare const manageCacheSchema: z.ZodObject<{
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"]>, "many">>;
46
+ selector: z.ZodOptional<z.ZodObject<{
47
+ artifactId: z.ZodOptional<z.ZodString>;
48
+ version: z.ZodOptional<z.ZodString>;
49
+ jarPath: z.ZodOptional<z.ZodString>;
50
+ entryId: z.ZodOptional<z.ZodString>;
51
+ status: z.ZodOptional<z.ZodEnum<["healthy", "partial", "stale", "orphaned", "corrupt", "in_use"]>>;
52
+ olderThan: z.ZodOptional<z.ZodString>;
53
+ mapping: z.ZodOptional<z.ZodString>;
54
+ scope: z.ZodOptional<z.ZodString>;
55
+ projectPath: z.ZodOptional<z.ZodString>;
56
+ }, "strip", z.ZodTypeAny, {
57
+ mapping?: string | undefined;
58
+ jarPath?: string | undefined;
59
+ projectPath?: string | undefined;
60
+ entryId?: string | undefined;
61
+ artifactId?: string | undefined;
62
+ status?: "healthy" | "partial" | "stale" | "orphaned" | "corrupt" | "in_use" | undefined;
63
+ version?: string | undefined;
64
+ scope?: string | undefined;
65
+ olderThan?: string | undefined;
66
+ }, {
67
+ mapping?: string | undefined;
68
+ jarPath?: string | undefined;
69
+ projectPath?: string | undefined;
70
+ entryId?: string | undefined;
71
+ artifactId?: string | undefined;
72
+ status?: "healthy" | "partial" | "stale" | "orphaned" | "corrupt" | "in_use" | undefined;
73
+ version?: string | undefined;
74
+ scope?: string | undefined;
75
+ olderThan?: string | undefined;
76
+ }>>;
77
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
78
+ include: z.ZodOptional<z.ZodArray<z.ZodEnum<[string, ...string[]]>, "many">>;
79
+ limit: z.ZodDefault<z.ZodNumber>;
80
+ cursor: z.ZodOptional<z.ZodString>;
81
+ executionMode: z.ZodDefault<z.ZodEnum<["preview", "apply"]>>;
82
+ }, "strip", z.ZodTypeAny, {
83
+ limit: number;
84
+ executionMode: "preview" | "apply";
85
+ action: "list" | "summary" | "inspect" | "verify" | "delete" | "prune" | "rebuild";
86
+ cursor?: string | undefined;
87
+ detail?: "full" | "summary" | "standard" | undefined;
88
+ include?: string[] | undefined;
89
+ cacheKinds?: ("artifact-index" | "downloads" | "mapping" | "registry" | "decompiled-source" | "mod-remap")[] | undefined;
90
+ selector?: {
91
+ mapping?: string | undefined;
92
+ jarPath?: string | undefined;
93
+ projectPath?: string | undefined;
94
+ entryId?: string | undefined;
95
+ artifactId?: string | undefined;
96
+ status?: "healthy" | "partial" | "stale" | "orphaned" | "corrupt" | "in_use" | undefined;
97
+ version?: string | undefined;
98
+ scope?: string | undefined;
99
+ olderThan?: string | undefined;
100
+ } | undefined;
101
+ }, {
102
+ action: "list" | "summary" | "inspect" | "verify" | "delete" | "prune" | "rebuild";
103
+ limit?: number | undefined;
104
+ cursor?: string | undefined;
105
+ detail?: "full" | "summary" | "standard" | undefined;
106
+ include?: string[] | undefined;
107
+ executionMode?: "preview" | "apply" | undefined;
108
+ cacheKinds?: ("artifact-index" | "downloads" | "mapping" | "registry" | "decompiled-source" | "mod-remap")[] | undefined;
109
+ selector?: {
110
+ mapping?: string | undefined;
111
+ jarPath?: string | undefined;
112
+ projectPath?: string | undefined;
113
+ entryId?: string | undefined;
114
+ artifactId?: string | undefined;
115
+ status?: "healthy" | "partial" | "stale" | "orphaned" | "corrupt" | "in_use" | undefined;
116
+ version?: string | undefined;
117
+ scope?: string | undefined;
118
+ olderThan?: string | undefined;
119
+ } | undefined;
120
+ }>;
121
+ export type ManageCacheInput = z.infer<typeof manageCacheSchema>;
122
+ export declare class ManageCacheService {
123
+ private readonly deps;
124
+ constructor(deps: {
125
+ registry: CacheRegistry;
126
+ });
127
+ execute(input: ManageCacheInput): Promise<Record<string, unknown> & {
128
+ warnings?: string[];
129
+ }>;
130
+ }
@@ -0,0 +1,264 @@
1
+ import { z } from "zod";
2
+ import { PUBLIC_CACHE_KINDS } from "../cache-registry.js";
3
+ import { createError, ERROR_CODES } from "../errors.js";
4
+ import { buildIncludeSchema, detailSchema, executionModeSchema, positiveIntSchema } from "./entry-tool-schema.js";
5
+ import { buildEntryToolResult, createNextAction, createSummarySubject } from "./response-contract.js";
6
+ import { normalizeReadOnlyExecutionMode, requireNonEmptyObject, resolveDetail, resolveInclude } from "./request-normalizers.js";
7
+ const nonEmptyString = z.string().trim().min(1);
8
+ const INCLUDE_GROUPS = ["warnings", "cacheEntries", "paths", "owners", "health", "preview", "timings"];
9
+ export const manageCacheShape = {
10
+ action: z.enum(["summary", "list", "inspect", "delete", "prune", "rebuild", "verify"]),
11
+ cacheKinds: z.array(z.enum(PUBLIC_CACHE_KINDS)).optional(),
12
+ selector: z.object({
13
+ artifactId: nonEmptyString.optional(),
14
+ version: nonEmptyString.optional(),
15
+ jarPath: nonEmptyString.optional(),
16
+ entryId: nonEmptyString.optional(),
17
+ status: z.enum(["healthy", "partial", "stale", "orphaned", "corrupt", "in_use"]).optional(),
18
+ olderThan: nonEmptyString.optional(),
19
+ mapping: nonEmptyString.optional(),
20
+ scope: nonEmptyString.optional(),
21
+ projectPath: nonEmptyString.optional()
22
+ }).optional(),
23
+ detail: detailSchema.optional(),
24
+ include: buildIncludeSchema(INCLUDE_GROUPS),
25
+ limit: positiveIntSchema.default(50),
26
+ cursor: nonEmptyString.optional(),
27
+ executionMode: executionModeSchema.default("preview")
28
+ };
29
+ export const manageCacheSchema = z.object(manageCacheShape);
30
+ export class ManageCacheService {
31
+ deps;
32
+ constructor(deps) {
33
+ this.deps = deps;
34
+ }
35
+ async execute(input) {
36
+ const detail = resolveDetail(input.detail);
37
+ const include = resolveInclude(input.include);
38
+ const executionMode = normalizeReadOnlyExecutionMode(input.action, input.executionMode);
39
+ const cacheKinds = input.cacheKinds?.length ? input.cacheKinds : [...PUBLIC_CACHE_KINDS];
40
+ const summarySubject = createSummarySubject({
41
+ action: input.action,
42
+ cacheKinds,
43
+ executionMode,
44
+ selector: input.selector
45
+ });
46
+ if (executionMode === "apply" &&
47
+ (input.action === "delete" || input.action === "prune" || input.action === "rebuild")) {
48
+ requireNonEmptyObject(input.selector, `${input.action} apply requires a non-empty selector.`);
49
+ }
50
+ switch (input.action) {
51
+ case "summary": {
52
+ const summary = await this.deps.registry.summarize({
53
+ cacheKinds,
54
+ selector: input.selector
55
+ });
56
+ const hasUnhealthyKinds = Object.values(summary.kinds).some((item) => item && item.status !== "healthy");
57
+ const entryCount = Object.values(summary.kinds).reduce((total, item) => total + (item?.entryCount ?? 0), 0);
58
+ const totalBytes = Object.values(summary.kinds).reduce((total, item) => total + (item?.totalBytes ?? 0), 0);
59
+ return {
60
+ ...buildEntryToolResult({
61
+ task: "summary",
62
+ detail,
63
+ include,
64
+ summary: {
65
+ status: hasUnhealthyKinds ? "partial" : "ok",
66
+ headline: `Summarized ${cacheKinds.length} cache kind(s).`,
67
+ subject: summarySubject,
68
+ counts: {
69
+ entries: entryCount,
70
+ bytes: totalBytes
71
+ }
72
+ },
73
+ blocks: {
74
+ stats: summary.kinds,
75
+ operation: {
76
+ executionMode
77
+ }
78
+ },
79
+ alwaysBlocks: ["operation"]
80
+ }),
81
+ warnings: []
82
+ };
83
+ }
84
+ case "list":
85
+ case "inspect": {
86
+ const page = input.action === "list"
87
+ ? await this.deps.registry.listEntries({
88
+ cacheKinds,
89
+ selector: input.selector,
90
+ limit: input.limit,
91
+ cursor: input.cursor
92
+ })
93
+ : {
94
+ entries: await this.deps.registry.inspectEntries({
95
+ cacheKinds,
96
+ selector: input.selector,
97
+ limit: input.limit
98
+ }),
99
+ nextCursor: undefined
100
+ };
101
+ const hasUnhealthyEntries = page.entries.some((entry) => entry.status !== "healthy");
102
+ return {
103
+ ...buildEntryToolResult({
104
+ task: input.action,
105
+ detail,
106
+ include,
107
+ summary: {
108
+ status: hasUnhealthyEntries ? "partial" : "ok",
109
+ headline: `${input.action === "list" ? "Listed" : "Inspected"} ${page.entries.length} cache entr${page.entries.length === 1 ? "y" : "ies"}.`,
110
+ subject: summarySubject,
111
+ counts: {
112
+ entries: page.entries.length
113
+ }
114
+ },
115
+ blocks: {
116
+ cacheEntries: page.entries,
117
+ operation: {
118
+ executionMode
119
+ }
120
+ },
121
+ alwaysBlocks: ["operation"]
122
+ }),
123
+ warnings: [],
124
+ ...(input.action === "list" && page.nextCursor
125
+ ? {
126
+ meta: {
127
+ pagination: {
128
+ nextCursor: page.nextCursor
129
+ }
130
+ }
131
+ }
132
+ : {})
133
+ };
134
+ }
135
+ case "verify": {
136
+ const output = await this.deps.registry.verifyEntries({
137
+ cacheKinds,
138
+ selector: input.selector
139
+ });
140
+ return {
141
+ ...buildEntryToolResult({
142
+ task: "verify",
143
+ detail,
144
+ include,
145
+ summary: {
146
+ status: output.unhealthyEntries > 0 ? "partial" : "ok",
147
+ headline: `Verified ${output.checkedEntries} cache entr${output.checkedEntries === 1 ? "y" : "ies"}.`,
148
+ subject: summarySubject,
149
+ counts: {
150
+ checkedEntries: output.checkedEntries,
151
+ unhealthyEntries: output.unhealthyEntries
152
+ }
153
+ },
154
+ blocks: {
155
+ operation: {
156
+ executionMode
157
+ }
158
+ },
159
+ alwaysBlocks: ["operation"]
160
+ }),
161
+ warnings: output.warnings
162
+ };
163
+ }
164
+ case "delete":
165
+ case "prune": {
166
+ const output = input.action === "delete"
167
+ ? await this.deps.registry.deleteEntries({
168
+ cacheKinds,
169
+ selector: input.selector,
170
+ executionMode
171
+ })
172
+ : await this.deps.registry.pruneEntries({
173
+ cacheKinds,
174
+ selector: input.selector,
175
+ executionMode
176
+ });
177
+ return {
178
+ ...buildEntryToolResult({
179
+ task: input.action,
180
+ detail,
181
+ include,
182
+ summary: {
183
+ status: output.deletedEntries > 0 && executionMode === "apply" ? "changed" : "unchanged",
184
+ headline: `${executionMode === "apply" ? "Applied" : "Previewed"} ${input.action} across ${cacheKinds.length} cache kind(s).`,
185
+ subject: summarySubject,
186
+ counts: {
187
+ deletedEntries: output.deletedEntries,
188
+ deletedBytes: output.deletedBytes
189
+ },
190
+ ...(executionMode === "preview"
191
+ ? {
192
+ nextActions: [
193
+ createNextAction("manage-cache", {
194
+ action: input.action,
195
+ cacheKinds,
196
+ executionMode: "apply",
197
+ selector: input.selector
198
+ })
199
+ ]
200
+ }
201
+ : {})
202
+ },
203
+ blocks: {
204
+ operation: {
205
+ executionMode,
206
+ deletedEntries: output.deletedEntries,
207
+ deletedBytes: output.deletedBytes
208
+ }
209
+ },
210
+ alwaysBlocks: ["operation"]
211
+ }),
212
+ warnings: output.warnings
213
+ };
214
+ }
215
+ case "rebuild": {
216
+ const output = await this.deps.registry.rebuildEntries({
217
+ cacheKinds,
218
+ selector: input.selector,
219
+ executionMode
220
+ });
221
+ return {
222
+ ...buildEntryToolResult({
223
+ task: "rebuild",
224
+ detail,
225
+ include,
226
+ summary: {
227
+ status: output.rebuiltEntries > 0 && executionMode === "apply" ? "changed" : "unchanged",
228
+ headline: `${executionMode === "apply" ? "Applied" : "Previewed"} rebuild for ${cacheKinds.length} cache kind(s).`,
229
+ subject: summarySubject,
230
+ counts: {
231
+ rebuiltEntries: output.rebuiltEntries
232
+ },
233
+ ...(executionMode === "preview"
234
+ ? {
235
+ nextActions: [
236
+ createNextAction("manage-cache", {
237
+ action: "rebuild",
238
+ cacheKinds,
239
+ executionMode: "apply",
240
+ selector: input.selector
241
+ })
242
+ ]
243
+ }
244
+ : {})
245
+ },
246
+ blocks: {
247
+ operation: {
248
+ executionMode,
249
+ rebuiltEntries: output.rebuiltEntries
250
+ }
251
+ },
252
+ alwaysBlocks: ["operation"]
253
+ }),
254
+ warnings: output.warnings
255
+ };
256
+ }
257
+ }
258
+ throw createError({
259
+ code: ERROR_CODES.INVALID_INPUT,
260
+ message: `Unsupported manage-cache action "${input.action}".`
261
+ });
262
+ }
263
+ }
264
+ //# sourceMappingURL=manage-cache-service.js.map
@@ -0,0 +1,10 @@
1
+ import type { DetailLevel, NextAction } from "./response-contract.js";
2
+ export declare function resolveDetail(detail: DetailLevel | undefined): DetailLevel;
3
+ export declare function resolveInclude(include: readonly string[] | undefined): string[];
4
+ export declare function normalizeReadOnlyExecutionMode(action: string, executionMode: "preview" | "apply" | undefined): "preview" | "apply";
5
+ export declare function capArray<T>(values: readonly T[], maxItems: number): {
6
+ items: T[];
7
+ truncated: boolean;
8
+ };
9
+ export declare function requireNonEmptyObject(selector: Record<string, unknown> | undefined, message: string): Record<string, unknown>;
10
+ export declare function nextActionsOrUndefined(actions: NextAction[]): NextAction[] | undefined;
@@ -0,0 +1,36 @@
1
+ import { createError, ERROR_CODES } from "../errors.js";
2
+ import { normalizeIncludeGroups } from "./response-contract.js";
3
+ export function resolveDetail(detail) {
4
+ return detail ?? "summary";
5
+ }
6
+ export function resolveInclude(include) {
7
+ return normalizeIncludeGroups(include);
8
+ }
9
+ export function normalizeReadOnlyExecutionMode(action, executionMode) {
10
+ if (action === "summary" || action === "list" || action === "inspect" || action === "verify") {
11
+ return "preview";
12
+ }
13
+ return executionMode ?? "preview";
14
+ }
15
+ export function capArray(values, maxItems) {
16
+ if (values.length <= maxItems) {
17
+ return { items: [...values], truncated: false };
18
+ }
19
+ return {
20
+ items: [...values.slice(0, maxItems)],
21
+ truncated: true
22
+ };
23
+ }
24
+ export function requireNonEmptyObject(selector, message) {
25
+ if (!selector || Object.keys(selector).length === 0) {
26
+ throw createError({
27
+ code: ERROR_CODES.INVALID_INPUT,
28
+ message
29
+ });
30
+ }
31
+ return selector;
32
+ }
33
+ export function nextActionsOrUndefined(actions) {
34
+ return actions.length > 0 ? actions : undefined;
35
+ }
36
+ //# sourceMappingURL=request-normalizers.js.map
@@ -0,0 +1,45 @@
1
+ export declare const DETAIL_LEVELS: readonly ["summary", "standard", "full"];
2
+ export type DetailLevel = (typeof DETAIL_LEVELS)[number];
3
+ export declare const CANONICAL_INCLUDE_GROUPS: readonly ["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 type IncludeGroup = (typeof CANONICAL_INCLUDE_GROUPS)[number];
5
+ export type SummaryStatus = "ok" | "partial" | "ambiguous" | "not_found" | "invalid" | "blocked" | "changed" | "unchanged";
6
+ export type NextAction = {
7
+ tool: string;
8
+ params: Record<string, unknown>;
9
+ };
10
+ export type Summary = {
11
+ status: SummaryStatus;
12
+ headline: string;
13
+ subject?: Record<string, unknown>;
14
+ counts?: Record<string, number>;
15
+ nextActions?: NextAction[];
16
+ notes?: string[];
17
+ };
18
+ export type TruncationMeta = {
19
+ didTruncate: true;
20
+ reason: "limit";
21
+ omittedGroups?: string[];
22
+ nextActions?: NextAction[];
23
+ };
24
+ export declare function normalizeIncludeGroups(include: readonly string[] | undefined): string[];
25
+ export declare function createNextAction(tool: string, params: Record<string, unknown>): NextAction;
26
+ export declare function createSummarySubject(fields: Record<string, unknown>): Record<string, unknown>;
27
+ export declare function createTruncationMeta(input: {
28
+ omittedGroups?: string[];
29
+ nextActions?: NextAction[];
30
+ }): TruncationMeta;
31
+ export declare function buildEntryToolMeta(input: {
32
+ detail: DetailLevel;
33
+ include?: readonly string[];
34
+ warnings?: readonly string[];
35
+ truncated?: TruncationMeta;
36
+ pagination?: Record<string, unknown>;
37
+ }): Record<string, unknown>;
38
+ export declare function buildEntryToolResult(input: {
39
+ task: string;
40
+ summary: Summary;
41
+ detail: DetailLevel;
42
+ include?: readonly string[];
43
+ blocks?: Record<string, unknown>;
44
+ alwaysBlocks?: readonly string[];
45
+ }): Record<string, unknown>;
@@ -0,0 +1,99 @@
1
+ export const DETAIL_LEVELS = ["summary", "standard", "full"];
2
+ export const CANONICAL_INCLUDE_GROUPS = [
3
+ "warnings",
4
+ "provenance",
5
+ "candidates",
6
+ "members",
7
+ "source",
8
+ "files",
9
+ "samples",
10
+ "diff",
11
+ "issues",
12
+ "timeline",
13
+ "matrix",
14
+ "entries",
15
+ "workspace",
16
+ "health",
17
+ "recovery",
18
+ "paths",
19
+ "owners",
20
+ "preview",
21
+ "cacheEntries",
22
+ "timings",
23
+ "artifact",
24
+ "classes",
25
+ "registry"
26
+ ];
27
+ const INCLUDE_ORDER = new Map(CANONICAL_INCLUDE_GROUPS.map((group, index) => [group, index]));
28
+ export function normalizeIncludeGroups(include) {
29
+ if (!include || include.length === 0) {
30
+ return [];
31
+ }
32
+ const seen = new Set();
33
+ const deduped = [];
34
+ for (const group of include) {
35
+ if (!group || seen.has(group)) {
36
+ continue;
37
+ }
38
+ seen.add(group);
39
+ deduped.push(group);
40
+ }
41
+ deduped.sort((left, right) => {
42
+ const leftIndex = INCLUDE_ORDER.get(left);
43
+ const rightIndex = INCLUDE_ORDER.get(right);
44
+ if (leftIndex == null && rightIndex == null) {
45
+ return left.localeCompare(right);
46
+ }
47
+ if (leftIndex == null) {
48
+ return 1;
49
+ }
50
+ if (rightIndex == null) {
51
+ return -1;
52
+ }
53
+ return leftIndex - rightIndex;
54
+ });
55
+ return deduped;
56
+ }
57
+ export function createNextAction(tool, params) {
58
+ return { tool, params };
59
+ }
60
+ export function createSummarySubject(fields) {
61
+ return Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== undefined));
62
+ }
63
+ export function createTruncationMeta(input) {
64
+ return {
65
+ didTruncate: true,
66
+ reason: "limit",
67
+ ...(input.omittedGroups?.length ? { omittedGroups: [...input.omittedGroups] } : {}),
68
+ ...(input.nextActions?.length ? { nextActions: [...input.nextActions] } : {})
69
+ };
70
+ }
71
+ export function buildEntryToolMeta(input) {
72
+ return {
73
+ warnings: [...(input.warnings ?? [])],
74
+ detailApplied: input.detail,
75
+ ...(input.include && input.include.length > 0
76
+ ? { includeApplied: normalizeIncludeGroups(input.include) }
77
+ : {}),
78
+ ...(input.truncated ? { truncated: input.truncated } : {}),
79
+ ...(input.pagination ? { pagination: input.pagination } : {})
80
+ };
81
+ }
82
+ export function buildEntryToolResult(input) {
83
+ const result = {
84
+ task: input.task,
85
+ summary: input.summary
86
+ };
87
+ const include = new Set(normalizeIncludeGroups(input.include));
88
+ const alwaysBlocks = new Set(input.alwaysBlocks ?? []);
89
+ for (const [key, value] of Object.entries(input.blocks ?? {})) {
90
+ if (value === undefined) {
91
+ continue;
92
+ }
93
+ if (alwaysBlocks.has(key) || input.detail !== "summary" || include.has(key)) {
94
+ result[key] = value;
95
+ }
96
+ }
97
+ return result;
98
+ }
99
+ //# sourceMappingURL=response-contract.js.map