@adhisang/minecraft-modding-mcp 3.1.0 → 3.2.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 +62 -34
- package/README.md +79 -100
- package/dist/access-transformer-parser.d.ts +17 -0
- package/dist/access-transformer-parser.js +97 -0
- package/dist/concurrency.d.ts +1 -0
- package/dist/concurrency.js +24 -0
- package/dist/config.js +19 -11
- package/dist/decompiler/vineflower.js +22 -21
- package/dist/entry-tools/analyze-mod-service.d.ts +4 -4
- package/dist/entry-tools/analyze-symbol-service.d.ts +22 -20
- package/dist/entry-tools/analyze-symbol-service.js +6 -3
- package/dist/entry-tools/inspect-minecraft-service.d.ts +166 -149
- package/dist/entry-tools/inspect-minecraft-service.js +318 -55
- package/dist/entry-tools/validate-project-service.d.ts +153 -16
- package/dist/entry-tools/validate-project-service.js +360 -23
- package/dist/gradle-paths.d.ts +4 -0
- package/dist/gradle-paths.js +57 -0
- package/dist/index.js +274 -13
- package/dist/mapping-pipeline-service.d.ts +3 -1
- package/dist/mapping-pipeline-service.js +16 -1
- package/dist/mapping-service.d.ts +5 -0
- package/dist/mapping-service.js +200 -84
- package/dist/minecraft-explorer-service.d.ts +13 -0
- package/dist/minecraft-explorer-service.js +8 -4
- package/dist/mixin-validator.d.ts +33 -2
- package/dist/mixin-validator.js +197 -11
- package/dist/mod-analyzer.d.ts +1 -0
- package/dist/mod-analyzer.js +17 -1
- package/dist/mod-decompile-service.js +4 -4
- package/dist/mod-remap-service.js +1 -54
- package/dist/mod-search-service.d.ts +1 -0
- package/dist/mod-search-service.js +84 -51
- package/dist/response-utils.d.ts +35 -0
- package/dist/response-utils.js +113 -0
- package/dist/source-jar-reader.d.ts +16 -0
- package/dist/source-jar-reader.js +103 -1
- package/dist/source-resolver.js +9 -10
- package/dist/source-service.d.ts +24 -2
- package/dist/source-service.js +1052 -139
- package/dist/tool-contract-manifest.js +74 -74
- package/dist/types.d.ts +17 -0
- package/dist/workspace-mapping-service.d.ts +13 -0
- package/dist/workspace-mapping-service.js +146 -14
- package/package.json +1 -1
|
@@ -11,128 +11,128 @@ export const TOOL_SURFACE_SECTION_IDS = [
|
|
|
11
11
|
const SECTION_ROWS = {
|
|
12
12
|
"v3-entry-tools": {
|
|
13
13
|
en: [
|
|
14
|
-
"| `inspect-minecraft` |
|
|
15
|
-
"| `analyze-symbol` |
|
|
16
|
-
"| `compare-minecraft` | Compare version pairs, class
|
|
17
|
-
"| `analyze-mod` |
|
|
18
|
-
"| `validate-project` |
|
|
19
|
-
"| `manage-cache` |
|
|
14
|
+
"| `inspect-minecraft` | Inspect versions, artifacts, classes, files, source text, and workspace-aware lookup flows |",
|
|
15
|
+
"| `analyze-symbol` | Handle symbol existence checks, namespace mapping, lifecycle tracing, workspace symbol resolution, and API overviews |",
|
|
16
|
+
"| `compare-minecraft` | Compare version pairs, class diffs, registry diffs, and migration-oriented summaries |",
|
|
17
|
+
"| `analyze-mod` | Summarize mod metadata, decompile and search mod code, inspect class source, and preview or apply remaps |",
|
|
18
|
+
"| `validate-project` | Summarize workspaces and run direct Mixin, Access Widener, or Access Transformer validation |",
|
|
19
|
+
"| `manage-cache` | List, verify, and preview or apply cache cleanup and rebuild operations |"
|
|
20
20
|
],
|
|
21
21
|
ja: [
|
|
22
|
-
"| `inspect-minecraft` |
|
|
23
|
-
"| `analyze-symbol` |
|
|
24
|
-
"| `compare-minecraft` |
|
|
25
|
-
"| `analyze-mod` | Mod
|
|
26
|
-
"| `validate-project` | ワークスペース要約と、Mixin / Access Widener
|
|
27
|
-
"| `manage-cache` |
|
|
22
|
+
"| `inspect-minecraft` | バージョン、アーティファクト、クラス、ファイル、ソース本文、ワークスペース文脈の調査フローをまとめて扱う |",
|
|
23
|
+
"| `analyze-symbol` | シンボル存在確認、名前空間変換、ライフサイクル追跡、ワークスペースシンボル解決、API 概要をまとめて扱う |",
|
|
24
|
+
"| `compare-minecraft` | バージョン差分、クラス差分、レジストリ差分、移行向け概要を比較する |",
|
|
25
|
+
"| `analyze-mod` | Mod メタデータの要約、Mod コードのデコンパイル / 検索、クラスソース確認、リマップのプレビュー / 実行を扱う |",
|
|
26
|
+
"| `validate-project` | ワークスペース要約と、Mixin / Access Widener / Access Transformer の直接検証を行う |",
|
|
27
|
+
"| `manage-cache` | キャッシュの一覧、検証、クリーンアップ / 再構築のプレビュー / 実行を行う |"
|
|
28
28
|
]
|
|
29
29
|
},
|
|
30
30
|
"source-exploration": {
|
|
31
31
|
en: [
|
|
32
|
-
"| `list-versions` | List available Minecraft versions from Mojang
|
|
33
|
-
"| `resolve-artifact` | Resolve source
|
|
34
|
-
"| `find-class` |
|
|
35
|
-
"| `get-class-source` |
|
|
36
|
-
"| `get-class-members` |
|
|
37
|
-
"| `search-class-source` | Search indexed class source
|
|
38
|
-
"| `get-artifact-file` | Read full source file with byte
|
|
39
|
-
"| `list-artifact-files` | List indexed source file paths with cursor pagination |
|
|
40
|
-
"| `index-artifact` | Rebuild
|
|
32
|
+
"| `list-versions` | List available Minecraft versions from Mojang metadata and local cache |",
|
|
33
|
+
"| `resolve-artifact` | Resolve source artifacts from versions, JAR paths, or Maven coordinates |",
|
|
34
|
+
"| `find-class` | Find simple or fully-qualified class names inside an artifact |",
|
|
35
|
+
"| `get-class-source` | Read class source from an artifact or resolve the backing artifact on demand |",
|
|
36
|
+
"| `get-class-members` | List constructors, fields, and methods from bytecode |",
|
|
37
|
+
"| `search-class-source` | Search indexed class source by symbol, text, or path |",
|
|
38
|
+
"| `get-artifact-file` | Read a full source file with a byte limit |",
|
|
39
|
+
"| `list-artifact-files` | List indexed source file paths with cursor pagination |",
|
|
40
|
+
"| `index-artifact` | Rebuild indexed metadata for an existing artifact |"
|
|
41
41
|
],
|
|
42
42
|
ja: [
|
|
43
|
-
"| `list-versions` | Mojang
|
|
44
|
-
"| `resolve-artifact` |
|
|
45
|
-
"| `find-class` |
|
|
46
|
-
"| `get-class-source` |
|
|
47
|
-
"| `get-class-members` |
|
|
48
|
-
"| `search-class-source` |
|
|
49
|
-
"| `get-artifact-file` | バイト上限付きでソースファイル全体を読み取る |
|
|
50
|
-
"| `list-artifact-files` |
|
|
51
|
-
"| `index-artifact` |
|
|
43
|
+
"| `list-versions` | Mojang メタデータとローカルキャッシュから利用可能な Minecraft バージョンを一覧表示する |",
|
|
44
|
+
"| `resolve-artifact` | バージョン、JAR パス、Maven 座標からソースアーティファクトを解決する |",
|
|
45
|
+
"| `find-class` | アーティファクト内で簡易名または完全修飾クラス名を探す |",
|
|
46
|
+
"| `get-class-source` | アーティファクトからクラスソースを読み取り、必要に応じて背後のアーティファクトを解決する |",
|
|
47
|
+
"| `get-class-members` | バイトコードからコンストラクタ、フィールド、メソッドを一覧化する |",
|
|
48
|
+
"| `search-class-source` | インデックス化されたクラスソースをシンボル、テキスト、パスで検索する |",
|
|
49
|
+
"| `get-artifact-file` | バイト上限付きでソースファイル全体を読み取る |",
|
|
50
|
+
"| `list-artifact-files` | インデックス化されたソースファイルパスをカーソルページネーション付きで一覧表示する |",
|
|
51
|
+
"| `index-artifact` | 既存アーティファクトのインデックスメタデータを再構築する |"
|
|
52
52
|
]
|
|
53
53
|
},
|
|
54
54
|
"version-comparison-symbol-tracking": {
|
|
55
55
|
en: [
|
|
56
|
-
"| `trace-symbol-lifecycle` | Trace when `Class.method` exists across Minecraft versions
|
|
57
|
-
"| `diff-class-signatures` | Compare one class
|
|
58
|
-
"| `compare-versions` | Compare class
|
|
56
|
+
"| `trace-symbol-lifecycle` | Trace when `Class.method` exists across Minecraft versions |",
|
|
57
|
+
"| `diff-class-signatures` | Compare one class across two versions and return member deltas |",
|
|
58
|
+
"| `compare-versions` | Compare class and registry changes between two versions |"
|
|
59
59
|
],
|
|
60
60
|
ja: [
|
|
61
|
-
"| `trace-symbol-lifecycle` | `Class.method` が Minecraft
|
|
62
|
-
"| `diff-class-signatures` | 2 つのバージョン間で 1 つのクラスを比較し、メンバー差分を返す |
|
|
63
|
-
"| `compare-versions` | 2
|
|
61
|
+
"| `trace-symbol-lifecycle` | `Class.method` が Minecraft のどのバージョンで存在するかを追跡する |",
|
|
62
|
+
"| `diff-class-signatures` | 2 つのバージョン間で 1 つのクラスを比較し、メンバー差分を返す |",
|
|
63
|
+
"| `compare-versions` | 2 つのバージョン間でクラスとレジストリの変更を比較する |"
|
|
64
64
|
]
|
|
65
65
|
},
|
|
66
66
|
"mapping-symbols": {
|
|
67
67
|
en: [
|
|
68
|
-
"| `find-mapping` |
|
|
69
|
-
"| `resolve-method-mapping-exact` | Resolve one method mapping with strict owner
|
|
70
|
-
"| `get-class-api-matrix` | Show one class API
|
|
71
|
-
"| `resolve-workspace-symbol` | Resolve compile-visible symbol names
|
|
72
|
-
"| `check-symbol-exists` |
|
|
68
|
+
"| `find-mapping` | Look up mapping candidates for class, field, or method symbols |",
|
|
69
|
+
"| `resolve-method-mapping-exact` | Resolve one method mapping with strict owner, name, and descriptor matching |",
|
|
70
|
+
"| `get-class-api-matrix` | Show one class API across `obfuscated`, `mojang`, `intermediary`, and `yarn` |",
|
|
71
|
+
"| `resolve-workspace-symbol` | Resolve compile-visible symbol names from a Gradle workspace |",
|
|
72
|
+
"| `check-symbol-exists` | Check whether a class, field, or method exists in a namespace |"
|
|
73
73
|
],
|
|
74
74
|
ja: [
|
|
75
|
-
"| `find-mapping` |
|
|
76
|
-
"| `resolve-method-mapping-exact` | owner
|
|
77
|
-
"| `get-class-api-matrix` | 1 つのクラス API
|
|
78
|
-
"| `resolve-workspace-symbol` | Gradle
|
|
79
|
-
"| `check-symbol-exists` |
|
|
75
|
+
"| `find-mapping` | クラス、フィールド、メソッドのシンボルに対するマッピング候補を調べる |",
|
|
76
|
+
"| `resolve-method-mapping-exact` | owner、name、descriptor の厳密一致で 1 つのメソッドマッピングを解決する |",
|
|
77
|
+
"| `get-class-api-matrix` | 1 つのクラス API を `obfuscated`、`mojang`、`intermediary`、`yarn` で見比べる |",
|
|
78
|
+
"| `resolve-workspace-symbol` | Gradle ワークスペースからコンパイル時に見えるシンボル名を解決する |",
|
|
79
|
+
"| `check-symbol-exists` | 名前空間内でクラス、フィールド、メソッドが存在するかを確認する |"
|
|
80
80
|
]
|
|
81
81
|
},
|
|
82
82
|
"nbt-utilities": {
|
|
83
83
|
en: [
|
|
84
|
-
"| `nbt-to-json` | Decode Java Edition NBT binary
|
|
85
|
-
"| `nbt-apply-json-patch` | Apply RFC 6902
|
|
86
|
-
"| `json-to-nbt` | Encode typed JSON back to Java Edition NBT binary
|
|
84
|
+
"| `nbt-to-json` | Decode Java Edition NBT binary payloads into typed JSON |",
|
|
85
|
+
"| `nbt-apply-json-patch` | Apply RFC 6902 patches to typed NBT JSON |",
|
|
86
|
+
"| `json-to-nbt` | Encode typed JSON back to Java Edition NBT binary |"
|
|
87
87
|
],
|
|
88
88
|
ja: [
|
|
89
|
-
"| `nbt-to-json` | Java Edition の NBT
|
|
90
|
-
"| `nbt-apply-json-patch` |
|
|
91
|
-
"| `json-to-nbt` | 型付き JSON を Java Edition の NBT
|
|
89
|
+
"| `nbt-to-json` | Java Edition の NBT バイナリを型付き JSON にデコードする |",
|
|
90
|
+
"| `nbt-apply-json-patch` | 型付き NBT JSON に RFC 6902 パッチを適用する |",
|
|
91
|
+
"| `json-to-nbt` | 型付き JSON を Java Edition の NBT バイナリへ再エンコードする |"
|
|
92
92
|
]
|
|
93
93
|
},
|
|
94
94
|
"mod-analysis": {
|
|
95
95
|
en: [
|
|
96
|
-
"| `analyze-mod-jar` | Extract mod metadata
|
|
97
|
-
"| `decompile-mod-jar` | Decompile mod JAR and optionally return one class source |
|
|
98
|
-
"| `get-mod-class-source` | Read one class source from decompiled mod cache |
|
|
99
|
-
"| `search-mod-source` | Search decompiled mod source by class
|
|
100
|
-
"| `remap-mod-jar` | Remap a Fabric
|
|
96
|
+
"| `analyze-mod-jar` | Extract mod metadata, dependencies, entrypoints, mixin config info, and packaged access transformer paths from a JAR |",
|
|
97
|
+
"| `decompile-mod-jar` | Decompile a mod JAR and optionally return one class source |",
|
|
98
|
+
"| `get-mod-class-source` | Read one class source from the decompiled mod cache |",
|
|
99
|
+
"| `search-mod-source` | Search decompiled mod source by class, method, field, or content |",
|
|
100
|
+
"| `remap-mod-jar` | Remap a Fabric or Quilt mod JAR to `yarn` or `mojang` names |"
|
|
101
101
|
],
|
|
102
102
|
ja: [
|
|
103
|
-
"| `analyze-mod-jar` |
|
|
104
|
-
"| `decompile-mod-jar` | Mod JAR をデコンパイルし、必要に応じて 1 つのクラスソースを返す |
|
|
105
|
-
"| `get-mod-class-source` | デコンパイル済み Mod キャッシュから 1 つのクラスソースを読み取る |
|
|
106
|
-
"| `search-mod-source` | デコンパイル済み Mod ソースを class
|
|
107
|
-
"| `remap-mod-jar` | Fabric
|
|
103
|
+
"| `analyze-mod-jar` | JAR から Mod メタデータ、依存関係、エントリポイント、Mixin 設定情報、同梱 Access Transformer パスを抽出する |",
|
|
104
|
+
"| `decompile-mod-jar` | Mod JAR をデコンパイルし、必要に応じて 1 つのクラスソースを返す |",
|
|
105
|
+
"| `get-mod-class-source` | デコンパイル済み Mod キャッシュから 1 つのクラスソースを読み取る |",
|
|
106
|
+
"| `search-mod-source` | デコンパイル済み Mod ソースを class、method、field、content で検索する |",
|
|
107
|
+
"| `remap-mod-jar` | Fabric または Quilt の Mod JAR を `yarn` または `mojang` 名へリマップする |"
|
|
108
108
|
]
|
|
109
109
|
},
|
|
110
110
|
"validation": {
|
|
111
111
|
en: [
|
|
112
|
-
"| `validate-mixin` |
|
|
113
|
-
"| `validate-access-widener` |
|
|
112
|
+
"| `validate-mixin` | Validate Mixin source against a target Minecraft version |",
|
|
113
|
+
"| `validate-access-widener` | Validate Access Widener content against a target Minecraft version, optionally using runtime-aware Loom artifacts |",
|
|
114
|
+
"| `validate-access-transformer` | Validate Access Transformer content against a target Minecraft version, optionally using Forge/NeoForge runtime artifacts |"
|
|
114
115
|
],
|
|
115
116
|
ja: [
|
|
116
|
-
"| `validate-mixin` | 対象 Minecraft バージョンに対して Mixin
|
|
117
|
-
"| `validate-access-widener` |
|
|
117
|
+
"| `validate-mixin` | 対象 Minecraft バージョンに対して Mixin ソースを検証する |",
|
|
118
|
+
"| `validate-access-widener` | 対象 Minecraft バージョンに対して Access Widener の内容を検証し、必要に応じて Loom runtime artifact も使う |",
|
|
119
|
+
"| `validate-access-transformer` | 対象 Minecraft バージョンに対して Access Transformer の内容を検証し、必要に応じて Forge / NeoForge runtime artifact も使う |"
|
|
118
120
|
]
|
|
119
121
|
},
|
|
120
122
|
"registry-diagnostics": {
|
|
121
123
|
en: [
|
|
122
|
-
"| `get-registry-data` |
|
|
123
|
-
"| `get-runtime-metrics` | Inspect runtime
|
|
124
|
+
"| `get-registry-data` | Read generated registry snapshots and optionally include entry data |",
|
|
125
|
+
"| `get-runtime-metrics` | Inspect runtime metrics and latency snapshots |"
|
|
124
126
|
],
|
|
125
127
|
ja: [
|
|
126
|
-
"| `get-registry-data` |
|
|
127
|
-
"| `get-runtime-metrics` |
|
|
128
|
+
"| `get-registry-data` | 生成済みレジストリスナップショットを読み取り、必要に応じてエントリデータも含める |",
|
|
129
|
+
"| `get-runtime-metrics` | ランタイムメトリクスとレイテンシスナップショットを確認する |"
|
|
128
130
|
]
|
|
129
131
|
}
|
|
130
132
|
};
|
|
131
133
|
export function renderToolSurfaceSection(locale, sectionId) {
|
|
132
|
-
const header = locale === "en"
|
|
133
|
-
|
|
134
|
-
: "| ツール | 役割 | 主な入力 | 主な出力 |";
|
|
135
|
-
const divider = "| --- | --- | --- | --- |";
|
|
134
|
+
const header = locale === "en" ? "| Tool | Purpose |" : "| ツール | 役割 |";
|
|
135
|
+
const divider = "| --- | --- |";
|
|
136
136
|
const rows = SECTION_ROWS[sectionId][locale];
|
|
137
137
|
return [header, divider, ...rows].join("\n");
|
|
138
138
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export type SourceOrigin = "local-jar" | "local-m2" | "remote-repo" | "decompiled";
|
|
2
2
|
export type SourceMapping = "obfuscated" | "mojang" | "intermediary" | "yarn";
|
|
3
|
+
export type AccessTransformerNamespace = "srg" | "mojang" | "obfuscated";
|
|
4
|
+
export type RuntimeValidationNamespace = SourceMapping | AccessTransformerNamespace;
|
|
3
5
|
export type MappingSourcePriority = "loom-first" | "maven-first";
|
|
4
6
|
export type ArtifactTargetKind = "version" | "jar" | "coordinate";
|
|
5
7
|
export type ArtifactScope = "vanilla" | "merged" | "loader";
|
|
@@ -37,6 +39,21 @@ export interface ArtifactProvenance {
|
|
|
37
39
|
};
|
|
38
40
|
transformChain: string[];
|
|
39
41
|
}
|
|
42
|
+
export interface RuntimeValidationProvenance<TMapping extends RuntimeValidationNamespace = RuntimeValidationNamespace> {
|
|
43
|
+
version: string;
|
|
44
|
+
jarPath: string;
|
|
45
|
+
requestedScope?: ArtifactScope;
|
|
46
|
+
appliedScope?: ArtifactScope;
|
|
47
|
+
requestedMapping: TMapping;
|
|
48
|
+
mappingApplied: TMapping;
|
|
49
|
+
origin: SourceOrigin | "loom-cache" | "version-jar";
|
|
50
|
+
resolutionNotes?: string[];
|
|
51
|
+
scopeFallback?: {
|
|
52
|
+
requested: string;
|
|
53
|
+
applied: string;
|
|
54
|
+
reason: string;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
40
57
|
export interface ErrorEnvelope {
|
|
41
58
|
code: string;
|
|
42
59
|
message: string;
|
|
@@ -13,7 +13,20 @@ export type WorkspaceCompileMappingOutput = {
|
|
|
13
13
|
evidence: WorkspaceMappingEvidence[];
|
|
14
14
|
warnings: string[];
|
|
15
15
|
};
|
|
16
|
+
export type WorkspaceProjectLoader = "fabric" | "quilt" | "forge" | "neoforge" | "unknown";
|
|
17
|
+
export type WorkspaceLoaderEvidence = {
|
|
18
|
+
filePath: string;
|
|
19
|
+
loader: WorkspaceProjectLoader;
|
|
20
|
+
reason: string;
|
|
21
|
+
};
|
|
22
|
+
export type WorkspaceProjectLoaderOutput = {
|
|
23
|
+
resolved: boolean;
|
|
24
|
+
loader?: WorkspaceProjectLoader;
|
|
25
|
+
evidence: WorkspaceLoaderEvidence[];
|
|
26
|
+
warnings: string[];
|
|
27
|
+
};
|
|
16
28
|
export declare class WorkspaceMappingService {
|
|
17
29
|
detectCompileMapping(input: WorkspaceCompileMappingInput): Promise<WorkspaceCompileMappingOutput>;
|
|
18
30
|
detectProjectMinecraftVersion(projectPath: string): Promise<string | undefined>;
|
|
31
|
+
detectProjectLoader(projectPath: string): Promise<WorkspaceProjectLoaderOutput>;
|
|
19
32
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import fastGlob from "fast-glob";
|
|
4
|
+
import { mapWithConcurrencyLimit } from "./concurrency.js";
|
|
4
5
|
import { createError, ERROR_CODES } from "./errors.js";
|
|
6
|
+
const WORKSPACE_FILE_READ_CONCURRENCY = 4;
|
|
5
7
|
function detectMappingsFromContent(content) {
|
|
6
8
|
const detections = [];
|
|
7
9
|
if (/officialMojangMappings\s*\(/i.test(content)) {
|
|
@@ -36,6 +38,46 @@ function detectMappingsFromContent(content) {
|
|
|
36
38
|
}
|
|
37
39
|
return detections;
|
|
38
40
|
}
|
|
41
|
+
function detectLoadersFromContent(content) {
|
|
42
|
+
const detections = [];
|
|
43
|
+
if (/\bid\s*(?:\(\s*)?["']net\.neoforged\.moddev["']\s*\)?/i.test(content)) {
|
|
44
|
+
detections.push({
|
|
45
|
+
loader: "neoforge",
|
|
46
|
+
reason: "net.neoforged.moddev plugin"
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (/\bid\s*(?:\(\s*)?["']net\.minecraftforge\.gradle["']\s*\)?/i.test(content)) {
|
|
50
|
+
detections.push({
|
|
51
|
+
loader: "forge",
|
|
52
|
+
reason: "net.minecraftforge.gradle plugin"
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (/\bid\s*(?:\(\s*)?["']org\.quiltmc\.loom["']\s*\)?/i.test(content)) {
|
|
56
|
+
detections.push({
|
|
57
|
+
loader: "quilt",
|
|
58
|
+
reason: "org.quiltmc.loom plugin"
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (/\bid\s*(?:\(\s*)?["']fabric-loom["']\s*\)?/i.test(content) || /\bid\s*(?:\(\s*)?["']dev\.architectury\.loom["']\s*\)?/i.test(content)) {
|
|
62
|
+
detections.push({
|
|
63
|
+
loader: "fabric",
|
|
64
|
+
reason: "fabric/dev.architectury loom plugin"
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
if (/\bminecraft\s*\{[\s\S]*?\baccessTransformer\b/i.test(content)) {
|
|
68
|
+
detections.push({
|
|
69
|
+
loader: "forge",
|
|
70
|
+
reason: "minecraft { accessTransformer ... } block"
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (/\bneoForge\s*\{[\s\S]*?\baccessTransformers\b/i.test(content)) {
|
|
74
|
+
detections.push({
|
|
75
|
+
loader: "neoforge",
|
|
76
|
+
reason: "neoForge { accessTransformers ... } block"
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return detections;
|
|
80
|
+
}
|
|
39
81
|
export class WorkspaceMappingService {
|
|
40
82
|
async detectCompileMapping(input) {
|
|
41
83
|
const projectPath = input.projectPath?.trim();
|
|
@@ -49,30 +91,26 @@ export class WorkspaceMappingService {
|
|
|
49
91
|
});
|
|
50
92
|
}
|
|
51
93
|
const root = resolve(projectPath);
|
|
52
|
-
const files = fastGlob.
|
|
94
|
+
const files = (await fastGlob.glob(["build.gradle", "build.gradle.kts", "**/build.gradle", "**/build.gradle.kts"], {
|
|
53
95
|
cwd: root,
|
|
54
96
|
absolute: true,
|
|
55
97
|
onlyFiles: true,
|
|
56
98
|
ignore: ["**/.git/**", "**/.gradle/**", "**/build/**", "**/out/**", "**/node_modules/**"]
|
|
57
|
-
});
|
|
58
|
-
const evidence =
|
|
59
|
-
for (const filePath of files.sort((left, right) => left.localeCompare(right))) {
|
|
99
|
+
})).sort((left, right) => left.localeCompare(right));
|
|
100
|
+
const evidence = (await mapWithConcurrencyLimit(files, WORKSPACE_FILE_READ_CONCURRENCY, async (filePath) => {
|
|
60
101
|
let content;
|
|
61
102
|
try {
|
|
62
103
|
content = await readFile(filePath, "utf8");
|
|
63
104
|
}
|
|
64
105
|
catch {
|
|
65
|
-
|
|
106
|
+
return [];
|
|
66
107
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
108
|
+
return detectMappingsFromContent(content).map((detection) => ({
|
|
109
|
+
filePath,
|
|
110
|
+
mapping: detection.mapping,
|
|
111
|
+
reason: detection.reason
|
|
112
|
+
}));
|
|
113
|
+
})).flat();
|
|
76
114
|
if (evidence.length === 0) {
|
|
77
115
|
return {
|
|
78
116
|
resolved: false,
|
|
@@ -121,5 +159,99 @@ export class WorkspaceMappingService {
|
|
|
121
159
|
}
|
|
122
160
|
return undefined;
|
|
123
161
|
}
|
|
162
|
+
async detectProjectLoader(projectPath) {
|
|
163
|
+
const root = resolve(projectPath);
|
|
164
|
+
const buildFiles = (await fastGlob.glob(["build.gradle", "build.gradle.kts", "**/build.gradle", "**/build.gradle.kts"], {
|
|
165
|
+
cwd: root,
|
|
166
|
+
absolute: true,
|
|
167
|
+
onlyFiles: true,
|
|
168
|
+
ignore: ["**/.git/**", "**/.gradle/**", "**/build/**", "**/out/**", "**/node_modules/**"]
|
|
169
|
+
})).sort((left, right) => left.localeCompare(right));
|
|
170
|
+
const descriptorFiles = (await fastGlob.glob([
|
|
171
|
+
"fabric.mod.json",
|
|
172
|
+
"quilt.mod.json",
|
|
173
|
+
"META-INF/mods.toml",
|
|
174
|
+
"META-INF/neoforge.mods.toml",
|
|
175
|
+
"**/fabric.mod.json",
|
|
176
|
+
"**/quilt.mod.json",
|
|
177
|
+
"**/META-INF/mods.toml",
|
|
178
|
+
"**/META-INF/neoforge.mods.toml"
|
|
179
|
+
], {
|
|
180
|
+
cwd: root,
|
|
181
|
+
absolute: true,
|
|
182
|
+
onlyFiles: true,
|
|
183
|
+
ignore: ["**/.git/**", "**/.gradle/**", "**/build/**", "**/out/**", "**/node_modules/**"]
|
|
184
|
+
})).sort((left, right) => left.localeCompare(right));
|
|
185
|
+
const evidence = (await mapWithConcurrencyLimit(buildFiles, WORKSPACE_FILE_READ_CONCURRENCY, async (filePath) => {
|
|
186
|
+
let content;
|
|
187
|
+
try {
|
|
188
|
+
content = await readFile(filePath, "utf8");
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
return detectLoadersFromContent(content).map((detection) => ({
|
|
194
|
+
filePath,
|
|
195
|
+
loader: detection.loader,
|
|
196
|
+
reason: detection.reason
|
|
197
|
+
}));
|
|
198
|
+
})).flat();
|
|
199
|
+
for (const descriptorPath of descriptorFiles) {
|
|
200
|
+
const normalized = descriptorPath.replaceAll("\\", "/");
|
|
201
|
+
if (normalized.endsWith("fabric.mod.json")) {
|
|
202
|
+
evidence.push({
|
|
203
|
+
filePath: descriptorPath,
|
|
204
|
+
loader: "fabric",
|
|
205
|
+
reason: "fabric.mod.json"
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
else if (normalized.endsWith("quilt.mod.json")) {
|
|
209
|
+
evidence.push({
|
|
210
|
+
filePath: descriptorPath,
|
|
211
|
+
loader: "quilt",
|
|
212
|
+
reason: "quilt.mod.json"
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
else if (normalized.endsWith("META-INF/neoforge.mods.toml")) {
|
|
216
|
+
evidence.push({
|
|
217
|
+
filePath: descriptorPath,
|
|
218
|
+
loader: "neoforge",
|
|
219
|
+
reason: "META-INF/neoforge.mods.toml"
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
else if (normalized.endsWith("META-INF/mods.toml")) {
|
|
223
|
+
evidence.push({
|
|
224
|
+
filePath: descriptorPath,
|
|
225
|
+
loader: "forge",
|
|
226
|
+
reason: "META-INF/mods.toml"
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (evidence.length === 0) {
|
|
231
|
+
return {
|
|
232
|
+
resolved: false,
|
|
233
|
+
evidence,
|
|
234
|
+
warnings: ["No workspace loader declaration was detected from build.gradle(.kts) files or mod descriptors."]
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const loaderSet = new Set(evidence
|
|
238
|
+
.map((entry) => entry.loader)
|
|
239
|
+
.filter((loader) => loader !== "unknown"));
|
|
240
|
+
if (loaderSet.size !== 1) {
|
|
241
|
+
return {
|
|
242
|
+
resolved: false,
|
|
243
|
+
evidence,
|
|
244
|
+
warnings: [
|
|
245
|
+
`Multiple or ambiguous workspace loaders were detected: ${[...loaderSet].join(", ") || "unknown"}.`
|
|
246
|
+
]
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
resolved: true,
|
|
251
|
+
loader: [...loaderSet][0],
|
|
252
|
+
evidence,
|
|
253
|
+
warnings: []
|
|
254
|
+
};
|
|
255
|
+
}
|
|
124
256
|
}
|
|
125
257
|
//# sourceMappingURL=workspace-mapping-service.js.map
|