hoi4-agent-tools 0.2.0 → 1.0.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 (428) hide show
  1. package/CHANGELOG.md +12 -118
  2. package/README.md +35 -127
  3. package/SECURITY.md +5 -7
  4. package/dist/bin/http.js +0 -1
  5. package/dist/bin/setup.js +141 -92
  6. package/dist/bin/stdio.js +0 -1
  7. package/dist/hoi4_agent_tools/core/artifacts.js +0 -1
  8. package/dist/hoi4_agent_tools/core/canonical.js +0 -1
  9. package/dist/hoi4_agent_tools/core/configuration.js +28 -28
  10. package/dist/hoi4_agent_tools/core/diagnostic-collector.js +0 -1
  11. package/dist/hoi4_agent_tools/core/diagnostics.js +0 -1
  12. package/dist/hoi4_agent_tools/core/diff.js +0 -1
  13. package/dist/hoi4_agent_tools/core/engine.js +6 -21
  14. package/dist/hoi4_agent_tools/core/image-diff.js +0 -1
  15. package/dist/hoi4_agent_tools/core/index.js +0 -1
  16. package/dist/hoi4_agent_tools/core/render-budget.js +0 -1
  17. package/dist/hoi4_agent_tools/core/result.js +0 -1
  18. package/dist/hoi4_agent_tools/core/scanner.js +0 -1
  19. package/dist/hoi4_agent_tools/core/server-state.js +0 -1
  20. package/dist/hoi4_agent_tools/core/source/encoding.js +0 -1
  21. package/dist/hoi4_agent_tools/core/source/index.js +0 -1
  22. package/dist/hoi4_agent_tools/core/source/lexer.js +0 -1
  23. package/dist/hoi4_agent_tools/core/source/limits.js +0 -1
  24. package/dist/hoi4_agent_tools/core/source/localisation.js +0 -1
  25. package/dist/hoi4_agent_tools/core/source/parser.js +0 -1
  26. package/dist/hoi4_agent_tools/core/source/rewrite.js +0 -1
  27. package/dist/hoi4_agent_tools/core/svg-text.js +0 -1
  28. package/dist/hoi4_agent_tools/core/transaction-limits.js +0 -1
  29. package/dist/hoi4_agent_tools/core/transactions.js +2 -30
  30. package/dist/hoi4_agent_tools/core/workspace.js +112 -396
  31. package/dist/hoi4_agent_tools/focus/compiler.js +0 -1
  32. package/dist/hoi4_agent_tools/focus/continuous-render.js +0 -1
  33. package/dist/hoi4_agent_tools/focus/drift.js +0 -1
  34. package/dist/hoi4_agent_tools/focus/geometry.js +0 -1
  35. package/dist/hoi4_agent_tools/focus/importer.js +0 -1
  36. package/dist/hoi4_agent_tools/focus/index.js +0 -1
  37. package/dist/hoi4_agent_tools/focus/layout.js +0 -1
  38. package/dist/hoi4_agent_tools/focus/limits.js +0 -1
  39. package/dist/hoi4_agent_tools/focus/lint.js +0 -1
  40. package/dist/hoi4_agent_tools/focus/model.js +0 -1
  41. package/dist/hoi4_agent_tools/focus/native-effects.js +0 -1
  42. package/dist/hoi4_agent_tools/focus/planning.js +0 -1
  43. package/dist/hoi4_agent_tools/focus/presentation.js +0 -1
  44. package/dist/hoi4_agent_tools/focus/render.js +0 -1
  45. package/dist/hoi4_agent_tools/focus/service.js +7 -8
  46. package/dist/hoi4_agent_tools/focus/source-update.js +1 -2
  47. package/dist/hoi4_agent_tools/gui/animation-manifest.js +0 -1
  48. package/dist/hoi4_agent_tools/gui/assets.js +0 -1
  49. package/dist/hoi4_agent_tools/gui/dds.js +0 -1
  50. package/dist/hoi4_agent_tools/gui/helpers.js +1 -2
  51. package/dist/hoi4_agent_tools/gui/index.js +0 -1
  52. package/dist/hoi4_agent_tools/gui/layout.js +0 -1
  53. package/dist/hoi4_agent_tools/gui/limits.js +0 -1
  54. package/dist/hoi4_agent_tools/gui/renderer.js +0 -1
  55. package/dist/hoi4_agent_tools/gui/scenario.js +0 -1
  56. package/dist/hoi4_agent_tools/gui/source-graph.js +0 -1
  57. package/dist/hoi4_agent_tools/gui/source-patch.js +1 -2
  58. package/dist/hoi4_agent_tools/gui/studio.js +247 -104
  59. package/dist/hoi4_agent_tools/gui/tga.js +0 -1
  60. package/dist/hoi4_agent_tools/gui/types.js +0 -1
  61. package/dist/hoi4_agent_tools/gui/validators.js +0 -1
  62. package/dist/hoi4_agent_tools/map/bmp.js +0 -1
  63. package/dist/hoi4_agent_tools/map/diagnostic-limit.js +0 -1
  64. package/dist/hoi4_agent_tools/map/index.js +0 -1
  65. package/dist/hoi4_agent_tools/map/limits.js +2 -1
  66. package/dist/hoi4_agent_tools/map/model.js +0 -1
  67. package/dist/hoi4_agent_tools/map/operations.js +0 -1
  68. package/dist/hoi4_agent_tools/map/render.js +0 -1
  69. package/dist/hoi4_agent_tools/map/service.js +171 -33
  70. package/dist/hoi4_agent_tools/map/validation.js +0 -1
  71. package/dist/hoi4_agent_tools/mcp/resources/register.js +61 -187
  72. package/dist/hoi4_agent_tools/mcp/security/auth.js +1 -2
  73. package/dist/hoi4_agent_tools/mcp/server/base-tools.js +24 -750
  74. package/dist/hoi4_agent_tools/mcp/server/create.js +3 -12
  75. package/dist/hoi4_agent_tools/mcp/server/output-schemas.js +0 -71
  76. package/dist/hoi4_agent_tools/mcp/server/progress.js +0 -1
  77. package/dist/hoi4_agent_tools/mcp/server/result.js +24 -30
  78. package/dist/hoi4_agent_tools/mcp/server/transaction-execution.js +10 -14
  79. package/dist/hoi4_agent_tools/mcp/tools/focus.js +219 -275
  80. package/dist/hoi4_agent_tools/mcp/tools/gui.js +149 -250
  81. package/dist/hoi4_agent_tools/mcp/tools/map.js +256 -337
  82. package/dist/hoi4_agent_tools/mcp/tools/mods.js +54 -0
  83. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js +0 -1
  84. package/dist/hoi4_agent_tools/mcp/transports/event-store.js +0 -1
  85. package/dist/hoi4_agent_tools/mcp/transports/http.js +1 -12
  86. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js +0 -1
  87. package/dist/hoi4_agent_tools/runtime.js +5 -2
  88. package/dist/hoi4_agent_tools/schemas/common.js +1 -2
  89. package/dist/hoi4_agent_tools/schemas/focus.js +0 -1
  90. package/dist/hoi4_agent_tools/schemas/map.js +0 -1
  91. package/dist/hoi4_agent_tools/schemas/transaction.js +0 -1
  92. package/dist/hoi4_agent_tools/version.js +1 -2
  93. package/docs/README.md +8 -21
  94. package/docs/development.md +22 -0
  95. package/docs/focus.md +40 -0
  96. package/docs/gui.md +37 -0
  97. package/docs/http.md +53 -0
  98. package/docs/map.md +39 -0
  99. package/docs/setup.md +39 -0
  100. package/package.json +10 -11
  101. package/server.json +3 -12
  102. package/dist/bin/http.d.ts +0 -3
  103. package/dist/bin/http.d.ts.map +0 -1
  104. package/dist/bin/http.js.map +0 -1
  105. package/dist/bin/setup.d.ts +0 -3
  106. package/dist/bin/setup.d.ts.map +0 -1
  107. package/dist/bin/setup.js.map +0 -1
  108. package/dist/bin/stdio.d.ts +0 -3
  109. package/dist/bin/stdio.d.ts.map +0 -1
  110. package/dist/bin/stdio.js.map +0 -1
  111. package/dist/hoi4_agent_tools/core/artifacts.d.ts +0 -117
  112. package/dist/hoi4_agent_tools/core/artifacts.d.ts.map +0 -1
  113. package/dist/hoi4_agent_tools/core/artifacts.js.map +0 -1
  114. package/dist/hoi4_agent_tools/core/canonical.d.ts +0 -13
  115. package/dist/hoi4_agent_tools/core/canonical.d.ts.map +0 -1
  116. package/dist/hoi4_agent_tools/core/canonical.js.map +0 -1
  117. package/dist/hoi4_agent_tools/core/configuration.d.ts +0 -138
  118. package/dist/hoi4_agent_tools/core/configuration.d.ts.map +0 -1
  119. package/dist/hoi4_agent_tools/core/configuration.js.map +0 -1
  120. package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts +0 -18
  121. package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts.map +0 -1
  122. package/dist/hoi4_agent_tools/core/diagnostic-collector.js.map +0 -1
  123. package/dist/hoi4_agent_tools/core/diagnostics.d.ts +0 -26
  124. package/dist/hoi4_agent_tools/core/diagnostics.d.ts.map +0 -1
  125. package/dist/hoi4_agent_tools/core/diagnostics.js.map +0 -1
  126. package/dist/hoi4_agent_tools/core/diff.d.ts +0 -22
  127. package/dist/hoi4_agent_tools/core/diff.d.ts.map +0 -1
  128. package/dist/hoi4_agent_tools/core/diff.js.map +0 -1
  129. package/dist/hoi4_agent_tools/core/engine.d.ts +0 -57
  130. package/dist/hoi4_agent_tools/core/engine.d.ts.map +0 -1
  131. package/dist/hoi4_agent_tools/core/engine.js.map +0 -1
  132. package/dist/hoi4_agent_tools/core/image-diff.d.ts +0 -14
  133. package/dist/hoi4_agent_tools/core/image-diff.d.ts.map +0 -1
  134. package/dist/hoi4_agent_tools/core/image-diff.js.map +0 -1
  135. package/dist/hoi4_agent_tools/core/index.d.ts +0 -64
  136. package/dist/hoi4_agent_tools/core/index.d.ts.map +0 -1
  137. package/dist/hoi4_agent_tools/core/index.js.map +0 -1
  138. package/dist/hoi4_agent_tools/core/index.public.d.ts +0 -16
  139. package/dist/hoi4_agent_tools/core/index.public.d.ts.map +0 -1
  140. package/dist/hoi4_agent_tools/core/index.public.js +0 -16
  141. package/dist/hoi4_agent_tools/core/index.public.js.map +0 -1
  142. package/dist/hoi4_agent_tools/core/render-budget.d.ts +0 -51
  143. package/dist/hoi4_agent_tools/core/render-budget.d.ts.map +0 -1
  144. package/dist/hoi4_agent_tools/core/render-budget.js.map +0 -1
  145. package/dist/hoi4_agent_tools/core/result.d.ts +0 -45
  146. package/dist/hoi4_agent_tools/core/result.d.ts.map +0 -1
  147. package/dist/hoi4_agent_tools/core/result.js.map +0 -1
  148. package/dist/hoi4_agent_tools/core/scanner.d.ts +0 -28
  149. package/dist/hoi4_agent_tools/core/scanner.d.ts.map +0 -1
  150. package/dist/hoi4_agent_tools/core/scanner.js.map +0 -1
  151. package/dist/hoi4_agent_tools/core/server-state.d.ts +0 -31
  152. package/dist/hoi4_agent_tools/core/server-state.d.ts.map +0 -1
  153. package/dist/hoi4_agent_tools/core/server-state.js.map +0 -1
  154. package/dist/hoi4_agent_tools/core/source/encoding.d.ts +0 -10
  155. package/dist/hoi4_agent_tools/core/source/encoding.d.ts.map +0 -1
  156. package/dist/hoi4_agent_tools/core/source/encoding.js.map +0 -1
  157. package/dist/hoi4_agent_tools/core/source/index.d.ts +0 -7
  158. package/dist/hoi4_agent_tools/core/source/index.d.ts.map +0 -1
  159. package/dist/hoi4_agent_tools/core/source/index.js.map +0 -1
  160. package/dist/hoi4_agent_tools/core/source/lexer.d.ts +0 -30
  161. package/dist/hoi4_agent_tools/core/source/lexer.d.ts.map +0 -1
  162. package/dist/hoi4_agent_tools/core/source/lexer.js.map +0 -1
  163. package/dist/hoi4_agent_tools/core/source/limits.d.ts +0 -21
  164. package/dist/hoi4_agent_tools/core/source/limits.d.ts.map +0 -1
  165. package/dist/hoi4_agent_tools/core/source/limits.js.map +0 -1
  166. package/dist/hoi4_agent_tools/core/source/localisation.d.ts +0 -20
  167. package/dist/hoi4_agent_tools/core/source/localisation.d.ts.map +0 -1
  168. package/dist/hoi4_agent_tools/core/source/localisation.js.map +0 -1
  169. package/dist/hoi4_agent_tools/core/source/parser.d.ts +0 -44
  170. package/dist/hoi4_agent_tools/core/source/parser.d.ts.map +0 -1
  171. package/dist/hoi4_agent_tools/core/source/parser.js.map +0 -1
  172. package/dist/hoi4_agent_tools/core/source/rewrite.d.ts +0 -10
  173. package/dist/hoi4_agent_tools/core/source/rewrite.d.ts.map +0 -1
  174. package/dist/hoi4_agent_tools/core/source/rewrite.js.map +0 -1
  175. package/dist/hoi4_agent_tools/core/svg-text.d.ts +0 -34
  176. package/dist/hoi4_agent_tools/core/svg-text.d.ts.map +0 -1
  177. package/dist/hoi4_agent_tools/core/svg-text.js.map +0 -1
  178. package/dist/hoi4_agent_tools/core/transaction-limits.d.ts +0 -9
  179. package/dist/hoi4_agent_tools/core/transaction-limits.d.ts.map +0 -1
  180. package/dist/hoi4_agent_tools/core/transaction-limits.js.map +0 -1
  181. package/dist/hoi4_agent_tools/core/transactions.d.ts +0 -164
  182. package/dist/hoi4_agent_tools/core/transactions.d.ts.map +0 -1
  183. package/dist/hoi4_agent_tools/core/transactions.js.map +0 -1
  184. package/dist/hoi4_agent_tools/core/workspace.d.ts +0 -68
  185. package/dist/hoi4_agent_tools/core/workspace.d.ts.map +0 -1
  186. package/dist/hoi4_agent_tools/core/workspace.js.map +0 -1
  187. package/dist/hoi4_agent_tools/focus/compiler.d.ts +0 -10
  188. package/dist/hoi4_agent_tools/focus/compiler.d.ts.map +0 -1
  189. package/dist/hoi4_agent_tools/focus/compiler.js.map +0 -1
  190. package/dist/hoi4_agent_tools/focus/continuous-render.d.ts +0 -32
  191. package/dist/hoi4_agent_tools/focus/continuous-render.d.ts.map +0 -1
  192. package/dist/hoi4_agent_tools/focus/continuous-render.js.map +0 -1
  193. package/dist/hoi4_agent_tools/focus/drift.d.ts +0 -22
  194. package/dist/hoi4_agent_tools/focus/drift.d.ts.map +0 -1
  195. package/dist/hoi4_agent_tools/focus/drift.js.map +0 -1
  196. package/dist/hoi4_agent_tools/focus/geometry.d.ts +0 -17
  197. package/dist/hoi4_agent_tools/focus/geometry.d.ts.map +0 -1
  198. package/dist/hoi4_agent_tools/focus/geometry.js.map +0 -1
  199. package/dist/hoi4_agent_tools/focus/importer.d.ts +0 -9
  200. package/dist/hoi4_agent_tools/focus/importer.d.ts.map +0 -1
  201. package/dist/hoi4_agent_tools/focus/importer.js.map +0 -1
  202. package/dist/hoi4_agent_tools/focus/index.d.ts +0 -14
  203. package/dist/hoi4_agent_tools/focus/index.d.ts.map +0 -1
  204. package/dist/hoi4_agent_tools/focus/index.js.map +0 -1
  205. package/dist/hoi4_agent_tools/focus/layout.d.ts +0 -5
  206. package/dist/hoi4_agent_tools/focus/layout.d.ts.map +0 -1
  207. package/dist/hoi4_agent_tools/focus/layout.js.map +0 -1
  208. package/dist/hoi4_agent_tools/focus/limits.d.ts +0 -9
  209. package/dist/hoi4_agent_tools/focus/limits.d.ts.map +0 -1
  210. package/dist/hoi4_agent_tools/focus/limits.js.map +0 -1
  211. package/dist/hoi4_agent_tools/focus/lint.d.ts +0 -14
  212. package/dist/hoi4_agent_tools/focus/lint.d.ts.map +0 -1
  213. package/dist/hoi4_agent_tools/focus/lint.js.map +0 -1
  214. package/dist/hoi4_agent_tools/focus/model.d.ts +0 -307
  215. package/dist/hoi4_agent_tools/focus/model.d.ts.map +0 -1
  216. package/dist/hoi4_agent_tools/focus/model.js.map +0 -1
  217. package/dist/hoi4_agent_tools/focus/native-effects.d.ts +0 -9
  218. package/dist/hoi4_agent_tools/focus/native-effects.d.ts.map +0 -1
  219. package/dist/hoi4_agent_tools/focus/native-effects.js.map +0 -1
  220. package/dist/hoi4_agent_tools/focus/planning.d.ts +0 -15
  221. package/dist/hoi4_agent_tools/focus/planning.d.ts.map +0 -1
  222. package/dist/hoi4_agent_tools/focus/planning.js.map +0 -1
  223. package/dist/hoi4_agent_tools/focus/presentation.d.ts +0 -24
  224. package/dist/hoi4_agent_tools/focus/presentation.d.ts.map +0 -1
  225. package/dist/hoi4_agent_tools/focus/presentation.js.map +0 -1
  226. package/dist/hoi4_agent_tools/focus/render.d.ts +0 -39
  227. package/dist/hoi4_agent_tools/focus/render.d.ts.map +0 -1
  228. package/dist/hoi4_agent_tools/focus/render.js.map +0 -1
  229. package/dist/hoi4_agent_tools/focus/service.d.ts +0 -82
  230. package/dist/hoi4_agent_tools/focus/service.d.ts.map +0 -1
  231. package/dist/hoi4_agent_tools/focus/service.js.map +0 -1
  232. package/dist/hoi4_agent_tools/focus/source-update.d.ts +0 -6
  233. package/dist/hoi4_agent_tools/focus/source-update.d.ts.map +0 -1
  234. package/dist/hoi4_agent_tools/focus/source-update.js.map +0 -1
  235. package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts +0 -37
  236. package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts.map +0 -1
  237. package/dist/hoi4_agent_tools/gui/animation-manifest.js.map +0 -1
  238. package/dist/hoi4_agent_tools/gui/assets.d.ts +0 -71
  239. package/dist/hoi4_agent_tools/gui/assets.d.ts.map +0 -1
  240. package/dist/hoi4_agent_tools/gui/assets.js.map +0 -1
  241. package/dist/hoi4_agent_tools/gui/dds.d.ts +0 -17
  242. package/dist/hoi4_agent_tools/gui/dds.d.ts.map +0 -1
  243. package/dist/hoi4_agent_tools/gui/dds.js.map +0 -1
  244. package/dist/hoi4_agent_tools/gui/helpers.d.ts +0 -101
  245. package/dist/hoi4_agent_tools/gui/helpers.d.ts.map +0 -1
  246. package/dist/hoi4_agent_tools/gui/helpers.js.map +0 -1
  247. package/dist/hoi4_agent_tools/gui/index.d.ts +0 -15
  248. package/dist/hoi4_agent_tools/gui/index.d.ts.map +0 -1
  249. package/dist/hoi4_agent_tools/gui/index.js.map +0 -1
  250. package/dist/hoi4_agent_tools/gui/layout.d.ts +0 -6
  251. package/dist/hoi4_agent_tools/gui/layout.d.ts.map +0 -1
  252. package/dist/hoi4_agent_tools/gui/layout.js.map +0 -1
  253. package/dist/hoi4_agent_tools/gui/limits.d.ts +0 -25
  254. package/dist/hoi4_agent_tools/gui/limits.d.ts.map +0 -1
  255. package/dist/hoi4_agent_tools/gui/limits.js.map +0 -1
  256. package/dist/hoi4_agent_tools/gui/renderer.d.ts +0 -18
  257. package/dist/hoi4_agent_tools/gui/renderer.d.ts.map +0 -1
  258. package/dist/hoi4_agent_tools/gui/renderer.js.map +0 -1
  259. package/dist/hoi4_agent_tools/gui/scenario.d.ts +0 -66
  260. package/dist/hoi4_agent_tools/gui/scenario.d.ts.map +0 -1
  261. package/dist/hoi4_agent_tools/gui/scenario.js.map +0 -1
  262. package/dist/hoi4_agent_tools/gui/source-graph.d.ts +0 -7
  263. package/dist/hoi4_agent_tools/gui/source-graph.d.ts.map +0 -1
  264. package/dist/hoi4_agent_tools/gui/source-graph.js.map +0 -1
  265. package/dist/hoi4_agent_tools/gui/source-patch.d.ts +0 -13
  266. package/dist/hoi4_agent_tools/gui/source-patch.d.ts.map +0 -1
  267. package/dist/hoi4_agent_tools/gui/source-patch.js.map +0 -1
  268. package/dist/hoi4_agent_tools/gui/studio.d.ts +0 -86
  269. package/dist/hoi4_agent_tools/gui/studio.d.ts.map +0 -1
  270. package/dist/hoi4_agent_tools/gui/studio.js.map +0 -1
  271. package/dist/hoi4_agent_tools/gui/tga.d.ts +0 -16
  272. package/dist/hoi4_agent_tools/gui/tga.d.ts.map +0 -1
  273. package/dist/hoi4_agent_tools/gui/tga.js.map +0 -1
  274. package/dist/hoi4_agent_tools/gui/types.d.ts +0 -322
  275. package/dist/hoi4_agent_tools/gui/types.d.ts.map +0 -1
  276. package/dist/hoi4_agent_tools/gui/types.js.map +0 -1
  277. package/dist/hoi4_agent_tools/gui/validators.d.ts +0 -8
  278. package/dist/hoi4_agent_tools/gui/validators.d.ts.map +0 -1
  279. package/dist/hoi4_agent_tools/gui/validators.js.map +0 -1
  280. package/dist/hoi4_agent_tools/map/bmp.d.ts +0 -62
  281. package/dist/hoi4_agent_tools/map/bmp.d.ts.map +0 -1
  282. package/dist/hoi4_agent_tools/map/bmp.js.map +0 -1
  283. package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts +0 -5
  284. package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts.map +0 -1
  285. package/dist/hoi4_agent_tools/map/diagnostic-limit.js.map +0 -1
  286. package/dist/hoi4_agent_tools/map/index.d.ts +0 -8
  287. package/dist/hoi4_agent_tools/map/index.d.ts.map +0 -1
  288. package/dist/hoi4_agent_tools/map/index.js.map +0 -1
  289. package/dist/hoi4_agent_tools/map/limits.d.ts +0 -13
  290. package/dist/hoi4_agent_tools/map/limits.d.ts.map +0 -1
  291. package/dist/hoi4_agent_tools/map/limits.js.map +0 -1
  292. package/dist/hoi4_agent_tools/map/model.d.ts +0 -269
  293. package/dist/hoi4_agent_tools/map/model.d.ts.map +0 -1
  294. package/dist/hoi4_agent_tools/map/model.js.map +0 -1
  295. package/dist/hoi4_agent_tools/map/operations.d.ts +0 -401
  296. package/dist/hoi4_agent_tools/map/operations.d.ts.map +0 -1
  297. package/dist/hoi4_agent_tools/map/operations.js.map +0 -1
  298. package/dist/hoi4_agent_tools/map/render.d.ts +0 -90
  299. package/dist/hoi4_agent_tools/map/render.d.ts.map +0 -1
  300. package/dist/hoi4_agent_tools/map/render.js.map +0 -1
  301. package/dist/hoi4_agent_tools/map/service.d.ts +0 -81
  302. package/dist/hoi4_agent_tools/map/service.d.ts.map +0 -1
  303. package/dist/hoi4_agent_tools/map/service.js.map +0 -1
  304. package/dist/hoi4_agent_tools/map/validation.d.ts +0 -23
  305. package/dist/hoi4_agent_tools/map/validation.d.ts.map +0 -1
  306. package/dist/hoi4_agent_tools/map/validation.js.map +0 -1
  307. package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts +0 -4
  308. package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts.map +0 -1
  309. package/dist/hoi4_agent_tools/mcp/prompts/register.js +0 -72
  310. package/dist/hoi4_agent_tools/mcp/prompts/register.js.map +0 -1
  311. package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts +0 -9
  312. package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts.map +0 -1
  313. package/dist/hoi4_agent_tools/mcp/registry/metadata.js +0 -10
  314. package/dist/hoi4_agent_tools/mcp/registry/metadata.js.map +0 -1
  315. package/dist/hoi4_agent_tools/mcp/resources/register.d.ts +0 -5
  316. package/dist/hoi4_agent_tools/mcp/resources/register.d.ts.map +0 -1
  317. package/dist/hoi4_agent_tools/mcp/resources/register.js.map +0 -1
  318. package/dist/hoi4_agent_tools/mcp/security/auth.d.ts +0 -24
  319. package/dist/hoi4_agent_tools/mcp/security/auth.d.ts.map +0 -1
  320. package/dist/hoi4_agent_tools/mcp/security/auth.js.map +0 -1
  321. package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts +0 -47
  322. package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts.map +0 -1
  323. package/dist/hoi4_agent_tools/mcp/server/base-tools.js.map +0 -1
  324. package/dist/hoi4_agent_tools/mcp/server/create.d.ts +0 -5
  325. package/dist/hoi4_agent_tools/mcp/server/create.d.ts.map +0 -1
  326. package/dist/hoi4_agent_tools/mcp/server/create.js.map +0 -1
  327. package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts +0 -138
  328. package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts.map +0 -1
  329. package/dist/hoi4_agent_tools/mcp/server/output-schemas.js.map +0 -1
  330. package/dist/hoi4_agent_tools/mcp/server/progress.d.ts +0 -8
  331. package/dist/hoi4_agent_tools/mcp/server/progress.d.ts.map +0 -1
  332. package/dist/hoi4_agent_tools/mcp/server/progress.js.map +0 -1
  333. package/dist/hoi4_agent_tools/mcp/server/result.d.ts +0 -232
  334. package/dist/hoi4_agent_tools/mcp/server/result.d.ts.map +0 -1
  335. package/dist/hoi4_agent_tools/mcp/server/result.js.map +0 -1
  336. package/dist/hoi4_agent_tools/mcp/server/transaction-execution.d.ts +0 -31
  337. package/dist/hoi4_agent_tools/mcp/server/transaction-execution.d.ts.map +0 -1
  338. package/dist/hoi4_agent_tools/mcp/server/transaction-execution.js.map +0 -1
  339. package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts +0 -5
  340. package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts.map +0 -1
  341. package/dist/hoi4_agent_tools/mcp/tools/focus.js.map +0 -1
  342. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts +0 -117
  343. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts.map +0 -1
  344. package/dist/hoi4_agent_tools/mcp/tools/gui.js.map +0 -1
  345. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts +0 -5
  346. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts.map +0 -1
  347. package/dist/hoi4_agent_tools/mcp/tools/map.js.map +0 -1
  348. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts +0 -58
  349. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts.map +0 -1
  350. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js.map +0 -1
  351. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts +0 -26
  352. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts.map +0 -1
  353. package/dist/hoi4_agent_tools/mcp/transports/event-store.js.map +0 -1
  354. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts +0 -28
  355. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts.map +0 -1
  356. package/dist/hoi4_agent_tools/mcp/transports/http.js.map +0 -1
  357. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts +0 -15
  358. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts.map +0 -1
  359. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js.map +0 -1
  360. package/dist/hoi4_agent_tools/runtime.d.ts +0 -4
  361. package/dist/hoi4_agent_tools/runtime.d.ts.map +0 -1
  362. package/dist/hoi4_agent_tools/runtime.js.map +0 -1
  363. package/dist/hoi4_agent_tools/schemas/common.d.ts +0 -74
  364. package/dist/hoi4_agent_tools/schemas/common.d.ts.map +0 -1
  365. package/dist/hoi4_agent_tools/schemas/common.js.map +0 -1
  366. package/dist/hoi4_agent_tools/schemas/focus.d.ts +0 -784
  367. package/dist/hoi4_agent_tools/schemas/focus.d.ts.map +0 -1
  368. package/dist/hoi4_agent_tools/schemas/focus.js.map +0 -1
  369. package/dist/hoi4_agent_tools/schemas/index.d.ts +0 -5
  370. package/dist/hoi4_agent_tools/schemas/index.d.ts.map +0 -1
  371. package/dist/hoi4_agent_tools/schemas/index.js +0 -5
  372. package/dist/hoi4_agent_tools/schemas/index.js.map +0 -1
  373. package/dist/hoi4_agent_tools/schemas/map.d.ts +0 -654
  374. package/dist/hoi4_agent_tools/schemas/map.d.ts.map +0 -1
  375. package/dist/hoi4_agent_tools/schemas/map.js.map +0 -1
  376. package/dist/hoi4_agent_tools/schemas/transaction.d.ts +0 -259
  377. package/dist/hoi4_agent_tools/schemas/transaction.d.ts.map +0 -1
  378. package/dist/hoi4_agent_tools/schemas/transaction.js.map +0 -1
  379. package/dist/hoi4_agent_tools/version.d.ts +0 -6
  380. package/dist/hoi4_agent_tools/version.d.ts.map +0 -1
  381. package/dist/hoi4_agent_tools/version.js.map +0 -1
  382. package/dist/index.d.ts +0 -3
  383. package/dist/index.d.ts.map +0 -1
  384. package/dist/index.js +0 -3
  385. package/dist/index.js.map +0 -1
  386. package/docs/adr/0001-runtime-and-language.md +0 -16
  387. package/docs/adr/0002-lossless-source-model.md +0 -18
  388. package/docs/adr/0003-image-and-font-codecs.md +0 -18
  389. package/docs/adr/0004-focus-layout.md +0 -16
  390. package/docs/adr/0005-offline-rendering.md +0 -18
  391. package/docs/adr/0006-mcp-sdk-and-protocol.md +0 -16
  392. package/docs/adr/0007-storage-and-transactions.md +0 -24
  393. package/docs/adr/0008-test-strategy.md +0 -18
  394. package/docs/adr/0009-packaging-and-registry.md +0 -16
  395. package/docs/adr/0010-unsupported-and-refusal-policy.md +0 -18
  396. package/docs/adr/0011-http-security.md +0 -16
  397. package/docs/adr/0012-autonomous-rewrites.md +0 -55
  398. package/docs/adr/README.md +0 -14
  399. package/docs/agent-integration.md +0 -146
  400. package/docs/architecture.md +0 -76
  401. package/docs/artifacts.md +0 -136
  402. package/docs/compatibility.md +0 -33
  403. package/docs/completion-report.md +0 -122
  404. package/docs/configuration.md +0 -305
  405. package/docs/focus-workflow.md +0 -197
  406. package/docs/gui-workflow.md +0 -125
  407. package/docs/limitations.md +0 -32
  408. package/docs/map-workflow.md +0 -95
  409. package/docs/performance.md +0 -117
  410. package/docs/release.md +0 -222
  411. package/docs/research/mcp-2026-07-10.md +0 -52
  412. package/docs/research/source-ledger.md +0 -68
  413. package/docs/security.md +0 -145
  414. package/docs/self-hosting.md +0 -170
  415. package/docs/testing.md +0 -43
  416. package/docs/third-party-notices.md +0 -11
  417. package/docs/transactions.md +0 -180
  418. package/docs/troubleshooting.md +0 -54
  419. package/schemas/configuration.schema.json +0 -795
  420. package/schemas/continuous-focus-palette.schema.json +0 -325
  421. package/schemas/focus-plan.schema.json +0 -927
  422. package/schemas/focus-planning-sidecar.schema.json +0 -379
  423. package/schemas/gui-animation-source.schema.json +0 -176
  424. package/schemas/gui-helper.schema.json +0 -301
  425. package/schemas/gui-scenario.schema.json +0 -298
  426. package/schemas/map-operation.schema.json +0 -2284
  427. package/schemas/operation-result.schema.json +0 -344
  428. package/schemas/transaction-manifest.schema.json +0 -685
