@hotmeshio/long-tail 0.27.0 → 0.28.1

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 (386) hide show
  1. package/README.md +9 -2
  2. package/build/api/files.d.ts +5 -0
  3. package/build/api/files.js +19 -2
  4. package/build/api/knowledge.d.ts +3 -1
  5. package/build/api/settings.d.ts +4 -1
  6. package/build/api/settings.js +7 -1
  7. package/build/index.js +9 -4
  8. package/build/lib/db/config-lock.d.ts +10 -0
  9. package/build/lib/db/config-lock.js +28 -0
  10. package/build/lib/db/schemas/041_machine_lines.sql +26 -0
  11. package/build/lib/db/schemas/042_knowledge_edition_labels.sql +9 -0
  12. package/build/lib/events/browser-view.js +8 -2
  13. package/build/lib/events/publish.d.ts +33 -0
  14. package/build/lib/events/publish.js +52 -1
  15. package/build/lib/machines/line.d.ts +7 -1
  16. package/build/lib/machines/line.js +25 -2
  17. package/build/lib/machines/protocol/codec.d.ts +14 -0
  18. package/build/lib/machines/protocol/codec.js +10 -1
  19. package/build/lib/machines/protocol/constants.d.ts +1 -1
  20. package/build/lib/machines/protocol/constants.js +1 -1
  21. package/build/lib/machines/protocol/contract.d.ts +2 -0
  22. package/build/lib/machines/protocol/contract.js +13 -8
  23. package/build/lib/machines/site/mosquitto-conf.d.ts +9 -4
  24. package/build/lib/machines/site/mosquitto-conf.js +32 -22
  25. package/build/lib/machines/site/site-conf.d.ts +13 -3
  26. package/build/lib/machines/site/site-conf.js +31 -8
  27. package/build/lib/machines/transport/callback-feed.d.ts +1 -0
  28. package/build/lib/machines/transport/callback-feed.js +4 -1
  29. package/build/lib/machines/transport/memory.d.ts +2 -0
  30. package/build/lib/machines/transport/memory.js +6 -0
  31. package/build/lib/machines/transport/mqtt-bus.d.ts +2 -0
  32. package/build/lib/machines/transport/mqtt-bus.js +4 -0
  33. package/build/lib/machines/transport/nats-bus.d.ts +3 -0
  34. package/build/lib/machines/transport/nats-bus.js +3 -0
  35. package/build/lib/machines/transport/nats-feed.d.ts +1 -0
  36. package/build/lib/machines/transport/nats-feed.js +4 -1
  37. package/build/lib/machines/transport/pubsub-feed.d.ts +1 -0
  38. package/build/lib/machines/transport/pubsub-feed.js +4 -1
  39. package/build/lib/machines/transport/stream-bus.d.ts +7 -1
  40. package/build/lib/machines/transport/stream-bus.js +17 -5
  41. package/build/lib/machines/transport/streams.d.ts +10 -2
  42. package/build/lib/machines/transport/streams.js +32 -5
  43. package/build/lib/messaging/memory.js +3 -0
  44. package/build/lib/messaging/nats/streams.d.ts +3 -0
  45. package/build/lib/messaging/nats/streams.js +16 -0
  46. package/build/lib/storage/local.d.ts +2 -0
  47. package/build/lib/storage/local.js +3 -0
  48. package/build/lib/storage/s3.d.ts +3 -2
  49. package/build/lib/storage/s3.js +6 -1
  50. package/build/lib/storage/types.d.ts +7 -1
  51. package/build/modules/machines.d.ts +8 -0
  52. package/build/modules/machines.js +16 -0
  53. package/build/routes/file-browser.js +3 -1
  54. package/build/routes/index.js +2 -0
  55. package/build/routes/knowledge.js +6 -5
  56. package/build/routes/machines.d.ts +2 -0
  57. package/build/routes/machines.js +253 -0
  58. package/build/services/knowledge/index.d.ts +4 -2
  59. package/build/services/knowledge/index.js +8 -2
  60. package/build/services/knowledge/lookup-cache.d.ts +8 -0
  61. package/build/services/knowledge/lookup-cache.js +30 -3
  62. package/build/services/knowledge/lookup-refs.js +1 -1
  63. package/build/services/knowledge/sql.d.ts +4 -2
  64. package/build/services/knowledge/sql.js +8 -3
  65. package/build/services/machines/commands.d.ts +5 -5
  66. package/build/services/machines/commands.js +3 -2
  67. package/build/services/machines/config.d.ts +4 -1
  68. package/build/services/machines/config.js +2 -1
  69. package/build/services/machines/contracts.d.ts +28 -0
  70. package/build/services/machines/contracts.js +15 -1
  71. package/build/services/machines/forms.d.ts +26 -1
  72. package/build/services/machines/forms.js +17 -1
  73. package/build/services/machines/gateway/actions.d.ts +14 -1
  74. package/build/services/machines/gateway/admission.d.ts +30 -4
  75. package/build/services/machines/gateway/admission.js +76 -14
  76. package/build/services/machines/gateway/api-escalations.js +4 -0
  77. package/build/services/machines/gateway/dispatcher.d.ts +12 -4
  78. package/build/services/machines/gateway/dispatcher.js +53 -17
  79. package/build/services/machines/gateway/executor.d.ts +13 -2
  80. package/build/services/machines/gateway/executor.js +84 -29
  81. package/build/services/machines/gateway/gateway.d.ts +21 -1
  82. package/build/services/machines/gateway/gateway.js +65 -25
  83. package/build/services/machines/gateway/index.d.ts +3 -0
  84. package/build/services/machines/gateway/index.js +3 -0
  85. package/build/services/machines/gateway/inspect.d.ts +17 -0
  86. package/build/services/machines/gateway/inspect.js +68 -0
  87. package/build/services/machines/gateway/log.d.ts +10 -0
  88. package/build/services/machines/gateway/log.js +20 -0
  89. package/build/services/machines/gateway/lt-http.js +11 -2
  90. package/build/services/machines/gateway/pacing.js +2 -1
  91. package/build/services/machines/gateway/plan-escalation.js +8 -3
  92. package/build/services/machines/gateway/plan-machine.js +41 -16
  93. package/build/services/machines/gateway/plan-shared.d.ts +5 -3
  94. package/build/services/machines/gateway/plan-shared.js +6 -4
  95. package/build/services/machines/gateway/project.d.ts +9 -0
  96. package/build/services/machines/gateway/project.js +55 -0
  97. package/build/services/machines/gateway/receipts.d.ts +3 -0
  98. package/build/services/machines/gateway/receipts.js +3 -1
  99. package/build/services/machines/gateway/reconcile.js +3 -3
  100. package/build/services/machines/gateway/registration.js +1 -1
  101. package/build/services/machines/gateway/reply-waiter.d.ts +8 -3
  102. package/build/services/machines/gateway/reply-waiter.js +37 -16
  103. package/build/services/machines/gateway/state.d.ts +53 -4
  104. package/build/services/machines/gateway/state.js +128 -13
  105. package/build/services/machines/gateway/wire-window.d.ts +21 -0
  106. package/build/services/machines/gateway/wire-window.js +61 -0
  107. package/build/services/machines/gateway/wire.d.ts +58 -0
  108. package/build/services/machines/gateway/wire.js +172 -0
  109. package/build/services/machines/index.d.ts +3 -0
  110. package/build/services/machines/index.js +2 -0
  111. package/build/services/machines/line-index.d.ts +16 -0
  112. package/build/services/machines/line-index.js +39 -0
  113. package/build/services/machines/registry-sql.d.ts +31 -0
  114. package/build/services/machines/registry-sql.js +110 -0
  115. package/build/services/machines/registry-sync.d.ts +31 -0
  116. package/build/services/machines/registry-sync.js +81 -0
  117. package/build/services/machines/registry.d.ts +77 -0
  118. package/build/services/machines/registry.js +158 -0
  119. package/build/services/machines/roles.d.ts +5 -4
  120. package/build/services/machines/roles.js +13 -4
  121. package/build/services/machines/rows.js +10 -1
  122. package/build/services/machines/select.d.ts +3 -2
  123. package/build/services/machines/select.js +4 -3
  124. package/build/services/machines/surface.d.ts +54 -5
  125. package/build/services/machines/surface.js +113 -17
  126. package/build/start/apply-report.d.ts +1 -1
  127. package/build/start/apply-report.js +3 -25
  128. package/build/start/index.js +16 -4
  129. package/build/system/activities/knowledge.d.ts +4 -0
  130. package/build/system/activities/knowledge.js +15 -0
  131. package/build/system/activities/sql.d.ts +2 -0
  132. package/build/system/activities/sql.js +6 -1
  133. package/build/system/index.js +13 -0
  134. package/build/system/mcp-servers/admin/schemas.d.ts +22 -22
  135. package/build/system/mcp-servers/human-queue-schemas.d.ts +7 -7
  136. package/build/system/mcp-servers/knowledge.js +4 -2
  137. package/build/system/mcp-servers/machines-schemas.d.ts +35 -0
  138. package/build/system/mcp-servers/machines-schemas.js +35 -0
  139. package/build/system/mcp-servers/machines.d.ts +20 -0
  140. package/build/system/mcp-servers/machines.js +154 -0
  141. package/build/system/seed/tool-manifests-machines.d.ts +2 -0
  142. package/build/system/seed/tool-manifests-machines.js +88 -0
  143. package/build/tsconfig.tsbuildinfo +1 -1
  144. package/build/types/escalation.d.ts +9 -6
  145. package/build/types/escalation.js +8 -2
  146. package/build/types/events.d.ts +6 -1
  147. package/build/types/index.d.ts +1 -0
  148. package/build/types/machines-view.d.ts +175 -0
  149. package/build/types/machines-view.js +7 -0
  150. package/build/types/machines.d.ts +5 -0
  151. package/build/types/messaging.d.ts +2 -0
  152. package/build/types/startup.d.ts +2 -0
  153. package/dashboard/dist/assets/{AdminDashboard-DlItqxFS.js → AdminDashboard-Bm7VG65H.js} +2 -2
  154. package/dashboard/dist/assets/{AdminDashboard-DlItqxFS.js.map → AdminDashboard-Bm7VG65H.js.map} +1 -1
  155. package/dashboard/dist/assets/{AgentConfigPage-BUmT4a7n.js → AgentConfigPage-aJF7Sdbc.js} +6 -6
  156. package/dashboard/dist/assets/{AgentConfigPage-BUmT4a7n.js.map → AgentConfigPage-aJF7Sdbc.js.map} +1 -1
  157. package/dashboard/dist/assets/{AgentDetailPage-Cww8rlBi.js → AgentDetailPage-GwwghhxT.js} +3 -3
  158. package/dashboard/dist/assets/{AgentDetailPage-Cww8rlBi.js.map → AgentDetailPage-GwwghhxT.js.map} +1 -1
  159. package/dashboard/dist/assets/AgentsPage-DVvCzZyg.js +2 -0
  160. package/dashboard/dist/assets/{AgentsPage-C9UuUKhr.js.map → AgentsPage-DVvCzZyg.js.map} +1 -1
  161. package/dashboard/dist/assets/AvailableEscalationsPage-Cxmcji_K.js +2 -0
  162. package/dashboard/dist/assets/{AvailableEscalationsPage-DrvfXz70.js.map → AvailableEscalationsPage-Cxmcji_K.js.map} +1 -1
  163. package/dashboard/dist/assets/{BotPicker-CDq9XRMp.js → BotPicker-CofRxk4L.js} +2 -2
  164. package/dashboard/dist/assets/{BotPicker-CDq9XRMp.js.map → BotPicker-CofRxk4L.js.map} +1 -1
  165. package/dashboard/dist/assets/{BulkAssignModal-jsvqtrEA.js → BulkAssignModal-BARWuz4L.js} +2 -2
  166. package/dashboard/dist/assets/{BulkAssignModal-jsvqtrEA.js.map → BulkAssignModal-BARWuz4L.js.map} +1 -1
  167. package/dashboard/dist/assets/{CapabilitiesPage-CSCrI6B1.js → CapabilitiesPage-BJAWVNEx.js} +2 -2
  168. package/dashboard/dist/assets/{CapabilitiesPage-CSCrI6B1.js.map → CapabilitiesPage-BJAWVNEx.js.map} +1 -1
  169. package/dashboard/dist/assets/{CollapsibleSection-uD9mn-CQ.js → CollapsibleSection-CtgoaG75.js} +2 -2
  170. package/dashboard/dist/assets/{CollapsibleSection-uD9mn-CQ.js.map → CollapsibleSection-CtgoaG75.js.map} +1 -1
  171. package/dashboard/dist/assets/{ConfirmDeleteModal-BRmx2hA4.js → ConfirmDeleteModal-BYXXBWs6.js} +2 -2
  172. package/dashboard/dist/assets/{ConfirmDeleteModal-BRmx2hA4.js.map → ConfirmDeleteModal-BYXXBWs6.js.map} +1 -1
  173. package/dashboard/dist/assets/{ConnectedAppsPage-DlMzE5a-.js → ConnectedAppsPage-D0JkzWa7.js} +2 -2
  174. package/dashboard/dist/assets/{ConnectedAppsPage-DlMzE5a-.js.map → ConnectedAppsPage-D0JkzWa7.js.map} +1 -1
  175. package/dashboard/dist/assets/{CountdownTimer-sRuM4eM5.js → CountdownTimer-BcFxdZYN.js} +2 -2
  176. package/dashboard/dist/assets/{CountdownTimer-sRuM4eM5.js.map → CountdownTimer-BcFxdZYN.js.map} +1 -1
  177. package/dashboard/dist/assets/{CredentialsPage-bLYydwqa.js → CredentialsPage-DPSY20rV.js} +2 -2
  178. package/dashboard/dist/assets/{CredentialsPage-bLYydwqa.js.map → CredentialsPage-DPSY20rV.js.map} +1 -1
  179. package/dashboard/dist/assets/{CronLabel-D_ATDL2N.js → CronLabel-Dg_Oew_Y.js} +2 -2
  180. package/dashboard/dist/assets/{CronLabel-D_ATDL2N.js.map → CronLabel-Dg_Oew_Y.js.map} +1 -1
  181. package/dashboard/dist/assets/{DropZone-u1JGfR9G.js → DropZone-Cl_Flb16.js} +2 -2
  182. package/dashboard/dist/assets/{DropZone-u1JGfR9G.js.map → DropZone-Cl_Flb16.js.map} +1 -1
  183. package/dashboard/dist/assets/{ElapsedCell-groSMfqB.js → ElapsedCell-Dm3G5fK2.js} +2 -2
  184. package/dashboard/dist/assets/{ElapsedCell-groSMfqB.js.map → ElapsedCell-Dm3G5fK2.js.map} +1 -1
  185. package/dashboard/dist/assets/{EntityTimelinePanel-D-F3_A9m.js → EntityTimelinePanel-CrEEP04e.js} +2 -2
  186. package/dashboard/dist/assets/{EntityTimelinePanel-D-F3_A9m.js.map → EntityTimelinePanel-CrEEP04e.js.map} +1 -1
  187. package/dashboard/dist/assets/{EscalationListSchemaPage-Bad6Jrmr.js → EscalationListSchemaPage-wOInXcjs.js} +3 -3
  188. package/dashboard/dist/assets/{EscalationListSchemaPage-Bad6Jrmr.js.map → EscalationListSchemaPage-wOInXcjs.js.map} +1 -1
  189. package/dashboard/dist/assets/{EscalationSchemaPage-BKi_npI9.js → EscalationSchemaPage-CrIj_g9d.js} +3 -3
  190. package/dashboard/dist/assets/{EscalationSchemaPage-BKi_npI9.js.map → EscalationSchemaPage-CrIj_g9d.js.map} +1 -1
  191. package/dashboard/dist/assets/{EscalationTimeline-DQUUm3b1.js → EscalationTimeline-CeAsl5IT.js} +2 -2
  192. package/dashboard/dist/assets/{EscalationTimeline-DQUUm3b1.js.map → EscalationTimeline-CeAsl5IT.js.map} +1 -1
  193. package/dashboard/dist/assets/{EscalationTitleSelect-3mhXh77a.js → EscalationTitleSelect-D8qpCYiy.js} +2 -2
  194. package/dashboard/dist/assets/{EscalationTitleSelect-3mhXh77a.js.map → EscalationTitleSelect-D8qpCYiy.js.map} +1 -1
  195. package/dashboard/dist/assets/{EscalationsOverview-Qaov-uML.js → EscalationsOverview-CvaqVPsr.js} +2 -2
  196. package/dashboard/dist/assets/{EscalationsOverview-Qaov-uML.js.map → EscalationsOverview-CvaqVPsr.js.map} +1 -1
  197. package/dashboard/dist/assets/{EventTable-V4RF_n58.js → EventTable-Be0JuEl6.js} +2 -2
  198. package/dashboard/dist/assets/{EventTable-V4RF_n58.js.map → EventTable-Be0JuEl6.js.map} +1 -1
  199. package/dashboard/dist/assets/FilterBar-BVyAjIgv.js +2 -0
  200. package/dashboard/dist/assets/FilterBar-BVyAjIgv.js.map +1 -0
  201. package/dashboard/dist/assets/{GraphInvokePage-Djslhf96.js → GraphInvokePage-D_QigJeD.js} +2 -2
  202. package/dashboard/dist/assets/{GraphInvokePage-Djslhf96.js.map → GraphInvokePage-D_QigJeD.js.map} +1 -1
  203. package/dashboard/dist/assets/{HomePage-EjcNxlKx.js → HomePage-C1haeuNy.js} +2 -2
  204. package/dashboard/dist/assets/{HomePage-EjcNxlKx.js.map → HomePage-C1haeuNy.js.map} +1 -1
  205. package/dashboard/dist/assets/LinePage-CWD5pv1g.js +5 -0
  206. package/dashboard/dist/assets/LinePage-CWD5pv1g.js.map +1 -0
  207. package/dashboard/dist/assets/LinesPage-NqChsKcO.js +3 -0
  208. package/dashboard/dist/assets/LinesPage-NqChsKcO.js.map +1 -0
  209. package/dashboard/dist/assets/{ListToolbar-RrEAePOX.js → ListToolbar-BZCNrTh6.js} +2 -2
  210. package/dashboard/dist/assets/{ListToolbar-RrEAePOX.js.map → ListToolbar-BZCNrTh6.js.map} +1 -1
  211. package/dashboard/dist/assets/{McpOverview-8gqiL3Vj.js → McpOverview-yJTYnh1z.js} +2 -2
  212. package/dashboard/dist/assets/{McpOverview-8gqiL3Vj.js.map → McpOverview-yJTYnh1z.js.map} +1 -1
  213. package/dashboard/dist/assets/{McpQueryDetailPage-COyn6Ak5.js → McpQueryDetailPage-ChuLpJ4u.js} +3 -3
  214. package/dashboard/dist/assets/{McpQueryDetailPage-COyn6Ak5.js.map → McpQueryDetailPage-ChuLpJ4u.js.map} +1 -1
  215. package/dashboard/dist/assets/{McpQueryPage-Dj6Qj72w.js → McpQueryPage-9S-v9soF.js} +2 -2
  216. package/dashboard/dist/assets/{McpQueryPage-Dj6Qj72w.js.map → McpQueryPage-9S-v9soF.js.map} +1 -1
  217. package/dashboard/dist/assets/McpRunDetailPage-BhrcfxD5.js +2 -0
  218. package/dashboard/dist/assets/{McpRunDetailPage-80fQn9iX.js.map → McpRunDetailPage-BhrcfxD5.js.map} +1 -1
  219. package/dashboard/dist/assets/{McpRunsPage-DaSsI-EM.js → McpRunsPage-C5_i8_Zx.js} +2 -2
  220. package/dashboard/dist/assets/{McpRunsPage-DaSsI-EM.js.map → McpRunsPage-C5_i8_Zx.js.map} +1 -1
  221. package/dashboard/dist/assets/{NamespacePill-C5epAgq6.js → NamespacePill-OTZD2hzt.js} +2 -2
  222. package/dashboard/dist/assets/{NamespacePill-C5epAgq6.js.map → NamespacePill-OTZD2hzt.js.map} +1 -1
  223. package/dashboard/dist/assets/{OperationsPage-BSu1o2gB.js → OperationsPage-C03CeU5P.js} +2 -2
  224. package/dashboard/dist/assets/{OperationsPage-BSu1o2gB.js.map → OperationsPage-C03CeU5P.js.map} +1 -1
  225. package/dashboard/dist/assets/{OperatorDashboard-HFI4WGIV.js → OperatorDashboard-BzC134Jt.js} +2 -2
  226. package/dashboard/dist/assets/{OperatorDashboard-HFI4WGIV.js.map → OperatorDashboard-BzC134Jt.js.map} +1 -1
  227. package/dashboard/dist/assets/{PageHeader-BSWIspNB.js → PageHeader-Hx8APPwE.js} +2 -2
  228. package/dashboard/dist/assets/{PageHeader-BSWIspNB.js.map → PageHeader-Hx8APPwE.js.map} +1 -1
  229. package/dashboard/dist/assets/{PageHeaderWithStats-DDjopQ-k.js → PageHeaderWithStats-BEQYYBJv.js} +2 -2
  230. package/dashboard/dist/assets/{PageHeaderWithStats-DDjopQ-k.js.map → PageHeaderWithStats-BEQYYBJv.js.map} +1 -1
  231. package/dashboard/dist/assets/{PersonaDetailPage-D0qlBuGi.js → PersonaDetailPage-D0mY9L6j.js} +2 -2
  232. package/dashboard/dist/assets/{PersonaDetailPage-D0qlBuGi.js.map → PersonaDetailPage-D0mY9L6j.js.map} +1 -1
  233. package/dashboard/dist/assets/{PersonasPage-BJClu-5H.js → PersonasPage-FFlm5Eug.js} +2 -2
  234. package/dashboard/dist/assets/{PersonasPage-BJClu-5H.js.map → PersonasPage-FFlm5Eug.js.map} +1 -1
  235. package/dashboard/dist/assets/{PortalPage-CucNZn_w.js → PortalPage-Cpc25uO-.js} +2 -2
  236. package/dashboard/dist/assets/{PortalPage-CucNZn_w.js.map → PortalPage-Cpc25uO-.js.map} +1 -1
  237. package/dashboard/dist/assets/{ProcessDetailPage-B9wMw0RV.js → ProcessDetailPage-Di2J7KwY.js} +2 -2
  238. package/dashboard/dist/assets/{ProcessDetailPage-B9wMw0RV.js.map → ProcessDetailPage-Di2J7KwY.js.map} +1 -1
  239. package/dashboard/dist/assets/{ProcessesListPage-B6k4RpmR.js → ProcessesListPage-BEXwU3Z0.js} +2 -2
  240. package/dashboard/dist/assets/{ProcessesListPage-B6k4RpmR.js.map → ProcessesListPage-BEXwU3Z0.js.map} +1 -1
  241. package/dashboard/dist/assets/{ResolverForm-ZVufJ4G-.js → ResolverForm-2ks-3jXC.js} +6 -6
  242. package/dashboard/dist/assets/{ResolverForm-ZVufJ4G-.js.map → ResolverForm-2ks-3jXC.js.map} +1 -1
  243. package/dashboard/dist/assets/{RoleDetailPage-CTbq0mz4.js → RoleDetailPage-DqoOk0xc.js} +3 -3
  244. package/dashboard/dist/assets/{RoleDetailPage-CTbq0mz4.js.map → RoleDetailPage-DqoOk0xc.js.map} +1 -1
  245. package/dashboard/dist/assets/{RolePill-CoETDpjF.js → RolePill-R5_ctGFy.js} +2 -2
  246. package/dashboard/dist/assets/{RolePill-CoETDpjF.js.map → RolePill-R5_ctGFy.js.map} +1 -1
  247. package/dashboard/dist/assets/{RolesPage-DBKxeam4.js → RolesPage-CPmo8Srr.js} +2 -2
  248. package/dashboard/dist/assets/{RolesPage-DBKxeam4.js.map → RolesPage-CPmo8Srr.js.map} +1 -1
  249. package/dashboard/dist/assets/{RosterWidget-BkLAwEYB.js → RosterWidget-D2yovCKw.js} +2 -2
  250. package/dashboard/dist/assets/{RosterWidget-BkLAwEYB.js.map → RosterWidget-D2yovCKw.js.map} +1 -1
  251. package/dashboard/dist/assets/{RunAsSelector-D2DC4iDf.js → RunAsSelector-CMv96On6.js} +2 -2
  252. package/dashboard/dist/assets/{RunAsSelector-D2DC4iDf.js.map → RunAsSelector-CMv96On6.js.map} +1 -1
  253. package/dashboard/dist/assets/{ScanCodesPage-BlKleaT0.js → ScanCodesPage-CA6cTT-M.js} +2 -2
  254. package/dashboard/dist/assets/{ScanCodesPage-BlKleaT0.js.map → ScanCodesPage-CA6cTT-M.js.map} +1 -1
  255. package/dashboard/dist/assets/{ScanSchemeDetailPage-CTW6gofi.js → ScanSchemeDetailPage-DnctN5-H.js} +2 -2
  256. package/dashboard/dist/assets/{ScanSchemeDetailPage-CTW6gofi.js.map → ScanSchemeDetailPage-DnctN5-H.js.map} +1 -1
  257. package/dashboard/dist/assets/{ScanStationPage-DPRjSPyT.js → ScanStationPage-Bk8RwkKL.js} +2 -2
  258. package/dashboard/dist/assets/{ScanStationPage-DPRjSPyT.js.map → ScanStationPage-Bk8RwkKL.js.map} +1 -1
  259. package/dashboard/dist/assets/{ScopeBadge-CGsTtqFr.js → ScopeBadge-BXZ084nD.js} +2 -2
  260. package/dashboard/dist/assets/{ScopeBadge-CGsTtqFr.js.map → ScopeBadge-BXZ084nD.js.map} +1 -1
  261. package/dashboard/dist/assets/{StickyPagination-CkmX3-Gu.js → StickyPagination-B0FSuUgs.js} +2 -2
  262. package/dashboard/dist/assets/{StickyPagination-CkmX3-Gu.js.map → StickyPagination-B0FSuUgs.js.map} +1 -1
  263. package/dashboard/dist/assets/{StreamMessageDetail-Xm_n510s.js → StreamMessageDetail-BwZEvMpP.js} +2 -2
  264. package/dashboard/dist/assets/{StreamMessageDetail-Xm_n510s.js.map → StreamMessageDetail-BwZEvMpP.js.map} +1 -1
  265. package/dashboard/dist/assets/{SwimlaneTimeline-De48aJan.js → SwimlaneTimeline-BDVQEaMw.js} +2 -2
  266. package/dashboard/dist/assets/{SwimlaneTimeline-De48aJan.js.map → SwimlaneTimeline-BDVQEaMw.js.map} +1 -1
  267. package/dashboard/dist/assets/{TagInput-S7UuVT_M.js → TagInput-DjPUDp2M.js} +2 -2
  268. package/dashboard/dist/assets/{TagInput-S7UuVT_M.js.map → TagInput-DjPUDp2M.js.map} +1 -1
  269. package/dashboard/dist/assets/{TaskDetailPage-HycMx3O9.js → TaskDetailPage-BOlv3iGB.js} +2 -2
  270. package/dashboard/dist/assets/{TaskDetailPage-HycMx3O9.js.map → TaskDetailPage-BOlv3iGB.js.map} +1 -1
  271. package/dashboard/dist/assets/{TaskQueuePill-BlHNpYiZ.js → TaskQueuePill-D-4Ynf3K.js} +2 -2
  272. package/dashboard/dist/assets/{TaskQueuePill-BlHNpYiZ.js.map → TaskQueuePill-D-4Ynf3K.js.map} +1 -1
  273. package/dashboard/dist/assets/{TasksListPage-OIcFFp1C.js → TasksListPage-e2teY0bD.js} +2 -2
  274. package/dashboard/dist/assets/{TasksListPage-OIcFFp1C.js.map → TasksListPage-e2teY0bD.js.map} +1 -1
  275. package/dashboard/dist/assets/{TimeAgo-OTC_55oZ.js → TimeAgo-Cvkpf_b3.js} +2 -2
  276. package/dashboard/dist/assets/{TimeAgo-OTC_55oZ.js.map → TimeAgo-Cvkpf_b3.js.map} +1 -1
  277. package/dashboard/dist/assets/{TimestampCell-CAwIj_AI.js → TimestampCell-B3btAV0N.js} +2 -2
  278. package/dashboard/dist/assets/{TimestampCell-CAwIj_AI.js.map → TimestampCell-B3btAV0N.js.map} +1 -1
  279. package/dashboard/dist/assets/{ToolPill-D40uLM_v.js → ToolPill-GsKQ80CO.js} +2 -2
  280. package/dashboard/dist/assets/{ToolPill-D40uLM_v.js.map → ToolPill-GsKQ80CO.js.map} +1 -1
  281. package/dashboard/dist/assets/{ToolTestPanel-8Vf6pfw4.js → ToolTestPanel-B03nebR7.js} +2 -2
  282. package/dashboard/dist/assets/{ToolTestPanel-8Vf6pfw4.js.map → ToolTestPanel-B03nebR7.js.map} +1 -1
  283. package/dashboard/dist/assets/{TopicDetailPage-iZW8rK9L.js → TopicDetailPage-DBRWne3O.js} +3 -3
  284. package/dashboard/dist/assets/{TopicDetailPage-iZW8rK9L.js.map → TopicDetailPage-DBRWne3O.js.map} +1 -1
  285. package/dashboard/dist/assets/{TopicsPage-CqiEcj-W.js → TopicsPage-CVe2M9HD.js} +2 -2
  286. package/dashboard/dist/assets/{TopicsPage-CqiEcj-W.js.map → TopicsPage-CVe2M9HD.js.map} +1 -1
  287. package/dashboard/dist/assets/{UserName-DQFjuoib.js → UserName-B_q_qp6V.js} +2 -2
  288. package/dashboard/dist/assets/{UserName-DQFjuoib.js.map → UserName-B_q_qp6V.js.map} +1 -1
  289. package/dashboard/dist/assets/WorkflowExecutionPage-Bh_dr9tM.js +2 -0
  290. package/dashboard/dist/assets/{WorkflowExecutionPage-Di08wCbs.js.map → WorkflowExecutionPage-Bh_dr9tM.js.map} +1 -1
  291. package/dashboard/dist/assets/{WorkflowPill-DJLcK_CM.js → WorkflowPill-D7244fKp.js} +2 -2
  292. package/dashboard/dist/assets/{WorkflowPill-DJLcK_CM.js.map → WorkflowPill-D7244fKp.js.map} +1 -1
  293. package/dashboard/dist/assets/{WorkflowsDashboard-Bb8HlrTJ.js → WorkflowsDashboard-DA6Mj7qH.js} +2 -2
  294. package/dashboard/dist/assets/{WorkflowsDashboard-Bb8HlrTJ.js.map → WorkflowsDashboard-DA6Mj7qH.js.map} +1 -1
  295. package/dashboard/dist/assets/{WorkflowsOverview-Dta1kurk.js → WorkflowsOverview-B1kBLj-a.js} +2 -2
  296. package/dashboard/dist/assets/{WorkflowsOverview-Dta1kurk.js.map → WorkflowsOverview-B1kBLj-a.js.map} +1 -1
  297. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CfAajg68.js → YamlWorkflowDetailPage-6GJM8QIX.js} +8 -8
  298. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CfAajg68.js.map → YamlWorkflowDetailPage-6GJM8QIX.js.map} +1 -1
  299. package/dashboard/dist/assets/{YamlWorkflowsPage-CQFUzT4t.js → YamlWorkflowsPage-Bu811C7f.js} +2 -2
  300. package/dashboard/dist/assets/{YamlWorkflowsPage-CQFUzT4t.js.map → YamlWorkflowsPage-Bu811C7f.js.map} +1 -1
  301. package/dashboard/dist/assets/{agents-PuftRTB2.js → agents-MPk_GnYz.js} +2 -2
  302. package/dashboard/dist/assets/{agents-PuftRTB2.js.map → agents-MPk_GnYz.js.map} +1 -1
  303. package/dashboard/dist/assets/{bots-BmEiPAWY.js → bots-2RihE2Tc.js} +2 -2
  304. package/dashboard/dist/assets/{bots-BmEiPAWY.js.map → bots-2RihE2Tc.js.map} +1 -1
  305. package/dashboard/dist/assets/{capabilities-CRii4Soa.js → capabilities-CC4iwJ1P.js} +2 -2
  306. package/dashboard/dist/assets/{capabilities-CRii4Soa.js.map → capabilities-CC4iwJ1P.js.map} +1 -1
  307. package/dashboard/dist/assets/{controlplane-DO_czaYo.js → controlplane-Bmkic8BH.js} +2 -2
  308. package/dashboard/dist/assets/{controlplane-DO_czaYo.js.map → controlplane-Bmkic8BH.js.map} +1 -1
  309. package/dashboard/dist/assets/{escalation-columns-CzCquCPh.js → escalation-columns-B0lhUUrQ.js} +2 -2
  310. package/dashboard/dist/assets/{escalation-columns-CzCquCPh.js.map → escalation-columns-B0lhUUrQ.js.map} +1 -1
  311. package/dashboard/dist/assets/{escalation-items-Cy0ZgJqV.js → escalation-items-7WFpPo46.js} +2 -2
  312. package/dashboard/dist/assets/{escalation-items-Cy0ZgJqV.js.map → escalation-items-7WFpPo46.js.map} +1 -1
  313. package/dashboard/dist/assets/index-B9uv-euR.css +1 -0
  314. package/dashboard/dist/assets/{index-DhSCCpqM.js → index-B_XV1rwu.js} +2 -2
  315. package/dashboard/dist/assets/{index-DhSCCpqM.js.map → index-B_XV1rwu.js.map} +1 -1
  316. package/dashboard/dist/assets/{index-Cx8xb-oU.js → index-C2CLfGwL.js} +2 -2
  317. package/dashboard/dist/assets/{index-Cx8xb-oU.js.map → index-C2CLfGwL.js.map} +1 -1
  318. package/dashboard/dist/assets/{index-Cga5IW3D.js → index-C3AeFihz.js} +2 -2
  319. package/dashboard/dist/assets/{index-Cga5IW3D.js.map → index-C3AeFihz.js.map} +1 -1
  320. package/dashboard/dist/assets/{index-DiaRlFYI.js → index-CBri8fYM.js} +2 -2
  321. package/dashboard/dist/assets/{index-DiaRlFYI.js.map → index-CBri8fYM.js.map} +1 -1
  322. package/dashboard/dist/assets/{index-CL_1VpGb.js → index-CRWsB7ZC.js} +2 -2
  323. package/dashboard/dist/assets/{index-CL_1VpGb.js.map → index-CRWsB7ZC.js.map} +1 -1
  324. package/dashboard/dist/assets/{index-XntldBd0.js → index-CTOv3G7a.js} +2 -2
  325. package/dashboard/dist/assets/{index-XntldBd0.js.map → index-CTOv3G7a.js.map} +1 -1
  326. package/dashboard/dist/assets/{index-CfP2nKRc.js → index-CcArGkzI.js} +3 -3
  327. package/dashboard/dist/assets/{index-CfP2nKRc.js.map → index-CcArGkzI.js.map} +1 -1
  328. package/dashboard/dist/assets/{index-Dz6R8-Dw.js → index-CkMHS-hG.js} +25 -25
  329. package/dashboard/dist/assets/index-CkMHS-hG.js.map +1 -0
  330. package/dashboard/dist/assets/index-CmsmwCyv.js +2 -0
  331. package/dashboard/dist/assets/{index-4YaDUcKd.js.map → index-CmsmwCyv.js.map} +1 -1
  332. package/dashboard/dist/assets/{index-2SM2_onB.js → index-CvJsvqIc.js} +2 -2
  333. package/dashboard/dist/assets/{index-2SM2_onB.js.map → index-CvJsvqIc.js.map} +1 -1
  334. package/dashboard/dist/assets/{index-Rwqrflm-.js → index-D-ilRyfy.js} +2 -2
  335. package/dashboard/dist/assets/{index-Rwqrflm-.js.map → index-D-ilRyfy.js.map} +1 -1
  336. package/dashboard/dist/assets/{index-CZ7A3AcD.js → index-DSUtfDXx.js} +2 -2
  337. package/dashboard/dist/assets/{index-CZ7A3AcD.js.map → index-DSUtfDXx.js.map} +1 -1
  338. package/dashboard/dist/assets/{index-jL2K6us4.js → index-Da6ycKyf.js} +2 -2
  339. package/dashboard/dist/assets/{index-jL2K6us4.js.map → index-Da6ycKyf.js.map} +1 -1
  340. package/dashboard/dist/assets/{knowledge-CeUqGPuo.js → knowledge-Bpbg20DC.js} +2 -2
  341. package/dashboard/dist/assets/{knowledge-CeUqGPuo.js.map → knowledge-Bpbg20DC.js.map} +1 -1
  342. package/dashboard/dist/assets/machines-BqOZZU-3.js +2 -0
  343. package/dashboard/dist/assets/machines-BqOZZU-3.js.map +1 -0
  344. package/dashboard/dist/assets/{mcp-Cx96NTeD.js → mcp-CmcUXYce.js} +2 -2
  345. package/dashboard/dist/assets/{mcp-Cx96NTeD.js.map → mcp-CmcUXYce.js.map} +1 -1
  346. package/dashboard/dist/assets/{mcp-query-XAzWl0gm.js → mcp-query-C8buQxN9.js} +2 -2
  347. package/dashboard/dist/assets/{mcp-query-XAzWl0gm.js.map → mcp-query-C8buQxN9.js.map} +1 -1
  348. package/dashboard/dist/assets/{personas--4kjwyOw.js → personas-C2n5oDmY.js} +2 -2
  349. package/dashboard/dist/assets/{personas--4kjwyOw.js.map → personas-C2n5oDmY.js.map} +1 -1
  350. package/dashboard/dist/assets/{pipelines-PgkwvG7f.js → pipelines-RKpSkFz7.js} +2 -2
  351. package/dashboard/dist/assets/{pipelines-PgkwvG7f.js.map → pipelines-RKpSkFz7.js.map} +1 -1
  352. package/dashboard/dist/assets/{tasks-CcYxdBa3.js → tasks-Dab4hExW.js} +2 -2
  353. package/dashboard/dist/assets/{tasks-CcYxdBa3.js.map → tasks-Dab4hExW.js.map} +1 -1
  354. package/dashboard/dist/assets/{topics-_lik7cNY.js → topics-FTMNP7r3.js} +2 -2
  355. package/dashboard/dist/assets/{topics-_lik7cNY.js.map → topics-FTMNP7r3.js.map} +1 -1
  356. package/dashboard/dist/assets/{useDebouncedValue-Bm_AoxVx.js → useDebouncedValue-B_1u1YIk.js} +2 -2
  357. package/dashboard/dist/assets/{useDebouncedValue-Bm_AoxVx.js.map → useDebouncedValue-B_1u1YIk.js.map} +1 -1
  358. package/dashboard/dist/assets/{useNamespace-DgXXKdx5.js → useNamespace-HUeAI7Qb.js} +2 -2
  359. package/dashboard/dist/assets/{useNamespace-DgXXKdx5.js.map → useNamespace-HUeAI7Qb.js.map} +1 -1
  360. package/dashboard/dist/assets/{useYamlActivityEvents-Dj2qtGSd.js → useYamlActivityEvents-Cax54qHH.js} +2 -2
  361. package/dashboard/dist/assets/{useYamlActivityEvents-Dj2qtGSd.js.map → useYamlActivityEvents-Cax54qHH.js.map} +1 -1
  362. package/dashboard/dist/assets/{validate-FlXCBBT6.js → validate-DxOaV7QS.js} +2 -2
  363. package/dashboard/dist/assets/{validate-FlXCBBT6.js.map → validate-DxOaV7QS.js.map} +1 -1
  364. package/dashboard/dist/assets/{vendor-icons-DUYcKTjP.js → vendor-icons-fxBvvHBi.js} +187 -182
  365. package/dashboard/dist/assets/vendor-icons-fxBvvHBi.js.map +1 -0
  366. package/dashboard/dist/assets/{yaml-workflows-B0_JxRYQ.js → yaml-workflows-BgY1XHJx.js} +2 -2
  367. package/dashboard/dist/assets/{yaml-workflows-B0_JxRYQ.js.map → yaml-workflows-BgY1XHJx.js.map} +1 -1
  368. package/dashboard/dist/index.html +3 -3
  369. package/docs/architecture.md +1 -0
  370. package/docs/code-owned-configuration.md +6 -0
  371. package/docs/dashboard.md +2 -1
  372. package/docs/events.md +34 -1
  373. package/docs/hitl/lookups.md +6 -4
  374. package/docs/machines.md +114 -28
  375. package/docs/mcp.md +19 -0
  376. package/package.json +1 -1
  377. package/dashboard/dist/assets/AgentsPage-C9UuUKhr.js +0 -2
  378. package/dashboard/dist/assets/AvailableEscalationsPage-DrvfXz70.js +0 -2
  379. package/dashboard/dist/assets/FilterBar-BygWrnB1.js +0 -2
  380. package/dashboard/dist/assets/FilterBar-BygWrnB1.js.map +0 -1
  381. package/dashboard/dist/assets/McpRunDetailPage-80fQn9iX.js +0 -2
  382. package/dashboard/dist/assets/WorkflowExecutionPage-Di08wCbs.js +0 -2
  383. package/dashboard/dist/assets/index-4YaDUcKd.js +0 -2
  384. package/dashboard/dist/assets/index-CnU7Jjz3.css +0 -1
  385. package/dashboard/dist/assets/index-Dz6R8-Dw.js.map +0 -1
  386. package/dashboard/dist/assets/vendor-icons-DUYcKTjP.js.map +0 -1
