hoi4-agent-tools 0.1.7 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (424) hide show
  1. package/CHANGELOG.md +12 -94
  2. package/README.md +35 -121
  3. package/SECURITY.md +5 -5
  4. package/dist/bin/http.js +0 -1
  5. package/dist/bin/setup.js +141 -85
  6. package/dist/bin/stdio.js +0 -1
  7. package/dist/hoi4_agent_tools/core/artifacts.js +0 -1
  8. package/dist/hoi4_agent_tools/core/canonical.js +0 -1
  9. package/dist/hoi4_agent_tools/core/configuration.js +28 -28
  10. package/dist/hoi4_agent_tools/core/diagnostic-collector.js +0 -1
  11. package/dist/hoi4_agent_tools/core/diagnostics.js +0 -1
  12. package/dist/hoi4_agent_tools/core/diff.js +0 -1
  13. package/dist/hoi4_agent_tools/core/engine.js +6 -20
  14. package/dist/hoi4_agent_tools/core/image-diff.js +0 -1
  15. package/dist/hoi4_agent_tools/core/index.js +0 -1
  16. package/dist/hoi4_agent_tools/core/render-budget.js +0 -1
  17. package/dist/hoi4_agent_tools/core/result.js +0 -1
  18. package/dist/hoi4_agent_tools/core/scanner.js +0 -1
  19. package/dist/hoi4_agent_tools/core/server-state.js +0 -1
  20. package/dist/hoi4_agent_tools/core/source/encoding.js +0 -1
  21. package/dist/hoi4_agent_tools/core/source/index.js +0 -1
  22. package/dist/hoi4_agent_tools/core/source/lexer.js +0 -1
  23. package/dist/hoi4_agent_tools/core/source/limits.js +0 -1
  24. package/dist/hoi4_agent_tools/core/source/localisation.js +0 -1
  25. package/dist/hoi4_agent_tools/core/source/parser.js +0 -1
  26. package/dist/hoi4_agent_tools/core/source/rewrite.js +0 -1
  27. package/dist/hoi4_agent_tools/core/svg-text.js +0 -1
  28. package/dist/hoi4_agent_tools/core/transaction-limits.js +0 -1
  29. package/dist/hoi4_agent_tools/core/transactions.js +46 -31
  30. package/dist/hoi4_agent_tools/core/workspace.js +112 -396
  31. package/dist/hoi4_agent_tools/focus/compiler.js +0 -1
  32. package/dist/hoi4_agent_tools/focus/continuous-render.js +0 -1
  33. package/dist/hoi4_agent_tools/focus/drift.js +0 -1
  34. package/dist/hoi4_agent_tools/focus/geometry.js +0 -1
  35. package/dist/hoi4_agent_tools/focus/importer.js +0 -1
  36. package/dist/hoi4_agent_tools/focus/index.js +0 -1
  37. package/dist/hoi4_agent_tools/focus/layout.js +0 -1
  38. package/dist/hoi4_agent_tools/focus/limits.js +0 -1
  39. package/dist/hoi4_agent_tools/focus/lint.js +0 -1
  40. package/dist/hoi4_agent_tools/focus/model.js +0 -1
  41. package/dist/hoi4_agent_tools/focus/native-effects.js +0 -1
  42. package/dist/hoi4_agent_tools/focus/planning.js +0 -1
  43. package/dist/hoi4_agent_tools/focus/presentation.js +0 -1
  44. package/dist/hoi4_agent_tools/focus/render.js +0 -1
  45. package/dist/hoi4_agent_tools/focus/service.js +11 -26
  46. package/dist/hoi4_agent_tools/focus/source-update.js +1 -2
  47. package/dist/hoi4_agent_tools/gui/animation-manifest.js +0 -1
  48. package/dist/hoi4_agent_tools/gui/assets.js +0 -1
  49. package/dist/hoi4_agent_tools/gui/dds.js +0 -1
  50. package/dist/hoi4_agent_tools/gui/helpers.js +1 -2
  51. package/dist/hoi4_agent_tools/gui/index.js +0 -1
  52. package/dist/hoi4_agent_tools/gui/layout.js +0 -1
  53. package/dist/hoi4_agent_tools/gui/limits.js +0 -1
  54. package/dist/hoi4_agent_tools/gui/renderer.js +0 -1
  55. package/dist/hoi4_agent_tools/gui/scenario.js +0 -1
  56. package/dist/hoi4_agent_tools/gui/source-graph.js +0 -1
  57. package/dist/hoi4_agent_tools/gui/source-patch.js +1 -2
  58. package/dist/hoi4_agent_tools/gui/studio.js +247 -103
  59. package/dist/hoi4_agent_tools/gui/tga.js +0 -1
  60. package/dist/hoi4_agent_tools/gui/types.js +0 -1
  61. package/dist/hoi4_agent_tools/gui/validators.js +0 -1
  62. package/dist/hoi4_agent_tools/map/bmp.js +0 -1
  63. package/dist/hoi4_agent_tools/map/diagnostic-limit.js +0 -1
  64. package/dist/hoi4_agent_tools/map/index.js +0 -1
  65. package/dist/hoi4_agent_tools/map/limits.js +2 -1
  66. package/dist/hoi4_agent_tools/map/model.js +0 -1
  67. package/dist/hoi4_agent_tools/map/operations.js +0 -1
  68. package/dist/hoi4_agent_tools/map/render.js +0 -1
  69. package/dist/hoi4_agent_tools/map/service.js +182 -38
  70. package/dist/hoi4_agent_tools/map/validation.js +0 -1
  71. package/dist/hoi4_agent_tools/mcp/resources/register.js +61 -187
  72. package/dist/hoi4_agent_tools/mcp/security/auth.js +1 -5
  73. package/dist/hoi4_agent_tools/mcp/server/base-tools.js +26 -733
  74. package/dist/hoi4_agent_tools/mcp/server/create.js +3 -6
  75. package/dist/hoi4_agent_tools/mcp/server/output-schemas.js +0 -70
  76. package/dist/hoi4_agent_tools/mcp/server/progress.js +0 -1
  77. package/dist/hoi4_agent_tools/mcp/server/result.js +24 -30
  78. package/dist/hoi4_agent_tools/mcp/server/transaction-execution.js +123 -0
  79. package/dist/hoi4_agent_tools/mcp/tools/focus.js +244 -254
  80. package/dist/hoi4_agent_tools/mcp/tools/gui.js +163 -236
  81. package/dist/hoi4_agent_tools/mcp/tools/map.js +269 -323
  82. package/dist/hoi4_agent_tools/mcp/tools/mods.js +54 -0
  83. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js +0 -1
  84. package/dist/hoi4_agent_tools/mcp/transports/event-store.js +0 -1
  85. package/dist/hoi4_agent_tools/mcp/transports/http.js +1 -9
  86. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js +0 -1
  87. package/dist/hoi4_agent_tools/runtime.js +5 -2
  88. package/dist/hoi4_agent_tools/schemas/common.js +1 -2
  89. package/dist/hoi4_agent_tools/schemas/focus.js +0 -1
  90. package/dist/hoi4_agent_tools/schemas/map.js +0 -1
  91. package/dist/hoi4_agent_tools/schemas/transaction.js +0 -1
  92. package/dist/hoi4_agent_tools/version.js +1 -2
  93. package/docs/README.md +8 -21
  94. package/docs/development.md +22 -0
  95. package/docs/focus.md +40 -0
  96. package/docs/gui.md +37 -0
  97. package/docs/http.md +53 -0
  98. package/docs/map.md +39 -0
  99. package/docs/setup.md +39 -0
  100. package/package.json +10 -11
  101. package/server.json +3 -12
  102. package/dist/bin/http.d.ts +0 -3
  103. package/dist/bin/http.d.ts.map +0 -1
  104. package/dist/bin/http.js.map +0 -1
  105. package/dist/bin/setup.d.ts +0 -3
  106. package/dist/bin/setup.d.ts.map +0 -1
  107. package/dist/bin/setup.js.map +0 -1
  108. package/dist/bin/stdio.d.ts +0 -3
  109. package/dist/bin/stdio.d.ts.map +0 -1
  110. package/dist/bin/stdio.js.map +0 -1
  111. package/dist/hoi4_agent_tools/core/artifacts.d.ts +0 -117
  112. package/dist/hoi4_agent_tools/core/artifacts.d.ts.map +0 -1
  113. package/dist/hoi4_agent_tools/core/artifacts.js.map +0 -1
  114. package/dist/hoi4_agent_tools/core/canonical.d.ts +0 -13
  115. package/dist/hoi4_agent_tools/core/canonical.d.ts.map +0 -1
  116. package/dist/hoi4_agent_tools/core/canonical.js.map +0 -1
  117. package/dist/hoi4_agent_tools/core/configuration.d.ts +0 -137
  118. package/dist/hoi4_agent_tools/core/configuration.d.ts.map +0 -1
  119. package/dist/hoi4_agent_tools/core/configuration.js.map +0 -1
  120. package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts +0 -18
  121. package/dist/hoi4_agent_tools/core/diagnostic-collector.d.ts.map +0 -1
  122. package/dist/hoi4_agent_tools/core/diagnostic-collector.js.map +0 -1
  123. package/dist/hoi4_agent_tools/core/diagnostics.d.ts +0 -26
  124. package/dist/hoi4_agent_tools/core/diagnostics.d.ts.map +0 -1
  125. package/dist/hoi4_agent_tools/core/diagnostics.js.map +0 -1
  126. package/dist/hoi4_agent_tools/core/diff.d.ts +0 -22
  127. package/dist/hoi4_agent_tools/core/diff.d.ts.map +0 -1
  128. package/dist/hoi4_agent_tools/core/diff.js.map +0 -1
  129. package/dist/hoi4_agent_tools/core/engine.d.ts +0 -56
  130. package/dist/hoi4_agent_tools/core/engine.d.ts.map +0 -1
  131. package/dist/hoi4_agent_tools/core/engine.js.map +0 -1
  132. package/dist/hoi4_agent_tools/core/image-diff.d.ts +0 -14
  133. package/dist/hoi4_agent_tools/core/image-diff.d.ts.map +0 -1
  134. package/dist/hoi4_agent_tools/core/image-diff.js.map +0 -1
  135. package/dist/hoi4_agent_tools/core/index.d.ts +0 -64
  136. package/dist/hoi4_agent_tools/core/index.d.ts.map +0 -1
  137. package/dist/hoi4_agent_tools/core/index.js.map +0 -1
  138. package/dist/hoi4_agent_tools/core/index.public.d.ts +0 -16
  139. package/dist/hoi4_agent_tools/core/index.public.d.ts.map +0 -1
  140. package/dist/hoi4_agent_tools/core/index.public.js +0 -16
  141. package/dist/hoi4_agent_tools/core/index.public.js.map +0 -1
  142. package/dist/hoi4_agent_tools/core/render-budget.d.ts +0 -51
  143. package/dist/hoi4_agent_tools/core/render-budget.d.ts.map +0 -1
  144. package/dist/hoi4_agent_tools/core/render-budget.js.map +0 -1
  145. package/dist/hoi4_agent_tools/core/result.d.ts +0 -45
  146. package/dist/hoi4_agent_tools/core/result.d.ts.map +0 -1
  147. package/dist/hoi4_agent_tools/core/result.js.map +0 -1
  148. package/dist/hoi4_agent_tools/core/scanner.d.ts +0 -28
  149. package/dist/hoi4_agent_tools/core/scanner.d.ts.map +0 -1
  150. package/dist/hoi4_agent_tools/core/scanner.js.map +0 -1
  151. package/dist/hoi4_agent_tools/core/server-state.d.ts +0 -31
  152. package/dist/hoi4_agent_tools/core/server-state.d.ts.map +0 -1
  153. package/dist/hoi4_agent_tools/core/server-state.js.map +0 -1
  154. package/dist/hoi4_agent_tools/core/source/encoding.d.ts +0 -10
  155. package/dist/hoi4_agent_tools/core/source/encoding.d.ts.map +0 -1
  156. package/dist/hoi4_agent_tools/core/source/encoding.js.map +0 -1
  157. package/dist/hoi4_agent_tools/core/source/index.d.ts +0 -7
  158. package/dist/hoi4_agent_tools/core/source/index.d.ts.map +0 -1
  159. package/dist/hoi4_agent_tools/core/source/index.js.map +0 -1
  160. package/dist/hoi4_agent_tools/core/source/lexer.d.ts +0 -30
  161. package/dist/hoi4_agent_tools/core/source/lexer.d.ts.map +0 -1
  162. package/dist/hoi4_agent_tools/core/source/lexer.js.map +0 -1
  163. package/dist/hoi4_agent_tools/core/source/limits.d.ts +0 -21
  164. package/dist/hoi4_agent_tools/core/source/limits.d.ts.map +0 -1
  165. package/dist/hoi4_agent_tools/core/source/limits.js.map +0 -1
  166. package/dist/hoi4_agent_tools/core/source/localisation.d.ts +0 -20
  167. package/dist/hoi4_agent_tools/core/source/localisation.d.ts.map +0 -1
  168. package/dist/hoi4_agent_tools/core/source/localisation.js.map +0 -1
  169. package/dist/hoi4_agent_tools/core/source/parser.d.ts +0 -44
  170. package/dist/hoi4_agent_tools/core/source/parser.d.ts.map +0 -1
  171. package/dist/hoi4_agent_tools/core/source/parser.js.map +0 -1
  172. package/dist/hoi4_agent_tools/core/source/rewrite.d.ts +0 -10
  173. package/dist/hoi4_agent_tools/core/source/rewrite.d.ts.map +0 -1
  174. package/dist/hoi4_agent_tools/core/source/rewrite.js.map +0 -1
  175. package/dist/hoi4_agent_tools/core/svg-text.d.ts +0 -34
  176. package/dist/hoi4_agent_tools/core/svg-text.d.ts.map +0 -1
  177. package/dist/hoi4_agent_tools/core/svg-text.js.map +0 -1
  178. package/dist/hoi4_agent_tools/core/transaction-limits.d.ts +0 -9
  179. package/dist/hoi4_agent_tools/core/transaction-limits.d.ts.map +0 -1
  180. package/dist/hoi4_agent_tools/core/transaction-limits.js.map +0 -1
  181. package/dist/hoi4_agent_tools/core/transactions.d.ts +0 -162
  182. package/dist/hoi4_agent_tools/core/transactions.d.ts.map +0 -1
  183. package/dist/hoi4_agent_tools/core/transactions.js.map +0 -1
  184. package/dist/hoi4_agent_tools/core/workspace.d.ts +0 -68
  185. package/dist/hoi4_agent_tools/core/workspace.d.ts.map +0 -1
  186. package/dist/hoi4_agent_tools/core/workspace.js.map +0 -1
  187. package/dist/hoi4_agent_tools/focus/compiler.d.ts +0 -10
  188. package/dist/hoi4_agent_tools/focus/compiler.d.ts.map +0 -1
  189. package/dist/hoi4_agent_tools/focus/compiler.js.map +0 -1
  190. package/dist/hoi4_agent_tools/focus/continuous-render.d.ts +0 -32
  191. package/dist/hoi4_agent_tools/focus/continuous-render.d.ts.map +0 -1
  192. package/dist/hoi4_agent_tools/focus/continuous-render.js.map +0 -1
  193. package/dist/hoi4_agent_tools/focus/drift.d.ts +0 -22
  194. package/dist/hoi4_agent_tools/focus/drift.d.ts.map +0 -1
  195. package/dist/hoi4_agent_tools/focus/drift.js.map +0 -1
  196. package/dist/hoi4_agent_tools/focus/geometry.d.ts +0 -17
  197. package/dist/hoi4_agent_tools/focus/geometry.d.ts.map +0 -1
  198. package/dist/hoi4_agent_tools/focus/geometry.js.map +0 -1
  199. package/dist/hoi4_agent_tools/focus/importer.d.ts +0 -9
  200. package/dist/hoi4_agent_tools/focus/importer.d.ts.map +0 -1
  201. package/dist/hoi4_agent_tools/focus/importer.js.map +0 -1
  202. package/dist/hoi4_agent_tools/focus/index.d.ts +0 -14
  203. package/dist/hoi4_agent_tools/focus/index.d.ts.map +0 -1
  204. package/dist/hoi4_agent_tools/focus/index.js.map +0 -1
  205. package/dist/hoi4_agent_tools/focus/layout.d.ts +0 -5
  206. package/dist/hoi4_agent_tools/focus/layout.d.ts.map +0 -1
  207. package/dist/hoi4_agent_tools/focus/layout.js.map +0 -1
  208. package/dist/hoi4_agent_tools/focus/limits.d.ts +0 -9
  209. package/dist/hoi4_agent_tools/focus/limits.d.ts.map +0 -1
  210. package/dist/hoi4_agent_tools/focus/limits.js.map +0 -1
  211. package/dist/hoi4_agent_tools/focus/lint.d.ts +0 -14
  212. package/dist/hoi4_agent_tools/focus/lint.d.ts.map +0 -1
  213. package/dist/hoi4_agent_tools/focus/lint.js.map +0 -1
  214. package/dist/hoi4_agent_tools/focus/model.d.ts +0 -307
  215. package/dist/hoi4_agent_tools/focus/model.d.ts.map +0 -1
  216. package/dist/hoi4_agent_tools/focus/model.js.map +0 -1
  217. package/dist/hoi4_agent_tools/focus/native-effects.d.ts +0 -9
  218. package/dist/hoi4_agent_tools/focus/native-effects.d.ts.map +0 -1
  219. package/dist/hoi4_agent_tools/focus/native-effects.js.map +0 -1
  220. package/dist/hoi4_agent_tools/focus/planning.d.ts +0 -15
  221. package/dist/hoi4_agent_tools/focus/planning.d.ts.map +0 -1
  222. package/dist/hoi4_agent_tools/focus/planning.js.map +0 -1
  223. package/dist/hoi4_agent_tools/focus/presentation.d.ts +0 -24
  224. package/dist/hoi4_agent_tools/focus/presentation.d.ts.map +0 -1
  225. package/dist/hoi4_agent_tools/focus/presentation.js.map +0 -1
  226. package/dist/hoi4_agent_tools/focus/render.d.ts +0 -39
  227. package/dist/hoi4_agent_tools/focus/render.d.ts.map +0 -1
  228. package/dist/hoi4_agent_tools/focus/render.js.map +0 -1
  229. package/dist/hoi4_agent_tools/focus/service.d.ts +0 -82
  230. package/dist/hoi4_agent_tools/focus/service.d.ts.map +0 -1
  231. package/dist/hoi4_agent_tools/focus/service.js.map +0 -1
  232. package/dist/hoi4_agent_tools/focus/source-update.d.ts +0 -6
  233. package/dist/hoi4_agent_tools/focus/source-update.d.ts.map +0 -1
  234. package/dist/hoi4_agent_tools/focus/source-update.js.map +0 -1
  235. package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts +0 -37
  236. package/dist/hoi4_agent_tools/gui/animation-manifest.d.ts.map +0 -1
  237. package/dist/hoi4_agent_tools/gui/animation-manifest.js.map +0 -1
  238. package/dist/hoi4_agent_tools/gui/assets.d.ts +0 -71
  239. package/dist/hoi4_agent_tools/gui/assets.d.ts.map +0 -1
  240. package/dist/hoi4_agent_tools/gui/assets.js.map +0 -1
  241. package/dist/hoi4_agent_tools/gui/dds.d.ts +0 -17
  242. package/dist/hoi4_agent_tools/gui/dds.d.ts.map +0 -1
  243. package/dist/hoi4_agent_tools/gui/dds.js.map +0 -1
  244. package/dist/hoi4_agent_tools/gui/helpers.d.ts +0 -101
  245. package/dist/hoi4_agent_tools/gui/helpers.d.ts.map +0 -1
  246. package/dist/hoi4_agent_tools/gui/helpers.js.map +0 -1
  247. package/dist/hoi4_agent_tools/gui/index.d.ts +0 -15
  248. package/dist/hoi4_agent_tools/gui/index.d.ts.map +0 -1
  249. package/dist/hoi4_agent_tools/gui/index.js.map +0 -1
  250. package/dist/hoi4_agent_tools/gui/layout.d.ts +0 -6
  251. package/dist/hoi4_agent_tools/gui/layout.d.ts.map +0 -1
  252. package/dist/hoi4_agent_tools/gui/layout.js.map +0 -1
  253. package/dist/hoi4_agent_tools/gui/limits.d.ts +0 -25
  254. package/dist/hoi4_agent_tools/gui/limits.d.ts.map +0 -1
  255. package/dist/hoi4_agent_tools/gui/limits.js.map +0 -1
  256. package/dist/hoi4_agent_tools/gui/renderer.d.ts +0 -18
  257. package/dist/hoi4_agent_tools/gui/renderer.d.ts.map +0 -1
  258. package/dist/hoi4_agent_tools/gui/renderer.js.map +0 -1
  259. package/dist/hoi4_agent_tools/gui/scenario.d.ts +0 -66
  260. package/dist/hoi4_agent_tools/gui/scenario.d.ts.map +0 -1
  261. package/dist/hoi4_agent_tools/gui/scenario.js.map +0 -1
  262. package/dist/hoi4_agent_tools/gui/source-graph.d.ts +0 -7
  263. package/dist/hoi4_agent_tools/gui/source-graph.d.ts.map +0 -1
  264. package/dist/hoi4_agent_tools/gui/source-graph.js.map +0 -1
  265. package/dist/hoi4_agent_tools/gui/source-patch.d.ts +0 -13
  266. package/dist/hoi4_agent_tools/gui/source-patch.d.ts.map +0 -1
  267. package/dist/hoi4_agent_tools/gui/source-patch.js.map +0 -1
  268. package/dist/hoi4_agent_tools/gui/studio.d.ts +0 -86
  269. package/dist/hoi4_agent_tools/gui/studio.d.ts.map +0 -1
  270. package/dist/hoi4_agent_tools/gui/studio.js.map +0 -1
  271. package/dist/hoi4_agent_tools/gui/tga.d.ts +0 -16
  272. package/dist/hoi4_agent_tools/gui/tga.d.ts.map +0 -1
  273. package/dist/hoi4_agent_tools/gui/tga.js.map +0 -1
  274. package/dist/hoi4_agent_tools/gui/types.d.ts +0 -322
  275. package/dist/hoi4_agent_tools/gui/types.d.ts.map +0 -1
  276. package/dist/hoi4_agent_tools/gui/types.js.map +0 -1
  277. package/dist/hoi4_agent_tools/gui/validators.d.ts +0 -8
  278. package/dist/hoi4_agent_tools/gui/validators.d.ts.map +0 -1
  279. package/dist/hoi4_agent_tools/gui/validators.js.map +0 -1
  280. package/dist/hoi4_agent_tools/map/bmp.d.ts +0 -62
  281. package/dist/hoi4_agent_tools/map/bmp.d.ts.map +0 -1
  282. package/dist/hoi4_agent_tools/map/bmp.js.map +0 -1
  283. package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts +0 -5
  284. package/dist/hoi4_agent_tools/map/diagnostic-limit.d.ts.map +0 -1
  285. package/dist/hoi4_agent_tools/map/diagnostic-limit.js.map +0 -1
  286. package/dist/hoi4_agent_tools/map/index.d.ts +0 -8
  287. package/dist/hoi4_agent_tools/map/index.d.ts.map +0 -1
  288. package/dist/hoi4_agent_tools/map/index.js.map +0 -1
  289. package/dist/hoi4_agent_tools/map/limits.d.ts +0 -13
  290. package/dist/hoi4_agent_tools/map/limits.d.ts.map +0 -1
  291. package/dist/hoi4_agent_tools/map/limits.js.map +0 -1
  292. package/dist/hoi4_agent_tools/map/model.d.ts +0 -269
  293. package/dist/hoi4_agent_tools/map/model.d.ts.map +0 -1
  294. package/dist/hoi4_agent_tools/map/model.js.map +0 -1
  295. package/dist/hoi4_agent_tools/map/operations.d.ts +0 -401
  296. package/dist/hoi4_agent_tools/map/operations.d.ts.map +0 -1
  297. package/dist/hoi4_agent_tools/map/operations.js.map +0 -1
  298. package/dist/hoi4_agent_tools/map/render.d.ts +0 -90
  299. package/dist/hoi4_agent_tools/map/render.d.ts.map +0 -1
  300. package/dist/hoi4_agent_tools/map/render.js.map +0 -1
  301. package/dist/hoi4_agent_tools/map/service.d.ts +0 -81
  302. package/dist/hoi4_agent_tools/map/service.d.ts.map +0 -1
  303. package/dist/hoi4_agent_tools/map/service.js.map +0 -1
  304. package/dist/hoi4_agent_tools/map/validation.d.ts +0 -23
  305. package/dist/hoi4_agent_tools/map/validation.d.ts.map +0 -1
  306. package/dist/hoi4_agent_tools/map/validation.js.map +0 -1
  307. package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts +0 -3
  308. package/dist/hoi4_agent_tools/mcp/prompts/register.d.ts.map +0 -1
  309. package/dist/hoi4_agent_tools/mcp/prompts/register.js +0 -50
  310. package/dist/hoi4_agent_tools/mcp/prompts/register.js.map +0 -1
  311. package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts +0 -9
  312. package/dist/hoi4_agent_tools/mcp/registry/metadata.d.ts.map +0 -1
  313. package/dist/hoi4_agent_tools/mcp/registry/metadata.js +0 -10
  314. package/dist/hoi4_agent_tools/mcp/registry/metadata.js.map +0 -1
  315. package/dist/hoi4_agent_tools/mcp/resources/register.d.ts +0 -5
  316. package/dist/hoi4_agent_tools/mcp/resources/register.d.ts.map +0 -1
  317. package/dist/hoi4_agent_tools/mcp/resources/register.js.map +0 -1
  318. package/dist/hoi4_agent_tools/mcp/security/auth.d.ts +0 -24
  319. package/dist/hoi4_agent_tools/mcp/security/auth.d.ts.map +0 -1
  320. package/dist/hoi4_agent_tools/mcp/security/auth.js.map +0 -1
  321. package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts +0 -35
  322. package/dist/hoi4_agent_tools/mcp/server/base-tools.d.ts.map +0 -1
  323. package/dist/hoi4_agent_tools/mcp/server/base-tools.js.map +0 -1
  324. package/dist/hoi4_agent_tools/mcp/server/create.d.ts +0 -5
  325. package/dist/hoi4_agent_tools/mcp/server/create.d.ts.map +0 -1
  326. package/dist/hoi4_agent_tools/mcp/server/create.js.map +0 -1
  327. package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts +0 -133
  328. package/dist/hoi4_agent_tools/mcp/server/output-schemas.d.ts.map +0 -1
  329. package/dist/hoi4_agent_tools/mcp/server/output-schemas.js.map +0 -1
  330. package/dist/hoi4_agent_tools/mcp/server/progress.d.ts +0 -8
  331. package/dist/hoi4_agent_tools/mcp/server/progress.d.ts.map +0 -1
  332. package/dist/hoi4_agent_tools/mcp/server/progress.js.map +0 -1
  333. package/dist/hoi4_agent_tools/mcp/server/result.d.ts +0 -232
  334. package/dist/hoi4_agent_tools/mcp/server/result.d.ts.map +0 -1
  335. package/dist/hoi4_agent_tools/mcp/server/result.js.map +0 -1
  336. package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts +0 -5
  337. package/dist/hoi4_agent_tools/mcp/tools/focus.d.ts.map +0 -1
  338. package/dist/hoi4_agent_tools/mcp/tools/focus.js.map +0 -1
  339. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts +0 -111
  340. package/dist/hoi4_agent_tools/mcp/tools/gui.d.ts.map +0 -1
  341. package/dist/hoi4_agent_tools/mcp/tools/gui.js.map +0 -1
  342. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts +0 -5
  343. package/dist/hoi4_agent_tools/mcp/tools/map.d.ts.map +0 -1
  344. package/dist/hoi4_agent_tools/mcp/tools/map.js.map +0 -1
  345. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts +0 -58
  346. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.d.ts.map +0 -1
  347. package/dist/hoi4_agent_tools/mcp/transports/bounded-stdio.js.map +0 -1
  348. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts +0 -26
  349. package/dist/hoi4_agent_tools/mcp/transports/event-store.d.ts.map +0 -1
  350. package/dist/hoi4_agent_tools/mcp/transports/event-store.js.map +0 -1
  351. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts +0 -28
  352. package/dist/hoi4_agent_tools/mcp/transports/http.d.ts.map +0 -1
  353. package/dist/hoi4_agent_tools/mcp/transports/http.js.map +0 -1
  354. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts +0 -15
  355. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.d.ts.map +0 -1
  356. package/dist/hoi4_agent_tools/mcp/transports/protocol-gate.js.map +0 -1
  357. package/dist/hoi4_agent_tools/runtime.d.ts +0 -4
  358. package/dist/hoi4_agent_tools/runtime.d.ts.map +0 -1
  359. package/dist/hoi4_agent_tools/runtime.js.map +0 -1
  360. package/dist/hoi4_agent_tools/schemas/common.d.ts +0 -74
  361. package/dist/hoi4_agent_tools/schemas/common.d.ts.map +0 -1
  362. package/dist/hoi4_agent_tools/schemas/common.js.map +0 -1
  363. package/dist/hoi4_agent_tools/schemas/focus.d.ts +0 -784
  364. package/dist/hoi4_agent_tools/schemas/focus.d.ts.map +0 -1
  365. package/dist/hoi4_agent_tools/schemas/focus.js.map +0 -1
  366. package/dist/hoi4_agent_tools/schemas/index.d.ts +0 -5
  367. package/dist/hoi4_agent_tools/schemas/index.d.ts.map +0 -1
  368. package/dist/hoi4_agent_tools/schemas/index.js +0 -5
  369. package/dist/hoi4_agent_tools/schemas/index.js.map +0 -1
  370. package/dist/hoi4_agent_tools/schemas/map.d.ts +0 -654
  371. package/dist/hoi4_agent_tools/schemas/map.d.ts.map +0 -1
  372. package/dist/hoi4_agent_tools/schemas/map.js.map +0 -1
  373. package/dist/hoi4_agent_tools/schemas/transaction.d.ts +0 -259
  374. package/dist/hoi4_agent_tools/schemas/transaction.d.ts.map +0 -1
  375. package/dist/hoi4_agent_tools/schemas/transaction.js.map +0 -1
  376. package/dist/hoi4_agent_tools/version.d.ts +0 -6
  377. package/dist/hoi4_agent_tools/version.d.ts.map +0 -1
  378. package/dist/hoi4_agent_tools/version.js.map +0 -1
  379. package/dist/index.d.ts +0 -3
  380. package/dist/index.d.ts.map +0 -1
  381. package/dist/index.js +0 -3
  382. package/dist/index.js.map +0 -1
  383. package/docs/adr/0001-runtime-and-language.md +0 -16
  384. package/docs/adr/0002-lossless-source-model.md +0 -18
  385. package/docs/adr/0003-image-and-font-codecs.md +0 -18
  386. package/docs/adr/0004-focus-layout.md +0 -16
  387. package/docs/adr/0005-offline-rendering.md +0 -18
  388. package/docs/adr/0006-mcp-sdk-and-protocol.md +0 -16
  389. package/docs/adr/0007-storage-and-transactions.md +0 -24
  390. package/docs/adr/0008-test-strategy.md +0 -18
  391. package/docs/adr/0009-packaging-and-registry.md +0 -16
  392. package/docs/adr/0010-unsupported-and-refusal-policy.md +0 -18
  393. package/docs/adr/0011-http-security.md +0 -16
  394. package/docs/adr/README.md +0 -13
  395. package/docs/agent-integration.md +0 -136
  396. package/docs/architecture.md +0 -60
  397. package/docs/artifacts.md +0 -133
  398. package/docs/compatibility.md +0 -33
  399. package/docs/completion-report.md +0 -162
  400. package/docs/configuration.md +0 -289
  401. package/docs/focus-workflow.md +0 -195
  402. package/docs/gui-workflow.md +0 -121
  403. package/docs/limitations.md +0 -31
  404. package/docs/map-workflow.md +0 -89
  405. package/docs/performance.md +0 -117
  406. package/docs/release.md +0 -220
  407. package/docs/research/mcp-2026-07-10.md +0 -46
  408. package/docs/research/source-ledger.md +0 -68
  409. package/docs/security.md +0 -139
  410. package/docs/self-hosting.md +0 -168
  411. package/docs/testing.md +0 -43
  412. package/docs/third-party-notices.md +0 -11
  413. package/docs/transactions.md +0 -168
  414. package/docs/troubleshooting.md +0 -46
  415. package/schemas/configuration.schema.json +0 -794
  416. package/schemas/continuous-focus-palette.schema.json +0 -325
  417. package/schemas/focus-plan.schema.json +0 -927
  418. package/schemas/focus-planning-sidecar.schema.json +0 -379
  419. package/schemas/gui-animation-source.schema.json +0 -176
  420. package/schemas/gui-helper.schema.json +0 -301
  421. package/schemas/gui-scenario.schema.json +0 -298
  422. package/schemas/map-operation.schema.json +0 -2284
  423. package/schemas/operation-result.schema.json +0 -344
  424. package/schemas/transaction-manifest.schema.json +0 -685