@@ -1,125 +0,0 @@
1
- # Scripted GUI Studio
2
-
3
- Scripted GUI Studio builds an offline source graph across `.gui`, `.gfx`, `common/scripted_guis`, localisation/scripted localisation, sprites/textures, frame animation, fonts, decision entry points, parents/contexts, button effects, triggers, properties, dynamic lists, and AI behavior.
4
-
5
- It does not launch, automate, hook, or capture the game. Output is always labelled an offline representation.
6
-
7
- ## Preview scenarios
8
-
9
- A scenario selects resolution, UI scale, root window, rendered state, global animation sample time, optional time-since-visible, explicit frame overrides, and mock country/state/variables/flags/lists/localisation/scripted-GUI values. `play_on_show = yes` samples `visibleTimeSeconds` (or the global clock when it is omitted); other animations sample `animationTimeSeconds`. Non-looping sprites clamp to the final frame, and looping sprites honor `pause_on_loop`. The exact scenario and source revision are stored with every artifact so another coding agent can reproduce it.
10
-
11
- Required state coverage includes normal, hover, selected, locked, disabled, warning, active, completed, empty/full list, minimum/maximum values, long text, and missing localisation.
12
-
13
- ## Renderer
14
-
15
- The renderer resolves nested parent offsets, positions, sizes, scale, clipping, z-order, sprite dimensions/frame strips, text alignment/wrapping, font metrics/kerning, button/icon states, list rows, visibility, and selected animation frames. Scanned TTF/OTF text is rendered from fontkit outline paths and uses the scanned ascent as its baseline. Scanned BMFont text defaults to the font's native `info size` when the GUI element has no `fontSize`, uses `common lineHeight` and `base`, and composes bounded crops of declared atlas pages with parsed offsets, advances, and kerning. Artifact-owned labels and unavailable workspace glyph data use paths from the pinned redistributable project font, so SVG-to-PNG output never depends on fonts installed on the host. It produces:
16
-
17
- - full and cropped PNG/SVG renders;
18
- - annotated bounds/ID render;
19
- - click-region overlay;
20
- - hierarchy and source-location reports;
21
- - state gallery;
22
- - resolution/UI-scale gallery;
23
- - before/after comparison;
24
- - JSON layout and fidelity reports.
25
-
26
- Generated PNGs are real compositions from parsed synthetic or workspace assets, not placeholder diagrams.
27
-
28
- Standalone comparison artifacts are bound to the exact source graph used for both renders. Their JSON evidence records both complete preview scenarios, both source revisions, both full fidelity reports, and the deterministic bitmap-diff statistics; PNG and JSON manifests repeat bounded fidelity summaries for both scenarios.
29
-
30
- Studio discovery is two phase. `gui_scan` indexes configured `roots.interface`, `roots.gfx`, `roots.scriptedGui`, and `roots.localisation` definitions plus the fixed decision, scripted-localisation, font-definition, and animation-manifest paths. It does not eagerly read every texture in an installed game. Lint and render calls then resolve only the selected window's transitive sprites, static fallbacks, fonts, BMFont pages, and animation source frames by safe exact path or unique basename.
31
-
32
- The complete source graph is never truncated to fit artifact storage. If its canonical JSON exceeds
33
- the configured per-object ceiling, `gui_scan` and render storage return a `*.chunks.json` logical
34
- artifact index. Its ordered content-addressed resource links reconstruct the exact original JSON
35
- bytes and hash. The index, chunks, and their provenance manifests are admitted and rolled back as
36
- one bounded artifact batch; all physical objects still consume the configured byte and entry
37
- budgets. See [Artifact resources](artifacts.md) for the index format and reconstruction rule.
38
-
39
- If an active definition source exceeds a fixed parser byte, line, token, entry, or nesting limit, broad GUI discovery skips that whole source before content sniffing or graph traversal. `gui_scan` returns `GUI_SCANNED_PARTIAL`, `complete: false`, the total skipped-source count, and a bounded source sample in both structured output and the graph artifact. Missing references become partial-inventory warnings only when the skipped source family could define that exact target kind; an unrelated capped source does not weaken validation. A lint/render target that cannot be found because a GUI definition source was skipped, and a patch aimed directly at a capped source, refuse with `GUI_TARGET_SOURCE_SKIPPED_LIMIT`.
40
-
41
- Localisation is selected with the same bounded approach. Discovery indexes `l_english`; lint, render, state, resolution, and comparison calls derive the complete language set from their preview scenarios and scan those exact language directories. A French scenario therefore resolves `l_french` source without retaining every unrelated installed translation.
42
-
43
- ## Fidelity report
44
-
45
- Every render groups fields into:
46
-
47
- - `modelled`: represented from source values;
48
- - `approximated`: deterministic but not asserted engine-identical;
49
- - `ignored`: known nonvisual or intentionally excluded fields;
50
- - `missing`: referenced asset/font/localisation is unavailable;
51
- - `unsupported`: parsed construct has no renderer implementation;
52
- - `unresolved`: dynamic value is absent from the scenario.
53
-
54
- The report includes scenario, source revision, resolution, UI scale, state, font/asset hashes, and renderer version. `font_glyph_rendering` is modelled only when the rendered line comes from scanned TTF/OTF outlines or BMFont atlas glyphs with a declared baseline; a project-font or missing-baseline substitution is approximated and missing code points are separately reported. Every parsed element attribute is classified: attributes actually consulted by the scene model are `modelled`, while fields such as tooltips, sounds, shortcuts, engine-only window animation, and `fixedsize` are explicitly `ignored` until their behavior is represented. A missing or unsupported field is never given an invented appearance.
55
-
56
- The primary frame of `textSpriteType`, `corneredTileSpriteType`, GFX `progressbarType`, and `maskedShieldType` can be shown for source review, but their engine text generation, tiling, progress composition, and masking semantics are not implemented. `textureFile2` and `effectFile` are retained in the source graph but are not composited or executed. Each affected element therefore receives explicit unsupported fields, an approximated `sprite_frame`, and a `GUI_SPRITE_RENDER_PARTIAL` warning; it is never labelled as a fully modelled appearance.
57
-
58
- ## Bounded resource admission
59
-
60
- Studio discovery, graph construction, validation, and rendering use fixed process-safety ceilings. A render admits no more than 512 distinct raster/native-image operations, including selected GUI assets, galleries, focus icons, render plans, and bitmap comparisons. Rendered text is limited to 16,384 characters per element, 262,144 aggregate characters per scene, and 32,768 layout operations while preserving BMFont kerning across wrapping decisions.
61
-
62
- BMFont text inputs stop at 2,097,152 bytes, 50,000 records, 32 fields per record, 256 pages, 32,768 characters, and 32,768 kerning pairs; binary font inputs stop at 8,388,608 bytes. Missing-glyph evidence retains 64 samples. Source-graph admission fails before retaining more than 50,000 GUI elements, 500,000 total nodes, or 1,000,000 edges; expanded scenes stop at 10,000 elements. Validation stops at 2,000 diagnostics, 2,000,000 pair comparisons, or 2,000,000 ancestor hops. Exceeding a bound returns an explicit blocker instead of a partial render, unbounded validation pass, or invented approximation.
63
-
64
- ## Source-preserving plans
65
-
66
- Existing `.gui` files accept only hash-bound patches at parser-proven ranges. A patch may replace one known scalar assignment or scalar value, delete one known scalar assignment, or insert complete parsed entries immediately before a block close. Whole-file ranges, block rewrites, unknown-field rewrites, malformed insertions, stale text, and ambiguous ranges are refused. New files may be supplied in full only when no mod, dependency, or game source already owns the path. Every proposal is reparsed and rendered before it can be journaled or applied.
67
-
68
- With `writePolicy: "autonomous"`, call `hoi4.gui_rewrite` in `source`, `patches`, or `helpers` mode. The one call validates the proposal, persists exact recovery bytes, applies under the workspace lock, rebuilds the index, and post-validates. A successful result reports `execution: "applied"`; a blocked proposal reports `execution: "blocked"` and changes no source; a valid no-change request reports `execution: "unchanged"`. Any application or post-validation failure restores the original bytes automatically. No transaction diff/apply/rollback tools are exposed in autonomous mode.
69
-
70
- The optional `"transactions"` compatibility policy exposes `hoi4.gui_plan_changes` and the separate transaction review/apply tools instead. Both policies use the same source-preserving compiler, validation, journal, and recovery implementation.
71
-
72
- ## Declarative helper compilation
73
-
74
- `hoi4.gui_rewrite` in `helpers` mode compiles a strict, build-time helper document into explicit `.gui` source and runs it through the normal autonomous rewrite path. In compatibility mode, use `hoi4.gui_plan_changes` with the same input. The generated mod has no runtime dependency on `hoi4-agent-tools` or its server.
75
-
76
- A document has one `root` and may declare reusable `templates`. A template instance uses `kind: "template"` plus `templateId`; its instance ID becomes the deterministic prefix for every expanded ID and name. For example, instance `left_status` of a template whose root is named `status_card` produces `left_status__status_card`. Instance fields may override the template root, but templates do not provide parameters, slots, or appended children. Missing references, duplicate template IDs, duplicate node IDs, reference cycles, duplicate compiled GUI names, and source or expanded budget overflow refuse compilation. Expanded identifiers stop at 1,024 UTF-8 bytes; conservative source-construction work stops at 16 MiB, and final source stops at the 8 MiB Clausewitz parser ceiling before a transaction is planned.
77
-
78
- The structured helpers compile as follows:
79
-
80
- | Helper | Explicit source behavior |
81
- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
82
- | `anchor` | A child-bearing `containerWindowType`; `orientation` selects the reference point in the parent or screen, while `origo` selects the corresponding point on the container itself. Both default to `upper_left`. |
83
- | `row` | Children flow horizontally with margins and `gap`. |
84
- | `column` | Children flow vertically with margins and `gap`. |
85
- | `stack` | Children overlap at their explicit offsets inside the padded container. |
86
- | `grid` | Children occupy fixed columns; each following row begins after the tallest item in the preceding row. |
87
- | `card` | A stacked container with an optional named sprite background. |
88
- | `tabs` | Tab controls flow horizontally; button appearance is supplied by explicit `buttonType` children and state selection. |
89
- | `scroll-list` | A clipped, background-backed scrolling container with a nested `gridBoxType` and one independent, top-level entry container. |
90
- | `target-row` | Target controls flow horizontally as a distinct composition surface. |
91
- | `meter` | A container with an icon whose selected frame is derived deterministically from `minValue`, `maxValue`, `value`, and `frames`. |
92
- | `status-panel` | Status items flow vertically. |
93
- | `modal` | A centered `windowType` with centered `origo`, stacked children, and an optional named sprite background. |
94
- | `overlay` | Children overlap and the container defaults to `clipping = no`. |
95
-
96
- `scroll-list` requires positive dimensions, a background sprite, an axis-compatible scrollbar definition, and exactly one structured entry-container child. A helper named `orders` emits `orders__grid`, `orders__entry`, and `orders__background`. `flow: "vertical"` emits a vertical scrollbar and one horizontal slot; `flow: "horizontal"` emits a horizontal scrollbar and one vertical slot. The compiler cannot inspect the referenced scrollbar definition in this standalone build-time document, so the caller must supply a definition whose `horizontal` setting matches the selected flow. The matching `common/scripted_guis` `dynamic_lists` wiring must reference the generated grid and entry names separately; helper compilation does not invent an array, scope, or scripted-GUI binding.
97
-
98
- `meter` is a static, reviewable frame selection, not an engine progress widget or runtime variable binding. `progressbarType` belongs to GFX sprite definitions and is never emitted as a `.gui` element. The declared range is validated, then `value` selects a frame from the declared multi-frame icon sprite. Runtime changes still require explicit scripted-GUI properties or raw source authored for that mechanic.
99
-
100
- Structured leaf output is type-aware. `iconType` accepts sprite/frame fields, `instantTextBoxType` accepts text/font plus `maxWidth` and `maxHeight`, and `buttonType` accepts sprite/frame plus `buttonText` and `buttonFont`. Leaf elements never receive a fabricated `size` block and cannot contain child GUI elements. Hardcoded or legacy forms such as `checkboxType`, `guiButtonType`, and `textBoxType` are refused by the structured helper; use `raw` only when an exact engine precedent justifies them.
101
-
102
- Selecting a custom UI `state` requires a matching `stateVariants` entry. Its frame, sprite, text, font, and allowlisted scalar attributes replace the base values in the emitted source; no preview-state comment or inferred frame is written. The engine-managed `normal`, `hover`, `pressed`, and `disabled` states may be named on `buttonType` without a custom variant, but the compiler does not fabricate their frame mapping. Attribute keys must be both safe identifiers and documented scalar fields for the selected container, icon, text, or button type; structured fields, misspellings, and type-incompatible fields cannot be smuggled through `attributes`. `raw` remains the explicit escape hatch for complete advanced Clausewitz GUI source and is counted in rewrite evidence.
103
-
104
- ## Validation
105
-
106
- The studio checks visible overlap, clipping, overflow, spacing, invalid size, child/clip escape, visual/click mismatch, invisible blockers, conflicting click regions, missing assets/fonts/localisation, frame/sheet/fallback errors, parent/context errors, z-order risks, cut scroll rows, resolution drift, conflicting tab states, button trigger/effect gaps, cost disagreements, AI equivalence, and renderer fidelity blockers.
107
-
108
- Actual font metrics drive text checks; OCR is not used. GUI costs are derived from standard `£icon amount` tokens in the button's referenced localisation and compared with direct negative scripted-GUI resource effects such as `add_political_power = -12`. Diagnostics link the localisation, GUI element, and scripted effect source locations. Scenario `guiCosts`/`scriptCosts` remain optional preview assertions but are not the source-validation path.
109
-
110
- ## Animation source manifests
111
-
112
- A project-owned animation may provide one manifest at `hoi4_agent/animation_sources/<animation>/manifest.json`, validated by `schemas/gui-animation-source.schema.json`. The manifest identifies the `frameAnimatedSpriteType`, final sheet path and hash, cell dimensions, independently authored source-frame paths/hashes/anchors, animation settings, and a source-derived static fallback.
113
-
114
- For a selected window, the public Studio path verifies:
115
-
116
- - manifest and sprite frame counts and animation settings;
117
- - source, sheet, and fallback SHA-256 hashes;
118
- - supported and identical source-frame dimensions;
119
- - distinct source bytes and distinct decoded artwork;
120
- - stable in-frame anchors;
121
- - exact decoded pixels from each source frame against its sheet cell;
122
- - sheet dimensions and declared sprite size;
123
- - static-fallback sprite/path/hash/dimensions and exact equality to its declared source frame.
124
-
125
- Without a manifest, the composed sheet remains renderable but validation emits `GUI_ANIMATION_SOURCE_PROVENANCE_UNAVAILABLE`; it is not accepted as proof of independent frames. Rendering checks cancellation between bounded element chunks and variants without changing deterministic output.
@@ -1,32 +0,0 @@
1
- # Known limitations and refusal cases
2
-
3
- These are precise safety boundaries, not silent fallbacks.
4
-
5
- - Arbitrary dynamic trigger/effect evaluation is outside an offline renderer. Preview scenarios must supply dynamic values; unresolved values appear in fidelity reports.
6
- - Workspace scans default to 20,000 enumerated files, 134,217,728 aggregate content bytes, and 67,108,864 bytes for one file. Operators may lower these values per request but cannot raise them above server policy. Exceeding any ceiling refuses the complete scan with `SCAN_FILE_LIMIT` or `SCAN_BYTE_LIMIT`; a partial index is not returned. The configuration additionally requires aggregate scan bytes multiplied by HTTP request concurrency to remain at or below 512 MiB.
7
- - Stdio uses strictly decoded UTF-8 newline-delimited JSON-RPC with a fixed 16,777,216-byte frame ceiling, excluding the line-feed delimiter. A malformed UTF-8 frame is refused without replacement decoding; an oversized frame is refused as soon as it crosses the ceiling, even without a newline or end-of-input. Either condition closes the local transport without emitting protocol output. Use workspace files and MCP resources instead of oversized inline payloads.
8
- - Clausewitz/localisation parsing is bounded to 8,388,608 source bytes and 250,000 lines per file; Clausewitz tokenization is bounded to 250,000 tokens, block nesting to 256 levels, and localisation parsing to 100,000 entries. Broad project and GUI inventories skip the entire active source when one of these bounds is crossed, return `complete: false` with a bounded skipped-source list, and do not walk or publish symbols from the partial parse. An unresolved reference is downgraded only when the skipped source's path family could define that reference kind. Targeted reads and writes still refuse the affected source with an explicit blocker; content beyond a limit is never treated as a complete parse.
9
- - The aggregate shared index is bounded to 500,000 symbol records and 500,000 reference records. Reaching either ceiling returns an explicitly incomplete inventory. A symbol-ceiling drop records the affected symbol kind so unresolved definitions are reported as partial only where dropped symbols could contain them; the reference ceiling reports incomplete outbound-reference coverage without implying that a missing definition might exist. The server never presents a capped inventory as complete.
10
- - Source diagnostics are capped at 100 per file. When additional findings exist, 99 findings are retained and the final slot becomes `SOURCE_DIAGNOSTICS_TRUNCATED`, a blocker rather than a silent truncation.
11
- - Renderer coverage is field-by-field. Parsed engine-only GUI properties are retained raw and reported as ignored or unsupported; source changes crossing an unknown field or parsed block are blocked rather than normalized away. Special `textSpriteType`, `corneredTileSpriteType`, GFX `progressbarType`, and `maskedShieldType` semantics, secondary textures, and effect files currently produce only a partial primary-texture appearance with explicit fidelity items and a warning.
12
- - Offline GUI output is not guaranteed pixel-identical to the game engine and is never called a screenshot. Modelled geometry and asset composition are deterministic for the recorded render profile.
13
- - Offline image work uses fixed process-safety ceilings: 16,384 pixels per axis, 50,331,648 pixels per generated artifact, 16,777,216 pixels per decoded texture, 33,554,432 bytes per encoded image input, and 67,108,864 charged pixel units across one request. Oversized source assets, derived canvases, scale factors, comparison planes, or variant matrices are refused with `RENDER_*_BLOCKED`; these ceilings are not configurable and are checked before pixel allocation where dimensions are known. Workspace SVG raster inputs are rejected before decoding because nested SVG resources are not governed by the outer pixel limit; use PNG source frames/assets instead. Deterministic SVG remains a generated review-artifact format.
14
- - Declarative GUI helpers stop at 128 levels and 10,000 nodes. GUI scenarios admit at most 256 list keys, 10,000 aggregate rows, 100,000 aggregate keys, and 1,000,000 string characters; expanded scenes stop at 128 levels, 10,000 elements, or 100,000 construction-work units. One render may perform at most 512 distinct raster/native-image operations. Rendered text is limited to 16,384 characters per element, 262,144 aggregate characters per scene, and 32,768 text-layout operations. BMFont text sources are limited to 2,097,152 bytes, 50,000 records, 32 fields per record, 256 pages, 32,768 characters, and 32,768 kerning pairs; binary font inputs stop at 8,388,608 bytes, and missing-glyph evidence retains at most 64 samples. Focus and GUI graph validation uses fixed node, edge, depth, and work ceilings: the GUI source graph stops at 50,000 GUI elements, 500,000 total nodes, or 1,000,000 edges; validation stops at 2,000,000 pair comparisons or ancestor hops; focus layout stops at 500,000 work units; and focus lint stops at 2,000,000 transitive/route-analysis units. Focus lint/layout, GUI source-graph, and GUI validation diagnostics retain at most 2,000 entries, including an explicit truncation blocker when findings overflow.
15
- - Declarative GUI helper documents admit at most 1,024 one-root templates and 64 state variants per node; both source and expanded trees remain subject to the 128-level and 10,000-node ceilings. Grid columns stop at 10,000, expanded identifiers at 1,024 UTF-8 bytes, conservative source-construction work at 16 MiB, and final generated source at 8 MiB. Templates have root overrides but no parameters, slots, or appended children. Scroll-list helpers emit deterministic grid and entry-container handoff names but do not create `dynamic_lists` scripted-GUI bindings or verify an external scrollbar definition's axis. Meter helpers choose one static icon frame from a validated range and do not provide runtime progress behavior. Advanced, hardcoded, legacy, or non-allowlisted scalar GUI fields require the counted raw escape hatch.
16
- - Focus design diagnostics such as weak branches, payoff quality, avoidable crossings, or generic rewards are deterministic heuristics and do not rewrite gameplay.
17
- - Plan/script drift requires an explicit authoritative-source choice.
18
- - Autonomous mode deliberately exposes only `hoi4.focus_rewrite`, `hoi4.gui_rewrite`, and `hoi4.map_rewrite`; it does not expose transaction diff, status, apply, or explicit rollback tools. Failed application and post-validation restore automatically. An intentional later reversal requires Git or another explicit domain rewrite. The tools advertise `destructiveHint: true`, but MCP does not mandate per-tool confirmation and the server cannot override its host's approval policy.
19
- - Map geometry requires an exact polygon with explicit `fillRule: "even-odd"`, a canonical hash-bound raster-mask manifest, or absolute pixel selection. Polygon vertices are integer raster-boundary coordinates: `0` through raster width/height are valid, greater coordinates are refused before work allocation, and polygons are never clipped. Inclusion is determined at pixel centers. Descriptive geography alone cannot apply.
20
- - Province hole detection is a deterministic four-connected digital-topology review. It warns on enclosed components but does not declare every enclave invalid; provinces touching the horizontally wrapping map seam are excluded from the planar hole calculation.
21
- - Map text tables are limited to 16,777,216 bytes and 500,000 records so the bounded parser admits the current vanilla unit-position table. Province rasters are limited to the documented 13,238,272-pixel engine area, exact raster masks to 20,000,000 cells, and polygon rasterization to 50,000,000 cell-point comparisons. Every exact selection/recolor operation is additionally limited to 1,000,000 pixels, including explicit pixels, selected mask cells, rasterized polygons, normal-adjacency transfers, whole-province color updates, and merges. Known counts are refused before dangerous decoding/scanning/materialization with `MAP_SELECTED_PIXEL_BUDGET_BLOCKED`. Selected pixels use four-byte numeric offsets, so the primary operation-owned offset buffer remains below 4 MiB (4,000,000 bytes); coordinate-string keys and per-pixel coordinate/color object arrays are not materialized. Map diagnostics are capped at 2,000; overflow retains 1,999 findings and replaces the last slot with a blocking `MAP_DIAGNOSTICS_TRUNCATED`. Undefined bitmap colors retain at most 256 individual samples and add a blocker when more distinct colors exist.
22
- - State/province redistribution and new-state English localisation policy must be explicit. State move/split/merge policies name port, supply-node, railway, and position behavior; province splits name retention for every connected reference family. Missing or ambiguous policy blocks the plan; localisation writes require a safe BOM source or an explicit in-root creation target.
23
- - Bitmap-derived normal adjacency changes require exact source-to-target pixel transfers whose requested topological result can be verified. The service does not infer a corridor or boundary; special adjacency CSV rows remain a separate operation family.
24
- - Province land/sea/lake migration only supports the documented complete dependency policy. Agent Nudger will not infer a state, reconnect a railway after removing a province, move a port, or repair incompatible positions/adjacencies.
25
- - State `capital` is derived from exact victory points for inspection; Agent Nudger does not write a generic state `capital` assignment.
26
- - Map ID allocation obeys scanned format/contiguity evidence from every root's own `default.map`-selected definition database; it refuses an allocation when the current source family cannot safely represent a gap or append. A present selector with any syntax or parser-limit diagnostic blocks the whole map model, including when it belongs to a lower game/dependency root, because falling back could hide an ID or color collision.
27
- - Province merge/removal supports arbitrary compatible source IDs and compacts every connected province reference; it refuses renumbering only when the active definition table is already gapped or ambiguous by ID/color, or when source and target type/state/region membership is incompatible.
28
- - Recoverable logical multi-file atomicity cannot prevent an unrelated process from briefly reading a replacement sequence. Success follows the server's post-write validation and final hash check, and persisted before-bytes support automatic failure restoration (plus explicit rollback in reviewed compatibility mode). This is not a race-proof filesystem transaction: hostile concurrent symlink, junction, mount, directory, or file replacement by another operating-system principal is outside the application security boundary. Git supplies project history but is not required for the internal recovery guarantee.
29
- - Artifact retention defaults to 536,870,912 bytes, 5,000 manifests, and 134,217,728 bytes per content object; each provenance manifest is separately capped at 1 MiB before parsing. Broad project, focus, GUI, and map manifests retain a bounded source-hash sample plus a digest commitment to the complete inventory, while exact structured artifact content retains the complete hashes. Opt-in oversized logical evidence is preserved as bounded binary chunks plus a one-read JSON index, not as a larger content object: every chunk/index manifest counts against the same quotas, an index above 1 MiB is refused, and one logical preparation batch has a fixed 536,870,912-byte in-memory ceiling (or the lower configured aggregate ceiling). The whole logical batch is admitted before copying or hashing; preflight and hashing yield to cancellation. Internal rewrite/transaction journals default to 536,870,912 bytes and 128 entries, with a fixed 16 MiB ceiling per authenticated manifest; only expired authenticated planned/rolled-back journals, authenticated safe cache-without-head remnants, head-without-cache remnants, or old manifest-less directories are pruned, while other terminal/interrupted or unauthenticated states remain fail-closed and count against quota. See [artifacts](artifacts.md) and [autonomous rewrites and transactions](transactions.md).
30
- - Installed-game and external-workspace font files are read locally and are never published as raw MCP resources or redistributed by this package. Their glyph outlines or bounded BMFont atlas crops may appear inside an authorized generated review artifact. Portable fixtures and tool-owned artifact labels use the pinned Roboto package under OFL-1.1; unavailable workspace glyph data is visibly classified as an approximation rather than delegated to a host font.
31
- - Local external integration depends on environment-provided paths and is not a substitute for portable CI.
32
- - The server never launches, automates, controls, or captures Hearts of Iron IV. Offline previews are not game screenshots and do not prove in-engine rendering or gameplay behavior.
@@ -1,95 +0,0 @@
1
- # Agent Nudger map workflow
2
-
3
- Agent Nudger is a headless declarative map rewrite service for coding agents. HTML/PNG/JSON maps are inspection evidence, not a manual editor.
4
-
5
- ## Indexed sources
6
-
7
- The shared scan connects province bitmap and definitions, states, strategic regions, terrain/continent values, adjacency CSV, supply nodes, railways, victory points, resources/buildings, ownership/control/cores/claims, coast/ports, placement files, localisation, and dependency overrides. It honors each workspace's configured `roots.map`, `roots.states`, and `roots.localisation` directories. Files named by the active `default.map` (including adjacency, supply-node, railway, province, definition, and position files) remain authoritative for active reads and additive writes. Allocation and collision evidence additionally resolves every scanned root's own `default.map`-selected definition filename. A partial root without its own selector inherits the active definition filename for evidence only. If any selector-owning root has a malformed, parser-limited, or otherwise diagnostic-bearing `default.map`, map scan and indexing stop with `MAP_DEFAULT_MAP_SELECTOR_BLOCKED`; the service never substitutes `definition.csv`, `provinces.bmp`, or an inherited selector for an untrustworthy file.
8
-
9
- ## Geometry input
10
-
11
- Province geometry rewrite requires one exact representation:
12
-
13
- - selected existing province IDs;
14
- - polygon with integer raster-boundary coordinates and explicit `fillRule: "even-odd"`;
15
- - raster mask manifest with dimensions, origin, exact selected-pixel count, SHA-256, and canonical Base64 data;
16
- - explicit absolute pixel region (`kind: pixels`).
17
-
18
- Natural-language descriptions can guide a coding agent, but are not accepted as rewrite geometry.
19
-
20
- Polygon vertices describe raster cell boundaries, not pixel indices. For a raster of `width` by `height`, every vertex must use an integer `x` from `0` through `width` and an integer `y` from `0` through `height`; the right and bottom boundary values `width` and `height` are valid. A greater coordinate is rejected with `MAP_GEOMETRY_OUT_OF_BOUNDS` before bounding-box or raster-work allocation, and polygon geometry is never silently clipped. Rasterization samples each candidate pixel at its center, `(x + 0.5, y + 0.5)`, using the required even-odd fill rule. Every selected center must still belong to the declared source province.
21
-
22
- Raster-mask `data` is one byte per cell in row-major order. Every byte is exactly `0` or `1`; the SHA-256 is computed over those decoded bytes. The declared rectangle must fit the active raster, its byte length must equal `width * height`, and both the selected count and hash must match before every selected absolute pixel is checked against the source province. A mask may describe at most 20,000,000 cells, while any one split, mask, polygon, normal-adjacency transfer set, whole-province color update, or merge may select/recolor at most 1,000,000 pixels. Polygon admission also stops at 50,000,000 cell-point comparisons. Counts known from the manifest or indexed province geometry are checked before decoding, raster scanning, or selection-buffer allocation; an over-limit operation returns `MAP_SELECTED_PIXEL_BUDGET_BLOCKED` without proposing changes.
23
-
24
- Selected geometry is represented internally as deterministic row-major numeric offsets rather than coordinate strings or `{x, y, color}` object arrays. The fixed 1,000,000-pixel ceiling keeps the primary four-byte offset buffer below 4 MiB (4,000,000 bytes), and uniform recolors copy the BMP once and write directly through those offsets. Explicit-coordinate duplicates and normal-adjacency transfer duplicates are detected by numeric offset. Source BMP operations use exact colors without antialiasing, interpolation, resizing, alpha conversion, or palette quantization. Untouched bytes and pixels remain identical.
25
-
26
- ## State payload policies
27
-
28
- Split/merge/move operations do not guess manpower, resources, buildings, victory points, ownership, control, cores, claims, supply, or railway behavior. Each applicable payload must select an explicit policy:
29
-
30
- - remain with original state;
31
- - move with a named province;
32
- - deterministic proportional distribution;
33
- - exact manifest values;
34
- - block until resolved.
35
-
36
- Proportional rounding is deterministic and checked for conservation. The rewrite remains blocked while any required policy is unresolved.
37
-
38
- State move, split, and merge manifests also declare `ports`, `supplyNodes`, `railways`, and `positions` as `follow-province`. Those records are keyed by a selected province or its state association, so their source bytes remain unchanged except for the already modelled state-ID field on applicable position rows. The explicit literals make that behavior reviewable and prevent a partial distribution object from silently choosing it.
39
-
40
- New states require an explicit name localisation key and a strict `localisation` policy. `existing` requires exactly one safe active `l_english` entry. `upsert` updates only the quoted value of that exact entry, appends to an explicitly targeted existing file, or creates an explicitly targeted file in a configured localisation root. Created and edited files are UTF-8 with BOM. Comments, key versions, spacing, line endings, ordering, unknown lines, and unrelated entries are preserved. Missing policy/target/key, duplicate active keys, unsafe paths, target mismatch, non-BOM encoding, or malformed target source blocks the whole operation before it contributes changes.
41
-
42
- `StateRecord.capital` is inspection-only derived data: select the province with the highest exact victory-point value, then the lowest province ID on a tie. Current state source has no generic `capital = <province>` field. Agent Nudger never emits or patches that assignment. `update_state.changes.capital` is therefore an assertion, not a write: it is accepted only beside an exact `victoryPoints` payload whose derived result matches the assertion (including `null` for no victory points). State moves, splits, and merges derive the result from their explicit VP policy.
43
-
44
- ## Province merge and removal
45
-
46
- `merge_provinces` and `remove_province` accept arbitrary compatible source IDs; removed IDs do not need to be the highest rows in `definition.csv`. Surviving definitions are compacted deterministically to contiguous IDs from zero in old-ID order. Removed source IDs map to the target's compacted ID, including when the target itself moves downward.
47
-
48
- The same total old-to-new map is applied as one recoverable operation to state membership, victory points, province buildings, strategic regions, special-adjacency endpoints and through-provinces, supply nodes, railways, unit positions, and building-position sea references. Source pixels are repainted with the target color; other province colors and pixels remain unchanged. Reference collisions created by the merge are resolved by the declared sum/deduplicate policy. Definition row order, comments and extra fields, text-file comments, line endings, and source encoding are retained by targeted rewrites. A failed application or post-validation restores every affected file byte-for-byte.
49
-
50
- Compaction requires an active definition table that is already contiguous from zero and unambiguous by ID and color. The merge also requires every source and target to share province type plus exact state and strategic-region membership; these are refusal cases rather than guessed redistribution.
51
-
52
- Province split/create manifests explicitly retain existing victory points, province buildings, ports, supply nodes, railways, special adjacencies, positions, and entity locators on the source province while the selected pixels and new ID join the declared state and strategic region. To move connected data to the new province, place the corresponding exact remove/add or update operations after the split in the same ordered rewrite. Omitting any retention field blocks the split before geometry changes are proposed.
53
-
54
- ## Province type migration
55
-
56
- `update_province_definition` can migrate among `land`, `sea`, and `lake`. A real type change requires the complete strict `distribution` object; missing, partial, unknown, or transition-incompatible policies block the operation before it contributes any file change.
57
-
58
- The policy explicitly covers:
59
-
60
- - exact state membership (`retain`, `remove` with the indexed state ID, or `assign` with a target state ID);
61
- - retention of state-level values in their current states and strategic-region membership;
62
- - victory points and non-port province buildings (`retain-if-valid` or `remove`);
63
- - naval-base buildings plus port placements/references (`retain-if-valid` or `remove`);
64
- - supply nodes (`retain-if-valid` or `remove`);
65
- - railways (`retain-if-valid` or remove every containing route; routes are never silently spliced);
66
- - building and unit positions (`retain-if-valid` or `remove`) and entity locators (`retain-at-coordinate`, because type migration does not alter geometry);
67
- - special adjacency endpoint/through references (`retain-if-valid` or `remove-referencing`).
68
-
69
- Land-to-water requires removal from the exact indexed state and cannot leave that state without land. Water-to-land requires an explicit existing target state in the same strategic region. Sea targets require `ocean` terrain and continent `0`; lake targets require `lakes` and continent `0`; land targets require a non-water terrain and nonzero continent. Coastal fields and neighboring coastal changes remain exact manifest inputs and are verified by final map validation. Dependency removals and the definition edit share one hash-bound journal, so success or automatic failure restoration covers every affected state, definition, network, position, and adjacency file together.
70
-
71
- When a dependency should move rather than disappear, place the corresponding exact `update_state`, position, supply, railway, or adjacency operation after the type migration in the same ordered manifest. The migration policy removes or retains the old record explicitly; the later operation supplies the new target explicitly.
72
-
73
- ## Normal and special adjacency
74
-
75
- Special adjacency rows remain declarative `add_adjacency` and `remove_adjacency` operations against the active `default.map` adjacency CSV. Normal topological adjacency is derived only from four-neighbor province bitmap geometry (including horizontal map wrap) and uses separate `add_normal_adjacency` and `remove_normal_adjacency` operations.
76
-
77
- Every normal-adjacency operation carries unique exact pixel transfers with a coordinate, the province currently owning that pixel, and the destination province. Both requested endpoints and all transfer provinces must exist, every source must match the active raster, and every transfer must involve at least one requested endpoint. Agent Nudger repaints only those 24-bit pixels, rebuilds topology, and restores the operation unless the requested pair is present after an add or absent after a remove. Related coastal-definition changes remain explicit ordered operations in the same rewrite.
78
-
79
- ## Allocation
80
-
81
- ID/color allocation scans current game, dependencies, and mod sources first, including the definition table selected by each root's own `default.map` even when its filename differs from the active table. It records per-file/root maxima, used ranges, active definition contiguity, collisions, reserved values, selected value/color, and source revision. Explicit values are checked against the same evidence. A lower-root ID/color collision is returned as a named dependency conflict on the manifest operation that requested it. The allocator never assumes the numerically next value is safe.
82
-
83
- ## Autonomous rewrite
84
-
85
- With `writePolicy: "autonomous"`, submit the complete ordered operation manifest once to `hoi4.map_rewrite`. The tool scans dependencies, resolves exact geometry and policies, renders baseline/proposed/diff evidence, validates, journals exact before-bytes, applies all affected text and binary files under the workspace lock, rescans, and post-validates. `execution: "applied"` means the final hashes and validation passed. A blocked proposal reports `execution: "blocked"` and changes nothing; a valid no-change request reports `execution: "unchanged"`; a failure after replacement begins restores every affected file automatically.
86
-
87
- No transaction tools are registered in autonomous mode. The optional `"transactions"` compatibility policy exposes `hoi4.map_plan` followed by the separate diff/apply/status/rollback tools, using the same internal journal and recovery engine.
88
-
89
- ## Artifacts and validation
90
-
91
- Map base layers cover province, state, strategic region, terrain, continent, owner, controller, cores, claims, and coast. Overlays cover coastlines, ports, victory points, resources, state buildings, province buildings, supply nodes, railways, special adjacencies, building positions, unit positions, and weather positions. Resource/building data is present in canonical JSON as exact sorted state/province maps as well as deterministic PNG markers; HTML embeds the same JSON and PNG with pan/zoom controls. Render loops honor cancellation signals.
92
-
93
- Every map preflight stores three content-addressed PNG/JSON/HTML triplets: baseline (`map-before.*`), proposed (`map-proposed.*`), and changed-pixel/semantic diff (`map-diff.*`). Their links and content hashes are included in the internal plan hash. Semantic diff JSON includes definitions, state/region membership, full state values (manpower, category, resources, owner/controller, cores/claims, VPs, state/province buildings, and derived capital), ports, building/unit/weather positions, entity locators, supply, railways, exact special-adjacency records, and exact bitmap-derived normal-adjacency pairs.
94
-
95
- Validation detects duplicate IDs/colors, bitmap-definition mismatches, invalid references, unassigned/multi-state land, invalid derived capitals/VPs/ports/regions/adjacency/supply/rail/placements, removed references, coast inconsistencies, duplicate state IDs, missing localisation, ownership/control conflicts, lost payload, changes outside declared bounds, and dependency conflicts. Geometry review includes disconnected components, one-pixel corridors, and enclosed province holes. Hole detection uses one bounded digital-topology pass and reports `MAP_PROVINCE_HOLE_REVIEW` as a warning because intentional enclaves can be valid; provinces crossing the horizontally wrapping seam are excluded from planar hole classification. Baseline comparisons diagnose dimensions, file/DIB header, row orientation, pixel offset, bit depth, and palette changes separately. Sea and legitimate lake/island cases are not misclassified as missing state membership.
@@ -1,117 +0,0 @@
1
- # Performance benchmark
2
-
3
- Performance is recorded by an explicit developer command, not by a required CI timing assertion:
4
-
5
- ```bash
6
- npm ci
7
- npm run benchmark
8
- ```
9
-
10
- The command prints a structured JSON report to stdout and exits nonzero only for correctness failures such as a fixture below its required size, a changed deterministic output, or unsafe cache invalidation. It has no elapsed-time or memory pass threshold. Timing and memory naturally vary by host, runtime, system load, and native codec build.
11
-
12
- ## Workload and methodology
13
-
14
- The benchmark reads only checked-in, project-owned synthetic fixtures:
15
-
16
- - `fixtures/focus`: 255 focuses in ten route families, scanned and indexed through `CoreEngine`, then laid out, linted, rendered, and stored through `FocusWorkbench`;
17
- - `fixtures/gui`: 158 source elements and 203 visible scene elements, rendered through `ScriptedGuiStudio` as fourteen state scenes, three resolution/UI-scale scenes, five primary variants, comparison evidence, and 24 stored artifacts;
18
- - `fixtures/map`: the complete 256×256 map fixture across game, dependency, and mod fixture roots, scanned and indexed through `AgentNudger`, then rendered in all ten current base layers (including continent) with all twelve current overlays enabled;
19
- - a temporary copy of the focus workspace for metadata/content-hash cache checks.
20
-
21
- The 255-focus fixture's 13,152×3,600 raster (47,347,200 pixels) is intentionally below the fixed 48-Mi-pixel per-artifact ceiling. The vanilla 5,632×2,048 map is also below the ceiling at scale 1, and its diff/before/proposed output trio charges 34,603,008 of the 64-Mi-pixel aggregate request budget. Larger scale or variant combinations are refused before allocation rather than included in benchmark timing.
22
-
23
- Each workload runs twice in one process. **Cold** means the first invocation using a fresh service and empty temporary artifact/cache roots. **Warm** means the immediate repeat in the same Node process. The script does not evict the operating system's file cache, so “cold” is an application-level cold run, not a physical-disk cold run. With `--expose-gc`, garbage collection is requested before each measured pass.
24
-
25
- Elapsed values use the monotonic Node performance clock. Memory is the process endpoint measurement from `process.memoryUsage()`, not a sampled peak. RSS includes native allocations from Sharp/libvips; because suites run sequentially, native allocator retention can affect later baselines and deltas. One cold and one warm pass keep the command bounded; rerun it several times externally when investigating variance.
26
-
27
- The GUI total deliberately includes an explicit source scan followed by `renderAndStore`, which performs its own scan as part of the public workflow. The map render phase operates on the fully scanned index and renders all base layers without artifact-store I/O. Output fingerprints must match between cold and warm passes.
28
-
29
- ## Recorded result
30
-
31
- Recorded at `2026-07-10T22:22:50.905Z` with this exact command from the repository root:
32
-
33
- ```bash
34
- npm run benchmark
35
- ```
36
-
37
- Runtime and platform:
38
-
39
- - Windows (`win32`) release `10.0.26200`, x64;
40
- - AMD Ryzen 5 7500F 6-Core Processor; 12 logical processors;
41
- - 32,375.906 MiB total physical memory;
42
- - Node.js `v24.15.0`, V8 `13.6.233.17-node.48`;
43
- - Sharp `0.35.3`, libvips `8.18.3`.
44
-
45
- Times are milliseconds. Memory columns are endpoint delta MiB for the measured pass.
46
-
47
- | Workload | Pass | Total | Scan/index | Layout or render/store | RSS Δ | Heap-used Δ |
48
- | ------------------------------ | ---- | ---------: | -------------------: | ------------------------------------------: | ------: | ----------: |
49
- | Focus (255 nodes) | Cold | 15,082.652 | 36.402 | layout 62.085; lint/render/store 14,983.948 | 21.820 | 12.223 |
50
- | Focus (255 nodes) | Warm | 16,721.268 | 8.274 | layout 59.933; lint/render/store 16,652.932 | 55.937 | 4.343 |
51
- | GUI (158 source / 203 visible) | Cold | 11,507.893 | 59.041 explicit scan | gallery render/store 11,448.837 | 200.343 | 47.387 |
52
- | GUI (158 source / 203 visible) | Warm | 5,607.155 | 46.417 explicit scan | gallery render/store 5,560.708 | 49.492 | 48.742 |
53
- | Map (65,536 pixels) | Cold | 852.390 | 31.467 | ten layers × twelve overlays 820.908 | -38.598 | 58.195 |
54
- | Map (65,536 pixels) | Warm | 671.601 | 21.518 | ten layers × twelve overlays 650.073 | 20.762 | 30.028 |
55
-
56
- Relevant output and input counts from the same run:
57
-
58
- | Workload | Counts |
59
- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
60
- | Focus | 8 scanned files; 255 focuses; 10 route families; 6 artifacts |
61
- | GUI | 7 scanned files; 158 source elements; 203 visible elements; 14 states; 3 resolutions; 5 primary variants; 24 artifacts; 14,455,435 output bytes |
62
- | Map | 21 scanned files / 198,897 bytes; 65,536 pixels; 5 definition rows; 4 provinces with geometry; 3 states; 2 strategic regions; 10 base layers; 12 overlays per layer; 14,339 PNG bytes |
63
-
64
- Cold and warm output fingerprints matched for all three workloads.
65
-
66
- ## Cache invalidation behavior
67
-
68
- `WorkspaceScanner` reads file metadata and bytes on every scan and computes a SHA-256 content hash. `CoreEngine` derives its revision from each file's display path, load order, and content hash, then keys its in-memory scan/index cache by workspace ID and revision. Size and modification time are recorded as evidence but are not trusted as the semantic cache key.
69
-
70
- Scan admission normally serializes physical scans for a workspace. If a scanner ignores cancellation, one replacement scan may run after the original request is aborted so current callers are not held behind abandoned work. At most two physical scanners may exist for that workspace in this state; a third request waits. Generation fencing prevents a stale late completion from replacing the current cache entry.
71
-
72
- The benchmark changes only the copied fixture's modification time and confirms that the revision remains unchanged and the in-memory snapshot is reused. It then changes source bytes without changing file size or modification time and confirms that the content hash changes, the revision changes, and the cached snapshot is not reused. In the recorded run:
73
-
74
- - baseline scan: 21.353 ms;
75
- - metadata-only rescan/cache hit: 5.431 ms;
76
- - same-size, same-mtime content change/rescan: 20.300 ms.
77
-
78
- The deterministic unit test in `tests/unit/core-cache.test.ts` continuously checks this correctness property without asserting timing. Autonomous rewrites and reviewed transaction apply/rollback paths all invalidate the workspace cache; the content-derived revision remains the safety backstop for external edits.
79
-
80
- The Scripted GUI Studio and Agent Nudger benchmark paths currently rebuild their domain scans/indexes on each call. Their warm figures therefore reflect runtime/JIT and operating-system cache effects rather than a domain-level memoization claim. Stored artifacts are content-addressed, but artifact storage is not treated as a parsed-source cache.
81
-
82
- ## Reproducing and comparing runs
83
-
84
- Run from a clean install on the host being measured:
85
-
86
- ```bash
87
- npm ci
88
- npm run --silent benchmark > benchmark-result.json
89
- ```
90
-
91
- No game installation, mod workspace, environment variable, network access, or proprietary input is used. The script creates all runtime storage below the operating system temporary directory and removes it on completion. Compare the JSON phase timings, memory samples, counts, and runtime/platform block; do not compare only the total time across unlike hosts.
92
-
93
- To check cache correctness without collecting performance data:
94
-
95
- ```bash
96
- npm test -- tests/unit/core-cache.test.ts
97
- ```
98
-
99
- ## Opt-in installed-data qualification
100
-
101
- The opt-in local suite is a compatibility qualification, not a CI performance threshold. It reads configured installed-game and external-mod roots in place, writes only to an operating-system temporary directory, and neither launches the game nor copies proprietary inputs into the project.
102
-
103
- On the same Windows/Node host documented above, the final `2026-07-10` qualification completed all three required tests through the fail-closed `npm run test:local` harness:
104
-
105
- | Workflow | Elapsed |
106
- | ----------------------------------------------------------------------------------------------------------- | --------: |
107
- | Large vanilla focus import, stable layout, and two deterministic renders, plus an external-mod focus render | 83.551 s |
108
- | External GUI/GFX/font graph construction and two deterministic full/annotated renders | 56.019 s |
109
- | External map scan plus state/coastline/supply/railway render and content-addressed PNG/JSON/HTML storage | 22.981 s |
110
- | Total test time | 162.578 s |
111
-
112
- The GUI qualification's canonical source-graph JSON was 302,497,021 bytes. The default
113
- 134,217,728-byte per-object ceiling remained enabled: storage produced a byte-exact three-chunk
114
- resource bundle plus its canonical index, repeated the same render/storage call, and verified
115
- deterministic output without truncating the graph or increasing the ceiling.
116
-
117
- The reporter independently confirmed three completed tests and no unhandled worker error. Root paths and source-derived content are intentionally absent from the report. These timings vary with installed data, disk/cache state, processor, memory, and codec versions; only completion and deterministic/correct output are assertions.