hoi4-agent-tools 0.2.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (430) hide show
  1. package/CHANGELOG.md +21 -118
  2. package/README.md +38 -124
  3. package/SECURITY.md +5 -7
  4. package/dist/bin/http.js +0 -1
  5. package/dist/bin/setup.js +141 -92
  6. package/dist/bin/stdio.js +0 -1
  7. package/dist/hoi4_agent_tools/core/artifacts.js +0 -1
  8. package/dist/hoi4_agent_tools/core/canonical.js +0 -1
  9. package/dist/hoi4_agent_tools/core/configuration.js +28 -28
  10. package/dist/hoi4_agent_tools/core/diagnostic-collector.js +0 -1
  11. package/dist/hoi4_agent_tools/core/diagnostics.js +0 -1
  12. package/dist/hoi4_agent_tools/core/diff.js +0 -1
  13. package/dist/hoi4_agent_tools/core/engine.js +6 -21
  14. package/dist/hoi4_agent_tools/core/image-diff.js +0 -1
  15. package/dist/hoi4_agent_tools/core/index.js +0 -1
  16. package/dist/hoi4_agent_tools/core/render-budget.js +0 -1
  17. package/dist/hoi4_agent_tools/core/result.js +0 -1
  18. package/dist/hoi4_agent_tools/core/scanner.js +0 -1
  19. package/dist/hoi4_agent_tools/core/server-state.js +0 -1
  20. package/dist/hoi4_agent_tools/core/source/encoding.js +0 -1
  21. package/dist/hoi4_agent_tools/core/source/index.js +0 -1
  22. package/dist/hoi4_agent_tools/core/source/lexer.js +0 -1
  23. package/dist/hoi4_agent_tools/core/source/limits.js +0 -1
  24. package/dist/hoi4_agent_tools/core/source/localisation.js +0 -1
  25. package/dist/hoi4_agent_tools/core/source/parser.js +0 -1
  26. package/dist/hoi4_agent_tools/core/source/rewrite.js +0 -1
  27. package/dist/hoi4_agent_tools/core/svg-text.js +0 -1
  28. package/dist/hoi4_agent_tools/core/transaction-limits.js +0 -1
  29. package/dist/hoi4_agent_tools/core/transactions.js +2 -30
  30. package/dist/hoi4_agent_tools/core/workspace.js +112 -396
  31. package/dist/hoi4_agent_tools/focus/compact.js +432 -0
  32. package/dist/hoi4_agent_tools/focus/compiler.js +1 -8
  33. package/dist/hoi4_agent_tools/focus/continuous-render.js +0 -1
  34. package/dist/hoi4_agent_tools/focus/drift.js +0 -1
  35. package/dist/hoi4_agent_tools/focus/geometry.js +203 -17
  36. package/dist/hoi4_agent_tools/focus/importer.js +0 -1
  37. package/dist/hoi4_agent_tools/focus/index.js +1 -1
  38. package/dist/hoi4_agent_tools/focus/layout.js +1256 -93
  39. package/dist/hoi4_agent_tools/focus/limits.js +1 -2
  40. package/dist/hoi4_agent_tools/focus/lint.js +11 -4
  41. package/dist/hoi4_agent_tools/focus/model.js +0 -1
  42. package/dist/hoi4_agent_tools/focus/native-effects.js +0 -1
  43. package/dist/hoi4_agent_tools/focus/planning.js +6 -2
  44. package/dist/hoi4_agent_tools/focus/presentation.js +0 -1
  45. package/dist/hoi4_agent_tools/focus/render.js +14 -10
  46. package/dist/hoi4_agent_tools/focus/service.js +7 -8
  47. package/dist/hoi4_agent_tools/focus/source-update.js +1 -2
  48. package/dist/hoi4_agent_tools/gui/animation-manifest.js +0 -1
  49. package/dist/hoi4_agent_tools/gui/assets.js +0 -1
  50. package/dist/hoi4_agent_tools/gui/dds.js +0 -1
  51. package/dist/hoi4_agent_tools/gui/helpers.js +1 -2
  52. package/dist/hoi4_agent_tools/gui/index.js +0 -1
  53. package/dist/hoi4_agent_tools/gui/layout.js +0 -1
  54. package/dist/hoi4_agent_tools/gui/limits.js +0 -1
  55. package/dist/hoi4_agent_tools/gui/renderer.js +0 -1
  56. package/dist/hoi4_agent_tools/gui/scenario.js +0 -1
  57. package/dist/hoi4_agent_tools/gui/source-graph.js +0 -1
  58. package/dist/hoi4_agent_tools/gui/source-patch.js +1 -2
  59. package/dist/hoi4_agent_tools/gui/studio.js +247 -104
  60. package/dist/hoi4_agent_tools/gui/tga.js +0 -1
  61. package/dist/hoi4_agent_tools/gui/types.js +0 -1
  62. package/dist/hoi4_agent_tools/gui/validators.js +0 -1
  63. package/dist/hoi4_agent_tools/map/bmp.js +0 -1
  64. package/dist/hoi4_agent_tools/map/diagnostic-limit.js +0 -1
  65. package/dist/hoi4_agent_tools/map/index.js +0 -1
  66. package/dist/hoi4_agent_tools/map/limits.js +2 -1
  67. package/dist/hoi4_agent_tools/map/model.js +0 -1
  68. package/dist/hoi4_agent_tools/map/operations.js +0 -1
  69. package/dist/hoi4_agent_tools/map/render.js +0 -1
  70. package/dist/hoi4_agent_tools/map/service.js +171 -33
  71. package/dist/hoi4_agent_tools/map/validation.js +0 -1
  72. package/dist/hoi4_agent_tools/mcp/resources/register.js +61 -187
  73. package/dist/hoi4_agent_tools/mcp/security/auth.js +1 -2
  74. package/dist/hoi4_agent_tools/mcp/server/base-tools.js +24 -750
  75. package/dist/hoi4_agent_tools/mcp/server/context-schemas.js +8 -0
  76. package/dist/hoi4_agent_tools/mcp/server/create.js +2 -12
  77. package/dist/hoi4_agent_tools/mcp/server/output-schemas.js +0 -71
  78. package/dist/hoi4_agent_tools/mcp/server/progress.js +0 -1
  79. package/dist/hoi4_agent_tools/mcp/server/result.js +146 -81
  80. package/dist/hoi4_agent_tools/mcp/server/transaction-execution.js +10 -14
  81. package/dist/hoi4_agent_tools/mcp/tools/focus.js +309 -279
  82. package/dist/hoi4_agent_tools/mcp/tools/gui.js +156 -254
  83. package/dist/hoi4_agent_tools/mcp/tools/map.js +259 -338
  84. package/dist/hoi4_agent_tools/mcp/tools/mods.js +54 -0
  85. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js +0 -1
  86. package/dist/hoi4_agent_tools/mcp/transports/event-store.js +0 -1
  87. package/dist/hoi4_agent_tools/mcp/transports/http.js +1 -12
  88. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js +0 -1
  89. package/dist/hoi4_agent_tools/runtime.js +5 -2
  90. package/dist/hoi4_agent_tools/schemas/common.js +1 -2
  91. package/dist/hoi4_agent_tools/schemas/focus.js +64 -9
  92. package/dist/hoi4_agent_tools/schemas/map.js +0 -1
  93. package/dist/hoi4_agent_tools/schemas/transaction.js +0 -1
  94. package/dist/hoi4_agent_tools/version.js +1 -2
  95. package/docs/README.md +8 -21
  96. package/docs/development.md +22 -0
  97. package/docs/focus.md +50 -0
  98. package/docs/gui.md +37 -0
  99. package/docs/http.md +53 -0
  100. package/docs/map.md +39 -0
  101. package/docs/setup.md +39 -0
  102. package/package.json +12 -13
  103. package/server.json +3 -12
  104. package/dist/bin/http.d.ts +0 -3
  105. package/dist/bin/http.d.ts.map +0 -1
  106. package/dist/bin/http.js.map +0 -1
  107. package/dist/bin/setup.d.ts +0 -3
  108. package/dist/bin/setup.d.ts.map +0 -1
  109. package/dist/bin/setup.js.map +0 -1
  110. package/dist/bin/stdio.d.ts +0 -3
  111. package/dist/bin/stdio.d.ts.map +0 -1
  112. package/dist/bin/stdio.js.map +0 -1
  113. package/dist/hoi4_agent_tools/core/artifacts.d.ts +0 -117
  114. package/dist/hoi4_agent_tools/core/artifacts.d.ts.map +0 -1
  115. package/dist/hoi4_agent_tools/core/artifacts.js.map +0 -1
  116. package/dist/hoi4_agent_tools/core/canonical.d.ts +0 -13
  117. package/dist/hoi4_agent_tools/core/canonical.d.ts.map +0 -1
  118. package/dist/hoi4_agent_tools/core/canonical.js.map +0 -1
  119. package/dist/hoi4_agent_tools/core/configuration.d.ts +0 -138
  120. package/dist/hoi4_agent_tools/core/configuration.d.ts.map +0 -1
  121. package/dist/hoi4_agent_tools/core/configuration.js.map +0 -1
  122. package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts +0 -18
  123. package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts.map +0 -1
  124. package/dist/hoi4_agent_tools/core/diagnostic-collector.js.map +0 -1
  125. package/dist/hoi4_agent_tools/core/diagnostics.d.ts +0 -26
  126. package/dist/hoi4_agent_tools/core/diagnostics.d.ts.map +0 -1
  127. package/dist/hoi4_agent_tools/core/diagnostics.js.map +0 -1
  128. package/dist/hoi4_agent_tools/core/diff.d.ts +0 -22
  129. package/dist/hoi4_agent_tools/core/diff.d.ts.map +0 -1
  130. package/dist/hoi4_agent_tools/core/diff.js.map +0 -1
  131. package/dist/hoi4_agent_tools/core/engine.d.ts +0 -57
  132. package/dist/hoi4_agent_tools/core/engine.d.ts.map +0 -1
  133. package/dist/hoi4_agent_tools/core/engine.js.map +0 -1
  134. package/dist/hoi4_agent_tools/core/image-diff.d.ts +0 -14
  135. package/dist/hoi4_agent_tools/core/image-diff.d.ts.map +0 -1
  136. package/dist/hoi4_agent_tools/core/image-diff.js.map +0 -1
  137. package/dist/hoi4_agent_tools/core/index.d.ts +0 -64
  138. package/dist/hoi4_agent_tools/core/index.d.ts.map +0 -1
  139. package/dist/hoi4_agent_tools/core/index.js.map +0 -1
  140. package/dist/hoi4_agent_tools/core/index.public.d.ts +0 -16
  141. package/dist/hoi4_agent_tools/core/index.public.d.ts.map +0 -1
  142. package/dist/hoi4_agent_tools/core/index.public.js +0 -16
  143. package/dist/hoi4_agent_tools/core/index.public.js.map +0 -1
  144. package/dist/hoi4_agent_tools/core/render-budget.d.ts +0 -51
  145. package/dist/hoi4_agent_tools/core/render-budget.d.ts.map +0 -1
  146. package/dist/hoi4_agent_tools/core/render-budget.js.map +0 -1
  147. package/dist/hoi4_agent_tools/core/result.d.ts +0 -45
  148. package/dist/hoi4_agent_tools/core/result.d.ts.map +0 -1
  149. package/dist/hoi4_agent_tools/core/result.js.map +0 -1
  150. package/dist/hoi4_agent_tools/core/scanner.d.ts +0 -28
  151. package/dist/hoi4_agent_tools/core/scanner.d.ts.map +0 -1
  152. package/dist/hoi4_agent_tools/core/scanner.js.map +0 -1
  153. package/dist/hoi4_agent_tools/core/server-state.d.ts +0 -31
  154. package/dist/hoi4_agent_tools/core/server-state.d.ts.map +0 -1
  155. package/dist/hoi4_agent_tools/core/server-state.js.map +0 -1
  156. package/dist/hoi4_agent_tools/core/source/encoding.d.ts +0 -10
  157. package/dist/hoi4_agent_tools/core/source/encoding.d.ts.map +0 -1
  158. package/dist/hoi4_agent_tools/core/source/encoding.js.map +0 -1
  159. package/dist/hoi4_agent_tools/core/source/index.d.ts +0 -7
  160. package/dist/hoi4_agent_tools/core/source/index.d.ts.map +0 -1
  161. package/dist/hoi4_agent_tools/core/source/index.js.map +0 -1
  162. package/dist/hoi4_agent_tools/core/source/lexer.d.ts +0 -30
  163. package/dist/hoi4_agent_tools/core/source/lexer.d.ts.map +0 -1
  164. package/dist/hoi4_agent_tools/core/source/lexer.js.map +0 -1
  165. package/dist/hoi4_agent_tools/core/source/limits.d.ts +0 -21
  166. package/dist/hoi4_agent_tools/core/source/limits.d.ts.map +0 -1
  167. package/dist/hoi4_agent_tools/core/source/limits.js.map +0 -1
  168. package/dist/hoi4_agent_tools/core/source/localisation.d.ts +0 -20
  169. package/dist/hoi4_agent_tools/core/source/localisation.d.ts.map +0 -1
  170. package/dist/hoi4_agent_tools/core/source/localisation.js.map +0 -1
  171. package/dist/hoi4_agent_tools/core/source/parser.d.ts +0 -44
  172. package/dist/hoi4_agent_tools/core/source/parser.d.ts.map +0 -1
  173. package/dist/hoi4_agent_tools/core/source/parser.js.map +0 -1
  174. package/dist/hoi4_agent_tools/core/source/rewrite.d.ts +0 -10
  175. package/dist/hoi4_agent_tools/core/source/rewrite.d.ts.map +0 -1
  176. package/dist/hoi4_agent_tools/core/source/rewrite.js.map +0 -1
  177. package/dist/hoi4_agent_tools/core/svg-text.d.ts +0 -34
  178. package/dist/hoi4_agent_tools/core/svg-text.d.ts.map +0 -1
  179. package/dist/hoi4_agent_tools/core/svg-text.js.map +0 -1
  180. package/dist/hoi4_agent_tools/core/transaction-limits.d.ts +0 -9
  181. package/dist/hoi4_agent_tools/core/transaction-limits.d.ts.map +0 -1
  182. package/dist/hoi4_agent_tools/core/transaction-limits.js.map +0 -1
  183. package/dist/hoi4_agent_tools/core/transactions.d.ts +0 -164
  184. package/dist/hoi4_agent_tools/core/transactions.d.ts.map +0 -1
  185. package/dist/hoi4_agent_tools/core/transactions.js.map +0 -1
  186. package/dist/hoi4_agent_tools/core/workspace.d.ts +0 -68
  187. package/dist/hoi4_agent_tools/core/workspace.d.ts.map +0 -1
  188. package/dist/hoi4_agent_tools/core/workspace.js.map +0 -1
  189. package/dist/hoi4_agent_tools/focus/compiler.d.ts +0 -10
  190. package/dist/hoi4_agent_tools/focus/compiler.d.ts.map +0 -1
  191. package/dist/hoi4_agent_tools/focus/compiler.js.map +0 -1
  192. package/dist/hoi4_agent_tools/focus/continuous-render.d.ts +0 -32
  193. package/dist/hoi4_agent_tools/focus/continuous-render.d.ts.map +0 -1
  194. package/dist/hoi4_agent_tools/focus/continuous-render.js.map +0 -1
  195. package/dist/hoi4_agent_tools/focus/drift.d.ts +0 -22
  196. package/dist/hoi4_agent_tools/focus/drift.d.ts.map +0 -1
  197. package/dist/hoi4_agent_tools/focus/drift.js.map +0 -1
  198. package/dist/hoi4_agent_tools/focus/geometry.d.ts +0 -17
  199. package/dist/hoi4_agent_tools/focus/geometry.d.ts.map +0 -1
  200. package/dist/hoi4_agent_tools/focus/geometry.js.map +0 -1
  201. package/dist/hoi4_agent_tools/focus/importer.d.ts +0 -9
  202. package/dist/hoi4_agent_tools/focus/importer.d.ts.map +0 -1
  203. package/dist/hoi4_agent_tools/focus/importer.js.map +0 -1
  204. package/dist/hoi4_agent_tools/focus/index.d.ts +0 -14
  205. package/dist/hoi4_agent_tools/focus/index.d.ts.map +0 -1
  206. package/dist/hoi4_agent_tools/focus/index.js.map +0 -1
  207. package/dist/hoi4_agent_tools/focus/layout.d.ts +0 -5
  208. package/dist/hoi4_agent_tools/focus/layout.d.ts.map +0 -1
  209. package/dist/hoi4_agent_tools/focus/layout.js.map +0 -1
  210. package/dist/hoi4_agent_tools/focus/limits.d.ts +0 -9
  211. package/dist/hoi4_agent_tools/focus/limits.d.ts.map +0 -1
  212. package/dist/hoi4_agent_tools/focus/limits.js.map +0 -1
  213. package/dist/hoi4_agent_tools/focus/lint.d.ts +0 -14
  214. package/dist/hoi4_agent_tools/focus/lint.d.ts.map +0 -1
  215. package/dist/hoi4_agent_tools/focus/lint.js.map +0 -1
  216. package/dist/hoi4_agent_tools/focus/model.d.ts +0 -307
  217. package/dist/hoi4_agent_tools/focus/model.d.ts.map +0 -1
  218. package/dist/hoi4_agent_tools/focus/model.js.map +0 -1
  219. package/dist/hoi4_agent_tools/focus/native-effects.d.ts +0 -9
  220. package/dist/hoi4_agent_tools/focus/native-effects.d.ts.map +0 -1
  221. package/dist/hoi4_agent_tools/focus/native-effects.js.map +0 -1
  222. package/dist/hoi4_agent_tools/focus/planning.d.ts +0 -15
  223. package/dist/hoi4_agent_tools/focus/planning.d.ts.map +0 -1
  224. package/dist/hoi4_agent_tools/focus/planning.js.map +0 -1
  225. package/dist/hoi4_agent_tools/focus/presentation.d.ts +0 -24
  226. package/dist/hoi4_agent_tools/focus/presentation.d.ts.map +0 -1
  227. package/dist/hoi4_agent_tools/focus/presentation.js.map +0 -1
  228. package/dist/hoi4_agent_tools/focus/render.d.ts +0 -39
  229. package/dist/hoi4_agent_tools/focus/render.d.ts.map +0 -1
  230. package/dist/hoi4_agent_tools/focus/render.js.map +0 -1
  231. package/dist/hoi4_agent_tools/focus/service.d.ts +0 -82
  232. package/dist/hoi4_agent_tools/focus/service.d.ts.map +0 -1
  233. package/dist/hoi4_agent_tools/focus/service.js.map +0 -1
  234. package/dist/hoi4_agent_tools/focus/source-update.d.ts +0 -6
  235. package/dist/hoi4_agent_tools/focus/source-update.d.ts.map +0 -1
  236. package/dist/hoi4_agent_tools/focus/source-update.js.map +0 -1
  237. package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts +0 -37
  238. package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts.map +0 -1
  239. package/dist/hoi4_agent_tools/gui/animation-manifest.js.map +0 -1
  240. package/dist/hoi4_agent_tools/gui/assets.d.ts +0 -71
  241. package/dist/hoi4_agent_tools/gui/assets.d.ts.map +0 -1
  242. package/dist/hoi4_agent_tools/gui/assets.js.map +0 -1
  243. package/dist/hoi4_agent_tools/gui/dds.d.ts +0 -17
  244. package/dist/hoi4_agent_tools/gui/dds.d.ts.map +0 -1
  245. package/dist/hoi4_agent_tools/gui/dds.js.map +0 -1
  246. package/dist/hoi4_agent_tools/gui/helpers.d.ts +0 -101
  247. package/dist/hoi4_agent_tools/gui/helpers.d.ts.map +0 -1
  248. package/dist/hoi4_agent_tools/gui/helpers.js.map +0 -1
  249. package/dist/hoi4_agent_tools/gui/index.d.ts +0 -15
  250. package/dist/hoi4_agent_tools/gui/index.d.ts.map +0 -1
  251. package/dist/hoi4_agent_tools/gui/index.js.map +0 -1
  252. package/dist/hoi4_agent_tools/gui/layout.d.ts +0 -6
  253. package/dist/hoi4_agent_tools/gui/layout.d.ts.map +0 -1
  254. package/dist/hoi4_agent_tools/gui/layout.js.map +0 -1
  255. package/dist/hoi4_agent_tools/gui/limits.d.ts +0 -25
  256. package/dist/hoi4_agent_tools/gui/limits.d.ts.map +0 -1
  257. package/dist/hoi4_agent_tools/gui/limits.js.map +0 -1
  258. package/dist/hoi4_agent_tools/gui/renderer.d.ts +0 -18
  259. package/dist/hoi4_agent_tools/gui/renderer.d.ts.map +0 -1
  260. package/dist/hoi4_agent_tools/gui/renderer.js.map +0 -1
  261. package/dist/hoi4_agent_tools/gui/scenario.d.ts +0 -66
  262. package/dist/hoi4_agent_tools/gui/scenario.d.ts.map +0 -1
  263. package/dist/hoi4_agent_tools/gui/scenario.js.map +0 -1
  264. package/dist/hoi4_agent_tools/gui/source-graph.d.ts +0 -7
  265. package/dist/hoi4_agent_tools/gui/source-graph.d.ts.map +0 -1
  266. package/dist/hoi4_agent_tools/gui/source-graph.js.map +0 -1
  267. package/dist/hoi4_agent_tools/gui/source-patch.d.ts +0 -13
  268. package/dist/hoi4_agent_tools/gui/source-patch.d.ts.map +0 -1
  269. package/dist/hoi4_agent_tools/gui/source-patch.js.map +0 -1
  270. package/dist/hoi4_agent_tools/gui/studio.d.ts +0 -86
  271. package/dist/hoi4_agent_tools/gui/studio.d.ts.map +0 -1
  272. package/dist/hoi4_agent_tools/gui/studio.js.map +0 -1
  273. package/dist/hoi4_agent_tools/gui/tga.d.ts +0 -16
  274. package/dist/hoi4_agent_tools/gui/tga.d.ts.map +0 -1
  275. package/dist/hoi4_agent_tools/gui/tga.js.map +0 -1
  276. package/dist/hoi4_agent_tools/gui/types.d.ts +0 -322
  277. package/dist/hoi4_agent_tools/gui/types.d.ts.map +0 -1
  278. package/dist/hoi4_agent_tools/gui/types.js.map +0 -1
  279. package/dist/hoi4_agent_tools/gui/validators.d.ts +0 -8
  280. package/dist/hoi4_agent_tools/gui/validators.d.ts.map +0 -1
  281. package/dist/hoi4_agent_tools/gui/validators.js.map +0 -1
  282. package/dist/hoi4_agent_tools/map/bmp.d.ts +0 -62
  283. package/dist/hoi4_agent_tools/map/bmp.d.ts.map +0 -1
  284. package/dist/hoi4_agent_tools/map/bmp.js.map +0 -1
  285. package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts +0 -5
  286. package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts.map +0 -1
  287. package/dist/hoi4_agent_tools/map/diagnostic-limit.js.map +0 -1
  288. package/dist/hoi4_agent_tools/map/index.d.ts +0 -8
  289. package/dist/hoi4_agent_tools/map/index.d.ts.map +0 -1
  290. package/dist/hoi4_agent_tools/map/index.js.map +0 -1
  291. package/dist/hoi4_agent_tools/map/limits.d.ts +0 -13
  292. package/dist/hoi4_agent_tools/map/limits.d.ts.map +0 -1
  293. package/dist/hoi4_agent_tools/map/limits.js.map +0 -1
  294. package/dist/hoi4_agent_tools/map/model.d.ts +0 -269
  295. package/dist/hoi4_agent_tools/map/model.d.ts.map +0 -1
  296. package/dist/hoi4_agent_tools/map/model.js.map +0 -1
  297. package/dist/hoi4_agent_tools/map/operations.d.ts +0 -401
  298. package/dist/hoi4_agent_tools/map/operations.d.ts.map +0 -1
  299. package/dist/hoi4_agent_tools/map/operations.js.map +0 -1
  300. package/dist/hoi4_agent_tools/map/render.d.ts +0 -90
  301. package/dist/hoi4_agent_tools/map/render.d.ts.map +0 -1
  302. package/dist/hoi4_agent_tools/map/render.js.map +0 -1
  303. package/dist/hoi4_agent_tools/map/service.d.ts +0 -81
  304. package/dist/hoi4_agent_tools/map/service.d.ts.map +0 -1
  305. package/dist/hoi4_agent_tools/map/service.js.map +0 -1
  306. package/dist/hoi4_agent_tools/map/validation.d.ts +0 -23
  307. package/dist/hoi4_agent_tools/map/validation.d.ts.map +0 -1
  308. package/dist/hoi4_agent_tools/map/validation.js.map +0 -1
  309. package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts +0 -4
  310. package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts.map +0 -1
  311. package/dist/hoi4_agent_tools/mcp/prompts/register.js +0 -72
  312. package/dist/hoi4_agent_tools/mcp/prompts/register.js.map +0 -1
  313. package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts +0 -9
  314. package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts.map +0 -1
  315. package/dist/hoi4_agent_tools/mcp/registry/metadata.js +0 -10
  316. package/dist/hoi4_agent_tools/mcp/registry/metadata.js.map +0 -1
  317. package/dist/hoi4_agent_tools/mcp/resources/register.d.ts +0 -5
  318. package/dist/hoi4_agent_tools/mcp/resources/register.d.ts.map +0 -1
  319. package/dist/hoi4_agent_tools/mcp/resources/register.js.map +0 -1
  320. package/dist/hoi4_agent_tools/mcp/security/auth.d.ts +0 -24
  321. package/dist/hoi4_agent_tools/mcp/security/auth.d.ts.map +0 -1
  322. package/dist/hoi4_agent_tools/mcp/security/auth.js.map +0 -1
  323. package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts +0 -47
  324. package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts.map +0 -1
  325. package/dist/hoi4_agent_tools/mcp/server/base-tools.js.map +0 -1
  326. package/dist/hoi4_agent_tools/mcp/server/create.d.ts +0 -5
  327. package/dist/hoi4_agent_tools/mcp/server/create.d.ts.map +0 -1
  328. package/dist/hoi4_agent_tools/mcp/server/create.js.map +0 -1
  329. package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts +0 -138
  330. package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts.map +0 -1
  331. package/dist/hoi4_agent_tools/mcp/server/output-schemas.js.map +0 -1
  332. package/dist/hoi4_agent_tools/mcp/server/progress.d.ts +0 -8
  333. package/dist/hoi4_agent_tools/mcp/server/progress.d.ts.map +0 -1
  334. package/dist/hoi4_agent_tools/mcp/server/progress.js.map +0 -1
  335. package/dist/hoi4_agent_tools/mcp/server/result.d.ts +0 -232
  336. package/dist/hoi4_agent_tools/mcp/server/result.d.ts.map +0 -1
  337. package/dist/hoi4_agent_tools/mcp/server/result.js.map +0 -1
  338. package/dist/hoi4_agent_tools/mcp/server/transaction-execution.d.ts +0 -31
  339. package/dist/hoi4_agent_tools/mcp/server/transaction-execution.d.ts.map +0 -1
  340. package/dist/hoi4_agent_tools/mcp/server/transaction-execution.js.map +0 -1
  341. package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts +0 -5
  342. package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts.map +0 -1
  343. package/dist/hoi4_agent_tools/mcp/tools/focus.js.map +0 -1
  344. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts +0 -117
  345. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts.map +0 -1
  346. package/dist/hoi4_agent_tools/mcp/tools/gui.js.map +0 -1
  347. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts +0 -5
  348. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts.map +0 -1
  349. package/dist/hoi4_agent_tools/mcp/tools/map.js.map +0 -1
  350. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts +0 -58
  351. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts.map +0 -1
  352. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js.map +0 -1
  353. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts +0 -26
  354. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts.map +0 -1
  355. package/dist/hoi4_agent_tools/mcp/transports/event-store.js.map +0 -1
  356. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts +0 -28
  357. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts.map +0 -1
  358. package/dist/hoi4_agent_tools/mcp/transports/http.js.map +0 -1
  359. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts +0 -15
  360. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts.map +0 -1
  361. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js.map +0 -1
  362. package/dist/hoi4_agent_tools/runtime.d.ts +0 -4
  363. package/dist/hoi4_agent_tools/runtime.d.ts.map +0 -1
  364. package/dist/hoi4_agent_tools/runtime.js.map +0 -1
  365. package/dist/hoi4_agent_tools/schemas/common.d.ts +0 -74
  366. package/dist/hoi4_agent_tools/schemas/common.d.ts.map +0 -1
  367. package/dist/hoi4_agent_tools/schemas/common.js.map +0 -1
  368. package/dist/hoi4_agent_tools/schemas/focus.d.ts +0 -784
  369. package/dist/hoi4_agent_tools/schemas/focus.d.ts.map +0 -1
  370. package/dist/hoi4_agent_tools/schemas/focus.js.map +0 -1
  371. package/dist/hoi4_agent_tools/schemas/index.d.ts +0 -5
  372. package/dist/hoi4_agent_tools/schemas/index.d.ts.map +0 -1
  373. package/dist/hoi4_agent_tools/schemas/index.js +0 -5
  374. package/dist/hoi4_agent_tools/schemas/index.js.map +0 -1
  375. package/dist/hoi4_agent_tools/schemas/map.d.ts +0 -654
  376. package/dist/hoi4_agent_tools/schemas/map.d.ts.map +0 -1
  377. package/dist/hoi4_agent_tools/schemas/map.js.map +0 -1
  378. package/dist/hoi4_agent_tools/schemas/transaction.d.ts +0 -259
  379. package/dist/hoi4_agent_tools/schemas/transaction.d.ts.map +0 -1
  380. package/dist/hoi4_agent_tools/schemas/transaction.js.map +0 -1
  381. package/dist/hoi4_agent_tools/version.d.ts +0 -6
  382. package/dist/hoi4_agent_tools/version.d.ts.map +0 -1
  383. package/dist/hoi4_agent_tools/version.js.map +0 -1
  384. package/dist/index.d.ts +0 -3
  385. package/dist/index.d.ts.map +0 -1
  386. package/dist/index.js +0 -3
  387. package/dist/index.js.map +0 -1
  388. package/docs/adr/0001-runtime-and-language.md +0 -16
  389. package/docs/adr/0002-lossless-source-model.md +0 -18
  390. package/docs/adr/0003-image-and-font-codecs.md +0 -18
  391. package/docs/adr/0004-focus-layout.md +0 -16
  392. package/docs/adr/0005-offline-rendering.md +0 -18
  393. package/docs/adr/0006-mcp-sdk-and-protocol.md +0 -16
  394. package/docs/adr/0007-storage-and-transactions.md +0 -24
  395. package/docs/adr/0008-test-strategy.md +0 -18
  396. package/docs/adr/0009-packaging-and-registry.md +0 -16
  397. package/docs/adr/0010-unsupported-and-refusal-policy.md +0 -18
  398. package/docs/adr/0011-http-security.md +0 -16
  399. package/docs/adr/0012-autonomous-rewrites.md +0 -55
  400. package/docs/adr/README.md +0 -14
  401. package/docs/agent-integration.md +0 -146
  402. package/docs/architecture.md +0 -76
  403. package/docs/artifacts.md +0 -136
  404. package/docs/compatibility.md +0 -33
  405. package/docs/completion-report.md +0 -122
  406. package/docs/configuration.md +0 -305
  407. package/docs/focus-workflow.md +0 -197
  408. package/docs/gui-workflow.md +0 -125
  409. package/docs/limitations.md +0 -32
  410. package/docs/map-workflow.md +0 -95
  411. package/docs/performance.md +0 -117
  412. package/docs/release.md +0 -222
  413. package/docs/research/mcp-2026-07-10.md +0 -52
  414. package/docs/research/source-ledger.md +0 -68
  415. package/docs/security.md +0 -145
  416. package/docs/self-hosting.md +0 -170
  417. package/docs/testing.md +0 -43
  418. package/docs/third-party-notices.md +0 -11
  419. package/docs/transactions.md +0 -180
  420. package/docs/troubleshooting.md +0 -54
  421. package/schemas/configuration.schema.json +0 -795
  422. package/schemas/continuous-focus-palette.schema.json +0 -325
  423. package/schemas/focus-plan.schema.json +0 -927
  424. package/schemas/focus-planning-sidecar.schema.json +0 -379
  425. package/schemas/gui-animation-source.schema.json +0 -176
  426. package/schemas/gui-helper.schema.json +0 -301
  427. package/schemas/gui-scenario.schema.json +0 -298
  428. package/schemas/map-operation.schema.json +0 -2284
  429. package/schemas/operation-result.schema.json +0 -344
  430. package/schemas/transaction-manifest.schema.json +0 -685