@@ -17,6 +17,7 @@ import { type LineEscalations } from './escalations';
17
17
  import { type GatewayLog } from './log';
18
18
  import type { CommandReply, ReplyWaiter } from './reply-waiter';
19
19
  import { type GatewayState } from './state';
20
+ import type { WireRecorder } from './wire';
20
21
  export interface DispatcherDeps {
21
22
  bus: MachineBus;
22
23
  codec: LineCodec;
@@ -27,6 +28,8 @@ export interface DispatcherDeps {
27
28
  replyTimeoutMs: number;
28
29
  dispatchAttempts: number;
29
30
  log: GatewayLog;
31
+ /** Records each command the gateway sends, for the line's wire view. */
32
+ wire?: Pick<WireRecorder, 'command'>;
30
33
  }
31
34
  type DispatchAction = Extract<Action, {
32
35
  kind: 'dispatch';
@@ -49,12 +52,15 @@ export declare class Dispatcher {
49
52
  /** Work still running sends nothing more and changes no row. */
50
53
  stop(): void;
51
54
  private live;
52
- /** This send's attempt number, and whether the machine may have the command already. */
55
+ /**
56
+ * This send's attempt number, whether the machine may have the command already, and when it was
57
+ * issued: the time given (a round's start, the same for every gateway), else the first send's.
58
+ */
53
59
  private countSend;
54
60
  /** False when the codec has no message for the command. `since` is when the command's row was created. */
55
- publish(machineId: string, op: string, cmdId: string, args: Record<string, any>, since?: number): Promise<boolean>;
61
+ publish(machineId: string, op: string, cmdId: string, args: Record<string, any>, since?: number, issuedAt?: number): Promise<boolean>;
56
62
  /** Publish and wait for the reply, asking again with the same id; null when none came. */
57
- ask(machineId: string, op: string, cmdId: string, args: Record<string, any>, since?: number): Promise<CommandReply | null>;
63
+ ask(machineId: string, op: string, cmdId: string, args: Record<string, any>, since?: number, issuedAt?: number): Promise<CommandReply | null>;
58
64
  command(a: CommandAction): Promise<void>;
59
65
  /**
60
66
  * A machine-command row: send it, then resolve the row with the reply, as the
@@ -65,7 +71,9 @@ export declare class Dispatcher {
65
71
  */
66
72
  control(a: ControlAction): Promise<void>;
67
73
  dispatch(a: DispatchAction): Promise<void>;
68
- /** The units were already at the machine: its acceptance completes the handoff. */
74
+ /** A job sent again after the machine restarted, for a row that already ended: the reply is only logged. */
75
+ private resent;
76
+ /** The units were already at the machine: a job it has taken and is ready for completes the handoff. */
69
77
  private received;
70
78
  /** Ask a silent machine what it holds; null when it cannot say or does not answer in time. */
71
79
  private heldJobs;
@@ -30,6 +30,10 @@ function fromMachine(reply) {
30
30
  function took(reply) {
31
31
  return reply?.status === protocol_1.REPLY_STATUS.ACCEPTED || reply?.status === protocol_1.REPLY_STATUS.COMPLETED;
32
32
  }
33
+ /** The reply's structured code for a resolution, when it carried one. */
34
+ function withCode(reply) {
35
+ return reply.code ? { code: reply.code } : {};
36
+ }
33
37
  /** Most command ids whose sends are counted; the oldest are forgotten first. */
34
38
  const SENT_REMEMBERED = 10_000;
35
39
  /** Ends a dispatch or command still running when the gateway stops; the next leader takes it up from the row. */
@@ -53,29 +57,38 @@ class Dispatcher {
53
57
  if (this.stopping.signal.aborted)
54
58
  throw new GatewayStopped();
55
59
  }
56
- /** This send's attempt number, and whether the machine may have the command already. */
57
- countSend(cmdId, since) {
58
- const attempt = (this.sent.get(cmdId) ?? 0) + 1;
60
+ /**
61
+ * This send's attempt number, whether the machine may have the command already, and when it was
62
+ * issued: the time given (a round's start, the same for every gateway), else the first send's.
63
+ */
64
+ countSend(cmdId, since, issuedAt) {
65
+ const before = this.sent.get(cmdId);
66
+ const record = { attempt: (before?.attempt ?? 0) + 1, issuedAt: issuedAt ?? before?.issuedAt ?? Date.now() };
59
67
  this.sent.delete(cmdId);
60
- this.sent.set(cmdId, attempt);
68
+ this.sent.set(cmdId, record);
61
69
  if (this.sent.size > SENT_REMEMBERED)
62
70
  this.sent.delete(this.sent.keys().next().value);
63
- return { attempt, retry: attempt > 1 || (since !== undefined && since < this.d.state.takenAt) };
71
+ const retry = record.attempt > 1 || (since !== undefined && since < this.d.state.takenAt);
72
+ return { attempt: record.attempt, retry, issuedAt: (0, protocol_1.isoTs)(record.issuedAt) };
64
73
  }
65
74
  /** False when the codec has no message for the command. `since` is when the command's row was created. */
66
- async publish(machineId, op, cmdId, args, since) {
75
+ async publish(machineId, op, cmdId, args, since, issuedAt) {
67
76
  this.live();
68
- const wires = this.d.codec.encode((0, registration_1.identFor)(this.d.state, this.d.line, machineId), { cmdId, op, args, ...this.countSend(cmdId, since) });
69
- for (const wire of wires)
77
+ const ident = (0, registration_1.identFor)(this.d.state, this.d.line, machineId);
78
+ const command = { cmdId, op, args, ...this.countSend(cmdId, since, issuedAt) };
79
+ const wires = this.d.codec.encode(ident, command);
80
+ for (const wire of wires) {
70
81
  await this.d.bus.publish(wire.topic, wire.payload);
82
+ this.d.wire?.command(ident, command, wire);
83
+ }
71
84
  return wires.length > 0;
72
85
  }
73
86
  /** Publish and wait for the reply, asking again with the same id; null when none came. */
74
- async ask(machineId, op, cmdId, args, since) {
87
+ async ask(machineId, op, cmdId, args, since, issuedAt) {
75
88
  for (let attempt = 1; attempt <= this.d.dispatchAttempts; attempt++) {
76
89
  this.live();
77
90
  const waiting = this.d.replies.wait(cmdId, this.d.replyTimeoutMs);
78
- if (!await this.publish(machineId, op, cmdId, args, since)) {
91
+ if (!await this.publish(machineId, op, cmdId, args, since, issuedAt)) {
79
92
  this.d.replies.settle({ cmdId, status: contracts_1.COMMAND_STATUS.UNSUPPORTED, reason: `the line's codec has no ${op} command` });
80
93
  }
81
94
  const reply = await waiting;
@@ -104,14 +117,15 @@ class Dispatcher {
104
117
  */
105
118
  async control(a) {
106
119
  const now = Date.now();
107
- const { round, expiresAt } = (0, pacing_1.dispatchWindow)(a.createdAt ?? now, now, this.d.replyTimeoutMs * this.d.dispatchAttempts);
108
- const reply = await this.ask(a.machineId, a.op, (0, contracts_1.controlCommandId)(a.rowId, round), { ...a.args, expiresAt: (0, protocol_1.isoTs)(expiresAt) }, a.createdAt);
120
+ const ttlMs = this.d.replyTimeoutMs * this.d.dispatchAttempts;
121
+ const { round, expiresAt } = (0, pacing_1.dispatchWindow)(a.createdAt ?? now, now, ttlMs);
122
+ const reply = await this.ask(a.machineId, a.op, (0, contracts_1.controlCommandId)(a.rowId, round), { ...a.args, expiresAt: (0, protocol_1.isoTs)(expiresAt) }, a.createdAt, expiresAt - ttlMs);
109
123
  // Timers may fire a little early; the command must have expired before the row says no-reply.
110
124
  if (!reply && Date.now() <= expiresAt)
111
125
  await (0, promises_1.setTimeout)(expiresAt - Date.now() + 1, undefined, { signal: this.stopping.signal }).catch(() => undefined);
112
126
  this.live();
113
127
  const outcome = reply
114
- ? { accepted: reply.status === protocol_1.REPLY_STATUS.ACCEPTED, machineId: a.machineId, op: a.op, status: reply.status, reason: reply.reason }
128
+ ? { accepted: reply.status === protocol_1.REPLY_STATUS.ACCEPTED, machineId: a.machineId, op: a.op, status: reply.status, reason: reply.reason, ...withCode(reply) }
115
129
  : { accepted: false, machineId: a.machineId, op: a.op, status: contracts_1.COMMAND_STATUS.NO_REPLY, reason: `no reply after ${this.d.dispatchAttempts} attempts` };
116
130
  const context = { row: a.rowId, machine: a.machineId, op: a.op, status: outcome.status, reason: outcome.reason };
117
131
  if (outcome.accepted)
@@ -134,22 +148,36 @@ class Dispatcher {
134
148
  for (const job of jobs)
135
149
  state.rememberDispatch(`${a.cmdId}${job.suffix}`, a.rowId);
136
150
  const since = state.get(a.rowId)?.createdAt;
137
- const replies = await Promise.all(jobs.map((job) => this.ask(a.machineId, protocol_1.OP.DISPATCH, `${a.cmdId}${job.suffix}`, { ...a.args, jobId: job.jobId, units: job.units }, since)));
151
+ const replies = await Promise.all(jobs.map((job) => this.ask(a.machineId, protocol_1.OP.DISPATCH, `${a.cmdId}${job.suffix}`, { ...a.args, jobId: job.jobId, units: job.units }, since, a.issuedAt)));
138
152
  const refused = replies.find((r) => r && !took(r));
139
153
  const silent = jobs.filter((_, i) => !replies[i]);
140
154
  const held = !refused && silent.length ? await this.heldJobs(a.machineId, a.cmdId) : null;
141
155
  this.live();
142
156
  const reconciled = !!held && silent.every((j) => held.has(j.jobId));
157
+ if (a.ended) {
158
+ this.resent(a, jobs, refused ?? null, !refused && (!silent.length || reconciled));
159
+ return;
160
+ }
143
161
  const row = state.get(a.rowId);
144
162
  if (!refused && (!silent.length || reconciled)) {
145
163
  if (row)
146
164
  row.dispatch = state_1.DISPATCH_STATE.ACCEPTED;
165
+ for (const job of jobs)
166
+ state.rememberSent(a.machineId, job.jobId, a.rowId);
147
167
  if (reconciled)
148
168
  log.info(log_1.GATEWAY_LOG.DISPATCH_RECONCILED, { row: a.rowId, machine: a.machineId, jobs: silent.map((j) => j.jobId) });
149
169
  log.info(log_1.GATEWAY_LOG.DISPATCHED, { row: a.rowId, machine: a.machineId, reason: replies.map((r) => r?.reason ?? 'held').join('; ') });
150
170
  this.check(a.rowId, 'claim', await lt.claim(a.machineId, a.rowId));
151
- if (a.receivedOnAccept)
171
+ if (!a.receivedOnAccept)
172
+ return;
173
+ const preparing = jobs.filter((job, i) => replies[i]?.status === protocol_1.REPLY_STATUS.ACCEPTED && replies[i]?.preparing).map((job) => `${a.cmdId}${job.suffix}`);
174
+ if (!preparing.length) {
152
175
  await this.received(a);
176
+ return;
177
+ }
178
+ if (row)
179
+ row.awaitingReady = new Set(preparing);
180
+ log.info(log_1.GATEWAY_LOG.DISPATCH_PREPARING, { row: a.rowId, machine: a.machineId, jobs: preparing });
153
181
  return;
154
182
  }
155
183
  // The handoff may have ended meanwhile: a machine that ran the job anyway reports the arrival.
@@ -158,7 +186,7 @@ class Dispatcher {
158
186
  row.dispatch = state_1.DISPATCH_STATE.REFUSED;
159
187
  const unanswered = `${a.machineId} sent no reply after ${this.d.dispatchAttempts} attempts`;
160
188
  const resolution = refused
161
- ? { received: false, errorCode: contracts_1.HANDOFF_ERROR.DISPATCH_REFUSED, detail: `${a.machineId} ${refused.status}: ${refused.reason}` }
189
+ ? { received: false, errorCode: contracts_1.HANDOFF_ERROR.DISPATCH_REFUSED, detail: `${a.machineId} ${refused.status}: ${refused.reason}`, ...withCode(refused) }
162
190
  : { received: false, errorCode: contracts_1.HANDOFF_ERROR.NO_REPLY, detail: held ? `${unanswered} and does not hold the job` : `${unanswered}; its state is unknown` };
163
191
  log.warn(log_1.GATEWAY_LOG.DISPATCH_REFUSED, { row: a.rowId, machine: a.machineId, ...resolution });
164
192
  const ended = await lt.resolve(fromMachine(refused ?? null) ? a.machineId : actions_1.CONTROLLER, a.rowId, resolution);
@@ -168,7 +196,15 @@ class Dispatcher {
168
196
  return;
169
197
  await this.withdraw(a, jobs.filter((_, i) => !replies[i] || took(replies[i])));
170
198
  }
171
- /** The units were already at the machine: its acceptance completes the handoff. */
199
+ /** A job sent again after the machine restarted, for a row that already ended: the reply is only logged. */
200
+ resent(a, jobs, refused, taken) {
201
+ const context = { row: a.rowId, machine: a.machineId, jobs: jobs.map((j) => j.jobId), resent: true };
202
+ if (taken)
203
+ this.d.log.info(log_1.GATEWAY_LOG.DISPATCHED, { ...context, reason: 'sent again after a restart' });
204
+ else
205
+ this.d.log.warn(log_1.GATEWAY_LOG.DISPATCH_REFUSED, { ...context, reason: refused ? `${refused.status}: ${refused.reason}` : 'no reply' });
206
+ }
207
+ /** The units were already at the machine: a job it has taken and is ready for completes the handoff. */
172
208
  async received(a) {
173
209
  this.live();
174
210
  const units = a.args.units.map((u) => u.unitId);
@@ -2,17 +2,20 @@
2
2
  * Runs the planner's actions: escalation verbs through LineEscalations,
3
3
  * dispatches and commands through the Dispatcher, alarm and machine rows,
4
4
  * and the offline debounce. A verb that fails for real throws, so the message that
5
- * caused it is delivered again.
5
+ * caused it is delivered again. What ran comes back as wire actions, for the
6
+ * record of the message that caused it.
6
7
  */
7
8
  import { type LineDef } from '../../../lib/machines/line';
8
9
  import { type LineCodec } from '../../../lib/machines/protocol';
9
10
  import type { MachineBus } from '../../../lib/machines/transport';
11
+ import type { WireAction } from '../../../types/machines-view';
10
12
  import { type Action } from './actions';
11
13
  import type { AddressBook } from './address-book';
12
14
  import { type LineEscalations } from './escalations';
13
15
  import { type GatewayLog } from './log';
14
16
  import type { ReplyWaiter } from './reply-waiter';
15
17
  import { type GatewayState } from './state';
18
+ import { type WireRecorder } from './wire';
16
19
  export interface ExecutorDeps {
17
20
  bus: MachineBus;
18
21
  lt: LineEscalations;
@@ -26,19 +29,25 @@ export interface ExecutorDeps {
26
29
  log: GatewayLog;
27
30
  /** Where learned addresses are kept (registration.ts). */
28
31
  addresses: AddressBook;
32
+ /** Records each command sent, for the line's wire view. */
33
+ wire?: Pick<WireRecorder, 'command'>;
29
34
  }
30
35
  export declare class Executor {
31
36
  private readonly d;
32
37
  private inflight;
33
38
  private quietPending;
34
39
  private timers;
40
+ private stopped;
35
41
  private readonly dispatcher;
36
42
  constructor(d: ExecutorDeps);
37
43
  /** Dispatches and commands run detached so one slow reply never holds up the feed. */
38
- apply(actions: Action[]): Promise<void>;
44
+ apply(actions: Action[]): Promise<WireAction[]>;
39
45
  /** Resolves when every detached dispatch has finished. */
40
46
  idle(): Promise<void>;
47
+ /** Work still running sends nothing more and raises no row; the next leader takes it up from the message or the row. */
41
48
  stop(): void;
49
+ /** A row raised after stop() would be raised again by the next leader, so the message is nak'd instead. */
50
+ private live;
42
51
  private track;
43
52
  private run;
44
53
  /**
@@ -48,6 +57,8 @@ export declare class Executor {
48
57
  * carrying the units out of it.
49
58
  */
50
59
  private lateReply;
60
+ /** On arrival dispatch, a row that waited for the machine to prepare is received once every job it sent is ready. */
61
+ private readyForArrival;
51
62
  /** Add the item; when the row then holds every key the action waits for, resolve it. */
52
63
  private accumulate;
53
64
  private check;
@@ -3,7 +3,8 @@
3
3
  * Runs the planner's actions: escalation verbs through LineEscalations,
4
4
  * dispatches and commands through the Dispatcher, alarm and machine rows,
5
5
  * and the offline debounce. A verb that fails for real throws, so the message that
6
- * caused it is delivered again.
6
+ * caused it is delivered again. What ran comes back as wire actions, for the
7
+ * record of the message that caused it.
7
8
  */
8
9
  Object.defineProperty(exports, "__esModule", { value: true });
9
10
  exports.Executor = void 0;
@@ -16,18 +17,28 @@ const log_1 = require("./log");
16
17
  const dispatcher_1 = require("./dispatcher");
17
18
  const plan_shared_1 = require("./plan-shared");
18
19
  const state_1 = require("./state");
20
+ const wire_1 = require("./wire");
19
21
  const NOT_FOUND = 404;
20
22
  const CONFLICT = 409;
23
+ /** A verb's outcome as the wire records it: done, already done, or refused by Long Tail. */
24
+ function outcomeOf(verb, rowId, result) {
25
+ const refused = result.outcome === escalations_1.VERB_OUTCOME.INVALID || result.status === NOT_FOUND || result.status === CONFLICT;
26
+ if (refused)
27
+ return { verb: 'refuse', rowId, detail: `${verb}: ${result.detail ?? result.outcome}` };
28
+ return { verb, rowId, ...(result.outcome === escalations_1.VERB_OUTCOME.ALREADY ? { detail: result.detail ?? 'already ended' } : {}) };
29
+ }
21
30
  class Executor {
22
31
  constructor(d) {
23
32
  this.d = d;
24
33
  this.inflight = new Set();
25
34
  this.quietPending = new Set();
26
35
  this.timers = new Set();
36
+ this.stopped = false;
27
37
  this.dispatcher = new dispatcher_1.Dispatcher(d);
28
38
  }
29
39
  /** Dispatches and commands run detached so one slow reply never holds up the feed. */
30
40
  async apply(actions) {
41
+ const done = [];
31
42
  for (const action of actions) {
32
43
  if (action.kind === 'dispatch')
33
44
  this.track(this.dispatcher.dispatch(action));
@@ -35,22 +46,33 @@ class Executor {
35
46
  this.track(this.dispatcher.command(action));
36
47
  else if (action.kind === 'control')
37
48
  this.track(this.dispatcher.control(action));
38
- else
39
- await this.run(action);
49
+ else {
50
+ done.push(...await this.run(action));
51
+ continue;
52
+ }
53
+ done.push((0, wire_1.plannedAction)(action));
40
54
  }
55
+ return done;
41
56
  }
42
57
  /** Resolves when every detached dispatch has finished. */
43
58
  async idle() {
44
59
  while (this.inflight.size)
45
60
  await Promise.all([...this.inflight]);
46
61
  }
62
+ /** Work still running sends nothing more and raises no row; the next leader takes it up from the message or the row. */
47
63
  stop() {
64
+ this.stopped = true;
48
65
  for (const t of this.timers)
49
66
  clearTimeout(t);
50
67
  this.timers.clear();
51
68
  this.dispatcher.stop();
52
69
  this.d.replies.cancelAll();
53
70
  }
71
+ /** A row raised after stop() would be raised again by the next leader, so the message is nak'd instead. */
72
+ live() {
73
+ if (this.stopped)
74
+ throw new dispatcher_1.GatewayStopped();
75
+ }
54
76
  track(work) {
55
77
  const tracked = work.catch((err) => {
56
78
  if (!(err instanceof dispatcher_1.GatewayStopped))
@@ -62,37 +84,48 @@ class Executor {
62
84
  async run(a) {
63
85
  const { lt, state, replies } = this.d;
64
86
  switch (a.kind) {
65
- case 'claim':
66
- return this.check(a, await lt.claim(a.as, a.rowId));
87
+ case 'claim': {
88
+ const result = await lt.claim(a.as, a.rowId);
89
+ this.check(a, result);
90
+ return [outcomeOf('claim', a.rowId, result)];
91
+ }
67
92
  case 'accumulate':
68
93
  return this.accumulate(a);
69
- case 'resolve':
70
- this.check(a, await lt.resolve(a.as, a.rowId, a.payload));
94
+ case 'resolve': {
95
+ const result = await lt.resolve(a.as, a.rowId, a.payload);
96
+ this.check(a, result);
71
97
  state.close(a.rowId);
72
- return;
98
+ return [outcomeOf('resolve', a.rowId, result)];
99
+ }
73
100
  case 'createAlarmRow':
74
- return this.createAlarmRow(a);
101
+ return [{ verb: 'create-row', rowId: await this.createAlarmRow(a), detail: `${a.row.type} ${a.alarmId} at ${a.machineId}` }];
75
102
  case 'createRow': {
103
+ this.live();
76
104
  const { id } = await lt.create(actions_1.CONTROLLER, a.row);
77
105
  this.d.log.info(log_1.GATEWAY_LOG.VIOLATION_ROW, { row: id, type: a.row.type });
78
- return;
106
+ return [{ verb: 'create-row', rowId: id, detail: a.row.type }];
79
107
  }
80
108
  case 'watchOffline':
81
- return this.watchOffline(a.machineId);
109
+ this.watchOffline(a.machineId);
110
+ return [(0, wire_1.plannedAction)(a)];
82
111
  case 'settleReply':
83
- if (!replies.settle({ cmdId: a.cmdId, status: a.status, reason: a.reason }))
84
- await this.lateReply(a);
85
- return;
112
+ if (replies.settle({ cmdId: a.cmdId, status: a.status, reason: a.reason, ...(a.code ? { code: a.code } : {}), ...(a.preparing ? { preparing: true } : {}) }))
113
+ return [(0, wire_1.plannedAction)(a)];
114
+ return [{ verb: 'ack', detail: `late ${a.status} ${a.cmdId}` }, ...await this.lateReply(a)];
86
115
  case 'settleSnapshot':
87
116
  replies.settleSnapshot(a.machineId, new Set(a.jobIds));
88
- return;
117
+ return [(0, wire_1.plannedAction)(a)];
89
118
  case 'bindAddress':
90
119
  await this.d.addresses.bind(a.machineId, a.address);
91
120
  state.bindAddress(a.machineId, a.address);
92
121
  this.d.log.info(log_1.GATEWAY_LOG.ADDRESS_BOUND, { machine: a.machineId, address: a.address, ...(a.by ? { approvedBy: a.by } : {}) });
93
- return;
122
+ return [{ verb: 'ack', detail: `bound ${a.machineId} to ${a.address}` }];
94
123
  case 'refuseBinding':
95
124
  this.d.log.warn(log_1.GATEWAY_LOG.ADDRESS_REFUSED, { machine: a.machineId, address: a.address, reason: a.reason });
125
+ return [(0, wire_1.plannedAction)(a)];
126
+ case 'unrecoverable':
127
+ this.d.log.warn(log_1.GATEWAY_LOG.DISPATCH_UNRECOVERABLE, { machine: a.machineId, jobs: a.jobs });
128
+ return [(0, wire_1.plannedAction)(a)];
96
129
  }
97
130
  }
98
131
  /**
@@ -106,34 +139,52 @@ class Executor {
106
139
  const into = state.rowForDispatch(a.cmdId);
107
140
  const m = into?.toMachine;
108
141
  if (!into || !m)
109
- return;
142
+ return [];
110
143
  const context = { row: into.id, machine: m, cmdId: a.cmdId, reason: a.reason };
111
- if (a.status === protocol_1.REPLY_STATUS.COMPLETED)
112
- return log.info(log_1.GATEWAY_LOG.DISPATCH_READY, context);
144
+ if (a.status === protocol_1.REPLY_STATUS.COMPLETED) {
145
+ log.info(log_1.GATEWAY_LOG.DISPATCH_READY, context);
146
+ return this.readyForArrival(into, m, a.cmdId);
147
+ }
113
148
  if (a.status !== protocol_1.REPLY_STATUS.FAILED)
114
- return;
149
+ return [];
115
150
  const row = into.ended ? onwardRow(state, into, m) : into;
116
151
  log.warn(log_1.GATEWAY_LOG.DISPATCH_FAILED, { ...context, ...(into.ended ? { onward: row?.id ?? null } : {}) });
117
152
  if (!row)
118
- return;
119
- await this.apply((0, plan_shared_1.failHandoff)(state, row, m, {
120
- received: false, errorCode: contracts_1.HANDOFF_ERROR.DISPATCH_FAILED, detail: `${m} could not prepare the job: ${a.reason}`,
153
+ return [];
154
+ return this.apply((0, plan_shared_1.failHandoff)(state, row, m, {
155
+ received: false, errorCode: contracts_1.HANDOFF_ERROR.DISPATCH_FAILED, detail: `${m} could not prepare the job: ${a.reason}`, ...(a.code ? { code: a.code } : {}),
121
156
  }));
122
157
  }
158
+ /** On arrival dispatch, a row that waited for the machine to prepare is received once every job it sent is ready. */
159
+ async readyForArrival(into, m, cmdId) {
160
+ const { lt, state } = this.d;
161
+ if (into.ended || !into.awaitingReady?.has(cmdId))
162
+ return [];
163
+ into.awaitingReady.delete(cmdId);
164
+ if (into.awaitingReady.size)
165
+ return [];
166
+ const units = into.units.map((u) => u.unitId);
167
+ const resolved = await lt.resolve(m, into.id, { received: true, receiver: m, units });
168
+ state.close(into.id);
169
+ return [outcomeOf('resolve', into.id, resolved)];
170
+ }
123
171
  /** Add the item; when the row then holds every key the action waits for, resolve it. */
124
172
  async accumulate(a) {
125
173
  const { lt, state } = this.d;
126
174
  const result = await lt.accumulate(a.as, a.rowId, a.itemKey, a.payload, a.metadata);
127
175
  this.check(a, result);
176
+ const added = { ...outcomeOf('accumulate', a.rowId, result), itemKey: a.itemKey };
128
177
  if (!a.complete || result.outcome === escalations_1.VERB_OUTCOME.INVALID)
129
- return;
178
+ return [added];
130
179
  const held = new Set(result.itemKeys ?? await lt.itemKeys(a.rowId));
131
180
  if (!a.complete.keys.every((k) => held.has(k)))
132
- return;
181
+ return [added];
133
182
  if (a.complete.then)
134
- return this.apply(a.complete.then);
135
- this.check(a, await lt.resolve(a.as, a.rowId, a.complete.payload ?? {}));
183
+ return [added, ...await this.apply(a.complete.then)];
184
+ const resolved = await lt.resolve(a.as, a.rowId, a.complete.payload ?? {});
185
+ this.check(a, resolved);
136
186
  state.close(a.rowId);
187
+ return [added, outcomeOf('resolve', a.rowId, resolved)];
137
188
  }
138
189
  check(a, result) {
139
190
  const rowId = a.rowId;
@@ -148,17 +199,19 @@ class Executor {
148
199
  }
149
200
  }
150
201
  async createAlarmRow(a) {
202
+ this.live();
151
203
  const { id } = await this.d.lt.create(actions_1.CONTROLLER, { ...a.row, role: (0, line_1.operatorRole)(this.d.line) });
152
204
  this.d.log.info(log_1.GATEWAY_LOG.ALARM_ROW, { row: id, machine: a.machineId, alarm: a.alarmId });
153
205
  const track = this.d.state.alarms.get(this.d.state.alarmKey(a.machineId, a.alarmId));
154
206
  const raisedAt = a.row.metadata?.raisedAt;
155
207
  if (track && (!track.raisedAt || !raisedAt || track.raisedAt === raisedAt)) {
156
208
  track.rowId = id;
157
- return;
209
+ return id;
158
210
  }
159
211
  // Cleared at the machine, or raised again, while the row was being created.
160
212
  const note = track ? `${a.machineId} raised ${a.alarmId} again; this one ended` : `cleared at ${a.machineId}`;
161
213
  await this.d.lt.resolve(actions_1.CONTROLLER, id, { decision: contracts_1.DECISION.CLEARED, note });
214
+ return id;
162
215
  }
163
216
  /** Raise a quiet row for each connected machine silent longer than `quietMs`. */
164
217
  checkQuiet(machineIds, quietMs) {
@@ -172,6 +225,7 @@ class Executor {
172
225
  }
173
226
  }
174
227
  async raiseQuiet(machineId, silentMs) {
228
+ this.live();
175
229
  const { id } = await this.d.lt.create(actions_1.CONTROLLER, {
176
230
  type: contracts_1.ROW_TYPE.MACHINE_QUIET, role: (0, line_1.operatorRole)(this.d.line), priority: 2,
177
231
  description: `${machineId} is connected but has sent nothing for ${Math.round(silentMs / 1000)} s`,
@@ -194,11 +248,12 @@ class Executor {
194
248
  link.watching = false;
195
249
  if (link.online || link.rowId)
196
250
  return;
251
+ this.live();
197
252
  const since = new Date(link.since).toISOString();
198
253
  const { id } = await this.d.lt.create(actions_1.CONTROLLER, {
199
254
  type: contracts_1.ROW_TYPE.MACHINE_OFFLINE, role: (0, line_1.operatorRole)(this.d.line), priority: 2,
200
255
  description: `${machineId} has been offline since ${since}`,
201
- metadata: { siteId: this.d.line.siteId, lineId: this.d.line.lineId, machineId, offlineSince: since },
256
+ metadata: { siteId: this.d.line.siteId, lineId: this.d.line.lineId, machineId, offlineSince: since, ...(link.reason ? { reason: link.reason } : {}) },
202
257
  });
203
258
  this.d.log.info(log_1.GATEWAY_LOG.OFFLINE_ROW, { row: id, machine: machineId });
204
259
  if (!link.online)
@@ -3,15 +3,19 @@
3
3
  * reads escalation events (a new handoff row means "dispatch"), reads every
4
4
  * machine message on the line (a receipt means "resolve"), and performs the
5
5
  * verbs a person would, as the machine. Neither side knows about the other.
6
+ * Every message read or sent is recorded on the wire (wire.ts).
6
7
  */
7
8
  import { type HandoffRowAdapter } from '../rows';
8
9
  import { type AddressBook } from './address-book';
9
10
  import type { LineDef } from '../../../lib/machines/line';
10
11
  import { type LineCodec } from '../../../lib/machines/protocol';
11
- import { type EscalationFeed, type MachineBus } from '../../../lib/machines/transport';
12
+ import { type EscalationFeed, type InboundMessage, type MachineBus } from '../../../lib/machines/transport';
13
+ import type { InspectResult } from '../../../types/machines-view';
12
14
  import type { LineEscalations } from './escalations';
13
15
  import { type GatewayLog } from './log';
14
16
  import { GatewayState } from './state';
17
+ import { type WireSink } from './wire';
18
+ import { WireWindow } from './wire-window';
15
19
  export interface GatewaySettings {
16
20
  topicRoot: string;
17
21
  replyTimeoutMs: number;
@@ -27,6 +31,10 @@ export interface GatewaySettings {
27
31
  lifecycle?: boolean;
28
32
  /** With lifecycle notes, progress is noted each time it crosses this many percent; 0 notes none. */
29
33
  progressStep?: number;
34
+ /** Record telemetry messages on the wire too; off unless set. */
35
+ wireTelemetry?: boolean;
36
+ /** How many of the latest wire events the gateway keeps for reading over HTTP; 500 by default. */
37
+ wireWindow?: number;
30
38
  }
31
39
  export interface GatewayDeps {
32
40
  bus: MachineBus;
@@ -41,6 +49,8 @@ export interface GatewayDeps {
41
49
  codec?: LineCodec;
42
50
  /** Where a line that learns addresses keeps them; in memory by default. */
43
51
  addresses?: AddressBook;
52
+ /** Where wire records go; Long Tail's events by default. */
53
+ wire?: WireSink;
44
54
  }
45
55
  export declare class MachineGateway {
46
56
  private readonly deps;
@@ -52,14 +62,24 @@ export declare class MachineGateway {
52
62
  private readonly log;
53
63
  private readonly addresses;
54
64
  private readonly admission;
65
+ private readonly wire;
66
+ /** The line's last wire events, newest first on read. */
67
+ readonly window: WireWindow;
55
68
  private quietTimer?;
56
69
  constructor(deps: GatewayDeps);
57
70
  start(): Promise<void>;
71
+ /**
72
+ * Hand the line over cleanly: nothing new is raised or sent, a message
73
+ * still being handled is nak'd for the next leader if it would make a row,
74
+ * receipts for what was applied go out, then the sessions close.
75
+ */
58
76
  stop(): Promise<void>;
59
77
  /** Machines that report only changes are asked for their full state once the gateway listens. */
60
78
  private askEveryMachine;
61
79
  /** Resolves when no dispatch is in flight (tests). */
62
80
  idle(): Promise<void>;
81
+ /** A dry run of one message on a copy of the state: nothing is applied (inspect.ts). */
82
+ inspect(msg: Pick<InboundMessage, 'topic' | 'payload' | 'retained'>): InspectResult;
63
83
  /**
64
84
  * On taking the line: open handoff and command rows (a dispatch or command
65
85
  * interrupted by a restart is sent again with the same cmdId), the gateway's