hoi4-agent-tools 0.0.0-bootstrap.1 → 0.1.2

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 (416) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +201 -0
  3. package/README.md +140 -2
  4. package/SECURITY.md +17 -0
  5. package/dist/bin/http.d.ts +3 -0
  6. package/dist/bin/http.d.ts.map +1 -0
  7. package/dist/bin/http.js +27 -0
  8. package/dist/bin/http.js.map +1 -0
  9. package/dist/bin/setup.d.ts +3 -0
  10. package/dist/bin/setup.d.ts.map +1 -0
  11. package/dist/bin/setup.js +188 -0
  12. package/dist/bin/setup.js.map +1 -0
  13. package/dist/bin/stdio.d.ts +3 -0
  14. package/dist/bin/stdio.d.ts.map +1 -0
  15. package/dist/bin/stdio.js +36 -0
  16. package/dist/bin/stdio.js.map +1 -0
  17. package/dist/hoi4_agent_tools/core/artifacts.d.ts +117 -0
  18. package/dist/hoi4_agent_tools/core/artifacts.d.ts.map +1 -0
  19. package/dist/hoi4_agent_tools/core/artifacts.js +1047 -0
  20. package/dist/hoi4_agent_tools/core/artifacts.js.map +1 -0
  21. package/dist/hoi4_agent_tools/core/canonical.d.ts +13 -0
  22. package/dist/hoi4_agent_tools/core/canonical.d.ts.map +1 -0
  23. package/dist/hoi4_agent_tools/core/canonical.js +41 -0
  24. package/dist/hoi4_agent_tools/core/canonical.js.map +1 -0
  25. package/dist/hoi4_agent_tools/core/configuration.d.ts +137 -0
  26. package/dist/hoi4_agent_tools/core/configuration.d.ts.map +1 -0
  27. package/dist/hoi4_agent_tools/core/configuration.js +383 -0
  28. package/dist/hoi4_agent_tools/core/configuration.js.map +1 -0
  29. package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts +18 -0
  30. package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts.map +1 -0
  31. package/dist/hoi4_agent_tools/core/diagnostic-collector.js +45 -0
  32. package/dist/hoi4_agent_tools/core/diagnostic-collector.js.map +1 -0
  33. package/dist/hoi4_agent_tools/core/diagnostics.d.ts +26 -0
  34. package/dist/hoi4_agent_tools/core/diagnostics.d.ts.map +1 -0
  35. package/dist/hoi4_agent_tools/core/diagnostics.js +25 -0
  36. package/dist/hoi4_agent_tools/core/diagnostics.js.map +1 -0
  37. package/dist/hoi4_agent_tools/core/diff.d.ts +22 -0
  38. package/dist/hoi4_agent_tools/core/diff.d.ts.map +1 -0
  39. package/dist/hoi4_agent_tools/core/diff.js +93 -0
  40. package/dist/hoi4_agent_tools/core/diff.js.map +1 -0
  41. package/dist/hoi4_agent_tools/core/engine.d.ts +56 -0
  42. package/dist/hoi4_agent_tools/core/engine.d.ts.map +1 -0
  43. package/dist/hoi4_agent_tools/core/engine.js +319 -0
  44. package/dist/hoi4_agent_tools/core/engine.js.map +1 -0
  45. package/dist/hoi4_agent_tools/core/image-diff.d.ts +14 -0
  46. package/dist/hoi4_agent_tools/core/image-diff.d.ts.map +1 -0
  47. package/dist/hoi4_agent_tools/core/image-diff.js +121 -0
  48. package/dist/hoi4_agent_tools/core/image-diff.js.map +1 -0
  49. package/dist/hoi4_agent_tools/core/index.d.ts +64 -0
  50. package/dist/hoi4_agent_tools/core/index.d.ts.map +1 -0
  51. package/dist/hoi4_agent_tools/core/index.js +963 -0
  52. package/dist/hoi4_agent_tools/core/index.js.map +1 -0
  53. package/dist/hoi4_agent_tools/core/index.public.d.ts +16 -0
  54. package/dist/hoi4_agent_tools/core/index.public.d.ts.map +1 -0
  55. package/dist/hoi4_agent_tools/core/index.public.js +16 -0
  56. package/dist/hoi4_agent_tools/core/index.public.js.map +1 -0
  57. package/dist/hoi4_agent_tools/core/render-budget.d.ts +51 -0
  58. package/dist/hoi4_agent_tools/core/render-budget.d.ts.map +1 -0
  59. package/dist/hoi4_agent_tools/core/render-budget.js +109 -0
  60. package/dist/hoi4_agent_tools/core/render-budget.js.map +1 -0
  61. package/dist/hoi4_agent_tools/core/result.d.ts +45 -0
  62. package/dist/hoi4_agent_tools/core/result.d.ts.map +1 -0
  63. package/dist/hoi4_agent_tools/core/result.js +26 -0
  64. package/dist/hoi4_agent_tools/core/result.js.map +1 -0
  65. package/dist/hoi4_agent_tools/core/scanner.d.ts +28 -0
  66. package/dist/hoi4_agent_tools/core/scanner.d.ts.map +1 -0
  67. package/dist/hoi4_agent_tools/core/scanner.js +136 -0
  68. package/dist/hoi4_agent_tools/core/scanner.js.map +1 -0
  69. package/dist/hoi4_agent_tools/core/server-state.d.ts +31 -0
  70. package/dist/hoi4_agent_tools/core/server-state.d.ts.map +1 -0
  71. package/dist/hoi4_agent_tools/core/server-state.js +413 -0
  72. package/dist/hoi4_agent_tools/core/server-state.js.map +1 -0
  73. package/dist/hoi4_agent_tools/core/source/encoding.d.ts +10 -0
  74. package/dist/hoi4_agent_tools/core/source/encoding.d.ts.map +1 -0
  75. package/dist/hoi4_agent_tools/core/source/encoding.js +54 -0
  76. package/dist/hoi4_agent_tools/core/source/encoding.js.map +1 -0
  77. package/dist/hoi4_agent_tools/core/source/index.d.ts +7 -0
  78. package/dist/hoi4_agent_tools/core/source/index.d.ts.map +1 -0
  79. package/dist/hoi4_agent_tools/core/source/index.js +7 -0
  80. package/dist/hoi4_agent_tools/core/source/index.js.map +1 -0
  81. package/dist/hoi4_agent_tools/core/source/lexer.d.ts +30 -0
  82. package/dist/hoi4_agent_tools/core/source/lexer.d.ts.map +1 -0
  83. package/dist/hoi4_agent_tools/core/source/lexer.js +266 -0
  84. package/dist/hoi4_agent_tools/core/source/lexer.js.map +1 -0
  85. package/dist/hoi4_agent_tools/core/source/limits.d.ts +21 -0
  86. package/dist/hoi4_agent_tools/core/source/limits.d.ts.map +1 -0
  87. package/dist/hoi4_agent_tools/core/source/limits.js +49 -0
  88. package/dist/hoi4_agent_tools/core/source/limits.js.map +1 -0
  89. package/dist/hoi4_agent_tools/core/source/localisation.d.ts +20 -0
  90. package/dist/hoi4_agent_tools/core/source/localisation.d.ts.map +1 -0
  91. package/dist/hoi4_agent_tools/core/source/localisation.js +163 -0
  92. package/dist/hoi4_agent_tools/core/source/localisation.js.map +1 -0
  93. package/dist/hoi4_agent_tools/core/source/parser.d.ts +44 -0
  94. package/dist/hoi4_agent_tools/core/source/parser.d.ts.map +1 -0
  95. package/dist/hoi4_agent_tools/core/source/parser.js +334 -0
  96. package/dist/hoi4_agent_tools/core/source/parser.js.map +1 -0
  97. package/dist/hoi4_agent_tools/core/source/rewrite.d.ts +10 -0
  98. package/dist/hoi4_agent_tools/core/source/rewrite.d.ts.map +1 -0
  99. package/dist/hoi4_agent_tools/core/source/rewrite.js +28 -0
  100. package/dist/hoi4_agent_tools/core/source/rewrite.js.map +1 -0
  101. package/dist/hoi4_agent_tools/core/svg-text.d.ts +34 -0
  102. package/dist/hoi4_agent_tools/core/svg-text.d.ts.map +1 -0
  103. package/dist/hoi4_agent_tools/core/svg-text.js +127 -0
  104. package/dist/hoi4_agent_tools/core/svg-text.js.map +1 -0
  105. package/dist/hoi4_agent_tools/core/transaction-limits.d.ts +9 -0
  106. package/dist/hoi4_agent_tools/core/transaction-limits.d.ts.map +1 -0
  107. package/dist/hoi4_agent_tools/core/transaction-limits.js +9 -0
  108. package/dist/hoi4_agent_tools/core/transaction-limits.js.map +1 -0
  109. package/dist/hoi4_agent_tools/core/transactions.d.ts +162 -0
  110. package/dist/hoi4_agent_tools/core/transactions.d.ts.map +1 -0
  111. package/dist/hoi4_agent_tools/core/transactions.js +1181 -0
  112. package/dist/hoi4_agent_tools/core/transactions.js.map +1 -0
  113. package/dist/hoi4_agent_tools/core/workspace.d.ts +68 -0
  114. package/dist/hoi4_agent_tools/core/workspace.d.ts.map +1 -0
  115. package/dist/hoi4_agent_tools/core/workspace.js +794 -0
  116. package/dist/hoi4_agent_tools/core/workspace.js.map +1 -0
  117. package/dist/hoi4_agent_tools/focus/compiler.d.ts +9 -0
  118. package/dist/hoi4_agent_tools/focus/compiler.d.ts.map +1 -0
  119. package/dist/hoi4_agent_tools/focus/compiler.js +273 -0
  120. package/dist/hoi4_agent_tools/focus/compiler.js.map +1 -0
  121. package/dist/hoi4_agent_tools/focus/continuous-render.d.ts +32 -0
  122. package/dist/hoi4_agent_tools/focus/continuous-render.d.ts.map +1 -0
  123. package/dist/hoi4_agent_tools/focus/continuous-render.js +179 -0
  124. package/dist/hoi4_agent_tools/focus/continuous-render.js.map +1 -0
  125. package/dist/hoi4_agent_tools/focus/drift.d.ts +22 -0
  126. package/dist/hoi4_agent_tools/focus/drift.d.ts.map +1 -0
  127. package/dist/hoi4_agent_tools/focus/drift.js +124 -0
  128. package/dist/hoi4_agent_tools/focus/drift.js.map +1 -0
  129. package/dist/hoi4_agent_tools/focus/geometry.d.ts +17 -0
  130. package/dist/hoi4_agent_tools/focus/geometry.d.ts.map +1 -0
  131. package/dist/hoi4_agent_tools/focus/geometry.js +35 -0
  132. package/dist/hoi4_agent_tools/focus/geometry.js.map +1 -0
  133. package/dist/hoi4_agent_tools/focus/importer.d.ts +9 -0
  134. package/dist/hoi4_agent_tools/focus/importer.d.ts.map +1 -0
  135. package/dist/hoi4_agent_tools/focus/importer.js +732 -0
  136. package/dist/hoi4_agent_tools/focus/importer.js.map +1 -0
  137. package/dist/hoi4_agent_tools/focus/index.d.ts +14 -0
  138. package/dist/hoi4_agent_tools/focus/index.d.ts.map +1 -0
  139. package/dist/hoi4_agent_tools/focus/index.js +14 -0
  140. package/dist/hoi4_agent_tools/focus/index.js.map +1 -0
  141. package/dist/hoi4_agent_tools/focus/layout.d.ts +5 -0
  142. package/dist/hoi4_agent_tools/focus/layout.d.ts.map +1 -0
  143. package/dist/hoi4_agent_tools/focus/layout.js +653 -0
  144. package/dist/hoi4_agent_tools/focus/layout.js.map +1 -0
  145. package/dist/hoi4_agent_tools/focus/limits.d.ts +9 -0
  146. package/dist/hoi4_agent_tools/focus/limits.d.ts.map +1 -0
  147. package/dist/hoi4_agent_tools/focus/limits.js +9 -0
  148. package/dist/hoi4_agent_tools/focus/limits.js.map +1 -0
  149. package/dist/hoi4_agent_tools/focus/lint.d.ts +14 -0
  150. package/dist/hoi4_agent_tools/focus/lint.d.ts.map +1 -0
  151. package/dist/hoi4_agent_tools/focus/lint.js +839 -0
  152. package/dist/hoi4_agent_tools/focus/lint.js.map +1 -0
  153. package/dist/hoi4_agent_tools/focus/model.d.ts +303 -0
  154. package/dist/hoi4_agent_tools/focus/model.d.ts.map +1 -0
  155. package/dist/hoi4_agent_tools/focus/model.js +20 -0
  156. package/dist/hoi4_agent_tools/focus/model.js.map +1 -0
  157. package/dist/hoi4_agent_tools/focus/native-effects.d.ts +9 -0
  158. package/dist/hoi4_agent_tools/focus/native-effects.d.ts.map +1 -0
  159. package/dist/hoi4_agent_tools/focus/native-effects.js +563 -0
  160. package/dist/hoi4_agent_tools/focus/native-effects.js.map +1 -0
  161. package/dist/hoi4_agent_tools/focus/planning.d.ts +15 -0
  162. package/dist/hoi4_agent_tools/focus/planning.d.ts.map +1 -0
  163. package/dist/hoi4_agent_tools/focus/planning.js +241 -0
  164. package/dist/hoi4_agent_tools/focus/planning.js.map +1 -0
  165. package/dist/hoi4_agent_tools/focus/presentation.d.ts +24 -0
  166. package/dist/hoi4_agent_tools/focus/presentation.d.ts.map +1 -0
  167. package/dist/hoi4_agent_tools/focus/presentation.js +204 -0
  168. package/dist/hoi4_agent_tools/focus/presentation.js.map +1 -0
  169. package/dist/hoi4_agent_tools/focus/render.d.ts +35 -0
  170. package/dist/hoi4_agent_tools/focus/render.d.ts.map +1 -0
  171. package/dist/hoi4_agent_tools/focus/render.js +491 -0
  172. package/dist/hoi4_agent_tools/focus/render.js.map +1 -0
  173. package/dist/hoi4_agent_tools/focus/service.d.ts +82 -0
  174. package/dist/hoi4_agent_tools/focus/service.d.ts.map +1 -0
  175. package/dist/hoi4_agent_tools/focus/service.js +492 -0
  176. package/dist/hoi4_agent_tools/focus/service.js.map +1 -0
  177. package/dist/hoi4_agent_tools/focus/source-update.d.ts +6 -0
  178. package/dist/hoi4_agent_tools/focus/source-update.d.ts.map +1 -0
  179. package/dist/hoi4_agent_tools/focus/source-update.js +328 -0
  180. package/dist/hoi4_agent_tools/focus/source-update.js.map +1 -0
  181. package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts +37 -0
  182. package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts.map +1 -0
  183. package/dist/hoi4_agent_tools/gui/animation-manifest.js +66 -0
  184. package/dist/hoi4_agent_tools/gui/animation-manifest.js.map +1 -0
  185. package/dist/hoi4_agent_tools/gui/assets.d.ts +71 -0
  186. package/dist/hoi4_agent_tools/gui/assets.d.ts.map +1 -0
  187. package/dist/hoi4_agent_tools/gui/assets.js +629 -0
  188. package/dist/hoi4_agent_tools/gui/assets.js.map +1 -0
  189. package/dist/hoi4_agent_tools/gui/dds.d.ts +17 -0
  190. package/dist/hoi4_agent_tools/gui/dds.d.ts.map +1 -0
  191. package/dist/hoi4_agent_tools/gui/dds.js +245 -0
  192. package/dist/hoi4_agent_tools/gui/dds.js.map +1 -0
  193. package/dist/hoi4_agent_tools/gui/helpers.d.ts +101 -0
  194. package/dist/hoi4_agent_tools/gui/helpers.d.ts.map +1 -0
  195. package/dist/hoi4_agent_tools/gui/helpers.js +1072 -0
  196. package/dist/hoi4_agent_tools/gui/helpers.js.map +1 -0
  197. package/dist/hoi4_agent_tools/gui/index.d.ts +15 -0
  198. package/dist/hoi4_agent_tools/gui/index.d.ts.map +1 -0
  199. package/dist/hoi4_agent_tools/gui/index.js +15 -0
  200. package/dist/hoi4_agent_tools/gui/index.js.map +1 -0
  201. package/dist/hoi4_agent_tools/gui/layout.d.ts +6 -0
  202. package/dist/hoi4_agent_tools/gui/layout.d.ts.map +1 -0
  203. package/dist/hoi4_agent_tools/gui/layout.js +753 -0
  204. package/dist/hoi4_agent_tools/gui/layout.js.map +1 -0
  205. package/dist/hoi4_agent_tools/gui/limits.d.ts +25 -0
  206. package/dist/hoi4_agent_tools/gui/limits.d.ts.map +1 -0
  207. package/dist/hoi4_agent_tools/gui/limits.js +27 -0
  208. package/dist/hoi4_agent_tools/gui/limits.js.map +1 -0
  209. package/dist/hoi4_agent_tools/gui/renderer.d.ts +18 -0
  210. package/dist/hoi4_agent_tools/gui/renderer.d.ts.map +1 -0
  211. package/dist/hoi4_agent_tools/gui/renderer.js +388 -0
  212. package/dist/hoi4_agent_tools/gui/renderer.js.map +1 -0
  213. package/dist/hoi4_agent_tools/gui/scenario.d.ts +66 -0
  214. package/dist/hoi4_agent_tools/gui/scenario.d.ts.map +1 -0
  215. package/dist/hoi4_agent_tools/gui/scenario.js +191 -0
  216. package/dist/hoi4_agent_tools/gui/scenario.js.map +1 -0
  217. package/dist/hoi4_agent_tools/gui/source-graph.d.ts +7 -0
  218. package/dist/hoi4_agent_tools/gui/source-graph.d.ts.map +1 -0
  219. package/dist/hoi4_agent_tools/gui/source-graph.js +1074 -0
  220. package/dist/hoi4_agent_tools/gui/source-graph.js.map +1 -0
  221. package/dist/hoi4_agent_tools/gui/source-patch.d.ts +13 -0
  222. package/dist/hoi4_agent_tools/gui/source-patch.d.ts.map +1 -0
  223. package/dist/hoi4_agent_tools/gui/source-patch.js +90 -0
  224. package/dist/hoi4_agent_tools/gui/source-patch.js.map +1 -0
  225. package/dist/hoi4_agent_tools/gui/studio.d.ts +86 -0
  226. package/dist/hoi4_agent_tools/gui/studio.d.ts.map +1 -0
  227. package/dist/hoi4_agent_tools/gui/studio.js +830 -0
  228. package/dist/hoi4_agent_tools/gui/studio.js.map +1 -0
  229. package/dist/hoi4_agent_tools/gui/tga.d.ts +16 -0
  230. package/dist/hoi4_agent_tools/gui/tga.d.ts.map +1 -0
  231. package/dist/hoi4_agent_tools/gui/tga.js +157 -0
  232. package/dist/hoi4_agent_tools/gui/tga.js.map +1 -0
  233. package/dist/hoi4_agent_tools/gui/types.d.ts +322 -0
  234. package/dist/hoi4_agent_tools/gui/types.d.ts.map +1 -0
  235. package/dist/hoi4_agent_tools/gui/types.js +19 -0
  236. package/dist/hoi4_agent_tools/gui/types.js.map +1 -0
  237. package/dist/hoi4_agent_tools/gui/validators.d.ts +8 -0
  238. package/dist/hoi4_agent_tools/gui/validators.d.ts.map +1 -0
  239. package/dist/hoi4_agent_tools/gui/validators.js +951 -0
  240. package/dist/hoi4_agent_tools/gui/validators.js.map +1 -0
  241. package/dist/hoi4_agent_tools/map/bmp.d.ts +62 -0
  242. package/dist/hoi4_agent_tools/map/bmp.d.ts.map +1 -0
  243. package/dist/hoi4_agent_tools/map/bmp.js +363 -0
  244. package/dist/hoi4_agent_tools/map/bmp.js.map +1 -0
  245. package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts +5 -0
  246. package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts.map +1 -0
  247. package/dist/hoi4_agent_tools/map/diagnostic-limit.js +21 -0
  248. package/dist/hoi4_agent_tools/map/diagnostic-limit.js.map +1 -0
  249. package/dist/hoi4_agent_tools/map/index.d.ts +8 -0
  250. package/dist/hoi4_agent_tools/map/index.d.ts.map +1 -0
  251. package/dist/hoi4_agent_tools/map/index.js +8 -0
  252. package/dist/hoi4_agent_tools/map/index.js.map +1 -0
  253. package/dist/hoi4_agent_tools/map/limits.d.ts +13 -0
  254. package/dist/hoi4_agent_tools/map/limits.d.ts.map +1 -0
  255. package/dist/hoi4_agent_tools/map/limits.js +13 -0
  256. package/dist/hoi4_agent_tools/map/limits.js.map +1 -0
  257. package/dist/hoi4_agent_tools/map/model.d.ts +269 -0
  258. package/dist/hoi4_agent_tools/map/model.d.ts.map +1 -0
  259. package/dist/hoi4_agent_tools/map/model.js +1114 -0
  260. package/dist/hoi4_agent_tools/map/model.js.map +1 -0
  261. package/dist/hoi4_agent_tools/map/operations.d.ts +401 -0
  262. package/dist/hoi4_agent_tools/map/operations.d.ts.map +1 -0
  263. package/dist/hoi4_agent_tools/map/operations.js +2717 -0
  264. package/dist/hoi4_agent_tools/map/operations.js.map +1 -0
  265. package/dist/hoi4_agent_tools/map/render.d.ts +90 -0
  266. package/dist/hoi4_agent_tools/map/render.d.ts.map +1 -0
  267. package/dist/hoi4_agent_tools/map/render.js +759 -0
  268. package/dist/hoi4_agent_tools/map/render.js.map +1 -0
  269. package/dist/hoi4_agent_tools/map/service.d.ts +81 -0
  270. package/dist/hoi4_agent_tools/map/service.d.ts.map +1 -0
  271. package/dist/hoi4_agent_tools/map/service.js +695 -0
  272. package/dist/hoi4_agent_tools/map/service.js.map +1 -0
  273. package/dist/hoi4_agent_tools/map/validation.d.ts +23 -0
  274. package/dist/hoi4_agent_tools/map/validation.d.ts.map +1 -0
  275. package/dist/hoi4_agent_tools/map/validation.js +1177 -0
  276. package/dist/hoi4_agent_tools/map/validation.js.map +1 -0
  277. package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts +3 -0
  278. package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts.map +1 -0
  279. package/dist/hoi4_agent_tools/mcp/prompts/register.js +50 -0
  280. package/dist/hoi4_agent_tools/mcp/prompts/register.js.map +1 -0
  281. package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts +9 -0
  282. package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts.map +1 -0
  283. package/dist/hoi4_agent_tools/mcp/registry/metadata.js +10 -0
  284. package/dist/hoi4_agent_tools/mcp/registry/metadata.js.map +1 -0
  285. package/dist/hoi4_agent_tools/mcp/resources/register.d.ts +5 -0
  286. package/dist/hoi4_agent_tools/mcp/resources/register.d.ts.map +1 -0
  287. package/dist/hoi4_agent_tools/mcp/resources/register.js +278 -0
  288. package/dist/hoi4_agent_tools/mcp/resources/register.js.map +1 -0
  289. package/dist/hoi4_agent_tools/mcp/security/auth.d.ts +24 -0
  290. package/dist/hoi4_agent_tools/mcp/security/auth.d.ts.map +1 -0
  291. package/dist/hoi4_agent_tools/mcp/security/auth.js +234 -0
  292. package/dist/hoi4_agent_tools/mcp/security/auth.js.map +1 -0
  293. package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts +35 -0
  294. package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts.map +1 -0
  295. package/dist/hoi4_agent_tools/mcp/server/base-tools.js +835 -0
  296. package/dist/hoi4_agent_tools/mcp/server/base-tools.js.map +1 -0
  297. package/dist/hoi4_agent_tools/mcp/server/create.d.ts +5 -0
  298. package/dist/hoi4_agent_tools/mcp/server/create.d.ts.map +1 -0
  299. package/dist/hoi4_agent_tools/mcp/server/create.js +26 -0
  300. package/dist/hoi4_agent_tools/mcp/server/create.js.map +1 -0
  301. package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts +133 -0
  302. package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts.map +1 -0
  303. package/dist/hoi4_agent_tools/mcp/server/output-schemas.js +127 -0
  304. package/dist/hoi4_agent_tools/mcp/server/output-schemas.js.map +1 -0
  305. package/dist/hoi4_agent_tools/mcp/server/progress.d.ts +8 -0
  306. package/dist/hoi4_agent_tools/mcp/server/progress.d.ts.map +1 -0
  307. package/dist/hoi4_agent_tools/mcp/server/progress.js +21 -0
  308. package/dist/hoi4_agent_tools/mcp/server/progress.js.map +1 -0
  309. package/dist/hoi4_agent_tools/mcp/server/result.d.ts +232 -0
  310. package/dist/hoi4_agent_tools/mcp/server/result.d.ts.map +1 -0
  311. package/dist/hoi4_agent_tools/mcp/server/result.js +353 -0
  312. package/dist/hoi4_agent_tools/mcp/server/result.js.map +1 -0
  313. package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts +5 -0
  314. package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts.map +1 -0
  315. package/dist/hoi4_agent_tools/mcp/tools/focus.js +1059 -0
  316. package/dist/hoi4_agent_tools/mcp/tools/focus.js.map +1 -0
  317. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts +111 -0
  318. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts.map +1 -0
  319. package/dist/hoi4_agent_tools/mcp/tools/gui.js +598 -0
  320. package/dist/hoi4_agent_tools/mcp/tools/gui.js.map +1 -0
  321. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts +5 -0
  322. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts.map +1 -0
  323. package/dist/hoi4_agent_tools/mcp/tools/map.js +685 -0
  324. package/dist/hoi4_agent_tools/mcp/tools/map.js.map +1 -0
  325. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts +58 -0
  326. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts.map +1 -0
  327. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js +181 -0
  328. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js.map +1 -0
  329. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts +26 -0
  330. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts.map +1 -0
  331. package/dist/hoi4_agent_tools/mcp/transports/event-store.js +86 -0
  332. package/dist/hoi4_agent_tools/mcp/transports/event-store.js.map +1 -0
  333. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts +28 -0
  334. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts.map +1 -0
  335. package/dist/hoi4_agent_tools/mcp/transports/http.js +744 -0
  336. package/dist/hoi4_agent_tools/mcp/transports/http.js.map +1 -0
  337. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts +15 -0
  338. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts.map +1 -0
  339. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js +51 -0
  340. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js.map +1 -0
  341. package/dist/hoi4_agent_tools/runtime.d.ts +4 -0
  342. package/dist/hoi4_agent_tools/runtime.d.ts.map +1 -0
  343. package/dist/hoi4_agent_tools/runtime.js +27 -0
  344. package/dist/hoi4_agent_tools/runtime.js.map +1 -0
  345. package/dist/hoi4_agent_tools/schemas/common.d.ts +74 -0
  346. package/dist/hoi4_agent_tools/schemas/common.d.ts.map +1 -0
  347. package/dist/hoi4_agent_tools/schemas/common.js +51 -0
  348. package/dist/hoi4_agent_tools/schemas/common.js.map +1 -0
  349. package/dist/hoi4_agent_tools/schemas/focus.d.ts +784 -0
  350. package/dist/hoi4_agent_tools/schemas/focus.d.ts.map +1 -0
  351. package/dist/hoi4_agent_tools/schemas/focus.js +330 -0
  352. package/dist/hoi4_agent_tools/schemas/focus.js.map +1 -0
  353. package/dist/hoi4_agent_tools/schemas/index.d.ts +5 -0
  354. package/dist/hoi4_agent_tools/schemas/index.d.ts.map +1 -0
  355. package/dist/hoi4_agent_tools/schemas/index.js +5 -0
  356. package/dist/hoi4_agent_tools/schemas/index.js.map +1 -0
  357. package/dist/hoi4_agent_tools/schemas/map.d.ts +654 -0
  358. package/dist/hoi4_agent_tools/schemas/map.d.ts.map +1 -0
  359. package/dist/hoi4_agent_tools/schemas/map.js +570 -0
  360. package/dist/hoi4_agent_tools/schemas/map.js.map +1 -0
  361. package/dist/hoi4_agent_tools/schemas/transaction.d.ts +259 -0
  362. package/dist/hoi4_agent_tools/schemas/transaction.d.ts.map +1 -0
  363. package/dist/hoi4_agent_tools/schemas/transaction.js +104 -0
  364. package/dist/hoi4_agent_tools/schemas/transaction.js.map +1 -0
  365. package/dist/hoi4_agent_tools/version.d.ts +6 -0
  366. package/dist/hoi4_agent_tools/version.d.ts.map +1 -0
  367. package/dist/hoi4_agent_tools/version.js +7 -0
  368. package/dist/hoi4_agent_tools/version.js.map +1 -0
  369. package/dist/index.d.ts +3 -0
  370. package/dist/index.d.ts.map +1 -0
  371. package/dist/index.js +3 -0
  372. package/dist/index.js.map +1 -0
  373. package/docs/README.md +22 -0
  374. package/docs/adr/0001-runtime-and-language.md +16 -0
  375. package/docs/adr/0002-lossless-source-model.md +18 -0
  376. package/docs/adr/0003-image-and-font-codecs.md +18 -0
  377. package/docs/adr/0004-focus-layout.md +16 -0
  378. package/docs/adr/0005-offline-rendering.md +18 -0
  379. package/docs/adr/0006-mcp-sdk-and-protocol.md +16 -0
  380. package/docs/adr/0007-storage-and-transactions.md +24 -0
  381. package/docs/adr/0008-test-strategy.md +18 -0
  382. package/docs/adr/0009-packaging-and-registry.md +16 -0
  383. package/docs/adr/0010-unsupported-and-refusal-policy.md +18 -0
  384. package/docs/adr/0011-http-security.md +16 -0
  385. package/docs/adr/README.md +13 -0
  386. package/docs/architecture.md +60 -0
  387. package/docs/artifacts.md +133 -0
  388. package/docs/compatibility.md +33 -0
  389. package/docs/completion-report.md +60 -0
  390. package/docs/configuration.md +285 -0
  391. package/docs/focus-workflow.md +68 -0
  392. package/docs/gui-workflow.md +121 -0
  393. package/docs/limitations.md +30 -0
  394. package/docs/map-workflow.md +89 -0
  395. package/docs/performance.md +117 -0
  396. package/docs/release.md +181 -0
  397. package/docs/research/mcp-2026-07-10.md +46 -0
  398. package/docs/research/source-ledger.md +68 -0
  399. package/docs/security.md +139 -0
  400. package/docs/self-hosting.md +168 -0
  401. package/docs/testing.md +43 -0
  402. package/docs/third-party-notices.md +11 -0
  403. package/docs/transactions.md +162 -0
  404. package/docs/troubleshooting.md +46 -0
  405. package/package.json +98 -5
  406. package/schemas/configuration.schema.json +794 -0
  407. package/schemas/continuous-focus-palette.schema.json +325 -0
  408. package/schemas/focus-plan.schema.json +902 -0
  409. package/schemas/focus-planning-sidecar.schema.json +364 -0
  410. package/schemas/gui-animation-source.schema.json +176 -0
  411. package/schemas/gui-helper.schema.json +301 -0
  412. package/schemas/gui-scenario.schema.json +298 -0
  413. package/schemas/map-operation.schema.json +2284 -0
  414. package/schemas/operation-result.schema.json +344 -0
  415. package/schemas/transaction-manifest.schema.json +685 -0
  416. package/server.json +32 -0