@@ -6,19 +6,22 @@ import { RenderBudget } from '../../core/render-budget.js';
6
6
  import { emptyServiceResult, ServiceError } from '../../core/result.js';
7
7
  import { parseClausewitz } from '../../core/source/index.js';
8
8
  import { readDependenciesFromScannedFiles } from '../../core/transactions.js';
9
- import { FocusWorkbench, FOCUS_RENDER_MAX_OUTPUT_SCALE, FOCUS_RENDER_MIN_OUTPUT_SCALE, assertFocusPlanAuthority, detectContinuousFocusDrift, detectFocusDrift, focusPlanHash, focusPresentationEvidence, focusPlanningSidecarPath, importContinuousFocusPalettes, importFocusTrees, linkContinuousFocusPalettes, parseFocusPlanningSidecar, renderContinuousFocusPalette, renderFocusTree, resolveFocusPresentation, enrichFocusPlanFromSidecar, } from '../../focus/index.js';
10
- import { continuousFocusPaletteSchema, focusLayoutDecisionSchema, focusLayoutSchema, focusTreePlanSchema, } from '../../schemas/focus.js';
9
+ import { FocusWorkbench, FOCUS_RENDER_MAX_OUTPUT_SCALE, FOCUS_RENDER_MIN_OUTPUT_SCALE, assertCompactLayoutQuality, compactFocusTreePlanAsync, focusPlanHash, focusPresentationEvidence, focusPlanningSidecarPath, importContinuousFocusPalettes, importFocusTrees, linkContinuousFocusPalettes, parseFocusPlanningSidecar, renderContinuousFocusPalette, renderFocusTree, resolveFocusPresentation, enrichFocusPlanFromSidecar, } from '../../focus/index.js';
10
+ import { continuousFocusPaletteSchema, focusLayoutMetricsSchema, focusLayoutSchema, focusTreePlanSchema, } from '../../schemas/focus.js';
11
11
  import { workspaceIdSchema, workspaceRelativePathSchema } from '../../schemas/common.js';
