@hotmeshio/long-tail 0.27.0 → 0.28.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 (339) hide show
  1. package/README.md +9 -2
  2. package/build/api/settings.d.ts +4 -1
  3. package/build/api/settings.js +7 -1
  4. package/build/index.js +9 -4
  5. package/build/lib/db/config-lock.d.ts +10 -0
  6. package/build/lib/db/config-lock.js +28 -0
  7. package/build/lib/db/schemas/041_machine_lines.sql +26 -0
  8. package/build/lib/events/browser-view.js +8 -2
  9. package/build/lib/events/publish.d.ts +33 -0
  10. package/build/lib/events/publish.js +52 -1
  11. package/build/lib/machines/line.d.ts +4 -1
  12. package/build/lib/machines/line.js +18 -1
  13. package/build/lib/machines/protocol/codec.d.ts +8 -0
  14. package/build/lib/machines/protocol/codec.js +9 -0
  15. package/build/lib/machines/protocol/constants.d.ts +1 -1
  16. package/build/lib/machines/protocol/constants.js +1 -1
  17. package/build/lib/machines/protocol/contract.js +2 -2
  18. package/build/lib/machines/site/mosquitto-conf.d.ts +5 -4
  19. package/build/lib/machines/site/mosquitto-conf.js +31 -16
  20. package/build/lib/machines/site/site-conf.d.ts +9 -2
  21. package/build/lib/machines/site/site-conf.js +27 -8
  22. package/build/lib/machines/transport/callback-feed.d.ts +1 -0
  23. package/build/lib/machines/transport/callback-feed.js +4 -1
  24. package/build/lib/machines/transport/memory.d.ts +2 -0
  25. package/build/lib/machines/transport/memory.js +6 -0
  26. package/build/lib/machines/transport/mqtt-bus.d.ts +2 -0
  27. package/build/lib/machines/transport/mqtt-bus.js +4 -0
  28. package/build/lib/machines/transport/nats-bus.d.ts +1 -0
  29. package/build/lib/machines/transport/nats-bus.js +3 -0
  30. package/build/lib/machines/transport/nats-feed.d.ts +1 -0
  31. package/build/lib/machines/transport/nats-feed.js +4 -1
  32. package/build/lib/machines/transport/pubsub-feed.d.ts +1 -0
  33. package/build/lib/machines/transport/pubsub-feed.js +4 -1
  34. package/build/lib/machines/transport/stream-bus.d.ts +2 -0
  35. package/build/lib/machines/transport/stream-bus.js +5 -1
  36. package/build/modules/machines.d.ts +8 -0
  37. package/build/modules/machines.js +16 -0
  38. package/build/routes/index.js +2 -0
  39. package/build/routes/machines.d.ts +2 -0
  40. package/build/routes/machines.js +220 -0
  41. package/build/services/machines/commands.d.ts +5 -5
  42. package/build/services/machines/commands.js +3 -2
  43. package/build/services/machines/config.d.ts +2 -1
  44. package/build/services/machines/config.js +1 -1
  45. package/build/services/machines/contracts.d.ts +10 -0
  46. package/build/services/machines/gateway/actions.d.ts +1 -0
  47. package/build/services/machines/gateway/admission.d.ts +15 -3
  48. package/build/services/machines/gateway/admission.js +29 -14
  49. package/build/services/machines/gateway/dispatcher.d.ts +3 -0
  50. package/build/services/machines/gateway/dispatcher.js +12 -4
  51. package/build/services/machines/gateway/executor.d.ts +11 -2
  52. package/build/services/machines/gateway/executor.js +68 -29
  53. package/build/services/machines/gateway/gateway.d.ts +16 -1
  54. package/build/services/machines/gateway/gateway.js +55 -23
  55. package/build/services/machines/gateway/index.d.ts +3 -0
  56. package/build/services/machines/gateway/index.js +3 -0
  57. package/build/services/machines/gateway/inspect.d.ts +17 -0
  58. package/build/services/machines/gateway/inspect.js +68 -0
  59. package/build/services/machines/gateway/log.d.ts +8 -0
  60. package/build/services/machines/gateway/log.js +18 -0
  61. package/build/services/machines/gateway/pacing.js +1 -0
  62. package/build/services/machines/gateway/plan-escalation.js +8 -3
  63. package/build/services/machines/gateway/plan-machine.js +16 -6
  64. package/build/services/machines/gateway/project.d.ts +9 -0
  65. package/build/services/machines/gateway/project.js +55 -0
  66. package/build/services/machines/gateway/receipts.d.ts +3 -0
  67. package/build/services/machines/gateway/receipts.js +3 -1
  68. package/build/services/machines/gateway/reconcile.js +3 -3
  69. package/build/services/machines/gateway/registration.js +1 -1
  70. package/build/services/machines/gateway/reply-waiter.d.ts +6 -3
  71. package/build/services/machines/gateway/reply-waiter.js +37 -16
  72. package/build/services/machines/gateway/state.d.ts +29 -3
  73. package/build/services/machines/gateway/state.js +61 -7
  74. package/build/services/machines/gateway/wire.d.ts +58 -0
  75. package/build/services/machines/gateway/wire.js +171 -0
  76. package/build/services/machines/index.d.ts +3 -0
  77. package/build/services/machines/index.js +2 -0
  78. package/build/services/machines/line-index.d.ts +16 -0
  79. package/build/services/machines/line-index.js +39 -0
  80. package/build/services/machines/registry-sql.d.ts +31 -0
  81. package/build/services/machines/registry-sql.js +110 -0
  82. package/build/services/machines/registry-sync.d.ts +31 -0
  83. package/build/services/machines/registry-sync.js +81 -0
  84. package/build/services/machines/registry.d.ts +77 -0
  85. package/build/services/machines/registry.js +158 -0
  86. package/build/services/machines/rows.js +10 -1
  87. package/build/services/machines/surface.d.ts +45 -5
  88. package/build/services/machines/surface.js +95 -15
  89. package/build/start/apply-report.d.ts +1 -1
  90. package/build/start/apply-report.js +3 -25
  91. package/build/start/index.js +16 -4
  92. package/build/system/index.js +13 -0
  93. package/build/system/mcp-servers/admin/schemas.d.ts +22 -22
  94. package/build/system/mcp-servers/human-queue-schemas.d.ts +7 -7
  95. package/build/system/mcp-servers/machines-schemas.d.ts +35 -0
  96. package/build/system/mcp-servers/machines-schemas.js +35 -0
  97. package/build/system/mcp-servers/machines.d.ts +20 -0
  98. package/build/system/mcp-servers/machines.js +154 -0
  99. package/build/system/seed/tool-manifests-machines.d.ts +2 -0
  100. package/build/system/seed/tool-manifests-machines.js +88 -0
  101. package/build/tsconfig.tsbuildinfo +1 -1
  102. package/build/types/events.d.ts +6 -1
  103. package/build/types/index.d.ts +1 -0
  104. package/build/types/machines-view.d.ts +159 -0
  105. package/build/types/machines-view.js +7 -0
  106. package/build/types/machines.d.ts +4 -0
  107. package/dashboard/dist/assets/{AdminDashboard-DlItqxFS.js → AdminDashboard-Bm7VG65H.js} +2 -2
  108. package/dashboard/dist/assets/{AdminDashboard-DlItqxFS.js.map → AdminDashboard-Bm7VG65H.js.map} +1 -1
  109. package/dashboard/dist/assets/{AgentConfigPage-BUmT4a7n.js → AgentConfigPage-aJF7Sdbc.js} +6 -6
  110. package/dashboard/dist/assets/{AgentConfigPage-BUmT4a7n.js.map → AgentConfigPage-aJF7Sdbc.js.map} +1 -1
  111. package/dashboard/dist/assets/{AgentDetailPage-Cww8rlBi.js → AgentDetailPage-GwwghhxT.js} +3 -3
  112. package/dashboard/dist/assets/{AgentDetailPage-Cww8rlBi.js.map → AgentDetailPage-GwwghhxT.js.map} +1 -1
  113. package/dashboard/dist/assets/AgentsPage-DVvCzZyg.js +2 -0
  114. package/dashboard/dist/assets/{AgentsPage-C9UuUKhr.js.map → AgentsPage-DVvCzZyg.js.map} +1 -1
  115. package/dashboard/dist/assets/AvailableEscalationsPage-Cxmcji_K.js +2 -0
  116. package/dashboard/dist/assets/{AvailableEscalationsPage-DrvfXz70.js.map → AvailableEscalationsPage-Cxmcji_K.js.map} +1 -1
  117. package/dashboard/dist/assets/{BotPicker-CDq9XRMp.js → BotPicker-CofRxk4L.js} +2 -2
  118. package/dashboard/dist/assets/{BotPicker-CDq9XRMp.js.map → BotPicker-CofRxk4L.js.map} +1 -1
  119. package/dashboard/dist/assets/{BulkAssignModal-jsvqtrEA.js → BulkAssignModal-BARWuz4L.js} +2 -2
  120. package/dashboard/dist/assets/{BulkAssignModal-jsvqtrEA.js.map → BulkAssignModal-BARWuz4L.js.map} +1 -1
  121. package/dashboard/dist/assets/{CapabilitiesPage-CSCrI6B1.js → CapabilitiesPage-BJAWVNEx.js} +2 -2
  122. package/dashboard/dist/assets/{CapabilitiesPage-CSCrI6B1.js.map → CapabilitiesPage-BJAWVNEx.js.map} +1 -1
  123. package/dashboard/dist/assets/{CollapsibleSection-uD9mn-CQ.js → CollapsibleSection-CtgoaG75.js} +2 -2
  124. package/dashboard/dist/assets/{CollapsibleSection-uD9mn-CQ.js.map → CollapsibleSection-CtgoaG75.js.map} +1 -1
  125. package/dashboard/dist/assets/{ConfirmDeleteModal-BRmx2hA4.js → ConfirmDeleteModal-BYXXBWs6.js} +2 -2
  126. package/dashboard/dist/assets/{ConfirmDeleteModal-BRmx2hA4.js.map → ConfirmDeleteModal-BYXXBWs6.js.map} +1 -1
  127. package/dashboard/dist/assets/{ConnectedAppsPage-DlMzE5a-.js → ConnectedAppsPage-D0JkzWa7.js} +2 -2
  128. package/dashboard/dist/assets/{ConnectedAppsPage-DlMzE5a-.js.map → ConnectedAppsPage-D0JkzWa7.js.map} +1 -1
  129. package/dashboard/dist/assets/{CountdownTimer-sRuM4eM5.js → CountdownTimer-BcFxdZYN.js} +2 -2
  130. package/dashboard/dist/assets/{CountdownTimer-sRuM4eM5.js.map → CountdownTimer-BcFxdZYN.js.map} +1 -1
  131. package/dashboard/dist/assets/{CredentialsPage-bLYydwqa.js → CredentialsPage-DPSY20rV.js} +2 -2
  132. package/dashboard/dist/assets/{CredentialsPage-bLYydwqa.js.map → CredentialsPage-DPSY20rV.js.map} +1 -1
  133. package/dashboard/dist/assets/{CronLabel-D_ATDL2N.js → CronLabel-Dg_Oew_Y.js} +2 -2
  134. package/dashboard/dist/assets/{CronLabel-D_ATDL2N.js.map → CronLabel-Dg_Oew_Y.js.map} +1 -1
  135. package/dashboard/dist/assets/{DropZone-u1JGfR9G.js → DropZone-Cl_Flb16.js} +2 -2
  136. package/dashboard/dist/assets/{DropZone-u1JGfR9G.js.map → DropZone-Cl_Flb16.js.map} +1 -1
  137. package/dashboard/dist/assets/{ElapsedCell-groSMfqB.js → ElapsedCell-Dm3G5fK2.js} +2 -2
  138. package/dashboard/dist/assets/{ElapsedCell-groSMfqB.js.map → ElapsedCell-Dm3G5fK2.js.map} +1 -1
  139. package/dashboard/dist/assets/{EntityTimelinePanel-D-F3_A9m.js → EntityTimelinePanel-CrEEP04e.js} +2 -2
  140. package/dashboard/dist/assets/{EntityTimelinePanel-D-F3_A9m.js.map → EntityTimelinePanel-CrEEP04e.js.map} +1 -1
  141. package/dashboard/dist/assets/{EscalationListSchemaPage-Bad6Jrmr.js → EscalationListSchemaPage-wOInXcjs.js} +3 -3
  142. package/dashboard/dist/assets/{EscalationListSchemaPage-Bad6Jrmr.js.map → EscalationListSchemaPage-wOInXcjs.js.map} +1 -1
  143. package/dashboard/dist/assets/{EscalationSchemaPage-BKi_npI9.js → EscalationSchemaPage-CrIj_g9d.js} +3 -3
  144. package/dashboard/dist/assets/{EscalationSchemaPage-BKi_npI9.js.map → EscalationSchemaPage-CrIj_g9d.js.map} +1 -1
  145. package/dashboard/dist/assets/{EscalationTimeline-DQUUm3b1.js → EscalationTimeline-CeAsl5IT.js} +2 -2
  146. package/dashboard/dist/assets/{EscalationTimeline-DQUUm3b1.js.map → EscalationTimeline-CeAsl5IT.js.map} +1 -1
  147. package/dashboard/dist/assets/{EscalationTitleSelect-3mhXh77a.js → EscalationTitleSelect-D8qpCYiy.js} +2 -2
  148. package/dashboard/dist/assets/{EscalationTitleSelect-3mhXh77a.js.map → EscalationTitleSelect-D8qpCYiy.js.map} +1 -1
  149. package/dashboard/dist/assets/{EscalationsOverview-Qaov-uML.js → EscalationsOverview-CvaqVPsr.js} +2 -2
  150. package/dashboard/dist/assets/{EscalationsOverview-Qaov-uML.js.map → EscalationsOverview-CvaqVPsr.js.map} +1 -1
  151. package/dashboard/dist/assets/{EventTable-V4RF_n58.js → EventTable-Be0JuEl6.js} +2 -2
  152. package/dashboard/dist/assets/{EventTable-V4RF_n58.js.map → EventTable-Be0JuEl6.js.map} +1 -1
  153. package/dashboard/dist/assets/FilterBar-BVyAjIgv.js +2 -0
  154. package/dashboard/dist/assets/FilterBar-BVyAjIgv.js.map +1 -0
  155. package/dashboard/dist/assets/{GraphInvokePage-Djslhf96.js → GraphInvokePage-D_QigJeD.js} +2 -2
  156. package/dashboard/dist/assets/{GraphInvokePage-Djslhf96.js.map → GraphInvokePage-D_QigJeD.js.map} +1 -1
  157. package/dashboard/dist/assets/{HomePage-EjcNxlKx.js → HomePage-C1haeuNy.js} +2 -2
  158. package/dashboard/dist/assets/{HomePage-EjcNxlKx.js.map → HomePage-C1haeuNy.js.map} +1 -1
  159. package/dashboard/dist/assets/LinePage-CWD5pv1g.js +5 -0
  160. package/dashboard/dist/assets/LinePage-CWD5pv1g.js.map +1 -0
  161. package/dashboard/dist/assets/LinesPage-NqChsKcO.js +3 -0
  162. package/dashboard/dist/assets/LinesPage-NqChsKcO.js.map +1 -0
  163. package/dashboard/dist/assets/{ListToolbar-RrEAePOX.js → ListToolbar-BZCNrTh6.js} +2 -2
  164. package/dashboard/dist/assets/{ListToolbar-RrEAePOX.js.map → ListToolbar-BZCNrTh6.js.map} +1 -1
  165. package/dashboard/dist/assets/{McpOverview-8gqiL3Vj.js → McpOverview-yJTYnh1z.js} +2 -2
  166. package/dashboard/dist/assets/{McpOverview-8gqiL3Vj.js.map → McpOverview-yJTYnh1z.js.map} +1 -1
  167. package/dashboard/dist/assets/{McpQueryDetailPage-COyn6Ak5.js → McpQueryDetailPage-ChuLpJ4u.js} +3 -3
  168. package/dashboard/dist/assets/{McpQueryDetailPage-COyn6Ak5.js.map → McpQueryDetailPage-ChuLpJ4u.js.map} +1 -1
  169. package/dashboard/dist/assets/{McpQueryPage-Dj6Qj72w.js → McpQueryPage-9S-v9soF.js} +2 -2
  170. package/dashboard/dist/assets/{McpQueryPage-Dj6Qj72w.js.map → McpQueryPage-9S-v9soF.js.map} +1 -1
  171. package/dashboard/dist/assets/McpRunDetailPage-BhrcfxD5.js +2 -0
  172. package/dashboard/dist/assets/{McpRunDetailPage-80fQn9iX.js.map → McpRunDetailPage-BhrcfxD5.js.map} +1 -1
  173. package/dashboard/dist/assets/{McpRunsPage-DaSsI-EM.js → McpRunsPage-C5_i8_Zx.js} +2 -2
  174. package/dashboard/dist/assets/{McpRunsPage-DaSsI-EM.js.map → McpRunsPage-C5_i8_Zx.js.map} +1 -1
  175. package/dashboard/dist/assets/{NamespacePill-C5epAgq6.js → NamespacePill-OTZD2hzt.js} +2 -2
  176. package/dashboard/dist/assets/{NamespacePill-C5epAgq6.js.map → NamespacePill-OTZD2hzt.js.map} +1 -1
  177. package/dashboard/dist/assets/{OperationsPage-BSu1o2gB.js → OperationsPage-C03CeU5P.js} +2 -2
  178. package/dashboard/dist/assets/{OperationsPage-BSu1o2gB.js.map → OperationsPage-C03CeU5P.js.map} +1 -1
  179. package/dashboard/dist/assets/{OperatorDashboard-HFI4WGIV.js → OperatorDashboard-BzC134Jt.js} +2 -2
  180. package/dashboard/dist/assets/{OperatorDashboard-HFI4WGIV.js.map → OperatorDashboard-BzC134Jt.js.map} +1 -1
  181. package/dashboard/dist/assets/{PageHeader-BSWIspNB.js → PageHeader-Hx8APPwE.js} +2 -2
  182. package/dashboard/dist/assets/{PageHeader-BSWIspNB.js.map → PageHeader-Hx8APPwE.js.map} +1 -1
  183. package/dashboard/dist/assets/{PageHeaderWithStats-DDjopQ-k.js → PageHeaderWithStats-BEQYYBJv.js} +2 -2
  184. package/dashboard/dist/assets/{PageHeaderWithStats-DDjopQ-k.js.map → PageHeaderWithStats-BEQYYBJv.js.map} +1 -1
  185. package/dashboard/dist/assets/{PersonaDetailPage-D0qlBuGi.js → PersonaDetailPage-D0mY9L6j.js} +2 -2
  186. package/dashboard/dist/assets/{PersonaDetailPage-D0qlBuGi.js.map → PersonaDetailPage-D0mY9L6j.js.map} +1 -1
  187. package/dashboard/dist/assets/{PersonasPage-BJClu-5H.js → PersonasPage-FFlm5Eug.js} +2 -2
  188. package/dashboard/dist/assets/{PersonasPage-BJClu-5H.js.map → PersonasPage-FFlm5Eug.js.map} +1 -1
  189. package/dashboard/dist/assets/{PortalPage-CucNZn_w.js → PortalPage-Cpc25uO-.js} +2 -2
  190. package/dashboard/dist/assets/{PortalPage-CucNZn_w.js.map → PortalPage-Cpc25uO-.js.map} +1 -1
  191. package/dashboard/dist/assets/{ProcessDetailPage-B9wMw0RV.js → ProcessDetailPage-Di2J7KwY.js} +2 -2
  192. package/dashboard/dist/assets/{ProcessDetailPage-B9wMw0RV.js.map → ProcessDetailPage-Di2J7KwY.js.map} +1 -1
  193. package/dashboard/dist/assets/{ProcessesListPage-B6k4RpmR.js → ProcessesListPage-BEXwU3Z0.js} +2 -2
  194. package/dashboard/dist/assets/{ProcessesListPage-B6k4RpmR.js.map → ProcessesListPage-BEXwU3Z0.js.map} +1 -1
  195. package/dashboard/dist/assets/{ResolverForm-ZVufJ4G-.js → ResolverForm-2ks-3jXC.js} +6 -6
  196. package/dashboard/dist/assets/{ResolverForm-ZVufJ4G-.js.map → ResolverForm-2ks-3jXC.js.map} +1 -1
  197. package/dashboard/dist/assets/{RoleDetailPage-CTbq0mz4.js → RoleDetailPage-DqoOk0xc.js} +3 -3
  198. package/dashboard/dist/assets/{RoleDetailPage-CTbq0mz4.js.map → RoleDetailPage-DqoOk0xc.js.map} +1 -1
  199. package/dashboard/dist/assets/{RolePill-CoETDpjF.js → RolePill-R5_ctGFy.js} +2 -2
  200. package/dashboard/dist/assets/{RolePill-CoETDpjF.js.map → RolePill-R5_ctGFy.js.map} +1 -1
  201. package/dashboard/dist/assets/{RolesPage-DBKxeam4.js → RolesPage-CPmo8Srr.js} +2 -2
  202. package/dashboard/dist/assets/{RolesPage-DBKxeam4.js.map → RolesPage-CPmo8Srr.js.map} +1 -1
  203. package/dashboard/dist/assets/{RosterWidget-BkLAwEYB.js → RosterWidget-D2yovCKw.js} +2 -2
  204. package/dashboard/dist/assets/{RosterWidget-BkLAwEYB.js.map → RosterWidget-D2yovCKw.js.map} +1 -1
  205. package/dashboard/dist/assets/{RunAsSelector-D2DC4iDf.js → RunAsSelector-CMv96On6.js} +2 -2
  206. package/dashboard/dist/assets/{RunAsSelector-D2DC4iDf.js.map → RunAsSelector-CMv96On6.js.map} +1 -1
  207. package/dashboard/dist/assets/{ScanCodesPage-BlKleaT0.js → ScanCodesPage-CA6cTT-M.js} +2 -2
  208. package/dashboard/dist/assets/{ScanCodesPage-BlKleaT0.js.map → ScanCodesPage-CA6cTT-M.js.map} +1 -1
  209. package/dashboard/dist/assets/{ScanSchemeDetailPage-CTW6gofi.js → ScanSchemeDetailPage-DnctN5-H.js} +2 -2
  210. package/dashboard/dist/assets/{ScanSchemeDetailPage-CTW6gofi.js.map → ScanSchemeDetailPage-DnctN5-H.js.map} +1 -1
  211. package/dashboard/dist/assets/{ScanStationPage-DPRjSPyT.js → ScanStationPage-Bk8RwkKL.js} +2 -2
  212. package/dashboard/dist/assets/{ScanStationPage-DPRjSPyT.js.map → ScanStationPage-Bk8RwkKL.js.map} +1 -1
  213. package/dashboard/dist/assets/{ScopeBadge-CGsTtqFr.js → ScopeBadge-BXZ084nD.js} +2 -2
  214. package/dashboard/dist/assets/{ScopeBadge-CGsTtqFr.js.map → ScopeBadge-BXZ084nD.js.map} +1 -1
  215. package/dashboard/dist/assets/{StickyPagination-CkmX3-Gu.js → StickyPagination-B0FSuUgs.js} +2 -2
  216. package/dashboard/dist/assets/{StickyPagination-CkmX3-Gu.js.map → StickyPagination-B0FSuUgs.js.map} +1 -1
  217. package/dashboard/dist/assets/{StreamMessageDetail-Xm_n510s.js → StreamMessageDetail-BwZEvMpP.js} +2 -2
  218. package/dashboard/dist/assets/{StreamMessageDetail-Xm_n510s.js.map → StreamMessageDetail-BwZEvMpP.js.map} +1 -1
  219. package/dashboard/dist/assets/{SwimlaneTimeline-De48aJan.js → SwimlaneTimeline-BDVQEaMw.js} +2 -2
  220. package/dashboard/dist/assets/{SwimlaneTimeline-De48aJan.js.map → SwimlaneTimeline-BDVQEaMw.js.map} +1 -1
  221. package/dashboard/dist/assets/{TagInput-S7UuVT_M.js → TagInput-DjPUDp2M.js} +2 -2
  222. package/dashboard/dist/assets/{TagInput-S7UuVT_M.js.map → TagInput-DjPUDp2M.js.map} +1 -1
  223. package/dashboard/dist/assets/{TaskDetailPage-HycMx3O9.js → TaskDetailPage-BOlv3iGB.js} +2 -2
  224. package/dashboard/dist/assets/{TaskDetailPage-HycMx3O9.js.map → TaskDetailPage-BOlv3iGB.js.map} +1 -1
  225. package/dashboard/dist/assets/{TaskQueuePill-BlHNpYiZ.js → TaskQueuePill-D-4Ynf3K.js} +2 -2
  226. package/dashboard/dist/assets/{TaskQueuePill-BlHNpYiZ.js.map → TaskQueuePill-D-4Ynf3K.js.map} +1 -1
  227. package/dashboard/dist/assets/{TasksListPage-OIcFFp1C.js → TasksListPage-e2teY0bD.js} +2 -2
  228. package/dashboard/dist/assets/{TasksListPage-OIcFFp1C.js.map → TasksListPage-e2teY0bD.js.map} +1 -1
  229. package/dashboard/dist/assets/{TimeAgo-OTC_55oZ.js → TimeAgo-Cvkpf_b3.js} +2 -2
  230. package/dashboard/dist/assets/{TimeAgo-OTC_55oZ.js.map → TimeAgo-Cvkpf_b3.js.map} +1 -1
  231. package/dashboard/dist/assets/{TimestampCell-CAwIj_AI.js → TimestampCell-B3btAV0N.js} +2 -2
  232. package/dashboard/dist/assets/{TimestampCell-CAwIj_AI.js.map → TimestampCell-B3btAV0N.js.map} +1 -1
  233. package/dashboard/dist/assets/{ToolPill-D40uLM_v.js → ToolPill-GsKQ80CO.js} +2 -2
  234. package/dashboard/dist/assets/{ToolPill-D40uLM_v.js.map → ToolPill-GsKQ80CO.js.map} +1 -1
  235. package/dashboard/dist/assets/{ToolTestPanel-8Vf6pfw4.js → ToolTestPanel-B03nebR7.js} +2 -2
  236. package/dashboard/dist/assets/{ToolTestPanel-8Vf6pfw4.js.map → ToolTestPanel-B03nebR7.js.map} +1 -1
  237. package/dashboard/dist/assets/{TopicDetailPage-iZW8rK9L.js → TopicDetailPage-DBRWne3O.js} +3 -3
  238. package/dashboard/dist/assets/{TopicDetailPage-iZW8rK9L.js.map → TopicDetailPage-DBRWne3O.js.map} +1 -1
  239. package/dashboard/dist/assets/{TopicsPage-CqiEcj-W.js → TopicsPage-CVe2M9HD.js} +2 -2
  240. package/dashboard/dist/assets/{TopicsPage-CqiEcj-W.js.map → TopicsPage-CVe2M9HD.js.map} +1 -1
  241. package/dashboard/dist/assets/{UserName-DQFjuoib.js → UserName-B_q_qp6V.js} +2 -2
  242. package/dashboard/dist/assets/{UserName-DQFjuoib.js.map → UserName-B_q_qp6V.js.map} +1 -1
  243. package/dashboard/dist/assets/WorkflowExecutionPage-Bh_dr9tM.js +2 -0
  244. package/dashboard/dist/assets/{WorkflowExecutionPage-Di08wCbs.js.map → WorkflowExecutionPage-Bh_dr9tM.js.map} +1 -1
  245. package/dashboard/dist/assets/{WorkflowPill-DJLcK_CM.js → WorkflowPill-D7244fKp.js} +2 -2
  246. package/dashboard/dist/assets/{WorkflowPill-DJLcK_CM.js.map → WorkflowPill-D7244fKp.js.map} +1 -1
  247. package/dashboard/dist/assets/{WorkflowsDashboard-Bb8HlrTJ.js → WorkflowsDashboard-DA6Mj7qH.js} +2 -2
  248. package/dashboard/dist/assets/{WorkflowsDashboard-Bb8HlrTJ.js.map → WorkflowsDashboard-DA6Mj7qH.js.map} +1 -1
  249. package/dashboard/dist/assets/{WorkflowsOverview-Dta1kurk.js → WorkflowsOverview-B1kBLj-a.js} +2 -2
  250. package/dashboard/dist/assets/{WorkflowsOverview-Dta1kurk.js.map → WorkflowsOverview-B1kBLj-a.js.map} +1 -1
  251. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CfAajg68.js → YamlWorkflowDetailPage-6GJM8QIX.js} +8 -8
  252. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CfAajg68.js.map → YamlWorkflowDetailPage-6GJM8QIX.js.map} +1 -1
  253. package/dashboard/dist/assets/{YamlWorkflowsPage-CQFUzT4t.js → YamlWorkflowsPage-Bu811C7f.js} +2 -2
  254. package/dashboard/dist/assets/{YamlWorkflowsPage-CQFUzT4t.js.map → YamlWorkflowsPage-Bu811C7f.js.map} +1 -1
  255. package/dashboard/dist/assets/{agents-PuftRTB2.js → agents-MPk_GnYz.js} +2 -2
  256. package/dashboard/dist/assets/{agents-PuftRTB2.js.map → agents-MPk_GnYz.js.map} +1 -1
  257. package/dashboard/dist/assets/{bots-BmEiPAWY.js → bots-2RihE2Tc.js} +2 -2
  258. package/dashboard/dist/assets/{bots-BmEiPAWY.js.map → bots-2RihE2Tc.js.map} +1 -1
  259. package/dashboard/dist/assets/{capabilities-CRii4Soa.js → capabilities-CC4iwJ1P.js} +2 -2
  260. package/dashboard/dist/assets/{capabilities-CRii4Soa.js.map → capabilities-CC4iwJ1P.js.map} +1 -1
  261. package/dashboard/dist/assets/{controlplane-DO_czaYo.js → controlplane-Bmkic8BH.js} +2 -2
  262. package/dashboard/dist/assets/{controlplane-DO_czaYo.js.map → controlplane-Bmkic8BH.js.map} +1 -1
  263. package/dashboard/dist/assets/{escalation-columns-CzCquCPh.js → escalation-columns-B0lhUUrQ.js} +2 -2
  264. package/dashboard/dist/assets/{escalation-columns-CzCquCPh.js.map → escalation-columns-B0lhUUrQ.js.map} +1 -1
  265. package/dashboard/dist/assets/{escalation-items-Cy0ZgJqV.js → escalation-items-7WFpPo46.js} +2 -2
  266. package/dashboard/dist/assets/{escalation-items-Cy0ZgJqV.js.map → escalation-items-7WFpPo46.js.map} +1 -1
  267. package/dashboard/dist/assets/index-B9uv-euR.css +1 -0
  268. package/dashboard/dist/assets/{index-DhSCCpqM.js → index-B_XV1rwu.js} +2 -2
  269. package/dashboard/dist/assets/{index-DhSCCpqM.js.map → index-B_XV1rwu.js.map} +1 -1
  270. package/dashboard/dist/assets/{index-Cx8xb-oU.js → index-C2CLfGwL.js} +2 -2
  271. package/dashboard/dist/assets/{index-Cx8xb-oU.js.map → index-C2CLfGwL.js.map} +1 -1
  272. package/dashboard/dist/assets/{index-Cga5IW3D.js → index-C3AeFihz.js} +2 -2
  273. package/dashboard/dist/assets/{index-Cga5IW3D.js.map → index-C3AeFihz.js.map} +1 -1
  274. package/dashboard/dist/assets/{index-DiaRlFYI.js → index-CBri8fYM.js} +2 -2
  275. package/dashboard/dist/assets/{index-DiaRlFYI.js.map → index-CBri8fYM.js.map} +1 -1
  276. package/dashboard/dist/assets/{index-CL_1VpGb.js → index-CRWsB7ZC.js} +2 -2
  277. package/dashboard/dist/assets/{index-CL_1VpGb.js.map → index-CRWsB7ZC.js.map} +1 -1
  278. package/dashboard/dist/assets/{index-XntldBd0.js → index-CTOv3G7a.js} +2 -2
  279. package/dashboard/dist/assets/{index-XntldBd0.js.map → index-CTOv3G7a.js.map} +1 -1
  280. package/dashboard/dist/assets/{index-CfP2nKRc.js → index-CcArGkzI.js} +3 -3
  281. package/dashboard/dist/assets/{index-CfP2nKRc.js.map → index-CcArGkzI.js.map} +1 -1
  282. package/dashboard/dist/assets/{index-Dz6R8-Dw.js → index-CkMHS-hG.js} +25 -25
  283. package/dashboard/dist/assets/index-CkMHS-hG.js.map +1 -0
  284. package/dashboard/dist/assets/index-CmsmwCyv.js +2 -0
  285. package/dashboard/dist/assets/{index-4YaDUcKd.js.map → index-CmsmwCyv.js.map} +1 -1
  286. package/dashboard/dist/assets/{index-2SM2_onB.js → index-CvJsvqIc.js} +2 -2
  287. package/dashboard/dist/assets/{index-2SM2_onB.js.map → index-CvJsvqIc.js.map} +1 -1
  288. package/dashboard/dist/assets/{index-Rwqrflm-.js → index-D-ilRyfy.js} +2 -2
  289. package/dashboard/dist/assets/{index-Rwqrflm-.js.map → index-D-ilRyfy.js.map} +1 -1
  290. package/dashboard/dist/assets/{index-CZ7A3AcD.js → index-DSUtfDXx.js} +2 -2
  291. package/dashboard/dist/assets/{index-CZ7A3AcD.js.map → index-DSUtfDXx.js.map} +1 -1
  292. package/dashboard/dist/assets/{index-jL2K6us4.js → index-Da6ycKyf.js} +2 -2
  293. package/dashboard/dist/assets/{index-jL2K6us4.js.map → index-Da6ycKyf.js.map} +1 -1
  294. package/dashboard/dist/assets/{knowledge-CeUqGPuo.js → knowledge-Bpbg20DC.js} +2 -2
  295. package/dashboard/dist/assets/{knowledge-CeUqGPuo.js.map → knowledge-Bpbg20DC.js.map} +1 -1
  296. package/dashboard/dist/assets/machines-BqOZZU-3.js +2 -0
  297. package/dashboard/dist/assets/machines-BqOZZU-3.js.map +1 -0
  298. package/dashboard/dist/assets/{mcp-Cx96NTeD.js → mcp-CmcUXYce.js} +2 -2
  299. package/dashboard/dist/assets/{mcp-Cx96NTeD.js.map → mcp-CmcUXYce.js.map} +1 -1
  300. package/dashboard/dist/assets/{mcp-query-XAzWl0gm.js → mcp-query-C8buQxN9.js} +2 -2
  301. package/dashboard/dist/assets/{mcp-query-XAzWl0gm.js.map → mcp-query-C8buQxN9.js.map} +1 -1
  302. package/dashboard/dist/assets/{personas--4kjwyOw.js → personas-C2n5oDmY.js} +2 -2
  303. package/dashboard/dist/assets/{personas--4kjwyOw.js.map → personas-C2n5oDmY.js.map} +1 -1
  304. package/dashboard/dist/assets/{pipelines-PgkwvG7f.js → pipelines-RKpSkFz7.js} +2 -2
  305. package/dashboard/dist/assets/{pipelines-PgkwvG7f.js.map → pipelines-RKpSkFz7.js.map} +1 -1
  306. package/dashboard/dist/assets/{tasks-CcYxdBa3.js → tasks-Dab4hExW.js} +2 -2
  307. package/dashboard/dist/assets/{tasks-CcYxdBa3.js.map → tasks-Dab4hExW.js.map} +1 -1
  308. package/dashboard/dist/assets/{topics-_lik7cNY.js → topics-FTMNP7r3.js} +2 -2
  309. package/dashboard/dist/assets/{topics-_lik7cNY.js.map → topics-FTMNP7r3.js.map} +1 -1
  310. package/dashboard/dist/assets/{useDebouncedValue-Bm_AoxVx.js → useDebouncedValue-B_1u1YIk.js} +2 -2
  311. package/dashboard/dist/assets/{useDebouncedValue-Bm_AoxVx.js.map → useDebouncedValue-B_1u1YIk.js.map} +1 -1
  312. package/dashboard/dist/assets/{useNamespace-DgXXKdx5.js → useNamespace-HUeAI7Qb.js} +2 -2
  313. package/dashboard/dist/assets/{useNamespace-DgXXKdx5.js.map → useNamespace-HUeAI7Qb.js.map} +1 -1
  314. package/dashboard/dist/assets/{useYamlActivityEvents-Dj2qtGSd.js → useYamlActivityEvents-Cax54qHH.js} +2 -2
  315. package/dashboard/dist/assets/{useYamlActivityEvents-Dj2qtGSd.js.map → useYamlActivityEvents-Cax54qHH.js.map} +1 -1
  316. package/dashboard/dist/assets/{validate-FlXCBBT6.js → validate-DxOaV7QS.js} +2 -2
  317. package/dashboard/dist/assets/{validate-FlXCBBT6.js.map → validate-DxOaV7QS.js.map} +1 -1
  318. package/dashboard/dist/assets/{vendor-icons-DUYcKTjP.js → vendor-icons-fxBvvHBi.js} +187 -182
  319. package/dashboard/dist/assets/vendor-icons-fxBvvHBi.js.map +1 -0
  320. package/dashboard/dist/assets/{yaml-workflows-B0_JxRYQ.js → yaml-workflows-BgY1XHJx.js} +2 -2
  321. package/dashboard/dist/assets/{yaml-workflows-B0_JxRYQ.js.map → yaml-workflows-BgY1XHJx.js.map} +1 -1
  322. package/dashboard/dist/index.html +3 -3
  323. package/docs/architecture.md +1 -0
  324. package/docs/code-owned-configuration.md +6 -0
  325. package/docs/dashboard.md +1 -0
  326. package/docs/events.md +34 -1
  327. package/docs/machines.md +93 -16
  328. package/docs/mcp.md +19 -0
  329. package/package.json +1 -1
  330. package/dashboard/dist/assets/AgentsPage-C9UuUKhr.js +0 -2
  331. package/dashboard/dist/assets/AvailableEscalationsPage-DrvfXz70.js +0 -2
  332. package/dashboard/dist/assets/FilterBar-BygWrnB1.js +0 -2
  333. package/dashboard/dist/assets/FilterBar-BygWrnB1.js.map +0 -1
  334. package/dashboard/dist/assets/McpRunDetailPage-80fQn9iX.js +0 -2
  335. package/dashboard/dist/assets/WorkflowExecutionPage-Di08wCbs.js +0 -2
  336. package/dashboard/dist/assets/index-4YaDUcKd.js +0 -2
  337. package/dashboard/dist/assets/index-CnU7Jjz3.css +0 -1
  338. package/dashboard/dist/assets/index-Dz6R8-Dw.js.map +0 -1
  339. package/dashboard/dist/assets/vendor-icons-DUYcKTjP.js.map +0 -1
