@adhisang/minecraft-modding-mcp 7.0.0 → 7.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +72 -0
- package/README.md +4 -3
- package/dist/access-transformer-parser.d.ts +8 -0
- package/dist/access-transformer-parser.js +8 -1
- package/dist/access-widener-parser.d.ts +17 -0
- package/dist/access-widener-parser.js +12 -1
- package/dist/cache-registry.js +19 -6
- package/dist/entry-tools/analyze-mod-service.d.ts +2 -2
- package/dist/entry-tools/analyze-symbol-service.d.ts +2 -2
- package/dist/entry-tools/batch-class-members-service.d.ts +3 -2
- package/dist/entry-tools/batch-class-members-service.js +20 -6
- package/dist/entry-tools/batch-class-source-service.d.ts +3 -2
- package/dist/entry-tools/batch-class-source-service.js +10 -0
- package/dist/entry-tools/compare-minecraft-service.d.ts +27 -4
- package/dist/entry-tools/compare-minecraft-service.js +65 -4
- package/dist/entry-tools/entry-tool-schema.d.ts +2 -2
- package/dist/entry-tools/inspect-minecraft/handlers/versions.js +15 -9
- package/dist/entry-tools/inspect-minecraft-service.d.ts +2 -2
- package/dist/entry-tools/manage-cache-service.d.ts +2 -2
- package/dist/entry-tools/manage-cache-service.js +10 -14
- package/dist/entry-tools/validate-project/cases/access-transformer.js +22 -3
- package/dist/entry-tools/validate-project/cases/access-widener.js +31 -4
- package/dist/entry-tools/validate-project/cases/mixin.js +11 -3
- package/dist/entry-tools/validate-project/cases/project-summary.js +94 -16
- package/dist/entry-tools/validate-project-service.d.ts +2 -2
- package/dist/entry-tools/verify-mixin-target-service.js +19 -8
- package/dist/index.js +38 -15
- package/dist/java-process.d.ts +1 -0
- package/dist/java-process.js +14 -0
- package/dist/mapping/lookup.js +16 -1
- package/dist/mapping-service.d.ts +14 -0
- package/dist/mapping-service.js +35 -15
- package/dist/minecraft-explorer-service.js +70 -8
- package/dist/mixin/access-validators.js +38 -2
- package/dist/mixin/annotation-validators.js +137 -43
- package/dist/mixin/parsed-validator.js +21 -7
- package/dist/mixin-parser.d.ts +52 -0
- package/dist/mixin-parser.js +709 -130
- package/dist/mod-decompile-service.js +11 -1
- package/dist/mod-remap-service.js +6 -6
- package/dist/nbt/java-nbt-codec.js +7 -1
- package/dist/source/access-validate.js +10 -0
- package/dist/source/artifact-resolver.d.ts +27 -3
- package/dist/source/artifact-resolver.js +235 -30
- package/dist/source/class-source/members-builder.d.ts +7 -0
- package/dist/source/class-source/members-builder.js +4 -1
- package/dist/source/class-source.d.ts +9 -2
- package/dist/source/class-source.js +186 -27
- package/dist/source/indexer.js +69 -1
- package/dist/source/lifecycle/mapping-helpers.d.ts +20 -1
- package/dist/source/lifecycle/mapping-helpers.js +29 -3
- package/dist/source/lifecycle/runtime-check.d.ts +25 -0
- package/dist/source/lifecycle/runtime-check.js +68 -39
- package/dist/source/nested-jars.d.ts +15 -1
- package/dist/source/nested-jars.js +14 -5
- package/dist/source/search.d.ts +10 -2
- package/dist/source/search.js +60 -13
- package/dist/source/symbol-resolver.js +88 -0
- package/dist/source/validate-mixin/pipeline/mapping-health.js +20 -1
- package/dist/source/validate-mixin/pipeline/target-lookup.js +16 -7
- package/dist/source/validate-mixin.d.ts +5 -0
- package/dist/source/validate-mixin.js +136 -21
- package/dist/source/workspace-target.js +75 -7
- package/dist/source-jar-reader.d.ts +48 -1
- package/dist/source-jar-reader.js +93 -3
- package/dist/source-resolver.d.ts +7 -0
- package/dist/source-resolver.js +22 -14
- package/dist/source-service.d.ts +5 -0
- package/dist/source-service.js +7 -0
- package/dist/stdio-supervisor.d.ts +35 -1
- package/dist/stdio-supervisor.js +77 -2
- package/dist/storage/db.d.ts +62 -2
- package/dist/storage/db.js +181 -20
- package/dist/storage/files-repo.d.ts +7 -0
- package/dist/storage/files-repo.js +17 -4
- package/dist/storage/sqlite.d.ts +31 -1
- package/dist/storage/sqlite.js +125 -16
- package/dist/tool-contract-manifest.js +2 -2
- package/dist/tool-execution-gate.js +2 -1
- package/dist/tool-guidance.js +4 -1
- package/dist/tool-schemas.d.ts +64 -52
- package/dist/tool-schemas.js +9 -7
- package/dist/types.d.ts +9 -0
- package/dist/v1-parity-schemas.js +36 -2
- package/dist/version-diff-service.d.ts +23 -0
- package/dist/version-diff-service.js +101 -0
- package/dist/version-service.d.ts +14 -0
- package/dist/version-service.js +52 -3
- package/dist/workspace-context-cache.d.ts +25 -0
- package/dist/workspace-context-cache.js +52 -2
- package/dist/workspace-mapping-service.d.ts +8 -0
- package/dist/workspace-mapping-service.js +151 -21
- package/docs/README-ja.md +3 -1
- package/docs/tool-reference.md +69 -22
- package/package.json +1 -1
|
@@ -108,6 +108,15 @@ function buildPreview(content, query) {
|
|
|
108
108
|
function tokenizeIndexedQuery(query) {
|
|
109
109
|
return query.match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
110
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Quote a token so FTS5 reads it as a string literal instead of grammar. Real
|
|
113
|
+
* Minecraft identifiers tokenize into operator keywords (`BooleanOp.AND` ->
|
|
114
|
+
* `BooleanOp AND`), which unquoted is either a syntax error or - mid-query, as
|
|
115
|
+
* in `a NOT b` - a silent change of meaning.
|
|
116
|
+
*/
|
|
117
|
+
function quoteIndexedToken(token) {
|
|
118
|
+
return `"${token.replace(/"/g, '""')}"`;
|
|
119
|
+
}
|
|
111
120
|
function buildIndexedMatchQuery(query, match) {
|
|
112
121
|
const tokens = tokenizeIndexedQuery(query.trim());
|
|
113
122
|
if (tokens.length === 0) {
|
|
@@ -118,10 +127,11 @@ function buildIndexedMatchQuery(query, match) {
|
|
|
118
127
|
// path while SourceService re-checks hydrated path/content matches before
|
|
119
128
|
// returning hits. Callers can still use literal mode for exact substring scans.
|
|
120
129
|
return tokens.map((token, index) => {
|
|
130
|
+
const quoted = quoteIndexedToken(token);
|
|
121
131
|
if (match === "prefix" && index === tokens.length - 1) {
|
|
122
|
-
return `${
|
|
132
|
+
return `${quoted}*`;
|
|
123
133
|
}
|
|
124
|
-
return
|
|
134
|
+
return quoted;
|
|
125
135
|
}).join(" ");
|
|
126
136
|
}
|
|
127
137
|
/** Escape LIKE wildcards so the needle is matched literally under ESCAPE '\'. */
|
|
@@ -177,6 +187,7 @@ export class FilesRepo {
|
|
|
177
187
|
SELECT file_path
|
|
178
188
|
FROM files
|
|
179
189
|
WHERE artifact_id = ? AND file_path LIKE ? ESCAPE '\\'
|
|
190
|
+
AND (? IS NULL OR file_path LIKE ? ESCAPE '\\')
|
|
180
191
|
ORDER BY file_path ASC
|
|
181
192
|
LIMIT ?
|
|
182
193
|
`);
|
|
@@ -191,6 +202,7 @@ export class FilesRepo {
|
|
|
191
202
|
SELECT file_path, rank
|
|
192
203
|
FROM files_fts
|
|
193
204
|
WHERE artifact_id = ? AND files_fts MATCH ?
|
|
205
|
+
AND (? IS NULL OR file_path LIKE ? ESCAPE '\\')
|
|
194
206
|
ORDER BY rank
|
|
195
207
|
LIMIT ?
|
|
196
208
|
`);
|
|
@@ -314,6 +326,7 @@ export class FilesRepo {
|
|
|
314
326
|
const cursor = parseSearchCursor(options.cursor);
|
|
315
327
|
const likeQuery = `%${escapeLikeNeedle(normalized)}%`;
|
|
316
328
|
const ftsQuery = buildIndexedMatchQuery(normalized, options.match);
|
|
329
|
+
const scopePattern = options.pathPrefix ? `${escapeLikeNeedle(options.pathPrefix)}%` : null;
|
|
317
330
|
const mode = options.mode ?? "mixed";
|
|
318
331
|
// Cursor-adaptive fetch limit: when no cursor, use a generous limit;
|
|
319
332
|
// with cursor + SQL pushdown, we need far fewer rows.
|
|
@@ -325,7 +338,7 @@ export class FilesRepo {
|
|
|
325
338
|
const includePath = mode !== "text" && !cursorExhausted;
|
|
326
339
|
const includeContent = mode !== "path" && !cursorExhausted;
|
|
327
340
|
const pathRows = includePath
|
|
328
|
-
? this.searchPathStmt.all(artifactId, likeQuery, fetchLimit)
|
|
341
|
+
? this.searchPathStmt.all(artifactId, likeQuery, scopePattern, scopePattern, fetchLimit)
|
|
329
342
|
: [];
|
|
330
343
|
const merged = pathRows.map((row) => ({
|
|
331
344
|
filePath: row.file_path,
|
|
@@ -336,7 +349,7 @@ export class FilesRepo {
|
|
|
336
349
|
let contentRows = [];
|
|
337
350
|
if (includeContent && ftsQuery) {
|
|
338
351
|
try {
|
|
339
|
-
contentRows = this.searchFtsStmt.all(artifactId, ftsQuery, fetchLimit);
|
|
352
|
+
contentRows = this.searchFtsStmt.all(artifactId, ftsQuery, scopePattern, scopePattern, fetchLimit);
|
|
340
353
|
}
|
|
341
354
|
catch (error) {
|
|
342
355
|
const message = error instanceof Error ? error.message : String(error);
|
package/dist/storage/sqlite.d.ts
CHANGED
|
@@ -1,17 +1,47 @@
|
|
|
1
1
|
import { type StatementSync } from "node:sqlite";
|
|
2
|
+
/**
|
|
3
|
+
* Recognizes a raw (non-AppError) SQLite corruption error - the shape
|
|
4
|
+
* node:sqlite throws mid-query, e.g. `{ code: "ERR_SQLITE_ERROR", errcode: 11 }`.
|
|
5
|
+
* Lives here (rather than storage/db.ts, which imports this module) so the
|
|
6
|
+
* Database wrapper below can call it directly without a module cycle; db.ts
|
|
7
|
+
* re-exports it for callers that used to import it from there.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isRawSqliteCorruptionError(error: unknown): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Notified, at most once per `Database` instance, the first time a raw SQLite
|
|
12
|
+
* corruption error is thrown by any statement/pragma/transaction path on that
|
|
13
|
+
* instance. Called BEFORE the triggering error is rethrown unchanged, so it
|
|
14
|
+
* runs regardless of how (or whether) a caller further up the stack wraps or
|
|
15
|
+
* swallows that error - a wrapping catch block elsewhere in the codebase can
|
|
16
|
+
* no longer hide a runtime corruption from this observer.
|
|
17
|
+
*/
|
|
18
|
+
export type SqliteCorruptionObserver = (error: unknown) => void;
|
|
2
19
|
export declare class Statement<T = unknown> {
|
|
3
20
|
private readonly stmt;
|
|
4
|
-
|
|
21
|
+
private readonly notifyCorruption;
|
|
22
|
+
constructor(stmt: StatementSync, notifyCorruption: (error: unknown) => void);
|
|
5
23
|
run(...params: unknown[]): unknown;
|
|
6
24
|
get(...params: unknown[]): T | undefined;
|
|
7
25
|
all(...params: unknown[]): T[];
|
|
8
26
|
iterate(...params: unknown[]): Iterable<T>;
|
|
27
|
+
private wrapIterable;
|
|
9
28
|
private invoke;
|
|
10
29
|
}
|
|
11
30
|
export default class Database {
|
|
12
31
|
private readonly inner;
|
|
13
32
|
private transactionDepth;
|
|
33
|
+
private corruptionObserver;
|
|
34
|
+
private corruptionNotified;
|
|
14
35
|
constructor(path: string);
|
|
36
|
+
/**
|
|
37
|
+
* Registers (or clears, with `undefined`) the observer notified on this
|
|
38
|
+
* instance's first raw corruption error. Best-effort: an observer that
|
|
39
|
+
* throws is swallowed so it can never mask the real SQLite error being
|
|
40
|
+
* rethrown, and it fires at most once per instance.
|
|
41
|
+
*/
|
|
42
|
+
setCorruptionObserver(observer: SqliteCorruptionObserver | undefined): void;
|
|
43
|
+
private notifyCorruption;
|
|
44
|
+
private runRaw;
|
|
15
45
|
pragma(pragma: string): unknown;
|
|
16
46
|
prepare<T = Record<string, unknown>>(sql: string): Statement<T>;
|
|
17
47
|
transaction<T>(fn: () => T): () => T;
|
package/dist/storage/sqlite.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DatabaseSync } from "node:sqlite";
|
|
2
|
+
import { isAppError } from "../errors.js";
|
|
2
3
|
function isPlainObject(value) {
|
|
3
4
|
if (value === null || typeof value !== "object" || Array.isArray(value) || ArrayBuffer.isView(value)) {
|
|
4
5
|
return false;
|
|
@@ -18,10 +19,35 @@ function normalizeParameters(args) {
|
|
|
18
19
|
}
|
|
19
20
|
return { positional: args };
|
|
20
21
|
}
|
|
22
|
+
const SQLITE_CORRUPT_ERRCODE = 11;
|
|
23
|
+
const SQLITE_NOTADB_ERRCODE = 26;
|
|
24
|
+
/**
|
|
25
|
+
* Recognizes a raw (non-AppError) SQLite corruption error - the shape
|
|
26
|
+
* node:sqlite throws mid-query, e.g. `{ code: "ERR_SQLITE_ERROR", errcode: 11 }`.
|
|
27
|
+
* Lives here (rather than storage/db.ts, which imports this module) so the
|
|
28
|
+
* Database wrapper below can call it directly without a module cycle; db.ts
|
|
29
|
+
* re-exports it for callers that used to import it from there.
|
|
30
|
+
*/
|
|
31
|
+
export function isRawSqliteCorruptionError(error) {
|
|
32
|
+
if (isAppError(error)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const sqliteError = error;
|
|
36
|
+
if (sqliteError?.code === "SQLITE_CORRUPT" || sqliteError?.code === "SQLITE_NOTADB") {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
if (typeof sqliteError?.errcode !== "number") {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const primaryErrcode = sqliteError.errcode & 0xff;
|
|
43
|
+
return primaryErrcode === SQLITE_CORRUPT_ERRCODE || primaryErrcode === SQLITE_NOTADB_ERRCODE;
|
|
44
|
+
}
|
|
21
45
|
export class Statement {
|
|
22
46
|
stmt;
|
|
23
|
-
|
|
47
|
+
notifyCorruption;
|
|
48
|
+
constructor(stmt, notifyCorruption) {
|
|
24
49
|
this.stmt = stmt;
|
|
50
|
+
this.notifyCorruption = notifyCorruption;
|
|
25
51
|
}
|
|
26
52
|
run(...params) {
|
|
27
53
|
return this.invoke("run", params);
|
|
@@ -33,34 +59,116 @@ export class Statement {
|
|
|
33
59
|
return this.invoke("all", params);
|
|
34
60
|
}
|
|
35
61
|
iterate(...params) {
|
|
36
|
-
|
|
62
|
+
const rawIterable = this.invoke("iterate", params);
|
|
63
|
+
return this.wrapIterable(rawIterable);
|
|
64
|
+
}
|
|
65
|
+
// node:sqlite's iterate() returns lazily: the corrupted page is only ever
|
|
66
|
+
// touched once the consumer actually pulls a row, i.e. inside next(), not
|
|
67
|
+
// at the call above. Wrap the iterator itself so a mid-iteration corruption
|
|
68
|
+
// error still reaches the observer before propagating to the consumer.
|
|
69
|
+
wrapIterable(iterable) {
|
|
70
|
+
const notifyCorruption = this.notifyCorruption;
|
|
71
|
+
return {
|
|
72
|
+
[Symbol.iterator]() {
|
|
73
|
+
const inner = iterable[Symbol.iterator]();
|
|
74
|
+
const wrapped = {
|
|
75
|
+
next() {
|
|
76
|
+
try {
|
|
77
|
+
return inner.next();
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
notifyCorruption(error);
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
// Forward early termination (a `break` out of for...of, or a consuming
|
|
86
|
+
// generator being closed) so the underlying statement is reset instead
|
|
87
|
+
// of being left mid-iteration with its read snapshot open.
|
|
88
|
+
if (typeof inner.return === "function") {
|
|
89
|
+
wrapped.return = (value) => inner.return(value);
|
|
90
|
+
}
|
|
91
|
+
return wrapped;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
37
94
|
}
|
|
38
95
|
invoke(method, params) {
|
|
39
96
|
const normalized = normalizeParameters(params);
|
|
40
97
|
const target = this.stmt[method];
|
|
41
|
-
|
|
42
|
-
|
|
98
|
+
try {
|
|
99
|
+
if (normalized.named !== undefined) {
|
|
100
|
+
return target.call(this.stmt, normalized.named);
|
|
101
|
+
}
|
|
102
|
+
return target.call(this.stmt, ...(normalized.positional ?? []));
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
this.notifyCorruption(error);
|
|
106
|
+
throw error;
|
|
43
107
|
}
|
|
44
|
-
return target.call(this.stmt, ...(normalized.positional ?? []));
|
|
45
108
|
}
|
|
46
109
|
}
|
|
47
110
|
let transactionSerial = 0;
|
|
48
111
|
export default class Database {
|
|
49
112
|
inner;
|
|
50
113
|
transactionDepth = 0;
|
|
114
|
+
corruptionObserver;
|
|
115
|
+
corruptionNotified = false;
|
|
51
116
|
constructor(path) {
|
|
52
117
|
this.inner = new DatabaseSync(path);
|
|
53
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Registers (or clears, with `undefined`) the observer notified on this
|
|
121
|
+
* instance's first raw corruption error. Best-effort: an observer that
|
|
122
|
+
* throws is swallowed so it can never mask the real SQLite error being
|
|
123
|
+
* rethrown, and it fires at most once per instance.
|
|
124
|
+
*/
|
|
125
|
+
setCorruptionObserver(observer) {
|
|
126
|
+
this.corruptionObserver = observer;
|
|
127
|
+
}
|
|
128
|
+
notifyCorruption(error) {
|
|
129
|
+
if (this.corruptionNotified) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const observer = this.corruptionObserver;
|
|
133
|
+
if (!observer) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (!isRawSqliteCorruptionError(error)) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
this.corruptionNotified = true;
|
|
140
|
+
try {
|
|
141
|
+
observer(error);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// best-effort: never let the observer mask the real error being rethrown
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
runRaw(fn) {
|
|
148
|
+
try {
|
|
149
|
+
return fn();
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
this.notifyCorruption(error);
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
54
156
|
pragma(pragma) {
|
|
55
157
|
const sql = `PRAGMA ${pragma}`;
|
|
56
158
|
if (pragma.includes("=")) {
|
|
57
|
-
this.inner.exec(sql);
|
|
159
|
+
this.runRaw(() => this.inner.exec(sql));
|
|
58
160
|
return undefined;
|
|
59
161
|
}
|
|
60
|
-
return this.inner.prepare(sql).all();
|
|
162
|
+
return this.runRaw(() => this.inner.prepare(sql).all());
|
|
61
163
|
}
|
|
62
164
|
prepare(sql) {
|
|
63
|
-
|
|
165
|
+
// Wrapped in runRaw: PREPARING a statement can itself throw a raw
|
|
166
|
+
// corruption error - e.g. damage to the schema (sqlite_master) that a
|
|
167
|
+
// fresh connection only discovers while compiling its first statement -
|
|
168
|
+
// not just running one. Without this, that error skipped the observer
|
|
169
|
+
// entirely (reproduced: errcode 11, observer never notified).
|
|
170
|
+
const stmt = this.runRaw(() => this.inner.prepare(sql));
|
|
171
|
+
return new Statement(stmt, (error) => this.notifyCorruption(error));
|
|
64
172
|
}
|
|
65
173
|
transaction(fn) {
|
|
66
174
|
return () => this.runInTransaction(fn);
|
|
@@ -74,19 +182,19 @@ export default class Database {
|
|
|
74
182
|
const savepoint = `sp_${++transactionSerial}`;
|
|
75
183
|
try {
|
|
76
184
|
if (isOutermost) {
|
|
77
|
-
this.inner.exec("BEGIN");
|
|
185
|
+
this.runRaw(() => this.inner.exec("BEGIN"));
|
|
78
186
|
}
|
|
79
187
|
else {
|
|
80
|
-
this.inner.exec(`SAVEPOINT ${savepoint}`);
|
|
188
|
+
this.runRaw(() => this.inner.exec(`SAVEPOINT ${savepoint}`));
|
|
81
189
|
}
|
|
82
190
|
this.transactionDepth = initialDepth + 1;
|
|
83
191
|
const result = fn();
|
|
84
192
|
this.transactionDepth = initialDepth;
|
|
85
193
|
if (isOutermost) {
|
|
86
|
-
this.inner.exec("COMMIT");
|
|
194
|
+
this.runRaw(() => this.inner.exec("COMMIT"));
|
|
87
195
|
}
|
|
88
196
|
else {
|
|
89
|
-
this.inner.exec(`RELEASE SAVEPOINT ${savepoint}`);
|
|
197
|
+
this.runRaw(() => this.inner.exec(`RELEASE SAVEPOINT ${savepoint}`));
|
|
90
198
|
}
|
|
91
199
|
return result;
|
|
92
200
|
}
|
|
@@ -94,15 +202,16 @@ export default class Database {
|
|
|
94
202
|
this.transactionDepth = initialDepth;
|
|
95
203
|
try {
|
|
96
204
|
if (isOutermost) {
|
|
97
|
-
this.inner.exec("ROLLBACK");
|
|
205
|
+
this.runRaw(() => this.inner.exec("ROLLBACK"));
|
|
98
206
|
}
|
|
99
207
|
else {
|
|
100
|
-
this.inner.exec(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
101
|
-
this.inner.exec(`RELEASE SAVEPOINT ${savepoint}`);
|
|
208
|
+
this.runRaw(() => this.inner.exec(`ROLLBACK TO SAVEPOINT ${savepoint}`));
|
|
209
|
+
this.runRaw(() => this.inner.exec(`RELEASE SAVEPOINT ${savepoint}`));
|
|
102
210
|
}
|
|
103
211
|
}
|
|
104
212
|
catch {
|
|
105
|
-
// best-effort rollback cleanup
|
|
213
|
+
// best-effort rollback cleanup - runRaw already notified the
|
|
214
|
+
// observer (if any) before this catch swallows the rollback failure
|
|
106
215
|
}
|
|
107
216
|
throw error;
|
|
108
217
|
}
|
|
@@ -17,7 +17,7 @@ const SECTION_ROWS = {
|
|
|
17
17
|
"| `compare-minecraft` | Compare version pairs, class diffs, registry diffs, and migration-oriented summaries |",
|
|
18
18
|
"| `analyze-mod` | Summarize mod metadata, decompile and search mod code, inspect class source, read class members from bytecode, and preview or apply remaps |",
|
|
19
19
|
"| `validate-project` | Summarize workspaces and run direct Mixin, Access Widener, or Access Transformer validation |",
|
|
20
|
-
"| `manage-cache` | List, verify, and preview or apply cache cleanup
|
|
20
|
+
"| `manage-cache` | List, verify, and preview or apply cache cleanup operations |"
|
|
21
21
|
],
|
|
22
22
|
ja: [
|
|
23
23
|
"| `inspect-minecraft` | バージョン、アーティファクト、クラス、ファイル、ソース本文、ワークスペース文脈の調査フローをまとめて扱う |",
|
|
@@ -25,7 +25,7 @@ const SECTION_ROWS = {
|
|
|
25
25
|
"| `compare-minecraft` | バージョン差分、クラス差分、レジストリ差分、移行向け概要を比較する |",
|
|
26
26
|
"| `analyze-mod` | Mod メタデータの要約、Mod コードのデコンパイル / 検索、クラスソース確認、リマップのプレビュー / 実行を扱う |",
|
|
27
27
|
"| `validate-project` | ワークスペース要約と、Mixin / Access Widener / Access Transformer の直接検証を行う |",
|
|
28
|
-
"| `manage-cache` |
|
|
28
|
+
"| `manage-cache` | キャッシュの一覧、検証、クリーンアップのプレビュー / 実行を行う |"
|
|
29
29
|
]
|
|
30
30
|
},
|
|
31
31
|
"source-exploration": {
|
|
@@ -4,7 +4,8 @@ const DEFAULT_OPTIONS = {
|
|
|
4
4
|
maxQueue: 2
|
|
5
5
|
};
|
|
6
6
|
// Heavy tools that have a batch equivalent able to collapse many same-kind
|
|
7
|
-
// queries into
|
|
7
|
+
// queries into one call. The batch-* tools are NOT in the heavy set, so that
|
|
8
|
+
// one call bypasses this gate entirely. Used to point overflow guidance at the
|
|
8
9
|
// right batch-* tool instead of just telling the caller to retry serially.
|
|
9
10
|
const BATCH_EQUIVALENTS = {
|
|
10
11
|
"find-mapping": "batch-mappings",
|
package/dist/tool-guidance.js
CHANGED
|
@@ -800,7 +800,10 @@ export function buildValidateProjectSuggestedParams(normalizedInput) {
|
|
|
800
800
|
for (const field of booleanFields) {
|
|
801
801
|
const value = record[field];
|
|
802
802
|
if (typeof value === "boolean" &&
|
|
803
|
-
|
|
803
|
+
// project-summary infers an omitted version, so an explicit
|
|
804
|
+
// preferProjectVersion=false is an opt-out, not a droppable default.
|
|
805
|
+
(field === "preferProjectVersion" ||
|
|
806
|
+
!Object.prototype.hasOwnProperty.call(SUGGESTED_CALL_DEFAULTS, field) ||
|
|
804
807
|
!isSuggestedCallDefault(field, value))) {
|
|
805
808
|
result[field] = value;
|
|
806
809
|
}
|