hoi4-agent-tools 0.1.7 → 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 (424) hide show
  1. package/CHANGELOG.md +12 -94
  2. package/README.md +35 -121
  3. package/SECURITY.md +5 -5
  4. package/dist/bin/http.js +0 -1
  5. package/dist/bin/setup.js +141 -85
  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 -20
  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 +46 -31
  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 +11 -26
  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 -103
  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 +182 -38
  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 -5
  73. package/dist/hoi4_agent_tools/mcp/server/base-tools.js +26 -733
  74. package/dist/hoi4_agent_tools/mcp/server/create.js +3 -6
  75. package/dist/hoi4_agent_tools/mcp/server/output-schemas.js +0 -70
  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 +123 -0
  79. package/dist/hoi4_agent_tools/mcp/tools/focus.js +244 -254
  80. package/dist/hoi4_agent_tools/mcp/tools/gui.js +163 -236
  81. package/dist/hoi4_agent_tools/mcp/tools/map.js +269 -323
  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 -9
  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 -137
  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 -56
  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 -162
  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 -3
  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 -50
  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 -35
  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 -133
  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/tools/focus.d.ts +0 -5
  337. package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts.map +0 -1
  338. package/dist/hoi4_agent_tools/mcp/tools/focus.js.map +0 -1
  339. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts +0 -111
  340. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts.map +0 -1
  341. package/dist/hoi4_agent_tools/mcp/tools/gui.js.map +0 -1
  342. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts +0 -5
  343. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts.map +0 -1
  344. package/dist/hoi4_agent_tools/mcp/tools/map.js.map +0 -1
  345. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts +0 -58
  346. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts.map +0 -1
  347. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js.map +0 -1
  348. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts +0 -26
  349. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts.map +0 -1
  350. package/dist/hoi4_agent_tools/mcp/transports/event-store.js.map +0 -1
  351. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts +0 -28
  352. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts.map +0 -1
  353. package/dist/hoi4_agent_tools/mcp/transports/http.js.map +0 -1
  354. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts +0 -15
  355. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts.map +0 -1
  356. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js.map +0 -1
  357. package/dist/hoi4_agent_tools/runtime.d.ts +0 -4
  358. package/dist/hoi4_agent_tools/runtime.d.ts.map +0 -1
  359. package/dist/hoi4_agent_tools/runtime.js.map +0 -1
  360. package/dist/hoi4_agent_tools/schemas/common.d.ts +0 -74
  361. package/dist/hoi4_agent_tools/schemas/common.d.ts.map +0 -1
  362. package/dist/hoi4_agent_tools/schemas/common.js.map +0 -1
  363. package/dist/hoi4_agent_tools/schemas/focus.d.ts +0 -784
  364. package/dist/hoi4_agent_tools/schemas/focus.d.ts.map +0 -1
  365. package/dist/hoi4_agent_tools/schemas/focus.js.map +0 -1
  366. package/dist/hoi4_agent_tools/schemas/index.d.ts +0 -5
  367. package/dist/hoi4_agent_tools/schemas/index.d.ts.map +0 -1
  368. package/dist/hoi4_agent_tools/schemas/index.js +0 -5
  369. package/dist/hoi4_agent_tools/schemas/index.js.map +0 -1
  370. package/dist/hoi4_agent_tools/schemas/map.d.ts +0 -654
  371. package/dist/hoi4_agent_tools/schemas/map.d.ts.map +0 -1
  372. package/dist/hoi4_agent_tools/schemas/map.js.map +0 -1
  373. package/dist/hoi4_agent_tools/schemas/transaction.d.ts +0 -259
  374. package/dist/hoi4_agent_tools/schemas/transaction.d.ts.map +0 -1
  375. package/dist/hoi4_agent_tools/schemas/transaction.js.map +0 -1
  376. package/dist/hoi4_agent_tools/version.d.ts +0 -6
  377. package/dist/hoi4_agent_tools/version.d.ts.map +0 -1
  378. package/dist/hoi4_agent_tools/version.js.map +0 -1
  379. package/dist/index.d.ts +0 -3
  380. package/dist/index.d.ts.map +0 -1
  381. package/dist/index.js +0 -3
  382. package/dist/index.js.map +0 -1
  383. package/docs/adr/0001-runtime-and-language.md +0 -16
  384. package/docs/adr/0002-lossless-source-model.md +0 -18
  385. package/docs/adr/0003-image-and-font-codecs.md +0 -18
  386. package/docs/adr/0004-focus-layout.md +0 -16
  387. package/docs/adr/0005-offline-rendering.md +0 -18
  388. package/docs/adr/0006-mcp-sdk-and-protocol.md +0 -16
  389. package/docs/adr/0007-storage-and-transactions.md +0 -24
  390. package/docs/adr/0008-test-strategy.md +0 -18
  391. package/docs/adr/0009-packaging-and-registry.md +0 -16
  392. package/docs/adr/0010-unsupported-and-refusal-policy.md +0 -18
  393. package/docs/adr/0011-http-security.md +0 -16
  394. package/docs/adr/README.md +0 -13
  395. package/docs/agent-integration.md +0 -136
  396. package/docs/architecture.md +0 -60
  397. package/docs/artifacts.md +0 -133
  398. package/docs/compatibility.md +0 -33
  399. package/docs/completion-report.md +0 -162
  400. package/docs/configuration.md +0 -289
  401. package/docs/focus-workflow.md +0 -195
  402. package/docs/gui-workflow.md +0 -121
  403. package/docs/limitations.md +0 -31
  404. package/docs/map-workflow.md +0 -89
  405. package/docs/performance.md +0 -117
  406. package/docs/release.md +0 -220
  407. package/docs/research/mcp-2026-07-10.md +0 -46
  408. package/docs/research/source-ledger.md +0 -68
  409. package/docs/security.md +0 -139
  410. package/docs/self-hosting.md +0 -168
  411. package/docs/testing.md +0 -43
  412. package/docs/third-party-notices.md +0 -11
  413. package/docs/transactions.md +0 -168
  414. package/docs/troubleshooting.md +0 -46
  415. package/schemas/configuration.schema.json +0 -794
  416. package/schemas/continuous-focus-palette.schema.json +0 -325
  417. package/schemas/focus-plan.schema.json +0 -927
  418. package/schemas/focus-planning-sidecar.schema.json +0 -379
  419. package/schemas/gui-animation-source.schema.json +0 -176
  420. package/schemas/gui-helper.schema.json +0 -301
  421. package/schemas/gui-scenario.schema.json +0 -298
  422. package/schemas/map-operation.schema.json +0 -2284
  423. package/schemas/operation-result.schema.json +0 -344
  424. package/schemas/transaction-manifest.schema.json +0 -685