@@ -6,18 +6,21 @@ 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, focusPlanHash, focusPresentationEvidence, focusPlanningSidecarPath, importContinuousFocusPalettes, importFocusTrees, linkContinuousFocusPalettes, parseFocusPlanningSidecar, renderContinuousFocusPalette, renderFocusTree, resolveFocusPresentation, enrichFocusPlanFromSidecar, } from '../../focus/index.js';
10
+ import { continuousFocusPaletteSchema, 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
- const focusScanOutputSchema = strictOperationResultSchema(z
16
+ import { requireServerScope } from '../server/base-tools.js';
17
+ import { autonomousFailureContext, autonomousResultArtifacts, executePlannedTransaction, } from '../server/transaction-execution.js';
18
+ const focusInspectOutputSchema = strictOperationResultSchema(z
18
19
  .object({
20
+ mode: z.enum(['national', 'continuous']),
19
21
  revision: sha256Schema,
20
22
  treeCount: nonNegativeIntegerSchema,
23
+ paletteCount: nonNegativeIntegerSchema,
21
24
  trees: z
22
25
  .array(z
23
26
  .object({
@@ -28,36 +31,22 @@ const focusScanOutputSchema = strictOperationResultSchema(z
28
31
  continuousPaletteCount: nonNegativeIntegerSchema,
29
32
  continuousFocusCount: nonNegativeIntegerSchema,
30
33
  resolvedTitleCount: nonNegativeIntegerSchema,
31
- })
32
- .strict())
33
- .max(100),
34
- })
35
- .strict());
36
- const focusLintOutputSchema = strictOperationResultSchema(z.discriminatedUnion('mode', [
37
- z
38
- .object({
39
- mode: z.literal('national'),
40
- treeId: z.string().max(256),
41
- focusCount: nonNegativeIntegerSchema,
42
34
  layoutHash: sha256Schema,
35
+ layoutDecisionCount: nonNegativeIntegerSchema,
43
36
  diagnosticCount: nonNegativeIntegerSchema,
44
37
  })
45
- .strict(),
46
- z
38
+ .strict())
39
+ .max(100),
40
+ palettes: z
41
+ .array(z
47
42
  .object({
48
- mode: z.literal('continuous'),
49
- paletteId: z.string().max(256),
43
+ id: z.string().max(256),
44
+ sourcePath: z.string().max(4096),
50
45
  focusCount: nonNegativeIntegerSchema,
51
46
  diagnosticCount: nonNegativeIntegerSchema,
52
47
  })
53
- .strict(),
54
- ]));
55
- const focusLayoutOutputSchema = strictOperationResultSchema(z
56
- .object({
57
- treeId: z.string().max(256),
58
- layoutHash: sha256Schema,
59
- nodeCount: nonNegativeIntegerSchema,
60
- decisions: z.array(focusLayoutDecisionSchema).max(100),
48
+ .strict())
49
+ .max(100),
61
50
  })
62
51
  .strict());
63
52
  const focusRenderOutputSchema = strictOperationResultSchema(z.discriminatedUnion('mode', [
@@ -96,12 +85,6 @@ const focusDriftBaseOutputSchema = z
96
85
  ]),
97
86
  sourceChanged: z.boolean(),
98
87
  planChanged: z.boolean(),
99
- requiresAuthority: z.boolean(),
100
- savedPlanHash: sha256Schema,
101
- currentPlanHash: z.string().max(256),
102
- importedPlanHash: sha256Schema,
103
- savedSourceHash: sha256Schema,
104
- currentSourceHash: sha256Schema,
105
88
  })
106
89
  .strict();
107
90
  const focusDriftOutputSchema = focusDriftBaseOutputSchema;
@@ -113,10 +96,10 @@ const focusPlanOutputSchema = strictOperationResultSchema(z.discriminatedUnion('
113
96
  treeId: z.string().max(256),
114
97
  drift: focusDriftOutputSchema,
115
98
  created: z.boolean(),
99
+ execution: z.enum(['applied', 'blocked', 'unchanged']),
116
100
  layoutHash: sha256Schema,
117
- expiresAt: z.iso.datetime(),
118
- transactionFileCount: nonNegativeIntegerSchema,
119
- transactionArtifactCount: nonNegativeIntegerSchema,
101
+ fileCount: nonNegativeIntegerSchema,
102
+ artifactCount: nonNegativeIntegerSchema,
120
103
  })
121
104
  .strict(),
122
105
  z
@@ -125,26 +108,22 @@ const focusPlanOutputSchema = strictOperationResultSchema(z.discriminatedUnion('
125
108
  paletteId: z.string().max(256),
126
109
  drift: continuousFocusDriftOutputSchema,
127
110
  created: z.boolean(),
128
- expiresAt: z.iso.datetime(),
129
- transactionFileCount: nonNegativeIntegerSchema,
130
- transactionArtifactCount: nonNegativeIntegerSchema,
111
+ execution: z.enum(['applied', 'blocked', 'unchanged']),
112
+ fileCount: nonNegativeIntegerSchema,
113
+ artifactCount: nonNegativeIntegerSchema,
131
114
  })
132
115
  .strict(),
133
116
  ]));
