@adhisang/minecraft-modding-mcp 5.0.0 → 6.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 +55 -0
- package/dist/access-widener-parser.d.ts +1 -0
- package/dist/access-widener-parser.js +6 -3
- package/dist/cache-registry.js +35 -31
- package/dist/config.js +1 -1
- package/dist/decompiler/vineflower.js +8 -2
- package/dist/entry-tools/analyze-mod-service.js +2 -1
- package/dist/entry-tools/analyze-symbol-service.js +18 -9
- package/dist/entry-tools/batch-class-members-service.d.ts +2 -0
- package/dist/entry-tools/batch-class-members-service.js +1 -0
- package/dist/entry-tools/compare-minecraft-service.js +1 -1
- package/dist/entry-tools/inspect-minecraft/handlers/class-members.js +2 -1
- package/dist/entry-tools/inspect-minecraft/handlers/file.js +26 -1
- package/dist/entry-tools/inspect-minecraft/handlers/versions.js +2 -1
- package/dist/entry-tools/inspect-minecraft/internal.js +2 -0
- package/dist/entry-tools/response-contract.d.ts +2 -0
- package/dist/entry-tools/response-contract.js +2 -2
- package/dist/entry-tools/validate-project/cases/project-summary.js +30 -12
- package/dist/entry-tools/validate-project-service.d.ts +4 -4
- package/dist/entry-tools/verify-mixin-target-service.js +7 -7
- package/dist/index.js +21 -16
- package/dist/java-process.js +1 -1
- package/dist/json-rpc-framing.d.ts +4 -0
- package/dist/json-rpc-framing.js +23 -1
- package/dist/mapping/internal-types.d.ts +17 -0
- package/dist/mapping/loaders/tiny-maven.js +46 -20
- package/dist/mapping/lookup.d.ts +12 -1
- package/dist/mapping/lookup.js +53 -1
- package/dist/mapping-service.js +37 -22
- package/dist/minecraft-explorer-service.js +2 -1
- package/dist/mixin/annotation-validators.js +21 -3
- package/dist/mixin/parsed-validator.js +1 -0
- package/dist/mixin-parser.js +71 -3
- package/dist/mod-decompile-service.d.ts +2 -0
- package/dist/mod-decompile-service.js +19 -2
- package/dist/mod-remap-service.js +6 -5
- package/dist/mojang-tiny-mapping-service.js +5 -2
- package/dist/nbt/java-nbt-codec.js +40 -16
- package/dist/nbt/json-patch.js +51 -12
- package/dist/nbt/typed-json.d.ts +1 -0
- package/dist/nbt/typed-json.js +12 -2
- package/dist/nbt/types.d.ts +2 -2
- package/dist/path-converter.js +10 -3
- package/dist/registry-service.d.ts +2 -0
- package/dist/registry-service.js +16 -1
- package/dist/repo-downloader.js +4 -3
- package/dist/source/artifact-resolver.js +1 -1
- package/dist/source/class-source/members-builder.d.ts +26 -0
- package/dist/source/class-source/members-builder.js +31 -4
- package/dist/source/class-source/snippet-builder.js +6 -0
- package/dist/source/class-source-helpers.d.ts +4 -4
- package/dist/source/class-source-helpers.js +12 -11
- package/dist/source/class-source.d.ts +19 -0
- package/dist/source/class-source.js +87 -26
- package/dist/source/file-access.js +3 -2
- package/dist/source/indexer.js +24 -7
- package/dist/source/lifecycle/mapping-helpers.js +28 -3
- package/dist/source/lifecycle/runtime-check.js +20 -6
- package/dist/source/member-pattern.d.ts +16 -0
- package/dist/source/member-pattern.js +27 -0
- package/dist/source/search.js +23 -8
- package/dist/source/validate-mixin/pipeline/resolve.js +23 -3
- package/dist/source/workspace-target.js +2 -1
- package/dist/source-resolver.js +2 -2
- package/dist/source-service.d.ts +8 -4
- package/dist/source-service.js +9 -1
- package/dist/stdio-supervisor.d.ts +2 -2
- package/dist/stdio-supervisor.js +29 -9
- package/dist/storage/db.js +24 -1
- package/dist/storage/files-repo.d.ts +3 -0
- package/dist/storage/files-repo.js +43 -37
- package/dist/storage/symbols-repo.d.ts +9 -0
- package/dist/storage/symbols-repo.js +47 -19
- package/dist/symbols/symbol-extractor.js +1 -1
- package/dist/tool-guidance.d.ts +2 -1
- package/dist/tool-guidance.js +27 -2
- package/dist/tool-schemas.d.ts +15 -4
- package/dist/tool-schemas.js +102 -97
- package/dist/warning-details.d.ts +12 -0
- package/dist/warning-details.js +17 -0
- package/dist/workspace-mapping-service.js +9 -0
- package/docs/tool-reference.md +23 -0
- package/package.json +1 -1
|
@@ -90,8 +90,8 @@ export declare class StdioSupervisor {
|
|
|
90
90
|
private readonly handleWorkerData;
|
|
91
91
|
private readonly handleWorkerStdinError;
|
|
92
92
|
private readonly handleWorkerStderr;
|
|
93
|
-
private
|
|
94
|
-
private
|
|
93
|
+
private handleWorkerProcessError;
|
|
94
|
+
private handleWorkerExit;
|
|
95
95
|
private handleWorkerMessage;
|
|
96
96
|
private applyStageUpdate;
|
|
97
97
|
private handleWorkerReady;
|
package/dist/stdio-supervisor.js
CHANGED
|
@@ -408,6 +408,13 @@ export class StdioSupervisor {
|
|
|
408
408
|
if (this.shuttingDown) {
|
|
409
409
|
return;
|
|
410
410
|
}
|
|
411
|
+
const stale = this.child;
|
|
412
|
+
if (stale) {
|
|
413
|
+
this.detachChild();
|
|
414
|
+
if (stale.exitCode === null) {
|
|
415
|
+
stale.kill("SIGTERM");
|
|
416
|
+
}
|
|
417
|
+
}
|
|
411
418
|
const child = spawn(process.execPath, [...process.execArgv, this.entryFile], {
|
|
412
419
|
env: {
|
|
413
420
|
...process.env,
|
|
@@ -423,8 +430,8 @@ export class StdioSupervisor {
|
|
|
423
430
|
child.stdout.on("data", this.handleWorkerData);
|
|
424
431
|
child.stderr.on("data", this.handleWorkerStderr);
|
|
425
432
|
child.stdin.on("error", this.handleWorkerStdinError);
|
|
426
|
-
child.once("error", this.handleWorkerProcessError);
|
|
427
|
-
child.once("exit", this.handleWorkerExit);
|
|
433
|
+
child.once("error", (error) => this.handleWorkerProcessError(child, error));
|
|
434
|
+
child.once("exit", (code, signal) => this.handleWorkerExit(child, code, signal));
|
|
428
435
|
log("info", "supervisor.worker_spawn", { pid: child.pid });
|
|
429
436
|
}
|
|
430
437
|
handleWorkerData = (chunk) => {
|
|
@@ -455,10 +462,23 @@ export class StdioSupervisor {
|
|
|
455
462
|
process.stderr.write(`${line}\n`);
|
|
456
463
|
}
|
|
457
464
|
};
|
|
458
|
-
handleWorkerProcessError
|
|
465
|
+
handleWorkerProcessError(child, error) {
|
|
459
466
|
log("error", "supervisor.worker_process_error", { message: error.message });
|
|
460
|
-
|
|
461
|
-
|
|
467
|
+
if (child !== this.child) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
471
|
+
child.kill("SIGTERM");
|
|
472
|
+
}
|
|
473
|
+
this.handleWorkerExit(child, null, null);
|
|
474
|
+
}
|
|
475
|
+
handleWorkerExit(child, code, signal) {
|
|
476
|
+
if (child !== this.child) {
|
|
477
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
478
|
+
child.kill("SIGTERM");
|
|
479
|
+
}
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
462
482
|
const childPid = this.child?.pid;
|
|
463
483
|
this.detachChild();
|
|
464
484
|
if (this.shuttingDown) {
|
|
@@ -472,7 +492,7 @@ export class StdioSupervisor {
|
|
|
472
492
|
});
|
|
473
493
|
this.failPendingRequestsOnWorkerExit({ code, signal });
|
|
474
494
|
this.scheduleRestart();
|
|
475
|
-
}
|
|
495
|
+
}
|
|
476
496
|
handleWorkerMessage(message) {
|
|
477
497
|
debugSupervisor("worker_message", {
|
|
478
498
|
hasMethod: "method" in message,
|
|
@@ -580,7 +600,7 @@ export class StdioSupervisor {
|
|
|
580
600
|
}
|
|
581
601
|
}
|
|
582
602
|
failPendingRequestsOnWorkerExit(exit) {
|
|
583
|
-
const preservedInitializeKey = this.initializeRequest
|
|
603
|
+
const preservedInitializeKey = this.initializeRequest
|
|
584
604
|
? requestKey(this.initializeRequest.id)
|
|
585
605
|
: undefined;
|
|
586
606
|
const now = performance.now();
|
|
@@ -635,8 +655,8 @@ export class StdioSupervisor {
|
|
|
635
655
|
child.stdout.off("data", this.handleWorkerData);
|
|
636
656
|
child.stderr.off("data", this.handleWorkerStderr);
|
|
637
657
|
child.stdin.off("error", this.handleWorkerStdinError);
|
|
638
|
-
child.
|
|
639
|
-
child.
|
|
658
|
+
child.removeAllListeners("error");
|
|
659
|
+
child.removeAllListeners("exit");
|
|
640
660
|
this.child = undefined;
|
|
641
661
|
this.childReady = false;
|
|
642
662
|
}
|
package/dist/storage/db.js
CHANGED
|
@@ -14,7 +14,7 @@ function runIntegrityCheck(db) {
|
|
|
14
14
|
throw createError({
|
|
15
15
|
code: ERROR_CODES.DB_FAILURE,
|
|
16
16
|
message: "SQLite integrity check failed.",
|
|
17
|
-
details: { integrityCheck: result }
|
|
17
|
+
details: { reason: "integrity_check_failed", integrityCheck: result }
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
}
|
|
@@ -47,6 +47,22 @@ function isSchemaVersionMismatchError(error) {
|
|
|
47
47
|
return (error.details?.reason === "schema_version_unsupported" ||
|
|
48
48
|
error.details?.reason === "schema_version_invalid");
|
|
49
49
|
}
|
|
50
|
+
const SQLITE_CORRUPT_ERRCODE = 11;
|
|
51
|
+
const SQLITE_NOTADB_ERRCODE = 26;
|
|
52
|
+
function isCorruptionError(error) {
|
|
53
|
+
if (isAppError(error)) {
|
|
54
|
+
return (error.code === ERROR_CODES.DB_FAILURE && error.details?.reason === "integrity_check_failed");
|
|
55
|
+
}
|
|
56
|
+
const sqliteError = error;
|
|
57
|
+
if (sqliteError?.code === "SQLITE_CORRUPT" || sqliteError?.code === "SQLITE_NOTADB") {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
if (typeof sqliteError?.errcode !== "number") {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const primaryErrcode = sqliteError.errcode & 0xff;
|
|
64
|
+
return primaryErrcode === SQLITE_CORRUPT_ERRCODE || primaryErrcode === SQLITE_NOTADB_ERRCODE;
|
|
65
|
+
}
|
|
50
66
|
function buildDefaultLogger() {
|
|
51
67
|
return {
|
|
52
68
|
warn: (message, details) => {
|
|
@@ -104,6 +120,13 @@ export function openDatabase(config, logger = buildDefaultLogger()) {
|
|
|
104
120
|
throw caughtError;
|
|
105
121
|
}
|
|
106
122
|
if (!isMissingPath(config.sqlitePath)) {
|
|
123
|
+
if (!isCorruptionError(caughtError)) {
|
|
124
|
+
logger.error("SQLite initialization failed", {
|
|
125
|
+
path: config.sqlitePath,
|
|
126
|
+
reason: errorMessage
|
|
127
|
+
});
|
|
128
|
+
throw caughtError;
|
|
129
|
+
}
|
|
107
130
|
const backupPath = backupCorruptedDb(config.sqlitePath);
|
|
108
131
|
logger.warn("SQLite database integrity check failed. Recreated database after backup", {
|
|
109
132
|
sqlitePath: config.sqlitePath,
|
|
@@ -51,7 +51,10 @@ export declare class FilesRepo {
|
|
|
51
51
|
private readonly searchFtsStmt;
|
|
52
52
|
private readonly getByPathsStmtCache;
|
|
53
53
|
private readonly classLookupStmtCache;
|
|
54
|
+
private readonly dynamicStmtCache;
|
|
55
|
+
private static readonly DYNAMIC_STMT_CACHE_MAX;
|
|
54
56
|
constructor(db: SqliteDatabase);
|
|
57
|
+
private prepareCached;
|
|
55
58
|
clearFilesForArtifact(artifactId: string): void;
|
|
56
59
|
insertFilesForArtifact(artifactId: string, files: IndexedFile[]): void;
|
|
57
60
|
replaceFilesForArtifact(artifactId: string, files: IndexedFile[]): void;
|
|
@@ -67,18 +67,21 @@ function parseSearchCursor(cursor) {
|
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
function nextCursorFromRows(rows) {
|
|
71
|
-
if (rows.length === 0) {
|
|
70
|
+
function nextCursorFromRows(rows, limit) {
|
|
71
|
+
if (rows.length === 0 || rows.length < limit) {
|
|
72
72
|
return undefined;
|
|
73
73
|
}
|
|
74
74
|
const last = rows[rows.length - 1];
|
|
75
75
|
return buildCursor(last.file_path);
|
|
76
76
|
}
|
|
77
|
+
function compareFilePaths(left, right) {
|
|
78
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
79
|
+
}
|
|
77
80
|
function compareSearchOrdering(left, right) {
|
|
78
81
|
if (right.score !== left.score) {
|
|
79
82
|
return right.score - left.score;
|
|
80
83
|
}
|
|
81
|
-
return left.filePath
|
|
84
|
+
return compareFilePaths(left.filePath, right.filePath);
|
|
82
85
|
}
|
|
83
86
|
function isAfterSearchCursor(hit, cursor) {
|
|
84
87
|
if (hit.score < cursor.score) {
|
|
@@ -87,7 +90,7 @@ function isAfterSearchCursor(hit, cursor) {
|
|
|
87
90
|
if (hit.score > cursor.score) {
|
|
88
91
|
return false;
|
|
89
92
|
}
|
|
90
|
-
return hit.filePath
|
|
93
|
+
return compareFilePaths(hit.filePath, cursor.filePath) > 0;
|
|
91
94
|
}
|
|
92
95
|
function buildPreview(content, query) {
|
|
93
96
|
const normalizedQuery = query.toLowerCase();
|
|
@@ -137,6 +140,10 @@ export class FilesRepo {
|
|
|
137
140
|
searchFtsStmt;
|
|
138
141
|
getByPathsStmtCache = new Map();
|
|
139
142
|
classLookupStmtCache = new Map();
|
|
143
|
+
// Fixed-SQL statements built outside the constructor; cached (LRU by SQL text)
|
|
144
|
+
// so hot paths do not re-prepare per call.
|
|
145
|
+
dynamicStmtCache = new Map();
|
|
146
|
+
static DYNAMIC_STMT_CACHE_MAX = 64;
|
|
140
147
|
constructor(db) {
|
|
141
148
|
this.db = db;
|
|
142
149
|
this.deleteStmt = this.db.prepare(`
|
|
@@ -155,14 +162,14 @@ export class FilesRepo {
|
|
|
155
162
|
this.listStmt = this.db.prepare(`
|
|
156
163
|
SELECT artifact_id, file_path
|
|
157
164
|
FROM files
|
|
158
|
-
WHERE artifact_id = ? AND file_path > ? AND (? IS NULL OR file_path LIKE ?
|
|
165
|
+
WHERE artifact_id = ? AND file_path > ? AND (? IS NULL OR file_path LIKE ? ESCAPE '\\')
|
|
159
166
|
ORDER BY file_path ASC
|
|
160
167
|
LIMIT ?
|
|
161
168
|
`);
|
|
162
169
|
this.listRowsStmt = this.db.prepare(`
|
|
163
170
|
SELECT artifact_id, file_path, content, content_bytes, content_hash
|
|
164
171
|
FROM files
|
|
165
|
-
WHERE artifact_id = ? AND file_path > ? AND (? IS NULL OR file_path LIKE ?
|
|
172
|
+
WHERE artifact_id = ? AND file_path > ? AND (? IS NULL OR file_path LIKE ? ESCAPE '\\')
|
|
166
173
|
ORDER BY file_path ASC
|
|
167
174
|
LIMIT ?
|
|
168
175
|
`);
|
|
@@ -188,6 +195,23 @@ export class FilesRepo {
|
|
|
188
195
|
LIMIT ?
|
|
189
196
|
`);
|
|
190
197
|
}
|
|
198
|
+
prepareCached(sql) {
|
|
199
|
+
const cached = this.dynamicStmtCache.get(sql);
|
|
200
|
+
if (cached) {
|
|
201
|
+
// Refresh recency so hot statements survive eviction.
|
|
202
|
+
this.dynamicStmtCache.delete(sql);
|
|
203
|
+
this.dynamicStmtCache.set(sql, cached);
|
|
204
|
+
return cached;
|
|
205
|
+
}
|
|
206
|
+
const stmt = this.db.prepare(sql);
|
|
207
|
+
this.dynamicStmtCache.set(sql, stmt);
|
|
208
|
+
if (this.dynamicStmtCache.size > FilesRepo.DYNAMIC_STMT_CACHE_MAX) {
|
|
209
|
+
const oldest = this.dynamicStmtCache.keys().next().value;
|
|
210
|
+
if (oldest !== undefined)
|
|
211
|
+
this.dynamicStmtCache.delete(oldest);
|
|
212
|
+
}
|
|
213
|
+
return stmt;
|
|
214
|
+
}
|
|
191
215
|
clearFilesForArtifact(artifactId) {
|
|
192
216
|
this.deleteStmt.run([artifactId]);
|
|
193
217
|
}
|
|
@@ -231,15 +255,15 @@ export class FilesRepo {
|
|
|
231
255
|
}
|
|
232
256
|
listFiles(artifactId, options) {
|
|
233
257
|
const cursor = parseCursor(options.cursor);
|
|
234
|
-
const rows = this.listStmt.all(artifactId, cursor?.sortKey ?? "", options.prefix ?? null, options.prefix
|
|
258
|
+
const rows = this.listStmt.all(artifactId, cursor?.sortKey ?? "", options.prefix ?? null, options.prefix != null ? `${escapeLikeNeedle(options.prefix)}%` : "", Math.max(1, options.limit));
|
|
235
259
|
return {
|
|
236
260
|
items: rows.map((row) => row.file_path),
|
|
237
|
-
nextCursor: nextCursorFromRows(rows)
|
|
261
|
+
nextCursor: nextCursorFromRows(rows, Math.max(1, options.limit))
|
|
238
262
|
};
|
|
239
263
|
}
|
|
240
264
|
listFileRows(artifactId, options) {
|
|
241
265
|
const cursor = parseCursor(options.cursor);
|
|
242
|
-
const rows = this.listRowsStmt.all(artifactId, cursor?.sortKey ?? "", options.prefix ?? null, options.prefix
|
|
266
|
+
const rows = this.listRowsStmt.all(artifactId, cursor?.sortKey ?? "", options.prefix ?? null, options.prefix != null ? `${escapeLikeNeedle(options.prefix)}%` : "", Math.max(1, options.limit));
|
|
243
267
|
return {
|
|
244
268
|
items: rows.map((row) => ({
|
|
245
269
|
artifactId: row.artifact_id,
|
|
@@ -248,7 +272,7 @@ export class FilesRepo {
|
|
|
248
272
|
contentBytes: row.content_bytes,
|
|
249
273
|
contentHash: row.content_hash
|
|
250
274
|
})),
|
|
251
|
-
nextCursor: nextCursorFromRows(rows)
|
|
275
|
+
nextCursor: nextCursorFromRows(rows, Math.max(1, options.limit))
|
|
252
276
|
};
|
|
253
277
|
}
|
|
254
278
|
/**
|
|
@@ -288,7 +312,7 @@ export class FilesRepo {
|
|
|
288
312
|
return { items: [], nextCursor: undefined, scannedRows: 0, dbRoundtrips: 0 };
|
|
289
313
|
}
|
|
290
314
|
const cursor = parseSearchCursor(options.cursor);
|
|
291
|
-
const likeQuery = `%${normalized}%`;
|
|
315
|
+
const likeQuery = `%${escapeLikeNeedle(normalized)}%`;
|
|
292
316
|
const ftsQuery = buildIndexedMatchQuery(normalized, options.match);
|
|
293
317
|
const mode = options.mode ?? "mixed";
|
|
294
318
|
// Cursor-adaptive fetch limit: when no cursor, use a generous limit;
|
|
@@ -298,28 +322,11 @@ export class FilesRepo {
|
|
|
298
322
|
const fetchLimit = baseFetchLimit;
|
|
299
323
|
// When cursor score is below all possible bands, skip both queries
|
|
300
324
|
const cursorExhausted = cursor != null && cursor.score < 100;
|
|
301
|
-
|
|
302
|
-
const cursorPastPath = cursor != null && cursor.score < 120;
|
|
303
|
-
const includePath = mode !== "text" && !cursorExhausted && !cursorPastPath;
|
|
325
|
+
const includePath = mode !== "text" && !cursorExhausted;
|
|
304
326
|
const includeContent = mode !== "path" && !cursorExhausted;
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
// Cursor is within the path tier — only fetch paths after cursor.filePath
|
|
309
|
-
pathRows = this.db.prepare(`
|
|
310
|
-
SELECT file_path
|
|
311
|
-
FROM files
|
|
312
|
-
WHERE artifact_id = ? AND file_path LIKE ? ESCAPE '\\' AND file_path > ?
|
|
313
|
-
ORDER BY file_path ASC
|
|
314
|
-
LIMIT ?
|
|
315
|
-
`).all(artifactId, likeQuery, cursor.filePath, fetchLimit);
|
|
316
|
-
}
|
|
317
|
-
else if (includePath) {
|
|
318
|
-
pathRows = this.searchPathStmt.all(artifactId, likeQuery, fetchLimit);
|
|
319
|
-
}
|
|
320
|
-
else {
|
|
321
|
-
pathRows = [];
|
|
322
|
-
}
|
|
327
|
+
const pathRows = includePath
|
|
328
|
+
? this.searchPathStmt.all(artifactId, likeQuery, fetchLimit)
|
|
329
|
+
: [];
|
|
323
330
|
const merged = pathRows.map((row) => ({
|
|
324
331
|
filePath: row.file_path,
|
|
325
332
|
score: 120,
|
|
@@ -417,7 +424,7 @@ export class FilesRepo {
|
|
|
417
424
|
return 0;
|
|
418
425
|
}
|
|
419
426
|
try {
|
|
420
|
-
const row = this.
|
|
427
|
+
const row = this.prepareCached(`SELECT COUNT(*) AS cnt FROM files_fts WHERE artifact_id = ? AND files_fts MATCH ?`).get(artifactId, ftsQuery);
|
|
421
428
|
return row?.cnt ?? 0;
|
|
422
429
|
}
|
|
423
430
|
catch {
|
|
@@ -433,8 +440,8 @@ export class FilesRepo {
|
|
|
433
440
|
if (!normalized) {
|
|
434
441
|
return 0;
|
|
435
442
|
}
|
|
436
|
-
const likeQuery = `%${normalized}%`;
|
|
437
|
-
const row = this.
|
|
443
|
+
const likeQuery = `%${escapeLikeNeedle(normalized)}%`;
|
|
444
|
+
const row = this.prepareCached(`SELECT COUNT(*) AS cnt FROM files WHERE artifact_id = ? AND file_path LIKE ? ESCAPE '\\'`).get(artifactId, likeQuery);
|
|
438
445
|
return row?.cnt ?? 0;
|
|
439
446
|
}
|
|
440
447
|
findFirstFilePathByName(artifactId, fileName) {
|
|
@@ -442,8 +449,7 @@ export class FilesRepo {
|
|
|
442
449
|
if (!normalized) {
|
|
443
450
|
return undefined;
|
|
444
451
|
}
|
|
445
|
-
const row = this.
|
|
446
|
-
.prepare(`
|
|
452
|
+
const row = this.prepareCached(`
|
|
447
453
|
SELECT file_path
|
|
448
454
|
FROM files
|
|
449
455
|
WHERE artifact_id = ?
|
|
@@ -46,12 +46,21 @@ export declare class SymbolsRepo {
|
|
|
46
46
|
private readonly listByArtifactStmt;
|
|
47
47
|
private readonly listByArtifactKindStmt;
|
|
48
48
|
private readonly listByFileStmt;
|
|
49
|
+
private readonly dynamicStmtCache;
|
|
50
|
+
private static readonly DYNAMIC_STMT_CACHE_MAX;
|
|
49
51
|
constructor(db: SqliteDatabase);
|
|
52
|
+
private prepareCached;
|
|
50
53
|
clearSymbolsForArtifact(artifactId: string): void;
|
|
51
54
|
insertSymbolsForArtifact(artifactId: string, symbols: IndexedSymbol[]): void;
|
|
52
55
|
replaceSymbolsForArtifact(artifactId: string, symbols: IndexedSymbol[]): void;
|
|
53
56
|
findSymbols(options: FindSymbolsOptions): PagedResult<SymbolRow>;
|
|
54
57
|
listSymbolsForArtifact(artifactId: string, symbolKind?: string): SymbolRow[];
|
|
58
|
+
/**
|
|
59
|
+
* Streaming variant of listSymbolsForArtifact: rows are mapped lazily so callers
|
|
60
|
+
* that filter (e.g. regex symbol search) never materialize the full symbol set.
|
|
61
|
+
* Do not run other statements on this connection while consuming the iterator.
|
|
62
|
+
*/
|
|
63
|
+
iterateSymbolsForArtifact(artifactId: string, symbolKind?: string): IterableIterator<SymbolRow>;
|
|
55
64
|
listSymbolsForFile(artifactId: string, filePath: string): SymbolRow[];
|
|
56
65
|
listSymbolsForFiles(artifactId: string, filePaths: string[], symbolKind?: string): Map<string, SymbolRow[]>;
|
|
57
66
|
findBySymbolNames(artifactId: string, symbolNames: string[]): SymbolRow[];
|
|
@@ -60,6 +60,10 @@ export class SymbolsRepo {
|
|
|
60
60
|
listByArtifactStmt;
|
|
61
61
|
listByArtifactKindStmt;
|
|
62
62
|
listByFileStmt;
|
|
63
|
+
// Dynamic WHERE-clause builders produce a small bounded set of SQL strings;
|
|
64
|
+
// cache their prepared statements (LRU by SQL text) instead of re-preparing per call.
|
|
65
|
+
dynamicStmtCache = new Map();
|
|
66
|
+
static DYNAMIC_STMT_CACHE_MAX = 64;
|
|
63
67
|
constructor(db) {
|
|
64
68
|
this.db = db;
|
|
65
69
|
this.deleteStmt = this.db.prepare(`
|
|
@@ -106,6 +110,23 @@ export class SymbolsRepo {
|
|
|
106
110
|
ORDER BY line ASC, symbol_name ASC
|
|
107
111
|
`);
|
|
108
112
|
}
|
|
113
|
+
prepareCached(sql) {
|
|
114
|
+
const cached = this.dynamicStmtCache.get(sql);
|
|
115
|
+
if (cached) {
|
|
116
|
+
// Refresh recency so hot statements survive eviction.
|
|
117
|
+
this.dynamicStmtCache.delete(sql);
|
|
118
|
+
this.dynamicStmtCache.set(sql, cached);
|
|
119
|
+
return cached;
|
|
120
|
+
}
|
|
121
|
+
const stmt = this.db.prepare(sql);
|
|
122
|
+
this.dynamicStmtCache.set(sql, stmt);
|
|
123
|
+
if (this.dynamicStmtCache.size > SymbolsRepo.DYNAMIC_STMT_CACHE_MAX) {
|
|
124
|
+
const oldest = this.dynamicStmtCache.keys().next().value;
|
|
125
|
+
if (oldest !== undefined)
|
|
126
|
+
this.dynamicStmtCache.delete(oldest);
|
|
127
|
+
}
|
|
128
|
+
return stmt;
|
|
129
|
+
}
|
|
109
130
|
clearSymbolsForArtifact(artifactId) {
|
|
110
131
|
this.deleteStmt.run([artifactId]);
|
|
111
132
|
}
|
|
@@ -150,7 +171,7 @@ export class SymbolsRepo {
|
|
|
150
171
|
LIMIT ?
|
|
151
172
|
`;
|
|
152
173
|
const nameParam = options.exact ? symbolName : `${symbolName}%`;
|
|
153
|
-
rows = this.
|
|
174
|
+
rows = this.prepareCached(sql).all(options.artifactId, options.symbolKind ?? "", options.symbolKind ?? "", nameParam, cursor.symbolName, cursor.symbolName, cursor.filePath, cursor.symbolName, cursor.filePath, cursor.line, Math.max(1, fetchLimit));
|
|
154
175
|
}
|
|
155
176
|
else {
|
|
156
177
|
const queryRows = options.exact ? this.searchExactStmt : this.searchStmt;
|
|
@@ -173,16 +194,26 @@ export class SymbolsRepo {
|
|
|
173
194
|
};
|
|
174
195
|
}
|
|
175
196
|
listSymbolsForArtifact(artifactId, symbolKind) {
|
|
197
|
+
return [...this.iterateSymbolsForArtifact(artifactId, symbolKind)];
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Streaming variant of listSymbolsForArtifact: rows are mapped lazily so callers
|
|
201
|
+
* that filter (e.g. regex symbol search) never materialize the full symbol set.
|
|
202
|
+
* Do not run other statements on this connection while consuming the iterator.
|
|
203
|
+
*/
|
|
204
|
+
*iterateSymbolsForArtifact(artifactId, symbolKind) {
|
|
176
205
|
const rows = (symbolKind
|
|
177
|
-
? this.listByArtifactKindStmt.
|
|
178
|
-
: this.listByArtifactStmt.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
206
|
+
? this.listByArtifactKindStmt.iterate(artifactId, symbolKind)
|
|
207
|
+
: this.listByArtifactStmt.iterate(artifactId));
|
|
208
|
+
for (const row of rows) {
|
|
209
|
+
yield toSymbolRow(artifactId, {
|
|
210
|
+
filePath: row.file_path,
|
|
211
|
+
symbolKind: row.symbol_kind,
|
|
212
|
+
symbolName: row.symbol_name,
|
|
213
|
+
qualifiedName: row.qualified_name ?? undefined,
|
|
214
|
+
line: row.line
|
|
215
|
+
});
|
|
216
|
+
}
|
|
186
217
|
}
|
|
187
218
|
listSymbolsForFile(artifactId, filePath) {
|
|
188
219
|
const rows = this.listByFileStmt.all(artifactId, filePath);
|
|
@@ -209,7 +240,7 @@ export class SymbolsRepo {
|
|
|
209
240
|
ORDER BY file_path ASC, line ASC, symbol_name ASC
|
|
210
241
|
`;
|
|
211
242
|
const params = symbolKind ? [artifactId, ...uniqueFilePaths, symbolKind] : [artifactId, ...uniqueFilePaths];
|
|
212
|
-
const rows = this.
|
|
243
|
+
const rows = this.prepareCached(sql).all(...params);
|
|
213
244
|
const byFile = new Map();
|
|
214
245
|
for (const row of rows) {
|
|
215
246
|
const bucket = byFile.get(row.file_path) ?? [];
|
|
@@ -230,8 +261,7 @@ export class SymbolsRepo {
|
|
|
230
261
|
return [];
|
|
231
262
|
}
|
|
232
263
|
const placeholders = unique.map(() => "?").join(", ");
|
|
233
|
-
const rows = this.
|
|
234
|
-
.prepare(`
|
|
264
|
+
const rows = this.prepareCached(`
|
|
235
265
|
SELECT file_path, symbol_kind, symbol_name, qualified_name, line
|
|
236
266
|
FROM symbols
|
|
237
267
|
WHERE artifact_id = ?
|
|
@@ -306,7 +336,7 @@ export class SymbolsRepo {
|
|
|
306
336
|
ORDER BY symbol_name ASC, file_path ASC, line ASC
|
|
307
337
|
LIMIT ?
|
|
308
338
|
`;
|
|
309
|
-
const rows = this.
|
|
339
|
+
const rows = this.prepareCached(sql).all(...params);
|
|
310
340
|
const hasMore = rows.length > rawLimit;
|
|
311
341
|
const page = hasMore ? rows.slice(0, rawLimit) : rows;
|
|
312
342
|
const lastRow = page.length > 0 ? page[page.length - 1] : undefined;
|
|
@@ -360,12 +390,11 @@ export class SymbolsRepo {
|
|
|
360
390
|
WHERE artifact_id = ?
|
|
361
391
|
${where.length > 0 ? `AND ${where.join("\n AND ")}` : ""}
|
|
362
392
|
`;
|
|
363
|
-
const row = this.
|
|
393
|
+
const row = this.prepareCached(sql).get(...params);
|
|
364
394
|
return row?.cnt ?? 0;
|
|
365
395
|
}
|
|
366
396
|
listDistinctFilePathsByKind(artifactId, symbolKind) {
|
|
367
|
-
const rows = this.
|
|
368
|
-
.prepare(`
|
|
397
|
+
const rows = this.prepareCached(`
|
|
369
398
|
SELECT DISTINCT file_path
|
|
370
399
|
FROM symbols
|
|
371
400
|
WHERE artifact_id = ? AND symbol_kind = ?
|
|
@@ -380,8 +409,7 @@ export class SymbolsRepo {
|
|
|
380
409
|
if (!normalizedClassName || !normalizedSimpleName) {
|
|
381
410
|
return undefined;
|
|
382
411
|
}
|
|
383
|
-
const row = this.
|
|
384
|
-
.prepare(`
|
|
412
|
+
const row = this.prepareCached(`
|
|
385
413
|
SELECT file_path
|
|
386
414
|
FROM symbols
|
|
387
415
|
WHERE artifact_id = ?
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// A type token may carry spaced generics (Map<String, Integer>), arrays (int[][]),
|
|
2
2
|
// wildcards (List<? extends Foo>), and FQNs (java.util.Map). It must not contain "=".
|
|
3
3
|
const TYPE_TOKEN = "[\\w.$][\\w.$<>\\[\\],?\\s]*";
|
|
4
|
-
const MODIFIER = "(?:public|private|protected|abstract|final|static|native|synchronized|default|strictfp|transient|volatile)";
|
|
4
|
+
const MODIFIER = "(?:public|private|protected|abstract|final|static|native|synchronized|default|strictfp|transient|volatile|sealed|non-sealed)";
|
|
5
5
|
const MODIFIER_OR_ANNOTATION_RUN = `(?:(?:@[\\w.]+|${MODIFIER})\\s+)*`;
|
|
6
6
|
const TYPE_PARAMS = "(?:<[^>]+>\\s*)?";
|
|
7
7
|
const THROWS_CLAUSE = "(?:\\s+throws\\s+[\\w.$,\\s]+)?";
|
package/dist/tool-guidance.d.ts
CHANGED
|
@@ -6,7 +6,8 @@ export type ToolMeta = {
|
|
|
6
6
|
requestId: string;
|
|
7
7
|
tool: string;
|
|
8
8
|
durationMs: number;
|
|
9
|
-
warnings
|
|
9
|
+
/** Omitted entirely when there are no warnings (token efficiency). */
|
|
10
|
+
warnings?: string[];
|
|
10
11
|
/** Structured companion to `warnings`: one classified entry per warning string, referencing its text via `warnings[detail.index]`. */
|
|
11
12
|
warningDetails?: WarningDetail[];
|
|
12
13
|
detailApplied?: "summary" | "standard" | "full";
|
package/dist/tool-guidance.js
CHANGED
|
@@ -317,7 +317,22 @@ export function buildValidateMixinSuggestedParams(normalizedInput) {
|
|
|
317
317
|
version
|
|
318
318
|
};
|
|
319
319
|
}
|
|
320
|
-
|
|
320
|
+
if (inputRecord?.mode === "project") {
|
|
321
|
+
const projectInputPath = asNonEmptyString(inputRecord.path);
|
|
322
|
+
if (projectInputPath) {
|
|
323
|
+
return {
|
|
324
|
+
...shared,
|
|
325
|
+
input: {
|
|
326
|
+
mode: "project",
|
|
327
|
+
path: projectInputPath
|
|
328
|
+
},
|
|
329
|
+
version
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
const path = (inputRecord?.mode === "path" || inputRecord?.mode === undefined
|
|
334
|
+
? asNonEmptyString(inputRecord?.path)
|
|
335
|
+
: undefined) ??
|
|
321
336
|
asNonEmptyString(record.sourcePath);
|
|
322
337
|
if (path) {
|
|
323
338
|
return {
|
|
@@ -600,6 +615,16 @@ export function buildValidateProjectSuggestedParams(normalizedInput) {
|
|
|
600
615
|
return result;
|
|
601
616
|
}
|
|
602
617
|
const inputRecord = asObjectRecord(subjectRecord?.input) ?? asObjectRecord(record.input);
|
|
618
|
+
if (task === "access-transformer") {
|
|
619
|
+
result.subject = {
|
|
620
|
+
kind: "access-transformer",
|
|
621
|
+
input: inputRecord ?? {
|
|
622
|
+
mode: "inline",
|
|
623
|
+
content: "<access transformer contents>"
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
return result;
|
|
627
|
+
}
|
|
603
628
|
result.subject = {
|
|
604
629
|
kind: "access-widener",
|
|
605
630
|
input: inputRecord ?? {
|
|
@@ -647,7 +672,7 @@ export function buildInvalidInputGuidance(tool, normalizedInput) {
|
|
|
647
672
|
}
|
|
648
673
|
if (tool === "get-class-source" || tool === "get-class-members") {
|
|
649
674
|
return gatedGuidance(tool, [
|
|
650
|
-
`${tool}.target must be an object: {"kind":"version|jar|coordinate","value":"..."} or {"kind":"artifact","artifactId":"..."} (same shape as resolve-artifact).`,
|
|
675
|
+
`${tool}.target must be an object: {"kind":"version|jar|coordinate","value":"..."}, {"kind":"workspace"}, {"kind":"dependency","group":"...","name":"...","versionFromProject":true} (inspect a Fabric/loader dependency like vanilla), or {"kind":"artifact","artifactId":"..."} (same shape as resolve-artifact).`,
|
|
651
676
|
"Bare string targets are not accepted; wrap the value under target.kind/target.value."
|
|
652
677
|
], buildSourceLookupSuggestedParams(tool, normalizedInput));
|
|
653
678
|
}
|
package/dist/tool-schemas.d.ts
CHANGED
|
@@ -211,11 +211,14 @@ export declare const sourceLookupTargetSchema: z.ZodDiscriminatedUnion<"kind", [
|
|
|
211
211
|
kind: "artifact";
|
|
212
212
|
artifactId: string;
|
|
213
213
|
}>]>;
|
|
214
|
-
export declare const RESOLVE_ARTIFACT_TARGET_DESCRIPTION = "Object
|
|
215
|
-
export declare const SOURCE_LOOKUP_TARGET_DESCRIPTION = "
|
|
216
|
-
export declare const SOURCE_SCOPE_DESCRIPTION = "vanilla = Mojang client jar only; merged =
|
|
214
|
+
export declare const RESOLVE_ARTIFACT_TARGET_DESCRIPTION = "Object, not string. e.g. {\"kind\":\"version\",\"value\":\"1.21.10\"}, {\"kind\":\"workspace\"}, or to inspect a loader/Fabric dependency like vanilla: {\"kind\":\"dependency\",\"group\":\"net.fabricmc.fabric-api\",\"name\":\"fabric-api\",\"versionFromProject\":true} (needs projectPath) or with an explicit \"version\".";
|
|
215
|
+
export declare const SOURCE_LOOKUP_TARGET_DESCRIPTION = "Same shape as resolve-artifact target (incl. {\"kind\":\"dependency\",...} to read a Fabric/loader dependency class like vanilla), plus {\"kind\":\"artifact\",\"artifactId\":\"...\"} to reuse a resolved artifact. Object, not string.";
|
|
216
|
+
export declare const SOURCE_SCOPE_DESCRIPTION = "vanilla = Mojang client jar only; merged = merged runtime discovery; loader = loader-transformed runtime jars.";
|
|
217
|
+
export declare const MEMBER_PATTERN_DESCRIPTION = "Case-insensitive substring filter on member names. Use \"|\" for OR alternatives, e.g. \"getStateForPlacement|canSurvive|setPlacedBy\" (each token is matched as a substring, not a regex).";
|
|
218
|
+
export declare const memberProjectionSchema: z.ZodEnum<["names", "signatures", "full"]>;
|
|
219
|
+
export declare const MEMBER_PROJECTION_DESCRIPTION = "Per-member field projection: \"names\" (member name only), \"signatures\" (name + javaSignature, no jvmDescriptor), or \"full\" (default; complete member shape). Use \"names\"/\"signatures\" to cut response tokens for existence/signature checks.";
|
|
217
220
|
export declare const SIGNATURE_MODE_DESCRIPTION = "exact: descriptor required for kind=method; name-only (default): match by owner+name only.";
|
|
218
|
-
export declare const NAME_MODE_DESCRIPTION = "auto (default):
|
|
221
|
+
export declare const NAME_MODE_DESCRIPTION = "auto (default): FQCN, or dotless name where allowed; fqcn: require FQCN.";
|
|
219
222
|
export declare const listVersionsShape: {
|
|
220
223
|
includeSnapshots: z.ZodDefault<z.ZodBoolean>;
|
|
221
224
|
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -850,6 +853,7 @@ export declare const getClassMembersShape: {
|
|
|
850
853
|
includeSynthetic: z.ZodDefault<z.ZodBoolean>;
|
|
851
854
|
includeInherited: z.ZodDefault<z.ZodBoolean>;
|
|
852
855
|
memberPattern: z.ZodOptional<z.ZodString>;
|
|
856
|
+
projection: z.ZodOptional<z.ZodEnum<["names", "signatures", "full"]>>;
|
|
853
857
|
maxMembers: z.ZodOptional<z.ZodNumber>;
|
|
854
858
|
cursor: z.ZodOptional<z.ZodString>;
|
|
855
859
|
projectPath: z.ZodOptional<z.ZodString>;
|
|
@@ -938,6 +942,7 @@ export declare const getClassMembersSchema: z.ZodObject<{
|
|
|
938
942
|
includeSynthetic: z.ZodDefault<z.ZodBoolean>;
|
|
939
943
|
includeInherited: z.ZodDefault<z.ZodBoolean>;
|
|
940
944
|
memberPattern: z.ZodOptional<z.ZodString>;
|
|
945
|
+
projection: z.ZodOptional<z.ZodEnum<["names", "signatures", "full"]>>;
|
|
941
946
|
maxMembers: z.ZodOptional<z.ZodNumber>;
|
|
942
947
|
cursor: z.ZodOptional<z.ZodString>;
|
|
943
948
|
projectPath: z.ZodOptional<z.ZodString>;
|
|
@@ -992,6 +997,7 @@ export declare const getClassMembersSchema: z.ZodObject<{
|
|
|
992
997
|
memberPattern?: string | undefined;
|
|
993
998
|
include?: ("entries" | "workspace" | "warnings" | "source" | "registry" | "preview" | "files" | "samples" | "timings" | "issues" | "recovery" | "paths" | "members" | "provenance" | "artifact" | "candidates" | "classes" | "timeline" | "descriptors" | "diff" | "matrix" | "health" | "owners" | "cacheEntries")[] | undefined;
|
|
994
999
|
gradleUserHome?: string | undefined;
|
|
1000
|
+
projection?: "full" | "names" | "signatures" | undefined;
|
|
995
1001
|
}, {
|
|
996
1002
|
className: string;
|
|
997
1003
|
target: {
|
|
@@ -1034,6 +1040,7 @@ export declare const getClassMembersSchema: z.ZodObject<{
|
|
|
1034
1040
|
include?: ("entries" | "workspace" | "warnings" | "source" | "registry" | "preview" | "files" | "samples" | "timings" | "issues" | "recovery" | "paths" | "members" | "provenance" | "artifact" | "candidates" | "classes" | "timeline" | "descriptors" | "diff" | "matrix" | "health" | "owners" | "cacheEntries")[] | undefined;
|
|
1035
1041
|
gradleUserHome?: string | undefined;
|
|
1036
1042
|
includeProvenance?: boolean | undefined;
|
|
1043
|
+
projection?: "full" | "names" | "signatures" | undefined;
|
|
1037
1044
|
includeDescriptors?: boolean | undefined;
|
|
1038
1045
|
}>;
|
|
1039
1046
|
export declare const verifyMixinTargetMemberSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
@@ -1811,6 +1818,7 @@ export declare const batchClassMembersShape: {
|
|
|
1811
1818
|
concurrency: z.ZodOptional<z.ZodNumber>;
|
|
1812
1819
|
failFast: z.ZodOptional<z.ZodBoolean>;
|
|
1813
1820
|
detail: z.ZodDefault<z.ZodEnum<["summary", "standard", "full"]>>;
|
|
1821
|
+
projection: z.ZodOptional<z.ZodEnum<["names", "signatures", "full"]>>;
|
|
1814
1822
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<["warnings", "provenance", "candidates", "members", "descriptors", "source", "files", "samples", "diff", "issues", "timeline", "matrix", "entries", "workspace", "health", "recovery", "paths", "owners", "preview", "cacheEntries", "timings", "artifact", "classes", "registry"]>, "many">>;
|
|
1815
1823
|
entries: z.ZodArray<z.ZodObject<{
|
|
1816
1824
|
className: z.ZodString;
|
|
@@ -1905,6 +1913,7 @@ export declare const batchClassMembersSchema: z.ZodObject<{
|
|
|
1905
1913
|
concurrency: z.ZodOptional<z.ZodNumber>;
|
|
1906
1914
|
failFast: z.ZodOptional<z.ZodBoolean>;
|
|
1907
1915
|
detail: z.ZodDefault<z.ZodEnum<["summary", "standard", "full"]>>;
|
|
1916
|
+
projection: z.ZodOptional<z.ZodEnum<["names", "signatures", "full"]>>;
|
|
1908
1917
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<["warnings", "provenance", "candidates", "members", "descriptors", "source", "files", "samples", "diff", "issues", "timeline", "matrix", "entries", "workspace", "health", "recovery", "paths", "owners", "preview", "cacheEntries", "timings", "artifact", "classes", "registry"]>, "many">>;
|
|
1909
1918
|
entries: z.ZodArray<z.ZodObject<{
|
|
1910
1919
|
className: z.ZodString;
|
|
@@ -1967,6 +1976,7 @@ export declare const batchClassMembersSchema: z.ZodObject<{
|
|
|
1967
1976
|
sourcePriority?: "loom-first" | "maven-first" | undefined;
|
|
1968
1977
|
include?: ("entries" | "workspace" | "warnings" | "source" | "registry" | "preview" | "files" | "samples" | "timings" | "issues" | "recovery" | "paths" | "members" | "provenance" | "artifact" | "candidates" | "classes" | "timeline" | "descriptors" | "diff" | "matrix" | "health" | "owners" | "cacheEntries")[] | undefined;
|
|
1969
1978
|
gradleUserHome?: string | undefined;
|
|
1979
|
+
projection?: "full" | "names" | "signatures" | undefined;
|
|
1970
1980
|
concurrency?: number | undefined;
|
|
1971
1981
|
failFast?: boolean | undefined;
|
|
1972
1982
|
}, {
|
|
@@ -2008,6 +2018,7 @@ export declare const batchClassMembersSchema: z.ZodObject<{
|
|
|
2008
2018
|
detail?: "summary" | "standard" | "full" | undefined;
|
|
2009
2019
|
include?: ("entries" | "workspace" | "warnings" | "source" | "registry" | "preview" | "files" | "samples" | "timings" | "issues" | "recovery" | "paths" | "members" | "provenance" | "artifact" | "candidates" | "classes" | "timeline" | "descriptors" | "diff" | "matrix" | "health" | "owners" | "cacheEntries")[] | undefined;
|
|
2010
2020
|
gradleUserHome?: string | undefined;
|
|
2021
|
+
projection?: "full" | "names" | "signatures" | undefined;
|
|
2011
2022
|
concurrency?: number | undefined;
|
|
2012
2023
|
failFast?: boolean | undefined;
|
|
2013
2024
|
}>;
|