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,113 @@
1
+ import { satisfies } from "./version.js";
2
+ export function checkCompat(components, rules) {
3
+ const byId = new Map(components.map((c) => [c.id, c]));
4
+ const issues = [];
5
+ const undetermined = new Set();
6
+ for (const c of components) {
7
+ if (c.installed && c.version === undefined)
8
+ undetermined.add(c.id);
9
+ }
10
+ for (const rule of rules) {
11
+ if (!byId.get(rule.component)?.installed)
12
+ continue;
13
+ if (rule.advisory) {
14
+ evaluateAdvisoryRule(rule, byId, issues);
15
+ continue;
16
+ }
17
+ for (const req of rule.requires) {
18
+ const required = byId.get(req.component);
19
+ if (!required?.installed) {
20
+ issues.push({
21
+ ruleId: rule.id,
22
+ severity: rule.severity ?? "block",
23
+ component: req.component,
24
+ message: `${rule.component} requires ${req.component}, which is not installed.`,
25
+ hint: rule.note,
26
+ });
27
+ continue;
28
+ }
29
+ const result = satisfies(required.version, req);
30
+ if (result === "undetermined") {
31
+ issues.push({
32
+ ruleId: rule.id,
33
+ severity: rule.undeterminedSeverity ?? "warn",
34
+ component: req.component,
35
+ message: `${req.component}'s version could not be determined, so ${rule.component}'s ` +
36
+ `requirement on it (${describeRequirement(req)}) could not be checked.`,
37
+ hint: rule.note,
38
+ });
39
+ }
40
+ else if (result === "unsatisfied") {
41
+ issues.push({
42
+ ruleId: rule.id,
43
+ severity: rule.severity ?? "block",
44
+ component: req.component,
45
+ message: `${req.component} ${required.version ?? "?"} does not satisfy ${rule.component}'s ` +
46
+ `requirement (${describeRequirement(req)}).`,
47
+ hint: rule.note,
48
+ });
49
+ }
50
+ }
51
+ }
52
+ const hasBlock = issues.some((i) => i.severity === "block");
53
+ const hasWarn = issues.some((i) => i.severity === "warn");
54
+ const status = hasBlock ? "broken" : hasWarn ? "degraded" : "ok";
55
+ return {
56
+ game: "",
57
+ install: "",
58
+ components,
59
+ issues,
60
+ undetermined: [...undetermined].sort(),
61
+ status,
62
+ note: summarize(issues, rules.length, components),
63
+ };
64
+ }
65
+ function evaluateAdvisoryRule(rule, byId, issues) {
66
+ const allInstalled = rule.requires.every((r) => byId.get(r.component)?.installed);
67
+ if (!allInstalled)
68
+ return;
69
+ const gateKnown = rule.versionGate === undefined || byId.get(rule.versionGate)?.version !== undefined;
70
+ issues.push({
71
+ ruleId: rule.id,
72
+ severity: gateKnown ? rule.severity ?? "warn" : rule.undeterminedSeverity ?? "info",
73
+ component: rule.component,
74
+ message: rule.note,
75
+ hint: rule.source,
76
+ });
77
+ }
78
+ function describeRequirement(req) {
79
+ if (req.exact !== undefined)
80
+ return `exactly ${req.exact}`;
81
+ const parts = [];
82
+ if (req.min !== undefined)
83
+ parts.push(`>= ${req.min}`);
84
+ if (req.max !== undefined)
85
+ parts.push(`<= ${req.max}`);
86
+ return parts.length > 0 ? parts.join(", ") : "installed";
87
+ }
88
+ function summarize(issues, ruleCount, components) {
89
+ if (issues.length === 0) {
90
+ const installedCount = components.filter((c) => c.installed).length;
91
+ return `No incompatibilities found among ${installedCount} detected component(s) against ${ruleCount} rule(s).`;
92
+ }
93
+ const blockCount = issues.filter((i) => i.severity === "block").length;
94
+ const warnCount = issues.filter((i) => i.severity === "warn").length;
95
+ const infoCount = issues.filter((i) => i.severity === "info").length;
96
+ return `${blockCount} blocking, ${warnCount} warning, ${infoCount} informational issue(s) across ${ruleCount} rule(s).`;
97
+ }
98
+ export async function runCompat(surface, install) {
99
+ if (!surface.compat) {
100
+ return {
101
+ game: surface.id,
102
+ install: install.root,
103
+ components: [],
104
+ issues: [],
105
+ undetermined: [],
106
+ status: "unknown",
107
+ note: `${surface.name} has no compatibility checks implemented yet.`,
108
+ };
109
+ }
110
+ const components = await surface.compat.detectComponents(install);
111
+ const report = checkCompat(components, surface.compat.rules);
112
+ return { ...report, game: surface.id, install: install.root };
113
+ }
@@ -0,0 +1,220 @@
1
+ import { promises as fs } from "node:fs";
2
+ const DOS_MAGIC = 0x5a4d;
3
+ const PE_SIGNATURE = 0x00004550;
4
+ const RT_VERSION = 16;
5
+ const VS_FIXEDFILEINFO_SIGNATURE = 0xfeef04bd;
6
+ const MAX_SECTIONS = 96;
7
+ const MAX_RESOURCE_ENTRIES = 1024;
8
+ const MAX_VERSIONINFO_BYTES = 1_000_000;
9
+ export async function readPeFileVersion(filePath) {
10
+ let handle;
11
+ try {
12
+ handle = await fs.open(filePath, "r");
13
+ }
14
+ catch {
15
+ return undefined;
16
+ }
17
+ try {
18
+ return await readVersion(handle);
19
+ }
20
+ catch {
21
+ return undefined;
22
+ }
23
+ finally {
24
+ await handle.close();
25
+ }
26
+ }
27
+ export const PE_MACHINE_AMD64 = 0x8664;
28
+ export const PE_MACHINE_I386 = 0x014c;
29
+ const PE32_MAGIC = 0x10b;
30
+ const PE32_PLUS_MAGIC = 0x20b;
31
+ const MAX_EXPORT_NAMES = 65_536;
32
+ const MAX_EXPORT_NAME_BYTES = 1024;
33
+ export async function readPeImageInfo(filePath) {
34
+ let handle;
35
+ try {
36
+ handle = await fs.open(filePath, "r");
37
+ }
38
+ catch {
39
+ return undefined;
40
+ }
41
+ try {
42
+ return await readImageInfo(handle);
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ finally {
48
+ await handle.close();
49
+ }
50
+ }
51
+ async function readImageInfo(handle) {
52
+ const dos = await readRange(handle, 0, 64);
53
+ if (dos.readUInt16LE(0) !== DOS_MAGIC)
54
+ return undefined;
55
+ const peOffset = dos.readUInt32LE(0x3c);
56
+ const coff = await readRange(handle, peOffset, 24);
57
+ if (coff.readUInt32LE(0) !== PE_SIGNATURE)
58
+ return undefined;
59
+ const machine = coff.readUInt16LE(4);
60
+ const numberOfSections = coff.readUInt16LE(6);
61
+ const sizeOfOptionalHeader = coff.readUInt16LE(20);
62
+ if (numberOfSections <= 0 || numberOfSections > MAX_SECTIONS || sizeOfOptionalHeader < 2)
63
+ return undefined;
64
+ const optional = await readRange(handle, peOffset + 24, sizeOfOptionalHeader);
65
+ const magic = optional.readUInt16LE(0);
66
+ if (magic !== PE32_MAGIC && magic !== PE32_PLUS_MAGIC)
67
+ return undefined;
68
+ const pe32Plus = magic === PE32_PLUS_MAGIC;
69
+ const rvaCountAt = pe32Plus ? 108 : 92;
70
+ const dirsAt = pe32Plus ? 112 : 96;
71
+ if (sizeOfOptionalHeader < dirsAt + 8)
72
+ return { machine, pe32Plus, exports: [] };
73
+ const numberOfRvaAndSizes = optional.readUInt32LE(rvaCountAt);
74
+ const exportRva = numberOfRvaAndSizes > 0 ? optional.readUInt32LE(dirsAt) : 0;
75
+ const exportSize = numberOfRvaAndSizes > 0 ? optional.readUInt32LE(dirsAt + 4) : 0;
76
+ if (exportRva === 0 || exportSize === 0)
77
+ return { machine, pe32Plus, exports: [] };
78
+ const sectionTable = await readRange(handle, peOffset + 24 + sizeOfOptionalHeader, numberOfSections * 40);
79
+ const rvaToFile = (rva) => {
80
+ for (let i = 0; i < numberOfSections; i++) {
81
+ const entry = sectionTable.subarray(i * 40, i * 40 + 40);
82
+ const virtualSize = entry.readUInt32LE(8);
83
+ const virtualAddress = entry.readUInt32LE(12);
84
+ const sizeOfRawData = entry.readUInt32LE(16);
85
+ const pointerToRawData = entry.readUInt32LE(20);
86
+ const span = Math.max(virtualSize, sizeOfRawData);
87
+ if (rva >= virtualAddress && rva < virtualAddress + span)
88
+ return rva - virtualAddress + pointerToRawData;
89
+ }
90
+ return undefined;
91
+ };
92
+ const dirAt = rvaToFile(exportRva);
93
+ if (dirAt === undefined)
94
+ return undefined;
95
+ const dir = await readRange(handle, dirAt, 40);
96
+ const numberOfNames = dir.readUInt32LE(24);
97
+ const addressOfNames = dir.readUInt32LE(32);
98
+ if (numberOfNames === 0)
99
+ return { machine, pe32Plus, exports: [] };
100
+ if (numberOfNames > MAX_EXPORT_NAMES)
101
+ return undefined;
102
+ const namesAt = rvaToFile(addressOfNames);
103
+ if (namesAt === undefined)
104
+ return undefined;
105
+ const nameRvas = await readRange(handle, namesAt, numberOfNames * 4);
106
+ const exports = [];
107
+ for (let i = 0; i < numberOfNames; i++) {
108
+ const nameAt = rvaToFile(nameRvas.readUInt32LE(i * 4));
109
+ if (nameAt === undefined)
110
+ return undefined;
111
+ const buffer = Buffer.alloc(MAX_EXPORT_NAME_BYTES);
112
+ const { bytesRead } = await handle.read(buffer, 0, MAX_EXPORT_NAME_BYTES, nameAt);
113
+ const end = buffer.subarray(0, bytesRead).indexOf(0);
114
+ if (end <= 0)
115
+ return undefined;
116
+ exports.push(buffer.subarray(0, end).toString("latin1"));
117
+ }
118
+ return { machine, pe32Plus, exports };
119
+ }
120
+ async function readRange(handle, offset, length) {
121
+ if (offset < 0 || length <= 0)
122
+ throw new RangeError("invalid range");
123
+ const buffer = Buffer.alloc(length);
124
+ const { bytesRead } = await handle.read(buffer, 0, length, offset);
125
+ if (bytesRead < length)
126
+ throw new RangeError("short read");
127
+ return buffer;
128
+ }
129
+ async function readVersion(handle) {
130
+ const dos = await readRange(handle, 0, 64);
131
+ if (dos.readUInt16LE(0) !== DOS_MAGIC)
132
+ return undefined;
133
+ const peOffset = dos.readUInt32LE(0x3c);
134
+ const coff = await readRange(handle, peOffset, 24);
135
+ if (coff.readUInt32LE(0) !== PE_SIGNATURE)
136
+ return undefined;
137
+ const numberOfSections = coff.readUInt16LE(6);
138
+ const sizeOfOptionalHeader = coff.readUInt16LE(20);
139
+ if (numberOfSections <= 0 || numberOfSections > MAX_SECTIONS)
140
+ return undefined;
141
+ const sectionTableOffset = peOffset + 24 + sizeOfOptionalHeader;
142
+ const sectionTable = await readRange(handle, sectionTableOffset, numberOfSections * 40);
143
+ const rsrc = findRsrcSection(sectionTable, numberOfSections);
144
+ if (!rsrc)
145
+ return undefined;
146
+ return readVersionFromRsrc(handle, rsrc);
147
+ }
148
+ function findRsrcSection(sectionTable, numberOfSections) {
149
+ for (let i = 0; i < numberOfSections; i++) {
150
+ const entry = sectionTable.subarray(i * 40, i * 40 + 40);
151
+ const name = entry.subarray(0, 8).toString("latin1").replace(/\0+$/, "");
152
+ if (name === ".rsrc") {
153
+ return {
154
+ virtualAddress: entry.readUInt32LE(12),
155
+ pointerToRawData: entry.readUInt32LE(20),
156
+ };
157
+ }
158
+ }
159
+ return undefined;
160
+ }
161
+ async function readVersionFromRsrc(handle, rsrc) {
162
+ const dirOffsetToFile = (relativeOffset) => rsrc.pointerToRawData + relativeOffset;
163
+ const rvaToFile = (rva) => rva - rsrc.virtualAddress + rsrc.pointerToRawData;
164
+ const versionEntry = await findEntryById(handle, dirOffsetToFile(0), RT_VERSION);
165
+ if (versionEntry === undefined)
166
+ return undefined;
167
+ const nameDirOffset = dirOffsetToFile(versionEntry & 0x7fffffff);
168
+ const nameEntry = await findFirstEntry(handle, nameDirOffset);
169
+ if (nameEntry === undefined)
170
+ return undefined;
171
+ const langDirOffset = dirOffsetToFile(nameEntry & 0x7fffffff);
172
+ const langEntry = await findFirstEntry(handle, langDirOffset);
173
+ if (langEntry === undefined || (langEntry & 0x80000000) !== 0)
174
+ return undefined;
175
+ const dataEntry = await readRange(handle, dirOffsetToFile(langEntry), 16);
176
+ const dataRva = dataEntry.readUInt32LE(0);
177
+ const dataSize = dataEntry.readUInt32LE(4);
178
+ if (dataSize <= 0 || dataSize > MAX_VERSIONINFO_BYTES)
179
+ return undefined;
180
+ const payload = await readRange(handle, rvaToFile(dataRva), dataSize);
181
+ return extractFixedFileInfoVersion(payload);
182
+ }
183
+ async function findEntryById(handle, offset, id) {
184
+ const header = await readRange(handle, offset, 16);
185
+ const namedCount = header.readUInt16LE(12);
186
+ const idCount = header.readUInt16LE(14);
187
+ const total = namedCount + idCount;
188
+ if (total <= 0 || total > MAX_RESOURCE_ENTRIES)
189
+ return undefined;
190
+ const entries = await readRange(handle, offset + 16, total * 8);
191
+ for (let i = namedCount; i < total; i++) {
192
+ const entry = entries.subarray(i * 8, i * 8 + 8);
193
+ if (entry.readUInt32LE(0) === id)
194
+ return entry.readUInt32LE(4);
195
+ }
196
+ return undefined;
197
+ }
198
+ async function findFirstEntry(handle, offset) {
199
+ const header = await readRange(handle, offset, 16);
200
+ const namedCount = header.readUInt16LE(12);
201
+ const idCount = header.readUInt16LE(14);
202
+ if (namedCount + idCount <= 0)
203
+ return undefined;
204
+ const entry = await readRange(handle, offset + 16, 8);
205
+ return entry.readUInt32LE(4);
206
+ }
207
+ function extractFixedFileInfoVersion(payload) {
208
+ for (let offset = 0; offset + 16 <= payload.length; offset += 4) {
209
+ if (payload.readUInt32LE(offset) !== VS_FIXEDFILEINFO_SIGNATURE)
210
+ continue;
211
+ const ms = payload.readUInt32LE(offset + 8);
212
+ const ls = payload.readUInt32LE(offset + 12);
213
+ const major = ms >>> 16;
214
+ const minor = ms & 0xffff;
215
+ const build = ls >>> 16;
216
+ const revision = ls & 0xffff;
217
+ return `${major}.${minor}.${build}.${revision}`;
218
+ }
219
+ return undefined;
220
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,70 @@
1
+ const VERSION_PATTERN = /^\s*[vV]?(\d+(?:\.\d+)*)(.*)$/;
2
+ export function parseVersion(s) {
3
+ const match = VERSION_PATTERN.exec(s);
4
+ if (!match)
5
+ return undefined;
6
+ const numericPart = match[1];
7
+ const rest = match[2] ?? "";
8
+ if (!numericPart)
9
+ return undefined;
10
+ const numeric = numericPart.split(".").map((piece) => Number.parseInt(piece, 10));
11
+ if (numeric.length === 0 || numeric.some((n) => Number.isNaN(n)))
12
+ return undefined;
13
+ return { raw: s, numeric, suffix: rest.trim() };
14
+ }
15
+ export function isDifferentVersionAxis(a, b) {
16
+ const pa = parseVersion(a);
17
+ const pb = parseVersion(b);
18
+ if (!pa || !pb)
19
+ return false;
20
+ return pa.numeric.length !== pb.numeric.length;
21
+ }
22
+ function compareParsed(a, b) {
23
+ const length = Math.max(a.numeric.length, b.numeric.length);
24
+ for (let i = 0; i < length; i++) {
25
+ const na = a.numeric[i] ?? 0;
26
+ const nb = b.numeric[i] ?? 0;
27
+ if (na !== nb)
28
+ return na < nb ? -1 : 1;
29
+ }
30
+ return 0;
31
+ }
32
+ export function compareVersions(a, b) {
33
+ const pa = parseVersion(a);
34
+ const pb = parseVersion(b);
35
+ if (!pa || !pb) {
36
+ throw new RangeError(`compareVersions: not a comparable version ("${a}" vs "${b}")`);
37
+ }
38
+ return compareParsed(pa, pb);
39
+ }
40
+ export function satisfies(version, req) {
41
+ const hasConstraint = req.min !== undefined || req.max !== undefined || req.exact !== undefined;
42
+ if (!hasConstraint)
43
+ return "satisfied";
44
+ if (version === undefined)
45
+ return "undetermined";
46
+ const v = parseVersion(version);
47
+ if (!v)
48
+ return "undetermined";
49
+ if (req.exact !== undefined) {
50
+ const exact = parseVersion(req.exact);
51
+ if (!exact)
52
+ return "undetermined";
53
+ return compareParsed(v, exact) === 0 ? "satisfied" : "unsatisfied";
54
+ }
55
+ if (req.min !== undefined) {
56
+ const min = parseVersion(req.min);
57
+ if (!min)
58
+ return "undetermined";
59
+ if (compareParsed(v, min) < 0)
60
+ return "unsatisfied";
61
+ }
62
+ if (req.max !== undefined) {
63
+ const max = parseVersion(req.max);
64
+ if (!max)
65
+ return "undetermined";
66
+ if (compareParsed(v, max) > 0)
67
+ return "unsatisfied";
68
+ }
69
+ return "satisfied";
70
+ }