modwright 0.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.
Files changed (455) hide show
  1. package/LICENSE +35 -0
  2. package/README.md +212 -0
  3. package/assets/claude/agents/mw-explore.md +46 -0
  4. package/assets/claude/agents/mw-fixture.md +33 -0
  5. package/assets/claude/agents/mw-rule-author.md +51 -0
  6. package/assets/claude/agents/mw-scaffold-author.md +48 -0
  7. package/assets/claude/skills/mw-author.md +59 -0
  8. package/assets/claude/skills/mw-new-item.md +51 -0
  9. package/assets/claude/skills/mw-new-spell.md +50 -0
  10. package/assets/claude/skills/mw-scaffold.md +59 -0
  11. package/assets/claude/skills/mw-ship.md +57 -0
  12. package/assets/claude/skills/mw-validate.md +51 -0
  13. package/assets/claude/skills/mw-verify.md +59 -0
  14. package/assets/nivalisnights/extract_resources.py +177 -0
  15. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Config.json +5 -0
  16. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapClient.lua +55 -0
  17. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapServer.lua +81 -0
  18. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Log.lua +96 -0
  19. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Probes.lua +1038 -0
  20. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/ProbesClient.lua +74 -0
  21. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Protocol.lua +985 -0
  22. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Watch.lua +175 -0
  23. package/bridges/bg3-se/Mods/ModWrightBridge/meta.lsx +45 -0
  24. package/bridges/bg3-se/README.md +99 -0
  25. package/bridges/bg3-se/bridge.json +68 -0
  26. package/bridges/cp2077-cet/ModWrightBridge/init.lua +375 -0
  27. package/bridges/cp2077-cet/ModWrightBridge/probes.lua +1104 -0
  28. package/bridges/cp2077-cet/ModWrightBridge/protocol.lua +1306 -0
  29. package/bridges/cp2077-cet/README.md +165 -0
  30. package/bridges/cp2077-cet/bridge.json +53 -0
  31. package/dist/core/bridge/arm.js +175 -0
  32. package/dist/core/bridge/cet-console.js +26 -0
  33. package/dist/core/bridge/cet-log.js +362 -0
  34. package/dist/core/bridge/index.js +11 -0
  35. package/dist/core/bridge/locate.js +35 -0
  36. package/dist/core/bridge/paths.js +34 -0
  37. package/dist/core/bridge/pending.js +89 -0
  38. package/dist/core/bridge/poll.js +155 -0
  39. package/dist/core/bridge/stage.js +100 -0
  40. package/dist/core/bridge/status.js +97 -0
  41. package/dist/core/bridge/types.js +145 -0
  42. package/dist/core/bridge/validate.js +107 -0
  43. package/dist/core/build/index.js +6 -0
  44. package/dist/core/build/manifest.js +47 -0
  45. package/dist/core/build/paths.js +32 -0
  46. package/dist/core/build/run.js +342 -0
  47. package/dist/core/build/stage.js +265 -0
  48. package/dist/core/build/steps/bg3.js +129 -0
  49. package/dist/core/build/steps/core.js +195 -0
  50. package/dist/core/build/steps/cyberpunk.js +95 -0
  51. package/dist/core/build/steps/listing.js +35 -0
  52. package/dist/core/build/types.js +13 -0
  53. package/dist/core/build/zip.js +148 -0
  54. package/dist/core/compat/check.js +113 -0
  55. package/dist/core/compat/pe.js +220 -0
  56. package/dist/core/compat/types.js +1 -0
  57. package/dist/core/compat/version.js +70 -0
  58. package/dist/core/deploy/guards.js +292 -0
  59. package/dist/core/deploy/index.js +5 -0
  60. package/dist/core/deploy/plan.js +696 -0
  61. package/dist/core/deploy/reload-apply.js +361 -0
  62. package/dist/core/deploy/reload.js +358 -0
  63. package/dist/core/deploy/sources.js +169 -0
  64. package/dist/core/deploy/types.js +1 -0
  65. package/dist/core/epic.js +54 -0
  66. package/dist/core/fsutil.js +191 -0
  67. package/dist/core/home.js +70 -0
  68. package/dist/core/knowledge/facts.js +229 -0
  69. package/dist/core/knowledge/index.js +4 -0
  70. package/dist/core/knowledge/search.js +112 -0
  71. package/dist/core/knowledge/store.js +123 -0
  72. package/dist/core/knowledge/types.js +1 -0
  73. package/dist/core/ledger/check.js +42 -0
  74. package/dist/core/ledger/hooks.js +80 -0
  75. package/dist/core/ledger/index.js +7 -0
  76. package/dist/core/ledger/query.js +17 -0
  77. package/dist/core/ledger/record.js +84 -0
  78. package/dist/core/ledger/status.js +53 -0
  79. package/dist/core/ledger/store.js +98 -0
  80. package/dist/core/ledger/types.js +108 -0
  81. package/dist/core/logs/index.js +4 -0
  82. package/dist/core/logs/registry.js +50 -0
  83. package/dist/core/logs/scan.js +195 -0
  84. package/dist/core/logs/triage.js +160 -0
  85. package/dist/core/logs/types.js +1 -0
  86. package/dist/core/lsx.js +10 -0
  87. package/dist/core/lz4.js +66 -0
  88. package/dist/core/mods.js +229 -0
  89. package/dist/core/process.js +49 -0
  90. package/dist/core/project/build-steps.js +83 -0
  91. package/dist/core/project/describe.js +74 -0
  92. package/dist/core/project/index.js +5 -0
  93. package/dist/core/project/load.js +146 -0
  94. package/dist/core/project/schema.js +264 -0
  95. package/dist/core/project/types.js +3 -0
  96. package/dist/core/prompts.js +72 -0
  97. package/dist/core/registry.js +35 -0
  98. package/dist/core/safety/backup.js +206 -0
  99. package/dist/core/safety/execute.js +188 -0
  100. package/dist/core/safety/index.js +5 -0
  101. package/dist/core/safety/plan.js +122 -0
  102. package/dist/core/safety/restore.js +172 -0
  103. package/dist/core/safety/types.js +1 -0
  104. package/dist/core/scaffold/bootstrap.js +7 -0
  105. package/dist/core/scaffold/catalog.js +28 -0
  106. package/dist/core/scaffold/claude-assets.js +271 -0
  107. package/dist/core/scaffold/collisions.js +64 -0
  108. package/dist/core/scaffold/emit.js +356 -0
  109. package/dist/core/scaffold/engine.js +680 -0
  110. package/dist/core/scaffold/ids.js +78 -0
  111. package/dist/core/scaffold/index.js +10 -0
  112. package/dist/core/scaffold/jsonpath.js +121 -0
  113. package/dist/core/scaffold/load.js +81 -0
  114. package/dist/core/scaffold/render.js +85 -0
  115. package/dist/core/scaffold/sequence.js +396 -0
  116. package/dist/core/scaffold/types.js +309 -0
  117. package/dist/core/steam.js +63 -0
  118. package/dist/core/surfaceutil.js +36 -0
  119. package/dist/core/testplan/check.js +67 -0
  120. package/dist/core/testplan/index.js +5 -0
  121. package/dist/core/testplan/load.js +100 -0
  122. package/dist/core/testplan/registry.js +317 -0
  123. package/dist/core/testplan/run.js +389 -0
  124. package/dist/core/testplan/types.js +82 -0
  125. package/dist/core/text/converters/bg3.js +50 -0
  126. package/dist/core/text/converters/cyberpunk.js +36 -0
  127. package/dist/core/text/converters/index.js +261 -0
  128. package/dist/core/text/diff/cr2w.js +180 -0
  129. package/dist/core/text/diff/index.js +16 -0
  130. package/dist/core/text/diff/loca.js +43 -0
  131. package/dist/core/text/diff/lsx.js +126 -0
  132. package/dist/core/text/handles.js +86 -0
  133. package/dist/core/text/index.js +6 -0
  134. package/dist/core/text/json.js +46 -0
  135. package/dist/core/text/templates/cache.js +71 -0
  136. package/dist/core/text/templates/index.js +3 -0
  137. package/dist/core/text/templates/library.js +245 -0
  138. package/dist/core/text/templates/types.js +51 -0
  139. package/dist/core/text/toolchain.js +16 -0
  140. package/dist/core/text/types.js +1 -0
  141. package/dist/core/text/validate.js +149 -0
  142. package/dist/core/text/xml.js +58 -0
  143. package/dist/core/toolchain/datafetch.js +151 -0
  144. package/dist/core/toolchain/env.js +63 -0
  145. package/dist/core/toolchain/features.js +170 -0
  146. package/dist/core/toolchain/index.js +8 -0
  147. package/dist/core/toolchain/install.js +191 -0
  148. package/dist/core/toolchain/locate.js +275 -0
  149. package/dist/core/toolchain/remember.js +84 -0
  150. package/dist/core/toolchain/run.js +318 -0
  151. package/dist/core/toolchain/specs.js +351 -0
  152. package/dist/core/toolchain/types.js +1 -0
  153. package/dist/core/types.js +1 -0
  154. package/dist/core/userconfig.js +66 -0
  155. package/dist/core/validate/context.js +139 -0
  156. package/dist/core/validate/index.js +5 -0
  157. package/dist/core/validate/registry.js +58 -0
  158. package/dist/core/validate/run.js +131 -0
  159. package/dist/core/validate/suppressions.js +91 -0
  160. package/dist/core/validate/types.js +2 -0
  161. package/dist/core/yamledit.js +51 -0
  162. package/dist/index.js +389 -0
  163. package/dist/server.js +1914 -0
  164. package/dist/surfaces/baldursgate3/compat.js +164 -0
  165. package/dist/surfaces/baldursgate3/identity.js +110 -0
  166. package/dist/surfaces/baldursgate3/index/build.js +331 -0
  167. package/dist/surfaces/baldursgate3/index/index.js +17 -0
  168. package/dist/surfaces/baldursgate3/index/info.js +40 -0
  169. package/dist/surfaces/baldursgate3/index/parsers/loca.js +41 -0
  170. package/dist/surfaces/baldursgate3/index/parsers/lsx.js +137 -0
  171. package/dist/surfaces/baldursgate3/index/parsers/stats.js +45 -0
  172. package/dist/surfaces/baldursgate3/index/parsers/treasuretable.js +57 -0
  173. package/dist/surfaces/baldursgate3/index/parsers/xmlutil.js +142 -0
  174. package/dist/surfaces/baldursgate3/index/queries.js +327 -0
  175. package/dist/surfaces/baldursgate3/index/schema.js +62 -0
  176. package/dist/surfaces/baldursgate3/index.js +3 -0
  177. package/dist/surfaces/baldursgate3/logs.js +278 -0
  178. package/dist/surfaces/baldursgate3/modsettings.js +115 -0
  179. package/dist/surfaces/baldursgate3/pak.js +153 -0
  180. package/dist/surfaces/baldursgate3/settings.js +49 -0
  181. package/dist/surfaces/baldursgate3/surface.js +232 -0
  182. package/dist/surfaces/baldursgate3/validators/bridge.js +7 -0
  183. package/dist/surfaces/baldursgate3/validators/files.js +476 -0
  184. package/dist/surfaces/baldursgate3/validators/items.js +1001 -0
  185. package/dist/surfaces/baldursgate3/validators/progression.js +734 -0
  186. package/dist/surfaces/baldursgate3/validators/stats.js +1076 -0
  187. package/dist/surfaces/baldursgate3/validators/story.js +790 -0
  188. package/dist/surfaces/baldursgate3/validators/templates.js +7 -0
  189. package/dist/surfaces/cyberpunk2077/compat.js +223 -0
  190. package/dist/surfaces/cyberpunk2077/index/build.js +231 -0
  191. package/dist/surfaces/cyberpunk2077/index/index.js +17 -0
  192. package/dist/surfaces/cyberpunk2077/index/info.js +51 -0
  193. package/dist/surfaces/cyberpunk2077/index/model.js +52 -0
  194. package/dist/surfaces/cyberpunk2077/index/parsers/tweak.js +483 -0
  195. package/dist/surfaces/cyberpunk2077/index/parsers/tweakxl-yaml.js +183 -0
  196. package/dist/surfaces/cyberpunk2077/index/queries.js +504 -0
  197. package/dist/surfaces/cyberpunk2077/index/resource.js +135 -0
  198. package/dist/surfaces/cyberpunk2077/index/schema.js +90 -0
  199. package/dist/surfaces/cyberpunk2077/index.js +3 -0
  200. package/dist/surfaces/cyberpunk2077/logs.js +742 -0
  201. package/dist/surfaces/cyberpunk2077/paths.js +12 -0
  202. package/dist/surfaces/cyberpunk2077/surface.js +218 -0
  203. package/dist/surfaces/cyberpunk2077/validators/bridge.js +7 -0
  204. package/dist/surfaces/cyberpunk2077/validators/cr2w.js +349 -0
  205. package/dist/surfaces/cyberpunk2077/validators/garments.js +1181 -0
  206. package/dist/surfaces/cyberpunk2077/validators/mesh.js +338 -0
  207. package/dist/surfaces/cyberpunk2077/validators/modsettings.js +120 -0
  208. package/dist/surfaces/cyberpunk2077/validators/packaging.js +463 -0
  209. package/dist/surfaces/cyberpunk2077/validators/red4ext.js +318 -0
  210. package/dist/surfaces/cyberpunk2077/validators/redscript.js +193 -0
  211. package/dist/surfaces/cyberpunk2077/validators/templates.js +7 -0
  212. package/dist/surfaces/cyberpunk2077/validators/tweaks.js +768 -0
  213. package/dist/surfaces/cyberpunk2077/validators/vehicles.js +531 -0
  214. package/dist/surfaces/cyberpunk2077/validators/xl.js +308 -0
  215. package/dist/surfaces/eldenring/binders.js +111 -0
  216. package/dist/surfaces/eldenring/compat.js +166 -0
  217. package/dist/surfaces/eldenring/dcx.js +49 -0
  218. package/dist/surfaces/eldenring/index.js +13 -0
  219. package/dist/surfaces/eldenring/loaders.js +132 -0
  220. package/dist/surfaces/eldenring/logs.js +67 -0
  221. package/dist/surfaces/eldenring/paramdef.js +256 -0
  222. package/dist/surfaces/eldenring/params.js +129 -0
  223. package/dist/surfaces/eldenring/surface.js +121 -0
  224. package/dist/surfaces/eldenring/tools.js +52 -0
  225. package/dist/surfaces/eldenring/validators/binders.js +193 -0
  226. package/dist/surfaces/eldenring/validators/packages.js +159 -0
  227. package/dist/surfaces/eldenring/validators/params.js +334 -0
  228. package/dist/surfaces/eldenring/validators/profiles.js +287 -0
  229. package/dist/surfaces/index.js +34 -0
  230. package/dist/surfaces/nivalisnights/compat.js +229 -0
  231. package/dist/surfaces/nivalisnights/index/build.js +310 -0
  232. package/dist/surfaces/nivalisnights/index/index.js +5 -0
  233. package/dist/surfaces/nivalisnights/index/queries.js +231 -0
  234. package/dist/surfaces/nivalisnights/index.js +4 -0
  235. package/dist/surfaces/nivalisnights/logs.js +473 -0
  236. package/dist/surfaces/nivalisnights/surface.js +195 -0
  237. package/dist/surfaces/skyrimse/archives.js +229 -0
  238. package/dist/surfaces/skyrimse/compat.js +163 -0
  239. package/dist/surfaces/skyrimse/index.js +12 -0
  240. package/dist/surfaces/skyrimse/loadorder.js +174 -0
  241. package/dist/surfaces/skyrimse/logs.js +241 -0
  242. package/dist/surfaces/skyrimse/plugins.js +149 -0
  243. package/dist/surfaces/skyrimse/records.js +94 -0
  244. package/dist/surfaces/skyrimse/surface.js +240 -0
  245. package/dist/surfaces/skyrimse/validators/archive-records.js +165 -0
  246. package/dist/surfaces/skyrimse/validators/archives.js +110 -0
  247. package/dist/surfaces/skyrimse/validators/plugins.js +374 -0
  248. package/dist/surfaces/skyrimse/validators/records.js +117 -0
  249. package/dist/surfaces/stardewvalley/compat.js +190 -0
  250. package/dist/surfaces/stardewvalley/config.js +42 -0
  251. package/dist/surfaces/stardewvalley/contentpatcher.js +203 -0
  252. package/dist/surfaces/stardewvalley/index/index.js +229 -0
  253. package/dist/surfaces/stardewvalley/index/wiki.js +190 -0
  254. package/dist/surfaces/stardewvalley/index.js +12 -0
  255. package/dist/surfaces/stardewvalley/logs.js +307 -0
  256. package/dist/surfaces/stardewvalley/mods.js +182 -0
  257. package/dist/surfaces/stardewvalley/surface.js +244 -0
  258. package/dist/surfaces/stardewvalley/validators/content.js +321 -0
  259. package/dist/surfaces/stardewvalley/validators/fields.js +147 -0
  260. package/dist/surfaces/stardewvalley/validators/loadorder.js +69 -0
  261. package/dist/surfaces/stardewvalley/validators/manifest.js +221 -0
  262. package/dist/surfaces/subnautica2/compat.js +138 -0
  263. package/dist/surfaces/subnautica2/index.js +5 -0
  264. package/dist/surfaces/subnautica2/logs.js +129 -0
  265. package/dist/surfaces/subnautica2/paks.js +173 -0
  266. package/dist/surfaces/subnautica2/surface.js +151 -0
  267. package/dist/surfaces/subnautica2/validators/packaging.js +298 -0
  268. package/dist/surfaces/valheim/compat.js +171 -0
  269. package/dist/surfaces/valheim/index/index.js +301 -0
  270. package/dist/surfaces/valheim/index/tables.js +103 -0
  271. package/dist/surfaces/valheim/index.js +11 -0
  272. package/dist/surfaces/valheim/logs.js +197 -0
  273. package/dist/surfaces/valheim/packaging.js +131 -0
  274. package/dist/surfaces/valheim/plugins.js +270 -0
  275. package/dist/surfaces/valheim/references.js +121 -0
  276. package/dist/surfaces/valheim/surface.js +223 -0
  277. package/dist/surfaces/valheim/validators/packaging.js +218 -0
  278. package/dist/surfaces/valheim/validators/plugins.js +287 -0
  279. package/dist/surfaces/valheim/validators/references.js +169 -0
  280. package/knowledge/baldursgate3/animations.gr2.yaml +166 -0
  281. package/knowledge/baldursgate3/audio.voice.yaml +182 -0
  282. package/knowledge/baldursgate3/audio.wwise.yaml +104 -0
  283. package/knowledge/baldursgate3/charactercreation.heads-hair.yaml +193 -0
  284. package/knowledge/baldursgate3/communitylibrary.shared-content.yaml +129 -0
  285. package/knowledge/baldursgate3/compatibilityframework.api.yaml +176 -0
  286. package/knowledge/baldursgate3/crash.causes.yaml +90 -0
  287. package/knowledge/baldursgate3/dialogue.dialogbank.yaml +120 -0
  288. package/knowledge/baldursgate3/dialogue.files.yaml +236 -0
  289. package/knowledge/baldursgate3/dialogue.osiris-goals.yaml +386 -0
  290. package/knowledge/baldursgate3/dialogue.yaml +122 -0
  291. package/knowledge/baldursgate3/feats.classes.yaml +164 -0
  292. package/knowledge/baldursgate3/items.cloth-physics.yaml +167 -0
  293. package/knowledge/baldursgate3/items.roottemplates.yaml +320 -0
  294. package/knowledge/baldursgate3/items.visualbank.yaml +628 -0
  295. package/knowledge/baldursgate3/journal.quests.yaml +214 -0
  296. package/knowledge/baldursgate3/loadorder.modsettings.yaml +128 -0
  297. package/knowledge/baldursgate3/localization.handles.yaml +92 -0
  298. package/knowledge/baldursgate3/misc.encoding-and-practice.yaml +111 -0
  299. package/knowledge/baldursgate3/origins.companions.yaml +144 -0
  300. package/knowledge/baldursgate3/osiris.signatures.yaml +211 -0
  301. package/knowledge/baldursgate3/packaging.meta.yaml +155 -0
  302. package/knowledge/baldursgate3/packaging.paks.yaml +79 -0
  303. package/knowledge/baldursgate3/process.launch.yaml +34 -0
  304. package/knowledge/baldursgate3/progressions.yaml +92 -0
  305. package/knowledge/baldursgate3/publishing.modio-nexus.yaml +170 -0
  306. package/knowledge/baldursgate3/publishing.toolkit-modio.yaml +135 -0
  307. package/knowledge/baldursgate3/races.progression.yaml +228 -0
  308. package/knowledge/baldursgate3/scriptextender.console.yaml +257 -0
  309. package/knowledge/baldursgate3/scriptextender.yaml +252 -0
  310. package/knowledge/baldursgate3/stats.boosts.yaml +293 -0
  311. package/knowledge/baldursgate3/stats.equipment-kits.yaml +69 -0
  312. package/knowledge/baldursgate3/stats.interrupts.yaml +45 -0
  313. package/knowledge/baldursgate3/stats.itemcombos.yaml +65 -0
  314. package/knowledge/baldursgate3/stats.spells.yaml +293 -0
  315. package/knowledge/baldursgate3/stats.weapons.yaml +210 -0
  316. package/knowledge/baldursgate3/toolchain.divine.yaml +179 -0
  317. package/knowledge/baldursgate3/toolchain.lslib-formats.yaml +242 -0
  318. package/knowledge/baldursgate3/toolkit.levels.yaml +177 -0
  319. package/knowledge/baldursgate3/ui.icons-atlas.yaml +78 -0
  320. package/knowledge/baldursgate3/ui.icons.yaml +412 -0
  321. package/knowledge/baldursgate3/ui.mcm.yaml +161 -0
  322. package/knowledge/baldursgate3/vfx.materials.yaml +174 -0
  323. package/knowledge/baldursgate3/visuals.characterfix.yaml +73 -0
  324. package/knowledge/cyberpunk2077/animations.anims.yaml +118 -0
  325. package/knowledge/cyberpunk2077/anims.archivexl.yaml +163 -0
  326. package/knowledge/cyberpunk2077/anims.authoring.yaml +579 -0
  327. package/knowledge/cyberpunk2077/anims.encoder.yaml +156 -0
  328. package/knowledge/cyberpunk2077/anims.graph.yaml +629 -0
  329. package/knowledge/cyberpunk2077/anims.method.yaml +360 -0
  330. package/knowledge/cyberpunk2077/anims.pipeline.yaml +352 -0
  331. package/knowledge/cyberpunk2077/anims.roundtrip.yaml +222 -0
  332. package/knowledge/cyberpunk2077/anims.sets.yaml +176 -0
  333. package/knowledge/cyberpunk2077/archivexl.bodytypes.yaml +149 -0
  334. package/knowledge/cyberpunk2077/archivexl.dynamic-appearances.yaml +218 -0
  335. package/knowledge/cyberpunk2077/archivexl.manifest.yaml +214 -0
  336. package/knowledge/cyberpunk2077/audio.events.yaml +168 -0
  337. package/knowledge/cyberpunk2077/audio.sounds.yaml +164 -0
  338. package/knowledge/cyberpunk2077/audio.voicesets.yaml +146 -0
  339. package/knowledge/cyberpunk2077/cet.sandbox.yaml +219 -0
  340. package/knowledge/cyberpunk2077/clothing.garments.yaml +283 -0
  341. package/knowledge/cyberpunk2077/clothing.refits.yaml +215 -0
  342. package/knowledge/cyberpunk2077/codeware.overview.yaml +111 -0
  343. package/knowledge/cyberpunk2077/codeware.systems.yaml +192 -0
  344. package/knowledge/cyberpunk2077/drones.combat.yaml +416 -0
  345. package/knowledge/cyberpunk2077/drones.control.yaml +552 -0
  346. package/knowledge/cyberpunk2077/entities.appearance.yaml +166 -0
  347. package/knowledge/cyberpunk2077/equipmentex.slots.yaml +151 -0
  348. package/knowledge/cyberpunk2077/fx.effects.yaml +246 -0
  349. package/knowledge/cyberpunk2077/fx.lights.yaml +171 -0
  350. package/knowledge/cyberpunk2077/hair.modding.yaml +145 -0
  351. package/knowledge/cyberpunk2077/items.wiring.yaml +246 -0
  352. package/knowledge/cyberpunk2077/loadorder.archives.yaml +71 -0
  353. package/knowledge/cyberpunk2077/mesh.blender.yaml +209 -0
  354. package/knowledge/cyberpunk2077/nativedb.dump.yaml +98 -0
  355. package/knowledge/cyberpunk2077/npc.appearance.yaml +275 -0
  356. package/knowledge/cyberpunk2077/npc.behaviour.yaml +128 -0
  357. package/knowledge/cyberpunk2077/npc.locomotion.yaml +490 -0
  358. package/knowledge/cyberpunk2077/packaging.deploy.yaml +175 -0
  359. package/knowledge/cyberpunk2077/packaging.variants.yaml +176 -0
  360. package/knowledge/cyberpunk2077/player.control.yaml +918 -0
  361. package/knowledge/cyberpunk2077/process.assetbuild.yaml +154 -0
  362. package/knowledge/cyberpunk2077/process.lessons.yaml +276 -0
  363. package/knowledge/cyberpunk2077/quests.minor.yaml +46 -0
  364. package/knowledge/cyberpunk2077/quests.scenes.yaml +282 -0
  365. package/knowledge/cyberpunk2077/quickhacks.tiers.yaml +41 -0
  366. package/knowledge/cyberpunk2077/red4ext.api.yaml +645 -0
  367. package/knowledge/cyberpunk2077/red4ext.plugins.yaml +124 -0
  368. package/knowledge/cyberpunk2077/redhottools.hotreload.yaml +245 -0
  369. package/knowledge/cyberpunk2077/redscript.compile-log.yaml +76 -0
  370. package/knowledge/cyberpunk2077/redscript.modules.yaml +118 -0
  371. package/knowledge/cyberpunk2077/toolchain.wolvenkit.yaml +163 -0
  372. package/knowledge/cyberpunk2077/tweakdb.loot-recipes.yaml +184 -0
  373. package/knowledge/cyberpunk2077/tweakdb.melee.yaml +352 -0
  374. package/knowledge/cyberpunk2077/tweakdb.weapons.yaml +325 -0
  375. package/knowledge/cyberpunk2077/tweakxl.hotreload.yaml +151 -0
  376. package/knowledge/cyberpunk2077/tweakxl.yaml-syntax.yaml +208 -0
  377. package/knowledge/cyberpunk2077/ui.icons.yaml +259 -0
  378. package/knowledge/cyberpunk2077/ui.inkatlas.yaml +81 -0
  379. package/knowledge/cyberpunk2077/ui.modsettings.yaml +204 -0
  380. package/knowledge/cyberpunk2077/vehicles.control.yaml +475 -0
  381. package/knowledge/cyberpunk2077/vehicles.dashboard-ui.yaml +203 -0
  382. package/knowledge/cyberpunk2077/vehicles.entities.yaml +195 -0
  383. package/knowledge/cyberpunk2077/vehicles.wiring.yaml +137 -0
  384. package/knowledge/cyberpunk2077/wolvenkit.cli.yaml +167 -0
  385. package/knowledge/cyberpunk2077/workspot.system.yaml +55 -0
  386. package/knowledge/cyberpunk2077/world.interactions.yaml +41 -0
  387. package/knowledge/cyberpunk2077/world.loot-container.yaml +167 -0
  388. package/knowledge/cyberpunk2077/world.sectors.yaml +233 -0
  389. package/knowledge/eldenring/formats.binders.yaml +237 -0
  390. package/knowledge/eldenring/launcher.me3.yaml +230 -0
  391. package/knowledge/eldenring/launcher.modengine2.yaml +119 -0
  392. package/knowledge/eldenring/params.paramdef.yaml +149 -0
  393. package/knowledge/eldenring/params.regulation.yaml +142 -0
  394. package/knowledge/eldenring/saves.online.yaml +118 -0
  395. package/knowledge/eldenring/toolchain.cli.yaml +256 -0
  396. package/knowledge/nivalisnights/modding.runtime.yaml +157 -0
  397. package/knowledge/skyrimse/archives.bsa.yaml +212 -0
  398. package/knowledge/skyrimse/install.detection.yaml +41 -0
  399. package/knowledge/skyrimse/loadorder.files.yaml +242 -0
  400. package/knowledge/skyrimse/plugins.esl.yaml +189 -0
  401. package/knowledge/skyrimse/plugins.format.yaml +224 -0
  402. package/knowledge/skyrimse/skse.runtime.yaml +283 -0
  403. package/knowledge/skyrimse/toolchain.xedit-spriggit.yaml +336 -0
  404. package/knowledge/stardewvalley/contentpatcher.format.yaml +338 -0
  405. package/knowledge/stardewvalley/distribution.channels.yaml +236 -0
  406. package/knowledge/stardewvalley/game.versions.yaml +202 -0
  407. package/knowledge/stardewvalley/install.layout.yaml +277 -0
  408. package/knowledge/stardewvalley/smapi.loader.yaml +284 -0
  409. package/knowledge/stardewvalley/smapi.logs.yaml +329 -0
  410. package/knowledge/stardewvalley/smapi.manifest.yaml +293 -0
  411. package/knowledge/stardewvalley/toolchain.build.yaml +261 -0
  412. package/knowledge/stardewvalley/wiki.dataformat.yaml +130 -0
  413. package/knowledge/subnautica2/game.build.yaml +331 -0
  414. package/knowledge/subnautica2/modding.state.yaml +210 -0
  415. package/knowledge/subnautica2/ue5.containers.yaml +72 -0
  416. package/knowledge/subnautica2/ue5.paks.yaml +203 -0
  417. package/knowledge/subnautica2/ue5.tooling.yaml +175 -0
  418. package/knowledge/subnautica2/ue5.ue4ss.yaml +203 -0
  419. package/knowledge/valheim/bepinex.loader.yaml +247 -0
  420. package/knowledge/valheim/bepinex.plugins.yaml +251 -0
  421. package/knowledge/valheim/game.versions.yaml +321 -0
  422. package/knowledge/valheim/install.layout.yaml +216 -0
  423. package/knowledge/valheim/jotunn.library.yaml +334 -0
  424. package/knowledge/valheim/thunderstore.packaging.yaml +217 -0
  425. package/knowledge/valheim/toolchain.build.yaml +111 -0
  426. package/package.json +29 -0
  427. package/scaffolds/baldursgate3/new-class-injection.yaml +148 -0
  428. package/scaffolds/baldursgate3/new-item.yaml +264 -0
  429. package/scaffolds/baldursgate3/new-mod.yaml +174 -0
  430. package/scaffolds/baldursgate3/new-passive.yaml +100 -0
  431. package/scaffolds/baldursgate3/new-project.yaml +118 -0
  432. package/scaffolds/baldursgate3/new-quest-stub.yaml +159 -0
  433. package/scaffolds/baldursgate3/new-spell.yaml +102 -0
  434. package/scaffolds/baldursgate3/new-status.yaml +119 -0
  435. package/scaffolds/baldursgate3/sequences/subclass-kit.yaml +50 -0
  436. package/scaffolds/cyberpunk2077/edit-tweak.yaml +70 -0
  437. package/scaffolds/cyberpunk2077/mesh-export-preset.yaml +170 -0
  438. package/scaffolds/cyberpunk2077/new-entity-patch.yaml +255 -0
  439. package/scaffolds/cyberpunk2077/new-garment-refit.yaml +279 -0
  440. package/scaffolds/cyberpunk2077/new-item-chain.yaml +548 -0
  441. package/scaffolds/cyberpunk2077/new-localization.yaml +130 -0
  442. package/scaffolds/cyberpunk2077/new-mod-settings.yaml +133 -0
  443. package/scaffolds/cyberpunk2077/new-player-replacer.yaml +1003 -0
  444. package/scaffolds/cyberpunk2077/new-project.yaml +157 -0
  445. package/scaffolds/cyberpunk2077/new-sector-node.yaml +156 -0
  446. package/scaffolds/cyberpunk2077/new-tweak.yaml +121 -0
  447. package/scaffolds/cyberpunk2077/new-vehicle-livery.yaml +148 -0
  448. package/scaffolds/cyberpunk2077/new-workspot-entity.yaml +177 -0
  449. package/scaffolds/cyberpunk2077/sequences/iconic-weapon.yaml +72 -0
  450. package/scaffolds/cyberpunk2077/sequences/quickhack-takeover.yaml +213 -0
  451. package/scaffolds/stardewvalley/new-cp-patch.yaml +106 -0
  452. package/scaffolds/stardewvalley/new-csharp-mod.yaml +195 -0
  453. package/scaffolds/stardewvalley/new-project.yaml +184 -0
  454. package/scaffolds/stardewvalley/sequences/content-pack.yaml +31 -0
  455. package/scripts/mw-tool.mjs +184 -0