134
- const focusPathInput = z
135
- .object({
136
- workspaceId: workspaceIdSchema,
137
- relativePath: workspaceRelativePathSchema,
138
- treeId: z.string().min(1).max(256).optional(),
139
- })
140
- .strict();
141
- const focusLintInput = z
117
+ const focusInspectInput = z
142
118
  .object({
143
119
  mode: z.enum(['national', 'continuous']).optional(),
144
120
  workspaceId: workspaceIdSchema,
145
- relativePath: workspaceRelativePathSchema,
121
+ relativePath: workspaceRelativePathSchema.optional(),
146
122
  treeId: z.string().min(1).max(256).optional(),
147
123
  paletteId: z.string().min(1).max(256).optional(),
124
+ previous: focusLayoutSchema.optional(),
125
+ laneSpacing: z.number().int().min(1).max(100).optional(),
126
+ nodeSpacing: z.number().int().min(1).max(100).optional(),
148
127
  })
149
128
  .strict()
150
129
  .superRefine((value, context) => {
@@ -161,6 +140,22 @@ const focusLintInput = z
161
140
  path: ['treeId'],
162
141
  message: 'treeId is only valid in national mode',
163
142
  });
143
+ if (mode === 'continuous') {
144
+ for (const field of ['previous', 'laneSpacing', 'nodeSpacing']) {
145
+ if (value[field] !== undefined)
146
+ context.addIssue({
147
+ code: 'custom',
148
+ path: [field],
149
+ message: `${field} is only valid in national mode`,
150
+ });
151
+ }
152
+ }
153
+ if (value.previous !== undefined && value.treeId === undefined)
154
+ context.addIssue({
155
+ code: 'custom',
156
+ path: ['previous'],
157
+ message: 'previous requires treeId so it applies to exactly one tree',
158
+ });
164
159
  });