12
12
  import { PACKAGE_VERSION } from '../../version.js';
13
13
  import { nonNegativeIntegerSchema, renderHashesSchema, sha256Schema, } from '../server/output-schemas.js';
14
14
  import { progressReporter } from '../server/progress.js';
15
15
  import { errorResult, setInlineFilesScanned, strictOperationResultSchema, toolResult, } from '../server/result.js';
16
- import { requireServerScope, transactionResourceLink, } from '../server/base-tools.js';
17
- import { autonomousFailureContext, autonomousResultArtifacts, autonomousWrites, executePlannedTransaction, } from '../server/transaction-execution.js';
18
- const focusScanOutputSchema = strictOperationResultSchema(z
16
+ import { requireServerScope } from '../server/base-tools.js';
17
+ import { compactValidatedInputSchema } from '../server/context-schemas.js';
18
+ import { autonomousFailureContext, autonomousResultArtifacts, executePlannedTransaction, } from '../server/transaction-execution.js';
19
+ const focusInspectOutputSchema = strictOperationResultSchema(z
19
20
  .object({
21
+ mode: z.enum(['national', 'continuous']),
20
22
  revision: sha256Schema,
21
23
  treeCount: nonNegativeIntegerSchema,
24
+ paletteCount: nonNegativeIntegerSchema,
22
25
  trees: z
23
26
  .array(z
24
27
  .object({
@@ -29,36 +32,23 @@ const focusScanOutputSchema = strictOperationResultSchema(z
29
32
  continuousPaletteCount: nonNegativeIntegerSchema,
30
33
  continuousFocusCount: nonNegativeIntegerSchema,
31
34
  resolvedTitleCount: nonNegativeIntegerSchema,
32
- })
33
- .strict())
34
- .max(100),
35
- })
36
- .strict());
37
- const focusLintOutputSchema = strictOperationResultSchema(z.discriminatedUnion('mode', [
38
- z
39
- .object({
40
- mode: z.literal('national'),
41
- treeId: z.string().max(256),
42
- focusCount: nonNegativeIntegerSchema,
43
35
  layoutHash: sha256Schema,
36
+ layoutDecisionCount: nonNegativeIntegerSchema,
37
+ layoutMetrics: focusLayoutMetricsSchema,
44
38
  diagnosticCount: nonNegativeIntegerSchema,
45
39
  })
46
- .strict(),
47
- z
40
+ .strict())
41
+ .max(100),
42
+ palettes: z
43
+ .array(z
48
44
  .object({
49
- mode: z.literal('continuous'),
50
- paletteId: z.string().max(256),
45
+ id: z.string().max(256),
46
+ sourcePath: z.string().max(4096),
51
47
  focusCount: nonNegativeIntegerSchema,
52
48
  diagnosticCount: nonNegativeIntegerSchema,
53
49
  })
54
- .strict(),
55
- ]));
56
- const focusLayoutOutputSchema = strictOperationResultSchema(z
57
- .object({
58
- treeId: z.string().max(256),
59
- layoutHash: sha256Schema,
60
- nodeCount: nonNegativeIntegerSchema,
61
- decisions: z.array(focusLayoutDecisionSchema).max(100),
50
+ .strict())
51
+ .max(100),
62
52
  })
63
53
  .strict());
64
54
  const focusRenderOutputSchema = strictOperationResultSchema(z.discriminatedUnion('mode', [
@@ -97,12 +87,6 @@ const focusDriftBaseOutputSchema = z
97
87
  ]),
98
88
  sourceChanged: z.boolean(),
99
89
  planChanged: z.boolean(),
100
- requiresAuthority: z.boolean(),
101
- savedPlanHash: sha256Schema,
102
- currentPlanHash: z.string().max(256),
103
- importedPlanHash: sha256Schema,
104
- savedSourceHash: sha256Schema,
105
- currentSourceHash: sha256Schema,
106
90
  })
