@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.
- package/README.md +9 -2
- package/build/api/settings.d.ts +4 -1
- package/build/api/settings.js +7 -1
- package/build/index.js +9 -4
- package/build/lib/db/config-lock.d.ts +10 -0
- package/build/lib/db/config-lock.js +28 -0
- package/build/lib/db/schemas/041_machine_lines.sql +26 -0
- package/build/lib/events/browser-view.js +8 -2
- package/build/lib/events/publish.d.ts +33 -0
- package/build/lib/events/publish.js +52 -1
- package/build/lib/machines/line.d.ts +4 -1
- package/build/lib/machines/line.js +18 -1
- package/build/lib/machines/protocol/codec.d.ts +8 -0
- package/build/lib/machines/protocol/codec.js +9 -0
- package/build/lib/machines/protocol/constants.d.ts +1 -1
- package/build/lib/machines/protocol/constants.js +1 -1
- package/build/lib/machines/protocol/contract.js +2 -2
- package/build/lib/machines/site/mosquitto-conf.d.ts +5 -4
- package/build/lib/machines/site/mosquitto-conf.js +31 -16
- package/build/lib/machines/site/site-conf.d.ts +9 -2
- package/build/lib/machines/site/site-conf.js +27 -8
- package/build/lib/machines/transport/callback-feed.d.ts +1 -0
- package/build/lib/machines/transport/callback-feed.js +4 -1
- package/build/lib/machines/transport/memory.d.ts +2 -0
- package/build/lib/machines/transport/memory.js +6 -0
- package/build/lib/machines/transport/mqtt-bus.d.ts +2 -0
- package/build/lib/machines/transport/mqtt-bus.js +4 -0
- package/build/lib/machines/transport/nats-bus.d.ts +1 -0
- package/build/lib/machines/transport/nats-bus.js +3 -0
- package/build/lib/machines/transport/nats-feed.d.ts +1 -0
- package/build/lib/machines/transport/nats-feed.js +4 -1
- package/build/lib/machines/transport/pubsub-feed.d.ts +1 -0
- package/build/lib/machines/transport/pubsub-feed.js +4 -1
- package/build/lib/machines/transport/stream-bus.d.ts +2 -0
- package/build/lib/machines/transport/stream-bus.js +5 -1
- package/build/modules/machines.d.ts +8 -0
- package/build/modules/machines.js +16 -0
- package/build/routes/index.js +2 -0
- package/build/routes/machines.d.ts +2 -0
- package/build/routes/machines.js +220 -0
- package/build/services/machines/commands.d.ts +5 -5
- package/build/services/machines/commands.js +3 -2
- package/build/services/machines/config.d.ts +2 -1
- package/build/services/machines/config.js +1 -1
- package/build/services/machines/contracts.d.ts +10 -0
- package/build/services/machines/gateway/actions.d.ts +1 -0
- package/build/services/machines/gateway/admission.d.ts +15 -3
- package/build/services/machines/gateway/admission.js +29 -14
- package/build/services/machines/gateway/dispatcher.d.ts +3 -0
- package/build/services/machines/gateway/dispatcher.js +12 -4
- package/build/services/machines/gateway/executor.d.ts +11 -2
- package/build/services/machines/gateway/executor.js +68 -29
- package/build/services/machines/gateway/gateway.d.ts +16 -1
- package/build/services/machines/gateway/gateway.js +55 -23
- package/build/services/machines/gateway/index.d.ts +3 -0
- package/build/services/machines/gateway/index.js +3 -0
- package/build/services/machines/gateway/inspect.d.ts +17 -0
- package/build/services/machines/gateway/inspect.js +68 -0
- package/build/services/machines/gateway/log.d.ts +8 -0
- package/build/services/machines/gateway/log.js +18 -0
- package/build/services/machines/gateway/pacing.js +1 -0
- package/build/services/machines/gateway/plan-escalation.js +8 -3
- package/build/services/machines/gateway/plan-machine.js +16 -6
- package/build/services/machines/gateway/project.d.ts +9 -0
- package/build/services/machines/gateway/project.js +55 -0
- package/build/services/machines/gateway/receipts.d.ts +3 -0
- package/build/services/machines/gateway/receipts.js +3 -1
- package/build/services/machines/gateway/reconcile.js +3 -3
- package/build/services/machines/gateway/registration.js +1 -1
- package/build/services/machines/gateway/reply-waiter.d.ts +6 -3
- package/build/services/machines/gateway/reply-waiter.js +37 -16
- package/build/services/machines/gateway/state.d.ts +29 -3
- package/build/services/machines/gateway/state.js +61 -7
- package/build/services/machines/gateway/wire.d.ts +58 -0
- package/build/services/machines/gateway/wire.js +171 -0
- package/build/services/machines/index.d.ts +3 -0
- package/build/services/machines/index.js +2 -0
- package/build/services/machines/line-index.d.ts +16 -0
- package/build/services/machines/line-index.js +39 -0
- package/build/services/machines/registry-sql.d.ts +31 -0
- package/build/services/machines/registry-sql.js +110 -0
- package/build/services/machines/registry-sync.d.ts +31 -0
- package/build/services/machines/registry-sync.js +81 -0
- package/build/services/machines/registry.d.ts +77 -0
- package/build/services/machines/registry.js +158 -0
- package/build/services/machines/rows.js +10 -1
- package/build/services/machines/surface.d.ts +45 -5
- package/build/services/machines/surface.js +95 -15
- package/build/start/apply-report.d.ts +1 -1
- package/build/start/apply-report.js +3 -25
- package/build/start/index.js +16 -4
- package/build/system/index.js +13 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +22 -22
- package/build/system/mcp-servers/human-queue-schemas.d.ts +7 -7
- package/build/system/mcp-servers/machines-schemas.d.ts +35 -0
- package/build/system/mcp-servers/machines-schemas.js +35 -0
- package/build/system/mcp-servers/machines.d.ts +20 -0
- package/build/system/mcp-servers/machines.js +154 -0
- package/build/system/seed/tool-manifests-machines.d.ts +2 -0
- package/build/system/seed/tool-manifests-machines.js +88 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/events.d.ts +6 -1
- package/build/types/index.d.ts +1 -0
- package/build/types/machines-view.d.ts +159 -0
- package/build/types/machines-view.js +7 -0
- package/build/types/machines.d.ts +4 -0
- package/dashboard/dist/assets/{AdminDashboard-DlItqxFS.js → AdminDashboard-Bm7VG65H.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-DlItqxFS.js.map → AdminDashboard-Bm7VG65H.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-BUmT4a7n.js → AgentConfigPage-aJF7Sdbc.js} +6 -6
- package/dashboard/dist/assets/{AgentConfigPage-BUmT4a7n.js.map → AgentConfigPage-aJF7Sdbc.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-Cww8rlBi.js → AgentDetailPage-GwwghhxT.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-Cww8rlBi.js.map → AgentDetailPage-GwwghhxT.js.map} +1 -1
- package/dashboard/dist/assets/AgentsPage-DVvCzZyg.js +2 -0
- package/dashboard/dist/assets/{AgentsPage-C9UuUKhr.js.map → AgentsPage-DVvCzZyg.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-Cxmcji_K.js +2 -0
- package/dashboard/dist/assets/{AvailableEscalationsPage-DrvfXz70.js.map → AvailableEscalationsPage-Cxmcji_K.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-CDq9XRMp.js → BotPicker-CofRxk4L.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-CDq9XRMp.js.map → BotPicker-CofRxk4L.js.map} +1 -1
- package/dashboard/dist/assets/{BulkAssignModal-jsvqtrEA.js → BulkAssignModal-BARWuz4L.js} +2 -2
- package/dashboard/dist/assets/{BulkAssignModal-jsvqtrEA.js.map → BulkAssignModal-BARWuz4L.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-CSCrI6B1.js → CapabilitiesPage-BJAWVNEx.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-CSCrI6B1.js.map → CapabilitiesPage-BJAWVNEx.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-uD9mn-CQ.js → CollapsibleSection-CtgoaG75.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-uD9mn-CQ.js.map → CollapsibleSection-CtgoaG75.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-BRmx2hA4.js → ConfirmDeleteModal-BYXXBWs6.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-BRmx2hA4.js.map → ConfirmDeleteModal-BYXXBWs6.js.map} +1 -1
- package/dashboard/dist/assets/{ConnectedAppsPage-DlMzE5a-.js → ConnectedAppsPage-D0JkzWa7.js} +2 -2
- package/dashboard/dist/assets/{ConnectedAppsPage-DlMzE5a-.js.map → ConnectedAppsPage-D0JkzWa7.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-sRuM4eM5.js → CountdownTimer-BcFxdZYN.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-sRuM4eM5.js.map → CountdownTimer-BcFxdZYN.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-bLYydwqa.js → CredentialsPage-DPSY20rV.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-bLYydwqa.js.map → CredentialsPage-DPSY20rV.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-D_ATDL2N.js → CronLabel-Dg_Oew_Y.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-D_ATDL2N.js.map → CronLabel-Dg_Oew_Y.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-u1JGfR9G.js → DropZone-Cl_Flb16.js} +2 -2
- package/dashboard/dist/assets/{DropZone-u1JGfR9G.js.map → DropZone-Cl_Flb16.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-groSMfqB.js → ElapsedCell-Dm3G5fK2.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-groSMfqB.js.map → ElapsedCell-Dm3G5fK2.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-D-F3_A9m.js → EntityTimelinePanel-CrEEP04e.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-D-F3_A9m.js.map → EntityTimelinePanel-CrEEP04e.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-Bad6Jrmr.js → EscalationListSchemaPage-wOInXcjs.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-Bad6Jrmr.js.map → EscalationListSchemaPage-wOInXcjs.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-BKi_npI9.js → EscalationSchemaPage-CrIj_g9d.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-BKi_npI9.js.map → EscalationSchemaPage-CrIj_g9d.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTimeline-DQUUm3b1.js → EscalationTimeline-CeAsl5IT.js} +2 -2
- package/dashboard/dist/assets/{EscalationTimeline-DQUUm3b1.js.map → EscalationTimeline-CeAsl5IT.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTitleSelect-3mhXh77a.js → EscalationTitleSelect-D8qpCYiy.js} +2 -2
- package/dashboard/dist/assets/{EscalationTitleSelect-3mhXh77a.js.map → EscalationTitleSelect-D8qpCYiy.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-Qaov-uML.js → EscalationsOverview-CvaqVPsr.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-Qaov-uML.js.map → EscalationsOverview-CvaqVPsr.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-V4RF_n58.js → EventTable-Be0JuEl6.js} +2 -2
- package/dashboard/dist/assets/{EventTable-V4RF_n58.js.map → EventTable-Be0JuEl6.js.map} +1 -1
- package/dashboard/dist/assets/FilterBar-BVyAjIgv.js +2 -0
- package/dashboard/dist/assets/FilterBar-BVyAjIgv.js.map +1 -0
- package/dashboard/dist/assets/{GraphInvokePage-Djslhf96.js → GraphInvokePage-D_QigJeD.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-Djslhf96.js.map → GraphInvokePage-D_QigJeD.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-EjcNxlKx.js → HomePage-C1haeuNy.js} +2 -2
- package/dashboard/dist/assets/{HomePage-EjcNxlKx.js.map → HomePage-C1haeuNy.js.map} +1 -1
- package/dashboard/dist/assets/LinePage-CWD5pv1g.js +5 -0
- package/dashboard/dist/assets/LinePage-CWD5pv1g.js.map +1 -0
- package/dashboard/dist/assets/LinesPage-NqChsKcO.js +3 -0
- package/dashboard/dist/assets/LinesPage-NqChsKcO.js.map +1 -0
- package/dashboard/dist/assets/{ListToolbar-RrEAePOX.js → ListToolbar-BZCNrTh6.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-RrEAePOX.js.map → ListToolbar-BZCNrTh6.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-8gqiL3Vj.js → McpOverview-yJTYnh1z.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-8gqiL3Vj.js.map → McpOverview-yJTYnh1z.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-COyn6Ak5.js → McpQueryDetailPage-ChuLpJ4u.js} +3 -3
- package/dashboard/dist/assets/{McpQueryDetailPage-COyn6Ak5.js.map → McpQueryDetailPage-ChuLpJ4u.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-Dj6Qj72w.js → McpQueryPage-9S-v9soF.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-Dj6Qj72w.js.map → McpQueryPage-9S-v9soF.js.map} +1 -1
- package/dashboard/dist/assets/McpRunDetailPage-BhrcfxD5.js +2 -0
- package/dashboard/dist/assets/{McpRunDetailPage-80fQn9iX.js.map → McpRunDetailPage-BhrcfxD5.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-DaSsI-EM.js → McpRunsPage-C5_i8_Zx.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-DaSsI-EM.js.map → McpRunsPage-C5_i8_Zx.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-C5epAgq6.js → NamespacePill-OTZD2hzt.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-C5epAgq6.js.map → NamespacePill-OTZD2hzt.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-BSu1o2gB.js → OperationsPage-C03CeU5P.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-BSu1o2gB.js.map → OperationsPage-C03CeU5P.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-HFI4WGIV.js → OperatorDashboard-BzC134Jt.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-HFI4WGIV.js.map → OperatorDashboard-BzC134Jt.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-BSWIspNB.js → PageHeader-Hx8APPwE.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-BSWIspNB.js.map → PageHeader-Hx8APPwE.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-DDjopQ-k.js → PageHeaderWithStats-BEQYYBJv.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-DDjopQ-k.js.map → PageHeaderWithStats-BEQYYBJv.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-D0qlBuGi.js → PersonaDetailPage-D0mY9L6j.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-D0qlBuGi.js.map → PersonaDetailPage-D0mY9L6j.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-BJClu-5H.js → PersonasPage-FFlm5Eug.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-BJClu-5H.js.map → PersonasPage-FFlm5Eug.js.map} +1 -1
- package/dashboard/dist/assets/{PortalPage-CucNZn_w.js → PortalPage-Cpc25uO-.js} +2 -2
- package/dashboard/dist/assets/{PortalPage-CucNZn_w.js.map → PortalPage-Cpc25uO-.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-B9wMw0RV.js → ProcessDetailPage-Di2J7KwY.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-B9wMw0RV.js.map → ProcessDetailPage-Di2J7KwY.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-B6k4RpmR.js → ProcessesListPage-BEXwU3Z0.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-B6k4RpmR.js.map → ProcessesListPage-BEXwU3Z0.js.map} +1 -1
- package/dashboard/dist/assets/{ResolverForm-ZVufJ4G-.js → ResolverForm-2ks-3jXC.js} +6 -6
- package/dashboard/dist/assets/{ResolverForm-ZVufJ4G-.js.map → ResolverForm-2ks-3jXC.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-CTbq0mz4.js → RoleDetailPage-DqoOk0xc.js} +3 -3
- package/dashboard/dist/assets/{RoleDetailPage-CTbq0mz4.js.map → RoleDetailPage-DqoOk0xc.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-CoETDpjF.js → RolePill-R5_ctGFy.js} +2 -2
- package/dashboard/dist/assets/{RolePill-CoETDpjF.js.map → RolePill-R5_ctGFy.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-DBKxeam4.js → RolesPage-CPmo8Srr.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-DBKxeam4.js.map → RolesPage-CPmo8Srr.js.map} +1 -1
- package/dashboard/dist/assets/{RosterWidget-BkLAwEYB.js → RosterWidget-D2yovCKw.js} +2 -2
- package/dashboard/dist/assets/{RosterWidget-BkLAwEYB.js.map → RosterWidget-D2yovCKw.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-D2DC4iDf.js → RunAsSelector-CMv96On6.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-D2DC4iDf.js.map → RunAsSelector-CMv96On6.js.map} +1 -1
- package/dashboard/dist/assets/{ScanCodesPage-BlKleaT0.js → ScanCodesPage-CA6cTT-M.js} +2 -2
- package/dashboard/dist/assets/{ScanCodesPage-BlKleaT0.js.map → ScanCodesPage-CA6cTT-M.js.map} +1 -1
- package/dashboard/dist/assets/{ScanSchemeDetailPage-CTW6gofi.js → ScanSchemeDetailPage-DnctN5-H.js} +2 -2
- package/dashboard/dist/assets/{ScanSchemeDetailPage-CTW6gofi.js.map → ScanSchemeDetailPage-DnctN5-H.js.map} +1 -1
- package/dashboard/dist/assets/{ScanStationPage-DPRjSPyT.js → ScanStationPage-Bk8RwkKL.js} +2 -2
- package/dashboard/dist/assets/{ScanStationPage-DPRjSPyT.js.map → ScanStationPage-Bk8RwkKL.js.map} +1 -1
- package/dashboard/dist/assets/{ScopeBadge-CGsTtqFr.js → ScopeBadge-BXZ084nD.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-CGsTtqFr.js.map → ScopeBadge-BXZ084nD.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-CkmX3-Gu.js → StickyPagination-B0FSuUgs.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-CkmX3-Gu.js.map → StickyPagination-B0FSuUgs.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-Xm_n510s.js → StreamMessageDetail-BwZEvMpP.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-Xm_n510s.js.map → StreamMessageDetail-BwZEvMpP.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-De48aJan.js → SwimlaneTimeline-BDVQEaMw.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-De48aJan.js.map → SwimlaneTimeline-BDVQEaMw.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-S7UuVT_M.js → TagInput-DjPUDp2M.js} +2 -2
- package/dashboard/dist/assets/{TagInput-S7UuVT_M.js.map → TagInput-DjPUDp2M.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-HycMx3O9.js → TaskDetailPage-BOlv3iGB.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-HycMx3O9.js.map → TaskDetailPage-BOlv3iGB.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-BlHNpYiZ.js → TaskQueuePill-D-4Ynf3K.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-BlHNpYiZ.js.map → TaskQueuePill-D-4Ynf3K.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-OIcFFp1C.js → TasksListPage-e2teY0bD.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-OIcFFp1C.js.map → TasksListPage-e2teY0bD.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-OTC_55oZ.js → TimeAgo-Cvkpf_b3.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-OTC_55oZ.js.map → TimeAgo-Cvkpf_b3.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-CAwIj_AI.js → TimestampCell-B3btAV0N.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-CAwIj_AI.js.map → TimestampCell-B3btAV0N.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-D40uLM_v.js → ToolPill-GsKQ80CO.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-D40uLM_v.js.map → ToolPill-GsKQ80CO.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-8Vf6pfw4.js → ToolTestPanel-B03nebR7.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-8Vf6pfw4.js.map → ToolTestPanel-B03nebR7.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-iZW8rK9L.js → TopicDetailPage-DBRWne3O.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-iZW8rK9L.js.map → TopicDetailPage-DBRWne3O.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-CqiEcj-W.js → TopicsPage-CVe2M9HD.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-CqiEcj-W.js.map → TopicsPage-CVe2M9HD.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DQFjuoib.js → UserName-B_q_qp6V.js} +2 -2
- package/dashboard/dist/assets/{UserName-DQFjuoib.js.map → UserName-B_q_qp6V.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-Bh_dr9tM.js +2 -0
- package/dashboard/dist/assets/{WorkflowExecutionPage-Di08wCbs.js.map → WorkflowExecutionPage-Bh_dr9tM.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-DJLcK_CM.js → WorkflowPill-D7244fKp.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-DJLcK_CM.js.map → WorkflowPill-D7244fKp.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-Bb8HlrTJ.js → WorkflowsDashboard-DA6Mj7qH.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-Bb8HlrTJ.js.map → WorkflowsDashboard-DA6Mj7qH.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-Dta1kurk.js → WorkflowsOverview-B1kBLj-a.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-Dta1kurk.js.map → WorkflowsOverview-B1kBLj-a.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CfAajg68.js → YamlWorkflowDetailPage-6GJM8QIX.js} +8 -8
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CfAajg68.js.map → YamlWorkflowDetailPage-6GJM8QIX.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-CQFUzT4t.js → YamlWorkflowsPage-Bu811C7f.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-CQFUzT4t.js.map → YamlWorkflowsPage-Bu811C7f.js.map} +1 -1
- package/dashboard/dist/assets/{agents-PuftRTB2.js → agents-MPk_GnYz.js} +2 -2
- package/dashboard/dist/assets/{agents-PuftRTB2.js.map → agents-MPk_GnYz.js.map} +1 -1
- package/dashboard/dist/assets/{bots-BmEiPAWY.js → bots-2RihE2Tc.js} +2 -2
- package/dashboard/dist/assets/{bots-BmEiPAWY.js.map → bots-2RihE2Tc.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-CRii4Soa.js → capabilities-CC4iwJ1P.js} +2 -2
- package/dashboard/dist/assets/{capabilities-CRii4Soa.js.map → capabilities-CC4iwJ1P.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-DO_czaYo.js → controlplane-Bmkic8BH.js} +2 -2
- package/dashboard/dist/assets/{controlplane-DO_czaYo.js.map → controlplane-Bmkic8BH.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-CzCquCPh.js → escalation-columns-B0lhUUrQ.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-CzCquCPh.js.map → escalation-columns-B0lhUUrQ.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-items-Cy0ZgJqV.js → escalation-items-7WFpPo46.js} +2 -2
- package/dashboard/dist/assets/{escalation-items-Cy0ZgJqV.js.map → escalation-items-7WFpPo46.js.map} +1 -1
- package/dashboard/dist/assets/index-B9uv-euR.css +1 -0
- package/dashboard/dist/assets/{index-DhSCCpqM.js → index-B_XV1rwu.js} +2 -2
- package/dashboard/dist/assets/{index-DhSCCpqM.js.map → index-B_XV1rwu.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cx8xb-oU.js → index-C2CLfGwL.js} +2 -2
- package/dashboard/dist/assets/{index-Cx8xb-oU.js.map → index-C2CLfGwL.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cga5IW3D.js → index-C3AeFihz.js} +2 -2
- package/dashboard/dist/assets/{index-Cga5IW3D.js.map → index-C3AeFihz.js.map} +1 -1
- package/dashboard/dist/assets/{index-DiaRlFYI.js → index-CBri8fYM.js} +2 -2
- package/dashboard/dist/assets/{index-DiaRlFYI.js.map → index-CBri8fYM.js.map} +1 -1
- package/dashboard/dist/assets/{index-CL_1VpGb.js → index-CRWsB7ZC.js} +2 -2
- package/dashboard/dist/assets/{index-CL_1VpGb.js.map → index-CRWsB7ZC.js.map} +1 -1
- package/dashboard/dist/assets/{index-XntldBd0.js → index-CTOv3G7a.js} +2 -2
- package/dashboard/dist/assets/{index-XntldBd0.js.map → index-CTOv3G7a.js.map} +1 -1
- package/dashboard/dist/assets/{index-CfP2nKRc.js → index-CcArGkzI.js} +3 -3
- package/dashboard/dist/assets/{index-CfP2nKRc.js.map → index-CcArGkzI.js.map} +1 -1
- package/dashboard/dist/assets/{index-Dz6R8-Dw.js → index-CkMHS-hG.js} +25 -25
- package/dashboard/dist/assets/index-CkMHS-hG.js.map +1 -0
- package/dashboard/dist/assets/index-CmsmwCyv.js +2 -0
- package/dashboard/dist/assets/{index-4YaDUcKd.js.map → index-CmsmwCyv.js.map} +1 -1
- package/dashboard/dist/assets/{index-2SM2_onB.js → index-CvJsvqIc.js} +2 -2
- package/dashboard/dist/assets/{index-2SM2_onB.js.map → index-CvJsvqIc.js.map} +1 -1
- package/dashboard/dist/assets/{index-Rwqrflm-.js → index-D-ilRyfy.js} +2 -2
- package/dashboard/dist/assets/{index-Rwqrflm-.js.map → index-D-ilRyfy.js.map} +1 -1
- package/dashboard/dist/assets/{index-CZ7A3AcD.js → index-DSUtfDXx.js} +2 -2
- package/dashboard/dist/assets/{index-CZ7A3AcD.js.map → index-DSUtfDXx.js.map} +1 -1
- package/dashboard/dist/assets/{index-jL2K6us4.js → index-Da6ycKyf.js} +2 -2
- package/dashboard/dist/assets/{index-jL2K6us4.js.map → index-Da6ycKyf.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-CeUqGPuo.js → knowledge-Bpbg20DC.js} +2 -2
- package/dashboard/dist/assets/{knowledge-CeUqGPuo.js.map → knowledge-Bpbg20DC.js.map} +1 -1
- package/dashboard/dist/assets/machines-BqOZZU-3.js +2 -0
- package/dashboard/dist/assets/machines-BqOZZU-3.js.map +1 -0
- package/dashboard/dist/assets/{mcp-Cx96NTeD.js → mcp-CmcUXYce.js} +2 -2
- package/dashboard/dist/assets/{mcp-Cx96NTeD.js.map → mcp-CmcUXYce.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-XAzWl0gm.js → mcp-query-C8buQxN9.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-XAzWl0gm.js.map → mcp-query-C8buQxN9.js.map} +1 -1
- package/dashboard/dist/assets/{personas--4kjwyOw.js → personas-C2n5oDmY.js} +2 -2
- package/dashboard/dist/assets/{personas--4kjwyOw.js.map → personas-C2n5oDmY.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-PgkwvG7f.js → pipelines-RKpSkFz7.js} +2 -2
- package/dashboard/dist/assets/{pipelines-PgkwvG7f.js.map → pipelines-RKpSkFz7.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-CcYxdBa3.js → tasks-Dab4hExW.js} +2 -2
- package/dashboard/dist/assets/{tasks-CcYxdBa3.js.map → tasks-Dab4hExW.js.map} +1 -1
- package/dashboard/dist/assets/{topics-_lik7cNY.js → topics-FTMNP7r3.js} +2 -2
- package/dashboard/dist/assets/{topics-_lik7cNY.js.map → topics-FTMNP7r3.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-Bm_AoxVx.js → useDebouncedValue-B_1u1YIk.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-Bm_AoxVx.js.map → useDebouncedValue-B_1u1YIk.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-DgXXKdx5.js → useNamespace-HUeAI7Qb.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-DgXXKdx5.js.map → useNamespace-HUeAI7Qb.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-Dj2qtGSd.js → useYamlActivityEvents-Cax54qHH.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-Dj2qtGSd.js.map → useYamlActivityEvents-Cax54qHH.js.map} +1 -1
- package/dashboard/dist/assets/{validate-FlXCBBT6.js → validate-DxOaV7QS.js} +2 -2
- package/dashboard/dist/assets/{validate-FlXCBBT6.js.map → validate-DxOaV7QS.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-DUYcKTjP.js → vendor-icons-fxBvvHBi.js} +187 -182
- package/dashboard/dist/assets/vendor-icons-fxBvvHBi.js.map +1 -0
- package/dashboard/dist/assets/{yaml-workflows-B0_JxRYQ.js → yaml-workflows-BgY1XHJx.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-B0_JxRYQ.js.map → yaml-workflows-BgY1XHJx.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/architecture.md +1 -0
- package/docs/code-owned-configuration.md +6 -0
- package/docs/dashboard.md +1 -0
- package/docs/events.md +34 -1
- package/docs/machines.md +93 -16
- package/docs/mcp.md +19 -0
- package/package.json +1 -1
- package/dashboard/dist/assets/AgentsPage-C9UuUKhr.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-DrvfXz70.js +0 -2
- package/dashboard/dist/assets/FilterBar-BygWrnB1.js +0 -2
- package/dashboard/dist/assets/FilterBar-BygWrnB1.js.map +0 -1
- package/dashboard/dist/assets/McpRunDetailPage-80fQn9iX.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-Di08wCbs.js +0 -2
- package/dashboard/dist/assets/index-4YaDUcKd.js +0 -2
- package/dashboard/dist/assets/index-CnU7Jjz3.css +0 -1
- package/dashboard/dist/assets/index-Dz6R8-Dw.js.map +0 -1
- 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
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
|
25
|
-
if (!
|
|
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
|
|
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
|
|
34
|
-
|
|
35
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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;
|