165
160
  const focusRenderInput = z
166
161
  .object({
@@ -214,7 +209,6 @@ const focusPlanInput = z
214
209
  workspaceId: workspaceIdSchema,
215
210
  relativePath: workspaceRelativePathSchema,
216
211
  plan: z.union([focusTreePlanSchema, continuousFocusPaletteSchema]),
217
- authority: z.enum(['plan', 'source']).optional(),
218
212
  createIfMissing: z.boolean().default(false),
219
213
  horizontalSpacing: z.number().int().min(80).max(1000).optional(),
220
214
  verticalSpacing: z.number().int().min(60).max(1000).optional(),
@@ -246,7 +240,7 @@ const focusPlanInput = z
246
240
  context.addIssue({
247
241
  code: 'custom',
248
242
  path: [field],
249
- message: `${field} is only valid for national focus transaction review renders`,
243
+ message: `${field} is only valid for national focus review renders`,
250
244
  });
251
245
  }
252
246
  }
@@ -257,9 +251,17 @@ const artifactProducing = {
257
251
  idempotentHint: true,
258
252
  openWorldHint: false,
259
253
  };
254
+ const LARGE_FOCUS_RENDER_NODE_THRESHOLD = 200;
255
+ const LARGE_FOCUS_RENDER_SCALE = 0.5;
256
+ function automaticFocusRenderScale(focusCount) {
257
+ return focusCount >= LARGE_FOCUS_RENDER_NODE_THRESHOLD ? LARGE_FOCUS_RENDER_SCALE : 1;
258
+ }
260
259
  function compactDrift(drift) {
261
- const { currentSourcePlan: _currentSourcePlan, ...summary } = drift;
262
- return summary;
260
+ return {
261
+ status: drift.status,
262
+ sourceChanged: drift.sourceChanged,
263
+ planChanged: drift.planChanged,
264
+ };
263
265
  }
