modsmith 0.6.2 → 0.7.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.
Files changed (39) hide show
  1. package/AGENTS.md +6 -0
  2. package/README.md +131 -20
  3. package/bin/modsmith.mjs +573 -405
  4. package/docs/conformance/README.md +62 -0
  5. package/docs/conformance/farmers-delight-1.21.1-3.3.6.json +209 -0
  6. package/docs/conformance/farmers-delight-dev-live.json +321 -0
  7. package/docs/conformance/moredelight-26.04.30-1.21.json +47 -0
  8. package/docs/conformance/supplementaries-1.21.1-4.0.2.json +227 -0
  9. package/docs/conformance/twilightforest-1.21.1-4.8.796.json +317 -0
  10. package/package.json +16 -3
  11. package/schema/manifest.schema.json +7 -0
  12. package/sidesheets/farmers-delight-3.3.6.crops.json +42 -42
  13. package/src/block-shapes.mjs +176 -0
  14. package/src/calibrate.mjs +1 -0
  15. package/src/conformance-live.mjs +208 -0
  16. package/src/conformance.mjs +366 -0
  17. package/src/cortico-bridge.mjs +397 -325
  18. package/src/crops.mjs +246 -227
  19. package/src/import-dump.mjs +139 -0
  20. package/src/index.mjs +3 -1
  21. package/src/inspect.mjs +466 -461
  22. package/src/manifest-io.mjs +1 -1
  23. package/src/onboard.mjs +21 -3
  24. package/src/probe.mjs +325 -316
  25. package/src/rcon.mjs +14 -8
  26. package/src/server-fingerprint.mjs +5 -5
  27. package/src/stations.mjs +22 -1
  28. package/src/validate.mjs +231 -223
  29. package/src/verify.mjs +18 -10
  30. package/templates/reference-bot/README.md +22 -0
  31. package/templates/reference-bot/index.mjs +59 -0
  32. package/templates/registry-dump/README.md +48 -0
  33. package/templates/registry-dump/build.gradle +39 -0
  34. package/templates/registry-dump/gradle.properties +2 -0
  35. package/templates/registry-dump/modsmith-dump-0.1.2.jar +0 -0
  36. package/templates/registry-dump/settings.gradle +9 -0
  37. package/templates/registry-dump/src/main/java/dev/modsmith/dump/RegistryDumpMod.java +98 -0
  38. package/templates/registry-dump/src/main/resources/fabric.mod.json +18 -0
  39. package/types/index.d.ts +174 -135
@@ -8,7 +8,7 @@ import { mkdirSync, existsSync, readFileSync, writeFileSync } from 'node:fs';
8
8
  import { dirname, join } from 'node:path';
9
9
 
10
10
  /** 写 manifest;键顺序固定,diff 才好看。 */
11
- const ORDER = ['mod', 'version', 'namespace', 'source', 'blocks', 'items', 'foods', 'crops',
11
+ const ORDER = ['mod', 'version', 'namespace', 'source', 'blocks', 'items', 'foods', 'bosses', 'crops',
12
12
  'recipes', 'names', 'containers', 'stations', 'prompt', 'candidates', 'unsupported'];
13
13
 
14
14
  export function writeManifest(file, manifest) {
package/src/onboard.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * modsmith onboard <jar> —— 把六步串成一条命令:
2
+ * modsmith onboard <jar> —— 把九步串成一条命令:
3
3
  * inspect → calibrate → probe → verify → recipes → sidecar
4
4
  *
5
5
  * 每步的产物就是下一步的输入;哪步失败就停在哪(子命令自己 fatal 退出),绝不带病前进。
@@ -25,18 +25,21 @@
25
25
  * resume?: boolean, // 产物已存在的步骤标记 done(断点续跑)
26
26
  * artifacts?: { manifest?: boolean, ids?: boolean, serverRecipes?: boolean },
27
27
  * dryRecipes?: boolean, // recipes 步骤不写回(默认写)
28
+ * serializers?: string, // 显式指定自定义序列化器 sidesheet(默认按 manifest.mod 找)
28
29
  * noBuild?: boolean, // sidecar 不编译
30
+ * dump?: string | null, // registry dump JSON:有就替代 calibrate(秒级)
29
31
  * }} opts