@@ -0,0 +1,1074 @@
1
+ import path from 'node:path';
2
+ import { compareCodeUnits, deterministicId } from '../core/canonical.js';
3
+ import { DiagnosticCollector } from '../core/diagnostic-collector.js';
4
+ import { sortDiagnostics } from '../core/diagnostics.js';
5
+ import { ServiceError } from '../core/result.js';
6
+ import { GUI_GRAPH_MAX_EDGES, GUI_GRAPH_MAX_ELEMENTS, GUI_GRAPH_MAX_NODES } from './limits.js';
7
+ import { assignments, childBlocks, firstScalar, locationFor, nodeLocation, parseClausewitz, parseLocalisation, } from '../core/source/index.js';
8
+ import { GuiAnimationSourceManifestSchema } from './animation-manifest.js';
9
+ const explicitGuiElementTypes = new Set([
10
+ 'containerWindowType',
11
+ 'windowType',
12
+ 'eu3dialogtype',
13
+ 'iconType',
14
+ 'buttonType',
15
+ 'guiButtonType',
16
+ 'instantTextBoxType',
17
+ 'textBoxType',
18
+ 'gridBoxType',
19
+ 'dynamicGridBoxType',
20
+ 'listboxType',
21
+ 'smoothListboxType',
22
+ 'scrollbarType',
23
+ 'extendedScrollbarType',
24
+ 'checkboxType',
25
+ 'editBoxType',
26
+ 'OverlappingElementsBoxType',
27
+ 'shieldtype',
28
+ 'progressbarType',
29
+ 'scrollableTextBoxType',
30
+ 'browserType',
31
+ 'mapIconType',
32
+ ]);
33
+ const spriteTypes = new Set([
34
+ 'spriteType',
35
+ 'textSpriteType',
36
+ 'frameAnimatedSpriteType',
37
+ 'corneredTileSpriteType',
38
+ 'progressbarType',
39
+ 'maskedShieldType',
40
+ ]);
41
+ const modelledElementAttributes = new Set([
42
+ 'name',
43
+ 'position',
44
+ 'size',
45
+ 'orientation',
46
+ 'origo',
47
+ 'scale',
48
+ 'clipping',
49
+ 'background',
50
+ 'spriteType',
51
+ 'quadTextureSprite',
52
+ 'frame',
53
+ 'text',
54
+ 'font',
55
+ 'fontSize',
56
+ 'maxWidth',
57
+ 'format',
58
+ 'buttonText',
59
+ 'buttonFont',
60
+ 'alwaystransparent',
61
+ 'allwaystransparent',
62
+ 'clickThrough',
63
+ 'spacing',
64
+ 'priority',
65
+ 'minValue',
66
+ 'maxValue',
67
+ 'startValue',
68
+ ]);
69
+ const ignoredElementAttributes = new Set([
70
+ 'margin',
71
+ 'maxHeight',
72
+ 'fixedsize',
73
+ 'pdx_tooltip',
74
+ 'pdx_tooltip_delayed',
75
+ 'hint_tag',
76
+ 'horizontal',
77
+ 'verticalScrollbar',
78
+ 'horizontalScrollbar',
79
+ 'scrollbartype',
80
+ 'scrollbarType',
81
+ 'drag_scroll',
82
+ 'autohide_scrollbars',
83
+ 'scroll_wheel_factor',
84
+ 'smooth_scrolling',
85
+ 'borderSize',
86
+ 'stepSize',
87
+ 'centerposition',
88
+ 'fullScreen',
89
+ 'moveable',
90
+ 'show_position',
91
+ 'hide_position',
92
+ 'show_animation_type',
93
+ 'hide_animation_type',
94
+ 'animation_type',
95
+ 'animation_time',
96
+ 'fade_time',
97
+ 'fade_type',
98
+ 'show_sound',
99
+ 'hide_sound',
100
+ 'clicksound',
101
+ 'oversound',
102
+ 'shortcut',
103
+ 'web_link',
104
+ 'cost',
105
+ ]);
106
+ export function guiElementAttributeFidelity(key) {
107
+ const modelled = [...modelledElementAttributes].find((candidate) => candidate.toLowerCase() === key.toLowerCase());
108
+ if (modelled !== undefined)
109
+ return 'modelled';
110
+ const ignored = [...ignoredElementAttributes].find((candidate) => candidate.toLowerCase() === key.toLowerCase());
111
+ if (ignored !== undefined)
112
+ return 'ignored';
113
+ if (/type$/iu.test(key))
114
+ return 'structural';
115
+ return 'unsupported';
116
+ }
117
+ function normalizeAssetPath(value) {
118
+ return value.replaceAll('\\', '/').replace(/^\.\//u, '').replace(/^\//u, '').toLowerCase();
119
+ }
120
+ function scalarValue(value, constants) {
121
+ const expanded = constants.get(value) ?? value;
122
+ if (/^-?(?:\d+\.?\d*|\.\d+)$/u.test(expanded))
123
+ return Number(expanded);
124
+ if (expanded === 'yes')
125
+ return true;
126
+ if (expanded === 'no')
127
+ return false;
128
+ return expanded;
129
+ }
130
+ function sourceValueToProperty(value, constants) {
131
+ if (value.type === 'scalar')
132
+ return scalarValue(value.value, constants);
133
+ const result = {};
134
+ const unnamed = [];
135
+ for (const entry of value.entries) {
136
+ if (entry.type === 'scalar') {
137
+ unnamed.push(scalarValue(entry.value, constants));
138
+ continue;
139
+ }
140
+ if (entry.type === 'block') {
141
+ unnamed.push(sourceValueToProperty(entry, constants));
142
+ continue;
143
+ }
144
+ const next = sourceValueToProperty(entry.value, constants);
145
+ const previous = result[entry.key.value];
146
+ if (previous === undefined)
147
+ result[entry.key.value] = next;
148
+ else if (Array.isArray(previous))
149
+ previous.push(next);
150
+ else
151
+ result[entry.key.value] = [previous, next];
152
+ }
153
+ if (unnamed.length > 0)
154
+ result.$values = unnamed;
155
+ return result;
156
+ }
157
+ function constantsFor(document) {
158
+ const result = new Map();
159
+ for (const assignment of assignments(document.root)) {
160
+ if (!assignment.key.value.startsWith('@') || assignment.value.type !== 'scalar')
161
+ continue;
162
+ result.set(assignment.key.value, assignment.value.value);
163
+ }
164
+ return result;
165
+ }
166
+ function firstScalarInsensitive(block, ...keys) {
167
+ const lower = new Set(keys.map((key) => key.toLowerCase()));
168
+ for (const assignment of assignments(block)) {
169
+ if (!lower.has(assignment.key.value.toLowerCase()) || assignment.value.type !== 'scalar')
170
+ continue;
171
+ return assignment.value.value;
172
+ }
173
+ return undefined;
174
+ }
175
+ function numberScalar(block, ...keys) {
176
+ const value = firstScalarInsensitive(block, ...keys);
177
+ if (value === undefined || !/^-?(?:\d+\.?\d*|\.\d+)$/u.test(value))
178
+ return undefined;
179
+ return Number(value);
180
+ }
181
+ function boolScalar(block, ...keys) {
182
+ const value = firstScalarInsensitive(block, ...keys);
183
+ if (value === 'yes')
184
+ return true;
185
+ if (value === 'no')
186
+ return false;
187
+ return undefined;
188
+ }
189
+ function sizeFrom(block) {
190
+ const size = childBlocks(block, 'size')[0];
191
+ if (size === undefined)
192
+ return undefined;
193
+ const width = numberScalar(size, 'width', 'x');
194
+ const height = numberScalar(size, 'height', 'y');
195
+ return width === undefined || height === undefined ? undefined : { width, height };
196
+ }
197
+ function raw(document, node) {
198
+ return document.text.slice(node.start, node.end);
199
+ }
200
+ function isGuiElement(assignment) {
201
+ if (assignment.value.type !== 'block')
202
+ return false;
203
+ if (explicitGuiElementTypes.has(assignment.key.value))
204
+ return true;
205
+ return (assignment.key.value.endsWith('Type') && firstScalar(assignment.value, 'name') !== undefined);
206
+ }
207
+ function fileKind(file) {
208
+ const lower = file.relativePath.toLowerCase();
209
+ if (lower.startsWith('hoi4_agent/animation_sources/') && lower.endsWith('.json'))
210
+ return 'animation_source_manifest';
211
+ if (lower.endsWith('.gui'))
212
+ return 'gui_file';
213
+ if (lower.endsWith('.gfx'))
214
+ return 'gfx_file';
215
+ if (lower.includes('common/scripted_guis/') && lower.endsWith('.txt'))
216
+ return 'scripted_gui_file';
217
+ if (lower.includes('common/scripted_localisation/') && lower.endsWith('.txt'))
218
+ return 'scripted_localisation_file';
219
+ if (lower.endsWith('.txt')) {
220
+ const source = file.bytes.toString('utf8');
221
+ if (/(?:^|\s)scripted_gui\s*=/u.test(source))
222
+ return 'scripted_gui_file';
223
+ if (/(?:^|\s)defined_text\s*=/u.test(source))
224
+ return 'scripted_localisation_file';
225
+ }
226
+ if (lower.endsWith('.yml'))
227
+ return 'localisation_file';
228
+ return undefined;
229
+ }
230
+ function addNode(nodes, node) {
231
+ if (nodes.length >= GUI_GRAPH_MAX_NODES) {
232
+ throw new ServiceError('GUI_GRAPH_NODE_BUDGET_BLOCKED', 'GUI source graph exceeds the fixed node ceiling during construction', { nodes: nodes.length + 1, maximumNodes: GUI_GRAPH_MAX_NODES });
233
+ }
234
+ nodes.push(node);
235
+ }
236
+ function addEdge(edges, kind, from, to, resolved, metadata = {}, location) {
237
+ if (edges.length >= GUI_GRAPH_MAX_EDGES) {
238
+ throw new ServiceError('GUI_GRAPH_EDGE_BUDGET_BLOCKED', 'GUI source graph exceeds the fixed edge ceiling during construction', { edges: edges.length + 1, maximumEdges: GUI_GRAPH_MAX_EDGES });
239
+ }
240
+ edges.push({
241
+ id: deterministicId('gui_edge', { kind, from, to, metadata }),
242
+ kind,
243
+ from,
244
+ to,
245
+ resolved,
246
+ ...(location === undefined ? {} : { location }),
247
+ metadata,
248
+ });
249
+ }
250
+ function addDomainEntry(entries, entry, domain, maximum = GUI_GRAPH_MAX_NODES) {
251
+ if (entries.length >= maximum) {
252
+ throw new ServiceError('GUI_GRAPH_DOMAIN_BUDGET_BLOCKED', `GUI source graph exceeds the fixed ${domain} ceiling during construction`, { domain, entries: entries.length + 1, maximumEntries: maximum });
253
+ }
254
+ entries.push(entry);
255
+ }
256
+ function elementNodeId(element) {
257
+ return deterministicId('gui_element', element);
258
+ }
259
+ function indexGuiElements(document, file, fileNodeId, nodes, edges, elements) {
260
+ const constants = constantsFor(document);
261
+ const firstFileElement = elements.length;
262
+ let order = 0;
263
+ const walk = (block, parentId) => {
264
+ for (const assignment of assignments(block)) {
265
+ if (assignment.value.type !== 'block')
266
+ continue;
267
+ if (isGuiElement(assignment)) {
268
+ const name = firstScalar(assignment.value, 'name')?.value;
269
+ if (name === undefined)
270
+ continue;
271
+ order += 1;
272
+ const attributes = sourceValueToProperty(assignment.value, constants);
273
+ if (typeof attributes !== 'object' || Array.isArray(attributes))
274
+ continue;
275
+ const id = elementNodeId({ sourcePath: file.displayPath, name, definitionOrder: order });
276
+ const element = {
277
+ id,
278
+ name,
279
+ elementType: assignment.key.value,
280
+ sourcePath: file.displayPath,
281
+ location: nodeLocation(document, assignment, name),
282
+ ...(parentId === undefined ? {} : { parentId }),
283
+ childIds: [],
284
+ attributes: attributes,
285
+ unsupportedAttributes: assignments(assignment.value)
286
+ .filter((child) => !isGuiElement(child))
287
+ .map(({ key }) => key.value)
288
+ .filter((key) => guiElementAttributeFidelity(key) === 'unsupported')
289
+ .sort((a, b) => compareCodeUnits(a, b)),
290
+ rawSource: raw(document, assignment),
291
+ definitionOrder: order,
292
+ };
293
+ addDomainEntry(elements, element, 'element', GUI_GRAPH_MAX_ELEMENTS);
294
+ addNode(nodes, {
295
+ id,
296
+ kind: 'gui_element',
297
+ name,
298
+ path: file.displayPath,
299
+ ...(element.location === undefined ? {} : { location: element.location }),
300
+ metadata: {
301
+ elementType: element.elementType,
302
+ definitionOrder: order,
303
+ unsupportedAttributes: element.unsupportedAttributes,
304
+ },
305
+ });
306
+ addEdge(edges, 'contains', parentId ?? fileNodeId, id, true, {}, element.location);
307
+ if (parentId !== undefined)
308
+ addEdge(edges, 'parent', id, parentId, true, {}, element.location);
309
+ walk(assignment.value, id);
310
+ }
311
+ else {
312
+ walk(assignment.value, parentId);
313
+ }
314
+ }
315
+ };
316
+ walk(document.root);
317
+ const fileElements = elements.slice(firstFileElement);
318
+ const byId = new Map(fileElements.map((element) => [element.id, element]));
319
+ for (const element of fileElements) {
320
+ if (element.parentId !== undefined) {
321
+ const parent = byId.get(element.parentId);
322
+ if (parent !== undefined)
323
+ addDomainEntry(parent.childIds, element.id, 'element child', GUI_GRAPH_MAX_ELEMENTS);
324
+ }
325
+ }
326
+ }
327
+ function indexSpritesAndFonts(document, file, fileNodeId, nodes, edges, sprites, fonts) {
328
+ const walk = (block) => {
329
+ for (const assignment of assignments(block)) {
330
+ if (assignment.value.type !== 'block')
331
+ continue;
332
+ const child = assignment.value;
333
+ if (spriteTypes.has(assignment.key.value)) {
334
+ const name = firstScalarInsensitive(child, 'name');
335
+ if (name !== undefined) {
336
+ const id = deterministicId('gui_sprite', { path: file.displayPath, name });
337
+ const texturePath = firstScalarInsensitive(child, 'texturefile', 'textureFile');
338
+ const texturePath2 = firstScalarInsensitive(child, 'textureFile2');
339
+ const staticFallback = firstScalarInsensitive(child, 'static_fallback', 'staticFallback');
340
+ const animationRateFps = numberScalar(child, 'animation_rate_fps');
341
+ const looping = boolScalar(child, 'looping');
342
+ const playOnShow = boolScalar(child, 'play_on_show');
343
+ const pauseOnLoop = numberScalar(child, 'pause_on_loop');
344
+ const effectFile = firstScalarInsensitive(child, 'effectFile');
345
+ const declaredSize = sizeFrom(child);
346
+ const definition = {
347
+ id,
348
+ name,
349
+ sourcePath: file.displayPath,
350
+ location: nodeLocation(document, assignment, name),
351
+ spriteType: assignment.key.value,
352
+ ...(texturePath === undefined ? {} : { texturePath }),
353
+ ...(texturePath2 === undefined ? {} : { texturePath2 }),
354
+ frameCount: Math.trunc(numberScalar(child, 'noOfFrames', 'noofframes') ?? 1),
355
+ frameAnimated: assignment.key.value === 'frameAnimatedSpriteType',
356
+ ...(animationRateFps === undefined ? {} : { animationRateFps }),
357
+ ...(looping === undefined ? {} : { looping }),
358
+ ...(playOnShow === undefined ? {} : { playOnShow }),
359
+ ...(pauseOnLoop === undefined ? {} : { pauseOnLoop }),
360
+ ...(effectFile === undefined ? {} : { effectFile }),
361
+ ...(staticFallback === undefined ? {} : { staticFallback }),
362
+ ...(declaredSize === undefined ? {} : { declaredSize }),
363
+ rawSource: raw(document, assignment),
364
+ };
365
+ addDomainEntry(sprites, definition, 'sprite');
366
+ addNode(nodes, {
367
+ id,
368
+ kind: 'sprite',
369
+ name,
370
+ path: file.displayPath,
371
+ ...(definition.location === undefined ? {} : { location: definition.location }),
372
+ metadata: {
373
+ spriteType: definition.spriteType,
374
+ frameCount: definition.frameCount,
375
+ frameAnimated: definition.frameAnimated,
376
+ ...(definition.animationRateFps === undefined
377
+ ? {}
378
+ : { animationRateFps: definition.animationRateFps }),
379
+ },
380
+ });
381
+ addEdge(edges, 'contains', fileNodeId, id, true, {}, definition.location);
382
+ }
383
+ }
384
+ else if (assignment.key.value === 'bitmapfont' ||
385
+ assignment.key.value === 'bitmapfont_override') {
386
+ const name = firstScalarInsensitive(child, 'name');
387
+ if (name !== undefined) {
388
+ const assetPaths = [firstScalarInsensitive(child, 'path')]
389
+ .filter((value) => value !== undefined)
390
+ .concat(childBlocks(child, 'fontfiles').flatMap((fontFiles) => fontFiles.entries
391
+ .filter((entry) => entry.type === 'scalar')
392
+ .map((entry) => entry.value)));
393
+ const id = deterministicId('gui_font', { path: file.displayPath, name });
394
+ const font = {
395
+ id,
396
+ name,
397
+ sourcePath: file.displayPath,
398
+ location: nodeLocation(document, assignment, name),
399
+ kind: 'bitmapfont',
400
+ assetPaths,
401
+ rawSource: raw(document, assignment),
402
+ };
403
+ addDomainEntry(fonts, font, 'font');
404
+ addNode(nodes, {
405
+ id,
406
+ kind: 'font',
407
+ name,
408
+ path: file.displayPath,
409
+ ...(font.location === undefined ? {} : { location: font.location }),
410
+ metadata: { kind: font.kind, assetPaths },
411
+ });
412
+ addEdge(edges, 'contains', fileNodeId, id, true, {}, font.location);
413
+ }
414
+ }
415
+ walk(child);
416
+ }
417
+ };
418
+ walk(document.root);
419
+ }
420
+ function actionElementName(action) {
421
+ return action
422
+ .replace(/_(?:alt_|control_|shift_)?(?:left_|right_)?click_enabled$/u, '')
423
+ .replace(/_(?:alt_|control_|shift_)?(?:left_|right_)?click$/u, '')
424
+ .replace(/_(?:visible|enabled)$/u, '');
425
+ }
426
+ function namedAssignments(block, key) {
427
+ return childBlocks(block, key).flatMap((child) => assignments(child));
428
+ }
429
+ const directCostEffects = new Map([
430
+ ['add_political_power', 'pol_power'],
431
+ ['add_command_power', 'command_power'],
432
+ ['add_manpower', 'manpower'],
433
+ ['add_stability', 'stability'],
434
+ ['add_war_support', 'war_support'],
435
+ ]);
436
+ function directEffectCosts(block) {
437
+ const costs = {};
438
+ for (const assignment of assignments(block)) {
439
+ const resource = directCostEffects.get(assignment.key.value);
440
+ if (resource === undefined || assignment.value.type !== 'scalar')
441
+ continue;
442
+ const value = Number(assignment.value.value);
443
+ if (!Number.isFinite(value) || value >= 0)
444
+ continue;
445
+ costs[resource] = (costs[resource] ?? 0) + -value;
446
+ }
447
+ return costs;
448
+ }
449
+ function indexScriptedGuis(document, file, fileNodeId, nodes, edges, scriptedGuis) {
450
+ for (const root of childBlocks(document.root, 'scripted_gui')) {
451
+ for (const assignment of assignments(root)) {
452
+ if (assignment.value.type !== 'block')
453
+ continue;
454
+ const block = assignment.value;
455
+ const name = assignment.key.value;
456
+ const id = deterministicId('scripted_gui', { path: file.displayPath, name });
457
+ const effectAssignments = namedAssignments(block, 'effects');
458
+ const effectDefinitions = effectAssignments.map((effect) => ({
459
+ name: effect.key.value,
460
+ elementName: actionElementName(effect.key.value),
461
+ costs: effect.value.type === 'block' ? directEffectCosts(effect.value) : {},
462
+ rawSource: raw(document, effect),
463
+ location: nodeLocation(document, effect, effect.key.value),
464
+ }));
465
+ const effects = effectDefinitions.map(({ name: effect }) => effect);
466
+ const triggers = namedAssignments(block, 'triggers').map(({ key }) => key.value);
467
+ const properties = namedAssignments(block, 'properties').map(({ key }) => key.value);
468
+ const dynamicLists = namedAssignments(block, 'dynamic_lists').map(({ key }) => key.value);
469
+ const aiWeights = namedAssignments(block, 'ai_weights').map(({ key }) => key.value);
470
+ const contextType = firstScalarInsensitive(block, 'context_type');
471
+ const windowName = firstScalarInsensitive(block, 'window_name');
472
+ const parentWindowToken = firstScalarInsensitive(block, 'parent_window_token');
473
+ const parentWindowName = firstScalarInsensitive(block, 'parent_window_window', 'parent_window_name');
474
+ const parentScriptedGui = firstScalarInsensitive(block, 'parent_scripted_gui');
475
+ const visible = childBlocks(block, 'visible')[0];
476
+ const definition = {
477
+ id,
478
+ name,
479
+ sourcePath: file.displayPath,
480
+ location: nodeLocation(document, assignment, name),
481
+ ...(contextType === undefined ? {} : { contextType }),
482
+ ...(windowName === undefined ? {} : { windowName }),
483
+ ...(parentWindowToken === undefined ? {} : { parentWindowToken }),
484
+ ...(parentWindowName === undefined ? {} : { parentWindowName }),
485
+ ...(parentScriptedGui === undefined ? {} : { parentScriptedGui }),
486
+ ...(visible === undefined ? {} : { visibleExpression: raw(document, visible) }),
487
+ effects: effects.sort((a, b) => compareCodeUnits(a, b)),
488
+ effectDefinitions: effectDefinitions.sort((a, b) => compareCodeUnits(a.name, b.name)),
489
+ triggers: triggers.sort((a, b) => compareCodeUnits(a, b)),
490
+ properties: properties.sort((a, b) => compareCodeUnits(a, b)),
491
+ dynamicLists: dynamicLists.sort((a, b) => compareCodeUnits(a, b)),
492
+ aiWeights: aiWeights.sort((a, b) => compareCodeUnits(a, b)),
493
+ aiEnabled: childBlocks(block, 'ai_enabled').length > 0 || childBlocks(block, 'ai_check').length > 0,
494
+ rawSource: raw(document, assignment),
495
+ };
496
+ addDomainEntry(scriptedGuis, definition, 'scripted GUI');
497
+ addNode(nodes, {
498
+ id,
499
+ kind: 'scripted_gui',
500
+ name,
501
+ path: file.displayPath,
502
+ ...(definition.location === undefined ? {} : { location: definition.location }),
503
+ metadata: {
504
+ effects: definition.effects,
505
+ triggers: definition.triggers,
506
+ properties: definition.properties,
507
+ dynamicLists: definition.dynamicLists,
508
+ aiWeights: definition.aiWeights,
509
+ aiEnabled: definition.aiEnabled,
510
+ },
511
+ });
512
+ addEdge(edges, 'contains', fileNodeId, id, true, {}, definition.location);
513
+ if (contextType !== undefined) {
514
+ const target = deterministicId('gui_context', contextType);
515
+ if (!nodes.some((node) => node.id === target)) {
516
+ addNode(nodes, {
517
+ id: target,
518
+ kind: 'context',
519
+ name: contextType,
520
+ path: file.displayPath,
521
+ metadata: {},
522
+ });
523
+ }
524
+ addEdge(edges, 'context', id, target, true, {}, definition.location);
525
+ }
526
+ for (const effect of effects) {
527
+ const effectId = deterministicId('gui_effect', { id, effect });
528
+ addNode(nodes, {
529
+ id: effectId,
530
+ kind: 'scripted_effect',
531
+ name: effect,
532
+ path: file.displayPath,
533
+ metadata: { scriptedGui: name, element: actionElementName(effect) },
534
+ });
535
+ addEdge(edges, 'contains', id, effectId, true);
536
+ }
537
+ for (const trigger of triggers) {
538
+ const triggerId = deterministicId('gui_trigger', { id, trigger });
539
+ addNode(nodes, {
540
+ id: triggerId,
541
+ kind: 'scripted_trigger',
542
+ name: trigger,
543
+ path: file.displayPath,
544
+ metadata: { scriptedGui: name, element: actionElementName(trigger) },
545
+ });
546
+ addEdge(edges, 'contains', id, triggerId, true);
547
+ }
548
+ }
549
+ }
550
+ }
551
+ function indexAnimationSourceManifest(file, fileNodeId, nodes, edges, manifests, diagnostics) {
552
+ const text = file.bytes.toString('utf8');
553
+ const location = locationFor(file.displayPath, text, 0, text.length);
554
+ let value;
555
+ try {
556
+ value = JSON.parse(text);
557
+ }
558
+ catch (error) {
559
+ diagnostics.push({
560
+ code: 'GUI_ANIMATION_SOURCE_MANIFEST_INVALID',
561
+ severity: 'error',
562
+ category: 'syntax',
563
+ message: `Animation source manifest is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
564
+ location,
565
+ });
566
+ return;
567
+ }
568
+ const parsed = GuiAnimationSourceManifestSchema.safeParse(value);
569
+ if (!parsed.success) {
570
+ diagnostics.push({
571
+ code: 'GUI_ANIMATION_SOURCE_MANIFEST_INVALID',
572
+ severity: 'error',
573
+ category: 'syntax',
574
+ message: `Animation source manifest does not match schema v1: ${parsed.error.issues
575
+ .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)
576
+ .join('; ')}`,
577
+ location,
578
+ });
579
+ return;
580
+ }
581
+ const id = deterministicId('gui_animation_source_manifest', {
582
+ path: file.displayPath,
583
+ sprite: parsed.data.sprite,
584
+ });
585
+ const manifest = {
586
+ ...parsed.data,
587
+ id,
588
+ sourcePath: file.displayPath,
589
+ relativePath: file.relativePath,
590
+ location,
591
+ };
592
+ addDomainEntry(manifests, manifest, 'animation source manifest');
593
+ addNode(nodes, {
594
+ id,
595
+ kind: 'animation_source_manifest',
596
+ name: parsed.data.sprite,
597
+ path: file.displayPath,
598
+ location,
599
+ metadata: {
600
+ schemaVersion: parsed.data.schemaVersion,
601
+ projectOwned: parsed.data.projectOwned,
602
+ sheet: parsed.data.sheet.path,
603
+ frameCount: parsed.data.sourceFrames.length,
604
+ },
605
+ });
606
+ addEdge(edges, 'contains', fileNodeId, id, true, {}, location);
607
+ }
608
+ function linkAnimationSources(nodes, edges, manifests, sprites, textureNodes, frameNodes) {
609
+ const spritesByName = new Map(sprites.map((sprite) => [sprite.name, sprite]));
610
+ for (const manifest of manifests) {
611
+ const sprite = spritesByName.get(manifest.sprite);
612
+ addEdge(edges, 'animation_provenance', sprite?.id ?? `sprite:${manifest.sprite}`, manifest.id, sprite !== undefined, { sprite: manifest.sprite }, manifest.location);
613
+ const sheet = textureNodes.get(normalizeAssetPath(manifest.sheet.path));
614
+ addEdge(edges, 'animation_sheet', manifest.id, sheet ?? `texture:${normalizeAssetPath(manifest.sheet.path)}`, sheet !== undefined, { texturePath: manifest.sheet.path }, manifest.location);
615
+ for (const frame of manifest.sourceFrames) {
616
+ const normalized = normalizeAssetPath(frame.path);
617
+ const target = frameNodes.get(normalized);
618
+ addEdge(edges, 'animation_source_frame', manifest.id, target ?? `animation_source_frame:${normalized}`, target !== undefined, { texturePath: frame.path }, manifest.location);
619
+ }
620
+ }
621
+ }
622
+ function indexScriptedLocalisation(document, file, fileNodeId, nodes, edges, definitions) {
623
+ for (const assignment of assignments(document.root, 'defined_text')) {
624
+ if (assignment.value.type !== 'block')
625
+ continue;
626
+ const name = firstScalar(assignment.value, 'name')?.value;
627
+ if (name === undefined)
628
+ continue;
629
+ const localisationKeys = childBlocks(assignment.value, 'text')
630
+ .flatMap((textBlock) => firstScalar(textBlock, 'localisation_key')?.value ?? [])
631
+ .sort((left, right) => compareCodeUnits(left, right));
632
+ const id = deterministicId('scripted_localisation', { path: file.displayPath, name });
633
+ const location = nodeLocation(document, assignment, name);
634
+ addDomainEntry(definitions, {
635
+ id,
636
+ name,
637
+ sourcePath: file.displayPath,
638
+ location,
639
+ localisationKeys,
640
+ rawSource: raw(document, assignment),
641
+ }, 'scripted localisation');
642
+ addNode(nodes, {
643
+ id,
644
+ kind: 'scripted_localisation',
645
+ name,
646
+ path: file.displayPath,
647
+ location,
648
+ metadata: { localisationKeys },
649
+ });
650
+ addEdge(edges, 'contains', fileNodeId, id, true, {}, location);
651
+ }
652
+ }
653
+ function indexDecisionEntries(document, file, nodes, pendingDecisionEdges) {
654
+ if (file.relativePath.toLowerCase().includes('common/scripted_guis/'))
655
+ return;
656
+ const walk = (block, owner) => {
657
+ for (const assignment of assignments(block)) {
658
+ const nextOwner = assignment.value.type === 'block'
659
+ ? (firstScalar(assignment.value, 'id')?.value ?? assignment.key.value)
660
+ : owner;
661
+ if (assignment.key.value === 'scripted_gui' && assignment.value.type === 'scalar') {
662
+ const category = owner ?? `${file.displayPath}:${assignment.start}`;
663
+ const categoryId = deterministicId('decision_category', {
664
+ path: file.displayPath,
665
+ category,
666
+ });
667
+ if (!nodes.some((node) => node.id === categoryId)) {
668
+ addNode(nodes, {
669
+ id: categoryId,
670
+ kind: 'decision_category',
671
+ name: category,
672
+ path: file.displayPath,
673
+ location: nodeLocation(document, assignment, category),
674
+ metadata: {},
675
+ });
676
+ }
677
+ addDomainEntry(pendingDecisionEdges, {
678
+ from: categoryId,
679
+ target: assignment.value.value,
680
+ location: nodeLocation(document, assignment, category),
681
+ }, 'pending decision edge', GUI_GRAPH_MAX_EDGES);
682
+ }
683
+ if (assignment.value.type === 'block')
684
+ walk(assignment.value, nextOwner);
685
+ }
686
+ };
687
+ walk(document.root);
688
+ }
689
+ function linkGraph(nodes, edges, elements, sprites, fonts, scriptedGuis, scriptedLocalisation, localisation, textureNodes, fontAssetNodes, pendingDecisionEdges) {
690
+ const spriteByName = new Map(sprites.map((sprite) => [sprite.name, sprite]));
691
+ const fontByName = new Map(fonts.map((font) => [font.name, font]));
692
+ const elementByName = new Map();
693
+ for (const element of [...elements].sort((a, b) => a.definitionOrder - b.definitionOrder)) {
694
+ if (!elementByName.has(element.name))
695
+ elementByName.set(element.name, element);
696
+ }
697
+ const scriptedByName = new Map(scriptedGuis.map((gui) => [gui.name, gui]));
698
+ const localisationByKey = new Map();
699
+ for (const entry of localisation)
700
+ if (!localisationByKey.has(entry.key))
701
+ localisationByKey.set(entry.key, entry);
702
+ for (const definition of scriptedLocalisation) {
703
+ for (const key of definition.localisationKeys) {
704
+ const entry = localisationByKey.get(key);
705
+ addEdge(edges, 'uses_localisation', definition.id, entry === undefined ? `localisation:${key}` : deterministicId('gui_loc', entry), entry !== undefined, { key }, definition.location);
706
+ }
707
+ }
708
+ for (const sprite of sprites) {
709
+ for (const [index, texturePath] of [sprite.texturePath, sprite.texturePath2].entries()) {
710
+ if (texturePath === undefined)
711
+ continue;
712
+ const textureId = textureNodes.get(normalizeAssetPath(texturePath));
713
+ addEdge(edges, 'uses_texture', sprite.id, textureId ?? `texture:${normalizeAssetPath(texturePath)}`, textureId !== undefined, { texturePath, slot: index + 1 }, sprite.location);
714
+ }
715
+ const candidates = [
716
+ sprite.staticFallback,
717
+ `${sprite.name}_static`,
718
+ `${sprite.name}_fallback`,
719
+ ].filter((value) => value !== undefined);
720
+ const fallback = candidates
721
+ .map((name) => spriteByName.get(name))
722
+ .find((value) => value !== undefined);
723
+ if (fallback !== undefined)
724
+ addEdge(edges, 'static_fallback', sprite.id, fallback.id, true, {}, sprite.location);
725
+ else if (sprite.staticFallback !== undefined)
726
+ addEdge(edges, 'static_fallback', sprite.id, `sprite:${sprite.staticFallback}`, false, { spriteName: sprite.staticFallback }, sprite.location);
727
+ }
728
+ for (const font of fonts) {
729
+ for (const assetPath of font.assetPaths) {
730
+ const normalizedAssetPath = normalizeAssetPath(assetPath);
731
+ const assetId = fontAssetNodes.get(normalizedAssetPath) ??
732
+ fontAssetNodes.get(`${normalizedAssetPath}.fnt`) ??
733
+ fontAssetNodes.get(`${normalizedAssetPath}.ttf`) ??
734
+ fontAssetNodes.get(`${normalizedAssetPath}.otf`);
735
+ addEdge(edges, 'uses_font', font.id, assetId ?? `font_asset:${normalizedAssetPath}`, assetId !== undefined, { assetPath }, font.location);
736
+ }
737
+ }
738
+ for (const element of elements) {
739
+ const spriteName = [element.attributes.spriteType, element.attributes.quadTextureSprite].find((value) => typeof value === 'string');
740
+ if (spriteName !== undefined) {
741
+ const sprite = spriteByName.get(spriteName);
742
+ addEdge(edges, 'uses_sprite', element.id, sprite?.id ?? `sprite:${spriteName}`, sprite !== undefined, { spriteName }, element.location);
743
+ }
744
+ const fontName = [element.attributes.font, element.attributes.buttonFont].find((value) => typeof value === 'string');
745
+ if (fontName !== undefined) {
746
+ const font = fontByName.get(fontName);
747
+ addEdge(edges, 'uses_font', element.id, font?.id ?? `font:${fontName}`, font !== undefined, { fontName }, element.location);
748
+ }
749
+ for (const key of ['text', 'buttonText', 'pdx_tooltip', 'pdx_tooltip_delayed', 'hint_tag']) {
750
+ const value = element.attributes[key];
751
+ if (typeof value !== 'string')
752
+ continue;
753
+ const entry = localisationByKey.get(value);
754
+ addEdge(edges, 'uses_localisation', element.id, entry === undefined ? `localisation:${value}` : deterministicId('gui_loc', entry), entry !== undefined, { field: key, key: value }, element.location);
755
+ }
756
+ }
757
+ for (const gui of scriptedGuis) {
758
+ if (gui.windowName !== undefined) {
759
+ const window = elementByName.get(gui.windowName);
760
+ addEdge(edges, 'window', gui.id, window?.id ?? `gui_element:${gui.windowName}`, window !== undefined, { windowName: gui.windowName }, gui.location);
761
+ }
762
+ const parentName = gui.parentWindowName ?? gui.parentWindowToken;
763
+ if (parentName !== undefined) {
764
+ const parent = elementByName.get(parentName);
765
+ const parentId = parent?.id ?? deterministicId('parent_window', parentName);
766
+ if (parent === undefined && !nodes.some((node) => node.id === parentId)) {
767
+ addNode(nodes, {
768
+ id: parentId,
769
+ kind: 'parent_window',
770
+ name: parentName,
771
+ path: gui.sourcePath,
772
+ metadata: {},
773
+ });
774
+ }
775
+ addEdge(edges, 'parent_window', gui.id, parentId, true, { token: parent === undefined }, gui.location);
776
+ }
777
+ if (gui.parentScriptedGui !== undefined) {
778
+ const parent = scriptedByName.get(gui.parentScriptedGui);
779
+ addEdge(edges, 'parent_scripted_gui', gui.id, parent?.id ?? `scripted_gui:${gui.parentScriptedGui}`, parent !== undefined, {}, gui.location);
780
+ }
781
+ for (const effect of gui.effects) {
782
+ const elementName = actionElementName(effect);
783
+ const element = elementByName.get(elementName);
784
+ const effectNode = deterministicId('gui_effect', { id: gui.id, effect });
785
+ addEdge(edges, 'button_effect', effectNode, element?.id ?? `gui_element:${elementName}`, element !== undefined, { action: effect }, gui.location);
786
+ }
787
+ for (const trigger of gui.triggers) {
788
+ const elementName = actionElementName(trigger);
789
+ const element = elementByName.get(elementName);
790
+ const triggerNode = deterministicId('gui_trigger', { id: gui.id, trigger });
791
+ addEdge(edges, 'button_trigger', triggerNode, element?.id ?? `gui_element:${elementName}`, element !== undefined, { action: trigger }, gui.location);
792
+ }
793
+ for (const property of gui.properties) {
794
+ const element = elementByName.get(property);
795
+ addEdge(edges, 'property_target', gui.id, element?.id ?? `gui_element:${property}`, element !== undefined, { property }, gui.location);
796
+ }
797
+ }
798
+ for (const pending of pendingDecisionEdges) {
799
+ const target = scriptedByName.get(pending.target);
800
+ addEdge(edges, 'decision_category_entry', pending.from, target?.id ?? `scripted_gui:${pending.target}`, target !== undefined, { scriptedGui: pending.target }, pending.location);
801
+ }
802
+ }
803
+ function skippedInventoryCouldResolve(edge, sharedIndex) {
804
+ switch (edge.kind) {
805
+ case 'uses_sprite':
806
+ case 'static_fallback':
807
+ return sharedIndex.hasSkippedSourceForKind('sprite');
808
+ case 'uses_localisation':
809
+ return sharedIndex.hasSkippedSourceForKind('localisation');
810
+ case 'uses_font':
811
+ // GFX definition files can contain both sprite and bitmap/outline font definitions.
812
+ return sharedIndex.hasSkippedSourceForKind('sprite');
813
+ case 'window':
814
+ case 'button_effect':
815
+ case 'button_trigger':
816
+ case 'property_target':
817
+ return sharedIndex.hasSkippedSourceForKind('gui_element');
818
+ case 'parent_scripted_gui':
819
+ case 'decision_category_entry':
820
+ return sharedIndex.hasSkippedSourceForKind('scripted_gui');
821
+ default:
822
+ return false;
823
+ }
824
+ }
825
+ function markPartialReferenceEdges(edges, sharedIndex) {
826
+ for (const edge of edges) {
827
+ if (!edge.resolved && skippedInventoryCouldResolve(edge, sharedIndex)) {
828
+ edge.partialInventory = true;
829
+ }
830
+ }
831
+ }
832
+ function* referenceDiagnostics(edges) {
833
+ for (const edge of edges) {
834
+ if (edge.resolved ||
835
+ edge.kind === 'uses_texture' ||
836
+ edge.kind === 'animation_sheet' ||
837
+ edge.kind === 'animation_source_frame' ||
838
+ (edge.kind === 'uses_font' && edge.metadata.assetPath !== undefined))
839
+ continue;
840
+ const partial = edge.partialInventory === true;
841
+ yield {
842
+ code: partial ? 'GUI_REFERENCE_UNRESOLVED_PARTIAL' : 'GUI_REFERENCE_UNRESOLVED',
843
+ severity: partial ? 'warning' : 'error',
844
+ category: 'reference',
845
+ message: partial
846
+ ? `The partial GUI inventory cannot resolve ${edge.kind.replaceAll('_', ' ')} reference ${referenceLabel(edge)}; a skipped source could define it`
847
+ : `Unresolved GUI ${edge.kind.replaceAll('_', ' ')} reference: ${referenceLabel(edge)}`,
848
+ ...(edge.location === undefined ? {} : { location: edge.location }),
849
+ details: {
850
+ edgeId: edge.id,
851
+ edgeKind: edge.kind,
852
+ from: edge.from,
853
+ to: edge.to,
854
+ ...(partial ? { partialInventory: true } : {}),
855
+ },
856
+ };
857
+ }
858
+ }
859
+ function referenceLabel(edge) {
860
+ const value = edge.metadata.texturePath ??
861
+ edge.metadata.spriteName ??
862
+ edge.metadata.fontName ??
863
+ edge.metadata.key;
864
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean')
865
+ return String(value);
866
+ return value === undefined ? edge.to : JSON.stringify(value);
867
+ }
868
+ export function buildGuiSourceGraph(files, sharedIndex) {
869
+ const activeFiles = files.filter(({ shadowedBy }) => shadowedBy === undefined);
870
+ const nodes = [];
871
+ const edges = [];
872
+ const elements = [];
873
+ const sprites = [];
874
+ const fonts = [];
875
+ const scriptedGuis = [];
876
+ const animationSources = [];
877
+ const scriptedLocalisation = [];
878
+ const localisation = [];
879
+ const diagnostics = new DiagnosticCollector(2_000, {
880
+ code: 'GUI_GRAPH_DIAGNOSTICS_TRUNCATED',
881
+ category: 'layout',
882
+ message: 'GUI source graph diagnostics exceeded the fixed global result ceiling',
883
+ });
884
+ diagnostics.pushMany(sharedIndex.diagnostics);
885
+ if (!sharedIndex.complete) {
886
+ diagnostics.push({
887
+ code: 'GUI_INVENTORY_PARTIAL',
888
+ severity: 'warning',
889
+ category: 'reference',
890
+ message: sharedIndex.skippedSourceCount === 0
891
+ ? 'The GUI inventory is incomplete because the shared index reached a fixed record limit'
892
+ : `The GUI inventory skipped ${sharedIndex.skippedSourceCount} over-limit source${sharedIndex.skippedSourceCount === 1 ? '' : 's'}`,
893
+ details: {
894
+ skippedSourceCount: sharedIndex.skippedSourceCount,
895
+ retainedSkippedSources: sharedIndex.skippedSources.length,
896
+ skippedSources: sharedIndex.skippedSources.slice(0, 10).map(({ path, reasonCodes }) => ({
897
+ path,
898
+ reasonCodes,
899
+ })),
900
+ },
901
+ });
902
+ }
903
+ const sourceHashes = {};
904
+ const textureNodes = new Map();
905
+ const fontAssetNodes = new Map();
906
+ const animationFrameNodes = new Map();
907
+ const pendingDecisionEdges = [];
908
+ for (const file of [...activeFiles].sort((a, b) => compareCodeUnits(a.displayPath, b.displayPath))) {
909
+ sourceHashes[file.displayPath] = file.sha256;
910
+ if (sharedIndex.isSourceSkipped(file.displayPath))
911
+ continue;
912
+ const kind = fileKind(file);
913
+ let fileNodeId;
914
+ if (kind !== undefined) {
915
+ fileNodeId = deterministicId('gui_file', { kind, path: file.displayPath });
916
+ addNode(nodes, {
917
+ id: fileNodeId,
918
+ kind,
919
+ name: path.posix.basename(file.relativePath),
920
+ path: file.displayPath,
921
+ metadata: { rootKind: file.rootKind, loadOrder: file.loadOrder, sha256: file.sha256 },
922
+ });
923
+ }
924
+ const normalized = normalizeAssetPath(file.relativePath);
925
+ if (normalized.startsWith('hoi4_agent/animation_sources/') && !normalized.endsWith('.json')) {
926
+ const id = deterministicId('gui_animation_source_frame', { path: file.displayPath });
927
+ animationFrameNodes.set(normalized, id);
928
+ addNode(nodes, {
929
+ id,
930
+ kind: 'animation_source_frame',
931
+ name: path.posix.basename(normalized),
932
+ path: file.displayPath,
933
+ metadata: { relativePath: file.relativePath, sha256: file.sha256 },
934
+ });
935
+ }
936
+ if (/\.(?:png|tga|bmp|dds)$/u.test(normalized)) {
937
+ const id = deterministicId('gui_texture', { path: file.displayPath });
938
+ textureNodes.set(normalized, id);
939
+ addNode(nodes, {
940
+ id,
941
+ kind: 'texture',
942
+ name: path.posix.basename(normalized),
943
+ path: file.displayPath,
944
+ metadata: {
945
+ relativePath: file.relativePath,
946
+ format: path.posix.extname(normalized).slice(1),
947
+ },
948
+ });
949
+ }
950
+ if (/\.(?:ttf|otf|ttc|woff|woff2|fnt)$/u.test(normalized)) {
951
+ const id = deterministicId('gui_font_asset', { path: file.displayPath });
952
+ fontAssetNodes.set(normalized, id);
953
+ addNode(nodes, {
954
+ id,
955
+ kind: 'font',
956
+ name: path.posix.basename(normalized),
957
+ path: file.displayPath,
958
+ metadata: { asset: true, relativePath: file.relativePath },
959
+ });
960
+ if (normalized.endsWith('.fnt')) {
961
+ addDomainEntry(fonts, {
962
+ id,
963
+ name: path.posix.basename(normalized, '.fnt'),
964
+ sourcePath: file.displayPath,
965
+ kind: 'bmfont',
966
+ assetPaths: [file.relativePath],
967
+ }, 'font');
968
+ }
969
+ }
970
+ if (kind === 'localisation_file' && fileNodeId !== undefined) {
971
+ const document = parseLocalisation(file.bytes, file.displayPath);
972
+ diagnostics.pushMany(document.diagnostics);
973
+ for (const entry of document.entries) {
974
+ const value = {
975
+ key: entry.key,
976
+ language: entry.language,
977
+ value: entry.value,
978
+ sourcePath: file.displayPath,
979
+ location: locationFor(file.displayPath, document.lineIndex, entry.start, entry.end),
980
+ };
981
+ addDomainEntry(localisation, value, 'localisation');
982
+ const id = deterministicId('gui_loc', value);
983
+ addNode(nodes, {
984
+ id,
985
+ kind: 'localisation',
986
+ name: entry.key,
987
+ path: file.displayPath,
988
+ ...(value.location === undefined ? {} : { location: value.location }),
989
+ metadata: { language: entry.language, value: entry.value },
990
+ });
991
+ addEdge(edges, 'contains', fileNodeId, id, true, {}, value.location);
992
+ }
993
+ continue;
994
+ }
995
+ if (kind === 'animation_source_manifest' && fileNodeId !== undefined) {
996
+ indexAnimationSourceManifest(file, fileNodeId, nodes, edges, animationSources, diagnostics);
997
+ continue;
998
+ }
999
+ if (kind === undefined || fileNodeId === undefined) {
1000
+ if (/\.(?:txt|gui|gfx)$/u.test(normalized)) {
1001
+ const document = parseClausewitz(file.bytes, file.displayPath);
1002
+ diagnostics.pushMany(document.diagnostics);
1003
+ indexDecisionEntries(document, file, nodes, pendingDecisionEdges);
1004
+ }
1005
+ continue;
1006
+ }
1007
+ const document = parseClausewitz(file.bytes, file.displayPath);
1008
+ diagnostics.pushMany(document.diagnostics);
1009
+ if (kind === 'gui_file')
1010
+ indexGuiElements(document, file, fileNodeId, nodes, edges, elements);
1011
+ if (kind === 'gfx_file') {
1012
+ indexSpritesAndFonts(document, file, fileNodeId, nodes, edges, sprites, fonts);
1013
+ }
1014
+ if (kind === 'scripted_gui_file') {
1015
+ indexScriptedGuis(document, file, fileNodeId, nodes, edges, scriptedGuis);
1016
+ }
1017
+ if (kind === 'scripted_localisation_file') {
1018
+ indexScriptedLocalisation(document, file, fileNodeId, nodes, edges, scriptedLocalisation);
1019
+ }
1020
+ indexDecisionEntries(document, file, nodes, pendingDecisionEdges);
1021
+ }
1022
+ linkGraph(nodes, edges, elements, sprites, fonts, scriptedGuis, scriptedLocalisation, localisation, textureNodes, fontAssetNodes, pendingDecisionEdges);
1023
+ linkAnimationSources(nodes, edges, animationSources, sprites, textureNodes, animationFrameNodes);
1024
+ markPartialReferenceEdges(edges, sharedIndex);
1025
+ diagnostics.pushMany(referenceDiagnostics(edges));
1026
+ if (nodes.length > GUI_GRAPH_MAX_NODES ||
1027
+ edges.length > GUI_GRAPH_MAX_EDGES ||
1028
+ elements.length > GUI_GRAPH_MAX_ELEMENTS) {
1029
+ diagnostics.push({
1030
+ code: 'GUI_GRAPH_BUDGET_BLOCKED',
1031
+ severity: 'blocker',
1032
+ category: 'layout',
1033
+ message: 'GUI source graph exceeds the fixed graph work ceiling',
1034
+ details: {
1035
+ nodes: nodes.length,
1036
+ maximumNodes: GUI_GRAPH_MAX_NODES,
1037
+ edges: edges.length,
1038
+ maximumEdges: GUI_GRAPH_MAX_EDGES,
1039
+ elements: elements.length,
1040
+ maximumElements: GUI_GRAPH_MAX_ELEMENTS,
1041
+ },
1042
+ });
1043
+ }
1044
+ nodes.sort((a, b) => compareCodeUnits(a.id, b.id));
1045
+ edges.sort((a, b) => compareCodeUnits(a.id, b.id));
1046
+ elements.sort((a, b) => a.definitionOrder - b.definitionOrder || compareCodeUnits(a.id, b.id));
1047
+ sprites.sort((a, b) => compareCodeUnits(a.name, b.name) || compareCodeUnits(a.sourcePath, b.sourcePath));
1048
+ fonts.sort((a, b) => compareCodeUnits(a.name, b.name) || compareCodeUnits(a.sourcePath, b.sourcePath));
1049
+ scriptedGuis.sort((a, b) => compareCodeUnits(a.name, b.name));
1050
+ animationSources.sort((a, b) => compareCodeUnits(a.sprite, b.sprite) || compareCodeUnits(a.sourcePath, b.sourcePath));
1051
+ scriptedLocalisation.sort((a, b) => compareCodeUnits(a.name, b.name));
1052
+ localisation.sort((a, b) => compareCodeUnits(a.language, b.language) || compareCodeUnits(a.key, b.key));
1053
+ return {
1054
+ complete: sharedIndex.complete,
1055
+ skippedSourceCount: sharedIndex.skippedSourceCount,
1056
+ skippedSources: sharedIndex.skippedSources,
1057
+ skippedPossibleSymbolKinds: sharedIndex.skippedPossibleSymbolKinds,
1058
+ nodes,
1059
+ edges,
1060
+ elements,
1061
+ sprites,
1062
+ fonts,
1063
+ scriptedGuis,
1064
+ animationSources,
1065
+ scriptedLocalisation,
1066
+ localisation,
1067
+ sourceHashes: Object.fromEntries(Object.entries(sourceHashes).sort(([left], [right]) => compareCodeUnits(left, right))),
1068
+ filesScanned: [...activeFiles]
1069
+ .map(({ displayPath }) => displayPath)
1070
+ .sort((a, b) => compareCodeUnits(a, b)),
1071
+ diagnostics: sortDiagnostics(diagnostics.values()),
1072
+ };
1073
+ }
1074
+ //# sourceMappingURL=source-graph.js.map