@@ -2,7 +2,8 @@
2
2
  /**
3
3
  * Command replies by cmdId, and machine snapshots by machine. A wait registers
4
4
  * before the command is published and resolves with the reply, or null at the
5
- * deadline.
5
+ * deadline. Several waits on one key are all settled by the next answer, so
6
+ * two dispatches asking one machine what it holds share its next snapshot.
6
7
  */
7
8
  Object.defineProperty(exports, "__esModule", { value: true });
8
9
  exports.ReplyWaiter = void 0;
@@ -11,31 +12,51 @@ class Waits {
11
12
  this.waiting = new Map();
12
13
  }
13
14
  wait(key, timeoutMs) {
14
- this.waiting.get(key)?.resolve(null);
15
15
  return new Promise((resolve) => {
16
- const timer = setTimeout(() => {
17
- this.waiting.delete(key);
18
- resolve(null);
19
- }, timeoutMs);
20
- this.waiting.set(key, { resolve, timer });
16
+ const waiter = {
17
+ resolve,
18
+ timer: setTimeout(() => {
19
+ this.drop(key, waiter);
20
+ resolve(null);
21
+ }, timeoutMs),
22
+ };
23
+ let waiters = this.waiting.get(key);
24
+ if (!waiters) {
25
+ waiters = new Set();
26
+ this.waiting.set(key, waiters);
27
+ }
28
+ waiters.add(waiter);
21
29
  });
22
30
  }
