@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
@@ -9,6 +9,7 @@ exports.NatsStreams = void 0;
9
9
  exports.streamConfig = streamConfig;
10
10
  exports.consumerConfig = consumerConfig;
11
11
  exports.ensureStream = ensureStream;
12
+ exports.describeStream = describeStream;
12
13
  exports.ensureConsumer = ensureConsumer;
13
14
  exports.payloadOf = payloadOf;
14
15
  const nats_1 = require("nats");
@@ -41,6 +42,18 @@ async function ensureStream(jsm, spec) {
41
42
  }
42
43
  await jsm.streams.update(spec.name, config);
43
44
  }
45
+ /** The stream as JetStream holds it, or null when there is none. */
46
+ async function describeStream(jsm, name) {
47
+ try {
48
+ const info = await jsm.streams.info(name);
49
+ return { name, subjects: info.config.subjects ?? [], maxAgeMs: Math.round((info.config.max_age ?? 0) / 1_000_000) };
50
+ }
51
+ catch (err) {
52
+ if (/stream not found/i.test(err?.message ?? ''))
53
+ return null;
54
+ throw err;
55
+ }
56
+ }
44
57
  /** Create the consumer, or move an existing one to the spec's subjects without losing its place. */
45
58
  async function ensureConsumer(jsm, stream, spec) {
46
59
  let existing;
@@ -72,6 +85,9 @@ class NatsStreams {
72
85
  ensureConsumer(stream, spec) {
73
86
  return ensureConsumer(this.jsm, stream, spec);
74
87
  }
88
+ describeStream(name) {
89
+ return describeStream(this.jsm, name);
90
+ }
75
91
  async append(subject, payload) {
76
92
  await this.js.publish(subject, payload);
77
93
  }
@@ -32,10 +32,12 @@ export declare class LocalStorageBackend implements StorageBackend {
32
32
  directories: string[];
33
33
  nextToken?: string;
34
34
  }>;
35
+ /** The digest is read from the file itself, so it is always the stored bytes' own. */
35
36
  getMetadata(key: string): Promise<{
36
37
  size: number;
37
38
  modified_at: string;
38
39
  content_type: string;
40
+ sha256: string;
39
41
  }>;
40
42
  getSignedUrl(key: string, expiresInSeconds: number): Promise<string>;
41
43
  }
@@ -37,6 +37,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.LocalStorageBackend = void 0;
40
+ const crypto_1 = require("crypto");
40
41
  const fs = __importStar(require("fs"));
41
42
  const path = __importStar(require("path"));
42
43
  const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
@@ -168,6 +169,7 @@ class LocalStorageBackend {
168
169
  nextToken: hasMore ? String(offset + limit) : undefined,
169
170
  };
170
171
  }
