@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.
- package/CHANGELOG.md +38 -1
- package/README.md +224 -802
- package/dist/cache-registry.d.ts +95 -0
- package/dist/cache-registry.js +541 -0
- package/dist/entry-tools/analyze-mod-service.d.ts +207 -0
- package/dist/entry-tools/analyze-mod-service.js +309 -0
- package/dist/entry-tools/analyze-symbol-service.d.ts +209 -0
- package/dist/entry-tools/analyze-symbol-service.js +359 -0
- package/dist/entry-tools/compare-minecraft-service.d.ts +210 -0
- package/dist/entry-tools/compare-minecraft-service.js +429 -0
- package/dist/entry-tools/entry-tool-schema.d.ts +6 -0
- package/dist/entry-tools/entry-tool-schema.js +10 -0
- package/dist/entry-tools/inspect-minecraft-service.d.ts +1954 -0
- package/dist/entry-tools/inspect-minecraft-service.js +1030 -0
- package/dist/entry-tools/manage-cache-service.d.ts +130 -0
- package/dist/entry-tools/manage-cache-service.js +264 -0
- package/dist/entry-tools/request-normalizers.d.ts +10 -0
- package/dist/entry-tools/request-normalizers.js +36 -0
- package/dist/entry-tools/response-contract.d.ts +45 -0
- package/dist/entry-tools/response-contract.js +99 -0
- package/dist/entry-tools/validate-project-service.d.ts +543 -0
- package/dist/entry-tools/validate-project-service.js +414 -0
- package/dist/index.js +183 -59
- package/dist/observability.d.ts +18 -2
- package/dist/observability.js +47 -10
- package/dist/source-service.d.ts +0 -1
- package/dist/source-service.js +44 -54
- package/dist/storage/files-repo.d.ts +1 -0
- package/dist/storage/files-repo.js +29 -5
- package/dist/tool-contract-manifest.d.ts +4 -0
- package/dist/tool-contract-manifest.js +139 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13,6 +13,15 @@ import { remapModJar } from "./mod-remap-service.js";
|
|
|
13
13
|
import { registerResources } from "./resources.js";
|
|
14
14
|
import { SourceService } from "./source-service.js";
|
|
15
15
|
import { ToolExecutionGate } from "./tool-execution-gate.js";
|
|
16
|
+
import { WorkspaceMappingService } from "./workspace-mapping-service.js";
|
|
17
|
+
import { InspectMinecraftService, inspectMinecraftSchema, inspectMinecraftShape } from "./entry-tools/inspect-minecraft-service.js";
|
|
18
|
+
import { AnalyzeSymbolService, analyzeSymbolSchema, analyzeSymbolShape } from "./entry-tools/analyze-symbol-service.js";
|
|
19
|
+
import { CompareMinecraftService, compareMinecraftSchema, compareMinecraftShape } from "./entry-tools/compare-minecraft-service.js";
|
|
20
|
+
import { AnalyzeModService, analyzeModSchema, analyzeModShape } from "./entry-tools/analyze-mod-service.js";
|
|
21
|
+
import { ValidateProjectService, validateProjectSchema, validateProjectShape, discoverWorkspaceAccessWideners, discoverWorkspaceMixins } from "./entry-tools/validate-project-service.js";
|
|
22
|
+
import { ManageCacheService, manageCacheSchema, manageCacheShape } from "./entry-tools/manage-cache-service.js";
|
|
23
|
+
import { createCacheRegistry } from "./cache-registry.js";
|
|
24
|
+
import { buildEntryToolMeta } from "./entry-tools/response-contract.js";
|
|
16
25
|
if (!process.env.NODE_ENV) {
|
|
17
26
|
process.env.NODE_ENV = "production";
|
|
18
27
|
}
|
|
@@ -38,6 +47,14 @@ const HEAVY_TOOL_NAMES = new Set([
|
|
|
38
47
|
"get-class-api-matrix",
|
|
39
48
|
"get-registry-data"
|
|
40
49
|
]);
|
|
50
|
+
const ENTRY_TOOL_NAMES = new Set([
|
|
51
|
+
"inspect-minecraft",
|
|
52
|
+
"analyze-symbol",
|
|
53
|
+
"compare-minecraft",
|
|
54
|
+
"analyze-mod",
|
|
55
|
+
"validate-project",
|
|
56
|
+
"manage-cache"
|
|
57
|
+
]);
|
|
41
58
|
const heavyToolExecutionGate = new ToolExecutionGate({ maxConcurrent: 1, maxQueue: 2 });
|
|
42
59
|
const nonEmptyString = z.string().trim().min(1);
|
|
43
60
|
const optionalNonEmptyString = z.string().trim().min(1).optional();
|
|
@@ -73,9 +90,28 @@ const sourceLookupTargetSchema = z.discriminatedUnion("type", [
|
|
|
73
90
|
const RESOLVE_ARTIFACT_TARGET_DESCRIPTION = "Object with kind and value. Example: {\"kind\":\"version\",\"value\":\"1.21.10\"}. Must be an object, not a string.";
|
|
74
91
|
const SOURCE_LOOKUP_TARGET_DESCRIPTION = "Object: {\"type\":\"resolve\",\"kind\":\"version\",\"value\":\"1.21.10\"} or {\"type\":\"artifact\",\"artifactId\":\"...\"}. Must be an object, not a string.";
|
|
75
92
|
const SOURCE_SCOPE_DESCRIPTION = 'vanilla = Mojang client jar only; merged = Loom cache discovery (default); loader = currently behaves the same as "merged".';
|
|
93
|
+
const SUGGESTED_CALL_DEFAULTS = {
|
|
94
|
+
allowDecompile: true,
|
|
95
|
+
preferProjectVersion: false,
|
|
96
|
+
strictVersion: false,
|
|
97
|
+
mode: "metadata",
|
|
98
|
+
access: "public",
|
|
99
|
+
includeSynthetic: false,
|
|
100
|
+
includeInherited: false,
|
|
101
|
+
hideUncertain: false,
|
|
102
|
+
explain: false,
|
|
103
|
+
preferProjectMapping: false,
|
|
104
|
+
minSeverity: "all",
|
|
105
|
+
reportMode: "full",
|
|
106
|
+
treatInfoAsWarning: true,
|
|
107
|
+
includeIssues: true
|
|
108
|
+
};
|
|
109
|
+
function isSuggestedCallDefault(field, value) {
|
|
110
|
+
return value === SUGGESTED_CALL_DEFAULTS[field];
|
|
111
|
+
}
|
|
76
112
|
const listVersionsShape = {
|
|
77
|
-
includeSnapshots: z.boolean().
|
|
78
|
-
limit: optionalPositiveInt.describe("
|
|
113
|
+
includeSnapshots: z.boolean().default(false),
|
|
114
|
+
limit: optionalPositiveInt.default(20).describe("max 200")
|
|
79
115
|
};
|
|
80
116
|
const listVersionsSchema = z.object(listVersionsShape);
|
|
81
117
|
const resolveArtifactShape = {
|
|
@@ -85,7 +121,7 @@ const resolveArtifactShape = {
|
|
|
85
121
|
}).describe(RESOLVE_ARTIFACT_TARGET_DESCRIPTION),
|
|
86
122
|
mapping: sourceMappingSchema.optional().describe("obfuscated | mojang | intermediary | yarn"),
|
|
87
123
|
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
88
|
-
allowDecompile: z.boolean().
|
|
124
|
+
allowDecompile: z.boolean().default(true),
|
|
89
125
|
projectPath: optionalNonEmptyString.describe("Optional workspace root path for Loom cache-assisted source resolution"),
|
|
90
126
|
scope: artifactScopeSchema.optional().describe(SOURCE_SCOPE_DESCRIPTION),
|
|
91
127
|
preferProjectVersion: z.boolean().optional().describe("When true, detect MC version from gradle.properties and override target.value"),
|
|
@@ -94,11 +130,11 @@ const resolveArtifactShape = {
|
|
|
94
130
|
const resolveArtifactSchema = z.object(resolveArtifactShape);
|
|
95
131
|
const getClassSourceShape = {
|
|
96
132
|
className: nonEmptyString,
|
|
97
|
-
mode: sourceModeSchema.
|
|
133
|
+
mode: sourceModeSchema.default("metadata").describe("metadata = symbol outline only; snippet = source with default maxLines=200; full = entire source"),
|
|
98
134
|
target: sourceLookupTargetSchema.describe(SOURCE_LOOKUP_TARGET_DESCRIPTION),
|
|
99
135
|
mapping: sourceMappingSchema.optional().describe("obfuscated | mojang | intermediary | yarn"),
|
|
100
136
|
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
101
|
-
allowDecompile: z.boolean().
|
|
137
|
+
allowDecompile: z.boolean().default(true),
|
|
102
138
|
projectPath: optionalNonEmptyString.describe("Optional workspace root path for Loom cache-assisted source resolution"),
|
|
103
139
|
scope: artifactScopeSchema.optional().describe(SOURCE_SCOPE_DESCRIPTION),
|
|
104
140
|
preferProjectVersion: z.boolean().optional().describe("When true, detect MC version from gradle.properties and override target.value"),
|
|
@@ -127,10 +163,10 @@ const getClassMembersShape = {
|
|
|
127
163
|
target: sourceLookupTargetSchema.describe(SOURCE_LOOKUP_TARGET_DESCRIPTION),
|
|
128
164
|
mapping: sourceMappingSchema.optional().describe("obfuscated | mojang | intermediary | yarn (default obfuscated)"),
|
|
129
165
|
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
130
|
-
allowDecompile: z.boolean().
|
|
131
|
-
access: memberAccessSchema.
|
|
132
|
-
includeSynthetic: z.boolean().
|
|
133
|
-
includeInherited: z.boolean().
|
|
166
|
+
allowDecompile: z.boolean().default(true),
|
|
167
|
+
access: memberAccessSchema.default("public").describe("public | all"),
|
|
168
|
+
includeSynthetic: z.boolean().default(false),
|
|
169
|
+
includeInherited: z.boolean().default(false),
|
|
134
170
|
memberPattern: optionalNonEmptyString,
|
|
135
171
|
maxMembers: optionalPositiveInt.describe("default 500, max 5000"),
|
|
136
172
|
projectPath: optionalNonEmptyString,
|
|
@@ -147,8 +183,8 @@ const searchClassSourceShape = {
|
|
|
147
183
|
packagePrefix: optionalNonEmptyString,
|
|
148
184
|
fileGlob: optionalNonEmptyString,
|
|
149
185
|
symbolKind: searchSymbolKindSchema.optional().describe("class | interface | enum | record | method | field"),
|
|
150
|
-
queryMode: z.enum(["auto", "token", "literal"]).
|
|
151
|
-
limit: optionalPositiveInt.
|
|
186
|
+
queryMode: z.enum(["auto", "token", "literal"]).default("auto").describe("auto: indexed search, including separator queries like foo.bar; token: indexed-only; literal: explicit substring scan only"),
|
|
187
|
+
limit: optionalPositiveInt.default(20),
|
|
152
188
|
cursor: optionalNonEmptyString
|
|
153
189
|
};
|
|
154
190
|
const searchClassSourceSchema = z.object(searchClassSourceShape).superRefine((value, ctx) => {
|
|
@@ -180,9 +216,9 @@ const traceSymbolLifecycleShape = {
|
|
|
180
216
|
toVersion: optionalNonEmptyString,
|
|
181
217
|
mapping: sourceMappingSchema.optional().describe("obfuscated | mojang | intermediary | yarn (default obfuscated)"),
|
|
182
218
|
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
183
|
-
includeSnapshots: z.boolean().
|
|
184
|
-
maxVersions: optionalPositiveInt.describe("
|
|
185
|
-
includeTimeline: z.boolean().
|
|
219
|
+
includeSnapshots: z.boolean().default(false),
|
|
220
|
+
maxVersions: optionalPositiveInt.default(120).describe("max 400"),
|
|
221
|
+
includeTimeline: z.boolean().default(false)
|
|
186
222
|
};
|
|
187
223
|
const traceSymbolLifecycleSchema = z.object(traceSymbolLifecycleShape);
|
|
188
224
|
const diffClassSignaturesShape = {
|
|
@@ -191,7 +227,7 @@ const diffClassSignaturesShape = {
|
|
|
191
227
|
toVersion: nonEmptyString,
|
|
192
228
|
mapping: sourceMappingSchema.optional().describe("obfuscated | mojang | intermediary | yarn (default obfuscated)"),
|
|
193
229
|
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
194
|
-
includeFullDiff: z.boolean().
|
|
230
|
+
includeFullDiff: z.boolean().default(true).describe("When false, omit from/to snapshots from modified entries and keep only key+changed")
|
|
195
231
|
};
|
|
196
232
|
const diffClassSignaturesSchema = z.object(diffClassSignaturesShape);
|
|
197
233
|
const findMappingShape = {
|
|
@@ -210,7 +246,7 @@ const findMappingShape = {
|
|
|
210
246
|
})
|
|
211
247
|
.partial()
|
|
212
248
|
.optional(),
|
|
213
|
-
maxCandidates: optionalPositiveInt.describe("Limit returned candidates (
|
|
249
|
+
maxCandidates: optionalPositiveInt.default(200).describe("Limit returned candidates (max 200)")
|
|
214
250
|
};
|
|
215
251
|
const findMappingSchema = z.object(findMappingShape).superRefine((value, ctx) => {
|
|
216
252
|
if (value.kind === "class") {
|
|
@@ -277,7 +313,7 @@ const resolveMethodMappingExactShape = {
|
|
|
277
313
|
sourceMapping: sourceMappingSchema.describe("obfuscated | mojang | intermediary | yarn"),
|
|
278
314
|
targetMapping: sourceMappingSchema.describe("obfuscated | mojang | intermediary | yarn"),
|
|
279
315
|
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
280
|
-
maxCandidates: optionalPositiveInt.describe("Limit returned candidates (
|
|
316
|
+
maxCandidates: optionalPositiveInt.default(200).describe("Limit returned candidates (max 200)")
|
|
281
317
|
};
|
|
282
318
|
const resolveMethodMappingExactSchema = z
|
|
283
319
|
.object(resolveMethodMappingExactShape)
|
|
@@ -328,7 +364,7 @@ const resolveWorkspaceSymbolShape = {
|
|
|
328
364
|
descriptor: optionalNonEmptyString,
|
|
329
365
|
sourceMapping: sourceMappingSchema.describe("obfuscated | mojang | intermediary | yarn"),
|
|
330
366
|
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
331
|
-
maxCandidates: optionalPositiveInt.describe("Limit returned candidates for field/method lookups (
|
|
367
|
+
maxCandidates: optionalPositiveInt.default(200).describe("Limit returned candidates for field/method lookups (max 200)")
|
|
332
368
|
};
|
|
333
369
|
const resolveWorkspaceSymbolSchema = z
|
|
334
370
|
.object(resolveWorkspaceSymbolShape)
|
|
@@ -397,10 +433,10 @@ const checkSymbolExistsShape = {
|
|
|
397
433
|
descriptor: optionalNonEmptyString.describe("required for kind=method unless signatureMode=name-only"),
|
|
398
434
|
sourceMapping: sourceMappingSchema.describe("obfuscated | mojang | intermediary | yarn"),
|
|
399
435
|
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
400
|
-
nameMode: classNameModeSchema.
|
|
401
|
-
signatureMode: z.enum(["exact", "name-only"]).
|
|
402
|
-
.describe("exact
|
|
403
|
-
maxCandidates: optionalPositiveInt.describe("Limit returned candidates (
|
|
436
|
+
nameMode: classNameModeSchema.default("fqcn").describe("fqcn | auto"),
|
|
437
|
+
signatureMode: z.enum(["exact", "name-only"]).default("exact")
|
|
438
|
+
.describe("exact: require descriptor for methods; name-only: match by owner+name only"),
|
|
439
|
+
maxCandidates: optionalPositiveInt.default(200).describe("Limit returned candidates (max 200)")
|
|
404
440
|
};
|
|
405
441
|
const checkSymbolExistsSchema = z.object(checkSymbolExistsShape).superRefine((value, ctx) => {
|
|
406
442
|
if (value.kind === "class") {
|
|
@@ -461,7 +497,7 @@ const checkSymbolExistsSchema = z.object(checkSymbolExistsShape).superRefine((va
|
|
|
461
497
|
});
|
|
462
498
|
const nbtToJsonShape = {
|
|
463
499
|
nbtBase64: nonEmptyString,
|
|
464
|
-
compression: decodeCompressionSchema.
|
|
500
|
+
compression: decodeCompressionSchema.default("auto").describe("none | gzip | auto")
|
|
465
501
|
};
|
|
466
502
|
const nbtToJsonSchema = z.object(nbtToJsonShape);
|
|
467
503
|
const nbtPatchOperationSchema = z
|
|
@@ -478,12 +514,12 @@ const nbtApplyJsonPatchShape = {
|
|
|
478
514
|
const nbtApplyJsonPatchSchema = z.object(nbtApplyJsonPatchShape);
|
|
479
515
|
const jsonToNbtShape = {
|
|
480
516
|
typedJson: z.unknown(),
|
|
481
|
-
compression: encodeCompressionSchema.
|
|
517
|
+
compression: encodeCompressionSchema.default("none").describe("none | gzip")
|
|
482
518
|
};
|
|
483
519
|
const jsonToNbtSchema = z.object(jsonToNbtShape);
|
|
484
520
|
const indexArtifactShape = {
|
|
485
521
|
artifactId: nonEmptyString,
|
|
486
|
-
force: z.boolean().
|
|
522
|
+
force: z.boolean().default(false)
|
|
487
523
|
};
|
|
488
524
|
const indexArtifactSchema = z.object(indexArtifactShape);
|
|
489
525
|
const validateMixinShape = {
|
|
@@ -517,23 +553,23 @@ const validateMixinShape = {
|
|
|
517
553
|
scope: artifactScopeSchema.optional().describe(SOURCE_SCOPE_DESCRIPTION),
|
|
518
554
|
projectPath: optionalNonEmptyString.describe("Optional workspace root path for Loom cache-assisted source resolution"),
|
|
519
555
|
preferProjectVersion: z.boolean().optional().describe("When true, detect MC version from gradle.properties and override version"),
|
|
520
|
-
minSeverity: z.enum(["error", "warning", "all"]).
|
|
521
|
-
.describe("'error'=errors only, 'warning'=errors+warnings, 'all'=everything
|
|
522
|
-
hideUncertain: z.boolean().
|
|
523
|
-
.describe("Omit issues with confidence='uncertain'
|
|
524
|
-
explain: z.boolean().
|
|
525
|
-
.describe("When true, enrich each issue with explanation and suggestedCall for agent recovery
|
|
556
|
+
minSeverity: z.enum(["error", "warning", "all"]).default("all")
|
|
557
|
+
.describe("'error'=errors only, 'warning'=errors+warnings, 'all'=everything"),
|
|
558
|
+
hideUncertain: z.boolean().default(false)
|
|
559
|
+
.describe("Omit issues with confidence='uncertain'"),
|
|
560
|
+
explain: z.boolean().default(false)
|
|
561
|
+
.describe("When true, enrich each issue with explanation and suggestedCall for agent recovery"),
|
|
526
562
|
warningMode: z.enum(["full", "aggregated"]).optional()
|
|
527
|
-
.describe("'full'=all warnings
|
|
528
|
-
preferProjectMapping: z.boolean().
|
|
563
|
+
.describe("'full'=all warnings; 'aggregated'=group warnings by category with counts and samples. Single validation uses the provided value as-is; batch validation defaults to 'aggregated'"),
|
|
564
|
+
preferProjectMapping: z.boolean().default(false)
|
|
529
565
|
.describe("When true, auto-detect mapping from project config even if mapping is explicitly provided"),
|
|
530
|
-
reportMode: z.enum(["compact", "full", "summary-first"]).
|
|
531
|
-
.describe("'compact' omits heavy per-result detail, 'summary-first' hoists shared provenance/warnings/incomplete reasons, 'full'=everything
|
|
566
|
+
reportMode: z.enum(["compact", "full", "summary-first"]).default("full")
|
|
567
|
+
.describe("'compact' omits heavy per-result detail, 'summary-first' hoists shared provenance/warnings/incomplete reasons, 'full'=everything"),
|
|
532
568
|
warningCategoryFilter: z.array(z.enum(["mapping", "configuration", "validation", "resolution", "parse"])).optional()
|
|
533
569
|
.describe("Only include warnings/issues matching these categories (default: all)"),
|
|
534
|
-
treatInfoAsWarning: z.boolean().
|
|
535
|
-
.describe("When false, suppress info-severity structured warnings from output
|
|
536
|
-
includeIssues: z.boolean().
|
|
570
|
+
treatInfoAsWarning: z.boolean().default(true)
|
|
571
|
+
.describe("When false, suppress info-severity structured warnings from output"),
|
|
572
|
+
includeIssues: z.boolean().default(true)
|
|
537
573
|
.describe("When false, keep summary fields but omit per-result issues[] payloads")
|
|
538
574
|
};
|
|
539
575
|
const validateMixinSchema = z.object(validateMixinShape);
|
|
@@ -546,13 +582,13 @@ const validateAccessWidenerShape = {
|
|
|
546
582
|
const validateAccessWidenerSchema = z.object(validateAccessWidenerShape);
|
|
547
583
|
const analyzeModJarShape = {
|
|
548
584
|
jarPath: nonEmptyString.describe("Local path to the mod JAR file"),
|
|
549
|
-
includeClasses: z.boolean().
|
|
585
|
+
includeClasses: z.boolean().default(false).describe("Include full class listing")
|
|
550
586
|
};
|
|
551
587
|
const analyzeModJarSchema = z.object(analyzeModJarShape);
|
|
552
588
|
const getRegistryDataShape = {
|
|
553
589
|
version: nonEmptyString.describe("Minecraft version (e.g. 1.21)"),
|
|
554
590
|
registry: optionalNonEmptyString.describe('Optional registry name (e.g. "block", "item", "minecraft:biome"). Omit to list all registries.'),
|
|
555
|
-
includeData: z.boolean().
|
|
591
|
+
includeData: z.boolean().default(true).describe("When false, return registry names/counts without full entry bodies"),
|
|
556
592
|
maxEntriesPerRegistry: optionalPositiveInt.describe("Limit returned entries per registry body")
|
|
557
593
|
};
|
|
558
594
|
const getRegistryDataSchema = z.object(getRegistryDataShape);
|
|
@@ -561,15 +597,15 @@ const compareVersionsCategorySchema = z.enum(COMPARE_VERSIONS_CATEGORIES);
|
|
|
561
597
|
const compareVersionsShape = {
|
|
562
598
|
fromVersion: nonEmptyString.describe("Older Minecraft version (e.g. 1.20.4)"),
|
|
563
599
|
toVersion: nonEmptyString.describe("Newer Minecraft version (e.g. 1.21)"),
|
|
564
|
-
category: compareVersionsCategorySchema.
|
|
600
|
+
category: compareVersionsCategorySchema.default("all").describe("classes | registry | all"),
|
|
565
601
|
packageFilter: optionalNonEmptyString.describe("Filter classes to a package prefix (e.g. net.minecraft.world.item)"),
|
|
566
|
-
maxClassResults: optionalPositiveInt.describe("Max class results per direction (
|
|
602
|
+
maxClassResults: optionalPositiveInt.default(500).describe("Max class results per direction (max 5000)")
|
|
567
603
|
};
|
|
568
604
|
const compareVersionsSchema = z.object(compareVersionsShape);
|
|
569
605
|
const decompileModJarShape = {
|
|
570
606
|
jarPath: nonEmptyString.describe("Local path to the mod JAR file"),
|
|
571
607
|
className: optionalNonEmptyString.describe("Optional fully-qualified class name to view source. Omit to list all classes."),
|
|
572
|
-
includeFiles: z.boolean().
|
|
608
|
+
includeFiles: z.boolean().default(true).describe("When false, omit the full class list and return counts only"),
|
|
573
609
|
maxFiles: optionalPositiveInt.describe("Limit returned class names when files are included")
|
|
574
610
|
};
|
|
575
611
|
const decompileModJarSchema = z.object(decompileModJarShape);
|
|
@@ -586,8 +622,8 @@ const modSearchTypeSchema = z.enum(MOD_SEARCH_TYPES);
|
|
|
586
622
|
const searchModSourceShape = {
|
|
587
623
|
jarPath: nonEmptyString.describe("Local path to the mod JAR file"),
|
|
588
624
|
query: nonEmptyString.describe("Search pattern (regex or literal string)"),
|
|
589
|
-
searchType: modSearchTypeSchema.
|
|
590
|
-
limit: optionalPositiveInt.describe("Max results (
|
|
625
|
+
searchType: modSearchTypeSchema.default("all").describe("class | method | field | content | all"),
|
|
626
|
+
limit: optionalPositiveInt.default(50).describe("Max results (max 200)")
|
|
591
627
|
};
|
|
592
628
|
const searchModSourceSchema = z.object(searchModSourceShape);
|
|
593
629
|
const REMAP_TARGETS = ["yarn", "mojang"];
|
|
@@ -639,6 +675,50 @@ const sourceService = new Proxy({}, {
|
|
|
639
675
|
return typeof value === "function" ? value.bind(service) : value;
|
|
640
676
|
}
|
|
641
677
|
});
|
|
678
|
+
const workspaceMappingService = new WorkspaceMappingService();
|
|
679
|
+
const inspectMinecraftService = new InspectMinecraftService({
|
|
680
|
+
listVersions: (input) => sourceService.listVersions(input),
|
|
681
|
+
resolveArtifact: (input) => sourceService.resolveArtifact(input),
|
|
682
|
+
findClass: (input) => Promise.resolve(sourceService.findClass(input)),
|
|
683
|
+
getClassSource: (input) => sourceService.getClassSource(input),
|
|
684
|
+
getClassMembers: (input) => sourceService.getClassMembers(input),
|
|
685
|
+
searchClassSource: (input) => sourceService.searchClassSource(input),
|
|
686
|
+
getArtifactFile: (input) => sourceService.getArtifactFile(input),
|
|
687
|
+
listArtifactFiles: (input) => sourceService.listArtifactFiles(input),
|
|
688
|
+
detectProjectMinecraftVersion: (projectPath) => workspaceMappingService.detectProjectMinecraftVersion(projectPath)
|
|
689
|
+
});
|
|
690
|
+
const analyzeSymbolService = new AnalyzeSymbolService({
|
|
691
|
+
checkSymbolExists: (input) => sourceService.checkSymbolExists(input),
|
|
692
|
+
findMapping: (input) => sourceService.findMapping(input),
|
|
693
|
+
resolveMethodMappingExact: (input) => sourceService.resolveMethodMappingExact(input),
|
|
694
|
+
traceSymbolLifecycle: (input) => sourceService.traceSymbolLifecycle(input),
|
|
695
|
+
resolveWorkspaceSymbol: (input) => sourceService.resolveWorkspaceSymbol(input),
|
|
696
|
+
getClassApiMatrix: (input) => sourceService.getClassApiMatrix(input)
|
|
697
|
+
});
|
|
698
|
+
const compareMinecraftService = new CompareMinecraftService({
|
|
699
|
+
compareVersions: (input) => sourceService.compareVersions(input),
|
|
700
|
+
diffClassSignatures: (input) => sourceService.diffClassSignatures(input),
|
|
701
|
+
getRegistryData: (input) => sourceService.getRegistryData(input)
|
|
702
|
+
});
|
|
703
|
+
const analyzeModService = new AnalyzeModService({
|
|
704
|
+
analyzeModJar: (jarPath, options) => analyzeModJar(jarPath, options),
|
|
705
|
+
decompileModJar: (input) => sourceService.decompileModJar(input),
|
|
706
|
+
getModClassSource: (input) => sourceService.getModClassSource(input),
|
|
707
|
+
searchModSource: (input) => sourceService.searchModSource(input),
|
|
708
|
+
remapModJar: (input) => remapModJar(input, config)
|
|
709
|
+
});
|
|
710
|
+
const validateProjectService = new ValidateProjectService({
|
|
711
|
+
validateMixin: (input) => sourceService.validateMixin(input),
|
|
712
|
+
validateAccessWidener: (input) => sourceService.validateAccessWidener(input),
|
|
713
|
+
discoverMixins: discoverWorkspaceMixins,
|
|
714
|
+
discoverAccessWideners: discoverWorkspaceAccessWideners
|
|
715
|
+
});
|
|
716
|
+
const manageCacheService = new ManageCacheService({
|
|
717
|
+
registry: createCacheRegistry({
|
|
718
|
+
cacheDir: config.cacheDir,
|
|
719
|
+
sqlitePath: config.sqlitePath
|
|
720
|
+
})
|
|
721
|
+
});
|
|
642
722
|
registerResources(server, sourceService);
|
|
643
723
|
let processHandlersAttached = false;
|
|
644
724
|
let serverStarted = false;
|
|
@@ -847,7 +927,10 @@ function copySourceLookupSuggestionFields(tool, source) {
|
|
|
847
927
|
: ["className", "mapping", "sourcePriority", "projectPath", "scope", "access", "memberPattern"];
|
|
848
928
|
for (const field of stringFields) {
|
|
849
929
|
const value = source[field];
|
|
850
|
-
if (typeof value === "string" &&
|
|
930
|
+
if (typeof value === "string" &&
|
|
931
|
+
value.trim() &&
|
|
932
|
+
(!Object.prototype.hasOwnProperty.call(SUGGESTED_CALL_DEFAULTS, field) ||
|
|
933
|
+
!isSuggestedCallDefault(field, value))) {
|
|
851
934
|
result[field] = value;
|
|
852
935
|
}
|
|
853
936
|
}
|
|
@@ -865,7 +948,9 @@ function copySourceLookupSuggestionFields(tool, source) {
|
|
|
865
948
|
: ["allowDecompile", "preferProjectVersion", "strictVersion", "includeSynthetic", "includeInherited"];
|
|
866
949
|
for (const field of booleanFields) {
|
|
867
950
|
const value = source[field];
|
|
868
|
-
if (typeof value === "boolean"
|
|
951
|
+
if (typeof value === "boolean" &&
|
|
952
|
+
(!Object.prototype.hasOwnProperty.call(SUGGESTED_CALL_DEFAULTS, field) ||
|
|
953
|
+
!isSuggestedCallDefault(field, value))) {
|
|
869
954
|
result[field] = value;
|
|
870
955
|
}
|
|
871
956
|
}
|
|
@@ -885,7 +970,10 @@ function copyValidateMixinSharedParams(source) {
|
|
|
885
970
|
];
|
|
886
971
|
for (const field of stringFields) {
|
|
887
972
|
const value = source[field];
|
|
888
|
-
if (typeof value === "string" &&
|
|
973
|
+
if (typeof value === "string" &&
|
|
974
|
+
value.trim() &&
|
|
975
|
+
(!Object.prototype.hasOwnProperty.call(SUGGESTED_CALL_DEFAULTS, field) ||
|
|
976
|
+
!isSuggestedCallDefault(field, value))) {
|
|
889
977
|
result[field] = value;
|
|
890
978
|
}
|
|
891
979
|
}
|
|
@@ -899,7 +987,9 @@ function copyValidateMixinSharedParams(source) {
|
|
|
899
987
|
];
|
|
900
988
|
for (const field of booleanFields) {
|
|
901
989
|
const value = source[field];
|
|
902
|
-
if (typeof value === "boolean"
|
|
990
|
+
if (typeof value === "boolean" &&
|
|
991
|
+
(!Object.prototype.hasOwnProperty.call(SUGGESTED_CALL_DEFAULTS, field) ||
|
|
992
|
+
!isSuggestedCallDefault(field, value))) {
|
|
903
993
|
result[field] = value;
|
|
904
994
|
}
|
|
905
995
|
}
|
|
@@ -1037,7 +1127,8 @@ function buildResolveArtifactSuggestedParams(normalizedInput) {
|
|
|
1037
1127
|
const booleanFields = ["allowDecompile", "preferProjectVersion", "strictVersion"];
|
|
1038
1128
|
for (const field of booleanFields) {
|
|
1039
1129
|
const value = record[field];
|
|
1040
|
-
if (typeof value === "boolean"
|
|
1130
|
+
if (typeof value === "boolean" &&
|
|
1131
|
+
!isSuggestedCallDefault(field, value)) {
|
|
1041
1132
|
result[field] = value;
|
|
1042
1133
|
}
|
|
1043
1134
|
}
|
|
@@ -1146,18 +1237,27 @@ function mapErrorToProblem(caughtError, requestId, context) {
|
|
|
1146
1237
|
}
|
|
1147
1238
|
function splitWarnings(data) {
|
|
1148
1239
|
const result = { ...data };
|
|
1240
|
+
const warnings = [];
|
|
1149
1241
|
const maybeWarnings = result.warnings;
|
|
1150
|
-
if (
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1242
|
+
if (Array.isArray(maybeWarnings)) {
|
|
1243
|
+
warnings.push(...maybeWarnings.filter((entry) => typeof entry === "string"));
|
|
1244
|
+
delete result.warnings;
|
|
1245
|
+
}
|
|
1246
|
+
let meta = {};
|
|
1247
|
+
const maybeMeta = result.meta;
|
|
1248
|
+
if (maybeMeta && typeof maybeMeta === "object" && !Array.isArray(maybeMeta)) {
|
|
1249
|
+
meta = { ...maybeMeta };
|
|
1250
|
+
delete result.meta;
|
|
1251
|
+
const metaWarnings = meta.warnings;
|
|
1252
|
+
if (Array.isArray(metaWarnings)) {
|
|
1253
|
+
warnings.push(...metaWarnings.filter((entry) => typeof entry === "string"));
|
|
1254
|
+
delete meta.warnings;
|
|
1255
|
+
}
|
|
1155
1256
|
}
|
|
1156
|
-
const warnings = maybeWarnings.filter((entry) => typeof entry === "string");
|
|
1157
|
-
delete result.warnings;
|
|
1158
1257
|
return {
|
|
1159
1258
|
result,
|
|
1160
|
-
warnings
|
|
1259
|
+
warnings: [...new Set(warnings)],
|
|
1260
|
+
meta
|
|
1161
1261
|
};
|
|
1162
1262
|
}
|
|
1163
1263
|
async function runTool(tool, rawInput, schema, action) {
|
|
@@ -1192,10 +1292,28 @@ async function runTool(tool, rawInput, schema, action) {
|
|
|
1192
1292
|
const payload = await (HEAVY_TOOL_NAMES.has(tool)
|
|
1193
1293
|
? heavyToolExecutionGate.run(tool, () => action(parsedInput))
|
|
1194
1294
|
: action(parsedInput));
|
|
1195
|
-
const { result, warnings } = splitWarnings(payload);
|
|
1295
|
+
const { result, warnings, meta: resultMeta } = splitWarnings(payload);
|
|
1296
|
+
const entryMeta = ENTRY_TOOL_NAMES.has(tool)
|
|
1297
|
+
? buildEntryToolMeta({
|
|
1298
|
+
detail: normalizedInput &&
|
|
1299
|
+
typeof normalizedInput === "object" &&
|
|
1300
|
+
!Array.isArray(normalizedInput) &&
|
|
1301
|
+
typeof normalizedInput.detail === "string"
|
|
1302
|
+
? normalizedInput.detail ?? "summary"
|
|
1303
|
+
: "summary",
|
|
1304
|
+
include: normalizedInput &&
|
|
1305
|
+
typeof normalizedInput === "object" &&
|
|
1306
|
+
!Array.isArray(normalizedInput) &&
|
|
1307
|
+
Array.isArray(normalizedInput.include)
|
|
1308
|
+
? normalizedInput.include
|
|
1309
|
+
: undefined
|
|
1310
|
+
})
|
|
1311
|
+
: undefined;
|
|
1196
1312
|
return objectResult({
|
|
1197
1313
|
result,
|
|
1198
1314
|
meta: {
|
|
1315
|
+
...(entryMeta ?? {}),
|
|
1316
|
+
...resultMeta,
|
|
1199
1317
|
requestId,
|
|
1200
1318
|
tool,
|
|
1201
1319
|
durationMs: Date.now() - startedAt,
|
|
@@ -1253,6 +1371,12 @@ server.tool("list-versions", "List available Minecraft versions from Mojang mani
|
|
|
1253
1371
|
includeSnapshots: input.includeSnapshots,
|
|
1254
1372
|
limit: input.limit
|
|
1255
1373
|
})));
|
|
1374
|
+
server.tool("inspect-minecraft", "High-level v3 entry tool for version discovery, artifact resolution, class inspection, source search, file reads, and file listings.", inspectMinecraftShape, { readOnlyHint: true }, async (args) => runTool("inspect-minecraft", args, inspectMinecraftSchema, async (input) => inspectMinecraftService.execute(input)));
|
|
1375
|
+
server.tool("analyze-symbol", "High-level v3 entry tool for symbol existence, mapping, lifecycle, workspace analysis, and API overview.", analyzeSymbolShape, { readOnlyHint: true }, async (args) => runTool("analyze-symbol", args, analyzeSymbolSchema, async (input) => analyzeSymbolService.execute(input)));
|
|
1376
|
+
server.tool("compare-minecraft", "High-level v3 entry tool for version comparisons, class diffs, registry diffs, and migration overviews.", compareMinecraftShape, { readOnlyHint: true }, async (args) => runTool("compare-minecraft", args, compareMinecraftSchema, async (input) => compareMinecraftService.execute(input)));
|
|
1377
|
+
server.tool("analyze-mod", "High-level v3 entry tool for mod metadata inspection, decompile/search flows, class source, and safe remap previews/applies.", analyzeModShape, { readOnlyHint: false }, async (args) => runTool("analyze-mod", args, analyzeModSchema, async (input) => analyzeModService.execute(input)));
|
|
1378
|
+
server.tool("validate-project", "High-level v3 entry tool for project summary, direct mixin validation, and access widener validation.", validateProjectShape, { readOnlyHint: true }, async (args) => runTool("validate-project", args, validateProjectSchema, async (input) => validateProjectService.execute(input)));
|
|
1379
|
+
server.tool("manage-cache", "High-level v3 entry tool for cache summaries, listing, verification, previewed mutation, and explicit apply operations.", manageCacheShape, { readOnlyHint: false }, async (args) => runTool("manage-cache", args, manageCacheSchema, async (input) => manageCacheService.execute(input)));
|
|
1256
1380
|
server.tool("resolve-artifact", "Resolve source artifact from a target object ({ kind, value }) and return artifact metadata. For target.kind=jar, only <basename>-sources.jar is auto-adopted; other adjacent *-sources.jar files are informational.", resolveArtifactShape, { readOnlyHint: true }, async (args) => runTool("resolve-artifact", args, resolveArtifactSchema, async (input) => sourceService.resolveArtifact({
|
|
1257
1381
|
target: input.target,
|
|
1258
1382
|
mapping: input.mapping,
|
package/dist/observability.d.ts
CHANGED
|
@@ -3,12 +3,19 @@ export interface MetricTimingSnapshot {
|
|
|
3
3
|
totalMs: number;
|
|
4
4
|
avgMs: number;
|
|
5
5
|
lastMs: number;
|
|
6
|
+
p95Ms: number;
|
|
7
|
+
p99Ms: number;
|
|
6
8
|
}
|
|
7
9
|
export interface CacheArtifactByteAccountingRow {
|
|
8
10
|
artifact_id: string;
|
|
9
11
|
content_bytes: number;
|
|
10
12
|
updated_at: string;
|
|
11
13
|
}
|
|
14
|
+
type CacheArtifactByteAccountingRefRow = {
|
|
15
|
+
artifactId: string;
|
|
16
|
+
totalContentBytes: number;
|
|
17
|
+
updatedAt: string;
|
|
18
|
+
};
|
|
12
19
|
export interface RuntimeMetricSnapshot {
|
|
13
20
|
resolve_duration_ms: MetricTimingSnapshot;
|
|
14
21
|
search_duration_ms: MetricTimingSnapshot;
|
|
@@ -18,6 +25,10 @@ export interface RuntimeMetricSnapshot {
|
|
|
18
25
|
search_intent_symbol_duration_ms: MetricTimingSnapshot;
|
|
19
26
|
search_intent_text_duration_ms: MetricTimingSnapshot;
|
|
20
27
|
search_intent_path_duration_ms: MetricTimingSnapshot;
|
|
28
|
+
search_query_mode_auto_count: number;
|
|
29
|
+
search_query_mode_token_count: number;
|
|
30
|
+
search_query_mode_literal_count: number;
|
|
31
|
+
search_literal_explicit_count: number;
|
|
21
32
|
search_regex_fallback_count: number;
|
|
22
33
|
search_token_bytes_returned: number;
|
|
23
34
|
onehop_expand_count: number;
|
|
@@ -43,6 +54,10 @@ export declare class RuntimeMetrics {
|
|
|
43
54
|
private cacheHits;
|
|
44
55
|
private cacheMisses;
|
|
45
56
|
private repoFailoverCount;
|
|
57
|
+
private searchQueryModeAutoCount;
|
|
58
|
+
private searchQueryModeTokenCount;
|
|
59
|
+
private searchQueryModeLiteralCount;
|
|
60
|
+
private searchLiteralExplicitCount;
|
|
46
61
|
private searchRegexFallbackCount;
|
|
47
62
|
private searchTokenBytesReturned;
|
|
48
63
|
private oneHopExpandCount;
|
|
@@ -58,12 +73,13 @@ export declare class RuntimeMetrics {
|
|
|
58
73
|
private cacheEvictions;
|
|
59
74
|
private cacheEntries;
|
|
60
75
|
private cacheTotalContentBytes;
|
|
61
|
-
private
|
|
76
|
+
private cacheArtifactBytesLruRef;
|
|
62
77
|
constructor();
|
|
63
78
|
recordDuration(name: DurationMetricName, durationMs: number): void;
|
|
64
79
|
recordArtifactCacheHit(): void;
|
|
65
80
|
recordArtifactCacheMiss(): void;
|
|
66
81
|
recordRepoFailover(): void;
|
|
82
|
+
recordSearchQueryMode(mode: "auto" | "token" | "literal"): void;
|
|
67
83
|
recordSearchIntentDuration(intent: "symbol" | "text" | "path", durationMs: number): void;
|
|
68
84
|
recordSearchRegexFallback(): void;
|
|
69
85
|
recordSearchTokenBytesReturned(tokenBytes: number): void;
|
|
@@ -80,7 +96,7 @@ export declare class RuntimeMetrics {
|
|
|
80
96
|
recordCacheEviction(count?: number): void;
|
|
81
97
|
setCacheEntries(entries: number): void;
|
|
82
98
|
setCacheTotalContentBytes(totalBytes: number): void;
|
|
83
|
-
|
|
99
|
+
setCacheArtifactByteAccountingRef(entries: ReadonlyArray<CacheArtifactByteAccountingRefRow>): void;
|
|
84
100
|
snapshot(): RuntimeMetricSnapshot;
|
|
85
101
|
private toSnapshot;
|
|
86
102
|
private resolveCacheHitRate;
|
package/dist/observability.js
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
|
+
const MAX_TIMING_SAMPLES = 512;
|
|
2
|
+
function percentile(samples, p) {
|
|
3
|
+
if (samples.length === 0) {
|
|
4
|
+
return 0;
|
|
5
|
+
}
|
|
6
|
+
const sorted = [...samples].sort((left, right) => left - right);
|
|
7
|
+
const index = Math.min(sorted.length - 1, Math.ceil((p / 100) * sorted.length) - 1);
|
|
8
|
+
return sorted[index] ?? 0;
|
|
9
|
+
}
|
|
1
10
|
export class RuntimeMetrics {
|
|
2
11
|
timings = new Map();
|
|
3
12
|
cacheHits = 0;
|
|
4
13
|
cacheMisses = 0;
|
|
5
14
|
repoFailoverCount = 0;
|
|
15
|
+
searchQueryModeAutoCount = 0;
|
|
16
|
+
searchQueryModeTokenCount = 0;
|
|
17
|
+
searchQueryModeLiteralCount = 0;
|
|
18
|
+
searchLiteralExplicitCount = 0;
|
|
6
19
|
searchRegexFallbackCount = 0;
|
|
7
20
|
searchTokenBytesReturned = 0;
|
|
8
21
|
oneHopExpandCount = 0;
|
|
@@ -18,7 +31,7 @@ export class RuntimeMetrics {
|
|
|
18
31
|
cacheEvictions = 0;
|
|
19
32
|
cacheEntries = 0;
|
|
20
33
|
cacheTotalContentBytes = 0;
|
|
21
|
-
|
|
34
|
+
cacheArtifactBytesLruRef = [];
|
|
22
35
|
constructor() {
|
|
23
36
|
const names = [
|
|
24
37
|
"resolve_duration_ms",
|
|
@@ -31,7 +44,7 @@ export class RuntimeMetrics {
|
|
|
31
44
|
"search_intent_path_duration_ms"
|
|
32
45
|
];
|
|
33
46
|
for (const name of names) {
|
|
34
|
-
this.timings.set(name, { count: 0, totalMs: 0, lastMs: 0 });
|
|
47
|
+
this.timings.set(name, { count: 0, totalMs: 0, lastMs: 0, samples: [] });
|
|
35
48
|
}
|
|
36
49
|
}
|
|
37
50
|
recordDuration(name, durationMs) {
|
|
@@ -43,6 +56,10 @@ export class RuntimeMetrics {
|
|
|
43
56
|
timing.count += 1;
|
|
44
57
|
timing.totalMs += normalizedDuration;
|
|
45
58
|
timing.lastMs = normalizedDuration;
|
|
59
|
+
timing.samples.push(normalizedDuration);
|
|
60
|
+
if (timing.samples.length > MAX_TIMING_SAMPLES) {
|
|
61
|
+
timing.samples.shift();
|
|
62
|
+
}
|
|
46
63
|
}
|
|
47
64
|
recordArtifactCacheHit() {
|
|
48
65
|
this.cacheHits += 1;
|
|
@@ -53,6 +70,20 @@ export class RuntimeMetrics {
|
|
|
53
70
|
recordRepoFailover() {
|
|
54
71
|
this.repoFailoverCount += 1;
|
|
55
72
|
}
|
|
73
|
+
recordSearchQueryMode(mode) {
|
|
74
|
+
switch (mode) {
|
|
75
|
+
case "auto":
|
|
76
|
+
this.searchQueryModeAutoCount += 1;
|
|
77
|
+
break;
|
|
78
|
+
case "token":
|
|
79
|
+
this.searchQueryModeTokenCount += 1;
|
|
80
|
+
break;
|
|
81
|
+
case "literal":
|
|
82
|
+
this.searchQueryModeLiteralCount += 1;
|
|
83
|
+
this.searchLiteralExplicitCount += 1;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
56
87
|
recordSearchIntentDuration(intent, durationMs) {
|
|
57
88
|
const metricName = intent === "symbol"
|
|
58
89
|
? "search_intent_symbol_duration_ms"
|
|
@@ -106,12 +137,8 @@ export class RuntimeMetrics {
|
|
|
106
137
|
setCacheTotalContentBytes(totalBytes) {
|
|
107
138
|
this.cacheTotalContentBytes = Math.max(0, Math.trunc(totalBytes));
|
|
108
139
|
}
|
|
109
|
-
|
|
110
|
-
this.
|
|
111
|
-
artifact_id: entry.artifact_id,
|
|
112
|
-
content_bytes: Math.max(0, Math.trunc(entry.content_bytes)),
|
|
113
|
-
updated_at: entry.updated_at
|
|
114
|
-
}));
|
|
140
|
+
setCacheArtifactByteAccountingRef(entries) {
|
|
141
|
+
this.cacheArtifactBytesLruRef = entries;
|
|
115
142
|
}
|
|
116
143
|
snapshot() {
|
|
117
144
|
return {
|
|
@@ -123,6 +150,10 @@ export class RuntimeMetrics {
|
|
|
123
150
|
search_intent_symbol_duration_ms: this.toSnapshot("search_intent_symbol_duration_ms"),
|
|
124
151
|
search_intent_text_duration_ms: this.toSnapshot("search_intent_text_duration_ms"),
|
|
125
152
|
search_intent_path_duration_ms: this.toSnapshot("search_intent_path_duration_ms"),
|
|
153
|
+
search_query_mode_auto_count: this.searchQueryModeAutoCount,
|
|
154
|
+
search_query_mode_token_count: this.searchQueryModeTokenCount,
|
|
155
|
+
search_query_mode_literal_count: this.searchQueryModeLiteralCount,
|
|
156
|
+
search_literal_explicit_count: this.searchLiteralExplicitCount,
|
|
126
157
|
search_regex_fallback_count: this.searchRegexFallbackCount,
|
|
127
158
|
search_token_bytes_returned: this.searchTokenBytesReturned,
|
|
128
159
|
onehop_expand_count: this.oneHopExpandCount,
|
|
@@ -138,7 +169,11 @@ export class RuntimeMetrics {
|
|
|
138
169
|
cache_evictions: this.cacheEvictions,
|
|
139
170
|
cache_entries: this.cacheEntries,
|
|
140
171
|
cache_total_content_bytes: this.cacheTotalContentBytes,
|
|
141
|
-
cache_artifact_bytes_lru: this.
|
|
172
|
+
cache_artifact_bytes_lru: this.cacheArtifactBytesLruRef.map((entry) => ({
|
|
173
|
+
artifact_id: entry.artifactId,
|
|
174
|
+
content_bytes: Math.max(0, Math.trunc(entry.totalContentBytes)),
|
|
175
|
+
updated_at: entry.updatedAt
|
|
176
|
+
})),
|
|
142
177
|
cache_hit_rate: this.resolveCacheHitRate(),
|
|
143
178
|
repo_failover_count: this.repoFailoverCount
|
|
144
179
|
};
|
|
@@ -151,7 +186,9 @@ export class RuntimeMetrics {
|
|
|
151
186
|
count,
|
|
152
187
|
totalMs,
|
|
153
188
|
avgMs: count > 0 ? totalMs / count : 0,
|
|
154
|
-
lastMs: timing?.lastMs ?? 0
|
|
189
|
+
lastMs: timing?.lastMs ?? 0,
|
|
190
|
+
p95Ms: percentile(timing?.samples ?? [], 95),
|
|
191
|
+
p99Ms: percentile(timing?.samples ?? [], 99)
|
|
155
192
|
};
|
|
156
193
|
}
|
|
157
194
|
resolveCacheHitRate() {
|
package/dist/source-service.d.ts
CHANGED
|
@@ -488,7 +488,6 @@ export declare class SourceService {
|
|
|
488
488
|
private searchTextIntent;
|
|
489
489
|
private searchPathIntent;
|
|
490
490
|
private findSymbolHits;
|
|
491
|
-
private loadScopedFilePaths;
|
|
492
491
|
private indexedCandidateLimit;
|
|
493
492
|
private indexedCandidateLimitForMatch;
|
|
494
493
|
private extractClassMetadata;
|