31
+ /** True when at least one waiter took the value. */
23
32
  settle(key, value) {
24
- const w = this.waiting.get(key);
25
- if (!w)
33
+ const waiters = this.waiting.get(key);
34
+ if (!waiters)
26
35
  return false;
27
- clearTimeout(w.timer);
28
36
  this.waiting.delete(key);
29
- w.resolve(value);
37
+ for (const w of waiters) {
38
+ clearTimeout(w.timer);
39
+ w.resolve(value);
40
+ }
30
41
  return true;
31
42
  }
32
43
  cancelAll() {
33
- for (const [, w] of this.waiting) {
34
- clearTimeout(w.timer);
35
- w.resolve(null);
44
+ for (const waiters of this.waiting.values()) {
45
+ for (const w of waiters) {
46
+ clearTimeout(w.timer);
47
+ w.resolve(null);
48
+ }
36
49
  }
37
50
  this.waiting.clear();
38
51
  }
52
+ drop(key, waiter) {
53
+ const waiters = this.waiting.get(key);
54
+ if (!waiters)
55
+ return;
56
+ waiters.delete(waiter);
57
+ if (!waiters.size)
58
+ this.waiting.delete(key);
59
+ }
39
60
  }
40
61
  class ReplyWaiter {
41
62
  constructor() {
@@ -49,11 +70,11 @@ class ReplyWaiter {
49
70
  settle(reply) {
50
71
  return this.replies.settle(reply.cmdId, reply);
51
72
  }
52
- /** The next snapshot from `machineId`, or null at the deadline. */
73
+ /** The next snapshot from `machineId`, or null at the deadline; every wait in flight for the machine gets it. */
53
74
  waitSnapshot(machineId, timeoutMs) {
54
75
  return this.snapshots.wait(machineId, timeoutMs);
55
76
  }
56
- /** Answer a status query in flight; null when there is nothing to wait for. */
77
+ /** Answer the status queries in flight; null when there is nothing to wait for. */
57
78
  settleSnapshot(machineId, jobs) {
58
79
  this.snapshots.settle(machineId, jobs);
59
80
  }
@@ -5,6 +5,8 @@
5
5
  * machine's link: presence, last message, software and boot id.
6
6
  */
7
7
  import type { HandoffFacets, TraceEntry } from '../contracts';
8
+ import type { LineDef } from '../../../lib/machines/line';
9
+ import type { ContestedClaimView, LineView } from '../../../types/machines-view';
8
10
  /**
9
11
  * WAITING: the machine has no room yet (pacing.ts); the row waits in its role queue.
10
12
  * ARRIVING: the job goes out once its units arrive at the receiver (codec `dispatchOn: arrival`).
@@ -47,6 +49,7 @@ export interface AlarmTrack {
47
49
  alarmId: string;
48
50
  /** When the machine raised it; a reused alarm id with a new time is a new alarm. */
49
51
  raisedAt?: string;
52
+ level?: string;
50
53
  rowId?: string;
51
54
  /** Created and not yet resolved by anyone. */
52
55
  open: boolean;
@@ -62,12 +65,25 @@ export interface LinkTrack {
62
65
  watching?: boolean;
63
66
  software?: string;
64
67
  bootId?: string;
68
+ /** The machine's connection, when its presence names one; a new one while online is a reconnect to resync. */
69
+ sessionId?: string;
70
+ /** Why the machine went offline, when its presence said. */
71
+ reason?: string;
72
+ /** The jobs its last snapshot listed, as the codec reported them. */
73
+ jobs?: unknown[];
74
+ }
75
+ /** One unit a machine holds: the job it arrived under. */
76
+ export interface HeldUnit {
77
+ unitId: string;
78
+ jobId: string;
65
79
  }
66
80
  export declare class GatewayState {
67
81
  /** Units one dispatch may carry, from the codec; null when any number may. */
68
82
  unitsPerDispatch: number | null;
69
83
  /** Jobs go to a receiver once its units arrive there, from the codec. */
70
84
  dispatchOnArrival: boolean;
85
+ /** Commands of the machines' own that a machine-command row may ask for, from the codec. */
86
+ rowOps: readonly string[];
71
87
  /** Note each job's start, progress steps and pauses on the row that holds it (lifecycle.ts). */
72
88
  lifecycle: boolean;
73
89
  /** Active alarms are retained on the broker; otherwise snapshots list them (codec.ts retainedAlarms). */
@@ -87,6 +103,7 @@ export declare class GatewayState {
87
103
  readonly alarms: Map<string, AlarmTrack>;
88
104
  /** Finished records that came before their row: machine/unit → job body. */
89
105
  private earlyFinishes;
106
+ /** Open machine-command rows → the machine each commands. */
90
107
  private openCommands;
91
108
  /** Accepted dispatch command ids → their row, so a later failure finds the row. */
92
109
  private dispatches;
@@ -97,7 +114,7 @@ export declare class GatewayState {
97
114
  /** Learned addresses, both ways: station → address and address → station. */
98
115
  private addressOfStation;
99
116
  private stationOfAddress;
100
- /** Contested claims already raised as registration rows, `${address}>${station}`. */
117
+ /** Contested claims already raised as registration rows, `${address}>${station}` → the row. */
101
118
  private claims;
102
119
  /** Contested claims heard from the machines themselves, `${address}>${station}`. */
103
120
  private heard;
@@ -116,6 +133,7 @@ export declare class GatewayState {
116
133
  /** The job a unit arrived under at `machineId`, while it is still there. */
117
134
  heldJob(machineId: string, unitId: string): string | undefined;
118
135
  heldAt(machineId: string): string[];
136
+ heldUnitsAt(machineId: string): HeldUnit[];
119
137
  /** Keep only units whose job the machine still lists (its snapshot). */
120
138
  keepHeld(machineId: string, jobIds: Set<string>): void;
121
139
  /** Keep a sender's finished record until its row is known, so an arrival cannot close the row without it. */
@@ -125,14 +143,18 @@ export declare class GatewayState {
125
143
  /** The row a dispatch command belongs to, open or recently closed. */
126
144
  rowForDispatch(cmdId: string): HandoffRow | undefined;
127
145
  /** Track a machine-command row; false when it is already tracked or has ended. */
128
- trackCommand(id: string): boolean;
146
+ trackCommand(id: string, machineId?: string): boolean;
147
+ /** Open machine-command rows for one machine. */
148
+ openCommandsFor(machineId: string): number;
129
149
  endCommand(id: string): void;
130
150
  /** Bind a station to an address, replacing whatever either was bound to before. */
131
151
  bindAddress(machineId: string, address: string): void;
132
152
  learnedAddress(machineId: string): string | undefined;
133
153
  stationAt(address: string): string | undefined;
134
154
  claimRaised(address: string, machineId: string): boolean;
135
- raiseClaim(address: string, machineId: string): void;
155
+ raiseClaim(address: string, machineId: string, rowId?: string): void;
156
+ /** The contested claims waiting for a person, with the rows that ask. */
157
+ contested(): ContestedClaimView[];
136
158
  settleClaim(address: string, machineId: string): void;
137
159
  hearClaim(address: string, machineId: string): void;
138
160
  claimHeard(address: string, machineId: string): boolean;
@@ -142,4 +164,8 @@ export declare class GatewayState {
142
164
  raiseViolation(key: string): void;
143
165
  link(machineId: string, now?: number): LinkTrack;
144
166
  alarmKey(machineId: string, alarmId: string): string;
167
+ /** The line as this gateway sees it (project.ts). */
168
+ project(line: LineDef): LineView;
169
+ /** A copy a dry run may change without touching the line. */
170
+ clone(): GatewayState;
145
171
  }
@@ -7,6 +7,7 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.GatewayState = exports.ROW_END = exports.DISPATCH_STATE = void 0;
10
+ const project_1 = require("./project");
10
11
  const trace_1 = require("./trace");
11
12
  /**
12
13
  * WAITING: the machine has no room yet (pacing.ts); the row waits in its role queue.
@@ -16,6 +17,10 @@ exports.DISPATCH_STATE = {
16
17
  NONE: 'none', WAITING: 'waiting', ARRIVING: 'arriving', PENDING: 'pending', ACCEPTED: 'accepted', REFUSED: 'refused',
17
18
  };
18
19
  exports.ROW_END = { RESOLVED: 'resolved', CANCELLED: 'cancelled', EXPIRED: 'expired' };
20
+ function copyInto(from, into, clone = (v) => v) {
21
+ for (const [k, v] of from)
22
+ into.set(k, clone(v));
23
+ }
19
24
  const CLOSED_LIMIT = 2_000;
20
25
  class GatewayState {
21
26
  constructor() {
@@ -23,6 +28,8 @@ class GatewayState {
23
28
  this.unitsPerDispatch = null;
24
29
  /** Jobs go to a receiver once its units arrive there, from the codec. */
25
30
  this.dispatchOnArrival = false;
31
+ /** Commands of the machines' own that a machine-command row may ask for, from the codec. */
32
+ this.rowOps = [];
26
33
  /** Note each job's start, progress steps and pauses on the row that holds it (lifecycle.ts). */
27
34
  this.lifecycle = false;
28
35
  /** Active alarms are retained on the broker; otherwise snapshots list them (codec.ts retainedAlarms). */
@@ -42,7 +49,8 @@ class GatewayState {
42
49
  this.alarms = new Map();
43
50
  /** Finished records that came before their row: machine/unit → job body. */
44
51
  this.earlyFinishes = new Map();
45
- this.openCommands = new Set();
52
+ /** Open machine-command rows → the machine each commands. */
53
+ this.openCommands = new Map();
46
54
  /** Accepted dispatch command ids → their row, so a later failure finds the row. */
47
55
  this.dispatches = new Map();
48
56
  this.endedCommands = new Set();
@@ -52,8 +60,8 @@ class GatewayState {
52
60
  /** Learned addresses, both ways: station → address and address → station. */
53
61
  this.addressOfStation = new Map();
54
62
  this.stationOfAddress = new Map();
55
- /** Contested claims already raised as registration rows, `${address}>${station}`. */
56
- this.claims = new Set();
63
+ /** Contested claims already raised as registration rows, `${address}>${station}` → the row. */
64
+ this.claims = new Map();
57
65
  /** Contested claims heard from the machines themselves, `${address}>${station}`. */
58
66
  this.heard = new Set();
59
67
  /** Addresses heard that claim no station, logged once each. */
@@ -116,6 +124,9 @@ class GatewayState {
116
124
  heldAt(machineId) {
117
125
  return [...(this.held.get(machineId)?.values() ?? [])];
118
126
  }
127
+ heldUnitsAt(machineId) {
128
+ return [...(this.held.get(machineId)?.entries() ?? [])].map(([unitId, jobId]) => ({ unitId, jobId }));
129
+ }
119
130
  /** Keep only units whose job the machine still lists (its snapshot). */
120
131
  keepHeld(machineId, jobIds) {
121
132
  const units = this.held.get(machineId);
@@ -154,12 +165,16 @@ class GatewayState {
154
165
  return rowId ? this.openRows.get(rowId) ?? this.closedRows.get(rowId) : undefined;
155
166
  }
156
167
  /** Track a machine-command row; false when it is already tracked or has ended. */
157
- trackCommand(id) {
168
+ trackCommand(id, machineId = '') {
158
169
  if (this.openCommands.has(id) || this.endedCommands.has(id))
159
170
  return false;
160
- this.openCommands.add(id);
171
+ this.openCommands.set(id, machineId);
161
172
  return true;
162
173
  }
174
+ /** Open machine-command rows for one machine. */
175
+ openCommandsFor(machineId) {
176
+ return [...this.openCommands.values()].filter((m) => m === machineId).length;
177
+ }
163
178
  endCommand(id) {
164
179
  this.openCommands.delete(id);
165
180
  this.endedCommands.add(id);
@@ -189,8 +204,15 @@ class GatewayState {
189
204
  claimRaised(address, machineId) {
190
205
  return this.claims.has(`${address}>${machineId}`);
191
206
  }
192
- raiseClaim(address, machineId) {
193
- this.claims.add(`${address}>${machineId}`);
207
+ raiseClaim(address, machineId, rowId) {
208
+ this.claims.set(`${address}>${machineId}`, rowId ?? this.claims.get(`${address}>${machineId}`) ?? null);
209
+ }
210
+ /** The contested claims waiting for a person, with the rows that ask. */
211
+ contested() {
212
+ return [...this.claims.entries()].map(([key, rowId]) => {
213
+ const [address, station] = key.split('>');
214
+ return { address, station, rowId: rowId ?? '' };
215
+ });
194
216
  }
195
217
  settleClaim(address, machineId) {
196
218
  this.claims.delete(`${address}>${machineId}`);
@@ -234,6 +256,38 @@ class GatewayState {
234
256
  alarmKey(machineId, alarmId) {
235
257
  return `${machineId}/${alarmId}`;
236
258
  }
259
+ /** The line as this gateway sees it (project.ts). */
260
+ project(line) {
261
+ return (0, project_1.projectLine)(this, line);
262
+ }
263
+ /** A copy a dry run may change without touching the line. */
264
+ clone() {
265
+ const copy = new GatewayState();
266
+ Object.assign(copy, {
267
+ unitsPerDispatch: this.unitsPerDispatch, dispatchOnArrival: this.dispatchOnArrival, rowOps: this.rowOps, lifecycle: this.lifecycle,
268
+ retainedAlarms: this.retainedAlarms, readingRetained: this.readingRetained, takenAt: this.takenAt, progressStep: this.progressStep, holdDispatch: this.holdDispatch,
269
+ });
270
+ copyInto(this.held, copy.held, (units) => new Map(units));
271
+ copyInto(this.openRows, copy.openRows, (row) => ({ ...row, units: [...row.units], ...(row.noted ? { noted: [...row.noted] } : {}) }));
272
+ copyInto(this.closedRows, copy.closedRows, (row) => ({ ...row }));
273
+ copyInto(this.alarms, copy.alarms, (track) => ({ ...track, ...(track.noted ? { noted: [...track.noted] } : {}) }));
274
+ copyInto(this.earlyFinishes, copy.earlyFinishes);
275
+ copyInto(this.openCommands, copy.openCommands);
276
+ copyInto(this.dispatches, copy.dispatches);
277
+ copyInto(this.links, copy.links, (link) => ({ ...link }));
278
+ copyInto(this.addressOfStation, copy.addressOfStation);
279
+ copyInto(this.stationOfAddress, copy.stationOfAddress);
280
+ copyInto(this.claims, copy.claims);
281
+ for (const id of this.endedCommands)
282
+ copy.endedCommands.add(id);
283
+ for (const key of this.violations)
284
+ copy.violations.add(key);
285
+ for (const key of this.heard)
286
+ copy.heard.add(key);
287
+ for (const key of this.strangers)
288
+ copy.strangers.add(key);
289
+ return copy;
290
+ }
237
291
  }
238
292
  exports.GatewayState = GatewayState;
239
293
  function carries(row, unitId) {
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The wire record. Every message a gateway reads, and every command,
3
+ * snapshot request and receipt it sends, becomes one WireEvent for the
4
+ * line's view: what was on the wire, how the codec read it, and what the
5
+ * gateway did about it. Telemetry is left out unless the line asks for it.
6
+ */
7
+ import { type Inspection, type MachineCommand, type MachineIdent, type WireMessage } from '../../../lib/machines/protocol';
8
+ import { type InboundMessage } from '../../../lib/machines/transport';
9
+ import type { WireAction, WireEvent } from '../../../types/machines-view';
10
+ import type { Action } from './actions';
11
+ import type { Applied } from './admission';
12
+ export type WireSink = (event: WireEvent) => void;
13
+ export declare const WIRE_EVENT_TYPE = "machine.wire";
14
+ export declare const WIRE_DIRECTION: {
15
+ readonly IN: "in";
16
+ readonly OUT: "out";
17
+ };
18
+ export interface WireOptions {
19
+ /** Publish telemetry messages too. */
20
+ telemetry?: boolean;
21
+ }
22
+ interface WireLine {
23
+ siteId: string;
24
+ lineId: string;
25
+ }
26
+ /** The sender a message was read as, when it differs from the topic's. */
27
+ export interface WireSender {
28
+ machineId: string | null;
29
+ address: string | null;
30
+ }
31
+ export declare class WireRecorder {
32
+ private readonly line;
33
+ private readonly sink;
34
+ private readonly opts;
35
+ constructor(line: WireLine, sink: WireSink, opts?: WireOptions);
36
+ /** A decoded inbound message and what the gateway did with it. */
37
+ inbound(msg: InboundMessage, seen: Inspection, applied: Applied, deliveries: number, sender?: WireSender): void;
38
+ /** A message the codec could not read, or one that is not a machine's. */
39
+ unreadable(msg: InboundMessage, detail: string, verb?: WireAction['verb']): void;
40
+ /** A command the gateway sent, as the codec put it on the wire. */
41
+ command(ident: MachineIdent, command: MachineCommand, wire: WireMessage): void;
42
+ /** A receipt confirming the messages the gateway is done with. */
43
+ receipt(ident: MachineIdent, ids: string[], wire: WireMessage): void;
44
+ private outbound;
45
+ }
46
+ /** The event name within the kind: job event, alarm action, command op, reply status. */
47
+ export declare function eventOf(seen: Inspection): string | null;
48
+ /** One line from the kind, the event and the ids the body names. */
49
+ export declare function summarize(seen: Inspection): string;
50
+ /** The record of an inbound message before the gateway's actions are known. */
51
+ export declare function describeInbound(line: WireLine, msg: InboundMessage, seen: Inspection, sender?: WireSender): Omit<WireEvent, 'actions'>;
52
+ /** What handling a message came to, as actions; a message with none is acknowledged, or waits for its row. */
53
+ export declare function appliedActions(applied: Applied, deliveries: number, maxDeliveries?: number): WireAction[];
54
+ /** A message no row has claimed after this many deliveries is not racing its row. */
55
+ export declare const MAX_DELIVERIES = 30;
56
+ /** A planner action as the wire would record it, before it runs; a dry run shows these. */
57
+ export declare function plannedAction(a: Action): WireAction;
58
+ export {};
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ /**
3
+ * The wire record. Every message a gateway reads, and every command,
4
+ * snapshot request and receipt it sends, becomes one WireEvent for the
5
+ * line's view: what was on the wire, how the codec read it, and what the
6
+ * gateway did about it. Telemetry is left out unless the line asks for it.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.MAX_DELIVERIES = exports.WireRecorder = exports.WIRE_DIRECTION = exports.WIRE_EVENT_TYPE = void 0;
10
+ exports.eventOf = eventOf;
11
+ exports.summarize = summarize;
12
+ exports.describeInbound = describeInbound;
13
+ exports.appliedActions = appliedActions;
14
+ exports.plannedAction = plannedAction;
15
+ const protocol_1 = require("../../../lib/machines/protocol");
16
+ const transport_1 = require("../../../lib/machines/transport");
17
+ exports.WIRE_EVENT_TYPE = 'machine.wire';
18
+ exports.WIRE_DIRECTION = { IN: 'in', OUT: 'out' };
19
+ const RECEIPT_CHANNEL = 'receipt';
20
+ const ALARM_EVENT = { RAISED: 'raised', ACKED: 'acked', CLEARED: 'cleared' };
21
+ const PRESENCE_EVENT = { ONLINE: 'online', OFFLINE: 'offline' };
22
+ class WireRecorder {
23
+ constructor(line, sink, opts = {}) {
24
+ this.line = line;
25
+ this.sink = sink;
26
+ this.opts = opts;
27
+ }
28
+ /** A decoded inbound message and what the gateway did with it. */
29
+ inbound(msg, seen, applied, deliveries, sender) {
30
+ if (seen.parsed?.kind === protocol_1.MESSAGE_KIND.TELEMETRY && !this.opts.telemetry)
31
+ return;
32
+ this.sink({ ...describeInbound(this.line, msg, seen, sender), actions: appliedActions(applied, deliveries) });
33
+ }
34
+ /** A message the codec could not read, or one that is not a machine's. */
35
+ unreadable(msg, detail, verb = 'unreadable') {
36
+ this.sink({
37
+ ...describeInbound(this.line, msg, { parsed: null, body: null, violations: [] }),
38
+ summary: detail, actions: [{ verb, detail }],
39
+ });
40
+ }
41
+ /** A command the gateway sent, as the codec put it on the wire. */
42
+ command(ident, command, wire) {
43
+ const jobId = typeof command.args.jobId === 'string' ? ` ${command.args.jobId}` : '';
44
+ this.sink(this.outbound(ident, wire, protocol_1.MESSAGE_KIND.CMD, protocol_1.CHANNEL.CMD, command.op, `cmd ${command.op}${jobId} ${command.cmdId}`));
45
+ }
46
+ /** A receipt confirming the messages the gateway is done with. */
47
+ receipt(ident, ids, wire) {
48
+ this.sink(this.outbound(ident, wire, 'receipt', RECEIPT_CHANNEL, null, `receipt for ${ids.length} message${ids.length === 1 ? '' : 's'}`));
49
+ }
50
+ outbound(ident, wire, kind, channel, event, summary) {
51
+ const body = parseJson(wire.payload);
52
+ return {
53
+ type: exports.WIRE_EVENT_TYPE, siteId: this.line.siteId, lineId: this.line.lineId, machineId: ident.machineId, address: (0, protocol_1.addressOf)(ident),
54
+ direction: exports.WIRE_DIRECTION.OUT, channel, topic: wire.topic, id: typeof body?.id === 'string' ? body.id : null,
55
+ at: typeof body?.at === 'string' ? body.at : (0, protocol_1.isoTs)(), retained: false, kind, event, summary, violations: [], actions: [], payload: body ?? wire.payload,
56
+ };
57
+ }
58
+ }
59
+ exports.WireRecorder = WireRecorder;
60
+ function parseJson(payload) {
61
+ try {
62
+ const parsed = JSON.parse(payload);
63
+ return parsed && typeof parsed === 'object' ? parsed : null;
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ }
69
+ /** The line-protocol channel a decoded message belongs to. */
70
+ function channelOf(seen) {
71
+ const parsed = seen.parsed;
72
+ if (!parsed)
73
+ return '';
74
+ switch (parsed.kind) {
75
+ case protocol_1.MESSAGE_KIND.ALARM: return `${protocol_1.CHANNEL.ALARM}/${parsed.key ?? ''}`;
76
+ case protocol_1.MESSAGE_KIND.REPORT: return `${protocol_1.CHANNEL.REPORT}/${parsed.key ?? ''}`;
77
+ case protocol_1.MESSAGE_KIND.REPLY: return protocol_1.CHANNEL.REPLY;
78
+ default: return parsed.kind;
79
+ }
80
+ }
81
+ /** The event name within the kind: job event, alarm action, command op, reply status. */
82
+ function eventOf(seen) {
83
+ const parsed = seen.parsed;
84
+ const b = seen.body?.body ?? {};
85
+ if (!parsed)
86
+ return null;
87
+ switch (parsed.kind) {
88
+ case protocol_1.MESSAGE_KIND.JOB: return typeof b.event === 'string' ? b.event : null;
89
+ case protocol_1.MESSAGE_KIND.ALARM: return !seen.body || b.active === false ? ALARM_EVENT.CLEARED : b.ackedBy ? ALARM_EVENT.ACKED : ALARM_EVENT.RAISED;
90
+ case protocol_1.MESSAGE_KIND.CMD: return typeof b.op === 'string' ? b.op : null;
91
+ case protocol_1.MESSAGE_KIND.REPLY: return typeof b.status === 'string' ? b.status : null;
92
+ case protocol_1.MESSAGE_KIND.PRESENCE: return b.online === true ? PRESENCE_EVENT.ONLINE : PRESENCE_EVENT.OFFLINE;
93
+ case protocol_1.MESSAGE_KIND.SNAPSHOT: return typeof b.mode === 'string' ? b.mode : null;
94
+ case protocol_1.MESSAGE_KIND.REPORT: return parsed.key ?? null;
95
+ default: return null;
96
+ }
97
+ }
98
+ const count = (n, word) => `${n} ${word}${n === 1 ? '' : 's'}`;
99
+ /** One line from the kind, the event and the ids the body names. */
100
+ function summarize(seen) {
101
+ const parsed = seen.parsed;
102
+ if (!parsed)
103
+ return 'not a machine message';
104
+ const b = seen.body?.body ?? {};
105
+ const event = eventOf(seen);
106
+ switch (parsed.kind) {
107
+ case protocol_1.MESSAGE_KIND.PRESENCE:
108
+ return ['presence', event, b.software, b.reason ? `(${b.reason})` : null].filter(Boolean).join(' ');
109
+ case protocol_1.MESSAGE_KIND.SNAPSHOT:
110
+ return ['snapshot', event, count(Array.isArray(b.jobs) ? b.jobs.length : 0, 'job'), Array.isArray(b.alarms) && b.alarms.length ? count(b.alarms.length, 'alarm') : null].filter(Boolean).join(' ');
111
+ case protocol_1.MESSAGE_KIND.JOB:
112
+ return ['job', event, b.unitId ?? (b.carrierId ? `carrier ${b.carrierId}` : null), b.jobId ? `(${b.jobId})` : null, b.result, b.failure].filter(Boolean).join(' ');
113
+ case protocol_1.MESSAGE_KIND.ALARM:
114
+ return ['alarm', event, parsed.key ?? b.alarmId, b.level, b.text ? `: ${b.text}` : null].filter(Boolean).join(' ');
115
+ case protocol_1.MESSAGE_KIND.TELEMETRY:
116
+ return `telemetry ${count(Object.keys(b.readings ?? {}).length, 'reading')}`;
117
+ case protocol_1.MESSAGE_KIND.CMD:
118
+ return ['cmd', event, b.args?.jobId, b.cmdId].filter(Boolean).join(' ');
119
+ case protocol_1.MESSAGE_KIND.REPLY:
120
+ return ['reply', event, b.cmdId, b.reason ? `: ${b.reason}` : null].filter(Boolean).join(' ');
121
+ case protocol_1.MESSAGE_KIND.REPORT:
122
+ return `report ${parsed.key ?? ''}`.trim();
123
+ default:
124
+ return parsed.kind;
125
+ }
126
+ }
127
+ /** The record of an inbound message before the gateway's actions are known. */
128
+ function describeInbound(line, msg, seen, sender) {
129
+ const ident = seen.parsed?.ident;
130
+ return {
131
+ type: exports.WIRE_EVENT_TYPE, siteId: line.siteId, lineId: line.lineId,
132
+ machineId: sender ? sender.machineId : ident?.machineId ?? null,
133
+ address: sender ? sender.address : ident ? (0, protocol_1.addressOf)(ident) : null,
134
+ direction: exports.WIRE_DIRECTION.IN, channel: channelOf(seen), topic: msg.topic,
135
+ id: seen.body?.id ?? null, at: seen.body?.at ?? (0, protocol_1.isoTs)(), retained: msg.retained === true,
136
+ kind: seen.parsed?.kind ?? 'unknown', event: eventOf(seen), summary: summarize(seen),
137
+ violations: seen.violations, payload: seen.body ?? msg.payload,
138
+ };
139
+ }
140
+ /** What handling a message came to, as actions; a message with none is acknowledged, or waits for its row. */
141
+ function appliedActions(applied, deliveries, maxDeliveries = exports.MAX_DELIVERIES) {
142
+ if (applied.actions.length)
143
+ return applied.actions;
144
+ if (applied.disposition !== transport_1.DISPOSITION.NAK)
145
+ return [{ verb: 'ack' }];
146
+ if (applied.failed)
147
+ return [{ verb: 'none', detail: 'a verb failed; the message is delivered again' }];
148
+ if (deliveries >= maxDeliveries)
149
+ return [{ verb: 'unmatched', detail: `no row after ${deliveries} deliveries` }];
150
+ return [{ verb: 'none', detail: `waiting for its row (delivery ${deliveries})` }];
151
+ }
152
+ /** A message no row has claimed after this many deliveries is not racing its row. */
153
+ exports.MAX_DELIVERIES = 30;
154
+ /** A planner action as the wire would record it, before it runs; a dry run shows these. */
155
+ function plannedAction(a) {
156
+ switch (a.kind) {
157
+ case 'dispatch': return { verb: 'none', detail: `dispatch ${a.args.jobId ?? a.cmdId} to ${a.machineId}` };
158
+ case 'command': return { verb: 'none', detail: `${a.op} to ${a.machineId}` };
159
+ case 'control': return { verb: 'none', rowId: a.rowId, detail: `${a.op} to ${a.machineId}` };
160
+ case 'claim': return { verb: 'claim', rowId: a.rowId };
161
+ case 'accumulate': return { verb: 'accumulate', rowId: a.rowId, itemKey: a.itemKey };
162
+ case 'resolve': return { verb: 'resolve', rowId: a.rowId };
163
+ case 'createAlarmRow': return { verb: 'create-row', detail: `${a.row.type} for ${a.machineId}` };
164
+ case 'createRow': return { verb: 'create-row', detail: a.row.type };
165
+ case 'watchOffline': return { verb: 'none', detail: `watching ${a.machineId} for an offline row` };
166
+ case 'settleReply': return { verb: 'ack', detail: `${a.status} ${a.cmdId}` };
167
+ case 'settleSnapshot': return { verb: 'ack', detail: `${a.machineId} holds ${count(a.jobIds.length, 'job')}` };
168
+ case 'bindAddress': return { verb: 'ack', detail: `bind ${a.machineId} to ${a.address}` };
169
+ case 'refuseBinding': return { verb: 'refuse', detail: a.reason };
170
+ }
171
+ }
@@ -7,5 +7,8 @@ export * from './gateway';
7
7
  export * from './roles';
8
8
  export * from './identities';
9
9
  export * from './surface';
10
+ export * from './registry';
11
+ export * from './registry-sync';
10
12
  export * from './rows';
11
13
  export * from '../../lib/machines';
14
+ export type * from '../../types/machines-view';
@@ -23,5 +23,7 @@ __exportStar(require("./gateway"), exports);
23
23
  __exportStar(require("./roles"), exports);
24
24
  __exportStar(require("./identities"), exports);
25
25
  __exportStar(require("./surface"), exports);
26
+ __exportStar(require("./registry"), exports);
27
+ __exportStar(require("./registry-sync"), exports);
26
28
  __exportStar(require("./rows"), exports);
27
29
  __exportStar(require("../../lib/machines"), exports);
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The lines index as the API and the MCP server present it: a registry row
3
+ * joined with what the running surface knows about the line.
4
+ */
5
+ import type { LineDef } from '../../lib/machines/line';
6
+ import type { LineHealth, LineIndexRow, LineSummary } from '../../types/machines-view';
7
+ import type { LineRecordWithHealth } from './registry';
8
+ import { type LineSurface } from './surface';
9
+ /** The line as every replica describes it: the surface's own summary when it runs the line, else the stored definition. */
10
+ export declare function lineSummaryOf(surface: LineSurface, siteId: string, lineId: string, stored: LineDef): LineSummary;
11
+ /** A registry row as the index shows it. */
12
+ export declare function toLineIndexRow(surface: LineSurface, record: LineRecordWithHealth): LineIndexRow;
13
+ /** Health for a line no pending row names yet. */
14
+ export declare function emptyLineHealth(machines: number): LineHealth;
15
+ /** The raw wire payload as a string: an object is serialized, text passes through. */
16
+ export declare function wirePayloadOf(body: unknown): string;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ /**
3
+ * The lines index as the API and the MCP server present it: a registry row
4
+ * joined with what the running surface knows about the line.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.lineSummaryOf = lineSummaryOf;
8
+ exports.toLineIndexRow = toLineIndexRow;
9
+ exports.emptyLineHealth = emptyLineHealth;
10
+ exports.wirePayloadOf = wirePayloadOf;
11
+ const surface_1 = require("./surface");
12
+ /** The line as every replica describes it: the surface's own summary when it runs the line, else the stored definition. */
13
+ function lineSummaryOf(surface, siteId, lineId, stored) {
14
+ const running = surface.findLine(siteId, lineId)
15
+ ? surface.describeLines().find((l) => l.siteId === siteId && l.lineId === lineId)
16
+ : undefined;
17
+ return running ?? (0, surface_1.summarizeLine)(stored, {});
18
+ }
19
+ /** A registry row as the index shows it. */
20
+ function toLineIndexRow(surface, record) {
21
+ return {
22
+ ...lineSummaryOf(surface, record.siteId, record.lineId, record.definition),
23
+ source: record.source, version: record.version, enabled: record.enabled, updatedAt: record.updatedAt,
24
+ leading: surface.describeLine(record.siteId, record.lineId) !== null,
25
+ health: record.health,
26
+ };
27
+ }
28
+ /** Health for a line no pending row names yet. */
29
+ function emptyLineHealth(machines) {
30
+ return { machines, offline: 0, quiet: 0, alarms: 0, people: 0, handoff: 0, command: 0, attention: false };
31
+ }
32
+ /** The raw wire payload as a string: an object is serialized, text passes through. */
33
+ function wirePayloadOf(body) {
34
+ if (typeof body === 'string')
35
+ return body;
36
+ if (body === undefined || body === null)
37
+ return '';
38
+ return JSON.stringify(body);
39
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The line registry's statements. Every write is one statement: the
3
+ * version advances in the same UPDATE that changes the row, and a version
4
+ * check rides the WHERE so a stale writer gets zero rows back.
5
+ */
6
+ export declare const LINE_SOURCE: {
7
+ readonly CODE: "code";
8
+ readonly API: "api";
9
+ };
10
+ /** An API write: insert, or replace and advance the version; $5 non-null requires that version. */
11
+ export declare const UPSERT_API_LINE: string;
12
+ /** A db-owned code line: first writer wins, an existing row is left as it is. */
13
+ export declare const SEED_CODE_LINE: string;
14
+ /** A code-owned code line: written only when the definition or the owner differs, one version per change. */
15
+ export declare const APPLY_CODE_LINE: string;
16
+ export declare const GET_LINE = "SELECT site_id, line_id, definition, source, version, enabled, search_text, created_at, updated_at FROM lt_machine_lines WHERE site_id = $1 AND line_id = $2";
17
+ export declare const DELETE_LINE = "DELETE FROM lt_machine_lines WHERE site_id = $1 AND line_id = $2 RETURNING site_id, line_id, definition, source, version, enabled, search_text, created_at, updated_at";
18
+ export declare const LIST_ENABLED_LINES = "SELECT site_id, line_id, definition, source, version, enabled, search_text, created_at, updated_at FROM lt_machine_lines WHERE enabled ORDER BY site_id, line_id";
19
+ export declare const LIST_CODE_LINES: string;
20
+ /** The kinds of pending rows the index counts, in the order the health CTE projects them. */
21
+ export declare const HEALTH_ROW_TYPES: readonly ["machine-offline", "machine-quiet", "line-alarm", "handoff-error", "contract-violation", "machine-registration", "handoff", "machine-command"];
22
+ /** The index's order, by name; attention first within each. */
23
+ export declare const LINE_ORDER: Record<string, string>;
24
+ /**
25
+ * One page of the index: $1 row types, $2 search pattern or null, $3 site
26
+ * or null, $4 attention or null, $5 limit, $6 offset, $7 line or null. The
27
+ * total rides every row as a window count.
28
+ */
29
+ export declare function listLinesSql(order: string): string;
30
+ /** Every site, with its lines and how many need attention: $1 row types. */
31
+ export declare const LIST_SITES: string;