264
266
  function normalizedRoot(value) {
265
267
  return value.replaceAll('\\', '/').replace(/^\.\//u, '').replace(/\/+$/u, '').toLowerCase();
@@ -390,23 +392,101 @@ function validationFromDiagnostics(diagnostics) {
390
392
  }
391
393
  export function registerFocusTools(server, engine, context) {
392
394
  const workbench = new FocusWorkbench(engine.resolver, engine.transactions, engine.artifacts);
393
- server.registerTool('hoi4.focus_scan', {
394
- title: 'Scan focus trees',
395
- description: 'Import active focus-tree source through the shared lossless parser and return compact summaries plus a full resource artifact.',
396
- inputSchema: z
397
- .object({
398
- workspaceId: workspaceIdSchema,
399
- relativePath: workspaceRelativePathSchema.optional(),
400
- })
401
- .strict(),
402
- outputSchema: focusScanOutputSchema,
395
+ server.registerTool('hoi4.focus_inspect', {
396
+ title: 'Inspect focus trees',
397
+ description: 'Inspect national trees or continuous palettes for creation and cleanup, including complete plans, references, diagnostics, and stable layout decisions.',
398
+ inputSchema: focusInspectInput,
399
+ outputSchema: focusInspectOutputSchema,
403
400
  annotations: artifactProducing,
404
- }, async ({ workspaceId, relativePath }, extra) => {
401
+ }, async (input, extra) => {
402
+ const { workspaceId, relativePath } = input;
405
403
  try {
406
404
  const progress = progressReporter(extra);
407
405
  await progress.report(0, 3, 'Building shared workspace index');
408
406
  const snapshot = await engine.scan(workspaceId, {}, context.principal, progress.signal);
409
407
  const workspace = engine.resolver.get(workspaceId, context.principal);
408
+ if (input.mode === 'continuous') {
409
+ const selectedFiles = activeContinuousFocusFiles(snapshot).filter((file) => relativePath === undefined || file.relativePath === relativePath);
410
+ if (selectedFiles.length === 0) {
411
+ throw new ServiceError('CONTINUOUS_FOCUS_SOURCE_NOT_FOUND', 'No active continuous focus source matched the request');
412
+ }
413
+ const diagnostics = [];
414
+ const importedPalettes = [];
415
+ for (const file of selectedFiles) {
416
+ progress.signal.throwIfAborted();
417
+ const imported = importContinuousFocusPalettes(parseClausewitz(file.bytes, file.displayPath));
418
+ importedPalettes.push(...imported.continuousFocusPalettes);
419
+ diagnostics.push(...imported.diagnostics);
420
+ }
421
+ const palettes = importedPalettes.filter(({ id }) => input.paletteId === undefined || id === input.paletteId);
422
+ if (palettes.length === 0) {
423
+ throw new ServiceError('CONTINUOUS_FOCUS_PALETTE_NOT_FOUND', input.paletteId === undefined
424
+ ? 'The selected source contains no continuous focus palette'
425
+ : `Continuous focus palette was not found: ${input.paletteId}`);
426
+ }
427
+ const paletteDiagnosticCounts = new Map();
428
+ for (const palette of palettes) {
429
+ const lintDiagnostics = workbench.lintContinuous(palette);
430
+ paletteDiagnosticCounts.set(palette.id, lintDiagnostics.length);
431
+ diagnostics.push(...lintDiagnostics);
432
+ }
433
+ const presentation = await resolveFocusPresentation({
434
+ plans: [],
435
+ palettes,
436
+ files: snapshot.files,
437
+ index: snapshot.index,
438
+ scanner: engine.scanner,
439
+ workspace,
440
+ signal: progress.signal,
441
+ });
442
+ diagnostics.push(...presentation.diagnostics);
443
+ await progress.report(2, 3, 'Writing continuous focus inspection');
444
+ const completeSourceHashes = Object.fromEntries(Object.entries({
445
+ ...Object.fromEntries(selectedFiles.map(({ displayPath, sha256 }) => [displayPath, sha256])),
446
+ ...presentation.sourceHashes,
447
+ }).sort(([left], [right]) => compareCodeUnits(left, right)));
448
+ const sourceEvidence = boundedSourceHashEvidence(completeSourceHashes);
449
+ const artifact = await engine.artifacts.putChunked(workspace, `focus-inspect.${snapshot.revision.slice(0, 16)}.json`, 'application/json', `${canonicalJson({
450
+ schemaVersion: 1,
451
+ mode: 'continuous',
452
+ revision: snapshot.revision,
453
+ continuousFocusPalettes: palettes,
454
+ presentation: focusPresentationEvidence(presentation),
455
+ sourceHashes: completeSourceHashes,
456
+ diagnostics,
457
+ })}\n`, {
458
+ kind: 'focus-inspect',
459
+ toolVersion: PACKAGE_VERSION,
460
+ schemaVersion: 'focus-inspect.v1',
461
+ sourceHashes: sourceEvidence.sourceHashes,
462
+ metadata: { sourceHashInventory: sourceEvidence.inventory },
463
+ }, 'Continuous focus plans and diagnostics', progress.signal);
464
+ const result = emptyServiceResult(workspaceId, {
465
+ mode: 'continuous',
466
+ revision: snapshot.revision,
467
+ treeCount: 0,
468
+ paletteCount: palettes.length,
469
+ trees: [],
470
+ palettes: palettes.slice(0, 100).map((palette) => ({
471
+ id: palette.id,
472
+ sourcePath: palette.provenance.sourcePath,
473
+ focusCount: palette.focuses.length,
474
+ diagnosticCount: paletteDiagnosticCounts.get(palette.id) ?? 0,
475
+ })),
476
+ });
477
+ result.code = 'FOCUS_INSPECTED';
478
+ setInlineFilesScanned(result, [
479
+ ...new Set([
480
+ ...selectedFiles.map(({ displayPath }) => displayPath),
481
+ ...presentation.filesScanned,
482
+ ]),
483
+ ].sort((left, right) => compareCodeUnits(left, right)));
484
+ result.diagnostics = diagnostics.slice(0, 100);
485
+ result.artifacts = [publicArtifactLink(artifact)];
486
+ result.validation = validationFromDiagnostics(diagnostics);
487
+ await progress.report(3, 3, 'Continuous focus inspection complete');
488
+ return toolResult(result);
489
+ }
410
490
  const selectedFiles = activeFocusFiles(snapshot, workspace.registration.roots.focus).filter((file) => relativePath === undefined || file.relativePath === relativePath);
411
491
  if (selectedFiles.length === 0) {
412
492
  throw new ServiceError('FOCUS_SOURCE_NOT_FOUND', 'No active focus source matched the request');
@@ -415,16 +495,40 @@ export function registerFocusTools(server, engine, context) {
415
495
  const resolved = activeSidecar(snapshot, file);
416
496
  return resolved === undefined ? [] : [resolved.file];
417
497
  });
418
- const plans = [];
498
+ const importedPlans = [];
419
499
  const diagnostics = [];
420
500
  const paletteImport = continuousPalettes(snapshot);
421
501
  diagnostics.push(...paletteImport.diagnostics);
422
502
  for (const file of selectedFiles) {
423
503
  progress.signal.throwIfAborted();
424
504
  const imported = importFocusFile(snapshot, file, paletteImport.palettes);
425
- plans.push(...imported.plans);
505
+ importedPlans.push(...imported.plans);
426
506
  diagnostics.push(...imported.diagnostics);
427
507
  }
508
+ const plans = importedPlans.filter(({ id }) => input.treeId === undefined || id === input.treeId);
509
+ if (plans.length === 0) {
510
+ throw new ServiceError('FOCUS_TREE_NOT_FOUND', input.treeId === undefined
511
+ ? 'The selected source contains no national focus tree'
512
+ : `Focus tree was not found: ${input.treeId}`);
513
+ }
514
+ const inspectedPlans = [];
515
+ for (const plan of plans) {
516
+ const layout = await workbench.layoutAsync(plan, {
517
+ ...(input.previous === undefined
518
+ ? {}
519
+ : { previous: input.previous }),
520
+ ...(input.laneSpacing === undefined ? {} : { laneSpacing: input.laneSpacing }),
521
+ ...(input.nodeSpacing === undefined ? {} : { nodeSpacing: input.nodeSpacing }),
522
+ signal: progress.signal,
523
+ });
524
+ const lintDiagnostics = workbench.lint(plan, {
525
+ index: snapshot.index,
526
+ references: referenceCatalog(snapshot),
527
+ layout,
528
+ });
529
+ diagnostics.push(...lintDiagnostics);
530
+ inspectedPlans.push({ plan, layout, diagnosticCount: lintDiagnostics.length });
531
+ }
428
532
  const presentation = await resolveFocusPresentation({
429
533
  plans,
430
534
  palettes: paletteImport.palettes,
@@ -435,7 +539,7 @@ export function registerFocusTools(server, engine, context) {
435
539
  signal: progress.signal,
436
540
  });
437
541
  diagnostics.push(...presentation.diagnostics);
438
- await progress.report(2, 3, 'Writing imported planning models');
542
+ await progress.report(2, 3, 'Writing focus plans, diagnostics, and layouts');
439
543
  const completeSourceHashes = Object.fromEntries(Object.entries({
440
544
  ...Object.fromEntries([
441
545
  ...selectedFiles,
@@ -445,25 +549,32 @@ export function registerFocusTools(server, engine, context) {
445
549
  ...presentation.sourceHashes,
446
550
  }).sort(([left], [right]) => compareCodeUnits(left, right)));
447
551
  const sourceEvidence = boundedSourceHashEvidence(completeSourceHashes);
448
- const artifact = await engine.artifacts.putChunked(workspace, `focus-scan.${snapshot.revision.slice(0, 16)}.json`, 'application/json', `${canonicalJson({
552
+ const artifact = await engine.artifacts.putChunked(workspace, `focus-inspect.${snapshot.revision.slice(0, 16)}.json`, 'application/json', `${canonicalJson({
449
553
  schemaVersion: 1,
450
554
  revision: snapshot.revision,
451
555
  plans,
556
+ layouts: inspectedPlans.map(({ plan, layout, diagnosticCount }) => ({
557
+ treeId: plan.id,
558
+ layout,
559
+ diagnosticCount,
560
+ })),
452
561
  continuousFocusPalettes: paletteImport.palettes,
453
562
  presentation: focusPresentationEvidence(presentation),
454
563
  sourceHashes: completeSourceHashes,
455
564
  diagnostics,
456
565
  })}\n`, {
457
- kind: 'focus-scan',
566
+ kind: 'focus-inspect',
458
567
  toolVersion: PACKAGE_VERSION,
459
- schemaVersion: 'focus-scan.v1',
568
+ schemaVersion: 'focus-inspect.v1',
460
569
  sourceHashes: sourceEvidence.sourceHashes,
461
570
  metadata: { sourceHashInventory: sourceEvidence.inventory },
462
- }, 'Imported focus planning models and source-linked diagnostics', progress.signal);
571
+ }, 'Focus plans, diagnostics, and stable layout decisions', progress.signal);
463
572
  const result = emptyServiceResult(workspaceId, {
573
+ mode: 'national',
464
574
  revision: snapshot.revision,
465
575
  treeCount: plans.length,
466
- trees: plans.slice(0, 100).map((plan) => ({
576
+ paletteCount: paletteImport.palettes.length,
577
+ trees: inspectedPlans.slice(0, 100).map(({ plan, layout, diagnosticCount }) => ({
467
578
  id: plan.id,
468
579
  sourcePath: plan.provenance.sourcePath,
469
580
  focusCount: plan.focuses.length,
@@ -471,9 +582,13 @@ export function registerFocusTools(server, engine, context) {
471
582
  continuousPaletteCount: plan.continuousFocusPaletteIds.length,
472
583
  continuousFocusCount: plan.continuousFocusIds.length,
473
584
  resolvedTitleCount: plan.focuses.filter(({ id }) => presentation.entries[id]?.titleSourceLocation !== undefined).length,
585
+ layoutHash: layout.layoutHash,
586
+ layoutDecisionCount: layout.decisions.length,
587
+ diagnosticCount,
474
588
  })),
589
+ palettes: [],
475
590
  });
476
- result.code = 'FOCUS_SCANNED';
591
+ result.code = 'FOCUS_INSPECTED';
477
592
  setInlineFilesScanned(result, [
478
593
  ...new Set([
479
594
  ...selectedFiles.map(({ displayPath }) => displayPath),
@@ -485,143 +600,7 @@ export function registerFocusTools(server, engine, context) {
485
600
  result.diagnostics = diagnostics.slice(0, 100);
486
601
  result.artifacts = [publicArtifactLink(artifact)];
487
602
  result.validation = validationFromDiagnostics(diagnostics);
488
- await progress.report(3, 3, 'Focus scan complete');
489
- return toolResult(result);
490
- }
491
- catch (error) {
492
- return errorResult(error, workspaceId);
493
- }
494
- });
495
- server.registerTool('hoi4.focus_lint', {
496
- title: 'Lint focus source',
497
- description: 'Lint one national focus tree or continuous focus palette. Omit mode for backward-compatible national behavior.',
498
- inputSchema: focusLintInput,
499
- outputSchema: focusLintOutputSchema,
500
- annotations: artifactProducing,
501
- }, async (input, extra) => {
502
- const { workspaceId, relativePath } = input;
503
- try {
504
- const progress = progressReporter(extra);
505
- await progress.report(0, 3, 'Importing and indexing focus source');
506
- const snapshot = await engine.scan(workspaceId, {}, context.principal, progress.signal);
507
- const workspace = engine.resolver.get(workspaceId, context.principal);
508
- if (input.mode === 'continuous') {
509
- selectedContinuousFocusFile(snapshot, relativePath);
510
- const imported = await workbench.importContinuousPath(workspaceId, relativePath, context.principal);
511
- const plan = selectContinuousPlan(imported.result, input.paletteId);
512
- const diagnostics = [...imported.result.diagnostics, ...workbench.lintContinuous(plan)];
513
- await progress.report(2, 3, 'Writing continuous focus lint evidence');
514
- 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`, {
515
- kind: 'continuous-focus-lint',
516
- toolVersion: PACKAGE_VERSION,
517
- schemaVersion: 'continuous-focus-lint.v1',
518
- sourceHashes: { [plan.provenance.sourcePath]: plan.provenance.sourceHash },
519
- }, 'Complete continuous focus lint report', progress.signal);
520
- const result = emptyServiceResult(workspaceId, {
521
- mode: 'continuous',
522
- paletteId: plan.id,
523
- focusCount: plan.focuses.length,
524
- diagnosticCount: diagnostics.length,
525
- });
526
- result.code = 'CONTINUOUS_FOCUS_LINTED';
527
- setInlineFilesScanned(result, [plan.provenance.sourcePath]);
528
- result.diagnostics = diagnostics.slice(0, 100);
529
- result.artifacts = [publicArtifactLink(artifact)];
530
- result.validation = validationFromDiagnostics(diagnostics);
531
- await progress.report(3, 3, 'Continuous focus lint complete');
532
- return toolResult(result);
533
- }
534
- const paletteImport = continuousPalettes(snapshot);
535
- const imported = importFocusFile(snapshot, selectedFocusFile(snapshot, workspace.registration.roots.focus, relativePath), paletteImport.palettes);
536
- const plan = selectPlan(imported, input.treeId);
537
- const layout = await workbench.layoutAsync(plan, { signal: progress.signal });
538
- const diagnostics = [
539
- ...paletteImport.diagnostics,
540
- ...imported.diagnostics,
541
- ...workbench.lint(plan, {
542
- index: snapshot.index,
543
- references: referenceCatalog(snapshot),
544
- layout,
545
- }),
546
- ];
547
- await progress.report(2, 3, 'Writing focus lint evidence');
548
- 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`, {
549
- kind: 'focus-lint',
550
- toolVersion: PACKAGE_VERSION,
551
- schemaVersion: 'focus-lint.v1',
552
- sourceHashes: { [plan.provenance.sourcePath]: plan.provenance.sourceHash },
553
- }, 'Complete focus lint report', progress.signal);
554
- const result = emptyServiceResult(workspaceId, {
555
- mode: 'national',
556
- treeId: plan.id,
557
- focusCount: plan.focuses.length,
558
- layoutHash: layout.layoutHash,
559
- diagnosticCount: diagnostics.length,
560
- });
561
- result.code = 'FOCUS_LINTED';
562
- setInlineFilesScanned(result, [plan.provenance.sourcePath]);
563
- result.diagnostics = diagnostics.slice(0, 100);
564
- result.artifacts = [publicArtifactLink(artifact)];
565
- result.validation = validationFromDiagnostics(diagnostics);
566
- await progress.report(3, 3, 'Focus lint complete');
567
- return toolResult(result);
568
- }
569
- catch (error) {
570
- return errorResult(error, workspaceId);
571
- }
572
- });
573
- server.registerTool('hoi4.focus_layout', {
574
- title: 'Plan stable focus layout',
575
- 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".',
576
- inputSchema: focusPathInput
577
- .extend({
578
- previous: focusLayoutSchema.optional(),
579
- laneSpacing: z.number().int().min(1).max(100).optional(),
580
- nodeSpacing: z.number().int().min(1).max(100).optional(),
581
- })
582
- .strict(),
583
- outputSchema: focusLayoutOutputSchema,
584
- annotations: artifactProducing,
585
- }, async ({ workspaceId, relativePath, treeId, previous, laneSpacing, nodeSpacing }, extra) => {
586
- try {
587
- const progress = progressReporter(extra);
588
- await progress.report(0, 3, 'Importing and indexing focus source');
589
- const snapshot = await engine.scan(workspaceId, {}, context.principal, progress.signal);
590
- const workspace = engine.resolver.get(workspaceId, context.principal);
591
- const paletteImport = continuousPalettes(snapshot);
592
- const imported = importFocusFile(snapshot, selectedFocusFile(snapshot, workspace.registration.roots.focus, relativePath), paletteImport.palettes);
593
- const plan = selectPlan(imported, treeId);
594
- const layout = await workbench.layoutAsync(plan, {
595
- ...(previous === undefined ? {} : { previous: previous }),
596
- ...(laneSpacing === undefined ? {} : { laneSpacing }),
597
- ...(nodeSpacing === undefined ? {} : { nodeSpacing }),
598
- signal: progress.signal,
599
- });
600
- progress.signal.throwIfAborted();
601
- await progress.report(2, 3, 'Writing stable focus layout evidence');
602
- const artifact = await engine.artifacts.put(workspace, `${plan.id.replace(/[^A-Za-z0-9._-]/gu, '_')}.focus-layout.json`, 'application/json', `${canonicalJson(layout)}\n`, {
603
- kind: 'focus-layout',
604
- toolVersion: PACKAGE_VERSION,
605
- schemaVersion: 'focus-layout.v1',
606
- sourceHashes: { [plan.provenance.sourcePath]: plan.provenance.sourceHash },
607
- }, 'Stable focus layout decisions and diagnostics', progress.signal);
608
- const diagnostics = [
609
- ...paletteImport.diagnostics,
610
- ...imported.diagnostics,
611
- ...layout.diagnostics,
612
- ];
613
- const result = emptyServiceResult(workspaceId, {
614
- treeId: plan.id,
615
- layoutHash: layout.layoutHash,
616
- nodeCount: layout.nodes.length,
617
- decisions: layout.decisions.slice(0, 100),
618
- });
619
- result.code = 'FOCUS_LAYOUT_PLANNED';
620
- setInlineFilesScanned(result, [plan.provenance.sourcePath]);
621
- result.diagnostics = diagnostics.slice(0, 100);
622
- result.artifacts = [publicArtifactLink(artifact)];
623
- result.validation = validationFromDiagnostics(diagnostics);
624
- await progress.report(3, 3, 'Focus layout complete');
603
+ await progress.report(3, 3, 'Focus inspection complete');
625
604
  return toolResult(result);
626
605
  }
627
606
  catch (error) {
@@ -630,7 +609,7 @@ export function registerFocusTools(server, engine, context) {
630
609
  });
631
610
  server.registerTool('hoi4.focus_render', {
632
611
  title: 'Render focus review artifacts',
633
- 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.',
612
+ 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.',
634
613
  inputSchema: focusRenderInput,
635
614
  outputSchema: focusRenderOutputSchema,
636
615
  annotations: artifactProducing,
@@ -699,6 +678,7 @@ export function registerFocusTools(server, engine, context) {
699
678
  signal: progress.signal,
700
679
  });
701
680
  await progress.report(1, 3, 'Rendering focus artifacts');
681
+ const effectiveReviewScale = input.reviewScale ?? automaticFocusRenderScale(plan.focuses.length);
702
682
  const rendered = await workbench.renderAndStore(workspaceId, plan, {
703
683
  ...(context.principal === undefined ? {} : { principal: context.principal }),
704
684
  index: snapshot.index,
@@ -712,10 +692,10 @@ export function registerFocusTools(server, engine, context) {
712
692
  ? {}
713
693
  : { verticalSpacing: input.verticalSpacing }),
714
694
  ...(input.padding === undefined ? {} : { padding: input.padding }),
715
- ...(input.reviewScale === undefined ? {} : { outputScale: input.reviewScale }),
695
+ outputScale: effectiveReviewScale,
716
696
  renderProfile: {
717
697
  sourceRevision: snapshot.revision,
718
- ...(input.reviewScale === undefined ? {} : { reviewScale: input.reviewScale }),
698
+ reviewScale: effectiveReviewScale,
719
699
  },
720
700
  budget: renderBudget,
721
701
  signal: progress.signal,
@@ -745,23 +725,23 @@ export function registerFocusTools(server, engine, context) {
745
725
  return errorResult(error, workspaceId);
746
726
  }
747
727
  });
748
- server.registerTool('hoi4.focus_plan_changes', {
749
- title: 'Dry-run focus source changes',
750
- description: 'Compile a validated national tree or continuous palette plan into source and create a hash-bound dry-run transaction; never applies it. 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.',
728
+ server.registerTool('hoi4.focus_rewrite', {
729
+ title: 'Create or clean up focus content',
730
+ description: 'Create or clean up a national tree or continuous palette from a complete plan, validate the result, apply it in one call, and return before-and-after review artifacts. Omit mode for national behavior. National plans accept bounded horizontalSpacing, verticalSpacing, padding, and reviewScale controls. Set createIfMissing for a new file.',
751
731
  inputSchema: focusPlanInput,
752
732
  outputSchema: focusPlanOutputSchema,
753
733
  annotations: {
754
734
  readOnlyHint: false,
755
- destructiveHint: false,
735
+ destructiveHint: true,
756
736
  idempotentHint: false,
757
737
  openWorldHint: false,
758
738
  },
759
739
  }, async (input, extra) => {
760
- const { workspaceId, relativePath, authority, createIfMissing, horizontalSpacing, verticalSpacing, padding, reviewScale, } = input;
740
+ const { workspaceId, relativePath, createIfMissing, horizontalSpacing, verticalSpacing, padding, reviewScale, } = input;
761
741
  try {
762
742
  requireServerScope(context, 'hoi4:write');
763
743
  const progress = progressReporter(extra);
764
- await progress.report(0, 5, 'Validating shared index and source authority');
744
+ await progress.report(0, 5, 'Validating shared index and current source');
765
745
  const snapshot = await engine.scan(workspaceId, {}, context.principal, progress.signal);
766
746
  const workspace = engine.resolver.get(workspaceId, context.principal);
767
747
  if (input.mode === 'continuous') {
@@ -787,8 +767,6 @@ export function registerFocusTools(server, engine, context) {
787
767
  }
788
768
  if (currentPlan === undefined && createIfMissing && sourceFile !== undefined)
789
769
  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 });
790
- if (currentPlan !== undefined && imported !== undefined)
791
- assertFocusPlanAuthority(detectContinuousFocusDrift(plan, imported.document), authority);
792
770
  const renderBudget = new RenderBudget();
793
771
  const presentation = await resolveFocusPresentation({
794
772
  plans: [],
@@ -865,32 +843,37 @@ export function registerFocusTools(server, engine, context) {
865
843
  ...proposed.artifacts.map(publicArtifactLink),
866
844
  ...comparisonArtifacts.map(publicArtifactLink),
867
845
  ];
868
- await progress.report(3, 5, 'Creating hash-bound continuous focus transaction');
846
+ await progress.report(3, 5, 'Preparing the continuous focus rewrite');
869
847
  const planned = await workbench.planContinuousChanges({
870
848
  workspaceId,
871
849
  relativePath,
872
850
  plan,
873
851
  createIfMissing,
874
- ...(authority === undefined ? {} : { authority }),
852
+ authority: 'plan',
875
853
  ...(context.principal === undefined ? {} : { principal: context.principal }),
876
854
  artifacts: reviewArtifacts,
877
855
  readDependencies: readDependenciesFromScannedFiles(snapshot.files),
878
856
  signal: progress.signal,
879
857
  });
880
- const transaction = planned.transaction;
858
+ await progress.report(4, 5, 'Applying and validating the continuous focus rewrite');
859
+ const execution = await executePlannedTransaction(engine, planned.transaction, context.principal, progress.signal);
860
+ const transaction = execution.transaction;
881
861
  const result = emptyServiceResult(workspaceId, {
882
862
  mode: 'continuous',
883
863
  paletteId: plan.id,
884
864
  drift: compactDrift(planned.drift),
885
865
  created: planned.drift.status === 'target_missing',
886
- expiresAt: transaction.expiresAt,
887
- transactionFileCount: transaction.files.length,
888
- transactionArtifactCount: transaction.artifacts.length,
866
+ execution: execution.outcome,
867
+ fileCount: transaction.files.length,
868
+ artifactCount: transaction.artifacts.length,
889
869
  });
890
870
  result.status = transaction.validation.passed ? 'ok' : 'blocked';
891
- result.code = transaction.validation.passed
892
- ? 'CONTINUOUS_FOCUS_CHANGES_PLANNED'
893
- : 'CONTINUOUS_FOCUS_CHANGES_BLOCKED';
871
+ result.code =
872
+ execution.outcome === 'applied'
873
+ ? 'CONTINUOUS_FOCUS_CHANGES_APPLIED'
874
+ : execution.outcome === 'unchanged'
875
+ ? 'CONTINUOUS_FOCUS_CHANGES_UNCHANGED'
876
+ : 'CONTINUOUS_FOCUS_CHANGES_BLOCKED';
894
877
  setInlineFilesScanned(result, [
895
878
  ...new Set([
896
879
  ...(sourceFile === undefined ? [] : [sourceFile.displayPath]),
@@ -900,12 +883,10 @@ export function registerFocusTools(server, engine, context) {
900
883
  result.proposedFiles = transaction.files
901
884
  .slice(0, 100)
902
885
  .map(({ relativePath: file }) => file);
886
+ result.changedFiles = transaction.appliedFiles.slice(0, 100);
903
887
  result.diagnostics = transaction.diagnostics.slice(0, 100);
904
- result.transactionId = transaction.transactionId;
905
- result.planHash = transaction.planHash;
906
- result.artifacts = [transactionResourceLink(transaction)];
888
+ result.artifacts = autonomousResultArtifacts(execution);
907
889
  result.validation = transaction.validation;
908
- result.rollbackStatus = transaction.rollbackStatus;
909
890
  result.blockers = transaction.diagnostics
910
891
  .filter(({ severity }) => severity === 'error' || severity === 'blocker')
911
892
  .map(({ code, message, details }) => ({
@@ -913,7 +894,11 @@ export function registerFocusTools(server, engine, context) {
913
894
  message,
914
895
  ...(details === undefined ? {} : { details }),
915
896
  }));
916
- await progress.report(5, 5, 'Continuous focus dry run complete');
897
+ await progress.report(5, 5, execution.outcome === 'applied'
898
+ ? 'Continuous focus rewrite complete'
899
+ : execution.outcome === 'unchanged'
900
+ ? 'Continuous focus content already satisfied the plan'
901
+ : 'Continuous focus rewrite blocked');
917
902
  return toolResult(result);
918
903
  }
919
904
  const plan = input.plan;
@@ -943,20 +928,19 @@ export function registerFocusTools(server, engine, context) {
943
928
  }
944
929
  if (currentPlan === undefined && createIfMissing && focusFile !== undefined)
945
930
  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 });
946
- if (currentPlan !== undefined && imported !== undefined)
947
- assertFocusPlanAuthority(detectFocusDrift(plan, imported.document, catalog), authority);
948
931
  const renderBudget = new RenderBudget();
932
+ const effectiveReviewScale = reviewScale ?? automaticFocusRenderScale(plan.focuses.length);
949
933
  const reviewRenderOptions = {
950
934
  ...(horizontalSpacing === undefined ? {} : { horizontalSpacing }),
951
935
  ...(verticalSpacing === undefined ? {} : { verticalSpacing }),
952
936
  ...(padding === undefined ? {} : { padding }),
953
- ...(reviewScale === undefined ? {} : { outputScale: reviewScale }),
937
+ outputScale: effectiveReviewScale,
954
938
  };
955
939
  const reviewRenderProfile = {
956
940
  ...(horizontalSpacing === undefined ? {} : { horizontalSpacing }),
957
941
  ...(verticalSpacing === undefined ? {} : { verticalSpacing }),
958
942
  ...(padding === undefined ? {} : { padding }),
959
- ...(reviewScale === undefined ? {} : { reviewScale }),
943
+ reviewScale: effectiveReviewScale,
960
944
  };
961
945
  const presentation = await resolveFocusPresentation({
962
946
  plans: [...(currentPlan === undefined ? [] : [currentPlan]), plan],
@@ -1052,13 +1036,13 @@ export function registerFocusTools(server, engine, context) {
1052
1036
  ...proposed.artifacts.map(publicArtifactLink),
1053
1037
  ...comparisonArtifacts.map(publicArtifactLink),
1054
1038
  ];
1055
- await progress.report(3, 5, 'Creating hash-bound focus transaction');
1039
+ await progress.report(3, 5, 'Preparing the focus-tree rewrite');
1056
1040
  const planned = await workbench.planChanges({
1057
1041
  workspaceId,
1058
1042
  relativePath,
1059
1043
  plan,
1060
1044
  createIfMissing,
1061
- ...(authority === undefined ? {} : { authority }),
1045
+ authority: 'plan',
1062
1046
  ...(context.principal === undefined ? {} : { principal: context.principal }),
1063
1047
  index: snapshot.index,
1064
1048
  references: catalog,
@@ -1066,21 +1050,26 @@ export function registerFocusTools(server, engine, context) {
1066
1050
  readDependencies: readDependenciesFromScannedFiles(snapshot.files),
1067
1051
  signal: progress.signal,
1068
1052
  });
1069
- const transaction = planned.transaction;
1053
+ await progress.report(4, 5, 'Applying and validating the focus-tree rewrite');
1054
+ const execution = await executePlannedTransaction(engine, planned.transaction, context.principal, progress.signal);
1055
+ const transaction = execution.transaction;
1070
1056
  const result = emptyServiceResult(workspaceId, {
1071
1057
  mode: 'national',
1072
1058
  treeId: plan.id,
1073
1059
  drift: compactDrift(planned.drift),
1074
1060
  created: planned.drift.status === 'target_missing',
1061
+ execution: execution.outcome,
1075
1062
  layoutHash: planned.layout.layoutHash,
1076
- expiresAt: transaction.expiresAt,
1077
- transactionFileCount: transaction.files.length,
1078
- transactionArtifactCount: transaction.artifacts.length,
1063
+ fileCount: transaction.files.length,
1064
+ artifactCount: transaction.artifacts.length,
1079
1065
  });
1080
1066
  result.status = transaction.validation.passed ? 'ok' : 'blocked';
1081
- result.code = transaction.validation.passed
1082
- ? 'FOCUS_CHANGES_PLANNED'
1083
- : 'FOCUS_CHANGES_BLOCKED';
1067
+ result.code =
1068
+ execution.outcome === 'applied'
1069
+ ? 'FOCUS_CHANGES_APPLIED'
1070
+ : execution.outcome === 'unchanged'
1071
+ ? 'FOCUS_CHANGES_UNCHANGED'
1072
+ : 'FOCUS_CHANGES_BLOCKED';
1084
1073
  setInlineFilesScanned(result, [
1085
1074
  ...new Set([
1086
1075
  ...(focusFile === undefined ? [] : [focusFile.displayPath]),
@@ -1090,12 +1079,10 @@ export function registerFocusTools(server, engine, context) {
1090
1079
  result.proposedFiles = transaction.files
1091
1080
  .slice(0, 100)
1092
1081
  .map(({ relativePath: file }) => file);
1082
+ result.changedFiles = transaction.appliedFiles.slice(0, 100);
1093
1083
  result.diagnostics = transaction.diagnostics.slice(0, 100);
1094
- result.transactionId = transaction.transactionId;
1095
- result.planHash = transaction.planHash;
1096
- result.artifacts = [transactionResourceLink(transaction)];
1084
+ result.artifacts = autonomousResultArtifacts(execution);
1097
1085
  result.validation = transaction.validation;
1098
- result.rollbackStatus = transaction.rollbackStatus;
1099
1086
  result.blockers = transaction.diagnostics
1100
1087
  .filter(({ severity }) => severity === 'error' || severity === 'blocker')
1101
1088
  .map(({ code, message, details }) => ({
@@ -1103,12 +1090,15 @@ export function registerFocusTools(server, engine, context) {
1103
1090
  message,
1104
1091
  ...(details === undefined ? {} : { details }),
1105
1092
  }));
1106
- await progress.report(5, 5, 'Focus dry run complete');
1093
+ await progress.report(5, 5, execution.outcome === 'applied'
1094
+ ? 'Focus rewrite complete'
1095
+ : execution.outcome === 'unchanged'
1096
+ ? 'Focus content already satisfied the plan'
1097
+ : 'Focus rewrite blocked');
1107
1098
  return toolResult(result);
1108
1099
  }
1109
1100
  catch (error) {
1110
- return errorResult(error, workspaceId);
1101
+ return errorResult(error, workspaceId, autonomousFailureContext(error));
1111
1102
  }
1112
1103
  });
1113
1104
  }
1114
- //# sourceMappingURL=focus.js.map