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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (416) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/LICENSE +201 -0
  3. package/README.md +140 -2
  4. package/SECURITY.md +17 -0
  5. package/dist/bin/http.d.ts +3 -0
  6. package/dist/bin/http.d.ts.map +1 -0
  7. package/dist/bin/http.js +27 -0
  8. package/dist/bin/http.js.map +1 -0
  9. package/dist/bin/setup.d.ts +3 -0
  10. package/dist/bin/setup.d.ts.map +1 -0
  11. package/dist/bin/setup.js +188 -0
  12. package/dist/bin/setup.js.map +1 -0
  13. package/dist/bin/stdio.d.ts +3 -0
  14. package/dist/bin/stdio.d.ts.map +1 -0
  15. package/dist/bin/stdio.js +36 -0
  16. package/dist/bin/stdio.js.map +1 -0
  17. package/dist/hoi4_agent_tools/core/artifacts.d.ts +117 -0
  18. package/dist/hoi4_agent_tools/core/artifacts.d.ts.map +1 -0
  19. package/dist/hoi4_agent_tools/core/artifacts.js +1047 -0
  20. package/dist/hoi4_agent_tools/core/artifacts.js.map +1 -0
  21. package/dist/hoi4_agent_tools/core/canonical.d.ts +13 -0
  22. package/dist/hoi4_agent_tools/core/canonical.d.ts.map +1 -0
  23. package/dist/hoi4_agent_tools/core/canonical.js +41 -0
  24. package/dist/hoi4_agent_tools/core/canonical.js.map +1 -0
  25. package/dist/hoi4_agent_tools/core/configuration.d.ts +137 -0
  26. package/dist/hoi4_agent_tools/core/configuration.d.ts.map +1 -0
  27. package/dist/hoi4_agent_tools/core/configuration.js +383 -0
  28. package/dist/hoi4_agent_tools/core/configuration.js.map +1 -0
  29. package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts +18 -0
  30. package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts.map +1 -0
  31. package/dist/hoi4_agent_tools/core/diagnostic-collector.js +45 -0
  32. package/dist/hoi4_agent_tools/core/diagnostic-collector.js.map +1 -0
  33. package/dist/hoi4_agent_tools/core/diagnostics.d.ts +26 -0
  34. package/dist/hoi4_agent_tools/core/diagnostics.d.ts.map +1 -0
  35. package/dist/hoi4_agent_tools/core/diagnostics.js +25 -0
  36. package/dist/hoi4_agent_tools/core/diagnostics.js.map +1 -0
  37. package/dist/hoi4_agent_tools/core/diff.d.ts +22 -0
  38. package/dist/hoi4_agent_tools/core/diff.d.ts.map +1 -0
  39. package/dist/hoi4_agent_tools/core/diff.js +93 -0
  40. package/dist/hoi4_agent_tools/core/diff.js.map +1 -0
  41. package/dist/hoi4_agent_tools/core/engine.d.ts +56 -0
  42. package/dist/hoi4_agent_tools/core/engine.d.ts.map +1 -0
  43. package/dist/hoi4_agent_tools/core/engine.js +319 -0
  44. package/dist/hoi4_agent_tools/core/engine.js.map +1 -0
  45. package/dist/hoi4_agent_tools/core/image-diff.d.ts +14 -0
  46. package/dist/hoi4_agent_tools/core/image-diff.d.ts.map +1 -0
  47. package/dist/hoi4_agent_tools/core/image-diff.js +121 -0
  48. package/dist/hoi4_agent_tools/core/image-diff.js.map +1 -0
  49. package/dist/hoi4_agent_tools/core/index.d.ts +64 -0
  50. package/dist/hoi4_agent_tools/core/index.d.ts.map +1 -0
  51. package/dist/hoi4_agent_tools/core/index.js +963 -0
  52. package/dist/hoi4_agent_tools/core/index.js.map +1 -0
  53. package/dist/hoi4_agent_tools/core/index.public.d.ts +16 -0
  54. package/dist/hoi4_agent_tools/core/index.public.d.ts.map +1 -0
  55. package/dist/hoi4_agent_tools/core/index.public.js +16 -0
  56. package/dist/hoi4_agent_tools/core/index.public.js.map +1 -0
  57. package/dist/hoi4_agent_tools/core/render-budget.d.ts +51 -0
  58. package/dist/hoi4_agent_tools/core/render-budget.d.ts.map +1 -0
  59. package/dist/hoi4_agent_tools/core/render-budget.js +109 -0
  60. package/dist/hoi4_agent_tools/core/render-budget.js.map +1 -0
  61. package/dist/hoi4_agent_tools/core/result.d.ts +45 -0
  62. package/dist/hoi4_agent_tools/core/result.d.ts.map +1 -0
  63. package/dist/hoi4_agent_tools/core/result.js +26 -0
  64. package/dist/hoi4_agent_tools/core/result.js.map +1 -0
  65. package/dist/hoi4_agent_tools/core/scanner.d.ts +28 -0
  66. package/dist/hoi4_agent_tools/core/scanner.d.ts.map +1 -0
  67. package/dist/hoi4_agent_tools/core/scanner.js +136 -0
  68. package/dist/hoi4_agent_tools/core/scanner.js.map +1 -0
  69. package/dist/hoi4_agent_tools/core/server-state.d.ts +31 -0
  70. package/dist/hoi4_agent_tools/core/server-state.d.ts.map +1 -0
  71. package/dist/hoi4_agent_tools/core/server-state.js +413 -0
  72. package/dist/hoi4_agent_tools/core/server-state.js.map +1 -0
  73. package/dist/hoi4_agent_tools/core/source/encoding.d.ts +10 -0
  74. package/dist/hoi4_agent_tools/core/source/encoding.d.ts.map +1 -0
  75. package/dist/hoi4_agent_tools/core/source/encoding.js +54 -0
  76. package/dist/hoi4_agent_tools/core/source/encoding.js.map +1 -0
  77. package/dist/hoi4_agent_tools/core/source/index.d.ts +7 -0
  78. package/dist/hoi4_agent_tools/core/source/index.d.ts.map +1 -0
  79. package/dist/hoi4_agent_tools/core/source/index.js +7 -0
  80. package/dist/hoi4_agent_tools/core/source/index.js.map +1 -0
  81. package/dist/hoi4_agent_tools/core/source/lexer.d.ts +30 -0
  82. package/dist/hoi4_agent_tools/core/source/lexer.d.ts.map +1 -0
  83. package/dist/hoi4_agent_tools/core/source/lexer.js +266 -0
  84. package/dist/hoi4_agent_tools/core/source/lexer.js.map +1 -0
  85. package/dist/hoi4_agent_tools/core/source/limits.d.ts +21 -0
  86. package/dist/hoi4_agent_tools/core/source/limits.d.ts.map +1 -0
  87. package/dist/hoi4_agent_tools/core/source/limits.js +49 -0
  88. package/dist/hoi4_agent_tools/core/source/limits.js.map +1 -0
  89. package/dist/hoi4_agent_tools/core/source/localisation.d.ts +20 -0
  90. package/dist/hoi4_agent_tools/core/source/localisation.d.ts.map +1 -0
  91. package/dist/hoi4_agent_tools/core/source/localisation.js +163 -0
  92. package/dist/hoi4_agent_tools/core/source/localisation.js.map +1 -0
  93. package/dist/hoi4_agent_tools/core/source/parser.d.ts +44 -0
  94. package/dist/hoi4_agent_tools/core/source/parser.d.ts.map +1 -0
  95. package/dist/hoi4_agent_tools/core/source/parser.js +334 -0
  96. package/dist/hoi4_agent_tools/core/source/parser.js.map +1 -0
  97. package/dist/hoi4_agent_tools/core/source/rewrite.d.ts +10 -0
  98. package/dist/hoi4_agent_tools/core/source/rewrite.d.ts.map +1 -0
  99. package/dist/hoi4_agent_tools/core/source/rewrite.js +28 -0
  100. package/dist/hoi4_agent_tools/core/source/rewrite.js.map +1 -0
  101. package/dist/hoi4_agent_tools/core/svg-text.d.ts +34 -0
  102. package/dist/hoi4_agent_tools/core/svg-text.d.ts.map +1 -0
  103. package/dist/hoi4_agent_tools/core/svg-text.js +127 -0
  104. package/dist/hoi4_agent_tools/core/svg-text.js.map +1 -0
  105. package/dist/hoi4_agent_tools/core/transaction-limits.d.ts +9 -0
  106. package/dist/hoi4_agent_tools/core/transaction-limits.d.ts.map +1 -0
  107. package/dist/hoi4_agent_tools/core/transaction-limits.js +9 -0
  108. package/dist/hoi4_agent_tools/core/transaction-limits.js.map +1 -0
  109. package/dist/hoi4_agent_tools/core/transactions.d.ts +162 -0
  110. package/dist/hoi4_agent_tools/core/transactions.d.ts.map +1 -0
  111. package/dist/hoi4_agent_tools/core/transactions.js +1181 -0
  112. package/dist/hoi4_agent_tools/core/transactions.js.map +1 -0
  113. package/dist/hoi4_agent_tools/core/workspace.d.ts +68 -0
  114. package/dist/hoi4_agent_tools/core/workspace.d.ts.map +1 -0
  115. package/dist/hoi4_agent_tools/core/workspace.js +794 -0
  116. package/dist/hoi4_agent_tools/core/workspace.js.map +1 -0
  117. package/dist/hoi4_agent_tools/focus/compiler.d.ts +9 -0
  118. package/dist/hoi4_agent_tools/focus/compiler.d.ts.map +1 -0
  119. package/dist/hoi4_agent_tools/focus/compiler.js +273 -0
  120. package/dist/hoi4_agent_tools/focus/compiler.js.map +1 -0
  121. package/dist/hoi4_agent_tools/focus/continuous-render.d.ts +32 -0
  122. package/dist/hoi4_agent_tools/focus/continuous-render.d.ts.map +1 -0
  123. package/dist/hoi4_agent_tools/focus/continuous-render.js +179 -0
  124. package/dist/hoi4_agent_tools/focus/continuous-render.js.map +1 -0
  125. package/dist/hoi4_agent_tools/focus/drift.d.ts +22 -0
  126. package/dist/hoi4_agent_tools/focus/drift.d.ts.map +1 -0
  127. package/dist/hoi4_agent_tools/focus/drift.js +124 -0
  128. package/dist/hoi4_agent_tools/focus/drift.js.map +1 -0
  129. package/dist/hoi4_agent_tools/focus/geometry.d.ts +17 -0
  130. package/dist/hoi4_agent_tools/focus/geometry.d.ts.map +1 -0
  131. package/dist/hoi4_agent_tools/focus/geometry.js +35 -0
  132. package/dist/hoi4_agent_tools/focus/geometry.js.map +1 -0
  133. package/dist/hoi4_agent_tools/focus/importer.d.ts +9 -0
  134. package/dist/hoi4_agent_tools/focus/importer.d.ts.map +1 -0
  135. package/dist/hoi4_agent_tools/focus/importer.js +732 -0
  136. package/dist/hoi4_agent_tools/focus/importer.js.map +1 -0
  137. package/dist/hoi4_agent_tools/focus/index.d.ts +14 -0
  138. package/dist/hoi4_agent_tools/focus/index.d.ts.map +1 -0
  139. package/dist/hoi4_agent_tools/focus/index.js +14 -0
  140. package/dist/hoi4_agent_tools/focus/index.js.map +1 -0
  141. package/dist/hoi4_agent_tools/focus/layout.d.ts +5 -0
  142. package/dist/hoi4_agent_tools/focus/layout.d.ts.map +1 -0
  143. package/dist/hoi4_agent_tools/focus/layout.js +653 -0
  144. package/dist/hoi4_agent_tools/focus/layout.js.map +1 -0
  145. package/dist/hoi4_agent_tools/focus/limits.d.ts +9 -0
  146. package/dist/hoi4_agent_tools/focus/limits.d.ts.map +1 -0
  147. package/dist/hoi4_agent_tools/focus/limits.js +9 -0
  148. package/dist/hoi4_agent_tools/focus/limits.js.map +1 -0
  149. package/dist/hoi4_agent_tools/focus/lint.d.ts +14 -0
  150. package/dist/hoi4_agent_tools/focus/lint.d.ts.map +1 -0
  151. package/dist/hoi4_agent_tools/focus/lint.js +839 -0
  152. package/dist/hoi4_agent_tools/focus/lint.js.map +1 -0
  153. package/dist/hoi4_agent_tools/focus/model.d.ts +303 -0
  154. package/dist/hoi4_agent_tools/focus/model.d.ts.map +1 -0
  155. package/dist/hoi4_agent_tools/focus/model.js +20 -0
  156. package/dist/hoi4_agent_tools/focus/model.js.map +1 -0
  157. package/dist/hoi4_agent_tools/focus/native-effects.d.ts +9 -0
  158. package/dist/hoi4_agent_tools/focus/native-effects.d.ts.map +1 -0
  159. package/dist/hoi4_agent_tools/focus/native-effects.js +563 -0
  160. package/dist/hoi4_agent_tools/focus/native-effects.js.map +1 -0
  161. package/dist/hoi4_agent_tools/focus/planning.d.ts +15 -0
  162. package/dist/hoi4_agent_tools/focus/planning.d.ts.map +1 -0
  163. package/dist/hoi4_agent_tools/focus/planning.js +241 -0
  164. package/dist/hoi4_agent_tools/focus/planning.js.map +1 -0
  165. package/dist/hoi4_agent_tools/focus/presentation.d.ts +24 -0
  166. package/dist/hoi4_agent_tools/focus/presentation.d.ts.map +1 -0
  167. package/dist/hoi4_agent_tools/focus/presentation.js +204 -0
  168. package/dist/hoi4_agent_tools/focus/presentation.js.map +1 -0
  169. package/dist/hoi4_agent_tools/focus/render.d.ts +35 -0
  170. package/dist/hoi4_agent_tools/focus/render.d.ts.map +1 -0
  171. package/dist/hoi4_agent_tools/focus/render.js +491 -0
  172. package/dist/hoi4_agent_tools/focus/render.js.map +1 -0
  173. package/dist/hoi4_agent_tools/focus/service.d.ts +82 -0
  174. package/dist/hoi4_agent_tools/focus/service.d.ts.map +1 -0
  175. package/dist/hoi4_agent_tools/focus/service.js +492 -0
  176. package/dist/hoi4_agent_tools/focus/service.js.map +1 -0
  177. package/dist/hoi4_agent_tools/focus/source-update.d.ts +6 -0
  178. package/dist/hoi4_agent_tools/focus/source-update.d.ts.map +1 -0
  179. package/dist/hoi4_agent_tools/focus/source-update.js +328 -0
  180. package/dist/hoi4_agent_tools/focus/source-update.js.map +1 -0
  181. package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts +37 -0
  182. package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts.map +1 -0
  183. package/dist/hoi4_agent_tools/gui/animation-manifest.js +66 -0
  184. package/dist/hoi4_agent_tools/gui/animation-manifest.js.map +1 -0
  185. package/dist/hoi4_agent_tools/gui/assets.d.ts +71 -0
  186. package/dist/hoi4_agent_tools/gui/assets.d.ts.map +1 -0
  187. package/dist/hoi4_agent_tools/gui/assets.js +629 -0
  188. package/dist/hoi4_agent_tools/gui/assets.js.map +1 -0
  189. package/dist/hoi4_agent_tools/gui/dds.d.ts +17 -0
  190. package/dist/hoi4_agent_tools/gui/dds.d.ts.map +1 -0
  191. package/dist/hoi4_agent_tools/gui/dds.js +245 -0
  192. package/dist/hoi4_agent_tools/gui/dds.js.map +1 -0
  193. package/dist/hoi4_agent_tools/gui/helpers.d.ts +101 -0
  194. package/dist/hoi4_agent_tools/gui/helpers.d.ts.map +1 -0
  195. package/dist/hoi4_agent_tools/gui/helpers.js +1072 -0
  196. package/dist/hoi4_agent_tools/gui/helpers.js.map +1 -0
  197. package/dist/hoi4_agent_tools/gui/index.d.ts +15 -0
  198. package/dist/hoi4_agent_tools/gui/index.d.ts.map +1 -0
  199. package/dist/hoi4_agent_tools/gui/index.js +15 -0
  200. package/dist/hoi4_agent_tools/gui/index.js.map +1 -0
  201. package/dist/hoi4_agent_tools/gui/layout.d.ts +6 -0
  202. package/dist/hoi4_agent_tools/gui/layout.d.ts.map +1 -0
  203. package/dist/hoi4_agent_tools/gui/layout.js +753 -0
  204. package/dist/hoi4_agent_tools/gui/layout.js.map +1 -0
  205. package/dist/hoi4_agent_tools/gui/limits.d.ts +25 -0
  206. package/dist/hoi4_agent_tools/gui/limits.d.ts.map +1 -0
  207. package/dist/hoi4_agent_tools/gui/limits.js +27 -0
  208. package/dist/hoi4_agent_tools/gui/limits.js.map +1 -0
  209. package/dist/hoi4_agent_tools/gui/renderer.d.ts +18 -0
  210. package/dist/hoi4_agent_tools/gui/renderer.d.ts.map +1 -0
  211. package/dist/hoi4_agent_tools/gui/renderer.js +388 -0
  212. package/dist/hoi4_agent_tools/gui/renderer.js.map +1 -0
  213. package/dist/hoi4_agent_tools/gui/scenario.d.ts +66 -0
  214. package/dist/hoi4_agent_tools/gui/scenario.d.ts.map +1 -0
  215. package/dist/hoi4_agent_tools/gui/scenario.js +191 -0
  216. package/dist/hoi4_agent_tools/gui/scenario.js.map +1 -0
  217. package/dist/hoi4_agent_tools/gui/source-graph.d.ts +7 -0
  218. package/dist/hoi4_agent_tools/gui/source-graph.d.ts.map +1 -0
  219. package/dist/hoi4_agent_tools/gui/source-graph.js +1074 -0
  220. package/dist/hoi4_agent_tools/gui/source-graph.js.map +1 -0
  221. package/dist/hoi4_agent_tools/gui/source-patch.d.ts +13 -0
  222. package/dist/hoi4_agent_tools/gui/source-patch.d.ts.map +1 -0
  223. package/dist/hoi4_agent_tools/gui/source-patch.js +90 -0
  224. package/dist/hoi4_agent_tools/gui/source-patch.js.map +1 -0
  225. package/dist/hoi4_agent_tools/gui/studio.d.ts +86 -0
  226. package/dist/hoi4_agent_tools/gui/studio.d.ts.map +1 -0
  227. package/dist/hoi4_agent_tools/gui/studio.js +830 -0
  228. package/dist/hoi4_agent_tools/gui/studio.js.map +1 -0
  229. package/dist/hoi4_agent_tools/gui/tga.d.ts +16 -0
  230. package/dist/hoi4_agent_tools/gui/tga.d.ts.map +1 -0
  231. package/dist/hoi4_agent_tools/gui/tga.js +157 -0
  232. package/dist/hoi4_agent_tools/gui/tga.js.map +1 -0
  233. package/dist/hoi4_agent_tools/gui/types.d.ts +322 -0
  234. package/dist/hoi4_agent_tools/gui/types.d.ts.map +1 -0
  235. package/dist/hoi4_agent_tools/gui/types.js +19 -0
  236. package/dist/hoi4_agent_tools/gui/types.js.map +1 -0
  237. package/dist/hoi4_agent_tools/gui/validators.d.ts +8 -0
  238. package/dist/hoi4_agent_tools/gui/validators.d.ts.map +1 -0
  239. package/dist/hoi4_agent_tools/gui/validators.js +951 -0
  240. package/dist/hoi4_agent_tools/gui/validators.js.map +1 -0
  241. package/dist/hoi4_agent_tools/map/bmp.d.ts +62 -0
  242. package/dist/hoi4_agent_tools/map/bmp.d.ts.map +1 -0
  243. package/dist/hoi4_agent_tools/map/bmp.js +363 -0
  244. package/dist/hoi4_agent_tools/map/bmp.js.map +1 -0
  245. package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts +5 -0
  246. package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts.map +1 -0
  247. package/dist/hoi4_agent_tools/map/diagnostic-limit.js +21 -0
  248. package/dist/hoi4_agent_tools/map/diagnostic-limit.js.map +1 -0
  249. package/dist/hoi4_agent_tools/map/index.d.ts +8 -0
  250. package/dist/hoi4_agent_tools/map/index.d.ts.map +1 -0
  251. package/dist/hoi4_agent_tools/map/index.js +8 -0
  252. package/dist/hoi4_agent_tools/map/index.js.map +1 -0
  253. package/dist/hoi4_agent_tools/map/limits.d.ts +13 -0
  254. package/dist/hoi4_agent_tools/map/limits.d.ts.map +1 -0
  255. package/dist/hoi4_agent_tools/map/limits.js +13 -0
  256. package/dist/hoi4_agent_tools/map/limits.js.map +1 -0
  257. package/dist/hoi4_agent_tools/map/model.d.ts +269 -0
  258. package/dist/hoi4_agent_tools/map/model.d.ts.map +1 -0
  259. package/dist/hoi4_agent_tools/map/model.js +1114 -0
  260. package/dist/hoi4_agent_tools/map/model.js.map +1 -0
  261. package/dist/hoi4_agent_tools/map/operations.d.ts +401 -0
  262. package/dist/hoi4_agent_tools/map/operations.d.ts.map +1 -0
  263. package/dist/hoi4_agent_tools/map/operations.js +2717 -0
  264. package/dist/hoi4_agent_tools/map/operations.js.map +1 -0
  265. package/dist/hoi4_agent_tools/map/render.d.ts +90 -0
  266. package/dist/hoi4_agent_tools/map/render.d.ts.map +1 -0
  267. package/dist/hoi4_agent_tools/map/render.js +759 -0
  268. package/dist/hoi4_agent_tools/map/render.js.map +1 -0
  269. package/dist/hoi4_agent_tools/map/service.d.ts +81 -0
  270. package/dist/hoi4_agent_tools/map/service.d.ts.map +1 -0
  271. package/dist/hoi4_agent_tools/map/service.js +695 -0
  272. package/dist/hoi4_agent_tools/map/service.js.map +1 -0
  273. package/dist/hoi4_agent_tools/map/validation.d.ts +23 -0
  274. package/dist/hoi4_agent_tools/map/validation.d.ts.map +1 -0
  275. package/dist/hoi4_agent_tools/map/validation.js +1177 -0
  276. package/dist/hoi4_agent_tools/map/validation.js.map +1 -0
  277. package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts +3 -0
  278. package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts.map +1 -0
  279. package/dist/hoi4_agent_tools/mcp/prompts/register.js +50 -0
  280. package/dist/hoi4_agent_tools/mcp/prompts/register.js.map +1 -0
  281. package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts +9 -0
  282. package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts.map +1 -0
  283. package/dist/hoi4_agent_tools/mcp/registry/metadata.js +10 -0
  284. package/dist/hoi4_agent_tools/mcp/registry/metadata.js.map +1 -0
  285. package/dist/hoi4_agent_tools/mcp/resources/register.d.ts +5 -0
  286. package/dist/hoi4_agent_tools/mcp/resources/register.d.ts.map +1 -0
  287. package/dist/hoi4_agent_tools/mcp/resources/register.js +278 -0
  288. package/dist/hoi4_agent_tools/mcp/resources/register.js.map +1 -0
  289. package/dist/hoi4_agent_tools/mcp/security/auth.d.ts +24 -0
  290. package/dist/hoi4_agent_tools/mcp/security/auth.d.ts.map +1 -0
  291. package/dist/hoi4_agent_tools/mcp/security/auth.js +234 -0
  292. package/dist/hoi4_agent_tools/mcp/security/auth.js.map +1 -0
  293. package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts +35 -0
  294. package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts.map +1 -0
  295. package/dist/hoi4_agent_tools/mcp/server/base-tools.js +835 -0
  296. package/dist/hoi4_agent_tools/mcp/server/base-tools.js.map +1 -0
  297. package/dist/hoi4_agent_tools/mcp/server/create.d.ts +5 -0
  298. package/dist/hoi4_agent_tools/mcp/server/create.d.ts.map +1 -0
  299. package/dist/hoi4_agent_tools/mcp/server/create.js +26 -0
  300. package/dist/hoi4_agent_tools/mcp/server/create.js.map +1 -0
  301. package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts +133 -0
  302. package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts.map +1 -0
  303. package/dist/hoi4_agent_tools/mcp/server/output-schemas.js +127 -0
  304. package/dist/hoi4_agent_tools/mcp/server/output-schemas.js.map +1 -0
  305. package/dist/hoi4_agent_tools/mcp/server/progress.d.ts +8 -0
  306. package/dist/hoi4_agent_tools/mcp/server/progress.d.ts.map +1 -0
  307. package/dist/hoi4_agent_tools/mcp/server/progress.js +21 -0
  308. package/dist/hoi4_agent_tools/mcp/server/progress.js.map +1 -0
  309. package/dist/hoi4_agent_tools/mcp/server/result.d.ts +232 -0
  310. package/dist/hoi4_agent_tools/mcp/server/result.d.ts.map +1 -0
  311. package/dist/hoi4_agent_tools/mcp/server/result.js +353 -0
  312. package/dist/hoi4_agent_tools/mcp/server/result.js.map +1 -0
  313. package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts +5 -0
  314. package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts.map +1 -0
  315. package/dist/hoi4_agent_tools/mcp/tools/focus.js +1059 -0
  316. package/dist/hoi4_agent_tools/mcp/tools/focus.js.map +1 -0
  317. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts +111 -0
  318. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts.map +1 -0
  319. package/dist/hoi4_agent_tools/mcp/tools/gui.js +598 -0
  320. package/dist/hoi4_agent_tools/mcp/tools/gui.js.map +1 -0
  321. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts +5 -0
  322. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts.map +1 -0
  323. package/dist/hoi4_agent_tools/mcp/tools/map.js +685 -0
  324. package/dist/hoi4_agent_tools/mcp/tools/map.js.map +1 -0
  325. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts +58 -0
  326. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts.map +1 -0
  327. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js +181 -0
  328. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js.map +1 -0
  329. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts +26 -0
  330. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts.map +1 -0
  331. package/dist/hoi4_agent_tools/mcp/transports/event-store.js +86 -0
  332. package/dist/hoi4_agent_tools/mcp/transports/event-store.js.map +1 -0
  333. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts +28 -0
  334. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts.map +1 -0
  335. package/dist/hoi4_agent_tools/mcp/transports/http.js +744 -0
  336. package/dist/hoi4_agent_tools/mcp/transports/http.js.map +1 -0
  337. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts +15 -0
  338. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts.map +1 -0
  339. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js +51 -0
  340. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js.map +1 -0
  341. package/dist/hoi4_agent_tools/runtime.d.ts +4 -0
  342. package/dist/hoi4_agent_tools/runtime.d.ts.map +1 -0
  343. package/dist/hoi4_agent_tools/runtime.js +27 -0
  344. package/dist/hoi4_agent_tools/runtime.js.map +1 -0
  345. package/dist/hoi4_agent_tools/schemas/common.d.ts +74 -0
  346. package/dist/hoi4_agent_tools/schemas/common.d.ts.map +1 -0
  347. package/dist/hoi4_agent_tools/schemas/common.js +51 -0
  348. package/dist/hoi4_agent_tools/schemas/common.js.map +1 -0
  349. package/dist/hoi4_agent_tools/schemas/focus.d.ts +784 -0
  350. package/dist/hoi4_agent_tools/schemas/focus.d.ts.map +1 -0
  351. package/dist/hoi4_agent_tools/schemas/focus.js +330 -0
  352. package/dist/hoi4_agent_tools/schemas/focus.js.map +1 -0
  353. package/dist/hoi4_agent_tools/schemas/index.d.ts +5 -0
  354. package/dist/hoi4_agent_tools/schemas/index.d.ts.map +1 -0
  355. package/dist/hoi4_agent_tools/schemas/index.js +5 -0
  356. package/dist/hoi4_agent_tools/schemas/index.js.map +1 -0
  357. package/dist/hoi4_agent_tools/schemas/map.d.ts +654 -0
  358. package/dist/hoi4_agent_tools/schemas/map.d.ts.map +1 -0
  359. package/dist/hoi4_agent_tools/schemas/map.js +570 -0
  360. package/dist/hoi4_agent_tools/schemas/map.js.map +1 -0
  361. package/dist/hoi4_agent_tools/schemas/transaction.d.ts +259 -0
  362. package/dist/hoi4_agent_tools/schemas/transaction.d.ts.map +1 -0
  363. package/dist/hoi4_agent_tools/schemas/transaction.js +104 -0
  364. package/dist/hoi4_agent_tools/schemas/transaction.js.map +1 -0
  365. package/dist/hoi4_agent_tools/version.d.ts +6 -0
  366. package/dist/hoi4_agent_tools/version.d.ts.map +1 -0
  367. package/dist/hoi4_agent_tools/version.js +7 -0
  368. package/dist/hoi4_agent_tools/version.js.map +1 -0
  369. package/dist/index.d.ts +3 -0
  370. package/dist/index.d.ts.map +1 -0
  371. package/dist/index.js +3 -0
  372. package/dist/index.js.map +1 -0
  373. package/docs/README.md +22 -0
  374. package/docs/adr/0001-runtime-and-language.md +16 -0
  375. package/docs/adr/0002-lossless-source-model.md +18 -0
  376. package/docs/adr/0003-image-and-font-codecs.md +18 -0
  377. package/docs/adr/0004-focus-layout.md +16 -0
  378. package/docs/adr/0005-offline-rendering.md +18 -0
  379. package/docs/adr/0006-mcp-sdk-and-protocol.md +16 -0
  380. package/docs/adr/0007-storage-and-transactions.md +24 -0
  381. package/docs/adr/0008-test-strategy.md +18 -0
  382. package/docs/adr/0009-packaging-and-registry.md +16 -0
  383. package/docs/adr/0010-unsupported-and-refusal-policy.md +18 -0
  384. package/docs/adr/0011-http-security.md +16 -0
  385. package/docs/adr/README.md +13 -0
  386. package/docs/architecture.md +60 -0
  387. package/docs/artifacts.md +133 -0
  388. package/docs/compatibility.md +33 -0
  389. package/docs/completion-report.md +69 -0
  390. package/docs/configuration.md +285 -0
  391. package/docs/focus-workflow.md +68 -0
  392. package/docs/gui-workflow.md +121 -0
  393. package/docs/limitations.md +30 -0
  394. package/docs/map-workflow.md +89 -0
  395. package/docs/performance.md +117 -0
  396. package/docs/release.md +200 -0
  397. package/docs/research/mcp-2026-07-10.md +46 -0
  398. package/docs/research/source-ledger.md +68 -0
  399. package/docs/security.md +139 -0
  400. package/docs/self-hosting.md +168 -0
  401. package/docs/testing.md +43 -0
  402. package/docs/third-party-notices.md +11 -0
  403. package/docs/transactions.md +162 -0
  404. package/docs/troubleshooting.md +46 -0
  405. package/package.json +98 -5
  406. package/schemas/configuration.schema.json +794 -0
  407. package/schemas/continuous-focus-palette.schema.json +325 -0
  408. package/schemas/focus-plan.schema.json +902 -0
  409. package/schemas/focus-planning-sidecar.schema.json +364 -0
  410. package/schemas/gui-animation-source.schema.json +176 -0
  411. package/schemas/gui-helper.schema.json +301 -0
  412. package/schemas/gui-scenario.schema.json +298 -0
  413. package/schemas/map-operation.schema.json +2284 -0
  414. package/schemas/operation-result.schema.json +344 -0
  415. package/schemas/transaction-manifest.schema.json +685 -0
  416. package/server.json +32 -0