107
91
  .strict();
108
92
  const focusDriftOutputSchema = focusDriftBaseOutputSchema;
@@ -114,11 +98,10 @@ const focusPlanOutputSchema = strictOperationResultSchema(z.discriminatedUnion('
114
98
  treeId: z.string().max(256),
115
99
  drift: focusDriftOutputSchema,
116
100
  created: z.boolean(),
117
- execution: z.enum(['planned', 'applied', 'blocked', 'unchanged']),
101
+ execution: z.enum(['applied', 'blocked', 'unchanged']),
118
102
  layoutHash: sha256Schema,
119
- expiresAt: z.iso.datetime(),
120
- transactionFileCount: nonNegativeIntegerSchema,
121
- transactionArtifactCount: nonNegativeIntegerSchema,
103
+ fileCount: nonNegativeIntegerSchema,
104
+ artifactCount: nonNegativeIntegerSchema,
122
105
  })
123
106
  .strict(),
124
107
  z
@@ -127,27 +110,23 @@ const focusPlanOutputSchema = strictOperationResultSchema(z.discriminatedUnion('
127
110
  paletteId: z.string().max(256),
128
111
  drift: continuousFocusDriftOutputSchema,
129
112
  created: z.boolean(),
130
- execution: z.enum(['planned', 'applied', 'blocked', 'unchanged']),
131
- expiresAt: z.iso.datetime(),
132
- transactionFileCount: nonNegativeIntegerSchema,
133
- transactionArtifactCount: nonNegativeIntegerSchema,
113
+ execution: z.enum(['applied', 'blocked', 'unchanged']),
114
+ fileCount: nonNegativeIntegerSchema,
115
+ artifactCount: nonNegativeIntegerSchema,
134
116
  })
135
117
  .strict(),
136
118
  ]));
137
- const focusPathInput = z
138
- .object({
139
- workspaceId: workspaceIdSchema,
140
- relativePath: workspaceRelativePathSchema,
141
- treeId: z.string().min(1).max(256).optional(),
142
- })
143
- .strict();
144
- const focusLintInput = z
119
+ const compactFocusPlanSchema = compactValidatedInputSchema(z.union([focusTreePlanSchema, continuousFocusPaletteSchema]), `Complete focus plan: https://github.com/klimPaskov/hoi4-agent-tools/blob/v${PACKAGE_VERSION}/docs/focus.md`);
120
+ const focusInspectInput = z
145
121
  .object({
146
122
  mode: z.enum(['national', 'continuous']).optional(),
147
123
  workspaceId: workspaceIdSchema,
148
- relativePath: workspaceRelativePathSchema,
124
+ relativePath: workspaceRelativePathSchema.optional(),
149
125
  treeId: z.string().min(1).max(256).optional(),
150
126
  paletteId: z.string().min(1).max(256).optional(),
127
+ previous: focusLayoutSchema.optional(),
128
+ laneSpacing: z.number().int().min(1).max(100).optional(),
129
+ nodeSpacing: z.number().int().min(1).max(100).optional(),
151
130
  })
152
131
  .strict()
153
132
  .superRefine((value, context) => {
@@ -164,6 +143,22 @@ const focusLintInput = z
164
143
  path: ['treeId'],
165
144
  message: 'treeId is only valid in national mode',
166
145
  });
146
+ if (mode === 'continuous') {
147
+ for (const field of ['previous', 'laneSpacing', 'nodeSpacing']) {
148
+ if (value[field] !== undefined)
149
+ context.addIssue({
150
+ code: 'custom',
151
+ path: [field],
152
+ message: `${field} is only valid in national mode`,
153
+ });
154
+ }
155
+ }
156
+ if (value.previous !== undefined && value.treeId === undefined)
157
+ context.addIssue({
158
+ code: 'custom',
159
+ path: ['previous'],
160
+ message: 'previous requires treeId so it applies to exactly one tree',
161
+ });
167
162
  });
168
163
  const focusRenderInput = z
