@adhisang/minecraft-modding-mcp 1.2.0 → 2.0.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.
@@ -33,6 +33,12 @@ export interface SearchFileCandidateResult {
33
33
  export interface SearchFilesWithContentResult extends SearchFilesResult {
34
34
  content: string;
35
35
  }
36
+ export interface FileContentPrefixRow {
37
+ artifactId: string;
38
+ filePath: string;
39
+ contentPrefix: string;
40
+ truncated: boolean;
41
+ }
36
42
  export interface ListFileRowsOptions {
37
43
  limit: number;
38
44
  cursor?: string;
@@ -50,6 +56,7 @@ export declare class FilesRepo {
50
56
  private readonly searchPathStmt;
51
57
  private readonly searchFtsStmt;
52
58
  private readonly getByPathsStmtCache;
59
+ private readonly getPrefixByPathsStmtCache;
53
60
  constructor(db: SqliteDatabase);
54
61
  clearFilesForArtifact(artifactId: string): void;
55
62
  insertFilesForArtifact(artifactId: string, files: IndexedFile[]): void;
@@ -59,6 +66,7 @@ export declare class FilesRepo {
59
66
  listFiles(artifactId: string, options: ListFilesOptions): PagedResult<string>;
60
67
  listFileRows(artifactId: string, options: ListFileRowsOptions): PagedResult<FileRow>;
61
68
  getFileContentsByPaths(artifactId: string, filePaths: string[]): FileRow[];
69
+ getFileContentPrefixesByPaths(artifactId: string, filePaths: string[], maxChars: number): FileContentPrefixRow[];
62
70
  searchFileCandidates(artifactId: string, options: SearchFilesOptions): PagedResult<SearchFileCandidateResult> & {
63
71
  scannedRows: number;
64
72
  dbRoundtrips: number;
@@ -74,5 +82,6 @@ export declare class FilesRepo {
74
82
  totalContentBytes(): number;
75
83
  contentBytesForArtifact(artifactId: string): number;
76
84
  private getFileContentsByPathsStmt;
85
+ private getFileContentPrefixesByPathsStmt;
77
86
  }
78
87
  export {};
@@ -114,6 +114,7 @@ export class FilesRepo {
114
114
  searchPathStmt;
115
115
  searchFtsStmt;
116
116
  getByPathsStmtCache = new Map();
117
+ getPrefixByPathsStmtCache = new Map();
117
118
  constructor(db) {
118
119
  this.db = db;
119
120
  this.deleteStmt = this.db.prepare(`
@@ -249,6 +250,27 @@ export class FilesRepo {
249
250
  ]));
250
251
  return uniquePaths.map((path) => byPath.get(path)).filter((row) => row != null);
251
252
  }
253
+ getFileContentPrefixesByPaths(artifactId, filePaths, maxChars) {
254
+ if (filePaths.length === 0) {
255
+ return [];
256
+ }
257
+ const normalizedMaxChars = Math.max(1, Math.trunc(maxChars));
258
+ const uniquePaths = [...new Set(filePaths)];
259
+ const stmt = this.getFileContentPrefixesByPathsStmt(uniquePaths.length, normalizedMaxChars);
260
+ const rows = stmt.all(normalizedMaxChars, artifactId, ...uniquePaths);
261
+ const byPath = new Map(rows.map((row) => [
262
+ row.file_path,
263
+ {
264
+ artifactId: row.artifact_id,
265
+ filePath: row.file_path,
266
+ contentPrefix: row.content_prefix,
267
+ truncated: row.content_length > row.content_prefix.length
268
+ }
269
+ ]));
270
+ return uniquePaths
271
+ .map((path) => byPath.get(path))
272
+ .filter((row) => row != null);
273
+ }
252
274
  searchFileCandidates(artifactId, options) {
253
275
  const normalized = options.query.trim();
254
276
  if (!normalized) {
@@ -460,5 +482,25 @@ export class FilesRepo {
460
482
  this.getByPathsStmtCache.set(normalizedCount, stmt);
461
483
  return stmt;
462
484
  }
485
+ getFileContentPrefixesByPathsStmt(pathCount, maxChars) {
486
+ const normalizedCount = Math.max(1, Math.trunc(pathCount));
487
+ const normalizedMaxChars = Math.max(1, Math.trunc(maxChars));
488
+ const cacheKey = `${normalizedCount}:${normalizedMaxChars}`;
489
+ const cached = this.getPrefixByPathsStmtCache.get(cacheKey);
490
+ if (cached) {
491
+ return cached;
492
+ }
493
+ if (this.getPrefixByPathsStmtCache.size >= 128) {
494
+ this.getPrefixByPathsStmtCache.clear();
495
+ }
496
+ const placeholders = Array.from({ length: normalizedCount }, () => "?").join(", ");
497
+ const stmt = this.db.prepare(`
498
+ SELECT artifact_id, file_path, substr(content, 1, ?) AS content_prefix, length(content) AS content_length
499
+ FROM files
500
+ WHERE artifact_id = ? AND file_path IN (${placeholders})
501
+ `);
502
+ this.getPrefixByPathsStmtCache.set(cacheKey, stmt);
503
+ return stmt;
504
+ }
463
505
  }
464
506
  //# sourceMappingURL=files-repo.js.map
@@ -6,6 +6,6 @@ type MigrationRunner = {
6
6
  };
7
7
  transaction<T>(fn: () => T): () => T;
8
8
  };
9
- export declare const LATEST_SCHEMA_VERSION = 1;
9
+ export declare const LATEST_SCHEMA_VERSION = 2;
10
10
  export declare function runMigrations(db: MigrationRunner): number;
11
11
  export {};
@@ -1,10 +1,14 @@
1
1
  import { createError, ERROR_CODES } from "../errors.js";
2
- import { SCHEMA_V1_STATEMENTS } from "./schema.js";
3
- export const LATEST_SCHEMA_VERSION = 1;
2
+ import { SCHEMA_V1_STATEMENTS, SCHEMA_V2_STATEMENTS } from "./schema.js";
3
+ export const LATEST_SCHEMA_VERSION = 2;
4
4
  const migrations = [
5
5
  {
6
6
  version: 1,
7
7
  statements: SCHEMA_V1_STATEMENTS
8
+ },
9
+ {
10
+ version: 2,
11
+ statements: SCHEMA_V2_STATEMENTS
8
12
  }
9
13
  ];
10
14
  function selectSchemaVersion(tx) {
@@ -1 +1,2 @@
1
1
  export declare const SCHEMA_V1_STATEMENTS: string[];
2
+ export declare const SCHEMA_V2_STATEMENTS: string[];
@@ -157,4 +157,11 @@ export const SCHEMA_V1_STATEMENTS = [
157
157
  );
158
158
  END`
159
159
  ];
160
+ export const SCHEMA_V2_STATEMENTS = [
161
+ `DELETE FROM symbols`,
162
+ `DELETE FROM files`,
163
+ `DELETE FROM artifact_content_bytes`,
164
+ `DELETE FROM artifact_index_meta`,
165
+ `DELETE FROM artifacts`
166
+ ];
160
167
  //# sourceMappingURL=schema.js.map
@@ -0,0 +1,6 @@
1
+ export type PreparedToolInput = {
2
+ normalizedInput: unknown;
3
+ removedOfficialPaths: string[];
4
+ suggestedReplacementInput?: Record<string, unknown>;
5
+ };
6
+ export declare function prepareToolInput(rawInput: unknown): PreparedToolInput;
@@ -0,0 +1,64 @@
1
+ const POSITIVE_INT_FIELD_NAMES = new Set([
2
+ "limit",
3
+ "startLine",
4
+ "endLine",
5
+ "maxLines",
6
+ "maxChars",
7
+ "maxMembers",
8
+ "maxBytes",
9
+ "maxVersions",
10
+ "maxClassResults"
11
+ ]);
12
+ const MAPPING_FIELD_NAMES = new Set(["mapping", "sourceMapping", "targetMapping", "classNameMapping"]);
13
+ function coerceTopLevelNumericStrings(value) {
14
+ if (typeof value !== "object" || value == null || Array.isArray(value)) {
15
+ return value;
16
+ }
17
+ const output = {};
18
+ for (const [key, entry] of Object.entries(value)) {
19
+ if (typeof entry === "string" && POSITIVE_INT_FIELD_NAMES.has(key)) {
20
+ const trimmed = entry.trim();
21
+ if (/^\d+$/.test(trimmed)) {
22
+ output[key] = Number.parseInt(trimmed, 10);
23
+ continue;
24
+ }
25
+ }
26
+ output[key] = entry;
27
+ }
28
+ return output;
29
+ }
30
+ function collectRemovedOfficialNamespacePaths(value) {
31
+ if (typeof value !== "object" || value == null || Array.isArray(value)) {
32
+ return [];
33
+ }
34
+ const matches = [];
35
+ for (const [key, entry] of Object.entries(value)) {
36
+ if (typeof entry === "string" && MAPPING_FIELD_NAMES.has(key) && entry.trim() === "official") {
37
+ matches.push(key);
38
+ }
39
+ }
40
+ return matches;
41
+ }
42
+ function replaceRemovedOfficialMappings(value) {
43
+ if (typeof value !== "object" || value == null || Array.isArray(value)) {
44
+ return undefined;
45
+ }
46
+ const output = {};
47
+ for (const [key, entry] of Object.entries(value)) {
48
+ output[key] =
49
+ typeof entry === "string" && MAPPING_FIELD_NAMES.has(key) && entry.trim() === "official"
50
+ ? "obfuscated"
51
+ : entry;
52
+ }
53
+ return output;
54
+ }
55
+ export function prepareToolInput(rawInput) {
56
+ const normalizedInput = coerceTopLevelNumericStrings(rawInput);
57
+ const removedOfficialPaths = collectRemovedOfficialNamespacePaths(normalizedInput);
58
+ return {
59
+ normalizedInput,
60
+ removedOfficialPaths,
61
+ suggestedReplacementInput: removedOfficialPaths.length > 0 ? replaceRemovedOfficialMappings(normalizedInput) : undefined
62
+ };
63
+ }
64
+ //# sourceMappingURL=tool-input.js.map
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type SourceOrigin = "local-jar" | "local-m2" | "remote-repo" | "decompiled";
2
- export type SourceMapping = "official" | "mojang" | "intermediary" | "yarn";
2
+ export type SourceMapping = "obfuscated" | "mojang" | "intermediary" | "yarn";
3
3
  export type MappingSourcePriority = "loom-first" | "maven-first";
4
4
  export type ArtifactTargetKind = "version" | "jar" | "coordinate";
5
5
  export type ArtifactScope = "vanilla" | "merged" | "loader";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhisang/minecraft-modding-mcp",
3
- "version": "1.2.0",
3
+ "version": "2.0.0",
4
4
  "description": "MCP server with utilities for Minecraft modding workflows",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -39,6 +39,9 @@
39
39
  ],
40
40
  "author": "adhi-jp",
41
41
  "license": "MIT",
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
42
45
  "repository": "github:adhi-jp/minecraft-modding-mcp",
43
46
  "bugs": "https://github.com/adhi-jp/minecraft-modding-mcp/issues",
44
47
  "homepage": "https://github.com/adhi-jp/minecraft-modding-mcp#readme",