@hotmeshio/long-tail 0.22.2 → 0.22.3
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/build/api/escalations/lookups.d.ts +9 -2
- package/build/api/escalations/lookups.js +15 -3
- package/build/api/escalations/metadata.d.ts +2 -0
- package/build/api/escalations/metadata.js +9 -0
- package/build/api/scan-codes/locate.js +4 -0
- package/build/api/scan-codes/present.d.ts +1 -1
- package/build/api/scan-codes/present.js +43 -0
- package/build/api/scan-codes/verb-accumulate.js +5 -1
- package/build/api/scan-codes/verb-fill.js +4 -1
- package/build/api/scan-codes/verb-into-subject.d.ts +12 -0
- package/build/api/scan-codes/verb-into-subject.js +157 -0
- package/build/api/scan-codes/verbs-subject.d.ts +23 -4
- package/build/api/scan-codes/verbs-subject.js +32 -55
- package/build/api/scan-codes/verbs.d.ts +10 -8
- package/build/api/scan-codes/verbs.js +25 -16
- package/build/index.d.ts +1 -1
- package/build/index.js +3 -2
- package/build/sdk/index.d.ts +1 -0
- package/build/services/escalation/claim-asserted.d.ts +10 -0
- package/build/services/escalation/claim-asserted.js +64 -0
- package/build/services/escalation/facets.d.ts +3 -1
- package/build/services/escalation/facets.js +7 -3
- package/build/services/escalation/index.d.ts +1 -0
- package/build/services/escalation/index.js +3 -1
- package/build/services/knowledge/lookup-cache.d.ts +16 -4
- package/build/services/knowledge/lookup-cache.js +53 -20
- package/build/services/knowledge/lookup-refs.d.ts +3 -2
- package/build/services/knowledge/lookup-refs.js +6 -4
- package/build/services/knowledge/sql.d.ts +2 -0
- package/build/services/knowledge/sql.js +9 -1
- package/build/services/mcp/server-tools.js +1 -1
- package/build/services/orchestrator/condition.d.ts +13 -10
- package/build/services/orchestrator/condition.js +8 -6
- package/build/services/scan-code/index.d.ts +1 -1
- package/build/services/scan-code/index.js +2 -1
- package/build/services/scan-code/validate-facts.d.ts +5 -0
- package/build/services/scan-code/validate-facts.js +24 -0
- package/build/services/scan-code/validate-query.d.ts +8 -0
- package/build/services/scan-code/validate-query.js +36 -0
- package/build/services/scan-code/validate-subject.js +29 -2
- package/build/services/scan-code/validate.js +17 -8
- package/build/shared/scan-code/gtin.d.ts +6 -0
- package/build/shared/scan-code/gtin.js +13 -0
- package/build/shared/scan-code/index.d.ts +1 -1
- package/build/shared/scan-code/index.js +2 -1
- package/build/system/mcp-servers/admin/schemas.d.ts +185 -5
- package/build/system/mcp-servers/admin/schemas.js +16 -3
- package/build/system/seed/tool-manifests-admin.d.ts +202 -1
- package/build/system/seed/tool-manifests-admin.js +2 -2
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/escalation.d.ts +14 -8
- package/build/types/escalation.js +16 -7
- package/build/types/index.d.ts +3 -3
- package/build/types/index.js +3 -1
- package/build/types/scan-code/response.d.ts +5 -0
- package/build/types/scan-code/rule.d.ts +32 -2
- package/dashboard/dist/assets/{AdminDashboard-DBW12qQt.js → AdminDashboard-hI5-kKpL.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-DBW12qQt.js.map → AdminDashboard-hI5-kKpL.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-CmHv8U9M.js → AgentConfigPage-DetU4HZe.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-CmHv8U9M.js.map → AgentConfigPage-DetU4HZe.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-D1scIbz-.js → AgentDetailPage-DrGXo8KQ.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-D1scIbz-.js.map → AgentDetailPage-DrGXo8KQ.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-BA_ai9HJ.js → AgentsPage-D4md5BzM.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-BA_ai9HJ.js.map → AgentsPage-D4md5BzM.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-C2_5aEFW.js → AvailableEscalationsPage-B2bS2ZJy.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-C2_5aEFW.js.map → AvailableEscalationsPage-B2bS2ZJy.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-BZo4Kp4a.js → BotPicker-BXtey255.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-BZo4Kp4a.js.map → BotPicker-BXtey255.js.map} +1 -1
- package/dashboard/dist/assets/{BulkAssignModal-BFhyxY2T.js → BulkAssignModal-CSL_PeZv.js} +2 -2
- package/dashboard/dist/assets/{BulkAssignModal-BFhyxY2T.js.map → BulkAssignModal-CSL_PeZv.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-CvOX6vAc.js → CapabilitiesPage-5scufTHW.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-CvOX6vAc.js.map → CapabilitiesPage-5scufTHW.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-GCJsV9Oq.js → CollapsibleSection-DjjDGxP_.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-GCJsV9Oq.js.map → CollapsibleSection-DjjDGxP_.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-CAgYLcef.js → ConfirmDeleteModal-DJSmsHQM.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-CAgYLcef.js.map → ConfirmDeleteModal-DJSmsHQM.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-Dik2z0M_.js → CountdownTimer-C5ZRYPfF.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-Dik2z0M_.js.map → CountdownTimer-C5ZRYPfF.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-twd2xCOW.js → CredentialsPage-CV6e60yC.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-twd2xCOW.js.map → CredentialsPage-CV6e60yC.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-DdnIuudX.js → CronLabel-CnqhqW0B.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-DdnIuudX.js.map → CronLabel-CnqhqW0B.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-DCctVv5R.js → ElapsedCell-C1IOn-tj.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-DCctVv5R.js.map → ElapsedCell-C1IOn-tj.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-CMnskyWv.js → EntityTimelinePanel-Dz6Liig4.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-CMnskyWv.js.map → EntityTimelinePanel-Dz6Liig4.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-VfCn6WDb.js → EscalationListSchemaPage-bgdmLmrh.js} +2 -2
- package/dashboard/dist/assets/{EscalationListSchemaPage-VfCn6WDb.js.map → EscalationListSchemaPage-bgdmLmrh.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListView-CGQZxcC-.js → EscalationListView-CrlD3ZGt.js} +2 -2
- package/dashboard/dist/assets/{EscalationListView-CGQZxcC-.js.map → EscalationListView-CrlD3ZGt.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-BX0tx-PM.js → EscalationSchemaPage-dxXO_T3t.js} +2 -2
- package/dashboard/dist/assets/{EscalationSchemaPage-BX0tx-PM.js.map → EscalationSchemaPage-dxXO_T3t.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTimeline-DKoSM56J.js → EscalationTimeline-C3WQZQuM.js} +2 -2
- package/dashboard/dist/assets/{EscalationTimeline-DKoSM56J.js.map → EscalationTimeline-C3WQZQuM.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTitleSelect-DWGLBOmS.js → EscalationTitleSelect-CTtcETUO.js} +2 -2
- package/dashboard/dist/assets/{EscalationTitleSelect-DWGLBOmS.js.map → EscalationTitleSelect-CTtcETUO.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-C2XoguaA.js → EscalationsOverview-DAjZ7JY2.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-C2XoguaA.js.map → EscalationsOverview-DAjZ7JY2.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CBUWq7--.js → EventTable-B72DQP_v.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CBUWq7--.js.map → EventTable-B72DQP_v.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-8IdbleZ9.js → FilterBar-CCTaA_LH.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-8IdbleZ9.js.map → FilterBar-CCTaA_LH.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-CUvoPzsW.js → GraphInvokePage-CAsCgFo3.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-CUvoPzsW.js.map → GraphInvokePage-CAsCgFo3.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-BP7v9GLJ.js → HomePage-DseE_iSr.js} +2 -2
- package/dashboard/dist/assets/{HomePage-BP7v9GLJ.js.map → HomePage-DseE_iSr.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-Cnacuwoy.js → ListToolbar-1zdqnjW6.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-Cnacuwoy.js.map → ListToolbar-1zdqnjW6.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-C2JoNoDA.js → McpOverview-DS_JXDW5.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-C2JoNoDA.js.map → McpOverview-DS_JXDW5.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-C_nih0w-.js → McpQueryDetailPage-BeMUGcv3.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-C_nih0w-.js.map → McpQueryDetailPage-BeMUGcv3.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-U_wNXow2.js → McpQueryPage-CeiLO_LR.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-U_wNXow2.js.map → McpQueryPage-CeiLO_LR.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-DtKoJq6J.js → McpRunDetailPage-DYp1uZK2.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-DtKoJq6J.js.map → McpRunDetailPage-DYp1uZK2.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-CnYtfGhf.js → McpRunsPage-VeaDzcL4.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-CnYtfGhf.js.map → McpRunsPage-VeaDzcL4.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-C7hupIer.js → OperationsPage-DK2mgaXf.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-C7hupIer.js.map → OperationsPage-DK2mgaXf.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-fVuLn2D5.js → OperatorDashboard-BNjLF0f7.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-fVuLn2D5.js.map → OperatorDashboard-BNjLF0f7.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-C-4o8lPw.js → PersonaDetailPage-IQ2fZLa6.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-C-4o8lPw.js.map → PersonaDetailPage-IQ2fZLa6.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-BL1FwLmv.js → PersonasPage-DpGFEcU-.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-BL1FwLmv.js.map → PersonasPage-DpGFEcU-.js.map} +1 -1
- package/dashboard/dist/assets/{PortalPage-tJG5sgb1.js → PortalPage-D07xyvG_.js} +2 -2
- package/dashboard/dist/assets/{PortalPage-tJG5sgb1.js.map → PortalPage-D07xyvG_.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-Dz_jY4Yt.js → ProcessDetailPage-t8EEYSMk.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-Dz_jY4Yt.js.map → ProcessDetailPage-t8EEYSMk.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-Cbn9cter.js → ProcessesListPage-BDUXLFdb.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-Cbn9cter.js.map → ProcessesListPage-BDUXLFdb.js.map} +1 -1
- package/dashboard/dist/assets/{ResolverForm-Bk8iXQ6-.js → ResolverForm-BwWOYv_Z.js} +6 -6
- package/dashboard/dist/assets/ResolverForm-BwWOYv_Z.js.map +1 -0
- package/dashboard/dist/assets/{RoleDetailPage-owPi6gI9.js → RoleDetailPage-zMF3x2xi.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-owPi6gI9.js.map → RoleDetailPage-zMF3x2xi.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-NwmMvZFa.js → RolesPage-CEBp_PpL.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-NwmMvZFa.js.map → RolesPage-CEBp_PpL.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-tgEooTyU.js → RunAsSelector-CC_EHN3z.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-tgEooTyU.js.map → RunAsSelector-CC_EHN3z.js.map} +1 -1
- package/dashboard/dist/assets/{ScanCodesPage-CUv_8ic6.js → ScanCodesPage-DD4uU-jY.js} +2 -2
- package/dashboard/dist/assets/{ScanCodesPage-CUv_8ic6.js.map → ScanCodesPage-DD4uU-jY.js.map} +1 -1
- package/dashboard/dist/assets/ScanSchemeDetailPage-CUW8gYFh.js +2 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-CUW8gYFh.js.map +1 -0
- package/dashboard/dist/assets/ScanStationPage-DpO_ESuf.js +2 -0
- package/dashboard/dist/assets/ScanStationPage-DpO_ESuf.js.map +1 -0
- package/dashboard/dist/assets/{StickyPagination-CsTI_gvJ.js → StickyPagination-cNqSDm5f.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-CsTI_gvJ.js.map → StickyPagination-cNqSDm5f.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-auRlvjTh.js → StreamMessageDetail-C4oZqQdB.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-auRlvjTh.js.map → StreamMessageDetail-C4oZqQdB.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-BLoVHYAd.js → SwimlaneTimeline-BjBiV7GT.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-BLoVHYAd.js.map → SwimlaneTimeline-BjBiV7GT.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-BPsZ1bK_.js → TaskDetailPage-pO_AnVS1.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-BPsZ1bK_.js.map → TaskDetailPage-pO_AnVS1.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-BNGM74yT.js → TasksListPage-DKDHlWP7.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-BNGM74yT.js.map → TasksListPage-DKDHlWP7.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-BnAHXGK7.js → TimeAgo-D2qchUuJ.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-BnAHXGK7.js.map → TimeAgo-D2qchUuJ.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-J4yae6mc.js → TimestampCell-DeswZGGo.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-J4yae6mc.js.map → TimestampCell-DeswZGGo.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-BdzzgXDu.js → ToolTestPanel-DJh7PIUa.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-BdzzgXDu.js.map → ToolTestPanel-DJh7PIUa.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-DJKg8lb7.js → TopicDetailPage-CsgDJ4Z4.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-DJKg8lb7.js.map → TopicDetailPage-CsgDJ4Z4.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-DQV0WxG6.js → TopicsPage-tBRZDVDN.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-DQV0WxG6.js.map → TopicsPage-tBRZDVDN.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-Ct09nGh5.js → UserName-B-5JcDck.js} +2 -2
- package/dashboard/dist/assets/{UserName-Ct09nGh5.js.map → UserName-B-5JcDck.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-B5WJOsee.js → WorkflowExecutionPage-BPHVnhp6.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-B5WJOsee.js.map → WorkflowExecutionPage-BPHVnhp6.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-Hc87TRgD.js → WorkflowsDashboard-CxLlfZmY.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-Hc87TRgD.js.map → WorkflowsDashboard-CxLlfZmY.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-CJQbyOj-.js → WorkflowsOverview-C4az5rwp.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-CJQbyOj-.js.map → WorkflowsOverview-C4az5rwp.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BMeED677.js → YamlWorkflowDetailPage-BmhlAUFQ.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BMeED677.js.map → YamlWorkflowDetailPage-BmhlAUFQ.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BMMg0Id6.js → YamlWorkflowsPage-CSbG5o2V.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BMMg0Id6.js.map → YamlWorkflowsPage-CSbG5o2V.js.map} +1 -1
- package/dashboard/dist/assets/{agents-CdFkgFvg.js → agents-BohEn7vw.js} +2 -2
- package/dashboard/dist/assets/{agents-CdFkgFvg.js.map → agents-BohEn7vw.js.map} +1 -1
- package/dashboard/dist/assets/{bots-Mj3LHWWg.js → bots-BG2EO-Wi.js} +2 -2
- package/dashboard/dist/assets/{bots-Mj3LHWWg.js.map → bots-BG2EO-Wi.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-Dw1ObK2-.js → capabilities-CeFrBmYX.js} +2 -2
- package/dashboard/dist/assets/{capabilities-Dw1ObK2-.js.map → capabilities-CeFrBmYX.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-DcNE1APv.js → controlplane-Dhvt8l8F.js} +2 -2
- package/dashboard/dist/assets/{controlplane-DcNE1APv.js.map → controlplane-Dhvt8l8F.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-D364Trpy.js → escalation-columns-BWMNxImp.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-D364Trpy.js.map → escalation-columns-BWMNxImp.js.map} +1 -1
- package/dashboard/dist/assets/{index-DPStdq4T.js → index-Bd_dgyfJ.js} +2 -2
- package/dashboard/dist/assets/{index-DPStdq4T.js.map → index-Bd_dgyfJ.js.map} +1 -1
- package/dashboard/dist/assets/{index-B3veJ698.js → index-C8VlM2Oe.js} +2 -2
- package/dashboard/dist/assets/{index-B3veJ698.js.map → index-C8VlM2Oe.js.map} +1 -1
- package/dashboard/dist/assets/{index-BiVce3n0.js → index-CiqSVDga.js} +2 -2
- package/dashboard/dist/assets/{index-BiVce3n0.js.map → index-CiqSVDga.js.map} +1 -1
- package/dashboard/dist/assets/{index-DkcI4V_H.js → index-Cl_YXEdp.js} +2 -2
- package/dashboard/dist/assets/{index-DkcI4V_H.js.map → index-Cl_YXEdp.js.map} +1 -1
- package/dashboard/dist/assets/index-CtZWpy22.js +2 -0
- package/dashboard/dist/assets/index-CtZWpy22.js.map +1 -0
- package/dashboard/dist/assets/{index-Bq5XNEzD.js → index-D90D9y0J.js} +2 -2
- package/dashboard/dist/assets/{index-Bq5XNEzD.js.map → index-D90D9y0J.js.map} +1 -1
- package/dashboard/dist/assets/{index-eDm6cz0F.js → index-DABkM7s-.js} +2 -2
- package/dashboard/dist/assets/{index-eDm6cz0F.js.map → index-DABkM7s-.js.map} +1 -1
- package/dashboard/dist/assets/{index-WSm8bgE7.js → index-Dbwu51xm.js} +3 -3
- package/dashboard/dist/assets/{index-WSm8bgE7.js.map → index-Dbwu51xm.js.map} +1 -1
- package/dashboard/dist/assets/{index-Dyotfa_k.js → index-Dc3Om6G3.js} +2 -2
- package/dashboard/dist/assets/{index-Dyotfa_k.js.map → index-Dc3Om6G3.js.map} +1 -1
- package/dashboard/dist/assets/{index-BRGTmoYY.js → index-Dc_zWK23.js} +2 -2
- package/dashboard/dist/assets/{index-BRGTmoYY.js.map → index-Dc_zWK23.js.map} +1 -1
- package/dashboard/dist/assets/{index-MDD4JYtu.js → index-Y-bdW8vo.js} +2 -2
- package/dashboard/dist/assets/{index-MDD4JYtu.js.map → index-Y-bdW8vo.js.map} +1 -1
- package/dashboard/dist/assets/{index-Bd6-KmBE.js → index-dYKgd06u.js} +2 -2
- package/dashboard/dist/assets/{index-Bd6-KmBE.js.map → index-dYKgd06u.js.map} +1 -1
- package/dashboard/dist/assets/{index-BQeHJHYN.js → index-fUsx_gYx.js} +25 -25
- package/dashboard/dist/assets/index-fUsx_gYx.js.map +1 -0
- package/dashboard/dist/assets/{knowledge-Bafewjxk.js → knowledge-CCcTidNV.js} +2 -2
- package/dashboard/dist/assets/{knowledge-Bafewjxk.js.map → knowledge-CCcTidNV.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-vLIutbnc.js → mcp-CLA1z7Pg.js} +2 -2
- package/dashboard/dist/assets/{mcp-vLIutbnc.js.map → mcp-CLA1z7Pg.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-BzTtIG90.js → mcp-query-CWG0WMAs.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-BzTtIG90.js.map → mcp-query-CWG0WMAs.js.map} +1 -1
- package/dashboard/dist/assets/metadata-display-B7X5hGxG.js +2 -0
- package/dashboard/dist/assets/metadata-display-B7X5hGxG.js.map +1 -0
- package/dashboard/dist/assets/{personas-WD40EDS_.js → personas-8jURIzx6.js} +2 -2
- package/dashboard/dist/assets/{personas-WD40EDS_.js.map → personas-8jURIzx6.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-DFwULWs3.js → pipelines-hVVRAXqG.js} +2 -2
- package/dashboard/dist/assets/{pipelines-DFwULWs3.js.map → pipelines-hVVRAXqG.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-La_-WAUn.js → tasks-BE1O57Bf.js} +2 -2
- package/dashboard/dist/assets/{tasks-La_-WAUn.js.map → tasks-BE1O57Bf.js.map} +1 -1
- package/dashboard/dist/assets/{topics-CzYMlvqm.js → topics-Bg96Wp1r.js} +2 -2
- package/dashboard/dist/assets/{topics-CzYMlvqm.js.map → topics-Bg96Wp1r.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-C0FQyANW.js → useDebouncedValue-DmEveyEy.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-C0FQyANW.js.map → useDebouncedValue-DmEveyEy.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-WW_XjAb3.js → useNamespace-DHgkzIuL.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-WW_XjAb3.js.map → useNamespace-DHgkzIuL.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-B3YxPeFt.js → useYamlActivityEvents-RU0PvU8S.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-B3YxPeFt.js.map → useYamlActivityEvents-RU0PvU8S.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-COHOjdhF.js → yaml-workflows-DQWE9ijc.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-COHOjdhF.js.map → yaml-workflows-DQWE9ijc.js.map} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/docs/hitl/lookups.md +27 -18
- package/docs/hitl/x-lt-validation.md +1 -1
- package/docs/hitl/x-lt-widget.md +1 -1
- package/docs/hitl-guide.md +1 -1
- package/docs/scan-codes.md +86 -16
- package/package.json +1 -1
- package/dashboard/dist/assets/ResolverForm-Bk8iXQ6-.js.map +0 -1
- package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js +0 -2
- package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js.map +0 -1
- package/dashboard/dist/assets/ScanStationPage-B275l6r_.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-B275l6r_.js.map +0 -1
- package/dashboard/dist/assets/index-BQeHJHYN.js.map +0 -1
- package/dashboard/dist/assets/index-BmNAVd4s.js +0 -2
- package/dashboard/dist/assets/index-BmNAVd4s.js.map +0 -1
- package/dashboard/dist/assets/metadata-display-COo3mMCr.js +0 -2
- package/dashboard/dist/assets/metadata-display-COo3mMCr.js.map +0 -1
|
@@ -54,7 +54,8 @@ const hold_1 = require("./hold");
|
|
|
54
54
|
// ctx.auth is the effective actor: the badged person when a grant rode the
|
|
55
55
|
// request, otherwise the authenticated principal. Attribution and write
|
|
56
56
|
// scoping both derive from it, live, inside the escalation APIs.
|
|
57
|
-
|
|
57
|
+
/** Claims the scanned row; a presented choice passes the row it showed. */
|
|
58
|
+
async function claimStep(step, ctx, presentedId) {
|
|
58
59
|
const metadata = await (0, context_1.templated)(step, ctx, (tpl) => (0, context_1.interpolatedMetadata)(step, ctx, tpl));
|
|
59
60
|
if (metadata === null)
|
|
60
61
|
return null;
|
|
@@ -67,6 +68,7 @@ async function claimStep(step, ctx) {
|
|
|
67
68
|
durationMinutes: step.params?.durationMinutes,
|
|
68
69
|
metadata: { ...metadata, ...(0, context_1.provenance)(ctx) },
|
|
69
70
|
restrictRoles: step.query?.roles,
|
|
71
|
+
assertId: presentedId,
|
|
70
72
|
}, ctx.auth);
|
|
71
73
|
if (result.status === 404)
|
|
72
74
|
return null;
|
|
@@ -115,19 +117,19 @@ async function resolveStep(step, ctx, presentedId) {
|
|
|
115
117
|
?? (result.data.escalationId ? { id: result.data.escalationId } : undefined);
|
|
116
118
|
return (0, context_1.executed)(escalation, step);
|
|
117
119
|
}
|
|
118
|
-
async function escalateStep(step, ctx) {
|
|
120
|
+
async function escalateStep(step, ctx, presentedId) {
|
|
119
121
|
// Close the located escalation first when configured — the close doubles as
|
|
120
122
|
// the condition check AND the double-scan guard (second scan finds nothing
|
|
121
123
|
// to close and falls through).
|
|
122
124
|
if (step.params?.closeCurrent === 'resolve') {
|
|
123
|
-
const closed = await resolveStep({ ...step, params: { ...step.params, resolverPayload: step.params?.resolverPayload ?? {} } }, ctx);
|
|
125
|
+
const closed = await resolveStep({ ...step, params: { ...step.params, resolverPayload: step.params?.resolverPayload ?? {} } }, ctx, presentedId);
|
|
124
126
|
if (closed === null)
|
|
125
127
|
return null;
|
|
126
128
|
if (closed.data?.outcome !== types_1.SCAN_OUTCOMES.EXECUTED)
|
|
127
129
|
return closed;
|
|
128
130
|
}
|
|
129
131
|
else if (step.params?.closeCurrent === 'cancel') {
|
|
130
|
-
const cancelled = await cancelStep(step, ctx);
|
|
132
|
+
const cancelled = await cancelStep(step, ctx, presentedId);
|
|
131
133
|
if (cancelled === null)
|
|
132
134
|
return null;
|
|
133
135
|
if (cancelled.data?.outcome !== types_1.SCAN_OUTCOMES.EXECUTED)
|
|
@@ -152,9 +154,11 @@ async function escalateStep(step, ctx) {
|
|
|
152
154
|
return created;
|
|
153
155
|
return (0, context_1.executed)(created.data, step);
|
|
154
156
|
}
|
|
155
|
-
async function releaseStep(step, ctx) {
|
|
157
|
+
async function releaseStep(step, ctx, presentedId) {
|
|
156
158
|
// Locate the caller's own claim; release-by-id re-asserts the assignee
|
|
157
159
|
// inside the SDK, so a lost race resolves to 409, never a foreign release.
|
|
160
|
+
if (presentedId)
|
|
161
|
+
return releaseById(presentedId, step, ctx);
|
|
158
162
|
const scope = await (0, helpers_1.getEscalationReadScope)(ctx.auth.userId);
|
|
159
163
|
const readable = [...scope.allRoles, ...scope.selfRoles];
|
|
160
164
|
const roles = (0, metadata_1.restrictScopeRoles)(readable, scope.global, step.query?.roles);
|
|
@@ -169,23 +173,27 @@ async function releaseStep(step, ctx) {
|
|
|
169
173
|
});
|
|
170
174
|
if (escalations.length === 0)
|
|
171
175
|
return null;
|
|
176
|
+
return releaseById(escalations[0].id, step, ctx);
|
|
177
|
+
}
|
|
178
|
+
async function releaseById(id, step, ctx) {
|
|
172
179
|
const notPrimed = await (0, grant_1.spendGrant)(ctx);
|
|
173
180
|
if (notPrimed)
|
|
174
181
|
return notPrimed;
|
|
175
|
-
const result = await (0, claim_1.releaseEscalation)({ id
|
|
182
|
+
const result = await (0, claim_1.releaseEscalation)({ id }, ctx.auth);
|
|
176
183
|
if (result.status === 403)
|
|
177
184
|
return (0, context_1.forbidden)(result.error);
|
|
178
|
-
if (result.status === 409)
|
|
185
|
+
if (result.status === 409 || result.status === 404)
|
|
179
186
|
return (0, context_1.conflict)(result.error);
|
|
180
187
|
if (result.status !== 200)
|
|
181
188
|
return result;
|
|
182
189
|
return (0, context_1.executed)(result.data.escalation, step);
|
|
183
190
|
}
|
|
184
191
|
/**
|
|
185
|
-
* Dispatch one CHOICE verb against an already-presented row.
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
192
|
+
* Dispatch one CHOICE verb against an already-presented row. Every verb that
|
|
193
|
+
* writes the row writes that row by id, so a code shared by several rows
|
|
194
|
+
* never moves the write elsewhere. Unlike the step walk (where a miss falls
|
|
195
|
+
* through to the next step), a miss answers with the truth: FORBIDDEN when
|
|
196
|
+
* the actor holds no write scope here, CONFLICT when a concurrent actor won.
|
|
189
197
|
*/
|
|
190
198
|
async function dispatchChoiceVerb(step, ctx, row) {
|
|
191
199
|
switch (step.verb) {
|
|
@@ -195,15 +203,15 @@ async function dispatchChoiceVerb(step, ctx, row) {
|
|
|
195
203
|
return (await (0, hold_1.holdStep)(step, ctx, row));
|
|
196
204
|
case types_1.SCAN_VERBS.CLAIM:
|
|
197
205
|
case types_1.SCAN_VERBS.CLAIM_SHOW_DETAIL:
|
|
198
|
-
return (await claimStep(step, ctx)) ?? (await missReason(step, ctx, 'the item is no longer claimable'));
|
|
206
|
+
return (await claimStep(step, ctx, row.id)) ?? (await missReason(step, ctx, 'the item is no longer claimable'));
|
|
199
207
|
case types_1.SCAN_VERBS.RESOLVE:
|
|
200
208
|
return (await resolveStep(step, ctx, row.id)) ?? (await missReason(step, ctx, 'the item is no longer resolvable'));
|
|
201
209
|
case types_1.SCAN_VERBS.ESCALATE:
|
|
202
|
-
return (await escalateStep(step, ctx)) ?? (await missReason(step, ctx, 'the item already moved on'));
|
|
210
|
+
return (await escalateStep(step, ctx, row.id)) ?? (await missReason(step, ctx, 'the item already moved on'));
|
|
203
211
|
case types_1.SCAN_VERBS.RELEASE:
|
|
204
|
-
return (await releaseStep(step, ctx)) ?? (0, context_1.conflict)('no claim of yours to release');
|
|
212
|
+
return (await releaseStep(step, ctx, row.id)) ?? (0, context_1.conflict)('no claim of yours to release');
|
|
205
213
|
case types_1.SCAN_VERBS.CANCEL:
|
|
206
|
-
return (await cancelStep(step, ctx)) ?? (await missReason(step, ctx, 'the item is no longer cancellable'));
|
|
214
|
+
return (await cancelStep(step, ctx, row.id)) ?? (await missReason(step, ctx, 'the item is no longer cancellable'));
|
|
207
215
|
default:
|
|
208
216
|
throw new Error(`unknown choice verb "${step.verb}"`);
|
|
209
217
|
}
|
|
@@ -218,7 +226,7 @@ async function missReason(step, ctx, raceMessage) {
|
|
|
218
226
|
}
|
|
219
227
|
return (0, context_1.conflict)(raceMessage);
|
|
220
228
|
}
|
|
221
|
-
async function cancelStep(step, ctx) {
|
|
229
|
+
async function cancelStep(step, ctx, presentedId) {
|
|
222
230
|
// Claim-as-lock: the atomic claim pins the row to this caller (or extends
|
|
223
231
|
// their claim), serializing concurrent double-scans before the cancel.
|
|
224
232
|
const notPrimed = await (0, grant_1.spendGrant)(ctx);
|
|
@@ -229,6 +237,7 @@ async function cancelStep(step, ctx) {
|
|
|
229
237
|
value: ctx.parsed.target,
|
|
230
238
|
metadata: (0, context_1.provenance)(ctx),
|
|
231
239
|
restrictRoles: step.query?.roles,
|
|
240
|
+
assertId: presentedId,
|
|
232
241
|
}, ctx.auth);
|
|
233
242
|
if (claimed.status === 404)
|
|
234
243
|
return null;
|
package/build/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export * as TaskService from './services/task';
|
|
|
12
12
|
export * as EscalationService from './services/escalation';
|
|
13
13
|
export * as ConfigService from './services/config';
|
|
14
14
|
export * as UserService from './services/user';
|
|
15
|
-
export { assertValidScheme as assertValidScanScheme, assertValidSteps as assertValidScanSteps, assertValidIdentityRule as assertValidScanIdentityRule, isValidGtin, normalizeGtin, type ScanSchemeInput, type ScanRuleInput, } from './services/scan-code';
|
|
15
|
+
export { assertValidScheme as assertValidScanScheme, assertValidSteps as assertValidScanSteps, assertValidIdentityRule as assertValidScanIdentityRule, isValidGtin, normalizeGtin, displayGtin, type ScanSchemeInput, type ScanRuleInput, } from './services/scan-code';
|
|
16
16
|
export * as TopicService from './services/topics';
|
|
17
17
|
export { seedSystemTopics, seedConfigTopics } from './services/topics/system-topics';
|
|
18
18
|
export { ltConfig } from './modules/ltconfig';
|
package/build/index.js
CHANGED
|
@@ -36,8 +36,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
};
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.
|
|
40
|
-
exports.LTExpressAdapter = exports.api = exports.KnowledgeApi = exports.resolveCredential = exports.mimeFromPath = exports.getStorageBackend = exports.listOAuthConnections = exports.getFreshAccessToken = exports.createClient = exports.CallbackEventAdapter = exports.builtinMcpServerFactories = exports.getSystemAgents = exports.getSystemWorkers = exports.registerMcpTool = exports.getToolContext = exports.getActivityIdentity = exports.McpEscalationStrategy = exports.DefaultEscalationStrategy = exports.escalationStrategyRegistry = exports.McpVisionServer = exports.McpTranslationServer = void 0;
|
|
39
|
+
exports.McpClient = exports.McpService = exports.BuiltInMcpAdapter = exports.mcpRegistry = exports.defaultMaintenanceConfig = exports.maintenanceRegistry = exports.PinoLoggerAdapter = exports.loggerRegistry = exports.HoneycombTelemetryAdapter = exports.telemetryRegistry = exports.publishKnowledgeEvent = exports.publishAgentEvent = exports.publishWorkflowEvent = exports.publishActivityEvent = exports.publishEscalationEvent = exports.publishTaskEvent = exports.publishMilestoneEvent = exports.SocketIOEventAdapter = exports.InMemoryEventAdapter = exports.NatsEventAdapter = exports.eventRegistry = exports.ltConfig = exports.seedConfigTopics = exports.seedSystemTopics = exports.TopicService = exports.displayGtin = exports.normalizeGtin = exports.isValidGtin = exports.assertValidScanIdentityRule = exports.assertValidScanSteps = exports.assertValidScanScheme = exports.UserService = exports.ConfigService = exports.EscalationService = exports.TaskService = exports.setAuthAdapter = exports.signToken = exports.requireAdmin = exports.requireAuth = exports.createAuthMiddleware = exports.JwtAuthAdapter = exports.conditionalAccumulator = exports.conditionLT = exports.conditional = exports.executeLT = exports.createLTActivityInterceptor = exports.createLTInterceptor = exports.registerLT = exports.midnightTheme = exports.start = void 0;
|
|
40
|
+
exports.LTExpressAdapter = exports.api = exports.KnowledgeApi = exports.resolveCredential = exports.mimeFromPath = exports.getStorageBackend = exports.listOAuthConnections = exports.getFreshAccessToken = exports.createClient = exports.CallbackEventAdapter = exports.builtinMcpServerFactories = exports.getSystemAgents = exports.getSystemWorkers = exports.registerMcpTool = exports.getToolContext = exports.getActivityIdentity = exports.McpEscalationStrategy = exports.DefaultEscalationStrategy = exports.escalationStrategyRegistry = exports.McpVisionServer = exports.McpTranslationServer = exports.McpServer = void 0;
|
|
41
41
|
const config_1 = require("./modules/config");
|
|
42
42
|
const logger_1 = require("./lib/logger");
|
|
43
43
|
const midnight_1 = require("./themes/midnight");
|
|
@@ -76,6 +76,7 @@ Object.defineProperty(exports, "assertValidScanSteps", { enumerable: true, get:
|
|
|
76
76
|
Object.defineProperty(exports, "assertValidScanIdentityRule", { enumerable: true, get: function () { return scan_code_1.assertValidIdentityRule; } });
|
|
77
77
|
Object.defineProperty(exports, "isValidGtin", { enumerable: true, get: function () { return scan_code_1.isValidGtin; } });
|
|
78
78
|
Object.defineProperty(exports, "normalizeGtin", { enumerable: true, get: function () { return scan_code_1.normalizeGtin; } });
|
|
79
|
+
Object.defineProperty(exports, "displayGtin", { enumerable: true, get: function () { return scan_code_1.displayGtin; } });
|
|
79
80
|
exports.TopicService = __importStar(require("./services/topics"));
|
|
80
81
|
var system_topics_1 = require("./services/topics/system-topics");
|
|
81
82
|
Object.defineProperty(exports, "seedSystemTopics", { enumerable: true, get: function () { return system_topics_1.seedSystemTopics; } });
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -213,6 +213,7 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
213
213
|
metadata?: Record<string, any>;
|
|
214
214
|
provisionIfAbsent?: import("../api/escalations/helpers").ProvisionIfAbsent;
|
|
215
215
|
restrictRoles?: string[];
|
|
216
|
+
assertId?: string;
|
|
216
217
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
217
218
|
resolveByMetadata: (input: {
|
|
218
219
|
key: string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ClaimResult } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Claims one named row, the same claim `claimByMetadata` makes on the row it
|
|
4
|
+
* picks: pending, the facet still matches, the role is allowed, and no live
|
|
5
|
+
* claim by someone else. One statement; a miss writes nothing.
|
|
6
|
+
* $1=filter $2=assignee $3=minutes $4=roles $5=metadata patch $6=id
|
|
7
|
+
*/
|
|
8
|
+
export declare const CLAIM_ASSERTED = "WITH target AS MATERIALIZED (\n SELECT id, assigned_to AS prior_assigned_to FROM public.hmsh_escalations\n WHERE id = $6\n AND metadata @> $1::jsonb\n AND ($4::text[] IS NULL OR role = ANY($4::text[]))\n AND status = 'pending'\n AND (assigned_to IS NULL OR assigned_until IS NULL OR assigned_until <= NOW() OR assigned_to = $2)\n FOR UPDATE SKIP LOCKED\n)\nUPDATE public.hmsh_escalations e\nSET assigned_to = $2,\n claimed_at = NOW(),\n claim_expires_at = NOW() + ($3 * INTERVAL '1 minute'),\n assigned_until = NOW() + ($3 * INTERVAL '1 minute'),\n metadata = CASE WHEN $5::jsonb IS NOT NULL\n THEN COALESCE(e.metadata, '{}'::jsonb) || $5::jsonb\n ELSE e.metadata END,\n updated_at = NOW()\nFROM target WHERE e.id = target.id\nRETURNING e.*, target.prior_assigned_to\n";
|
|
9
|
+
/** Claim the row `id` when it still carries `key = value`; null when it does not. */
|
|
10
|
+
export declare function claimAssertedByMetadata(id: string, key: string, value: string, userId: string, durationMinutes?: number, metadata?: Record<string, any>, allowedRoles?: string[] | null): Promise<ClaimResult | null>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLAIM_ASSERTED = void 0;
|
|
4
|
+
exports.claimAssertedByMetadata = claimAssertedByMetadata;
|
|
5
|
+
const db_1 = require("../../lib/db");
|
|
6
|
+
const escalation_wire_1 = require("../../lib/events/escalation-wire");
|
|
7
|
+
const uuid_1 = require("../../lib/uuid");
|
|
8
|
+
const client_1 = require("./client");
|
|
9
|
+
const crud_1 = require("./crud");
|
|
10
|
+
const map_1 = require("./map");
|
|
11
|
+
/**
|
|
12
|
+
* Claims one named row, the same claim `claimByMetadata` makes on the row it
|
|
13
|
+
* picks: pending, the facet still matches, the role is allowed, and no live
|
|
14
|
+
* claim by someone else. One statement; a miss writes nothing.
|
|
15
|
+
* $1=filter $2=assignee $3=minutes $4=roles $5=metadata patch $6=id
|
|
16
|
+
*/
|
|
17
|
+
exports.CLAIM_ASSERTED = `\
|
|
18
|
+
WITH target AS MATERIALIZED (
|
|
19
|
+
SELECT id, assigned_to AS prior_assigned_to FROM public.hmsh_escalations
|
|
20
|
+
WHERE id = $6
|
|
21
|
+
AND metadata @> $1::jsonb
|
|
22
|
+
AND ($4::text[] IS NULL OR role = ANY($4::text[]))
|
|
23
|
+
AND status = 'pending'
|
|
24
|
+
AND (assigned_to IS NULL OR assigned_until IS NULL OR assigned_until <= NOW() OR assigned_to = $2)
|
|
25
|
+
FOR UPDATE SKIP LOCKED
|
|
26
|
+
)
|
|
27
|
+
UPDATE public.hmsh_escalations e
|
|
28
|
+
SET assigned_to = $2,
|
|
29
|
+
claimed_at = NOW(),
|
|
30
|
+
claim_expires_at = NOW() + ($3 * INTERVAL '1 minute'),
|
|
31
|
+
assigned_until = NOW() + ($3 * INTERVAL '1 minute'),
|
|
32
|
+
metadata = CASE WHEN $5::jsonb IS NOT NULL
|
|
33
|
+
THEN COALESCE(e.metadata, '{}'::jsonb) || $5::jsonb
|
|
34
|
+
ELSE e.metadata END,
|
|
35
|
+
updated_at = NOW()
|
|
36
|
+
FROM target WHERE e.id = target.id
|
|
37
|
+
RETURNING e.*, target.prior_assigned_to
|
|
38
|
+
`;
|
|
39
|
+
/** Claim the row `id` when it still carries `key = value`; null when it does not. */
|
|
40
|
+
async function claimAssertedByMetadata(id, key, value, userId, durationMinutes = 30, metadata, allowedRoles) {
|
|
41
|
+
if (!(0, uuid_1.isUuid)(id))
|
|
42
|
+
return null;
|
|
43
|
+
await (0, client_1.ensureEscalationCompatView)();
|
|
44
|
+
const { rows } = await (0, db_1.getPool)().query(exports.CLAIM_ASSERTED, [
|
|
45
|
+
JSON.stringify({ [key]: value }), userId, durationMinutes,
|
|
46
|
+
allowedRoles ?? null, metadata ? JSON.stringify(metadata) : null, id,
|
|
47
|
+
]);
|
|
48
|
+
if (rows.length === 0)
|
|
49
|
+
return null;
|
|
50
|
+
const { prior_assigned_to: prior, ...entry } = rows[0];
|
|
51
|
+
const escalation = (0, map_1.toEscalationRecord)(entry);
|
|
52
|
+
(0, crud_1.publishEscalationChange)({
|
|
53
|
+
type: 'escalation.claimed',
|
|
54
|
+
source: 'service',
|
|
55
|
+
workflowId: escalation.workflow_id || '',
|
|
56
|
+
workflowName: escalation.workflow_type || '',
|
|
57
|
+
taskQueue: escalation.task_queue || '',
|
|
58
|
+
escalationId: escalation.id,
|
|
59
|
+
role: escalation.role,
|
|
60
|
+
status: 'claimed',
|
|
61
|
+
data: (0, escalation_wire_1.escalationEventData)(escalation),
|
|
62
|
+
});
|
|
63
|
+
return { escalation, isExtension: prior === userId };
|
|
64
|
+
}
|
|
@@ -2,7 +2,9 @@ import type { ClaimedGroup, FacetQuery, GroupSummary, LTEscalationRecord } from
|
|
|
2
2
|
/** Ensure the compat view + the origin_id index exist before the first query. */
|
|
3
3
|
export declare function ensureFacetReady(): Promise<void>;
|
|
4
4
|
/** Item-level faceted search — filter/sort over top-level columns and metadata facets. */
|
|
5
|
-
export declare function searchByFacets(query: FacetQuery
|
|
5
|
+
export declare function searchByFacets(query: FacetQuery, opts?: {
|
|
6
|
+
total?: boolean;
|
|
7
|
+
}): Promise<{
|
|
6
8
|
escalations: LTEscalationRecord[];
|
|
7
9
|
total: number;
|
|
8
10
|
}>;
|
|
@@ -45,7 +45,7 @@ function ensureFacetReady() {
|
|
|
45
45
|
}
|
|
46
46
|
// ── Reads ────────────────────────────────────────────────────────────────────
|
|
47
47
|
/** Item-level faceted search — filter/sort over top-level columns and metadata facets. */
|
|
48
|
-
async function searchByFacets(query) {
|
|
48
|
+
async function searchByFacets(query, opts = {}) {
|
|
49
49
|
await ensureFacetReady();
|
|
50
50
|
const pool = (0, db_1.getPool)();
|
|
51
51
|
const params = [];
|
|
@@ -55,9 +55,13 @@ async function searchByFacets(query) {
|
|
|
55
55
|
const offset = query.offset ?? 0;
|
|
56
56
|
const [rows, count] = await Promise.all([
|
|
57
57
|
pool.query(`SELECT * FROM public.lt_escalations WHERE ${where} ORDER BY ${order} LIMIT $${params.length + 1} OFFSET $${params.length + 2}`, [...params, limit, offset]),
|
|
58
|
-
|
|
58
|
+
// A caller that only picks among a few rows skips the count.
|
|
59
|
+
opts.total === false
|
|
60
|
+
? null
|
|
61
|
+
: pool.query(`SELECT count(*)::int AS total FROM public.lt_escalations WHERE ${where}`, params),
|
|
59
62
|
]);
|
|
60
|
-
|
|
63
|
+
const escalations = (0, map_1.toEscalationRecords)(rows.rows);
|
|
64
|
+
return { escalations, total: count ? count.rows[0]?.total ?? 0 : escalations.length };
|
|
61
65
|
}
|
|
62
66
|
/**
|
|
63
67
|
* Order-level view of the pond — what a batched dispatcher reads to page by
|
|
@@ -14,9 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.AnalyticsInputError = exports.resetAnalyticsCaches = exports.resolveEntitySystem = exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = exports.claimGroups = exports.countByFacets = exports.searchGroups = exports.searchByFacets = exports.ensureFacetReady = exports.ensureEscalationCompatView = void 0;
|
|
17
|
+
exports.AnalyticsInputError = exports.resetAnalyticsCaches = exports.resolveEntitySystem = exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = exports.claimGroups = exports.countByFacets = exports.searchGroups = exports.searchByFacets = exports.ensureFacetReady = exports.ensureEscalationCompatView = exports.claimAssertedByMetadata = void 0;
|
|
18
18
|
__exportStar(require("./types"), exports);
|
|
19
19
|
__exportStar(require("./crud"), exports);
|
|
20
|
+
var claim_asserted_1 = require("./claim-asserted");
|
|
21
|
+
Object.defineProperty(exports, "claimAssertedByMetadata", { enumerable: true, get: function () { return claim_asserted_1.claimAssertedByMetadata; } });
|
|
20
22
|
__exportStar(require("./batch"), exports);
|
|
21
23
|
__exportStar(require("./accumulate"), exports);
|
|
22
24
|
__exportStar(require("./bulk"), exports);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type EscalationLookupRef } from '../../types/escalation';
|
|
2
2
|
interface KnowledgeSnapshot {
|
|
3
3
|
data: Record<string, unknown>;
|
|
4
4
|
tags: string[];
|
|
@@ -6,24 +6,36 @@ interface KnowledgeSnapshot {
|
|
|
6
6
|
export interface ResolvedLookup {
|
|
7
7
|
domain: string;
|
|
8
8
|
key: string;
|
|
9
|
-
|
|
9
|
+
/** The edition served; null when a current ref found no edition. */
|
|
10
|
+
version: number | null;
|
|
11
|
+
/** The ref follows the newest edition rather than pinning one. */
|
|
12
|
+
current?: true;
|
|
10
13
|
as?: string;
|
|
11
14
|
data: Record<string, unknown> | null;
|
|
12
15
|
missing?: boolean;
|
|
13
16
|
}
|
|
14
17
|
/** The immutable snapshot at (domain, key, version), or null when absent. */
|
|
15
18
|
export declare function getKnowledgeSnapshot(domain: string, key: string, version: number): Promise<KnowledgeSnapshot | null>;
|
|
19
|
+
/**
|
|
20
|
+
* The edition a ref names: its pin, or for a current ref the newest edition
|
|
21
|
+
* (the newest at `asOf` when given, so a closed row reads what was current
|
|
22
|
+
* when it closed). Null when there is none.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveRefEdition(ref: EscalationLookupRef, asOf?: string | null): Promise<{
|
|
25
|
+
version: number;
|
|
26
|
+
snapshot: KnowledgeSnapshot;
|
|
27
|
+
} | null>;
|
|
16
28
|
/**
|
|
17
29
|
* Resolve a metadata `lookups` array into the form-context `lookup` domain:
|
|
18
30
|
* { [as ?? key]: data }. Returns null when there is nothing to resolve, so
|
|
19
31
|
* escalations without refs cost zero SQL. Missing snapshots are omitted —
|
|
20
32
|
* interpolated selects then fail closed rather than render the wrong list.
|
|
21
33
|
*/
|
|
22
|
-
export declare function resolveLookupContext(refs: unknown): Promise<Record<string, unknown> | null>;
|
|
34
|
+
export declare function resolveLookupContext(refs: unknown, asOf?: string | null): Promise<Record<string, unknown> | null>;
|
|
23
35
|
/**
|
|
24
36
|
* Full per-ref resolution for the lookups endpoint: every ref answers, with
|
|
25
37
|
* `missing: true` marking a pin that has no snapshot — fail-visible per ref
|
|
26
38
|
* without failing the batch.
|
|
27
39
|
*/
|
|
28
|
-
export declare function resolveLookupRefs(refs: EscalationLookupRef[]): Promise<ResolvedLookup[]>;
|
|
40
|
+
export declare function resolveLookupRefs(refs: EscalationLookupRef[], asOf?: string | null): Promise<ResolvedLookup[]>;
|
|
29
41
|
export {};
|
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getKnowledgeSnapshot = getKnowledgeSnapshot;
|
|
4
|
+
exports.resolveRefEdition = resolveRefEdition;
|
|
4
5
|
exports.resolveLookupContext = resolveLookupContext;
|
|
5
6
|
exports.resolveLookupRefs = resolveLookupRefs;
|
|
6
7
|
/**
|
|
7
8
|
* Lookup snapshot cache — keeps escalation lookup resolution off the SQL hot
|
|
8
|
-
* path.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* the
|
|
12
|
-
* republish must become visible.
|
|
9
|
+
* path. An edition {domain, key, version} is immutable, so snapshots cache
|
|
10
|
+
* indefinitely under an LRU bound. A pinned ref resolves from memory after
|
|
11
|
+
* the first read; a current ref costs one indexed read to learn which
|
|
12
|
+
* edition is newest, then shares the same cache. Missing snapshots are never
|
|
13
|
+
* cached — a later seed or republish must become visible.
|
|
13
14
|
*/
|
|
14
15
|
const db_1 = require("../../lib/db");
|
|
16
|
+
const escalation_1 = require("../../types/escalation");
|
|
15
17
|
const sql_1 = require("./sql");
|
|
16
18
|
const SNAPSHOT_CACHE_MAX_ENTRIES = 256;
|
|
17
19
|
// Map preserves insertion order — delete+set on read keeps it LRU.
|
|
18
20
|
const snapshotCache = new Map();
|
|
21
|
+
function remember(cacheKey, snapshot) {
|
|
22
|
+
snapshotCache.set(cacheKey, snapshot);
|
|
23
|
+
while (snapshotCache.size > SNAPSHOT_CACHE_MAX_ENTRIES) {
|
|
24
|
+
const oldest = snapshotCache.keys().next().value;
|
|
25
|
+
snapshotCache.delete(oldest);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
19
28
|
/** The immutable snapshot at (domain, key, version), or null when absent. */
|
|
20
29
|
async function getKnowledgeSnapshot(domain, key, version) {
|
|
21
30
|
const cacheKey = `${domain} ${key} ${version}`;
|
|
@@ -33,13 +42,35 @@ async function getKnowledgeSnapshot(domain, key, version) {
|
|
|
33
42
|
data: rows[0].data ?? {},
|
|
34
43
|
tags: rows[0].tags ?? [],
|
|
35
44
|
};
|
|
36
|
-
|
|
37
|
-
while (snapshotCache.size > SNAPSHOT_CACHE_MAX_ENTRIES) {
|
|
38
|
-
const oldest = snapshotCache.keys().next().value;
|
|
39
|
-
snapshotCache.delete(oldest);
|
|
40
|
-
}
|
|
45
|
+
remember(cacheKey, snapshot);
|
|
41
46
|
return snapshot;
|
|
42
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* The edition a ref names: its pin, or for a current ref the newest edition
|
|
50
|
+
* (the newest at `asOf` when given, so a closed row reads what was current
|
|
51
|
+
* when it closed). Null when there is none.
|
|
52
|
+
*/
|
|
53
|
+
async function resolveRefEdition(ref, asOf) {
|
|
54
|
+
if (!(0, escalation_1.isCurrentLookupRef)(ref)) {
|
|
55
|
+
const version = ref.version;
|
|
56
|
+
const snapshot = await getKnowledgeSnapshot(ref.domain, ref.key, version);
|
|
57
|
+
return snapshot ? { version, snapshot } : null;
|
|
58
|
+
}
|
|
59
|
+
const { rows } = await (0, db_1.getPool)().query(sql_1.GET_LATEST_KNOWLEDGE_VERSION, [ref.domain, ref.key, asOf ?? null]);
|
|
60
|
+
if (!rows[0])
|
|
61
|
+
return null;
|
|
62
|
+
const version = Number(rows[0].version);
|
|
63
|
+
const cacheKey = `${ref.domain} ${ref.key} ${version}`;
|
|
64
|
+
const cached = snapshotCache.get(cacheKey);
|
|
65
|
+
if (cached)
|
|
66
|
+
return { version, snapshot: cached };
|
|
67
|
+
const snapshot = {
|
|
68
|
+
data: rows[0].data ?? {},
|
|
69
|
+
tags: rows[0].tags ?? [],
|
|
70
|
+
};
|
|
71
|
+
remember(cacheKey, snapshot);
|
|
72
|
+
return { version, snapshot };
|
|
73
|
+
}
|
|
43
74
|
/** Structural check for one ref — malformed entries in stored metadata are skipped, not fatal. */
|
|
44
75
|
function isLookupRef(ref) {
|
|
45
76
|
if (!ref || typeof ref !== 'object')
|
|
@@ -47,7 +78,7 @@ function isLookupRef(ref) {
|
|
|
47
78
|
const r = ref;
|
|
48
79
|
return typeof r.domain === 'string' && r.domain.length > 0
|
|
49
80
|
&& typeof r.key === 'string' && r.key.length > 0
|
|
50
|
-
&& typeof r.version === 'number' && Number.isInteger(r.version) && r.version >= 1
|
|
81
|
+
&& ((0, escalation_1.isCurrentLookupRef)(r) || (typeof r.version === 'number' && Number.isInteger(r.version) && r.version >= 1))
|
|
51
82
|
&& (r.as === undefined || (typeof r.as === 'string' && r.as.length > 0));
|
|
52
83
|
}
|
|
53
84
|
/**
|
|
@@ -56,7 +87,7 @@ function isLookupRef(ref) {
|
|
|
56
87
|
* escalations without refs cost zero SQL. Missing snapshots are omitted —
|
|
57
88
|
* interpolated selects then fail closed rather than render the wrong list.
|
|
58
89
|
*/
|
|
59
|
-
async function resolveLookupContext(refs) {
|
|
90
|
+
async function resolveLookupContext(refs, asOf) {
|
|
60
91
|
if (!Array.isArray(refs) || refs.length === 0)
|
|
61
92
|
return null;
|
|
62
93
|
const valid = refs.filter(isLookupRef);
|
|
@@ -64,9 +95,9 @@ async function resolveLookupContext(refs) {
|
|
|
64
95
|
return null;
|
|
65
96
|
const ctx = {};
|
|
66
97
|
for (const ref of valid) {
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
69
|
-
ctx[ref.as ?? ref.key] = snapshot.data;
|
|
98
|
+
const edition = await resolveRefEdition(ref, asOf);
|
|
99
|
+
if (edition)
|
|
100
|
+
ctx[ref.as ?? ref.key] = edition.snapshot.data;
|
|
70
101
|
}
|
|
71
102
|
return ctx;
|
|
72
103
|
}
|
|
@@ -75,19 +106,21 @@ async function resolveLookupContext(refs) {
|
|
|
75
106
|
* `missing: true` marking a pin that has no snapshot — fail-visible per ref
|
|
76
107
|
* without failing the batch.
|
|
77
108
|
*/
|
|
78
|
-
async function resolveLookupRefs(refs) {
|
|
109
|
+
async function resolveLookupRefs(refs, asOf) {
|
|
79
110
|
const resolved = [];
|
|
80
111
|
for (const ref of refs) {
|
|
81
112
|
if (!isLookupRef(ref))
|
|
82
113
|
continue;
|
|
83
|
-
const
|
|
114
|
+
const current = (0, escalation_1.isCurrentLookupRef)(ref);
|
|
115
|
+
const edition = await resolveRefEdition(ref, asOf);
|
|
84
116
|
resolved.push({
|
|
85
117
|
domain: ref.domain,
|
|
86
118
|
key: ref.key,
|
|
87
|
-
version: ref.version,
|
|
119
|
+
version: edition?.version ?? (current ? null : ref.version),
|
|
120
|
+
...(current ? { current: true } : {}),
|
|
88
121
|
...(ref.as ? { as: ref.as } : {}),
|
|
89
|
-
data:
|
|
90
|
-
...(
|
|
122
|
+
data: edition ? edition.snapshot.data : null,
|
|
123
|
+
...(edition ? {} : { missing: true }),
|
|
91
124
|
});
|
|
92
125
|
}
|
|
93
126
|
return resolved;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type EscalationLookupRef } from '../../types/escalation';
|
|
2
2
|
/**
|
|
3
|
-
* One message per ref
|
|
3
|
+
* One message per ref with no edition behind it (a pin that does not exist,
|
|
4
|
+
* or a current ref to an entry with no editions), naming what does.
|
|
4
5
|
* Shape is the caller's job (assertLookupRefs); this answers the second
|
|
5
6
|
* question a saver has: is there an edition behind the pin.
|
|
6
7
|
*/
|
|
@@ -2,25 +2,27 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.describeMissingLookupRefs = describeMissingLookupRefs;
|
|
4
4
|
const db_1 = require("../../lib/db");
|
|
5
|
+
const escalation_1 = require("../../types/escalation");
|
|
5
6
|
const lookup_cache_1 = require("./lookup-cache");
|
|
6
7
|
const sql_1 = require("./sql");
|
|
7
8
|
/**
|
|
8
|
-
* One message per ref
|
|
9
|
+
* One message per ref with no edition behind it (a pin that does not exist,
|
|
10
|
+
* or a current ref to an entry with no editions), naming what does.
|
|
9
11
|
* Shape is the caller's job (assertLookupRefs); this answers the second
|
|
10
12
|
* question a saver has: is there an edition behind the pin.
|
|
11
13
|
*/
|
|
12
14
|
async function describeMissingLookupRefs(refs) {
|
|
13
15
|
const problems = [];
|
|
14
16
|
for (const ref of refs) {
|
|
15
|
-
|
|
16
|
-
if (snapshot)
|
|
17
|
+
if (await (0, lookup_cache_1.resolveRefEdition)(ref))
|
|
17
18
|
continue;
|
|
18
19
|
const { rows } = await (0, db_1.getPool)().query(sql_1.LIST_KNOWLEDGE_VERSIONS, [ref.domain, ref.key]);
|
|
19
20
|
const versions = rows.map((r) => Number(r.version)).sort((a, b) => a - b);
|
|
20
21
|
const where = versions.length
|
|
21
22
|
? `editions: ${versions.map((v) => `v${v}`).join(', ')}`
|
|
22
23
|
: `no knowledge entry ${ref.domain}/${ref.key}`;
|
|
23
|
-
|
|
24
|
+
const named = (0, escalation_1.isCurrentLookupRef)(ref) ? 'current' : `v${ref.version}`;
|
|
25
|
+
problems.push(`Lookup ref ${ref.domain}/${ref.key} ${named} names no edition (${where})`);
|
|
24
26
|
}
|
|
25
27
|
return problems;
|
|
26
28
|
}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export declare const GET_KNOWLEDGE_VERSION = "\n SELECT domain, key, version, data, tags, change_summary, created_at\n FROM lt_knowledge_versions\n WHERE domain = $1 AND key = $2 AND version = $3";
|
|
2
2
|
export declare const LIST_KNOWLEDGE_VERSIONS = "\n SELECT v.version, v.change_summary, v.created_at,\n (v.version = k.current_version) AS is_current\n FROM lt_knowledge_versions v\n JOIN lt_knowledge k ON k.domain = v.domain AND k.key = v.key\n WHERE v.domain = $1 AND v.key = $2\n ORDER BY v.version DESC";
|
|
3
|
+
/** The newest edition, or the newest created at or before $3 when it is set. */
|
|
4
|
+
export declare const GET_LATEST_KNOWLEDGE_VERSION = "\n SELECT version, data, tags\n FROM lt_knowledge_versions\n WHERE domain = $1 AND key = $2\n AND ($3::timestamptz IS NULL OR created_at <= $3)\n ORDER BY version DESC\n LIMIT 1";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LIST_KNOWLEDGE_VERSIONS = exports.GET_KNOWLEDGE_VERSION = void 0;
|
|
3
|
+
exports.GET_LATEST_KNOWLEDGE_VERSION = exports.LIST_KNOWLEDGE_VERSIONS = exports.GET_KNOWLEDGE_VERSION = void 0;
|
|
4
4
|
exports.GET_KNOWLEDGE_VERSION = `
|
|
5
5
|
SELECT domain, key, version, data, tags, change_summary, created_at
|
|
6
6
|
FROM lt_knowledge_versions
|
|
@@ -12,3 +12,11 @@ exports.LIST_KNOWLEDGE_VERSIONS = `
|
|
|
12
12
|
JOIN lt_knowledge k ON k.domain = v.domain AND k.key = v.key
|
|
13
13
|
WHERE v.domain = $1 AND v.key = $2
|
|
14
14
|
ORDER BY v.version DESC`;
|
|
15
|
+
/** The newest edition, or the newest created at or before $3 when it is set. */
|
|
16
|
+
exports.GET_LATEST_KNOWLEDGE_VERSION = `
|
|
17
|
+
SELECT version, data, tags
|
|
18
|
+
FROM lt_knowledge_versions
|
|
19
|
+
WHERE domain = $1 AND key = $2
|
|
20
|
+
AND ($3::timestamptz IS NULL OR created_at <= $3)
|
|
21
|
+
ORDER BY version DESC
|
|
22
|
+
LIMIT 1`;
|
|
@@ -175,7 +175,7 @@ function registerHumanQueueTools(server) {
|
|
|
175
175
|
};
|
|
176
176
|
}
|
|
177
177
|
const refs = (0, lookups_1.readLookupRefs)(escalation.envelope);
|
|
178
|
-
const lookups = refs.length > 0 ? await (0, knowledge_1.resolveLookupRefs)(refs) : [];
|
|
178
|
+
const lookups = refs.length > 0 ? await (0, knowledge_1.resolveLookupRefs)(refs, (0, lookups_1.lookupAsOf)(escalation)) : [];
|
|
179
179
|
return {
|
|
180
180
|
content: [{
|
|
181
181
|
type: 'text',
|
|
@@ -2,10 +2,11 @@ import type { Types } from '@hotmeshio/hotmesh';
|
|
|
2
2
|
import { type AccumulateConfig, type AccumulatorResult, type EscalationLookupRef } from '../../types/escalation';
|
|
3
3
|
/**
|
|
4
4
|
* HotMesh's escalation config plus long-tail sugar. `schemaVersion` pins the
|
|
5
|
-
* role form version (lt_role_schemas) the resolve UI renders; `lookups`
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* workflow author sets, folded before the config
|
|
5
|
+
* role form version (lt_role_schemas) the resolve UI renders; `lookups` names
|
|
6
|
+
* the knowledge entries the form may read (the `lookup.*` context domain, see
|
|
7
|
+
* docs/hitl/lookups.md), each pinned to an edition or following the current
|
|
8
|
+
* one. Both are LITERALS the workflow author sets, folded before the config
|
|
9
|
+
* reaches the engine:
|
|
9
10
|
* schemaVersion into the GIN-indexed metadata (a queryable facet), lookups
|
|
10
11
|
* into the unindexed envelope (form plumbing, never a facet). Folding is a
|
|
11
12
|
* pure transform — no query, no activity — so a pinned `conditional` costs
|
|
@@ -57,17 +58,19 @@ export type ConditionEscalationConfig = Types.ConditionQueueConfig & {
|
|
|
57
58
|
* });
|
|
58
59
|
* ```
|
|
59
60
|
*
|
|
60
|
-
* **
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
61
|
+
* **Knowledge lookups — option lists the form reads.** Each ref names a
|
|
62
|
+
* knowledge entry; the resolve UI fetches it and the form addresses the
|
|
63
|
+
* content as the `lookup.*` context domain (`x-lt-options:
|
|
64
|
+
* "lookup.materials.items"`). Leave `version` out (or set `'current'`) and
|
|
65
|
+
* the form reads the newest edition, so a long-open row sees today's list
|
|
66
|
+
* and a closed row the list current when it closed. Pin a `version` when the
|
|
67
|
+
* form must read one exact edition.
|
|
65
68
|
*
|
|
66
69
|
* ```typescript
|
|
67
70
|
* const decision = await conditional<PickerResolverV1>(signalId, {
|
|
68
71
|
* role: 'catalog-picker',
|
|
69
72
|
* description: instructions,
|
|
70
|
-
* lookups: [{ domain: 'catalog', key: 'materials'
|
|
73
|
+
* lookups: [{ domain: 'catalog', key: 'materials' }],
|
|
71
74
|
* });
|
|
72
75
|
* ```
|
|
73
76
|
*
|