@@ -1,17 +1,135 @@
1
1
  import path from 'node:path';
2
2
  import fg from 'fast-glob';
3
- import { ArtifactStore, boundedSourceHashEvidence, } from '../core/artifacts.js';
3
+ import { ArtifactStore, boundedSourceHashEvidence, publicArtifactLink, } from '../core/artifacts.js';
4
4
  import { canonicalJson, compareCodeUnits, hashCanonical, sha256Bytes } from '../core/canonical.js';
5
5
  import { sortDiagnostics } from '../core/diagnostics.js';
6
6
  import { CoreEngine } from '../core/engine.js';
7
7
  import { RenderBudget } from '../core/render-budget.js';
8
+ import { ServiceError } from '../core/result.js';
8
9
  import { WorkspaceScanner } from '../core/scanner.js';
9
10
  import { readDependenciesFromScannedFiles, } from '../core/transactions.js';
10
11
  import { PACKAGE_VERSION } from '../version.js';
11
- import { defaultMapSelectorValue, MapWorkspaceIndex } from './model.js';
12
+ import { MAP_PROVINCE_GEOMETRY_SELECTOR_LIMIT, MAP_SELECTED_OFFSET_BYTES, MAP_SELECTED_PIXEL_LIMIT, } from './limits.js';
13
+ import { defaultMapSelectorValue, MapWorkspaceIndex, } from './model.js';
12
14
  import { planMapOperationsAsync } from './operations.js';
13
15
  import { renderMap, renderMapDiff, } from './render.js';
14
16
  import { validateMapAsync } from './validation.js';