30
32
  * @returns {{ steps: Array<{id, title, argv: string[], done: boolean, blocked: boolean, reason: string}>, manifestPath: string, idsPath: string }}
31
33
  */
32
34
  export function onboardPlan(opts) {
33
35
  const {
34
36
  jar, pack, modsDir = './mods', server = null, skip = [], resume = false,
35
- artifacts = {}, dryRecipes = false, noBuild = false,
37
+ artifacts = {}, dryRecipes = false, serializers = null, noBuild = false, dump = null,
36
38
  } = opts;
37
39
  const dir = modsDir.replace(/[\\/]+$/, '');
38
40
  const manifestPath = `${dir}/${pack}.json`;
39
41
  const idsPath = `${dir}/${pack}-ids.json`;
42
+ const conformancePath = `${dir}/${pack}-conformance.json`;
40
43
  // probe --scan-blocks 的证据落在这里,learn --infer 直接吃它。
41
44
  const probePath = `${dir}/${pack}-probe.json`;
42
45
  const srv = server ?? {};
@@ -64,13 +67,27 @@ export function onboardPlan(opts) {
64
67
  return { id, title, argv, done: Boolean(resume && done && !skipped), blocked, reason };
65
68
  };
66
69
 
70
+ const idStep = () => (dump
71
+ ? step('ids', '注册表 dump → ids(秒级)', [
72
+ 'import-dump', dump, '--manifest', manifestPath, '--ids', idsPath,
73
+ ...(srv.serverMods ? ['--server-mods', String(srv.serverMods)] : []),
74
+ ...(srv.mcVersion ? ['--mc-version', String(srv.mcVersion)] : []),
75
+ ], Boolean(artifacts.ids), false)
76
+ : step('calibrate', '现场量数字 id', ['calibrate', manifestPath, '--ids', idsPath, ...(resume ? ['--resume'] : []), ...serverArgs], Boolean(artifacts.ids), true));
77
+
67
78
  return {
68
79
  manifestPath,
69
80
  idsPath,
70
81
  probePath,
71
82
  steps: [
72
83
  step('inspect', '静态提取清单', ['inspect', jar, '--out', modsDir, '--pack', pack], Boolean(artifacts.manifest), false),
73
- step('calibrate', '现场量数字 id', ['calibrate', manifestPath, '--ids', idsPath, ...(resume ? ['--resume'] : []), ...serverArgs], Boolean(artifacts.ids), true),
84
+ // 清单先单独过一遍契约;ids 生成后再跑完整三层(含 registry)。
85
+ step('conformance-manifest', '清单契约检查', ['conformance', manifestPath, '--manifest-only'], false, false),
86
+ idStep(),
87
+ // 接包验收:ids 一落地就查 manifest/ids/registry 三层;不过就停,不让 probe
88
+ // 和 sidecar 继续消费坏数据。离线、不连服务器。
89
+ step('conformance', '接包验收(离线)', ['conformance', manifestPath, '--ids', idsPath,
90
+ '--json', conformancePath, ...(srv.serverMods ? ['--server-mods', String(srv.serverMods)] : [])], false, false),
74
91
  // --scan-blocks:把候选方块逐个右键一遍,记录开窗行为——这是 learn --infer 的证据。
75
92
  step('probe', '实测容器/站点 + 方块扫描', ['probe', manifestPath, '--pack', pack, '--mods-dir', modsDir,
76
93
  '--scan-blocks', '--out', probePath, ...serverArgs], Boolean(artifacts.probe), true),
@@ -83,6 +100,7 @@ export function onboardPlan(opts) {
83
100
  // --ids-all:同一台服上第二个包翻译时必然碰到别的包的物品(捕获是整服配方)。
84
101
  // 只有一份 ids 时它是空操作;多份时按指纹闸拒绝混用不同 jar 组合的量测。
85
102
  step('recipes', '服务端真配方翻进清单', ['recipes', manifestPath, '--ids', idsPath, '--ids-all', modsDir,
103
+ ...(serializers ? ['--serializers', serializers] : []),
86
104
  ...(srv.serverMods ? ['--server-mods', String(srv.serverMods)] : []),
87
105
  ...(dryRecipes ? [] : ['--write'])], Boolean(artifacts.serverRecipes), false),
88
106
  // 推断工作站:规则优先,不需要模型;有 probe 证据就用证据。