@@ -0,0 +1,139 @@
1
+ # Security and threat model
2
+
3
+ ## Protected assets
4
+
5
+ - external mod source and binary map data;
6
+ - installed game and dependency references;
7
+ - transaction approval intent and rollback blobs;
8
+ - generated artifacts that may reveal source details;
9
+ - HTTP credentials and principal/workspace grants.
10
+
11
+ ## Trust boundaries
12
+
13
+ MCP input, file paths, manifest content, client annotations, session IDs, Origin/Host headers, and remote access tokens are untrusted. Tool annotations are descriptive hints. Prompts are guidance. Server-side policy is authoritative.
14
+
15
+ ## Filesystem controls
16
+
17
+ - Only registered roots are visible.
18
+ - Public paths are relative and canonicalized.
19
+ - Traversal, absolute paths, UNC/device paths, NULs, alternate data streams, ambiguous trailing characters, and device names are rejected.
20
+ - Existing symlinks and junctions are resolved; an escape outside the root is rejected.
21
+ - Artifact shards, transaction journals, blobs, and lock descendants are re-canonicalized before access. A symlink or junction observed in artifact/journal enumeration is rejected.
22
+ - Transaction mode requires an absolute `serverStateRoot` whose existing components are non-linked
23
+ and whose canonical target does not overlap any source, registration capability,
24
+ generated-storage root, or runtime-nominated root. Harmless native path-spelling aliases are
25
+ normalized only after the link check. Its random journal key and protected revision heads are
26
+ never returned through MCP.
27
+ - Writes target the canonical mod root only. Game, dependency, fixture, and unrelated user files are never writable.
28
+ - Runtime mod registration requires a separate, default-empty `writableRegistrationRoots`
29
+ capability. A caller cannot relabel a game/dependency path from the read-only
30
+ `registrationRoots` allowlist as a mod.
31
+ - Artifact URIs are opaque and authorization-checked; filesystem paths are not placed in MCP responses.
32
+
33
+ These are application checks, not a kernel-enforced filesystem sandbox. The operator must prevent
34
+ hostile operating-system principals from concurrently replacing directories, symlinks, junctions,
35
+ mounts, or files inside registered and generated roots between validation and I/O. Such an actor
36
+ already has direct filesystem authority and is outside the application security boundary. The
37
+ server detects normal stale-source changes and observed link escapes, but does not claim
38
+ race-proof `openat`-style containment or operating-system transaction atomicity against hostile
39
+ concurrent mutation.
40
+
41
+ ## Write controls
42
+
43
+ Read-only is the default. A write requires global and workspace enablement, a validated dry run, a persisted transaction, exact plan hash, separate apply call, unexpired principal/workspace binding, unchanged source hashes, and a workspace lock. There is no command execution field. Stale apply and rollback operations fail closed.
44
+
45
+ Runtime registration definitions and raw paths are not persisted. The canonical artifact root does
46
+ retain an atomically created ownership claim containing only domain-separated SHA-256 workspace and
47
+ owner bindings. Re-registration restores that binding only for the same canonical workspace and
48
+ runtime principal; malformed, linked, raced, aliased, cross-principal, and cross-workspace claims
49
+ fail closed. A failed journal recovery removes only the in-memory registration, never its persistent
50
+ claim or existing generated data. Statically configured workspaces do not use runtime claims and
51
+ remain shared according to their operator-reviewed principal grants.
52
+
53
+ Every artifact provenance manifest includes the resolved workspace identity and its configured or
54
+ runtime owner identity in the immutable provenance hash. List, describe, and resource-read paths
55
+ verify both values before returning metadata or bytes. Reusing a physical artifact store through a
56
+ different workspace or owner therefore cannot expose prior evidence; unbound legacy or malformed
57
+ manifests are rejected rather than migrated or deleted implicitly.
58
+
59
+ Transaction manifests are authenticated with HMAC-SHA-256 over the complete canonical manifest,
60
+ excluding only the authentication tag. The 256-bit random key lives beneath `serverStateRoot`, not
61
+ in a workspace or public configuration value. Protected revision heads prevent replay of an older
62
+ valid manifest. A cache-first crash may reconcile only an authenticated exact next revision; a
63
+ missing head, revision gap, altered expiry/state/failure/rollback field, or recomputed public hash
64
+ fails closed. No HMAC key is derived from public workspace data.
65
+
66
+ Read-only transaction operations never repair protected state. Cache-first successor promotion is
67
+ confined to startup recovery and authorized write paths. Artifact manifests are capped at 1 MiB and
68
+ transaction manifests at 16 MiB before parsing; transaction resource ranges use a bounded verified
69
+ byte cache instead of repeatedly rebuilding the authenticated object.
70
+
71
+ ## HTTP controls
72
+
73
+ - Every POST, GET, and DELETE request to `/mcp` is authenticated; only standards-required OAuth discovery metadata is public.
74
+ - Present Origin and Host are checked before MCP dispatch. Security-sensitive singleton fields are counted from the raw HTTP header list before Node normalization, so duplicate Host, Authorization, Origin, content metadata, forwarding identity, or MCP session/protocol fields fail closed. Absolute-form request targets must use an allowlisted authority identical to Host.
75
+ - Session IDs are secure random routing identifiers bound to the authenticated principal, an explicit OAuth client when present, the exact bearer credential's SHA-256 identifier, and the non-downgraded scope set; they are not credentials. A token without `client_id` or `azp` is credential-bound rather than being aliased to the subject.
76
+ - Missing, expired, cross-principal, or unknown sessions fail.
77
+ - Connection count, requests per socket, header/request/keep-alive time, JSON body size, admitted concurrency, request rate, session count, event streams, event history, and session lifetime are bounded.
78
+ - Admitted request concurrency is fixed at no more than two; configured body bytes multiplied by
79
+ concurrency cannot exceed 16 MiB.
80
+ - Static bearer tokens are loopback-only. A non-loopback listener or a non-loopback canonical `publicUrl` (including a loopback listener behind a public reverse proxy) requires HTTPS and OAuth/OIDC JWT signature, issuer, audience, algorithm, expiry, subject, and scope verification.
81
+ - Tokens are accepted only in the Authorization header and are never logged, forwarded, copied into a session, or exposed to MCP handlers. Only a one-way SHA-256 credential identifier is retained for session binding.
82
+ - Protected Resource Metadata is published for OAuth deployments and linked from OAuth `WWW-Authenticate` challenges.
83
+ - Initial 401 challenges identify the baseline scope. A write-scoped tool call made with a read token receives an HTTP 403 `insufficient_scope` challenge naming the baseline plus `hoi4:write`, before JSON-RPC dispatch.
84
+ - Streamable HTTP reserves concurrency before JSON parsing or token verification and applies a socket-address rate bucket before authentication, followed by an independent per-principal bucket after authentication. Host and any present Origin are rejected even earlier. Every `/mcp` POST must advertise unparameterized, positively weighted `application/json` and `text/event-stream` response media types, use the exact `application/json` request media type with an absent or `utf-8` charset, and use no content coding other than identity. GET requires an unparameterized, positively weighted `text/event-stream` range. Bodies are fatal-decoded as UTF-8 and parsed under the raw-wire `maxBodyBytes` ceiling; suffix types, malformed or ambiguous media parameters, encoded entities, replacement-decoded UTF-8, and parameter-only media-type mentions are rejected before SDK dispatch.
85
+ - `trustedProxyAddresses` contains exact IP addresses only and affects only derivation of the pre-auth rate-limit key; it does not enable general forwarded-header trust. `X-Forwarded-For` is ignored unless the direct socket peer exactly matches a configured address (IPv4-mapped IPv6 is normalized). For a trusted peer, a missing or invalid header is rejected and only the first comma-separated address is used.
86
+ - A reverse proxy must be the only network path to a proxied server, terminate TLS, overwrite client-supplied forwarding headers with a validated client IP, preserve Authorization/Origin/Host, and enforce edge connection, header, body, timeout, and rate limits. CIDR ranges, hostnames, and an unverified proxy chain are not inferred by the application.
87
+ - Every session request is reauthenticated and must present the exact credential that initialized the session; another token cannot take over merely because its subject or client claims match. OAuth refresh and scope step-up therefore initialize a new MCP session. Scope authority within a session remains monotonic, and handler-level write-scope checks remain in place as defense in depth.
88
+
89
+ Session admission counts both active sessions and initializations in progress, globally and per
90
+ principal. Static-token sessions use the configured sliding inactivity lifetime. OAuth session
91
+ expiry is the earlier of that lifetime and the access token's `exp`; an expired token cannot create
92
+ a session. Expiration timers remove sessions at that bound, with access checks, pre-admission
93
+ pruning, and periodic cleanup as fail-closed backstops.
94
+ Resumable GET streams have separate global/per-principal ceilings; once accepted, a long-lived
95
+ stream releases the ordinary short-request concurrency reservation and remains charged to the
96
+ stream ceilings.
97
+
98
+ Replay history is also bounded: at most 1,000 events per session, the configured per-session byte
99
+ budget, the configured process-wide event-store byte budget, and the session TTL. Per-session
100
+ overflow evicts the oldest history first. If one event cannot fit the per-session or shared byte
101
+ budget, it is not retained for replay; the store does not evict another session's history to make
102
+ room. Closing or expiring a session releases its shared budget.
103
+
104
+ ## Stdio controls
105
+
106
+ Stdio accepts newline-delimited JSON-RPC frames of at most 16,777,216 bytes, excluding the line-feed
107
+ delimiter. The ceiling is fixed and matches the largest configurable Streamable HTTP JSON body.
108
+ Input is retained in a geometrically grown bounded byte buffer, keeping cumulative copy work
109
+ linear without per-chunk metadata growth. Completed frames use fatal UTF-8 decoding; malformed byte
110
+ sequences are never replaced with U+FFFD or dispatched as JSON-RPC. A malformed UTF-8 frame or a
111
+ frame that crosses the ceiling is refused immediately (for size, including when no newline or
112
+ end-of-input has arrived): the server writes a structured `STDIO_INVALID_UTF8` or
113
+ `STDIO_FRAME_TOO_LARGE` event to stderr, closes that transport, and exits unsuccessfully. The
114
+ rejected payload is never echoed. Protocol responses remain exclusively on stdout; transport and
115
+ startup diagnostics remain exclusively on stderr.
116
+
117
+ Well-formed UTF-8 frames that fail JSON or JSON-RPC schema validation are not dispatched. Their
118
+ stderr diagnostic has the fixed `STDIO_INVALID_MESSAGE` code and a generic message; it never
119
+ interpolates caller-controlled frame content. A later valid frame may continue on the local
120
+ connection.
121
+
122
+ ## Source and artifact privacy
123
+
124
+ Stdio inherits the local process user's access but still applies the configured roots. A remote deployment can access only paths mounted and registered on the server; it cannot reach a client computer. Do not mount a home directory or an entire game library when one read-only game root and selected workspaces suffice.
125
+
126
+ On POSIX, the server enforces mode `0700` on the state root and `0600` on the journal key. Node does
127
+ not provide a portable Windows DACL authoring API, so Windows operators must provision the state
128
+ root ACL for the dedicated server account; the server still rejects a linked/non-regular key and
129
+ inherits that operator ACL. A hostile operating-system principal that can read the key or replace
130
+ state-root entries remains outside the documented filesystem trust boundary.
131
+
132
+ Raw installed-game or dependency sprite, font, and bitmap files are never registered as downloadable resources. Structured JSON evidence strips embedded raster and glyph payloads, retaining only source-linked hashes, paths, frame and dimension metadata. Composite SVG/PNG reviews may contain processed frames or glyphs required to inspect the requested render, but remain generated, authorization-checked workspace evidence rather than raw asset-file resources. Transaction evidence may contain authorized mod-source before/proposed text and diffs; every artifact remains bound to the workspace principal.
133
+
134
+ The runtime sends no telemetry or analytics. Its only outbound network request is OAuth JWT-key retrieval from the administrator-configured JWKS endpoint; stdio and static-token loopback deployments require no runtime network access.
135
+
136
+ The product never launches, automates, controls, or captures Hearts of Iron IV. Every preview is
137
+ an offline tool-generated render, not a game screenshot or evidence of in-engine behavior.
138
+
139
+ Vulnerabilities should be reported through GitHub private vulnerability reporting as described in the root [security policy](../SECURITY.md).
@@ -0,0 +1,168 @@
1
+ # Self-hosting Streamable HTTP
2
+
3
+ The server exposes one stateful MCP endpoint at `/mcp` for POST and GET, plus DELETE session termination. It does not provide legacy SSE-only transport.
4
+
5
+ ## Loopback
6
+
7
+ Set a random token of at least 32 characters in the environment named by config:
8
+
9
+ ```bash
10
+ export HOI4_AGENT_HTTP_TOKEN='replace-with-a-random-secret'
11
+ HOI4_AGENT_CONFIG=/srv/hoi4/config.json hoi4-agent-tools-http
12
+ ```
13
+
14
+ Keep `host` as `127.0.0.1`. The client sends `Authorization: Bearer ...`. Present origins still need to match `allowedOrigins`.
15
+
16
+ The HTTP process refuses to start if a configured token environment variable is missing, shorter
17
+ than 32 characters, or has the same secret value as another configured token. Static tokens and
18
+ OAuth are mutually exclusive deployment modes.
19
+
20
+ ## Public/team deployment
21
+
22
+ Public mode—either a non-loopback listener or a non-loopback `publicUrl` in front of a loopback/private listener—refuses to start unless:
23
+
24
+ - `publicUrl` is an HTTPS origin or exact `/mcp` endpoint and contains no credentials, path prefix, query, or fragment;
25
+ - OAuth/OIDC JWT validation is configured;
26
+ - the OAuth issuer, JWKS, and every authorization-server URL use HTTPS;
27
+ - at least one origin is allowlisted;
28
+ - principal/workspace grants are configured.
29
+
30
+ ```json
31
+ {
32
+ "http": {
33
+ "host": "0.0.0.0",
34
+ "port": 3210,
35
+ "publicUrl": "https://mcp.example.test",
36
+ "allowedOrigins": ["https://agent.example.test"],
37
+ "trustedProxyAddresses": ["10.20.0.5"],
38
+ "tokens": [],
39
+ "principals": [
40
+ { "principal": "user-subject", "workspaceIds": ["example"], "allowRegistration": false }
41
+ ],
42
+ "oauth": {
43
+ "issuer": "https://issuer.example.test/",
44
+ "jwksUri": "https://issuer.example.test/.well-known/jwks.json",
45
+ "audience": "https://mcp.example.test/mcp",
46
+ "authorizationServers": ["https://issuer.example.test/"],
47
+ "requiredScopes": ["hoi4:read"],
48
+ "algorithms": ["RS256"]
49
+ }
50
+ }
51
+ }
52
+ ```
53
+
54
+ The server is an OAuth resource server, not an authorization server. Protected Resource Metadata is served at the standard well-known paths and its endpoint-specific URL is included in 401 and insufficient-scope 403 challenges. Baseline access uses the configured `requiredScopes`; transaction planning, registration, apply, and rollback additionally require `hoi4:write`. Each MCP session is bound to the exact bearer credential that initialized it, not only to mutable subject/client claims. A refreshed or step-up token must initialize a new MCP session; the previous session remains bound to its original credential and expires no later than that credential's `exp`. The server retains only a SHA-256 credential identifier, never the raw token. Static-token sessions keep the configured sliding inactivity lifetime. Terminate TLS at a trusted reverse proxy, preserve Authorization/Origin/Host headers, and do not make a session ID a bearer credential.
55
+
56
+ ### Reverse-proxy boundary
57
+
58
+ `trustedProxyAddresses` is not a general proxy switch; it affects only the pre-auth rate-limit
59
+ address and does not trust forwarded host or protocol metadata. Each entry is one exact IPv4 or
60
+ IPv6 address as it appears for the direct socket peer; CIDR ranges and hostnames are rejected. An
61
+ IPv4-mapped IPv6 peer is normalized to IPv4 for matching. When the peer is not an exact match, the
62
+ application ignores `X-Forwarded-For` and rate-limits the socket address. When it is a match, the
63
+ application requires a valid `X-Forwarded-For` value and uses its first comma-separated IP.
64
+
65
+ The edge proxy must therefore:
66
+
67
+ - be the only network path to the server port, enforced by a private bind/network and firewall;
68
+ - terminate TLS for the HTTPS `publicUrl`;
69
+ - remove any client-supplied forwarding chain and set the first `X-Forwarded-For` value to a
70
+ validated originating client IP;
71
+ - preserve the bearer `Authorization` header, the original `Origin`, and a `Host` accepted by the
72
+ configured bind host or `publicUrl`;
73
+ - enforce its own connection, header-size, body-size, header/request/idle timeout, and pre-auth
74
+ rate ceilings before forwarding.
75
+
76
+ Do not configure a load-balancer subnet and expect range matching, and do not allow clients to
77
+ bypass the named proxy. For multiple proxy hops, use an edge-controlled normalization point that
78
+ delivers one trustworthy first address to the directly connected trusted peer.
79
+
80
+ ### Admission, sessions, and streams
81
+
82
+ Before authentication, the application enforces Node connection/request timeouts and socket
83
+ ceilings, then reserves one `maxConcurrentRequests` slot and applies a fixed-minute
84
+ `requestsPerMinute` bucket to the resolved client address. Every POST must advertise exact,
85
+ unparameterized positive-quality `application/json` and `text/event-stream` response ranges, use exact
86
+ `application/json` request media with an absent or `utf-8` charset, and use identity content
87
+ encoding. GET must advertise exact positive-quality `text/event-stream`. JSON is fatal-decoded as
88
+ UTF-8 and parsed under the raw-wire `maxBodyBytes` ceiling before SDK dispatch. Suffix types,
89
+ duplicate/malformed parameters, encoded entities, invalid UTF-8, and parameter-only media mentions
90
+ are rejected.
91
+
92
+ Before those checks, the server counts security-sensitive fields in the raw header list rather
93
+ than trusting Node's first-value normalization. Duplicate Host, Authorization, Origin,
94
+ Content-Type, Content-Encoding, forwarding identity, or MCP session/protocol fields are rejected.
95
+ For an absolute-form request target, its allowlisted authority must exactly match Host; an allowed
96
+ Host cannot conceal an untrusted request-target authority.
97
+ After authentication, a separate fixed-minute bucket is applied to the principal. Host and any
98
+ present Origin are checked before admission. These in-process controls complement, rather than
99
+ replace, the edge limits above.
100
+
101
+ `maxConcurrentRequests` cannot exceed two, and its product with `maxBodyBytes` cannot exceed
102
+ 16 MiB. The fixed concurrency ceiling also bounds simultaneous offline render allocations; raise
103
+ edge capacity by running isolated server instances, not by removing the per-process safety bound.
104
+
105
+ Session initialization is refused when either the global `maxSessions` or
106
+ `maxSessionsPerPrincipal` count (including initializations in progress) is full. Resumable GET
107
+ streams use `maxEventStreams` and `maxEventStreamsPerPrincipal`; an accepted long-lived stream
108
+ releases the ordinary request-concurrency slot. Each session retains at most 1,000 replay events,
109
+ `maxSessionEventBytes`, and the shared `maxEventStoreBytes`, for no longer than
110
+ `sessionTtlSeconds`. Old per-session history is evicted first. A new event that cannot fit the
111
+ shared budget is not retained for replay and does not evict another session's history.
112
+
113
+ Principal grants isolate tool, resource, session, and transaction access within one deployment. Run separate least-privilege server instances or containers for mutually distrustful teams or operating-system trust domains; do not treat application-level grants as an OS sandbox.
114
+
115
+ Runtime registration has two operator capabilities. `registrationRoots` permits read-only source
116
+ selection. A caller-declared mod root additionally must be under the default-empty
117
+ `writableRegistrationRoots` list, even when source apply is disabled, because mod registration
118
+ creates generated storage. Never place a game or dependency directory under a writable
119
+ registration root. Granting `allowRegistration` exposes every otherwise-unclaimed source beneath
120
+ these capability roots to that principal; prefer static registrations or separate instances for
121
+ mutually distrustful users.
122
+
123
+ Runtime artifact storage must support same-volume hard links so the server can create persistent
124
+ owner claims without replacement races. Transaction deployments additionally require an isolated,
125
+ persistent `serverStateRoot` on a filesystem with hard-link and atomic-replacement support. Do not
126
+ place it beneath any source, capability, artifact, cache, fixture, or `storageRoots` directory.
127
+
128
+ ## Container
129
+
130
+ ```bash
131
+ docker build -t hoi4-agent-tools:0.1.3 .
132
+ docker run --read-only --rm -p 127.0.0.1:3210:3210 \
133
+ -e HOI4_AGENT_CONFIG=/config/config.json \
134
+ -v /srv/hoi4/config:/config:ro \
135
+ -v /srv/hoi4/game:/srv/hoi4/game:ro \
136
+ -v /srv/hoi4/workspaces:/srv/hoi4/workspaces \
137
+ -v /var/lib/hoi4-agent-tools:/var/lib/hoi4-agent-tools \
138
+ -v /var/lib/hoi4-agent-tools-state:/var/lib/hoi4-agent-tools-state \
139
+ hoi4-agent-tools:0.1.3
140
+ ```
141
+
142
+ Port publishing reaches the container through a non-loopback interface. The mounted configuration
143
+ for this form must therefore use the public/team OAuth policy above: bind `0.0.0.0`, declare the
144
+ canonical HTTPS `publicUrl`, allowlist the coding-agent origin, and validate OAuth access tokens.
145
+ Terminate TLS at the configured reverse proxy. Mapping the host port only to `127.0.0.1` limits host
146
+ exposure but does not turn the container-side listener into loopback, so it does not permit static
147
+ bearer tokens.
148
+
149
+ When writes are enabled, set `serverStateRoot` to `/var/lib/hoi4-agent-tools-state` in this example.
150
+ Keep that mount persistent across restarts and protect it for the dedicated server account. It is a
151
+ separate mount because a state root may not overlap `/var/lib/hoi4-agent-tools` when that path is a
152
+ configured generated-storage capability.
153
+
154
+ On Linux, a local-only static-token deployment may instead use `--network host` with the configured
155
+ listener kept at `127.0.0.1`; do not combine that mode with `-p`. Host networking changes the
156
+ container isolation boundary and is not portable to every Docker host, so review it explicitly
157
+ before use.
158
+
159
+ Do not mount a developer's home directory. A remote server sees only server-side mounts; the MCP client does not tunnel local files.
160
+
161
+ If a configured workspace has `kind: "game"` or `kind: "dependency"`, mount a separate writable
162
+ operator-owned generated-data directory, list its parent in `storageRoots`, and set both
163
+ `artifactRoot` and `cacheRoot` beneath it. Never make the installed-game or dependency source
164
+ mount writable merely to hold generated state. Mod workspaces may instead use their confined
165
+ `<mod>/.hoi4-agent/artifacts` and `<mod>/.hoi4-agent/cache` defaults.
166
+
167
+ The server does not launch or capture Hearts of Iron IV. A self-hosted deployment needs filesystem
168
+ access only; it does not need a desktop session, Steam automation, or game-process permissions.
@@ -0,0 +1,43 @@
1
+ # Testing and fixtures
2
+
3
+ ```bash
4
+ npm ci
5
+ npm run test
6
+ npm run test:coverage
7
+ npm run fixtures:check
8
+ npm run build
9
+ npm run inspector
10
+ npm run check
11
+ ```
12
+
13
+ ## Portable CI
14
+
15
+ CI owns all inputs:
16
+
17
+ - a 255-focus workspace with ten route families, exclusions, convergence, planner-sidecar hidden/crisis/shared-support metadata, relative/pinned/automatic positions, a real `continuous_focus_palette`, active localisation, a two-frame sprite texture, and resolved synthetic references;
18
+ - a 170-element five-tab GUI with a dynamic list, target cards, meters, distinct frame animation, modal, all required states, licensed fixture font, and defect variants;
19
+ - a nontrivial 24-bit BMP mini-world with islands, exact split masks/polygons, state/region/network/adjacency data, and invalid variants.
20
+
21
+ Suites cover parser byte round trips, encodings, property cases, source locations, overlay/load order, custom focus roots, exact referenced-texture scanning, strict schemas, deterministic goldens, generated-source maps, planning-sidecar enrichment, image comparisons, font metrics, bitmap diffs, transaction fault/recovery, path security, cross-workspace isolation, stdio, Streamable HTTP, auth/origin/session limits, resource/prompt/tool discovery, package installation, Registry schema, and end-to-end agent workflows.
22
+
23
+ ## Local integration
24
+
25
+ Set paths explicitly; tests are read-only:
26
+
27
+ ```bash
28
+ HOI4_GAME_ROOT=/path/to/game \
29
+ HOI4_EXTERNAL_MOD_ROOT=/path/to/mod \
30
+ npm run test:local
31
+ ```
32
+
33
+ Optionally set `HOI4_DEPENDENCY_ROOTS` to dependency roots separated by the operating system path delimiter (`;` on Windows, `:` on POSIX).
34
+
35
+ Three local tests parse and deterministically render a large vanilla focus tree, build and render a current GUI/GFX/font source graph, and scan/render/store the current province map with state, coastline, supply-node, and railway data against one external mod. Generated caches and artifacts stay in a temporary directory that is removed after the suite; the external roots remain read-only, no files are copied into the repository, and the game is never launched.
36
+
37
+ `npm run test:local` uses a project-owned validation runner around the standalone local Vitest configuration. It routes only `tests/local`, preserves ordinary Vitest failure codes, and independently requires the exact focus, GUI, and map qualification workflows to finish. The command fails when paths are absent and the tests skip, when a required workflow is not collected, when a worker terminates or runs out of memory, when Vitest reports any unhandled error, or when the reporter lifecycle is incomplete. A zero Vitest exit code alone is therefore not treated as success.
38
+
39
+ ## Performance
40
+
41
+ Run the explicit, non-CI benchmark with `npm run benchmark`. It records cold/warm shared scans, the 255-node focus layout/render, the 150+ element GUI state gallery, and a full cross-root synthetic map scan plus all base-layer renders. Cache keys include content hashes; a deterministic unit test mutates content while preserving size and modification time to prove safe invalidation.
42
+
43
+ Current measurements, methodology, and rerun instructions are in [performance.md](performance.md).
@@ -0,0 +1,11 @@
1
+ # Third-party notices
2
+
3
+ ## Roboto
4
+
5
+ HOI4 Agent Tools depends on `@fontsource-variable/roboto` version 5.2.10 for deterministic, host-independent artifact labels and the project-owned synthetic BMFont fixture.
6
+
7
+ Copyright 2011 The Roboto Project Authors (<https://github.com/googlefonts/roboto-classic>). Roboto-Italic[wdth,wght].ttf: Copyright 2011 The Roboto Project Authors (<https://github.com/googlefonts/roboto-classic>).
8
+
9
+ Roboto is licensed under the SIL Open Font License, Version 1.1 (`OFL-1.1`). The complete license text is distributed as `LICENSE` in the installed `@fontsource-variable/roboto` package. The font package is pinned in `package.json` and `package-lock.json`; generated SVG/PNG documents may contain derived glyph outlines or pixels as permitted by the OFL.
10
+
11
+ The application source remains licensed under Apache-2.0 as stated in the repository [LICENSE](../LICENSE). Third-party components retain their respective licenses.
@@ -0,0 +1,162 @@
1
+ # Transactions, diffs, and rollback
2
+
3
+ ## Plan
4
+
5
+ A domain `plan_changes`/`map_plan` call calculates every affected source and binary file before writing. Proposed bytes are validated in memory. The plan persists content-addressed before/after blobs and produces source, binary, pixel, and rendered comparison artifacts where applicable.
6
+
7
+ Every proposed source target is resolved with write access restricted to the workspace's canonical
8
+ mod root. Transaction calls cannot write the game, a dependency, a fixture, artifact storage,
9
+ cache storage, or the reserved `.hoi4-agent` subtree as mod source.
10
+
11
+ The transaction API requires both validation phases: planning must return at least one explicit in-memory check, and apply must return at least one explicit post-write check. Missing or empty callbacks fail with `TRANSACTION_DRY_RUN_VALIDATION_REQUIRED` or `TRANSACTION_POST_VALIDATION_REQUIRED`; callers cannot opt out through the typed core API. Diff artifacts are committed as one batch with the journal only after the planning validator returns structurally valid results. A rejected validator or journal admission leaves artifact inventory unchanged. A completed dry run whose explicit checks fail remains reviewable as a blocked plan and cannot be applied.
12
+
13
+ Text diffs use an exact deterministic algorithm with a fixed memory bound and cancellation checks. If an exact diff would exceed the bound, planning stops with `DIFF_COMPLEXITY_LIMIT`; the server does not substitute a truncated, approximate, or misleading diff.
14
+
15
+ The returned transaction ID is not approval. Review:
16
+
17
+ - operations and unresolved choices;
18
+ - affected file list;
19
+ - source and visual diff resources;
20
+ - diagnostic locations and validation gates;
21
+ - expiry and plan hash.
22
+
23
+ Plan and mutation tool results keep only a bounded path sample plus the authenticated transaction
24
+ manifest resource. Review artifacts remain listed in that manifest rather than being duplicated as
25
+ hundreds of inline resource links. `hoi4.transaction_diff` returns at most 20 files, operation
26
+ summaries, and artifact links per page; follow every `nextCursor` until it is absent. Cursors are
27
+ bound to the immutable plan hash and fail if reused for a different transaction. Inline validation
28
+ contains at most five checks with an explicit truncation diagnostic; the manifest is the complete
29
+ validation record.
30
+
31
+ Focus plans include both the edited Clausewitz source and its adjacent `.focus-plan.json` design sidecar in one transaction. The manifest also retains the proposed generated-source map and sidecar artifacts through apply and rollback so each generated focus range remains traceable to its planning/source node.
32
+
33
+ ## Apply
34
+
35
+ Call `hoi4.transaction_apply` separately with `workspaceId`, `transactionId`, and the exact 64-character `expectedPlanHash`. The server rejects a different principal/workspace, changed roots, failed dry run, expiry, reused state, or any changed before-hash.
36
+
37
+ The persisted immutable plan payload is recomputed against `planHash` whenever a manifest is
38
+ loaded. A recomputable integrity hash remains useful for deterministic diagnostics, but is never an
39
+ authorization boundary. Every exact-version manifest also carries an HMAC-SHA-256 tag over the
40
+ complete canonical payload except that tag itself, including expiry, state, applied files, failure,
41
+ rollback status, operations, plan, diagnostics, and validation. The random 256-bit key is created
42
+ atomically beneath the non-overlapping operator `serverStateRoot`; it is never derived from public
43
+ workspace data or exposed through MCP.
44
+
45
+ The same protected state stores one authenticated latest-revision head per admitted journal. An
46
+ older valid manifest is rejected as replay. Manifest replacement is cache-first and caller state is
47
+ updated only after persistence: a crash between cache replacement and protected-head commit may
48
+ reconcile only an HMAC-valid exact `+1` successor. Missing heads, gaps, conflicting same revisions,
49
+ and forged successors fail closed. Successor creation is durable before older revision-head files
50
+ are removed, so an old-head cleanup failure does not break loading.
51
+
52
+ Ordinary status, diff, and resource reads are pure: they accept only an exact protected head and
53
+ never promote state. An authenticated cache-first exact successor reports
54
+ `TRANSACTION_HEAD_RECONCILIATION_REQUIRED` until startup recovery or an authorized write path
55
+ performs the narrowly allowed reconciliation.
56
+
57
+ Unauthenticated journals from an older deployment are deliberately not auto-migrated. They remain
58
+ fail-closed for operator review because no server-held secret can prove their origin. Archive or
59
+ remove them explicitly before reclaiming their quota; do not manufacture an authentication tag.
60
+
61
+ During apply the server:
62
+
63
+ 1. takes the exclusive workspace lock;
64
+ 2. rechecks every precondition;
65
+ 3. writes and flushes same-volume staged files;
66
+ 4. journals backups and replacements in deterministic order;
67
+ 5. rebuilds the shared index;
68
+ 6. runs post-write validation;
69
+ 7. removes temporary backups only after success.
70
+
71
+ The workspace lock serializes cooperating server processes that use the same cache. Before each
72
+ replacement, the current source hash is checked again; after post-write validation, every result
73
+ hash is checked. These checks detect stale ordinary edits, but they are not a race-proof
74
+ filesystem sandbox against a hostile operating-system principal.
75
+
76
+ ## Failure and recovery
77
+
78
+ Any error starts rollback in reverse file order. Existing backups or persisted blobs restore exact original bytes, including BMP headers and padding. Restores stage and flush bytes before atomically renaming over the current target; they never unlink an existing target before a blob replacement. A durable `rolling_back` journal can also resume the legacy interrupted state where that target is already missing, but only after verifying its persisted before-blob. Startup scans unfinished journals and completes rollback before accepting a new write.
79
+
80
+ Runtime registration definitions are not persisted, but their hash-only ownership claims are.
81
+ Their unfinished journals are recovered only after the same principal re-registers an exactly
82
+ matching canonical workspace and the persistent claim is verified, before status or write access
83
+ is returned to the caller.
84
+
85
+ Lock owners record the host, process, server instance, and process start time. A dead owner on the same host is cleared during startup recovery; an ownerless acquisition lock is cleared only after a 30-second grace period. A live local owner and every different- or unknown-host owner remain authoritative. Automatic cross-host crash recovery is intentionally unsupported: deployments sharing a workspace/cache filesystem across hosts must provide single-writer orchestration and operator-confirmed recovery rather than relying on local PID evidence.
86
+
87
+ Multi-file atomicity is logical and recoverable, not an operating-system transaction. External
88
+ processes can briefly observe replacement steps. Under an operator-controlled filesystem, success
89
+ is returned only after post-write validation and final result-hash verification. A principal able
90
+ to concurrently replace directories, links, mounts, or files outside the transaction lock already
91
+ has direct filesystem authority and is outside the application security boundary; the server does
92
+ not claim race-proof atomicity against that actor.
93
+
94
+ ## Journal retention and quotas
95
+
96
+ Transaction journals live under `<cacheRoot>/transactions`. The configurable defaults are 128
97
+ journals and 536,870,912 bytes per workspace cache. A plan must also fit its own rollback blobs,
98
+ serialized manifest, and replacement-work estimate beneath the byte ceiling. The plan is refused
99
+ with `TRANSACTION_JOURNAL_LIMIT` before a usable journal is committed if either the count, stored
100
+ bytes, or single-plan work budget would be exceeded. No smaller or truncated rollback journal is
101
+ substituted.
102
+
103
+ One manifest is bounded to 1,000 changed files, 1,000 operations, 10,000 read dependencies, 100
104
+ validation checks, 100 diagnostics, 512 artifacts, and 1,000 applied-file entries. Inputs over a
105
+ count limit or the existing serialized journal/work-byte budget are rejected, never truncated.
106
+ Post-write validation is preflighted against the combined check and diagnostic counts before the
107
+ manifest is mutated. A 100+1 overflow triggers exact rollback while preserving a schema-bounded
108
+ authenticated terminal journal.
109
+
110
+ Before committing a new plan, the server performs narrowly scoped retention cleanup:
111
+
112
+ - expired `planned` and `rolled_back` journals are removed by deleting their protected head first
113
+ and cache journal second. A crash or later reintroduction of the cache copy then fails for a
114
+ missing head rather than replaying;
115
+ - an incomplete transaction directory with no manifest is removed only after it is older than
116
+ `transactionTtlSeconds`;
117
+ - `applied`, `failed`, `applying`, and `rolling_back` journals are not quota-evicted. Interrupted
118
+ states are handled by recovery instead;
119
+ - malformed, integrity-failing, or otherwise unreadable journals are retained and continue to
120
+ count against quota rather than being guessed safe to delete.
121
+
122
+ Only the latest protected revision is retained per live journal. Cache-without-head planned or
123
+ rolled-back remnants from an interrupted admission/prune are authenticated and removed safely;
124
+ active or unauthenticated remnants remain fail-closed. Head-without-cache remnants are removed
125
+ while reconciling a workspace. Protected state therefore remains bounded by admitted cache
126
+ journals rather than growing with revision or expiry churn.
127
+
128
+ After that cleanup, the server deterministically accepts the complete plan or refuses it. It does
129
+ not evict a valid applied/failed journal to make room. Operators who intentionally remove terminal
130
+ journals also remove their status, audit evidence, persisted blobs, and any later explicit rollback
131
+ ability.
132
+
133
+ Diff artifact creation and journal admission share a failure boundary. If the journal count or byte
134
+ check rejects a plan, the artifact store removes only content and provenance files created for that
135
+ attempt; artifact inventory is unchanged and any identical artifact retained by another operation
136
+ remains addressable.
137
+
138
+ ## Explicit rollback
139
+
140
+ `hoi4.transaction_rollback` is available after successful apply. It first verifies that every current file still has the transaction's after-hash. An external edit makes rollback stale, protecting later work from being overwritten.
141
+
142
+ Rollback accepts cancellation through its path/hash verification preflight. Once byte restoration
143
+ starts, restore plus authenticated journal advancement is deliberately non-cancellable so a client
144
+ disconnect cannot strand a partial rollback.
145
+
146
+ Status/manifest reads and runtime recovery enumeration accept cancellation around filesystem
147
+ reads, JSON/schema validation, and protected-head verification. Once recovery begins restoring
148
+ source bytes, it follows the same non-cancellable critical-phase rule.
149
+
150
+ Transaction manifests are readable as:
151
+
152
+ ```text
153
+ hoi4-agent://workspace/{workspaceId}/transaction/{transactionId}
154
+ ```
155
+
156
+ Manifest resources use the same 1 MiB `offset`/`length` byte ranges as artifacts. A complete
157
+ strict-UTF-8 manifest may be returned as MCP `text`; every partial range is a base64 `blob`.
158
+ Advance `offset` by the decoded byte count and continue until a chunk is shorter than the requested
159
+ length. Transaction manifests have a separate fixed 16 MiB serialized ceiling, independent of the
160
+ larger rollback-blob journal budget.
161
+ Canonical resource bytes are cached by stable file identity and protected revision, with at most
162
+ eight entries and 16 MiB total, so later ranges do not repeatedly rebuild a large manifest object.
@@ -0,0 +1,46 @@
1
+ # Troubleshooting
2
+
3
+ ## Configuration not found
4
+
5
+ Set `HOI4_AGENT_CONFIG` to an absolute path or add `--config PATH` to the server command. Run `hoi4-agent-tools-setup --diagnose --config PATH`.
6
+
7
+ ## Workspace/path rejected
8
+
9
+ Use a registered workspace-relative path. Confirm the canonical root is beneath `registrationRoots`; runtime mods also require the separate `writableRegistrationRoots` capability. Check for junctions/symlinks, parent segments, device names, trailing dots/spaces, or alternate data streams. Game and dependencies are intentionally read-only.
10
+
11
+ ## Apply reports stale
12
+
13
+ The source changed after planning. Do not reuse the transaction. Scan and produce a new dry run so review evidence matches current files.
14
+
15
+ ## Transaction state rejected
16
+
17
+ Transaction mode requires an absolute, persistent `serverStateRoot` that does not overlap any
18
+ source or generated-storage capability. Run setup with `--enable-writes --server-state ROOT`, then
19
+ run `--diagnose`. Preserve the same private state root across restarts. A missing key, malformed or
20
+ replayed head, unauthenticated legacy manifest, or cache/head revision conflict fails closed; review
21
+ and archive the affected journal/state evidence instead of regenerating a public hash or tag.
22
+
23
+ ## Runtime registration conflicts after restart
24
+
25
+ The artifact root already has a hash-only runtime owner claim. Register the exact canonical
26
+ workspace as the same principal, or stop the server and perform an explicit operator-reviewed data
27
+ reassignment. Do not delete the claim alone or expect a renamed workspace ID, path alias, or second
28
+ principal to inherit the existing evidence.
29
+
30
+ ## Render has missing/unsupported fields
31
+
32
+ Read the fidelity resource. Register the correct game/dependency root and supply a scenario value or asset. Unsupported fields stay raw; do not treat an approximation as engine evidence.
33
+
34
+ ## HTTP refuses to start
35
+
36
+ Authentication is mandatory. Static token secrets must be at least 32 characters and are loopback-only. Public binding requires HTTPS `publicUrl`, OAuth settings, allowed origins, and principal grants.
37
+
38
+ ## HTTP returns 401/403/404
39
+
40
+ - 401: missing/invalid/expired token or wrong issuer/audience.
41
+ - 403: origin, scope, principal/workspace, or cross-principal session rejected.
42
+ - 404 with session ID: session is unknown or expired; initialize a new MCP session.
43
+
44
+ ## Inspector
45
+
46
+ Build first, then run `npm run inspector`. The Inspector proxy is a local debugging surface; do not expose it unauthenticated.