17
+ function compareNumbers(left, right) {
18
+ return left - right;
19
+ }
20
+ function exactGeometryBounds(geometry) {
21
+ return {
22
+ minX: geometry.minX,
23
+ minY: geometry.minY,
24
+ maxXExclusive: geometry.maxX + 1,
25
+ maxYExclusive: geometry.maxY + 1,
26
+ };
27
+ }
28
+ function assertProvinceGeometryExportPixelBudget(pixelCount) {
29
+ if (!Number.isSafeInteger(pixelCount) || pixelCount < 0) {
30
+ throw new ServiceError('MAP_SELECTED_PIXEL_BUDGET_BLOCKED', 'Province geometry export declares an invalid selected-pixel count', {
31
+ source: 'Province geometry export',
32
+ selectedPixels: pixelCount,
33
+ maximumSelectedPixels: MAP_SELECTED_PIXEL_LIMIT,
34
+ });
35
+ }
36
+ if (pixelCount > MAP_SELECTED_PIXEL_LIMIT) {
37
+ throw new ServiceError('MAP_SELECTED_PIXEL_BUDGET_BLOCKED', 'Province geometry export exceeds the fixed selected-pixel memory budget', {
38
+ source: 'Province geometry export',
39
+ selectedPixels: pixelCount,
40
+ maximumSelectedPixels: MAP_SELECTED_PIXEL_LIMIT,
41
+ maximumOffsetBytes: MAP_SELECTED_PIXEL_LIMIT * MAP_SELECTED_OFFSET_BYTES,
42
+ });
43
+ }
44
+ }
45
+ /**
46
+ * Export maximal, canonical row runs from the same raster used by map rewrites.
47
+ * Runs are collected in raster order, so every province's tuples are sorted by
48
+ * y and then startX without a second, memory-heavy sort.
49
+ */
50
+ export async function exportProvinceGeometryRowRuns(source, provinceIds, signal) {
51
+ signal?.throwIfAborted();
52
+ if (provinceIds.length > MAP_PROVINCE_GEOMETRY_SELECTOR_LIMIT) {
53
+ throw new ServiceError('MAP_PROVINCE_GEOMETRY_SELECTOR_LIMIT', `Province geometry inspection accepts at most ${MAP_PROVINCE_GEOMETRY_SELECTOR_LIMIT} IDs`, {
54
+ requestedProvinceCount: provinceIds.length,
55
+ maximumProvinceCount: MAP_PROVINCE_GEOMETRY_SELECTOR_LIMIT,
56
+ });
57
+ }
58
+ if (provinceIds.some((provinceId) => !Number.isSafeInteger(provinceId) || provinceId < 0)) {
59
+ throw new ServiceError('MAP_PROVINCE_GEOMETRY_SELECTOR_INVALID', 'Province geometry inspection IDs must be non-negative safe integers');
60
+ }
61
+ const raster = source.raster;
62
+ if (raster === undefined) {
63
+ throw new ServiceError('MAP_PROVINCE_BITMAP_MISSING', 'Exact province geometry inspection requires provinces.bmp');
64
+ }
65
+ const requestedProvinceIds = [...new Set(provinceIds)].sort(compareNumbers);
66
+ const unknownProvinceIds = requestedProvinceIds.filter((provinceId) => !source.definitionsById.has(provinceId));
67
+ const missingGeometryProvinceIds = requestedProvinceIds.filter((provinceId) => source.definitionsById.has(provinceId) && !raster.geometry.has(provinceId));
68
+ const exportableProvinceIds = requestedProvinceIds.filter((provinceId) => source.definitionsById.has(provinceId) && raster.geometry.has(provinceId));
69
+ let pixelCount = 0;
70
+ for (const provinceId of exportableProvinceIds) {
71
+ const geometry = raster.geometry.get(provinceId);
72
+ if (geometry === undefined)
73
+ continue;
74
+ pixelCount += geometry.pixelCount;
75
+ assertProvinceGeometryExportPixelBudget(pixelCount);
76
+ }
77
+ const rowRunsByProvince = new Map(exportableProvinceIds.map((provinceId) => [provinceId, []]));
78
+ const observedPixelCounts = new Map(exportableProvinceIds.map((provinceId) => [provinceId, 0]));
79
+ for (let y = 0; y < raster.height; y += 1) {
80
+ if (y % 32 === 0) {
81
+ await new Promise((resolve) => setImmediate(resolve));
82
+ signal?.throwIfAborted();
83
+ }
84
+ let x = 0;
85
+ while (x < raster.width) {
86
+ const provinceId = raster.provinceIds[y * raster.width + x] ?? -1;
87
+ const startX = x;
88
+ x += 1;
89
+ while (x < raster.width && (raster.provinceIds[y * raster.width + x] ?? -1) === provinceId) {
90
+ x += 1;
91
+ }
92
+ const runs = rowRunsByProvince.get(provinceId);
93
+ if (runs === undefined)
94
+ continue;
95
+ runs.push([y, startX, x]);
96
+ observedPixelCounts.set(provinceId, (observedPixelCounts.get(provinceId) ?? 0) + x - startX);
97
+ }
98
+ }
99
+ signal?.throwIfAborted();
100
+ const provinces = exportableProvinceIds.map((provinceId) => {
101
+ const geometry = raster.geometry.get(provinceId);
102
+ if (geometry === undefined) {
103
+ throw new ServiceError('MAP_RASTER_GEOMETRY_MISMATCH', 'Province geometry disappeared during exact row-run export', { provinceId });
104
+ }
105
+ const observedPixelCount = observedPixelCounts.get(provinceId) ?? 0;
106
+ if (observedPixelCount !== geometry.pixelCount) {
107
+ throw new ServiceError('MAP_RASTER_GEOMETRY_MISMATCH', 'Exact province row runs do not match the indexed province pixel count', {
108
+ provinceId,
109
+ expectedPixelCount: geometry.pixelCount,
110
+ observedPixelCount,
111
+ });
112
+ }
113
+ const rowRuns = rowRunsByProvince.get(provinceId) ?? [];
114
+ return {
115
+ provinceId,
116
+ pixelCount: observedPixelCount,
117
+ bounds: exactGeometryBounds(geometry),
118
+ rowRunCount: rowRuns.length,
119
+ rowRuns,
120
+ };
121
+ });
122
+ return {
123
+ width: raster.width,
124
+ height: raster.height,
125
+ requestedProvinceIds,
126
+ unknownProvinceIds,
127
+ missingGeometryProvinceIds,
128
+ pixelCount,
129
+ rowRunCount: provinces.reduce((count, province) => count + province.rowRunCount, 0),
130
+ provinces,
131
+ };
132
+ }
15
133
  const provinceOperationKinds = new Set([
16
134
  'split_province',
17
135
  'create_province',
@@ -181,7 +299,7 @@ export function attributeMapValidationDiagnostics(input) {
181
299
  attributed.push({
182
300
  code: 'MAP_VALIDATION_OPERATION_UNOWNED',
183
301
  severity: 'blocker',
184
- category: 'transaction',
302
+ category: 'validation',
185
303
  message: `${diagnostic.code} already existed before the manifest and has no originating operation`,
186
304
  ...(diagnostic.location === undefined ? {} : { location: diagnostic.location }),
187
305
  ...(diagnostic.related === undefined ? {} : { related: diagnostic.related }),
@@ -238,7 +356,7 @@ export function attributeMapValidationDiagnostics(input) {
238
356
  attributed.push({
239
357
  code: 'MAP_VALIDATION_OPERATION_UNOWNED',
240
358
  severity: 'blocker',
241
- category: 'transaction',
359
+ category: 'validation',
242
360
  message: `${diagnostic.code} cannot be attributed to any manifest operation`,
243
361
  ...(diagnostic.location === undefined ? {} : { location: diagnostic.location }),
244
362
  ...(diagnostic.related === undefined ? {} : { related: diagnostic.related }),
@@ -390,14 +508,14 @@ export class AgentNudger {
390
508
  validation: await validateMapAsync(snapshot.index, signal === undefined ? {} : { signal }),
391
509
  };
392
510
  }
393
- async plan(input) {
394
- input.signal?.throwIfAborted();
395
- const snapshot = await this.scan(input.workspaceId, input.principal, input.signal);
396
- const plan = await planMapOperationsAsync(snapshot.index, input.operations, input.signal);
397
- const baselineValidation = await validateMapAsync(snapshot.index, input.signal === undefined ? {} : { signal: input.signal });
511
+ async prepareOperations(workspaceId, operations, principal, signal) {
512
+ signal?.throwIfAborted();
513
+ const snapshot = await this.scan(workspaceId, principal, signal);
514
+ const plan = await planMapOperationsAsync(snapshot.index, operations, signal);
515
+ const baselineValidation = await validateMapAsync(snapshot.index, signal === undefined ? {} : { signal });
398
516
  const rawValidation = await validateMapAsync(plan.finalIndex, {
399
517
  baseline: snapshot.index,
400
- ...(input.signal === undefined ? {} : { signal: input.signal }),
518
+ ...(signal === undefined ? {} : { signal }),
401
519
  ...(plan.expectedChangedBounds === undefined
402
520
  ? {}
403
521
  : { expectedChangedBounds: plan.expectedChangedBounds }),
@@ -411,7 +529,22 @@ export class AgentNudger {
411
529
  baselineDiagnostics: baselineValidation.diagnostics,
412
530
  }),
413
531
  };
414
- const validation = validationWithPlan(attributedValidation, plan);
532
+ return {
533
+ snapshot,
534
+ plan,
535
+ validation: validationWithPlan(attributedValidation, plan),
536
+ };
537
+ }
538
+ async plan(input) {
539
+ const prepared = await this.prepareOperations(input.workspaceId, input.operations, input.principal, input.signal);
540
+ return this.planPrepared(input, prepared);
541
+ }
542
+ async planPrepared(input, prepared) {
543
+ input.signal?.throwIfAborted();
544
+ const { snapshot, plan, validation } = prepared;
545
+ if (snapshot.workspaceId !== input.workspaceId) {
546
+ throw new ServiceError('MAP_PREPARED_WORKSPACE_MISMATCH', 'Prepared map operations belong to another workspace');
547
+ }
415
548
  const transaction = await this.transactions.plan({
416
549
  workspaceId: input.workspaceId,
417
550
  ...(input.principal === undefined ? {} : { principal: input.principal }),
@@ -424,15 +557,21 @@ export class AgentNudger {
424
557
  validate: (proposed, signal) => {
425
558
  signal?.throwIfAborted();
426
559
  const expected = new Map(plan.changes.map((change) => [change.relativePath, change.content]));
427
- const exactProposedBytes = proposed.size === expected.size &&
428
- [...proposed].every(([relativePath, content]) => {
429
- const planned = expected.get(relativePath);
430
- if (planned === undefined)
560
+ const current = new Map(snapshot.files
561
+ .filter(({ rootKind, shadowedBy }) => rootKind === 'mod' && shadowedBy === undefined)
562
+ .map(({ relativePath, bytes }) => [relativePath, bytes]));
563
+ const exactProposedBytes = proposed.size <= expected.size &&
564
+ [...expected].every(([relativePath, planned]) => {
565
+ const content = proposed.has(relativePath)
566
+ ? proposed.get(relativePath)
567
+ : (current.get(relativePath) ?? null);
568
+ if (content === undefined)
431
569
  return false;
432
570
  if (content === null || planned === null)
433
571
  return content === planned;
434
572
  return Buffer.from(content).equals(Buffer.from(planned));
435
- });
573
+ }) &&
574
+ [...proposed.keys()].every((relativePath) => expected.has(relativePath));
436
575
  const diagnostics = exactProposedBytes
437
576
  ? validation.diagnostics
438
577
  : [
@@ -440,7 +579,7 @@ export class AgentNudger {
440
579
  {
441
580
  code: 'MAP_TRANSACTION_BYTES_MISMATCH',
442
581
  severity: 'blocker',
443
- category: 'transaction',
582
+ category: 'validation',
444
583
  message: 'Transaction dry-run bytes differ from the validated map operation plan',
445
584
  },
446
585
  ];
@@ -515,26 +654,32 @@ export class AgentNudger {
515
654
  };
516
655
  }
517
656
  async renderDiffAndStore(workspaceId, operations, options = {}) {
518
- const budget = new RenderBudget();
519
- const snapshot = await this.scan(workspaceId, options.principal, options.signal);
520
- const plan = await planMapOperationsAsync(snapshot.index, operations, options.signal);
521
- const baselineValidation = await validateMapAsync(snapshot.index, options.signal === undefined ? {} : { signal: options.signal });
522
- const rawValidation = await validateMapAsync(plan.finalIndex, {
523
- baseline: snapshot.index,
524
- ...(options.signal === undefined ? {} : { signal: options.signal }),
525
- ...(plan.expectedChangedBounds === undefined
526
- ? {}
527
- : { expectedChangedBounds: plan.expectedChangedBounds }),
657
+ const prepared = await this.prepareOperations(workspaceId, operations, options.principal, options.signal);
658
+ return this.renderPreparedDiffAndStore(prepared, operations, options);
659
+ }
660
+ /**
661
+ * Build review evidence and a hash-bound transaction from one immutable scan and operation plan.
662
+ * Any source edit after this preparation is rejected by the transaction read-dependency checks.
663
+ */
664
+ async planRewriteWithDiff(input) {
665
+ const prepared = await this.prepareOperations(input.workspaceId, input.operations, input.principal, input.signal);
666
+ const diff = await this.renderPreparedDiffAndStore(prepared, input.operations, {
667
+ ...(input.diffScale === undefined ? {} : { scale: input.diffScale }),
668
+ ...(input.principal === undefined ? {} : { principal: input.principal }),
669
+ ...(input.signal === undefined ? {} : { signal: input.signal }),
528
670
  });
529
- const validation = validationWithPlan({
530
- ...rawValidation,
531
- diagnostics: attributeMapValidationDiagnostics({
532
- diagnostics: rawValidation.diagnostics,
533
- operations: plan.operations,
534
- changes: plan.changes,
535
- baselineDiagnostics: baselineValidation.diagnostics,
536
- }),
537
- }, plan);
671
+ const planned = await this.planPrepared({
672
+ workspaceId: input.workspaceId,
673
+ operations: input.operations,
674
+ artifacts: diff.artifacts.map(publicArtifactLink),
675
+ ...(input.principal === undefined ? {} : { principal: input.principal }),
676
+ ...(input.signal === undefined ? {} : { signal: input.signal }),
677
+ }, prepared);
678
+ return { ...diff, ...planned };
679
+ }
680
+ async renderPreparedDiffAndStore(prepared, operations, options) {
681
+ const budget = new RenderBudget();
682
+ const { snapshot, plan, validation } = prepared;
538
683
  const review = {
539
684
  operationIds: plan.operations.map(({ id }) => id),
540
685
  affectedFiles: plan.changes.map(({ relativePath, operationIds, mediaType, content }) => ({
@@ -593,7 +738,7 @@ export class AgentNudger {
593
738
  const bundle = mapBundleWithSourceHashes(rawBundle, completeSourceHashes);
594
739
  const beforeBundle = mapBundleWithSourceHashes(rawBeforeBundle, completeSourceHashes);
595
740
  const proposedBundle = mapBundleWithSourceHashes(rawProposedBundle, completeSourceHashes);
596
- const workspace = this.resolver.get(workspaceId, options.principal);
741
+ const workspace = this.resolver.get(snapshot.workspaceId, options.principal);
597
742
  const provenance = {
598
743
  kind: 'map-diff-render',
599
744
  toolVersion: PACKAGE_VERSION,
@@ -692,4 +837,3 @@ export class AgentNudger {
692
837
  };
693
838
  }
694
839
  }
695
- //# sourceMappingURL=service.js.map
@@ -1174,4 +1174,3 @@ export function validateMap(index, options = {}) {
1174
1174
  export async function validateMapAsync(index, options = {}) {
1175
1175
  return completeCooperatively(validateMapSteps(index, options), options.signal);
1176
1176
  }
1177
- //# sourceMappingURL=validation.js.map
@@ -1,11 +1,30 @@
1
1
  import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { readFile } from 'node:fs/promises';
3
- import path from 'node:path';
4
2
  import { canonicalJson } from '../../core/canonical.js';
5
3
  import { ServiceError } from '../../core/result.js';
6
- import { compactWorkspaceStatus } from '../server/base-tools.js';
7
4
  const artifactResourceLimit = 1_048_576;
5
+ const artifactChunkMetadataKey = 'io.github.klimpaskov/hoi4-agent-tools.artifact-byte-range';
8
6
  const fatalUtf8Decoder = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
7
+ const artifactResourceMetadata = {
8
+ title: 'HOI4 review artifact',
9
+ description: 'Complete plans, diagnostics, layouts, previews, and diffs. Reads accept zero-based byte offset and positive byte length query selectors; each response reports its exact byte range and continuation URI in _meta.',
10
+ _meta: {
11
+ [artifactChunkMetadataKey]: {
12
+ version: 1,
13
+ unit: 'byte',
14
+ maxChunkSize: artifactResourceLimit,
15
+ selectors: {
16
+ offset: { type: 'integer', minimum: 0, default: 0 },
17
+ length: {
18
+ type: 'integer',
19
+ minimum: 1,
20
+ maximum: artifactResourceLimit,
21
+ default: artifactResourceLimit,
22
+ },
23
+ metadata: { type: 'string', enum: ['manifest'], optional: true },
24
+ },
25
+ },
26
+ },
27
+ };
9
28
  function assertResourceSelectors(uri, allowed) {
10
29
  if (uri.hash !== '' || uri.username !== '' || uri.password !== '' || uri.port !== '') {
11
30
  throw new ServiceError('RESOURCE_URI_INVALID', 'Resource URI is not canonical');
@@ -28,31 +47,6 @@ function contentArtifactUri(uri) {
28
47
  contentUri.hash = '';
29
48
  return contentUri.href;
30
49
  }
31
- function transactionResourceIdentity(uri) {
32
- let segments;
33
- try {
34
- segments = uri.pathname.split('/').filter(Boolean).map(decodeURIComponent);
35
- }
36
- catch {
37
- throw new ServiceError('TRANSACTION_ID_INVALID', 'Invalid transaction resource URI');
38
- }
39
- if (uri.protocol !== 'hoi4-agent:' ||
40
- uri.hostname !== 'workspace' ||
41
- segments.length !== 3 ||
42
- segments[1] !== 'transaction' ||
43
- !/^[a-z][a-z0-9_-]{0,63}$/u.test(segments[0]) ||
44
- !/^txn_[0-9a-f-]{36}$/u.test(segments[2])) {
45
- throw new ServiceError('TRANSACTION_ID_INVALID', 'Invalid transaction resource URI');
46
- }
47
- const canonical = `hoi4-agent://workspace/${encodeURIComponent(segments[0])}/transaction/${encodeURIComponent(segments[2])}`;
48
- const queryless = new URL(uri);
49
- queryless.search = '';
50
- queryless.hash = '';
51
- if (queryless.href !== canonical) {
52
- throw new ServiceError('TRANSACTION_ID_INVALID', 'Transaction resource URI is not canonical');
53
- }
54
- return { workspaceId: segments[0], transactionId: segments[2] };
55
- }
56
50
  function exactUtf8Text(bytes) {
57
51
  try {
58
52
  const text = fatalUtf8Decoder.decode(bytes);
@@ -62,7 +56,7 @@ function exactUtf8Text(bytes) {
62
56
  return undefined;
63
57
  }
64
58
  }
65
- function artifactRangeParameter(uri, name, fallback, minimum) {
59
+ function artifactRangeParameter(uri, name, fallback, minimum, maximum = Number.MAX_SAFE_INTEGER) {
66
60
  const raw = uri.searchParams.get(name);
67
61
  if (raw === null)
68
62
  return fallback;
@@ -70,44 +64,40 @@ function artifactRangeParameter(uri, name, fallback, minimum) {
70
64
  throw new ServiceError('ARTIFACT_RANGE_INVALID', 'Artifact byte range is invalid');
71
65
  }
72
66
  const value = Number(raw);
73
- if (!Number.isSafeInteger(value) || value < minimum) {
67
+ if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {
74
68
  throw new ServiceError('ARTIFACT_RANGE_INVALID', 'Artifact byte range is invalid');
75
69
  }
76
70
  return value;
77
71
  }
72
+ function artifactChunkMetadata(uri, metadata, totalSize, offset, returnedLength, requestedLength) {
73
+ const endExclusive = offset + returnedLength;
74
+ let continuationUri = null;
75
+ if (endExclusive < totalSize) {
76
+ const continuation = new URL(contentArtifactUri(uri));
77
+ continuation.searchParams.set('offset', String(endExclusive));
78
+ continuation.searchParams.set('length', String(requestedLength));
79
+ if (metadata !== null)
80
+ continuation.searchParams.set('metadata', metadata);
81
+ continuationUri = continuation.href;
82
+ }
83
+ return {
84
+ [artifactChunkMetadataKey]: {
85
+ version: 1,
86
+ unit: 'byte',
87
+ totalSize,
88
+ returnedRange: { offset, length: returnedLength, endExclusive },
89
+ complete: offset === 0 && returnedLength === totalSize,
90
+ continuationUri,
91
+ },
92
+ };
93
+ }
78
94
  export function registerMcpResources(server, engine, context) {
79
- server.registerResource('workspace-summary', new ResourceTemplate('hoi4-agent://workspace/{workspaceId}/summary', {
80
- list: () => ({
81
- resources: engine.list(context.principal).map((workspace) => ({
82
- uri: `hoi4-agent://workspace/${workspace.id}/summary`,
83
- name: `${workspace.name} summary`,
84
- mimeType: 'application/json',
85
- })),
86
- }),
87
- }), {
88
- title: 'Workspace summary',
89
- description: 'Registered workspace capabilities',
90
- mimeType: 'application/json',
91
- }, (uri, { workspaceId }) => {
92
- assertResourceSelectors(uri, []);
93
- return {
94
- contents: [
95
- {
96
- uri: uri.href,
97
- mimeType: 'application/json',
98
- text: `${canonicalJson(compactWorkspaceStatus(engine.status(String(workspaceId), context.principal)))}\n`,
99
- },
100
- ],
101
- };
102
- });
103
- server.registerResource('artifact', new ResourceTemplate('hoi4-agent://workspace/{workspaceId}/artifact/{sha256}/{provenanceHash}/{name}', {
104
- list: undefined,
105
- }), { title: 'Generated artifact', description: 'Content-addressed workspace artifact' }, async (uri, { workspaceId }, extra) => {
95
+ server.registerResource('artifact', new ResourceTemplate('hoi4-agent://workspace/{workspaceId}/artifact/{sha256}/{provenanceHash}/{name}', { list: undefined }), artifactResourceMetadata, async (uri, { workspaceId }, extra) => {
106
96
  extra.signal.throwIfAborted();
107
97
  assertResourceSelectors(uri, ['offset', 'length', 'metadata']);
108
98
  const workspace = engine.resolver.get(String(workspaceId), context.principal);
109
99
  const offset = artifactRangeParameter(uri, 'offset', 0, 0);
110
- const length = Math.min(artifactResourceLimit, artifactRangeParameter(uri, 'length', artifactResourceLimit, 1));
100
+ const length = artifactRangeParameter(uri, 'length', artifactResourceLimit, 1, artifactResourceLimit);
111
101
  const metadata = uri.searchParams.get('metadata');
112
102
  if (metadata !== null && metadata !== 'manifest') {
113
103
  throw new ServiceError('ARTIFACT_METADATA_INVALID', 'Artifact metadata selector is invalid');
@@ -119,161 +109,45 @@ export function registerMcpResources(server, engine, context) {
119
109
  const manifestBytes = Buffer.from(`${canonicalJson(publicManifest)}\n`, 'utf8');
120
110
  const start = Math.min(offset, manifestBytes.length);
121
111
  const selected = manifestBytes.subarray(start, Math.min(manifestBytes.length, start + length));
122
- extra.signal.throwIfAborted();
123
112
  const complete = start === 0 && selected.length === manifestBytes.length;
113
+ const _meta = artifactChunkMetadata(uri, metadata, manifestBytes.length, start, selected.length, length);
124
114
  return {
125
115
  contents: [
126
116
  complete
127
- ? { uri: uri.href, mimeType: 'application/json', text: selected.toString('utf8') }
117
+ ? {
118
+ uri: uri.href,
119
+ mimeType: 'application/json',
120
+ text: selected.toString('utf8'),
121
+ _meta,
122
+ }
128
123
  : {
129
124
  uri: uri.href,
130
125
  mimeType: 'application/json',
131
126
  blob: selected.toString('base64'),
127
+ _meta,
132
128
  },
133
129
  ],
134
130
  };
135
131
  }
136
132
  const artifact = await engine.artifacts.read(workspace, contentArtifactUri(uri), { offset, length }, extra.signal);
137
- extra.signal.throwIfAborted();
138
133
  const textual = artifact.mimeType.startsWith('text/') ||
139
134
  artifact.mimeType === 'application/json' ||
140
135
  artifact.mimeType === 'image/svg+xml';
141
- const complete = offset === 0 && artifact.bytes.length === artifact.totalSize;
136
+ const start = Math.min(offset, artifact.totalSize);
137
+ const complete = start === 0 && artifact.bytes.length === artifact.totalSize;
142
138
  const text = textual && complete ? exactUtf8Text(artifact.bytes) : undefined;
139
+ const _meta = artifactChunkMetadata(uri, metadata, artifact.totalSize, start, artifact.bytes.length, length);
143
140
  return {
144
141
  contents: [
145
142
  text !== undefined
146
- ? { uri: uri.href, mimeType: artifact.mimeType, text }
143
+ ? { uri: uri.href, mimeType: artifact.mimeType, text, _meta }
147
144
  : {
148
145
  uri: uri.href,
149
146
  mimeType: artifact.mimeType,
150
147
  blob: artifact.bytes.toString('base64'),
148
+ _meta,
151
149
  },
152
150
  ],
153
151
  };
154
152
  });
155
- server.registerResource('transaction-manifest', new ResourceTemplate('hoi4-agent://workspace/{workspaceId}/transaction/{transactionId}', {
156
- list: undefined,
157
- }), {
158
- title: 'Transaction manifest',
159
- description: 'Declarative transaction and rollback status',
160
- mimeType: 'application/json',
161
- }, async (uri, { workspaceId }, extra) => {
162
- extra.signal.throwIfAborted();
163
- assertResourceSelectors(uri, ['offset', 'length']);
164
- const identity = transactionResourceIdentity(uri);
165
- if (identity.workspaceId !== String(workspaceId)) {
166
- throw new ServiceError('TRANSACTION_WORKSPACE_MISMATCH', 'Transaction resource does not belong to this workspace');
167
- }
168
- const offset = artifactRangeParameter(uri, 'offset', 0, 0);
169
- const length = Math.min(artifactResourceLimit, artifactRangeParameter(uri, 'length', artifactResourceLimit, 1));
170
- const manifestRange = await engine.transactions.readManifestRange(identity.workspaceId, identity.transactionId, { offset, length }, context.principal, extra.signal);
171
- extra.signal.throwIfAborted();
172
- const complete = offset === 0 && manifestRange.bytes.length === manifestRange.totalSize;
173
- return {
174
- contents: [
175
- complete
176
- ? {
177
- uri: uri.href,
178
- mimeType: 'application/json',
179
- text: manifestRange.bytes.toString('utf8'),
180
- }
181
- : {
182
- uri: uri.href,
183
- mimeType: 'application/json',
184
- blob: manifestRange.bytes.toString('base64'),
185
- },
186
- ],
187
- };
188
- });
189
- const packageRoot = path.resolve(import.meta.dirname, '../../../..');
190
- const documentation = new Map([
191
- ['agent-integration', 'docs/agent-integration.md'],
192
- ['architecture', 'docs/architecture.md'],
193
- ['artifacts', 'docs/artifacts.md'],
194
- ['compatibility', 'docs/compatibility.md'],
195
- ['configuration', 'docs/configuration.md'],
196
- ['focus-workflow', 'docs/focus-workflow.md'],
197
- ['gui-workflow', 'docs/gui-workflow.md'],
198
- ['limitations', 'docs/limitations.md'],
199
- ['map-workflow', 'docs/map-workflow.md'],
200
- ['security', 'docs/security.md'],
201
- ['self-hosting', 'docs/self-hosting.md'],
202
- ['testing', 'docs/testing.md'],
203
- ['transactions', 'docs/transactions.md'],
204
- ['troubleshooting', 'docs/troubleshooting.md'],
205
- ]);
206
- server.registerResource('documentation', new ResourceTemplate('hoi4-agent://docs/{name}', {
207
- list: () => ({
208
- resources: [...documentation.keys()].map((name) => ({
209
- uri: `hoi4-agent://docs/${name}`,
210
- name: `${name} documentation`,
211
- mimeType: 'text/markdown',
212
- })),
213
- }),
214
- }), {
215
- title: 'HOI4 Agent Tools documentation',
216
- description: 'Versioned package documentation for coding agents',
217
- mimeType: 'text/markdown',
218
- }, async (uri, { name }, extra) => {
219
- extra.signal.throwIfAborted();
220
- assertResourceSelectors(uri, []);
221
- const relative = documentation.get(String(name));
222
- if (relative === undefined)
223
- throw new ServiceError('RESOURCE_NOT_FOUND', 'Unknown document');
224
- const contents = await readFile(path.join(packageRoot, relative), 'utf8');
225
- extra.signal.throwIfAborted();
226
- return {
227
- contents: [
228
- {
229
- uri: uri.href,
230
- mimeType: 'text/markdown',
231
- text: contents,
232
- },
233
- ],
234
- };
235
- });
236
- const schemas = new Map([
237
- ['configuration', 'schemas/configuration.schema.json'],
238
- ['continuous-focus-palette', 'schemas/continuous-focus-palette.schema.json'],
239
- ['focus-plan', 'schemas/focus-plan.schema.json'],
240
- ['focus-planning-sidecar', 'schemas/focus-planning-sidecar.schema.json'],
241
- ['gui-animation-source', 'schemas/gui-animation-source.schema.json'],
242
- ['gui-helper', 'schemas/gui-helper.schema.json'],
243
- ['gui-scenario', 'schemas/gui-scenario.schema.json'],
244
- ['map-operation', 'schemas/map-operation.schema.json'],
245
- ['operation-result', 'schemas/operation-result.schema.json'],
246
- ['transaction-manifest', 'schemas/transaction-manifest.schema.json'],
247
- ]);
248
- server.registerResource('schema', new ResourceTemplate('hoi4-agent://schema/{name}', {
249
- list: () => ({
250
- resources: [...schemas.keys()].map((name) => ({
251
- uri: `hoi4-agent://schema/${name}`,
252
- name: `${name} JSON Schema`,
253
- mimeType: 'application/schema+json',
254
- })),
255
- }),
256
- }), {
257
- title: 'Public JSON Schema',
258
- description: 'Versioned strict schemas shipped with the package',
259
- mimeType: 'application/schema+json',
260
- }, async (uri, { name }, extra) => {
261
- extra.signal.throwIfAborted();
262
- assertResourceSelectors(uri, []);
263
- const relative = schemas.get(String(name));
264
- if (relative === undefined)
265
- throw new ServiceError('RESOURCE_NOT_FOUND', 'Unknown schema');
266
- const contents = await readFile(path.join(packageRoot, relative), 'utf8');
267
- extra.signal.throwIfAborted();
268
- return {
269
- contents: [
270
- {
271
- uri: uri.href,
272
- mimeType: 'application/schema+json',
273
- text: contents,
274
- },
275
- ],
276
- };
277
- });
278
153
  }
279
- //# sourceMappingURL=register.js.map
@@ -136,10 +136,7 @@ export async function authenticate(authorization, configuration, requiredScopes
136
136
  principal: configured.principal,
137
137
  clientId: configured.principal,
138
138
  credentialId: presentedCredentialId,
139
- scopes: [
140
- 'hoi4:read',
141
- ...(configuration.writePolicy === 'transactions' ? ['hoi4:write'] : []),
142
- ],
139
+ scopes: ['hoi4:read', 'hoi4:write'],
143
140
  };
144
141
  requireScopes(principal.scopes, normalizedRequiredScopes);
145
142
  return principal;
@@ -231,4 +228,3 @@ export function protectedResourceMetadata(configuration) {
231
228
  resource_name: 'HOI4 Agent Tools',
232
229
  };
233
230
  }
234
- //# sourceMappingURL=auth.js.map