172
+ /** The digest is read from the file itself, so it is always the stored bytes' own. */
171
173
  async getMetadata(key) {
172
174
  const resolved = resolveAndValidate(key);
173
175
  if (!fs.existsSync(resolved)) {
@@ -178,6 +180,7 @@ class LocalStorageBackend {
178
180
  size: stat.size,
179
181
  modified_at: stat.mtime.toISOString(),
180
182
  content_type: (0, mime_1.mimeFromPath)(key),
183
+ sha256: (0, crypto_1.createHash)('sha256').update(fs.readFileSync(resolved)).digest('hex'),
181
184
  };
182
185
  }
183
186
  async getSignedUrl(key, expiresInSeconds) {
@@ -1,4 +1,4 @@
1
- import type { StorageBackend } from './types';
1
+ import type { StorageBackend, WriteOptions } from './types';
2
2
  export declare class S3StorageBackend implements StorageBackend {
3
3
  private client;
4
4
  private signingClient;
@@ -6,7 +6,7 @@ export declare class S3StorageBackend implements StorageBackend {
6
6
  private bucketReady;
7
7
  constructor();
8
8
  private ensureBucket;
9
- write(key: string, data: Buffer): Promise<{
9
+ write(key: string, data: Buffer, options?: WriteOptions): Promise<{
10
10
  ref: string;
11
11
  size: number;
12
12
  }>;
@@ -42,6 +42,7 @@ export declare class S3StorageBackend implements StorageBackend {
42
42
  size: number;
43
43
  modified_at: string;
44
44
  content_type: string;
45
+ sha256?: string;
45
46
  }>;
46
47
  getSignedUrl(key: string, expiresInSeconds: number): Promise<string>;
47
48
  }
@@ -39,6 +39,8 @@ const os = __importStar(require("os"));
39
39
  const path = __importStar(require("path"));
40
40
  const client_s3_1 = require("@aws-sdk/client-s3");
41
41
  const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner");
42
+ /** The object metadata key the digest is kept under. */
43
+ const SHA256_METADATA = 'sha256';
42
44
  const mime_1 = require("./mime");
43
45
  const STAGING_DIR = path.join(os.tmpdir(), 'lt-staging');
44
46
  class S3StorageBackend {
@@ -91,12 +93,13 @@ class S3StorageBackend {
91
93
  }
92
94
  }
93
95
  }
94
- async write(key, data) {
96
+ async write(key, data, options) {
95
97
  await this.bucketReady;
96
98
  await this.client.send(new client_s3_1.PutObjectCommand({
97
99
  Bucket: this.bucket,
98
100
  Key: normalizeKey(key),
99
101
  Body: data,
102
+ ...(options?.sha256 ? { Metadata: { [SHA256_METADATA]: options.sha256 } } : {}),
100
103
  }));
101
104
  return { ref: key, size: data.length };
102
105
  }
@@ -222,10 +225,12 @@ class S3StorageBackend {
222
225
  Bucket: this.bucket,
223
226
  Key: normalizeKey(key),
224
227
  }));
228
+ const sha256 = resp.Metadata?.[SHA256_METADATA];
225
229
  return {
226
230
  size: resp.ContentLength || 0,
227
231
  modified_at: resp.LastModified?.toISOString() || new Date().toISOString(),
228
232
  content_type: resp.ContentType || (0, mime_1.mimeFromPath)(key),
233
+ ...(sha256 ? { sha256 } : {}),
229
234
  };
230
235
  }
231
236
  async getSignedUrl(key, expiresInSeconds) {
@@ -1,6 +1,10 @@
1
+ export interface WriteOptions {
2
+ /** The SHA-256 of `data`, hex, kept with the object. */
3
+ sha256?: string;
4
+ }
1
5
  export interface StorageBackend {
2
6
  /** Write data to storage. Returns the key and size. */
3
- write(key: string, data: Buffer): Promise<{
7
+ write(key: string, data: Buffer, options?: WriteOptions): Promise<{
4
8
  ref: string;
5
9
  size: number;
6
10
  }>;
@@ -53,6 +57,8 @@ export interface StorageBackend {
53
57
  size: number;
54
58
  modified_at: string;
55
59
  content_type: string;
60
+ /** The object's SHA-256, hex, when the backend knows it. */
61
+ sha256?: string;
56
62
  }>;
57
63
  /** Generate a time-limited signed URL for unauthenticated file access. */
58
64
  getSignedUrl(key: string, expiresInSeconds: number): Promise<string>;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The running machine surface, for settings and the machines API. Set by
3
+ * start() when the config declares lines; absent otherwise, so a deployment
4
+ * without machines serves no lines and no Lines view.
5
+ */
6
+ import type { LineSurface } from '../services/machines/surface';
7
+ export declare function registerMachineSurface(next: LineSurface | null): void;
8
+ export declare function getMachineSurface(): LineSurface | null;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ /**
3
+ * The running machine surface, for settings and the machines API. Set by
4
+ * start() when the config declares lines; absent otherwise, so a deployment
5
+ * without machines serves no lines and no Lines view.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.registerMachineSurface = registerMachineSurface;
9
+ exports.getMachineSurface = getMachineSurface;
10
+ let surface = null;
11
+ function registerMachineSurface(next) {
12
+ surface = next;
13
+ }
14
+ function getMachineSurface() {
15
+ return surface;
16
+ }
@@ -128,6 +128,7 @@ router.get('/download/{*filePath}', auth_1.requireBuilder, async (req, res) => {
128
128
  * POST /api/file-browser/upload
129
129
  * Upload a file to storage.
130
130
  * Query: ?path=images/photo.png (target path including filename)
131
+ * &sha256=<hex> (optional; the upload is refused with 422 when the bytes differ)
131
132
  * Body: raw file bytes (Content-Type should match the file type)
132
133
  */
133
134
  router.post('/upload', auth_1.requireBuilder, async (req, res) => {
@@ -146,7 +147,8 @@ router.post('/upload', auth_1.requireBuilder, async (req, res) => {
146
147
  res.status(400).json({ error: 'Empty file body' });
147
148
  return;
148
149
  }
149
- const result = await api.uploadFile({ path: targetPath, buffer });
150
+ const sha256 = typeof req.query.sha256 === 'string' ? req.query.sha256 : undefined;
151
+ const result = await api.uploadFile({ path: targetPath, buffer, sha256 });
150
152
  res.status(result.status).json(result.data ?? { error: result.error });
151
153
  }
152
154
  catch (err) {
@@ -40,6 +40,7 @@ const nats_credentials_1 = __importDefault(require("./nats-credentials"));
40
40
  const scan_codes_1 = __importDefault(require("./scan-codes"));
41
41
  const domain_1 = __importDefault(require("./domain"));
42
42
  const announcements_1 = __importDefault(require("./announcements"));
43
+ const machines_1 = __importDefault(require("./machines"));
43
44
  const router = (0, http_1.Router)();
44
45
  // Public routes (no auth required — they handle their own auth)
45
46
  router.use('/auth', auth_2.default);
@@ -80,6 +81,7 @@ router.use('/topics', topics_1.default);
80
81
  router.use('/scan-codes', scan_codes_1.default);
81
82
  router.use('/domain', domain_1.default);
82
83
  router.use('/announcements', announcements_1.default);
84
+ router.use('/machines', machines_1.default);
83
85
  const overview_1 = __importDefault(require("./overview"));
84
86
  router.use('/overview', overview_1.default);
85
87
  const diagnostics_1 = __importDefault(require("./diagnostics"));
@@ -74,8 +74,8 @@ router.get('/entries', async (req, res) => {
74
74
  /**
75
75
  * GET /api/knowledge/entry
76
76
  * Get a single knowledge entry — the live edition, or an immutable snapshot
77
- * when ?version=N is present.
78
- * Query: ?domain=...&key=...&version=N
77
+ * when ?version=N (or ?version=<label>) is present.
78
+ * Query: ?domain=...&key=...&version=N|label
79
79
  */
80
80
  router.get('/entry', async (req, res) => {
81
81
  const domain = req.query.domain;
@@ -85,9 +85,10 @@ router.get('/entry', async (req, res) => {
85
85
  return;
86
86
  }
87
87
  if (req.query.version !== undefined) {
88
- const version = Number(req.query.version);
89
- if (!Number.isInteger(version) || version < 1) {
90
- res.status(400).json({ error: 'version must be a positive integer' });
88
+ const raw = String(req.query.version);
89
+ const version = /^[1-9][0-9]*$/.test(raw) ? Number(raw) : raw;
90
+ if (version === '' || version === 'current') {
91
+ res.status(400).json({ error: 'version must be a positive integer or an edition label' });
91
92
  return;
92
93
  }
93
94
  const result = await api.getEntryVersion({ domain, key, version });
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -0,0 +1,253 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const http_1 = require("../lib/http");
37
+ const escalationsApi = __importStar(require("../api/escalations"));
38
+ const auth_1 = require("../modules/auth");
39
+ const machines_1 = require("../modules/machines");
40
+ const commands_1 = require("../services/machines/commands");
41
+ const registry_1 = require("../services/machines/registry");
42
+ const registry_sync_1 = require("../services/machines/registry-sync");
43
+ const line_index_1 = require("../services/machines/line-index");
44
+ const topics_1 = require("../lib/machines/protocol/topics");
45
+ const browser_view_1 = require("../lib/events/browser-view");
46
+ const wire_window_1 = require("../services/machines/gateway/wire-window");
47
+ const router = (0, http_1.Router)();
48
+ /**
49
+ * The machine surface for the dashboard's Lines view. Reads and the dry run
50
+ * take the ops tier (superadmin, admin type, or engineer); declaring and
51
+ * retiring a line takes an administrator. A command is a row parked on the
52
+ * machine's role as the caller, so that role's write access decides, exactly
53
+ * as it does for any row created through the API.
54
+ */
55
+ const NO_LINES = 'no machine lines are declared';
56
+ const NOT_LEADING = 'this replica is not leading the line';
57
+ function lineOf(req) {
58
+ const surface = (0, machines_1.getMachineSurface)();
59
+ const siteId = String(req.params.siteId);
60
+ const lineId = String(req.params.lineId);
61
+ const line = surface?.findLine(siteId, lineId);
62
+ return { surface, siteId, lineId, line };
63
+ }
64
+ const SORTS = new Set(['attention', 'site', 'updated']);
65
+ /** The longest search a person types; anything past it is cut, never an error. */
66
+ const QUERY_MAX_CHARS = 200;
67
+ function queryString(v) {
68
+ return typeof v === 'string' && v.trim() ? v.trim().slice(0, QUERY_MAX_CHARS) : undefined;
69
+ }
70
+ /** The line a path names, when both tokens could name a line at all. */
71
+ function pathLine(req) {
72
+ const siteId = req.params.siteId;
73
+ const lineId = req.params.lineId;
74
+ return (0, topics_1.isTopicLevel)(siteId) && (0, topics_1.isTopicLevel)(lineId) ? { siteId, lineId } : null;
75
+ }
76
+ function queryBoolean(v) {
77
+ return v === 'true' ? true : v === 'false' ? false : undefined;
78
+ }
79
+ function queryInt(v) {
80
+ const n = typeof v === 'string' ? Number(v) : NaN;
81
+ return Number.isFinite(n) ? n : undefined;
82
+ }
83
+ router.get('/lines', auth_1.requireRoleManager, async (req, res) => {
84
+ const surface = (0, machines_1.getMachineSurface)();
85
+ if (!surface) {
86
+ res.status(404).json({ error: NO_LINES });
87
+ return;
88
+ }
89
+ const sort = queryString(req.query.sort);
90
+ if (sort && !SORTS.has(sort)) {
91
+ res.status(400).json({ error: `sort must be one of ${[...SORTS].join(', ')}` });
92
+ return;
93
+ }
94
+ const query = {
95
+ q: queryString(req.query.q), site: queryString(req.query.site), attention: queryBoolean(req.query.attention),
96
+ sort: sort, limit: queryInt(req.query.limit), offset: queryInt(req.query.offset),
97
+ };
98
+ const [page, sites] = await Promise.all([(0, registry_1.listLines)(query), (0, registry_1.listSites)()]);
99
+ const body = {
100
+ lines: page.lines.map((record) => (0, line_index_1.toLineIndexRow)(surface, record)),
101
+ total: page.total, sites, limit: page.limit, offset: page.offset,
102
+ };
103
+ res.status(200).json(body);
104
+ });
105
+ router.put('/lines/:siteId/:lineId', auth_1.requireAdmin, async (req, res) => {
106
+ const surface = (0, machines_1.getMachineSurface)();
107
+ if (!surface) {
108
+ res.status(404).json({ error: NO_LINES });
109
+ return;
110
+ }
111
+ const named = pathLine(req);
112
+ if (!named) {
113
+ res.status(400).json({ error: 'siteId and lineId must be topic levels' });
114
+ return;
115
+ }
116
+ const { siteId, lineId } = named;
117
+ const definition = req.body?.definition;
118
+ if (!definition || typeof definition !== 'object' || Array.isArray(definition)) {
119
+ res.status(400).json({ error: 'definition is required' });
120
+ return;
121
+ }
122
+ if (definition.siteId !== siteId || definition.lineId !== lineId) {
123
+ res.status(400).json({ error: `definition must be for ${siteId}/${lineId}` });
124
+ return;
125
+ }
126
+ const version = req.body?.version;
127
+ if (version !== undefined && !(Number.isInteger(version) && version >= 1)) {
128
+ res.status(400).json({ error: 'version must be a whole number of at least 1' });
129
+ return;
130
+ }
131
+ try {
132
+ const record = await (0, registry_sync_1.declareLine)(surface, definition, version);
133
+ const stored = (await (0, registry_1.getLineWithHealth)(siteId, lineId)) ?? { ...record, health: (0, line_index_1.emptyLineHealth)(record.definition.machines.length) };
134
+ res.status(200).json({ line: (0, line_index_1.toLineIndexRow)(surface, stored) });
135
+ }
136
+ catch (err) {
137
+ if (err instanceof registry_1.LineVersionConflict) {
138
+ res.status(409).json({ error: err.message });
139
+ return;
140
+ }
141
+ res.status(400).json({ error: err instanceof Error ? err.message : String(err) });
142
+ }
143
+ });
144
+ router.delete('/lines/:siteId/:lineId', auth_1.requireAdmin, async (req, res) => {
145
+ const surface = (0, machines_1.getMachineSurface)();
146
+ if (!surface) {
147
+ res.status(404).json({ error: NO_LINES });
148
+ return;
149
+ }
150
+ const named = pathLine(req);
151
+ if (!named) {
152
+ res.status(404).json({ error: 'no such line' });
153
+ return;
154
+ }
155
+ const { siteId, lineId } = named;
156
+ const record = await (0, registry_sync_1.retireLine)(surface, siteId, lineId);
157
+ if (!record) {
158
+ res.status(404).json({ error: `no line ${siteId}/${lineId}` });
159
+ return;
160
+ }
161
+ res.status(204).end();
162
+ });
163
+ router.get('/lines/:siteId/:lineId', auth_1.requireRoleManager, (req, res) => {
164
+ const { surface, siteId, lineId, line } = lineOf(req);
165
+ if (!surface || !line) {
166
+ res.status(404).json({ error: surface ? `no line ${siteId}/${lineId}` : NO_LINES });
167
+ return;
168
+ }
169
+ const body = {
170
+ ...(surface.describeLine(siteId, lineId) ?? { siteId, lineId, leading: false }),
171
+ summary: (0, line_index_1.lineSummaryOf)(surface, siteId, lineId, line),
172
+ };
173
+ res.status(200).json(body);
174
+ });
175
+ /** The event as this viewer reads it: builders see the payload, everyone else the record without it. */
176
+ function wireForViewer(event, builder) {
177
+ if (builder)
178
+ return event;
179
+ const { payload: _payload, ...rest } = event;
180
+ return rest;
181
+ }
182
+ router.get('/lines/:siteId/:lineId/wire', auth_1.requireRoleManager, async (req, res) => {
183
+ const { surface, siteId, lineId, line } = lineOf(req);
184
+ if (!surface || !line) {
185
+ res.status(404).json({ error: surface ? `no line ${siteId}/${lineId}` : NO_LINES });
186
+ return;
187
+ }
188
+ const { direction, kind } = req.query;
189
+ if (direction !== undefined && !(0, wire_window_1.isWireDirection)(direction)) {
190
+ res.status(400).json({ error: 'direction must be in or out' });
191
+ return;
192
+ }
193
+ if (kind !== undefined && !(0, wire_window_1.isWireKind)(kind)) {
194
+ res.status(400).json({ error: 'kind is not a wire kind' });
195
+ return;
196
+ }
197
+ const query = {
198
+ limit: queryInt(req.query.limit), machine: queryString(req.query.machine), since: queryString(req.query.since),
199
+ ...(direction !== undefined ? { direction } : {}), ...(kind !== undefined ? { kind } : {}),
200
+ };
201
+ const events = surface.wire(siteId, lineId, query);
202
+ const viewer = await (0, browser_view_1.viewerFor)(req.auth?.userId);
203
+ const body = { siteId, lineId, leading: events !== null, events: (events ?? []).map((e) => wireForViewer(e, viewer.builder)) };
204
+ res.status(200).json(body);
205
+ });
206
+ router.post('/lines/:siteId/:lineId/inspect', auth_1.requireRoleManager, (req, res) => {
207
+ const { surface, siteId, lineId, line } = lineOf(req);
208
+ if (!surface || !line) {
209
+ res.status(404).json({ error: surface ? `no line ${siteId}/${lineId}` : NO_LINES });
210
+ return;
211
+ }
212
+ const topic = req.body?.topic;
213
+ if (typeof topic !== 'string' || !topic) {
214
+ res.status(400).json({ error: 'topic is required' });
215
+ return;
216
+ }
217
+ const result = surface.inspect(siteId, lineId, { topic, payload: (0, line_index_1.wirePayloadOf)(req.body?.payload), retained: req.body?.retained === true });
218
+ if (!result) {
219
+ res.status(409).json({ error: NOT_LEADING });
220
+ return;
221
+ }
222
+ res.status(200).json(result);
223
+ });
224
+ router.post('/lines/:siteId/:lineId/machines/:machineId/commands', async (req, res) => {
225
+ const { surface, siteId, lineId, line } = lineOf(req);
226
+ if (!surface || !line) {
227
+ res.status(404).json({ error: surface ? `no line ${siteId}/${lineId}` : NO_LINES });
228
+ return;
229
+ }
230
+ const machineId = String(req.params.machineId);
231
+ if (!line.machines.some((m) => m.machineId === machineId)) {
232
+ res.status(404).json({ error: `no machine ${machineId} on ${siteId}/${lineId}` });
233
+ return;
234
+ }
235
+ const op = req.body?.op;
236
+ const ops = surface.commandOps(siteId, lineId);
237
+ if (typeof op !== 'string' || !ops.includes(op)) {
238
+ res.status(400).json({ error: `op must be one of ${ops.join(', ')}` });
239
+ return;
240
+ }
241
+ const args = req.body?.args;
242
+ if (args !== undefined && (!args || typeof args !== 'object' || Array.isArray(args))) {
243
+ res.status(400).json({ error: 'args must be an object' });
244
+ return;
245
+ }
246
+ const result = await escalationsApi.createEscalation((0, commands_1.commandRow)((0, commands_1.commandTarget)(line, machineId), op, args ?? {}), req.auth);
247
+ if (result.status !== 201) {
248
+ res.status(result.status).json({ error: result.error });
249
+ return;
250
+ }
251
+ res.status(201).json({ rowId: result.data.id });
252
+ });
253
+ exports.default = router;
@@ -2,15 +2,17 @@ export * from './lookup-cache';
2
2
  export * from './lookup-refs';
3
3
  export interface KnowledgeVersionMeta {
4
4
  version: number;
5
+ label: string | null;
5
6
  change_summary: string | null;
6
7
  created_at: string;
7
8
  is_current: boolean;
8
9
  }
9
- /** The immutable snapshot at (domain, key, version), uncached full shape. */
10
- export declare function getKnowledgeVersion(domain: string, key: string, version: number): Promise<{
10
+ /** The immutable snapshot at (domain, key, version), by number or by the edition's label; uncached full shape. */
11
+ export declare function getKnowledgeVersion(domain: string, key: string, version: number | string): Promise<{
11
12
  domain: string;
12
13
  key: string;
13
14
  version: number;
15
+ label: string | null;
14
16
  data: Record<string, unknown>;
15
17
  tags: string[];
16
18
  created_at: string;
@@ -22,19 +22,24 @@ exports.listKnowledgeVersions = listKnowledgeVersions;
22
22
  * writes produce, and resolves escalation lookup refs against them.
23
23
  */
24
24
  const db_1 = require("../../lib/db");
25
+ const lookup_cache_1 = require("./lookup-cache");
25
26
  const sql_1 = require("./sql");
26
27
  __exportStar(require("./lookup-cache"), exports);
27
28
  __exportStar(require("./lookup-refs"), exports);
28
- /** The immutable snapshot at (domain, key, version), uncached full shape. */
29
+ /** The immutable snapshot at (domain, key, version), by number or by the edition's label; uncached full shape. */
29
30
  async function getKnowledgeVersion(domain, key, version) {
30
31
  const pool = (0, db_1.getPool)();
31
- const { rows } = await pool.query(sql_1.GET_KNOWLEDGE_VERSION, [domain, key, version]);
32
+ const number = typeof version === 'string' ? await (0, lookup_cache_1.editionOfLabel)(domain, key, version) : version;
33
+ if (number === null)
34
+ return null;
35
+ const { rows } = await pool.query(sql_1.GET_KNOWLEDGE_VERSION, [domain, key, number]);
32
36
  if (!rows[0])
33
37
  return null;
34
38
  return {
35
39
  domain: rows[0].domain,
36
40
  key: rows[0].key,
37
41
  version: rows[0].version,
42
+ label: rows[0].label ?? null,
38
43
  data: rows[0].data ?? {},
39
44
  tags: rows[0].tags ?? [],
40
45
  created_at: rows[0].created_at.toISOString(),
@@ -46,6 +51,7 @@ async function listKnowledgeVersions(domain, key) {
46
51
  const { rows } = await pool.query(sql_1.LIST_KNOWLEDGE_VERSIONS, [domain, key]);
47
52
  return rows.map((r) => ({
48
53
  version: r.version,
54
+ label: r.label ?? null,
49
55
  change_summary: r.change_summary ?? null,
50
56
  created_at: r.created_at.toISOString(),
51
57
  is_current: r.is_current === true,
@@ -10,6 +10,8 @@ export interface ResolvedLookup {
10
10
  version: number | null;
11
11
  /** The ref follows the newest edition rather than pinning one. */
12
12
  current?: true;
13
+ /** The ref pins an edition by this label. */
14
+ label?: string;
13
15
  as?: string;
14
16
  data: Record<string, unknown> | null;
15
17
  missing?: boolean;
@@ -25,6 +27,12 @@ export declare function resolveRefEdition(ref: EscalationLookupRef, asOf?: strin
25
27
  version: number;
26
28
  snapshot: KnowledgeSnapshot;
27
29
  } | null>;
30
+ /**
31
+ * The edition a label names, or, for a label that is a whole number no edition
32
+ * carries, that edition's number. Null when the label names nothing; that is
33
+ * never cached, so a label given later becomes visible.
34
+ */
35
+ export declare function editionOfLabel(domain: string, key: string, label: string): Promise<number | null>;
28
36
  /**
29
37
  * Resolve a metadata `lookups` array into the form-context `lookup` domain:
30
38
  * { [as ?? key]: data }. Returns null when there is nothing to resolve, so
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getKnowledgeSnapshot = getKnowledgeSnapshot;
4
4
  exports.resolveRefEdition = resolveRefEdition;
5
+ exports.editionOfLabel = editionOfLabel;
5
6
  exports.resolveLookupContext = resolveLookupContext;
6
7
  exports.resolveLookupRefs = resolveLookupRefs;
7
8
  /**
@@ -18,6 +19,8 @@ const sql_1 = require("./sql");
18
19
  const SNAPSHOT_CACHE_MAX_ENTRIES = 256;
19
20
  // Map preserves insertion order — delete+set on read keeps it LRU.
20
21
  const snapshotCache = new Map();
22
+ // A label names one edition for good, so the number it resolves to is kept too.
23
+ const labelCache = new Map();
21
24
  function remember(cacheKey, snapshot) {
22
25
  snapshotCache.set(cacheKey, snapshot);
23
26
  while (snapshotCache.size > SNAPSHOT_CACHE_MAX_ENTRIES) {
@@ -52,7 +55,9 @@ async function getKnowledgeSnapshot(domain, key, version) {
52
55
  */
53
56
  async function resolveRefEdition(ref, asOf) {
54
57
  if (!(0, escalation_1.isCurrentLookupRef)(ref)) {
55
- const version = ref.version;
58
+ const version = (0, escalation_1.isLabelLookupRef)(ref) ? await editionOfLabel(ref.domain, ref.key, ref.version) : ref.version;
59
+ if (version === null)
60
+ return null;
56
61
  const snapshot = await getKnowledgeSnapshot(ref.domain, ref.key, version);
57
62
  return snapshot ? { version, snapshot } : null;
58
63
  }
@@ -71,6 +76,26 @@ async function resolveRefEdition(ref, asOf) {
71
76
  remember(cacheKey, snapshot);
72
77
  return { version, snapshot };
73
78
  }
79
+ /**
80
+ * The edition a label names, or, for a label that is a whole number no edition
81
+ * carries, that edition's number. Null when the label names nothing; that is
82
+ * never cached, so a label given later becomes visible.
83
+ */
84
+ async function editionOfLabel(domain, key, label) {
85
+ const cacheKey = `${domain} ${key} #${label}`;
86
+ const hit = labelCache.get(cacheKey);
87
+ if (hit !== undefined)
88
+ return hit;
89
+ const { rows } = await (0, db_1.getPool)().query(sql_1.GET_KNOWLEDGE_VERSION_BY_LABEL, [domain, key, label]);
90
+ if (rows[0]) {
91
+ const version = Number(rows[0].version);
92
+ labelCache.set(cacheKey, version);
93
+ while (labelCache.size > SNAPSHOT_CACHE_MAX_ENTRIES)
94
+ labelCache.delete(labelCache.keys().next().value);
95
+ return version;
96
+ }
97
+ return /^[1-9][0-9]*$/.test(label) ? Number(label) : null;
98
+ }
74
99
  /** Structural check for one ref — malformed entries in stored metadata are skipped, not fatal. */
75
100
  function isLookupRef(ref) {
76
101
  if (!ref || typeof ref !== 'object')
@@ -78,7 +103,7 @@ function isLookupRef(ref) {
78
103
  const r = ref;
79
104
  return typeof r.domain === 'string' && r.domain.length > 0
80
105
  && typeof r.key === 'string' && r.key.length > 0
81
- && ((0, escalation_1.isCurrentLookupRef)(r) || (typeof r.version === 'number' && Number.isInteger(r.version) && r.version >= 1))
106
+ && ((0, escalation_1.isCurrentLookupRef)(r) || (0, escalation_1.isLabelLookupRef)(r) || (typeof r.version === 'number' && Number.isInteger(r.version) && r.version >= 1))
82
107
  && (r.as === undefined || (typeof r.as === 'string' && r.as.length > 0));
83
108
  }
84
109
  /**
@@ -112,12 +137,14 @@ async function resolveLookupRefs(refs, asOf) {
112
137
  if (!isLookupRef(ref))
113
138
  continue;
114
139
  const current = (0, escalation_1.isCurrentLookupRef)(ref);
140
+ const label = (0, escalation_1.isLabelLookupRef)(ref) ? ref.version : undefined;
115
141
  const edition = await resolveRefEdition(ref, asOf);
116
142
  resolved.push({
117
143
  domain: ref.domain,
118
144
  key: ref.key,
119
- version: edition?.version ?? (current ? null : ref.version),
145
+ version: edition?.version ?? (current || label !== undefined ? null : ref.version),
120
146
  ...(current ? { current: true } : {}),
147
+ ...(label !== undefined ? { label } : {}),
121
148
  ...(ref.as ? { as: ref.as } : {}),
122
149
  data: edition ? edition.snapshot.data : null,
123
150
  ...(edition ? {} : { missing: true }),