169
164
  .object({
@@ -216,8 +211,9 @@ const focusPlanInput = z
216
211
  mode: z.enum(['national', 'continuous']).optional(),
217
212
  workspaceId: workspaceIdSchema,
218
213
  relativePath: workspaceRelativePathSchema,
219
- plan: z.union([focusTreePlanSchema, continuousFocusPaletteSchema]),
220
- authority: z.enum(['plan', 'source']).optional(),
214
+ treeId: z.string().min(1).max(256).optional(),
215
+ layoutMode: z.enum(['authored', 'compact']).default('authored'),
216
+ plan: compactFocusPlanSchema.optional(),
221
217
  createIfMissing: z.boolean().default(false),
222
218
  horizontalSpacing: z.number().int().min(80).max(1000).optional(),
223
219
  verticalSpacing: z.number().int().min(60).max(1000).optional(),
@@ -232,13 +228,31 @@ const focusPlanInput = z
232
228
  .superRefine((value, context) => {
233
229
  const mode = value.mode ?? 'national';
234
230
  const schema = mode === 'continuous' ? continuousFocusPaletteSchema : focusTreePlanSchema;
235
- if (!schema.safeParse(value.plan).success)
231
+ if (value.plan !== undefined && !schema.safeParse(value.plan).success)
236
232
  context.addIssue({
237
233
  code: 'custom',
238
234
  path: ['plan'],
239
235
  message: `plan must be a ${mode} focus plan`,
240
236
  });
241
237
  if (mode === 'continuous') {
238
+ if (value.plan === undefined)
239
+ context.addIssue({
240
+ code: 'custom',
241
+ path: ['plan'],
242
+ message: 'plan is required in continuous mode',
243
+ });
244
+ if (value.treeId !== undefined)
245
+ context.addIssue({
246
+ code: 'custom',
247
+ path: ['treeId'],
248
+ message: 'treeId is only valid in national mode',
249
+ });
250
+ if (value.layoutMode !== 'authored')
251
+ context.addIssue({
252
+ code: 'custom',
253
+ path: ['layoutMode'],
254
+ message: 'compact layout mode is only valid in national mode',
255
+ });
242
256
  for (const [field, fieldValue] of [
243
257
  ['horizontalSpacing', value.horizontalSpacing],
244
258
  ['verticalSpacing', value.verticalSpacing],
@@ -249,10 +263,39 @@ const focusPlanInput = z
249
263
  context.addIssue({
250
264
  code: 'custom',
251
265
  path: [field],
252
- message: `${field} is only valid for national focus transaction review renders`,
266
+ message: `${field} is only valid for national focus review renders`,
253
267
  });
254
268
  }
255
269
  }
270
+ else {
271
+ if (value.plan === undefined && value.layoutMode !== 'compact')
272
+ context.addIssue({
273
+ code: 'custom',
274
+ path: ['plan'],
275
+ message: 'plan is required unless layoutMode is compact',
276
+ });
277
+ if (value.plan === undefined && value.treeId === undefined)
278
+ context.addIssue({
279
+ code: 'custom',
280
+ path: ['treeId'],
281
+ message: 'treeId is required for plan-free compact reflow',
282
+ });
283
+ if (value.plan === undefined && value.createIfMissing)
284
+ context.addIssue({
285
+ code: 'custom',
286
+ path: ['createIfMissing'],
287
+ message: 'plan-free compact reflow requires an existing focus source',
288
+ });
289
+ if (value.plan !== undefined &&
290
+ value.treeId !== undefined &&
291
+ 'id' in value.plan &&
292
+ value.plan.id !== value.treeId)
293
+ context.addIssue({
294
+ code: 'custom',
295
+ path: ['treeId'],
296
+ message: 'treeId must match the supplied national focus plan',
297
+ });
298
+ }
256
299
  });
257
300
  const artifactProducing = {
258
301
  readOnlyHint: false,
@@ -260,9 +303,17 @@ const artifactProducing = {
260
303
  idempotentHint: true,
261
304
  openWorldHint: false,
262
305
  };
306
+ const LARGE_FOCUS_RENDER_NODE_THRESHOLD = 200;
307
+ const LARGE_FOCUS_RENDER_SCALE = 0.5;
308
+ function automaticFocusRenderScale(focusCount) {
309
+ return focusCount >= LARGE_FOCUS_RENDER_NODE_THRESHOLD ? LARGE_FOCUS_RENDER_SCALE : 1;
310
+ }
263
311
  function compactDrift(drift) {
264
- const { currentSourcePlan: _currentSourcePlan, ...summary } = drift;
265
- return summary;
312
+ return {
313
+ status: drift.status,
314
+ sourceChanged: drift.sourceChanged,
315
+ planChanged: drift.planChanged,
316
+ };
266
317
  }
267
318
  function normalizedRoot(value) {
268
319
  return value.replaceAll('\\', '/').replace(/^\.\//u, '').replace(/\/+$/u, '').toLowerCase();
@@ -392,25 +443,102 @@ function validationFromDiagnostics(diagnostics) {
392
443
  };
393
444
  }
394
445
  export function registerFocusTools(server, engine, context) {
395
- const autonomous = autonomousWrites(engine);
396
446
  const workbench = new FocusWorkbench(engine.resolver, engine.transactions, engine.artifacts);
397
- server.registerTool('hoi4.focus_scan', {
398
- title: 'Scan focus trees',
399
- description: 'Import active focus-tree source through the shared lossless parser and return compact summaries plus a full resource artifact.',
400
- inputSchema: z
401
- .object({
402
- workspaceId: workspaceIdSchema,
403
- relativePath: workspaceRelativePathSchema.optional(),
404
- })
405
- .strict(),
406
- outputSchema: focusScanOutputSchema,
447
+ server.registerTool('hoi4.focus_inspect', {
448
+ title: 'Inspect focus trees',
449
+ description: 'Inspect national trees or continuous palettes for creation and cleanup, including complete plans, references, diagnostics, and stable layout decisions.',
450
+ inputSchema: focusInspectInput,
451
+ outputSchema: focusInspectOutputSchema,
407
452
  annotations: artifactProducing,
408
- }, async ({ workspaceId, relativePath }, extra) => {
453
+ }, async (input, extra) => {
454
+ const { workspaceId, relativePath } = input;
409
455
  try {
410
456
  const progress = progressReporter(extra);
411
457
  await progress.report(0, 3, 'Building shared workspace index');
412
458
  const snapshot = await engine.scan(workspaceId, {}, context.principal, progress.signal);
413
459
  const workspace = engine.resolver.get(workspaceId, context.principal);
460
+ if (input.mode === 'continuous') {
461
+ const selectedFiles = activeContinuousFocusFiles(snapshot).filter((file) => relativePath === undefined || file.relativePath === relativePath);
462
+ if (selectedFiles.length === 0) {
463
+ throw new ServiceError('CONTINUOUS_FOCUS_SOURCE_NOT_FOUND', 'No active continuous focus source matched the request');
464
+ }
465
+ const diagnostics = [];
466
+ const importedPalettes = [];
467
+ for (const file of selectedFiles) {
468
+ progress.signal.throwIfAborted();
469
+ const imported = importContinuousFocusPalettes(parseClausewitz(file.bytes, file.displayPath));
470
+ importedPalettes.push(...imported.continuousFocusPalettes);
471
+ diagnostics.push(...imported.diagnostics);
472
+ }
473
+ const palettes = importedPalettes.filter(({ id }) => input.paletteId === undefined || id === input.paletteId);
474
+ if (palettes.length === 0) {
475
+ throw new ServiceError('CONTINUOUS_FOCUS_PALETTE_NOT_FOUND', input.paletteId === undefined
476
+ ? 'The selected source contains no continuous focus palette'
477
+ : `Continuous focus palette was not found: ${input.paletteId}`);
478
+ }
479
+ const paletteDiagnosticCounts = new Map();
480
+ for (const palette of palettes) {
481
+ const lintDiagnostics = workbench.lintContinuous(palette);
482
+ paletteDiagnosticCounts.set(palette.id, lintDiagnostics.length);
483
+ diagnostics.push(...lintDiagnostics);
484
+ }
485
+ const presentation = await resolveFocusPresentation({
486
+ plans: [],
487
+ palettes,
488
+ files: snapshot.files,
489
+ index: snapshot.index,
490
+ scanner: engine.scanner,
491
+ workspace,
492
+ signal: progress.signal,
493
+ });
494
+ diagnostics.push(...presentation.diagnostics);
495
+ await progress.report(2, 3, 'Writing continuous focus inspection');
496
+ const completeSourceHashes = Object.fromEntries(Object.entries({
497
+ ...Object.fromEntries(selectedFiles.map(({ displayPath, sha256 }) => [displayPath, sha256])),
498
+ ...presentation.sourceHashes,
499
+ }).sort(([left], [right]) => compareCodeUnits(left, right)));
500
+ const sourceEvidence = boundedSourceHashEvidence(completeSourceHashes);
501
+ const artifact = await engine.artifacts.putChunked(workspace, `focus-inspect.${snapshot.revision.slice(0, 16)}.json`, 'application/json', `${canonicalJson({
502
+ schemaVersion: 1,
503
+ mode: 'continuous',
504
+ revision: snapshot.revision,
505
+ continuousFocusPalettes: palettes,
506
+ presentation: focusPresentationEvidence(presentation),
507
+ sourceHashes: completeSourceHashes,
508
+ diagnostics,
509
+ })}\n`, {
510
+ kind: 'focus-inspect',
511
+ toolVersion: PACKAGE_VERSION,
512
+ schemaVersion: 'focus-inspect.v1',
513
+ sourceHashes: sourceEvidence.sourceHashes,
514
+ metadata: { sourceHashInventory: sourceEvidence.inventory },
515
+ }, 'Continuous focus plans and diagnostics', progress.signal);
516
+ const result = emptyServiceResult(workspaceId, {
517
+ mode: 'continuous',
518
+ revision: snapshot.revision,
519
+ treeCount: 0,
520
+ paletteCount: palettes.length,
521
+ trees: [],
522
+ palettes: palettes.slice(0, 100).map((palette) => ({
523
+ id: palette.id,
524
+ sourcePath: palette.provenance.sourcePath,
525
+ focusCount: palette.focuses.length,
526
+ diagnosticCount: paletteDiagnosticCounts.get(palette.id) ?? 0,
527
+ })),
528
+ });
529
+ result.code = 'FOCUS_INSPECTED';
530
+ setInlineFilesScanned(result, [
531
+ ...new Set([
532
+ ...selectedFiles.map(({ displayPath }) => displayPath),
533
+ ...presentation.filesScanned,
534
+ ]),
535
+ ].sort((left, right) => compareCodeUnits(left, right)));
536
+ result.diagnostics = diagnostics.slice(0, 100);
537
+ result.artifacts = [publicArtifactLink(artifact)];
538
+ result.validation = validationFromDiagnostics(diagnostics);
539
+ await progress.report(3, 3, 'Continuous focus inspection complete');
540
+ return toolResult(result);
541
+ }
414
542
  const selectedFiles = activeFocusFiles(snapshot, workspace.registration.roots.focus).filter((file) => relativePath === undefined || file.relativePath === relativePath);
415
543
  if (selectedFiles.length === 0) {
416
544
  throw new ServiceError('FOCUS_SOURCE_NOT_FOUND', 'No active focus source matched the request');
@@ -419,16 +547,40 @@ export function registerFocusTools(server, engine, context) {
419
547
  const resolved = activeSidecar(snapshot, file);
420
548
  return resolved === undefined ? [] : [resolved.file];
421
549
  });
422
- const plans = [];
550
+ const importedPlans = [];
423
551
  const diagnostics = [];
424
552
  const paletteImport = continuousPalettes(snapshot);
425
553
  diagnostics.push(...paletteImport.diagnostics);
426
554
  for (const file of selectedFiles) {
427
555
  progress.signal.throwIfAborted();
428
556
  const imported = importFocusFile(snapshot, file, paletteImport.palettes);
429
- plans.push(...imported.plans);
557
+ importedPlans.push(...imported.plans);
430
558
  diagnostics.push(...imported.diagnostics);
431
559
  }
560
+ const plans = importedPlans.filter(({ id }) => input.treeId === undefined || id === input.treeId);
561
+ if (plans.length === 0) {
562
+ throw new ServiceError('FOCUS_TREE_NOT_FOUND', input.treeId === undefined
563
+ ? 'The selected source contains no national focus tree'
564
+ : `Focus tree was not found: ${input.treeId}`);
565
+ }
566
+ const inspectedPlans = [];
567
+ for (const plan of plans) {
568
+ const layout = await workbench.layoutAsync(plan, {
569
+ ...(input.previous === undefined
570
+ ? {}
571
+ : { previous: input.previous }),
572
+ ...(input.laneSpacing === undefined ? {} : { laneSpacing: input.laneSpacing }),
573
+ ...(input.nodeSpacing === undefined ? {} : { nodeSpacing: input.nodeSpacing }),
574
+ signal: progress.signal,
575
+ });
576
+ const lintDiagnostics = workbench.lint(plan, {
577
+ index: snapshot.index,
578
+ references: referenceCatalog(snapshot),
579
+ layout,
580
+ });
581
+ diagnostics.push(...lintDiagnostics);
582
+ inspectedPlans.push({ plan, layout, diagnosticCount: lintDiagnostics.length });
583
+ }
432
584
  const presentation = await resolveFocusPresentation({
433
585
  plans,
434
586
  palettes: paletteImport.palettes,
@@ -439,7 +591,7 @@ export function registerFocusTools(server, engine, context) {
439
591
  signal: progress.signal,
440
592
  });
441
593
  diagnostics.push(...presentation.diagnostics);
442
- await progress.report(2, 3, 'Writing imported planning models');
594
+ await progress.report(2, 3, 'Writing focus plans, diagnostics, and layouts');
443
595
  const completeSourceHashes = Object.fromEntries(Object.entries({
444
596
  ...Object.fromEntries([
445
597
  ...selectedFiles,
@@ -449,25 +601,32 @@ export function registerFocusTools(server, engine, context) {
449
601
  ...presentation.sourceHashes,
450
602
  }).sort(([left], [right]) => compareCodeUnits(left, right)));
451
603
  const sourceEvidence = boundedSourceHashEvidence(completeSourceHashes);
452
- const artifact = await engine.artifacts.putChunked(workspace, `focus-scan.${snapshot.revision.slice(0, 16)}.json`, 'application/json', `${canonicalJson({
604
+ const artifact = await engine.artifacts.putChunked(workspace, `focus-inspect.${snapshot.revision.slice(0, 16)}.json`, 'application/json', `${canonicalJson({
453
605
  schemaVersion: 1,
454
606
  revision: snapshot.revision,
455
607
  plans,
608
+ layouts: inspectedPlans.map(({ plan, layout, diagnosticCount }) => ({
609
+ treeId: plan.id,
610
+ layout,
611
+ diagnosticCount,
612
+ })),
456
613
  continuousFocusPalettes: paletteImport.palettes,
457
614
  presentation: focusPresentationEvidence(presentation),
458
615
  sourceHashes: completeSourceHashes,
459
616
  diagnostics,
460
617
  })}\n`, {
461
- kind: 'focus-scan',
618
+ kind: 'focus-inspect',
462
619
  toolVersion: PACKAGE_VERSION,
463
- schemaVersion: 'focus-scan.v1',
620
+ schemaVersion: 'focus-inspect.v1',
464
621
  sourceHashes: sourceEvidence.sourceHashes,
465
622
  metadata: { sourceHashInventory: sourceEvidence.inventory },
466
- }, 'Imported focus planning models and source-linked diagnostics', progress.signal);
623
+ }, 'Focus plans, diagnostics, and stable layout decisions', progress.signal);
467
624
  const result = emptyServiceResult(workspaceId, {
625
+ mode: 'national',
468
626
  revision: snapshot.revision,
469
627
  treeCount: plans.length,
470
- trees: plans.slice(0, 100).map((plan) => ({
628
+ paletteCount: paletteImport.palettes.length,
629
+ trees: inspectedPlans.slice(0, 100).map(({ plan, layout, diagnosticCount }) => ({
471
630
  id: plan.id,
472
631
  sourcePath: plan.provenance.sourcePath,
473
632
  focusCount: plan.focuses.length,
@@ -475,9 +634,14 @@ export function registerFocusTools(server, engine, context) {
475
634
  continuousPaletteCount: plan.continuousFocusPaletteIds.length,
476
635
  continuousFocusCount: plan.continuousFocusIds.length,
477
636
  resolvedTitleCount: plan.focuses.filter(({ id }) => presentation.entries[id]?.titleSourceLocation !== undefined).length,
637
+ layoutHash: layout.layoutHash,
638
+ layoutDecisionCount: layout.decisions.length,
639
+ layoutMetrics: layout.metrics,
640
+ diagnosticCount,
478
641
  })),
642
+ palettes: [],
479
643
  });
480
- result.code = 'FOCUS_SCANNED';
644
+ result.code = 'FOCUS_INSPECTED';
481
645
  setInlineFilesScanned(result, [
482
646
  ...new Set([
483
647
  ...selectedFiles.map(({ displayPath }) => displayPath),
@@ -489,143 +653,7 @@ export function registerFocusTools(server, engine, context) {
489
653
  result.diagnostics = diagnostics.slice(0, 100);
490
654
  result.artifacts = [publicArtifactLink(artifact)];
491
655
  result.validation = validationFromDiagnostics(diagnostics);
492
- await progress.report(3, 3, 'Focus scan complete');
493
- return toolResult(result);
494
- }
495
- catch (error) {
496
- return errorResult(error, workspaceId);
497
- }
498
- });
499
- server.registerTool('hoi4.focus_lint', {
500
- title: 'Lint focus source',
501
- description: 'Lint one national focus tree or continuous focus palette. Omit mode for backward-compatible national behavior.',
502
- inputSchema: focusLintInput,
503
- outputSchema: focusLintOutputSchema,
504
- annotations: artifactProducing,
505
- }, async (input, extra) => {
506
- const { workspaceId, relativePath } = input;
507
- try {
508
- const progress = progressReporter(extra);
509
- await progress.report(0, 3, 'Importing and indexing focus source');
510
- const snapshot = await engine.scan(workspaceId, {}, context.principal, progress.signal);
511
- const workspace = engine.resolver.get(workspaceId, context.principal);
512
- if (input.mode === 'continuous') {
513
- selectedContinuousFocusFile(snapshot, relativePath);
514
- const imported = await workbench.importContinuousPath(workspaceId, relativePath, context.principal);
515
- const plan = selectContinuousPlan(imported.result, input.paletteId);
516
- const diagnostics = [...imported.result.diagnostics, ...workbench.lintContinuous(plan)];
517
- await progress.report(2, 3, 'Writing continuous focus lint evidence');
518
- const artifact = await engine.artifacts.put(workspace, `${plan.id.replace(/[^A-Za-z0-9._-]/gu, '_')}.continuous-focus-lint.json`, 'application/json', `${canonicalJson({ schemaVersion: 1, mode: 'continuous', paletteId: plan.id, diagnostics })}\n`, {
519
- kind: 'continuous-focus-lint',
520
- toolVersion: PACKAGE_VERSION,
521
- schemaVersion: 'continuous-focus-lint.v1',
522
- sourceHashes: { [plan.provenance.sourcePath]: plan.provenance.sourceHash },
523
- }, 'Complete continuous focus lint report', progress.signal);
524
- const result = emptyServiceResult(workspaceId, {
525
- mode: 'continuous',
526
- paletteId: plan.id,
527
- focusCount: plan.focuses.length,
528
- diagnosticCount: diagnostics.length,
529
- });
530
- result.code = 'CONTINUOUS_FOCUS_LINTED';
531
- setInlineFilesScanned(result, [plan.provenance.sourcePath]);
532
- result.diagnostics = diagnostics.slice(0, 100);
533
- result.artifacts = [publicArtifactLink(artifact)];
534
- result.validation = validationFromDiagnostics(diagnostics);
535
- await progress.report(3, 3, 'Continuous focus lint complete');
536
- return toolResult(result);
537
- }
538
- const paletteImport = continuousPalettes(snapshot);
539
- const imported = importFocusFile(snapshot, selectedFocusFile(snapshot, workspace.registration.roots.focus, relativePath), paletteImport.palettes);
540
- const plan = selectPlan(imported, input.treeId);
541
- const layout = await workbench.layoutAsync(plan, { signal: progress.signal });
542
- const diagnostics = [
543
- ...paletteImport.diagnostics,
544
- ...imported.diagnostics,
545
- ...workbench.lint(plan, {
546
- index: snapshot.index,
547
- references: referenceCatalog(snapshot),
548
- layout,
549
- }),
550
- ];
551
- await progress.report(2, 3, 'Writing focus lint evidence');
552
- const artifact = await engine.artifacts.put(workspace, `${plan.id.replace(/[^A-Za-z0-9._-]/gu, '_')}.focus-lint.json`, 'application/json', `${canonicalJson({ schemaVersion: 1, treeId: plan.id, layoutHash: layout.layoutHash, diagnostics })}\n`, {
553
- kind: 'focus-lint',
554
- toolVersion: PACKAGE_VERSION,
555
- schemaVersion: 'focus-lint.v1',
556
- sourceHashes: { [plan.provenance.sourcePath]: plan.provenance.sourceHash },
557
- }, 'Complete focus lint report', progress.signal);
558
- const result = emptyServiceResult(workspaceId, {
559
- mode: 'national',
560
- treeId: plan.id,
561
- focusCount: plan.focuses.length,
562
- layoutHash: layout.layoutHash,
563
- diagnosticCount: diagnostics.length,
564
- });
565
- result.code = 'FOCUS_LINTED';
566
- setInlineFilesScanned(result, [plan.provenance.sourcePath]);
567
- result.diagnostics = diagnostics.slice(0, 100);
568
- result.artifacts = [publicArtifactLink(artifact)];
569
- result.validation = validationFromDiagnostics(diagnostics);
570
- await progress.report(3, 3, 'Focus lint complete');
571
- return toolResult(result);
572
- }
573
- catch (error) {
574
- return errorResult(error, workspaceId);
575
- }
576
- });
577
- server.registerTool('hoi4.focus_layout', {
578
- title: 'Plan stable focus layout',
579
- description: 'Create a deterministic constraint layout while preserving pinned, relative, and previous automatic positions. Imported authored coordinates remain fixed; a full existing-tree repair must submit a complete plan whose movable nodes use position.mode "auto".',
580
- inputSchema: focusPathInput
581
- .extend({
582
- previous: focusLayoutSchema.optional(),
583
- laneSpacing: z.number().int().min(1).max(100).optional(),
584
- nodeSpacing: z.number().int().min(1).max(100).optional(),
585
- })
586
- .strict(),
587
- outputSchema: focusLayoutOutputSchema,
588
- annotations: artifactProducing,
589
- }, async ({ workspaceId, relativePath, treeId, previous, laneSpacing, nodeSpacing }, extra) => {
590
- try {
591
- const progress = progressReporter(extra);
592
- await progress.report(0, 3, 'Importing and indexing focus source');
593
- const snapshot = await engine.scan(workspaceId, {}, context.principal, progress.signal);
594
- const workspace = engine.resolver.get(workspaceId, context.principal);
595
- const paletteImport = continuousPalettes(snapshot);
596
- const imported = importFocusFile(snapshot, selectedFocusFile(snapshot, workspace.registration.roots.focus, relativePath), paletteImport.palettes);
597
- const plan = selectPlan(imported, treeId);
598
- const layout = await workbench.layoutAsync(plan, {
599
- ...(previous === undefined ? {} : { previous: previous }),
600
- ...(laneSpacing === undefined ? {} : { laneSpacing }),
601
- ...(nodeSpacing === undefined ? {} : { nodeSpacing }),
602
- signal: progress.signal,
603
- });
604
- progress.signal.throwIfAborted();
605
- await progress.report(2, 3, 'Writing stable focus layout evidence');
606
- const artifact = await engine.artifacts.put(workspace, `${plan.id.replace(/[^A-Za-z0-9._-]/gu, '_')}.focus-layout.json`, 'application/json', `${canonicalJson(layout)}\n`, {
607
- kind: 'focus-layout',
608
- toolVersion: PACKAGE_VERSION,
609
- schemaVersion: 'focus-layout.v1',
610
- sourceHashes: { [plan.provenance.sourcePath]: plan.provenance.sourceHash },
611
- }, 'Stable focus layout decisions and diagnostics', progress.signal);
612
- const diagnostics = [
613
- ...paletteImport.diagnostics,
614
- ...imported.diagnostics,
615
- ...layout.diagnostics,
616
- ];
617
- const result = emptyServiceResult(workspaceId, {
618
- treeId: plan.id,
619
- layoutHash: layout.layoutHash,
620
- nodeCount: layout.nodes.length,
621
- decisions: layout.decisions.slice(0, 100),
622
- });
623
- result.code = 'FOCUS_LAYOUT_PLANNED';
624
- setInlineFilesScanned(result, [plan.provenance.sourcePath]);
625
- result.diagnostics = diagnostics.slice(0, 100);
626
- result.artifacts = [publicArtifactLink(artifact)];
627
- result.validation = validationFromDiagnostics(diagnostics);
628
- await progress.report(3, 3, 'Focus layout complete');
656
+ await progress.report(3, 3, 'Focus inspection complete');
629
657
  return toolResult(result);
630
658
  }
631
659
  catch (error) {
@@ -634,7 +662,7 @@ export function registerFocusTools(server, engine, context) {
634
662
  });
635
663
  server.registerTool('hoi4.focus_render', {
636
664
  title: 'Render focus review artifacts',
637
- description: 'Generate deterministic HTML, SVG, genuine PNG, JSON, and source-map artifacts for a national tree or continuous palette. Omit mode for national behavior. National renders accept a uniform reviewScale from 0.25 through 1.0 so very large trees can fit bounded artifacts without changing logical node geometry or source coordinates.',
665
+ description: 'Render a national tree or continuous palette for creation and cleanup review as deterministic HTML, SVG, PNG, JSON, and source-map artifacts. Omit mode for national behavior. National trees with at least 200 focuses use reviewScale 0.5 by default; set 0.25 through 1.0 explicitly when needed.',
638
666
  inputSchema: focusRenderInput,
639
667
  outputSchema: focusRenderOutputSchema,
640
668
  annotations: artifactProducing,
@@ -703,6 +731,7 @@ export function registerFocusTools(server, engine, context) {
703
731
  signal: progress.signal,
704
732
  });
705
733
  await progress.report(1, 3, 'Rendering focus artifacts');
734
+ const effectiveReviewScale = input.reviewScale ?? automaticFocusRenderScale(plan.focuses.length);
706
735
  const rendered = await workbench.renderAndStore(workspaceId, plan, {
707
736
  ...(context.principal === undefined ? {} : { principal: context.principal }),
708
737
  index: snapshot.index,
@@ -716,10 +745,10 @@ export function registerFocusTools(server, engine, context) {
716
745
  ? {}
717
746
  : { verticalSpacing: input.verticalSpacing }),
718
747
  ...(input.padding === undefined ? {} : { padding: input.padding }),
719
- ...(input.reviewScale === undefined ? {} : { outputScale: input.reviewScale }),
748
+ outputScale: effectiveReviewScale,
720
749
  renderProfile: {
721
750
  sourceRevision: snapshot.revision,
722
- ...(input.reviewScale === undefined ? {} : { reviewScale: input.reviewScale }),
751
+ reviewScale: effectiveReviewScale,
723
752
  },
724
753
  budget: renderBudget,
725
754
  signal: progress.signal,
@@ -749,25 +778,23 @@ export function registerFocusTools(server, engine, context) {
749
778
  return errorResult(error, workspaceId);
750
779
  }
751
780
  });
752
- server.registerTool(autonomous ? 'hoi4.focus_rewrite' : 'hoi4.focus_plan_changes', {
753
- title: autonomous ? 'Rewrite focus source' : 'Dry-run focus source changes',
754
- description: `${autonomous
755
- ? 'Compile, validate, journal, and immediately apply a national tree or continuous palette plan in one call. No transaction approval or follow-up apply call is required.'
756
- : 'Compile a validated national tree or continuous palette plan into source and create a hash-bound reviewed transaction; it does not apply the transaction.'} Omit mode for national behavior. National plans accept the same bounded horizontalSpacing, verticalSpacing, and padding controls as focus_render plus a uniform reviewScale that preserves logical SVG geometry while reducing both before/proposed raster outputs. For an unoccupied new source, pass createIfMissing: true with plan:<id> and zero-hash creation provenance.`,
781
+ server.registerTool('hoi4.focus_rewrite', {
782
+ title: 'Create or clean up focus content',
783
+ description: 'Create or clean up a national tree or continuous palette, validate it, and apply it in one call. Supply a complete plan; set layoutMode compact for automatic arrangement. Existing national trees can omit the plan and use treeId plus layoutMode compact. Set createIfMissing for a new file.',
757
784
  inputSchema: focusPlanInput,
758
785
  outputSchema: focusPlanOutputSchema,
759
786
  annotations: {
760
787
  readOnlyHint: false,
761
- destructiveHint: autonomous,
788
+ destructiveHint: true,
762
789
  idempotentHint: false,
763
790
  openWorldHint: false,
764
791
  },
765
792
  }, async (input, extra) => {
766
- const { workspaceId, relativePath, authority, createIfMissing, horizontalSpacing, verticalSpacing, padding, reviewScale, } = input;
793
+ const { workspaceId, relativePath, createIfMissing, horizontalSpacing, verticalSpacing, padding, reviewScale, } = input;
767
794
  try {
768
795
  requireServerScope(context, 'hoi4:write');
769
796
  const progress = progressReporter(extra);
770
- await progress.report(0, 5, 'Validating shared index and source authority');
797
+ await progress.report(0, 5, 'Validating shared index and current source');
771
798
  const snapshot = await engine.scan(workspaceId, {}, context.principal, progress.signal);
772
799
  const workspace = engine.resolver.get(workspaceId, context.principal);
773
800
  if (input.mode === 'continuous') {
@@ -793,8 +820,6 @@ export function registerFocusTools(server, engine, context) {
793
820
  }
794
821
  if (currentPlan === undefined && createIfMissing && sourceFile !== undefined)
795
822
  throw new ServiceError('CONTINUOUS_FOCUS_CREATE_REQUIRES_NEW_SOURCE', 'Creating a continuous-focus palette requires a new mod source file so unrelated existing source is never repurposed', { relativePath, paletteId: plan.id });
796
- if (currentPlan !== undefined && imported !== undefined)
797
- assertFocusPlanAuthority(detectContinuousFocusDrift(plan, imported.document), authority);
798
823
  const renderBudget = new RenderBudget();
799
824
  const presentation = await resolveFocusPresentation({
800
825
  plans: [],
@@ -871,21 +896,19 @@ export function registerFocusTools(server, engine, context) {
871
896
  ...proposed.artifacts.map(publicArtifactLink),
872
897
  ...comparisonArtifacts.map(publicArtifactLink),
873
898
  ];
874
- await progress.report(3, 5, 'Creating hash-bound continuous focus transaction');
899
+ await progress.report(3, 5, 'Preparing the continuous focus rewrite');
875
900
  const planned = await workbench.planContinuousChanges({
876
901
  workspaceId,
877
902
  relativePath,
878
903
  plan,
879
904
  createIfMissing,
880
- ...(authority === undefined ? {} : { authority }),
905
+ authority: 'plan',
881
906
  ...(context.principal === undefined ? {} : { principal: context.principal }),
882
907
  artifacts: reviewArtifacts,
883
908
  readDependencies: readDependenciesFromScannedFiles(snapshot.files),
884
909
  signal: progress.signal,
885
910
  });
886
- await progress.report(4, 5, autonomous
887
- ? 'Applying and post-validating continuous focus rewrite'
888
- : 'Finalizing reviewed transaction');
911
+ await progress.report(4, 5, 'Applying and validating the continuous focus rewrite');
889
912
  const execution = await executePlannedTransaction(engine, planned.transaction, context.principal, progress.signal);
890
913
  const transaction = execution.transaction;
891
914
  const result = emptyServiceResult(workspaceId, {
@@ -894,9 +917,8 @@ export function registerFocusTools(server, engine, context) {
894
917
  drift: compactDrift(planned.drift),
895
918
  created: planned.drift.status === 'target_missing',
896
919
  execution: execution.outcome,
897
- expiresAt: transaction.expiresAt,
898
- transactionFileCount: transaction.files.length,
899
- transactionArtifactCount: transaction.artifacts.length,
920
+ fileCount: transaction.files.length,
921
+ artifactCount: transaction.artifacts.length,
900
922
  });
901
923
  result.status = transaction.validation.passed ? 'ok' : 'blocked';
902
924
  result.code =
@@ -904,9 +926,7 @@ export function registerFocusTools(server, engine, context) {
904
926
  ? 'CONTINUOUS_FOCUS_CHANGES_APPLIED'
905
927
  : execution.outcome === 'unchanged'
906
928
  ? 'CONTINUOUS_FOCUS_CHANGES_UNCHANGED'
907
- : transaction.validation.passed
908
- ? 'CONTINUOUS_FOCUS_CHANGES_PLANNED'
909
- : 'CONTINUOUS_FOCUS_CHANGES_BLOCKED';
929
+ : 'CONTINUOUS_FOCUS_CHANGES_BLOCKED';
910
930
  setInlineFilesScanned(result, [
911
931
  ...new Set([
912
932
  ...(sourceFile === undefined ? [] : [sourceFile.displayPath]),
@@ -918,15 +938,7 @@ export function registerFocusTools(server, engine, context) {
918
938
  .map(({ relativePath: file }) => file);
919
939
  result.changedFiles = transaction.appliedFiles.slice(0, 100);
920
940
  result.diagnostics = transaction.diagnostics.slice(0, 100);
921
- if (autonomous) {
922
- result.artifacts = transaction.artifacts;
923
- }
924
- else {
925
- result.transactionId = transaction.transactionId;
926
- result.planHash = transaction.planHash;
927
- result.artifacts = [transactionResourceLink(transaction)];
928
- result.rollbackStatus = transaction.rollbackStatus;
929
- }
941
+ result.artifacts = autonomousResultArtifacts(execution);
930
942
  result.validation = transaction.validation;
931
943
  result.blockers = transaction.diagnostics
932
944
  .filter(({ severity }) => severity === 'error' || severity === 'blocker')
@@ -938,11 +950,11 @@ export function registerFocusTools(server, engine, context) {
938
950
  await progress.report(5, 5, execution.outcome === 'applied'
939
951
  ? 'Continuous focus rewrite complete'
940
952
  : execution.outcome === 'unchanged'
941
- ? 'Continuous focus source already satisfied the plan'
942
- : 'Continuous focus transaction planned');
953
+ ? 'Continuous focus content already satisfied the plan'
954
+ : 'Continuous focus rewrite blocked');
943
955
  return toolResult(result);
944
956
  }
945
- const plan = input.plan;
957
+ const suppliedPlan = input.plan;
946
958
  if (createIfMissing &&
947
959
  (!relativePath.toLowerCase().endsWith('.txt') ||
948
960
  !underConfiguredRoot(relativePath, workspace.registration.roots.focus)))
@@ -960,6 +972,30 @@ export function registerFocusTools(server, engine, context) {
960
972
  const paletteImport = continuousPalettes(snapshot);
961
973
  if (imported !== undefined)
962
974
  imported.result.plans = imported.result.plans.map((current) => linkContinuousFocusPalettes(current, paletteImport.palettes));
975
+ let compactPlanning;
976
+ let compactSourcePlan;
977
+ let plan;
978
+ if (suppliedPlan !== undefined) {
979
+ if (input.layoutMode === 'compact') {
980
+ compactSourcePlan = suppliedPlan;
981
+ compactPlanning = await compactFocusTreePlanAsync(suppliedPlan, {
982
+ signal: progress.signal,
983
+ });
984
+ plan = compactPlanning.plan;
985
+ }
986
+ else {
987
+ plan = suppliedPlan;
988
+ }
989
+ }
990
+ else {
991
+ if (imported === undefined)
992
+ throw new ServiceError('FOCUS_COMPACT_SOURCE_REQUIRED', 'Plan-free compact reflow requires an existing national focus source', { relativePath });
993
+ compactSourcePlan = selectPlan(imported.result, input.treeId);
994
+ compactPlanning = await compactFocusTreePlanAsync(compactSourcePlan, {
995
+ signal: progress.signal,
996
+ });
997
+ plan = compactPlanning.plan;
998
+ }
963
999
  const currentPlan = imported?.result.plans.find(({ id }) => id === plan.id);
964
1000
  if (currentPlan === undefined && !createIfMissing) {
965
1001
  if (imported === undefined)
@@ -969,20 +1005,19 @@ export function registerFocusTools(server, engine, context) {
969
1005
  }
970
1006
  if (currentPlan === undefined && createIfMissing && focusFile !== undefined)
971
1007
  throw new ServiceError('FOCUS_CREATE_REQUIRES_NEW_SOURCE', 'Creating a national focus tree requires a new mod source file so an existing source and its planning sidecar cannot be repurposed', { relativePath, treeId: plan.id });
972
- if (currentPlan !== undefined && imported !== undefined)
973
- assertFocusPlanAuthority(detectFocusDrift(plan, imported.document, catalog), authority);
974
1008
  const renderBudget = new RenderBudget();
1009
+ const effectiveReviewScale = reviewScale ?? automaticFocusRenderScale(plan.focuses.length);
975
1010
  const reviewRenderOptions = {
976
1011
  ...(horizontalSpacing === undefined ? {} : { horizontalSpacing }),
977
1012
  ...(verticalSpacing === undefined ? {} : { verticalSpacing }),
978
1013
  ...(padding === undefined ? {} : { padding }),
979
- ...(reviewScale === undefined ? {} : { outputScale: reviewScale }),
1014
+ outputScale: effectiveReviewScale,
980
1015
  };
981
1016
  const reviewRenderProfile = {
982
1017
  ...(horizontalSpacing === undefined ? {} : { horizontalSpacing }),
983
1018
  ...(verticalSpacing === undefined ? {} : { verticalSpacing }),
984
1019
  ...(padding === undefined ? {} : { padding }),
985
- ...(reviewScale === undefined ? {} : { reviewScale }),
1020
+ reviewScale: effectiveReviewScale,
986
1021
  };
987
1022
  const presentation = await resolveFocusPresentation({
988
1023
  plans: [...(currentPlan === undefined ? [] : [currentPlan]), plan],
@@ -996,7 +1031,9 @@ export function registerFocusTools(server, engine, context) {
996
1031
  });
997
1032
  const currentLayout = currentPlan === undefined
998
1033
  ? undefined
999
- : await workbench.layoutAsync(currentPlan, { signal: progress.signal });
1034
+ : currentPlan === compactSourcePlan && compactPlanning !== undefined
1035
+ ? compactPlanning.currentLayout
1036
+ : await workbench.layoutAsync(currentPlan, { signal: progress.signal });
1000
1037
  const currentDiagnostics = currentPlan === undefined || currentLayout === undefined
1001
1038
  ? []
1002
1039
  : workbench.lint(currentPlan, {
@@ -1022,6 +1059,11 @@ export function registerFocusTools(server, engine, context) {
1022
1059
  importedPlanHash: proposedPlanHash,
1023
1060
  },
1024
1061
  };
1062
+ const proposedLayout = compactPlanning?.proposedLayout ??
1063
+ (await workbench.layoutAsync(reviewPlan, { signal: progress.signal }));
1064
+ if (input.layoutMode === 'compact') {
1065
+ assertCompactLayoutQuality(currentLayout, proposedLayout);
1066
+ }
1025
1067
  const proposed = await workbench.renderAndStore(workspaceId, reviewPlan, {
1026
1068
  ...(context.principal === undefined ? {} : { principal: context.principal }),
1027
1069
  index: snapshot.index,
@@ -1036,6 +1078,7 @@ export function registerFocusTools(server, engine, context) {
1036
1078
  },
1037
1079
  budget: renderBudget,
1038
1080
  signal: progress.signal,
1081
+ layout: proposedLayout,
1039
1082
  });
1040
1083
  const beforePng = currentRender?.png ??
1041
1084
  (await createTransparentPng(proposed.bundle.width, proposed.bundle.height, 'new national focus baseline', renderBudget));
@@ -1078,13 +1121,14 @@ export function registerFocusTools(server, engine, context) {
1078
1121
  ...proposed.artifacts.map(publicArtifactLink),
1079
1122
  ...comparisonArtifacts.map(publicArtifactLink),
1080
1123
  ];
1081
- await progress.report(3, 5, 'Creating hash-bound focus transaction');
1124
+ await progress.report(3, 5, 'Preparing the focus-tree rewrite');
1082
1125
  const planned = await workbench.planChanges({
1083
1126
  workspaceId,
1084
1127
  relativePath,
1085
1128
  plan,
1086
1129
  createIfMissing,
1087
- ...(authority === undefined ? {} : { authority }),
1130
+ authority: 'plan',
1131
+ layout: proposed.layout,
1088
1132
  ...(context.principal === undefined ? {} : { principal: context.principal }),
1089
1133
  index: snapshot.index,
1090
1134
  references: catalog,
@@ -1092,9 +1136,7 @@ export function registerFocusTools(server, engine, context) {
1092
1136
  readDependencies: readDependenciesFromScannedFiles(snapshot.files),
1093
1137
  signal: progress.signal,
1094
1138
  });
1095
- await progress.report(4, 5, autonomous
1096
- ? 'Applying and post-validating focus rewrite'
1097
- : 'Finalizing reviewed transaction');
1139
+ await progress.report(4, 5, 'Applying and validating the focus-tree rewrite');
1098
1140
  const execution = await executePlannedTransaction(engine, planned.transaction, context.principal, progress.signal);
1099
1141
  const transaction = execution.transaction;
1100
1142
  const result = emptyServiceResult(workspaceId, {
@@ -1104,9 +1146,8 @@ export function registerFocusTools(server, engine, context) {
1104
1146
  created: planned.drift.status === 'target_missing',
1105
1147
  execution: execution.outcome,
1106
1148
  layoutHash: planned.layout.layoutHash,
1107
- expiresAt: transaction.expiresAt,
1108
- transactionFileCount: transaction.files.length,
1109
- transactionArtifactCount: transaction.artifacts.length,
1149
+ fileCount: transaction.files.length,
1150
+ artifactCount: transaction.artifacts.length,
1110
1151
  });
1111
1152
  result.status = transaction.validation.passed ? 'ok' : 'blocked';
1112
1153
  result.code =
@@ -1114,9 +1155,7 @@ export function registerFocusTools(server, engine, context) {
1114
1155
  ? 'FOCUS_CHANGES_APPLIED'
1115
1156
  : execution.outcome === 'unchanged'
1116
1157
  ? 'FOCUS_CHANGES_UNCHANGED'
1117
- : transaction.validation.passed
1118
- ? 'FOCUS_CHANGES_PLANNED'
1119
- : 'FOCUS_CHANGES_BLOCKED';
1158
+ : 'FOCUS_CHANGES_BLOCKED';
1120
1159
  setInlineFilesScanned(result, [
1121
1160
  ...new Set([
1122
1161
  ...(focusFile === undefined ? [] : [focusFile.displayPath]),
@@ -1128,15 +1167,7 @@ export function registerFocusTools(server, engine, context) {
1128
1167
  .map(({ relativePath: file }) => file);
1129
1168
  result.changedFiles = transaction.appliedFiles.slice(0, 100);
1130
1169
  result.diagnostics = transaction.diagnostics.slice(0, 100);
1131
- if (autonomous) {
1132
- result.artifacts = autonomousResultArtifacts(execution);
1133
- }
1134
- else {
1135
- result.transactionId = transaction.transactionId;
1136
- result.planHash = transaction.planHash;
1137
- result.artifacts = [transactionResourceLink(transaction)];
1138
- result.rollbackStatus = transaction.rollbackStatus;
1139
- }
1170
+ result.artifacts = autonomousResultArtifacts(execution);
1140
1171
  result.validation = transaction.validation;
1141
1172
  result.blockers = transaction.diagnostics
1142
1173
  .filter(({ severity }) => severity === 'error' || severity === 'blocker')
@@ -1148,8 +1179,8 @@ export function registerFocusTools(server, engine, context) {
1148
1179
  await progress.report(5, 5, execution.outcome === 'applied'
1149
1180
  ? 'Focus rewrite complete'
1150
1181
  : execution.outcome === 'unchanged'
1151
- ? 'Focus source already satisfied the plan'
1152
- : 'Focus transaction planned');
1182
+ ? 'Focus content already satisfied the plan'
1183
+ : 'Focus rewrite blocked');
1153
1184
  return toolResult(result);
1154
1185
  }
1155
1186
  catch (error) {
@@ -1157,4 +1188,3 @@ export function registerFocusTools(server, engine, context) {
1157
1188
  }
1158
1189
  });
1159
1190
  }
1160
- //# sourceMappingURL=focus.js.map