@@ -0,0 +1,175 @@
1
+ -- MODWRIGHT-BRIDGE-DO-NOT-SHIP
2
+ --
3
+ -- ModWrightBridge / Watch.lua — listeners for `effect: "observe"` probes
4
+ -- (an observe probe registers its listener at arm time and is harvested when window.seconds
5
+ -- elapses).
6
+ --
7
+ -- Why watching and not doing: `Osi.UseSpell` was observed to re-cast, move the caster and
8
+ -- self-kill via an HP-cost passive, and was removed from the mod that used it. So "spell
9
+ -- resolved" is reachable only by watching while the human casts — this bridge never calls
10
+ -- an Osiris action and never forces a cast.
11
+ --
12
+ -- ============================================================================
13
+ -- Ext API used in this file
14
+ -- ============================================================================
15
+ -- API.md §"Calling Lua from Osiris" / "Capturing Events/Calls":
16
+ -- `Ext.Osiris.RegisterListener(name, arity, event, handler)`
17
+ -- - `arity` is "the number of columns for DBs or the number of parameters (both IN and OUT)"
18
+ -- - `event` is one of `before`, `after`, `beforeDelete`, `afterDelete`
19
+ -- - "handler is a Lua function ... The function receives all parameters of the original DB/function."
20
+ -- Example: `Ext.Osiris.RegisterListener("TurnEnded", 1, "after", function (characterGuid) ... end)`
21
+ -- Arities this bridge is likely to be asked for (observed in game; wrong arity gives a
22
+ -- silently dead listener): CastedSpell 5, StatusApplied 4, StatusRemoved 4,
23
+ -- Died 1, KilledBy 4, UsingSpellOnTarget 6.
24
+ -- API.md §"SE Events":
25
+ -- `Ext.Events.<EVENT_NAME>:Subscribe(fun)` returning "a handler index that can be used to
26
+ -- cancel the subscription later on", and `Ext.Events.<EVENT_NAME>:Unsubscribe(handlerId)`.
27
+ --
28
+ -- KNOWN LIMIT, stated rather than hidden: API.md documents `Unsubscribe` for `Ext.Events` but
29
+ -- lists NO unregister for `Ext.Osiris.RegisterListener`. So an Osiris listener, once armed,
30
+ -- lives until the Lua state is reloaded. This module therefore registers at most ONE engine
31
+ -- listener per (name, arity) per Lua state and fans out to per-probe subscriber records that
32
+ -- can be deactivated; repeated observe requests reuse the same registration instead of
33
+ -- stacking a new dead closure on every run.
34
+
35
+ local Log = Ext.Require("ModWrightBridge/Log.lua")
36
+ local Protocol = Ext.Require("ModWrightBridge/Protocol.lua")
37
+
38
+ local Watch = {}
39
+
40
+ --- key "<name>/<arity>" -> { subscribers = { watchRecord, ... } }
41
+ Watch.osirisRegistry = {}
42
+
43
+ --- Capture one call's varargs as JSON-safe values. Osiris hands strings and numbers; anything
44
+ --- else is stringified rather than dropped, and an actual nil becomes "<nil>" so the argument
45
+ --- list keeps its positions (a hole would make the array encode short).
46
+ local function captureArgs(n, ...)
47
+ local args = Protocol.array({})
48
+ for i = 1, n do
49
+ local v = select(i, ...)
50
+ local t = type(v)
51
+ if v == nil then
52
+ args[i] = "<nil>"
53
+ elseif t == "number" or t == "string" or t == "boolean" then
54
+ args[i] = v
55
+ else
56
+ args[i] = tostring(v)
57
+ end
58
+ end
59
+ return args
60
+ end
61
+
62
+ --- `match` is a map from 1-based argument position to an expected value. JSON object keys are
63
+ --- strings, so both `match[i]` and `match[tostring(i)]` are honoured. GUID comparisons go
64
+ --- through Protocol.normGuid, because Osiris hands the same
65
+ --- entity as a bare UUID in some events and as a prefixed `Name_UUID` in others.
66
+ local function rowMatches(match, args)
67
+ if type(match) ~= "table" then return true end
68
+ for k, want in pairs(match) do
69
+ local idx = tonumber(k)
70
+ if idx ~= nil then
71
+ local got = args[idx]
72
+ local a, b = tostring(got), tostring(want)
73
+ if a ~= b and Protocol.normGuid(a) ~= Protocol.normGuid(b) then
74
+ return false
75
+ end
76
+ end
77
+ end
78
+ return true
79
+ end
80
+
81
+ --- Arm (or join) an Osiris listener. Returns a watch record, or (nil, error string).
82
+ function Watch.osiris(name, arity, match, limit)
83
+ if type(name) ~= "string" or name == "" then return nil, "params.name is required" end
84
+ local n = tonumber(arity)
85
+ if n == nil then
86
+ return nil, "params.arity is required and must be a number (a wrong arity gives a silently dead listener)"
87
+ end
88
+
89
+ local key = name .. "/" .. tostring(math.floor(n))
90
+ local reg = Watch.osirisRegistry[key]
91
+ if reg == nil then
92
+ reg = { subscribers = {} }
93
+ local ok, err = pcall(function()
94
+ Ext.Osiris.RegisterListener(name, math.floor(n), "after", Log.guarded("osiris:" .. key, function(...)
95
+ local argc = select("#", ...)
96
+ local args = captureArgs(argc, ...)
97
+ local at = Log.monotonic()
98
+ for _, w in ipairs(reg.subscribers) do
99
+ if w.active and #w.rows < w.limit and rowMatches(w.match, args) then
100
+ w.rows[#w.rows + 1] = { at = at, args = args }
101
+ end
102
+ end
103
+ end))
104
+ end)
105
+ if not ok then
106
+ return nil, "Ext.Osiris.RegisterListener(\"" .. name .. "\", " .. tostring(n) .. ", \"after\", ...) failed: " .. tostring(err)
107
+ end
108
+ Watch.osirisRegistry[key] = reg
109
+ Log.info("armed Osiris listener " .. key .. " (after)")
110
+ end
111
+
112
+ local w = {
113
+ kind = "osiris",
114
+ key = key,
115
+ name = name,
116
+ arity = math.floor(n),
117
+ match = match,
118
+ limit = tonumber(limit) or 64,
119
+ rows = Protocol.array({}),
120
+ active = true,
121
+ }
122
+ reg.subscribers[#reg.subscribers + 1] = w
123
+ return w
124
+ end
125
+
126
+ --- Arm an `Ext.Events.<name>` subscription. Returns a watch record, or (nil, error string).
127
+ --- Used for `bg3.event.damage`'s `EsvLuaBeforeDealDamage`, which is
128
+ --- **unverified (event fields)**: it is NOT in API.md's event table, only used in a
129
+ --- shipped SE mod. Hence the existence check below, and
130
+ --- hence rows are dumped WHOLE rather than read through a field path nothing pins.
131
+ function Watch.engineEvent(name, limit)
132
+ if type(name) ~= "string" or name == "" then return nil, "event name is required" end
133
+ local ev
134
+ pcall(function() ev = Ext.Events[name] end)
135
+ if ev == nil then
136
+ return nil, "Ext.Events." .. name .. " does not exist in this Script Extender build (it is not in API.md's event table either)"
137
+ end
138
+
139
+ local w = {
140
+ kind = "event",
141
+ name = name,
142
+ limit = tonumber(limit) or 10,
143
+ rows = Protocol.array({}),
144
+ active = true,
145
+ eventRef = ev,
146
+ }
147
+
148
+ local ok, handlerId = pcall(function()
149
+ return ev:Subscribe(Log.guarded("event:" .. name, function(e)
150
+ if not w.active then return end
151
+ if #w.rows >= w.limit then return end
152
+ local tbl = Protocol.dumpComponent(e, 6)
153
+ w.rows[#w.rows + 1] = { at = Log.monotonic(), event = tbl }
154
+ end))
155
+ end)
156
+ if not ok then
157
+ return nil, "Ext.Events." .. name .. ":Subscribe failed: " .. tostring(handlerId)
158
+ end
159
+ w.handlerId = handlerId
160
+ Log.info("armed engine event listener " .. name)
161
+ return w
162
+ end
163
+
164
+ --- Deactivate a watch. Engine-event subscriptions are unsubscribed (API.md documents it);
165
+ --- Osiris subscribers are only deactivated, because API.md documents no unregister for them.
166
+ function Watch.stop(w)
167
+ if type(w) ~= "table" then return end
168
+ w.active = false
169
+ if w.kind == "event" and w.eventRef ~= nil and w.handlerId ~= nil then
170
+ pcall(function() w.eventRef:Unsubscribe(w.handlerId) end)
171
+ w.eventRef = nil
172
+ end
173
+ end
174
+
175
+ return Watch
@@ -0,0 +1,45 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <save>
3
+ <version major="4" minor="8" revision="0" build="500" />
4
+ <region id="Config">
5
+ <node id="root">
6
+ <children>
7
+ <node id="Conflicts" />
8
+ <node id="Dependencies" />
9
+ <node id="ModuleInfo">
10
+ <attribute id="Author" type="LSString" value="ModWright" />
11
+ <attribute id="CharacterCreationLevelName" type="FixedString" value="" />
12
+ <attribute id="Description" type="LSString" value="MODWRIGHT-BRIDGE-DO-NOT-SHIP. ModWright's author-only verification bridge: reads entity components and stats on request and writes the answers to the Script Extender folder. Never ship this with a mod." />
13
+ <attribute id="FileSize" type="uint64" value="0" />
14
+ <attribute id="Folder" type="LSString" value="ModWrightBridge" />
15
+ <attribute id="LobbyLevelName" type="FixedString" value="" />
16
+ <attribute id="MD5" type="LSString" value="" />
17
+ <attribute id="MainMenuBackgroundVideo" type="FixedString" value="" />
18
+ <attribute id="MenuLevelName" type="FixedString" value="" />
19
+ <attribute id="Name" type="FixedString" value="ModWrightBridge" />
20
+ <attribute id="NumPlayers" type="uint8" value="4" />
21
+ <attribute id="PhotoBooth" type="FixedString" value="" />
22
+ <attribute id="PublishHandle" type="uint64" value="0" />
23
+ <attribute id="StartupLevelName" type="FixedString" value="" />
24
+ <attribute id="Tags" type="LSString" value="" />
25
+ <attribute id="Type" type="FixedString" value="Add-on" />
26
+ <attribute id="UUID" type="FixedString" value="2f81bf4a-d9c7-43c5-a5e1-16c5e1d6fbc9" />
27
+ <attribute id="Version64" type="int64" value="36028797018963968" />
28
+ <children>
29
+ <node id="PublishVersion">
30
+ <attribute id="Version64" type="int64" value="36028797018963968" />
31
+ </node>
32
+ <node id="Scripts" />
33
+ <node id="TargetModes">
34
+ <children>
35
+ <node id="Target">
36
+ <attribute id="Object" type="FixedString" value="Story" />
37
+ </node>
38
+ </children>
39
+ </node>
40
+ </children>
41
+ </node>
42
+ </children>
43
+ </node>
44
+ </region>
45
+ </save>
@@ -0,0 +1,99 @@
1
+ # bg3-se bridge
2
+
3
+ The Baldur's Gate 3 Script Extender bridge: ModWright's author-only, read-only verification
4
+ mod. It writes a heartbeat while loaded, polls for an armed request, runs the probes that
5
+ request names, and writes a result plus a `done` marker. It is staged by
6
+ `stageBridge(project, "baldursgate3")` (`src/core/bridge/stage.ts`) into
7
+ `<project>/.modwright/bridge/bg3-se/`, and `deploy --variant withBridge` copies
8
+ `Mods/ModWrightBridge` from there into the project's `loose` root
9
+ (`Data/Mods/ModWrightBridge`).
10
+
11
+ The protocol is implemented on the Node side in `src/core/bridge/`; the probe catalogue is
12
+ the dispatch table in `Probes.lua`.
13
+
14
+ ## Module identity
15
+
16
+ | | |
17
+ |---|---|
18
+ | Module UUID | `2f81bf4a-d9c7-43c5-a5e1-16c5e1d6fbc9` |
19
+ | `Folder` / `Name` | `ModWrightBridge` |
20
+ | `Version64` | `36028797018963968` (1.0.0.0) |
21
+ | `ModTable` | `ModWrightBridge` |
22
+ | `RequiredVersion` | `21` |
23
+
24
+ The UUID is **fixed and published here**: it is generated once and never
25
+ regenerated, because it is what a person pastes into a test profile's `modsettings.lsx`
26
+ `ModuleShortDesc` and what `bg3.mod.active` would be asked about. `RequiredVersion: 21`
27
+ matches the floor of a shipped SE mod rather than API.md's
28
+ example 29, so the bridge never demands a newer extender than the mod under test; anything
29
+ newer it wants (`Ext.Timer.ClockEpoch`, `Ext.Utils.GetCommandLineParams`) is `pcall`ed and
30
+ degraded gracefully when absent. `Version64` is Larian's packed form
31
+ (`major<<55 | minor<<47 | revision<<31 | build`), the same encoding other mods' meta.lsx files use.
32
+
33
+ ## protocolVersion
34
+
35
+ **1** — the current value of `PROTOCOL_VERSION` in `src/core/bridge/types.ts`. The Lua
36
+ defines the identical integer literal as `Protocol.PROTOCOL_VERSION`
37
+ (`ScriptExtender/Lua/ModWrightBridge/Protocol.lua`): `protocolVersion` is an
38
+ integer duplicated in the Lua and the Node constant, checked at arm time.
39
+ `test/unit/bridge/bg3-lua-parity.test.ts` asserts the two literals agree.
40
+
41
+ ## The tree
42
+
43
+ ```
44
+ bridges/bg3-se/
45
+ bridge.json # id, protocolVersion, version, file list, sha256s
46
+ README.md # this file
47
+ Mods/ModWrightBridge/
48
+ meta.lsx # Folder/Name/UUID/Version64
49
+ ScriptExtender/
50
+ Config.json # {"RequiredVersion":21,"ModTable":"ModWrightBridge","FeatureFlags":["Lua"]}
51
+ Lua/BootstrapServer.lua # registration point (SessionLoaded + ResetCompleted)
52
+ Lua/BootstrapClient.lua # client heartbeat + client probes only
53
+ Lua/ModWrightBridge/Protocol.lua # io + marker framing + nonce + heartbeat + run orchestration
54
+ Lua/ModWrightBridge/Probes.lua # server dispatch table (all 14 probe ids)
55
+ Lua/ModWrightBridge/ProbesClient.lua # client dispatch table (bg3.client.loaded)
56
+ Lua/ModWrightBridge/Watch.lua # observe-probe listeners
57
+ Lua/ModWrightBridge/Log.lua # [ModWrightBridge] prints + rolling ModWright_log.json
58
+ ```
59
+
60
+ `bridge.json`'s `files[]` carries a `sha256` per file: plain `sha256` over the file's raw
61
+ bytes, hex, keyed by a POSIX path relative to this directory. `bridge stage` copies the tree
62
+ verbatim and does **not** fill them in, and nothing in ModWright reads them yet — they exist
63
+ so a staged or deployed copy can be compared against the source of truth by hand. Recompute
64
+ them (and bump `version`) whenever a file here changes; `bridge.json` itself is excluded from
65
+ its own list.
66
+
67
+ ## The content banner
68
+
69
+ `BRIDGE_BANNER` in `src/core/bridge/types.ts` (`"MODWRIGHT-BRIDGE-DO-NOT-SHIP"`) appears,
70
+ verbatim, in the **first line** of every `.lua` file here and in the module's `meta.lsx`
71
+ description. This is what lets `bg3.history.bridge-never-ships`
72
+ (`src/surfaces/baldursgate3/validators/bridge.ts`) catch a bridge file that reached a build
73
+ output under a path that no longer says "ModWrightBridge" — e.g. flattened during packaging
74
+ — not just one that still does. The validator reads only the first 1024 bytes, so the banner
75
+ must stay on the first line: `bg3-lua-parity.test.ts` enforces that.
76
+
77
+ ## Checking the Lua
78
+
79
+ No Lua parser is vendored. Syntax is checked with `luac -p` under Lua 5.1 and
80
+ 5.4 (every file here passes both as shipped); drift is checked by
81
+ `test/unit/bridge/bg3-lua-parity.test.ts`, which reads the Lua as text and asserts the
82
+ dispatch-table keys equal the catalogue's probe ids, that the `PROTOCOL_VERSION` literals
83
+ agree, that `bridge.json` lists every shipped file, and that every `.lua` carries the banner.
84
+
85
+ ## What this bridge never does
86
+
87
+ - No Osiris **action**, ever, and no forced cast: `Osi.UseSpell` was observed to re-cast,
88
+ move the caster and self-kill via an HP-cost passive. `observe` probes watch while the
89
+ human acts.
90
+ - No Osiris **query** as a source of truth: the whole query set was observed returning
91
+ wrong/false on the tested build. Every read is an entity-component read. The
92
+ two deliberate exceptions — `Osi.GetMaxHitpoints` inside `bg3.osiris.health`, where the
93
+ query's unreliability *is* the measurement, and `Osi.GetHostCharacter()` to expand the
94
+ `"$host"` token — are named at the top of `Probes.lua` and stamped into probe evidence as
95
+ `hostResolvedVia`.
96
+ - No `PersistentVars`, `ModVars` or `UserVars` writes (API.md §"Persistence":
97
+ "PersistentVars are deprecated and should not be used").
98
+ - No file deletion or rename: `Ext.IO` has none, which is why a consumed
99
+ request is retired by an in-memory nonce plus the request's own `armedUntil`.
@@ -0,0 +1,68 @@
1
+ {
2
+ "id": "bg3-se",
3
+ "game": "baldursgate3",
4
+ "protocolVersion": 1,
5
+ "version": "0.1.0",
6
+ "moduleUuid": "2f81bf4a-d9c7-43c5-a5e1-16c5e1d6fbc9",
7
+ "moduleFolder": "ModWrightBridge",
8
+ "requiredExtenderVersion": 21,
9
+ "banner": "MODWRIGHT-BRIDGE-DO-NOT-SHIP",
10
+ "deploy": {
11
+ "rootId": "loose",
12
+ "from": ".modwright/bridge/bg3-se/Mods/ModWrightBridge",
13
+ "into": "Mods/ModWrightBridge",
14
+ "variant": "withBridge",
15
+ "locked": false,
16
+ "backup": true,
17
+ "prune": [
18
+ "ModWrightBridge/**"
19
+ ],
20
+ "note": "The deploy target a shipped SE mod uses, verbatim: `bridge stage` adds it to the project's deploy targets when no target already names this rootId, into and variant, so a fresh project deploys the bridge without a hand edit. A deploy WITHOUT `--variant withBridge` prunes the folder back out, with backup."
21
+ },
22
+ "sha256": {
23
+ "algorithm": "sha256",
24
+ "encoding": "hex",
25
+ "over": "the file's raw bytes, unmodified",
26
+ "paths": "POSIX-separated, relative to bridges/bg3-se/",
27
+ "regenerate": "python3 -c \"import hashlib,sys;print(hashlib.sha256(open(sys.argv[1],'rb').read()).hexdigest())\" <path>",
28
+ "note": "Recomputed by hand whenever a file here changes; `bridge stage` (src/core/bridge/stage.ts) copies the tree verbatim and does not fill these in, and nothing in ModWright reads them yet. They exist so a staged or deployed copy can be compared against the source of truth by hand."
29
+ },
30
+ "files": [
31
+ {
32
+ "path": "Mods/ModWrightBridge/ScriptExtender/Config.json",
33
+ "sha256": "50bf2bf72fc7f84b7ab373e9ecf1455dd8032e034701d29b08990a1a0b34a057"
34
+ },
35
+ {
36
+ "path": "Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapClient.lua",
37
+ "sha256": "3c867c190e9c0f091d06cff59b43acb5e6fbaa067f18c27d23f8b8d07e66e402"
38
+ },
39
+ {
40
+ "path": "Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapServer.lua",
41
+ "sha256": "40ba495dc6ca17640b921620e83f62ffb72503294456c898936d47bbb6e2aa6c"
42
+ },
43
+ {
44
+ "path": "Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Log.lua",
45
+ "sha256": "a0297f2d93175efce05638c5806baf126b025a26ac61f30abb936f3112822c9d"
46
+ },
47
+ {
48
+ "path": "Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Probes.lua",
49
+ "sha256": "76ca8cd1ddc993bd0e8bdb40c55e21021d4245b686bda64d4a9f9bb9f7f2c0e0"
50
+ },
51
+ {
52
+ "path": "Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/ProbesClient.lua",
53
+ "sha256": "8769934b38702435fb8f36c561d5a257010f5cd58a342982dc0d285ed9946e0f"
54
+ },
55
+ {
56
+ "path": "Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Protocol.lua",
57
+ "sha256": "ee62d070fd15ca818198c0403fdb659930fc04d1841c7fa1433e18d3abdd60ba"
58
+ },
59
+ {
60
+ "path": "Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Watch.lua",
61
+ "sha256": "8dc31ba46f6ab03e5804742292be46f8a8124259370fe33fbcdde96a6d17557d"
62
+ },
63
+ {
64
+ "path": "Mods/ModWrightBridge/meta.lsx",
65
+ "sha256": "ac6fd48f1dc547c3f95abd56c3bceb9252ebca258ef23c74a50c35138d5d24c7"
66
+ }
67
+ ]
68
+ }