@hotmeshio/long-tail 0.19.1 → 0.21.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 +4 -4
- package/build/api/escalations/accumulate.d.ts +96 -0
- package/build/api/escalations/accumulate.js +516 -0
- package/build/api/escalations/index.d.ts +1 -0
- package/build/api/escalations/index.js +10 -1
- package/build/api/roles.d.ts +4 -5
- package/build/api/roles.js +53 -4
- package/build/api/scan-codes/execute.js +2 -0
- package/build/api/scan-codes/verbs.d.ts +15 -0
- package/build/api/scan-codes/verbs.js +65 -0
- package/build/api/workflows/config.d.ts +3 -0
- package/build/api/workflows/config.js +15 -0
- package/build/api/workflows/index.d.ts +1 -0
- package/build/api/workflows/index.js +3 -1
- package/build/api/workflows/input-lookups.d.ts +16 -0
- package/build/api/workflows/input-lookups.js +69 -0
- package/build/api/workflows/input-validation.d.ts +4 -3
- package/build/api/workflows/input-validation.js +7 -4
- package/build/api/workflows/invocable.js +1 -0
- package/build/api/workflows/invocation.js +1 -1
- package/build/index.js +60 -0
- package/build/lib/db/schemas/035_workflow_input_lookups.sql +9 -0
- package/build/lib/db/schemas/036_role_portals.sql +12 -0
- package/build/routes/escalations/accumulate.d.ts +7 -0
- package/build/routes/escalations/accumulate.js +150 -0
- package/build/routes/escalations/index.js +5 -0
- package/build/routes/workflows/config.js +10 -0
- package/build/sdk/index.d.ts +25 -0
- package/build/sdk/index.js +8 -0
- package/build/services/config/cache.js +1 -0
- package/build/services/config/read.js +2 -0
- package/build/services/config/sql.d.ts +2 -2
- package/build/services/config/sql.js +6 -5
- package/build/services/config/write.js +10 -1
- package/build/services/escalation/accumulate.d.ts +81 -0
- package/build/services/escalation/accumulate.js +154 -0
- package/build/services/escalation/index.d.ts +1 -0
- package/build/services/escalation/index.js +1 -0
- package/build/services/knowledge/index.d.ts +1 -0
- package/build/services/knowledge/index.js +1 -0
- package/build/services/knowledge/lookup-refs.d.ts +7 -0
- package/build/services/knowledge/lookup-refs.js +26 -0
- package/build/services/mcp/db-server/schemas.d.ts +2 -2
- package/build/services/mcp/playwright-server/schemas.d.ts +2 -2
- package/build/services/orchestrator/condition.d.ts +40 -3
- package/build/services/orchestrator/condition.js +42 -2
- package/build/services/role/index.js +1 -0
- package/build/services/role/seed.js +6 -1
- package/build/services/role/sql.d.ts +6 -3
- package/build/services/role/sql.js +7 -2
- package/build/services/role/types.d.ts +38 -10
- package/build/services/role/types.js +10 -1
- package/build/services/scan-code/validate.js +16 -0
- package/build/shared/form-validation/display-only-widgets.d.ts +16 -0
- package/build/shared/form-validation/display-only-widgets.js +25 -0
- package/build/shared/form-validation/field-validator.d.ts +1 -0
- package/build/shared/form-validation/field-validator.js +94 -6
- package/build/shared/form-validation/index.d.ts +2 -0
- package/build/shared/form-validation/index.js +2 -0
- package/build/shared/form-validation/invoke-context.d.ts +4 -3
- package/build/shared/form-validation/invoke-context.js +5 -4
- package/build/shared/form-validation/x-lt-bind.d.ts +2 -14
- package/build/shared/form-validation/x-lt-bind.js +12 -8
- package/build/shared/form-validation/x-lt-invoke.d.ts +38 -0
- package/build/shared/form-validation/x-lt-invoke.js +103 -0
- package/build/shared/form-validation/x-lt-options.d.ts +3 -3
- package/build/shared/form-validation/x-lt-options.js +19 -5
- package/build/shared/form-validation/x-lt-show-if.d.ts +5 -0
- package/build/shared/form-validation/x-lt-show-if.js +10 -0
- package/build/start/workers.js +10 -0
- package/build/system/mcp-servers/admin/escalations.js +39 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +256 -33
- package/build/system/mcp-servers/admin/schemas.js +55 -3
- package/build/system/mcp-servers/admin/users.js +1 -0
- package/build/system/mcp-servers/admin/workflow-config.js +54 -9
- package/build/system/mcp-servers/admin/workflows.js +9 -7
- package/build/system/mcp-servers/db-query/schemas.d.ts +2 -2
- package/build/system/mcp-servers/docs.js +4 -0
- package/build/system/mcp-servers/human-queue-schemas.d.ts +85 -0
- package/build/system/mcp-servers/human-queue-schemas.js +19 -1
- package/build/system/mcp-servers/human-queue.d.ts +2 -0
- package/build/system/mcp-servers/human-queue.js +77 -0
- package/build/system/seed/tool-manifests-admin.d.ts +1509 -227
- package/build/system/seed/tool-manifests-admin.js +8 -4
- package/build/system/seed/tool-manifests-escalation.d.ts +174 -0
- package/build/system/seed/tool-manifests-escalation.js +56 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/config.d.ts +4 -0
- package/build/types/escalation.d.ts +52 -0
- package/build/types/escalation.js +29 -1
- package/build/types/index.d.ts +2 -2
- package/build/types/index.js +3 -1
- package/build/types/scan-code.d.ts +24 -0
- package/build/types/scan-code.js +9 -0
- package/build/types/startup.d.ts +26 -0
- package/dashboard/dist/assets/{AdminDashboard-Drs-9TRM.js → AdminDashboard-uarpHB88.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Drs-9TRM.js.map → AdminDashboard-uarpHB88.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-BDPDZ7-v.js → AgentConfigPage-BcUaDD5E.js} +6 -6
- package/dashboard/dist/assets/{AgentConfigPage-BDPDZ7-v.js.map → AgentConfigPage-BcUaDD5E.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-CGBulM4_.js → AgentDetailPage-BaZBhK6i.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-CGBulM4_.js.map → AgentDetailPage-BaZBhK6i.js.map} +1 -1
- package/dashboard/dist/assets/AgentsPage-CuVFSDc4.js +2 -0
- package/dashboard/dist/assets/{AgentsPage-D77JeViQ.js.map → AgentsPage-CuVFSDc4.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-CC5vI_Sv.js → BotPicker-CClMby6B.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-CC5vI_Sv.js.map → BotPicker-CClMby6B.js.map} +1 -1
- package/dashboard/dist/assets/BulkAssignModal-BL8FRgkN.js +2 -0
- package/dashboard/dist/assets/{BulkAssignModal-BXiJnlqt.js.map → BulkAssignModal-BL8FRgkN.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-D53ogPor.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-D9TC2iKy.js.map → CapabilitiesPage-D53ogPor.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-D10lGw_u.js → CollapsibleSection-ow8jpbtD.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-D10lGw_u.js.map → CollapsibleSection-ow8jpbtD.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-BJdLN6No.js → ConfirmDeleteModal-CeEDt9iJ.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-BJdLN6No.js.map → ConfirmDeleteModal-CeEDt9iJ.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-D9B-BjQ7.js → CountdownTimer-CSqyZMCG.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-D9B-BjQ7.js.map → CountdownTimer-CSqyZMCG.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-hniUAFBK.js → CredentialsPage-Dx7SxA23.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-hniUAFBK.js.map → CredentialsPage-Dx7SxA23.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-v9DCD2FX.js → CronLabel-LYPxpvNN.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-v9DCD2FX.js.map → CronLabel-LYPxpvNN.js.map} +1 -1
- package/dashboard/dist/assets/DataTable-spX1dFyb.js +2 -0
- package/dashboard/dist/assets/DataTable-spX1dFyb.js.map +1 -0
- package/dashboard/dist/assets/{DropZone-XlcY8hEH.js → DropZone-f1o-GLM8.js} +2 -2
- package/dashboard/dist/assets/{DropZone-XlcY8hEH.js.map → DropZone-f1o-GLM8.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-_xvVTK8N.js → ElapsedCell-BZJTSm9N.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-_xvVTK8N.js.map → ElapsedCell-BZJTSm9N.js.map} +1 -1
- package/dashboard/dist/assets/EntityTimelinePanel-0wIIW2en.js +2 -0
- package/dashboard/dist/assets/{EntityTimelinePanel-1lT3jkCM.js.map → EntityTimelinePanel-0wIIW2en.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-BeQUTUEO.js → EscalationListSchemaPage-CoYvtMzj.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-BeQUTUEO.js.map → EscalationListSchemaPage-CoYvtMzj.js.map} +1 -1
- package/dashboard/dist/assets/EscalationListView-DWFHPufv.js +2 -0
- package/dashboard/dist/assets/EscalationListView-DWFHPufv.js.map +1 -0
- package/dashboard/dist/assets/{EscalationSchemaPage-D4VlEwyS.js → EscalationSchemaPage-C9Xu_A25.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-D4VlEwyS.js.map → EscalationSchemaPage-C9Xu_A25.js.map} +1 -1
- package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js +2 -0
- package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js.map +1 -0
- package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js +2 -0
- package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js.map +1 -0
- package/dashboard/dist/assets/{EscalationsOverview-Bx6Zrzm-.js → EscalationsOverview-CW57FaP9.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-Bx6Zrzm-.js.map → EscalationsOverview-CW57FaP9.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-KEC3YWBf.js → EventTable-D1ctWhKf.js} +2 -2
- package/dashboard/dist/assets/{EventTable-KEC3YWBf.js.map → EventTable-D1ctWhKf.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-xwN_b5fj.js → FilterBar-C-iur-Nj.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-xwN_b5fj.js.map → FilterBar-C-iur-Nj.js.map} +1 -1
- package/dashboard/dist/assets/GraphInvokePage-CcA_44M4.js +2 -0
- package/dashboard/dist/assets/{GraphInvokePage-DV7Y0fe2.js.map → GraphInvokePage-CcA_44M4.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-Dc085ghJ.js +2 -0
- package/dashboard/dist/assets/{HomePage-G785SWcW.js.map → HomePage-Dc085ghJ.js.map} +1 -1
- package/dashboard/dist/assets/ListToolbar-h_ziBt4O.js +2 -0
- package/dashboard/dist/assets/{ListToolbar-zPVYPg3W.js.map → ListToolbar-h_ziBt4O.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-CMGUq8hx.js → McpOverview-qXXhbNWV.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-CMGUq8hx.js.map → McpOverview-qXXhbNWV.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-CdhLhaKn.js → McpQueryDetailPage-SEzSbZrd.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-CdhLhaKn.js.map → McpQueryDetailPage-SEzSbZrd.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryPage-Cy0V0kv9.js +2 -0
- package/dashboard/dist/assets/{McpQueryPage-CNSNMagY.js.map → McpQueryPage-Cy0V0kv9.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-DBm8hUaW.js → McpRunDetailPage-DjJO5vSb.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-DBm8hUaW.js.map → McpRunDetailPage-DjJO5vSb.js.map} +1 -1
- package/dashboard/dist/assets/McpRunsPage-BfjiJ8mM.js +2 -0
- package/dashboard/dist/assets/{McpRunsPage-B6rb5QBf.js.map → McpRunsPage-BfjiJ8mM.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js → NamespacePill-DADRJOUl.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js.map → NamespacePill-DADRJOUl.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-dJcER0T_.js +3 -0
- package/dashboard/dist/assets/OperationsPage-dJcER0T_.js.map +1 -0
- package/dashboard/dist/assets/OperatorDashboard-zCkW4eqk.js +2 -0
- package/dashboard/dist/assets/{OperatorDashboard-DBOscDnf.js.map → OperatorDashboard-zCkW4eqk.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js → PageHeader-Csq434-v.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js.map → PageHeader-Csq434-v.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js → PageHeaderWithStats-CSnk1p5A.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js.map → PageHeaderWithStats-CSnk1p5A.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-BGRdGpeR.js → PersonaDetailPage-Cx6L3Jvu.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-BGRdGpeR.js.map → PersonaDetailPage-Cx6L3Jvu.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-DRzOZcVa.js → PersonasPage-DOgGUlJl.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-DRzOZcVa.js.map → PersonasPage-DOgGUlJl.js.map} +1 -1
- package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js +2 -0
- package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js.map +1 -0
- package/dashboard/dist/assets/{ProcessDetailPage-BLGjZXpM.js → ProcessDetailPage-BFcFSDUv.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-BLGjZXpM.js.map → ProcessDetailPage-BFcFSDUv.js.map} +1 -1
- package/dashboard/dist/assets/ProcessesListPage-BaHV2cXp.js +2 -0
- package/dashboard/dist/assets/{ProcessesListPage-5NnysKFC.js.map → ProcessesListPage-BaHV2cXp.js.map} +1 -1
- package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js +7 -0
- package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js.map +1 -0
- package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js +8 -0
- package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-DhnVPK4q.js → RolePill-BafrASDX.js} +2 -2
- package/dashboard/dist/assets/{RolePill-DhnVPK4q.js.map → RolePill-BafrASDX.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-BmW1LzkU.js → RolesPage-DSqqKPbv.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-BmW1LzkU.js.map → RolesPage-DSqqKPbv.js.map} +1 -1
- package/dashboard/dist/assets/RunAsSelector-B29iWwel.js +2 -0
- package/dashboard/dist/assets/{RunAsSelector-BwZTJ4Yj.js.map → RunAsSelector-B29iWwel.js.map} +1 -1
- package/dashboard/dist/assets/ScanCodesPage-S8aAJfnC.js +2 -0
- package/dashboard/dist/assets/{ScanCodesPage-FiYIYB-m.js.map → ScanCodesPage-S8aAJfnC.js.map} +1 -1
- package/dashboard/dist/assets/{ScanSchemeDetailPage-BiAqtD-a.js → ScanSchemeDetailPage-CUBRAtmJ.js} +2 -2
- package/dashboard/dist/assets/{ScanSchemeDetailPage-BiAqtD-a.js.map → ScanSchemeDetailPage-CUBRAtmJ.js.map} +1 -1
- package/dashboard/dist/assets/ScanStationPage-R9t1-CeQ.js +2 -0
- package/dashboard/dist/assets/{ScanStationPage-8CdOtbCD.js.map → ScanStationPage-R9t1-CeQ.js.map} +1 -1
- package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js → ScopeBadge-b6MIBiYD.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js.map → ScopeBadge-b6MIBiYD.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-DRuqKhZt.js → StickyPagination-CkW_A507.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-DRuqKhZt.js.map → StickyPagination-CkW_A507.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-JwlbRiMn.js → StreamMessageDetail-yzWX0wac.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-JwlbRiMn.js.map → StreamMessageDetail-yzWX0wac.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-hu3c4bCJ.js → SwimlaneTimeline-Cf4DXFxj.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-hu3c4bCJ.js.map → SwimlaneTimeline-Cf4DXFxj.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js → TagInput-ZrIIrEUP.js} +2 -2
- package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js.map → TagInput-ZrIIrEUP.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-NqVZF3jW.js → TaskDetailPage-DCDcEps9.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-NqVZF3jW.js.map → TaskDetailPage-DCDcEps9.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js → TaskQueuePill-DkQ1uc6y.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js.map → TaskQueuePill-DkQ1uc6y.js.map} +1 -1
- package/dashboard/dist/assets/TasksListPage-BBATgpf7.js +2 -0
- package/dashboard/dist/assets/{TasksListPage-BQNaSzCn.js.map → TasksListPage-BBATgpf7.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-Cv35DOiI.js → TimeAgo-CSNVEjch.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-Cv35DOiI.js.map → TimeAgo-CSNVEjch.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DHUXey9s.js → TimestampCell-Du1nBrPn.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DHUXey9s.js.map → TimestampCell-Du1nBrPn.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js → ToolPill-Baxm02L6.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js.map → ToolPill-Baxm02L6.js.map} +1 -1
- package/dashboard/dist/assets/ToolTestPanel-CF-h_5Rg.js +2 -0
- package/dashboard/dist/assets/{ToolTestPanel-DvuLFWqQ.js.map → ToolTestPanel-CF-h_5Rg.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-TXX3QNSo.js → TopicDetailPage-Dr1UmWcp.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-TXX3QNSo.js.map → TopicDetailPage-Dr1UmWcp.js.map} +1 -1
- package/dashboard/dist/assets/TopicsPage-CUUo-Ylf.js +2 -0
- package/dashboard/dist/assets/{TopicsPage-h-oyTeEJ.js.map → TopicsPage-CUUo-Ylf.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-BceRCeDF.js → UserName-kBh1dc39.js} +2 -2
- package/dashboard/dist/assets/{UserName-BceRCeDF.js.map → UserName-kBh1dc39.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-CmHGcaN9.js → WorkflowExecutionPage-CCRSbnDx.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-CmHGcaN9.js.map → WorkflowExecutionPage-CCRSbnDx.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js → WorkflowPill-ZepbO_ny.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js.map → WorkflowPill-ZepbO_ny.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-BNQVvyek.js +2 -0
- package/dashboard/dist/assets/{WorkflowsDashboard-B0r2lQXk.js.map → WorkflowsDashboard-BNQVvyek.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-BTMc2PJ_.js → WorkflowsOverview-DswubNJN.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-BTMc2PJ_.js.map → WorkflowsOverview-DswubNJN.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DUiCVnZp.js → YamlWorkflowDetailPage-Cw9Dlmup.js} +11 -11
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DUiCVnZp.js.map → YamlWorkflowDetailPage-Cw9Dlmup.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BAuXfwi0.js → YamlWorkflowsPage-DB8xnIXy.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BAuXfwi0.js.map → YamlWorkflowsPage-DB8xnIXy.js.map} +1 -1
- package/dashboard/dist/assets/{agents-BvmLCk4h.js → agents-BwEnf6N9.js} +2 -2
- package/dashboard/dist/assets/{agents-BvmLCk4h.js.map → agents-BwEnf6N9.js.map} +1 -1
- package/dashboard/dist/assets/{bots-f_tyhl4I.js → bots-CCmJTT2u.js} +2 -2
- package/dashboard/dist/assets/{bots-f_tyhl4I.js.map → bots-CCmJTT2u.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DNo5bqLx.js → capabilities-BZHgp_nh.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DNo5bqLx.js.map → capabilities-BZHgp_nh.js.map} +1 -1
- package/dashboard/dist/assets/{constants-BHkpVaqx.js → constants-CeBBTzf5.js} +2 -2
- package/dashboard/dist/assets/{constants-BHkpVaqx.js.map → constants-CeBBTzf5.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-Dyyj2Irb.js → controlplane-CyfwUlFA.js} +2 -2
- package/dashboard/dist/assets/{controlplane-Dyyj2Irb.js.map → controlplane-CyfwUlFA.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js +2 -0
- package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js.map +1 -0
- package/dashboard/dist/assets/index-3gbd5neL.js +67 -0
- package/dashboard/dist/assets/index-3gbd5neL.js.map +1 -0
- package/dashboard/dist/assets/index-BAAVTyZ-.js +2 -0
- package/dashboard/dist/assets/{index-DL83W7Gu.js.map → index-BAAVTyZ-.js.map} +1 -1
- package/dashboard/dist/assets/{index-CsKiRyhy.js → index-BC6Jenlo.js} +2 -2
- package/dashboard/dist/assets/{index-CsKiRyhy.js.map → index-BC6Jenlo.js.map} +1 -1
- package/dashboard/dist/assets/index-C7KHqOTQ.js +2 -0
- package/dashboard/dist/assets/{index-D7ESqn22.js.map → index-C7KHqOTQ.js.map} +1 -1
- package/dashboard/dist/assets/index-CDrqqbSR.js +3 -0
- package/dashboard/dist/assets/index-CDrqqbSR.js.map +1 -0
- package/dashboard/dist/assets/index-CVwzCZ43.js +2 -0
- package/dashboard/dist/assets/{index-DvxxrFBo.js.map → index-CVwzCZ43.js.map} +1 -1
- package/dashboard/dist/assets/index-CaGF6TCC.js +2 -0
- package/dashboard/dist/assets/index-CaGF6TCC.js.map +1 -0
- package/dashboard/dist/assets/index-ClVbfe4z.js +13 -0
- package/dashboard/dist/assets/index-ClVbfe4z.js.map +1 -0
- package/dashboard/dist/assets/{index-DWse7ERF.js → index-CuVkSmj5.js} +2 -2
- package/dashboard/dist/assets/{index-DWse7ERF.js.map → index-CuVkSmj5.js.map} +1 -1
- package/dashboard/dist/assets/{index-PcyGjmBm.js → index-DAuX_PlL.js} +2 -2
- package/dashboard/dist/assets/{index-PcyGjmBm.js.map → index-DAuX_PlL.js.map} +1 -1
- package/dashboard/dist/assets/{index-e2X-s0EQ.js → index-DBWS5QL8.js} +2 -2
- package/dashboard/dist/assets/{index-e2X-s0EQ.js.map → index-DBWS5QL8.js.map} +1 -1
- package/dashboard/dist/assets/index-DIWCI6HC.js +2 -0
- package/dashboard/dist/assets/{index-BNZknxFY.js.map → index-DIWCI6HC.js.map} +1 -1
- package/dashboard/dist/assets/{index-C-Xr2V3F.js → index-DZ8X_Gp4.js} +2 -2
- package/dashboard/dist/assets/{index-C-Xr2V3F.js.map → index-DZ8X_Gp4.js.map} +1 -1
- package/dashboard/dist/assets/index-Dh8MJl3L.css +1 -0
- package/dashboard/dist/assets/{knowledge-Coo6CKzo.js → knowledge-CqyLhUMg.js} +2 -2
- package/dashboard/dist/assets/{knowledge-Coo6CKzo.js.map → knowledge-CqyLhUMg.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-Cz5eFnP_.js → mcp-Cvu6bFYH.js} +2 -2
- package/dashboard/dist/assets/{mcp-Cz5eFnP_.js.map → mcp-Cvu6bFYH.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-BtnuO4LF.js → mcp-query-qC6A3e9l.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-BtnuO4LF.js.map → mcp-query-qC6A3e9l.js.map} +1 -1
- package/dashboard/dist/assets/metadata-display-COo3mMCr.js +2 -0
- package/dashboard/dist/assets/metadata-display-COo3mMCr.js.map +1 -0
- package/dashboard/dist/assets/{personas-C2-LgpHQ.js → personas-BKN_lJuV.js} +2 -2
- package/dashboard/dist/assets/{personas-C2-LgpHQ.js.map → personas-BKN_lJuV.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-TuXQvUA-.js → pipelines-BldIfv85.js} +2 -2
- package/dashboard/dist/assets/{pipelines-TuXQvUA-.js.map → pipelines-BldIfv85.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-OUzpu__z.js → tasks-B-Uay8uL.js} +2 -2
- package/dashboard/dist/assets/{tasks-OUzpu__z.js.map → tasks-B-Uay8uL.js.map} +1 -1
- package/dashboard/dist/assets/{topics-B8bdrBaW.js → topics-438EQogt.js} +2 -2
- package/dashboard/dist/assets/{topics-B8bdrBaW.js.map → topics-438EQogt.js.map} +1 -1
- package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js +2 -0
- package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js.map +1 -0
- package/dashboard/dist/assets/{useDebouncedValue-Cp5ZOtVE.js → useDebouncedValue-Cw8hYZ8y.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-Cp5ZOtVE.js.map → useDebouncedValue-Cw8hYZ8y.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-DtQe3wZ5.js → useNamespace-D1218GQ8.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-DtQe3wZ5.js.map → useNamespace-D1218GQ8.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-CS22c15X.js → useYamlActivityEvents-BAQf_y_U.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-CS22c15X.js.map → useYamlActivityEvents-BAQf_y_U.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js → vendor-icons-B7OcUM6b.js} +2 -2
- package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js.map → vendor-icons-B7OcUM6b.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-HQIki3hI.js → yaml-workflows-CN01gEB0.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-HQIki3hI.js.map → yaml-workflows-CN01gEB0.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/accumulator.md +113 -0
- package/docs/api/http/escalations.md +89 -0
- package/docs/api/http/roles.md +1 -0
- package/docs/api/http/workflows.md +28 -1
- package/docs/api/mcp/admin.md +40 -4
- package/docs/api/sdk/escalations.md +91 -0
- package/docs/api/sdk/roles.md +2 -0
- package/docs/architecture.md +1 -1
- package/docs/code-owned-configuration.md +3 -2
- package/docs/dashboard.md +11 -5
- package/docs/hitl/design.md +1 -1
- package/docs/hitl/escalation.md +37 -1
- package/docs/hitl/form.md +12 -7
- package/docs/hitl/invoke-form.md +10 -3
- package/docs/hitl/lookups.md +21 -0
- package/docs/hitl/pinned-views.md +4 -0
- package/docs/hitl/portal.md +97 -0
- package/docs/hitl/resolution.md +41 -0
- package/docs/hitl/x-lt-embed.md +1 -1
- package/docs/hitl/x-lt-invoke.md +95 -0
- package/docs/hitl/x-lt-list-schema.md +3 -1
- package/docs/hitl/x-lt-validation.md +50 -3
- package/docs/hitl/x-lt-widget.md +22 -0
- package/docs/hitl-guide.md +12 -2
- package/docs/scan-codes.md +15 -2
- package/docs/sdk.md +1 -1
- package/docs/workflows.md +2 -2
- package/package.json +4 -2
- package/dashboard/dist/assets/AgentsPage-D77JeViQ.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js.map +0 -1
- package/dashboard/dist/assets/BulkAssignModal-BXiJnlqt.js +0 -2
- package/dashboard/dist/assets/CapabilitiesPage-D9TC2iKy.js +0 -2
- package/dashboard/dist/assets/DataTable-7C7riavf.js +0 -2
- package/dashboard/dist/assets/DataTable-7C7riavf.js.map +0 -1
- package/dashboard/dist/assets/EntityTimelinePanel-1lT3jkCM.js +0 -2
- package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js +0 -2
- package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js.map +0 -1
- package/dashboard/dist/assets/GraphInvokePage-DV7Y0fe2.js +0 -2
- package/dashboard/dist/assets/HomePage-G785SWcW.js +0 -2
- package/dashboard/dist/assets/ListToolbar-zPVYPg3W.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-CNSNMagY.js +0 -2
- package/dashboard/dist/assets/McpRunsPage-B6rb5QBf.js +0 -2
- package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js +0 -3
- package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-DBOscDnf.js +0 -2
- package/dashboard/dist/assets/ProcessesListPage-5NnysKFC.js +0 -2
- package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js +0 -2
- package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js.map +0 -1
- package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js +0 -8
- package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js.map +0 -1
- package/dashboard/dist/assets/RunAsSelector-BwZTJ4Yj.js +0 -2
- package/dashboard/dist/assets/ScanCodesPage-FiYIYB-m.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-8CdOtbCD.js +0 -2
- package/dashboard/dist/assets/TasksListPage-BQNaSzCn.js +0 -2
- package/dashboard/dist/assets/ToolTestPanel-DvuLFWqQ.js +0 -2
- package/dashboard/dist/assets/TopicsPage-h-oyTeEJ.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-B0r2lQXk.js +0 -2
- package/dashboard/dist/assets/escalation-columns-DIigeTOK.js +0 -2
- package/dashboard/dist/assets/escalation-columns-DIigeTOK.js.map +0 -1
- package/dashboard/dist/assets/index-BMlQYOE1.js +0 -67
- package/dashboard/dist/assets/index-BMlQYOE1.js.map +0 -1
- package/dashboard/dist/assets/index-BNZknxFY.js +0 -2
- package/dashboard/dist/assets/index-Bpvfr4OW.css +0 -1
- package/dashboard/dist/assets/index-CegPUKpc.js +0 -3
- package/dashboard/dist/assets/index-CegPUKpc.js.map +0 -1
- package/dashboard/dist/assets/index-D7ESqn22.js +0 -2
- package/dashboard/dist/assets/index-DL83W7Gu.js +0 -2
- package/dashboard/dist/assets/index-DPLssnMW.js +0 -6
- package/dashboard/dist/assets/index-DPLssnMW.js.map +0 -1
- package/dashboard/dist/assets/index-DoETPlJP.js +0 -11
- package/dashboard/dist/assets/index-DoETPlJP.js.map +0 -1
- package/dashboard/dist/assets/index-DvxxrFBo.js +0 -2
- package/dashboard/dist/assets/metadata-display--TzK0REC.js +0 -2
- package/dashboard/dist/assets/metadata-display--TzK0REC.js.map +0 -1
- package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js +0 -2
- package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js.map +0 -1
- package/dashboard/dist/assets/seed-form-json-DvPsISxD.js +0 -2
- package/dashboard/dist/assets/seed-form-json-DvPsISxD.js.map +0 -1
- package/docs/compilation.md +0 -152
- package/docs/compiler.md +0 -311
- package/docs/contributing.md +0 -56
- package/docs/design-principles.md +0 -244
- package/docs/schema-exchange.md +0 -173
- package/docs/self-test.md +0 -106
- package/docs/story.md +0 -184
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.describeMissingLookupRefs = describeMissingLookupRefs;
|
|
4
|
+
const db_1 = require("../../lib/db");
|
|
5
|
+
const lookup_cache_1 = require("./lookup-cache");
|
|
6
|
+
const sql_1 = require("./sql");
|
|
7
|
+
/**
|
|
8
|
+
* One message per ref whose pinned edition does not exist, naming what does.
|
|
9
|
+
* Shape is the caller's job (assertLookupRefs); this answers the second
|
|
10
|
+
* question a saver has: is there an edition behind the pin.
|
|
11
|
+
*/
|
|
12
|
+
async function describeMissingLookupRefs(refs) {
|
|
13
|
+
const problems = [];
|
|
14
|
+
for (const ref of refs) {
|
|
15
|
+
const snapshot = await (0, lookup_cache_1.getKnowledgeSnapshot)(ref.domain, ref.key, ref.version);
|
|
16
|
+
if (snapshot)
|
|
17
|
+
continue;
|
|
18
|
+
const { rows } = await (0, db_1.getPool)().query(sql_1.LIST_KNOWLEDGE_VERSIONS, [ref.domain, ref.key]);
|
|
19
|
+
const versions = rows.map((r) => Number(r.version)).sort((a, b) => a - b);
|
|
20
|
+
const where = versions.length
|
|
21
|
+
? `editions: ${versions.map((v) => `v${v}`).join(', ')}`
|
|
22
|
+
: `no knowledge entry ${ref.domain}/${ref.key}`;
|
|
23
|
+
problems.push(`Lookup ref ${ref.domain}/${ref.key} v${ref.version} names no edition (${where})`);
|
|
24
|
+
}
|
|
25
|
+
return problems;
|
|
26
|
+
}
|
|
@@ -7,12 +7,12 @@ export declare const findTasksSchema: z.ZodObject<{
|
|
|
7
7
|
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
8
8
|
}, "strip", z.ZodTypeAny, {
|
|
9
9
|
limit: number;
|
|
10
|
-
status?: "
|
|
10
|
+
status?: "completed" | "pending" | "in_progress" | "needs_intervention" | "failed" | undefined;
|
|
11
11
|
workflow_type?: string | undefined;
|
|
12
12
|
workflow_id?: string | undefined;
|
|
13
13
|
origin_id?: string | undefined;
|
|
14
14
|
}, {
|
|
15
|
-
status?: "
|
|
15
|
+
status?: "completed" | "pending" | "in_progress" | "needs_intervention" | "failed" | undefined;
|
|
16
16
|
workflow_type?: string | undefined;
|
|
17
17
|
workflow_id?: string | undefined;
|
|
18
18
|
origin_id?: string | undefined;
|
|
@@ -54,12 +54,12 @@ export declare const waitForSchema: z.ZodObject<{
|
|
|
54
54
|
timeout: z.ZodOptional<z.ZodNumber>;
|
|
55
55
|
}, "strip", z.ZodTypeAny, {
|
|
56
56
|
selector: string;
|
|
57
|
-
page_id?: string | undefined;
|
|
58
57
|
timeout?: number | undefined;
|
|
58
|
+
page_id?: string | undefined;
|
|
59
59
|
}, {
|
|
60
60
|
selector: string;
|
|
61
|
-
page_id?: string | undefined;
|
|
62
61
|
timeout?: number | undefined;
|
|
62
|
+
page_id?: string | undefined;
|
|
63
63
|
}>;
|
|
64
64
|
export declare const evaluateSchema: z.ZodObject<{
|
|
65
65
|
page_id: z.ZodOptional<z.ZodString>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Types } from '@hotmeshio/hotmesh';
|
|
2
|
-
import { type EscalationLookupRef } from '../../types/escalation';
|
|
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
5
|
* role form version (lt_role_schemas) the resolve UI renders; `lookups` pins
|
|
@@ -116,8 +116,32 @@ export type ConditionEscalationConfig = Types.ConditionQueueConfig & {
|
|
|
116
116
|
* ```
|
|
117
117
|
*
|
|
118
118
|
* `timeout`/cancel semantics are unchanged (`false`/`null`); partially filled
|
|
119
|
-
* items persist on the terminal row for audit.
|
|
120
|
-
*
|
|
119
|
+
* items persist on the terminal row for audit. Add `partialOnTimeout: true`
|
|
120
|
+
* (hotmesh 0.29.0+) and the timer instead resumes with the items filled so
|
|
121
|
+
* far plus `$trigger: 'timeout'`. A plain resolve on a batch row remains an
|
|
122
|
+
* admin override that resolves the whole row with its payload.
|
|
123
|
+
*
|
|
124
|
+
* **Open accumulation — items arrive over time (hotmesh 0.29.0+).** Declare
|
|
125
|
+
* `accumulate` and the escalation holds items added via `accumulateItem`
|
|
126
|
+
* (HTTP: POST /:id/accumulate, /accumulate-by-signal-key,
|
|
127
|
+
* /accumulate-by-metadata) until `max` items are held, the `timeout` fires,
|
|
128
|
+
* or someone resolves the row. Every path except cancel delivers the ordered
|
|
129
|
+
* collection with the trigger that ended the wait, so a timeout is a
|
|
130
|
+
* delivery window, never a failure. Progress rides `metadata.accumulate_count`
|
|
131
|
+
* / `accumulate_max` / `accumulate_keys` as queryable facets; entries live in
|
|
132
|
+
* `envelope.accumulate_items`. Use {@link conditionalAccumulator} for the
|
|
133
|
+
* typed form:
|
|
134
|
+
*
|
|
135
|
+
* ```typescript
|
|
136
|
+
* const bin = await conditionalAccumulator<BagV1>(signalId, {
|
|
137
|
+
* role: 'bin',
|
|
138
|
+
* metadata: { binKey },
|
|
139
|
+
* accumulate: { max: 12 },
|
|
140
|
+
* timeout: '4h',
|
|
141
|
+
* });
|
|
142
|
+
* if (bin === null) { /* cancelled */ }
|
|
143
|
+
* else bin.$trigger; // 'count' | 'timeout' | 'resolve'
|
|
144
|
+
* ```
|
|
121
145
|
*
|
|
122
146
|
* **Resolution provenance — the reserved `$resolution` key.** When the resolve
|
|
123
147
|
* carries the resolver's identity (the API layer supplies it for interactive
|
|
@@ -155,3 +179,16 @@ export type ConditionEscalationConfig = Types.ConditionQueueConfig & {
|
|
|
155
179
|
export declare function conditional<T = Record<string, any>>(signalId: string, escalation?: ConditionEscalationConfig): Promise<T | false | null>;
|
|
156
180
|
/** @deprecated Alias of {@link conditional}. */
|
|
157
181
|
export declare const conditionLT: typeof conditional;
|
|
182
|
+
/** {@link ConditionEscalationConfig} with the accumulator declaration required. */
|
|
183
|
+
export type ConditionAccumulatorConfig = ConditionEscalationConfig & {
|
|
184
|
+
accumulate: AccumulateConfig;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* {@link conditional} for an open accumulator: the same wait, typed for the
|
|
188
|
+
* contract an accumulator row keeps. It resolves with the ordered
|
|
189
|
+
* `$accumulated` collection and its `$trigger` on every terminal path
|
|
190
|
+
* (`count`, `timeout`, `resolve`), so `false` is not in the return type;
|
|
191
|
+
* cancellation still yields `null`. `P` types each item's payload, `R` the
|
|
192
|
+
* manual resolver payload merged in on `resolve`.
|
|
193
|
+
*/
|
|
194
|
+
export declare function conditionalAccumulator<P = Record<string, any>, R extends Record<string, any> = Record<string, any>>(signalId: string, escalation: ConditionAccumulatorConfig): Promise<AccumulatorResult<P, R> | null>;
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.conditionLT = void 0;
|
|
37
37
|
exports.conditional = conditional;
|
|
38
|
+
exports.conditionalAccumulator = conditionalAccumulator;
|
|
38
39
|
const hotmesh_1 = require("@hotmeshio/hotmesh");
|
|
39
40
|
const escalation_1 = require("../../types/escalation");
|
|
40
41
|
const interceptorActivities = __importStar(require("../interceptor/activities"));
|
|
@@ -162,8 +163,32 @@ function toEngineConfig(escalation) {
|
|
|
162
163
|
* ```
|
|
163
164
|
*
|
|
164
165
|
* `timeout`/cancel semantics are unchanged (`false`/`null`); partially filled
|
|
165
|
-
* items persist on the terminal row for audit.
|
|
166
|
-
*
|
|
166
|
+
* items persist on the terminal row for audit. Add `partialOnTimeout: true`
|
|
167
|
+
* (hotmesh 0.29.0+) and the timer instead resumes with the items filled so
|
|
168
|
+
* far plus `$trigger: 'timeout'`. A plain resolve on a batch row remains an
|
|
169
|
+
* admin override that resolves the whole row with its payload.
|
|
170
|
+
*
|
|
171
|
+
* **Open accumulation — items arrive over time (hotmesh 0.29.0+).** Declare
|
|
172
|
+
* `accumulate` and the escalation holds items added via `accumulateItem`
|
|
173
|
+
* (HTTP: POST /:id/accumulate, /accumulate-by-signal-key,
|
|
174
|
+
* /accumulate-by-metadata) until `max` items are held, the `timeout` fires,
|
|
175
|
+
* or someone resolves the row. Every path except cancel delivers the ordered
|
|
176
|
+
* collection with the trigger that ended the wait, so a timeout is a
|
|
177
|
+
* delivery window, never a failure. Progress rides `metadata.accumulate_count`
|
|
178
|
+
* / `accumulate_max` / `accumulate_keys` as queryable facets; entries live in
|
|
179
|
+
* `envelope.accumulate_items`. Use {@link conditionalAccumulator} for the
|
|
180
|
+
* typed form:
|
|
181
|
+
*
|
|
182
|
+
* ```typescript
|
|
183
|
+
* const bin = await conditionalAccumulator<BagV1>(signalId, {
|
|
184
|
+
* role: 'bin',
|
|
185
|
+
* metadata: { binKey },
|
|
186
|
+
* accumulate: { max: 12 },
|
|
187
|
+
* timeout: '4h',
|
|
188
|
+
* });
|
|
189
|
+
* if (bin === null) { /* cancelled */ }
|
|
190
|
+
* else bin.$trigger; // 'count' | 'timeout' | 'resolve'
|
|
191
|
+
* ```
|
|
167
192
|
*
|
|
168
193
|
* **Resolution provenance — the reserved `$resolution` key.** When the resolve
|
|
169
194
|
* carries the resolver's identity (the API layer supplies it for interactive
|
|
@@ -231,3 +256,18 @@ async function conditional(signalId, escalation) {
|
|
|
231
256
|
}
|
|
232
257
|
/** @deprecated Alias of {@link conditional}. */
|
|
233
258
|
exports.conditionLT = conditional;
|
|
259
|
+
/**
|
|
260
|
+
* {@link conditional} for an open accumulator: the same wait, typed for the
|
|
261
|
+
* contract an accumulator row keeps. It resolves with the ordered
|
|
262
|
+
* `$accumulated` collection and its `$trigger` on every terminal path
|
|
263
|
+
* (`count`, `timeout`, `resolve`), so `false` is not in the return type;
|
|
264
|
+
* cancellation still yields `null`. `P` types each item's payload, `R` the
|
|
265
|
+
* manual resolver payload merged in on `resolve`.
|
|
266
|
+
*/
|
|
267
|
+
async function conditionalAccumulator(signalId, escalation) {
|
|
268
|
+
const result = await conditional(signalId, escalation);
|
|
269
|
+
if (result === false) {
|
|
270
|
+
throw new Error(`Accumulator wait ${signalId} resumed with false; expected a delivered collection`);
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
@@ -153,6 +153,7 @@ async function updateRoleMetadata(role, input) {
|
|
|
153
153
|
provided('ops_home_default'), input.ops_home_default ?? null,
|
|
154
154
|
provided('entity_facet'), input.entity_facet ?? null,
|
|
155
155
|
provided('entity_state_source'), input.entity_state_source ?? null,
|
|
156
|
+
provided('portals'), input.portals != null ? JSON.stringify(input.portals) : null,
|
|
156
157
|
]);
|
|
157
158
|
if (!rows[0])
|
|
158
159
|
return null;
|
|
@@ -14,10 +14,12 @@ exports.STARTUP_CHANGE_SUMMARY = 'startup apply (code)';
|
|
|
14
14
|
const METADATA_FIELDS = [
|
|
15
15
|
'title', 'description', 'form_schema', 'metadata_schema', 'list_schema',
|
|
16
16
|
'properties', 'ops_visible', 'ops_home_default', 'parent_role',
|
|
17
|
-
'upstream_roles', 'default_pins', 'enforce_schema', 'sla_minutes',
|
|
17
|
+
'upstream_roles', 'default_pins', 'portals', 'enforce_schema', 'sla_minutes',
|
|
18
18
|
'target_per_hour', 'worker_count', 'priority_threshold_minutes',
|
|
19
19
|
'priority_facet', 'entity_facet', 'entity_state_source',
|
|
20
20
|
];
|
|
21
|
+
// Arrays whose order is meaning (portals and their rows), compared as declared.
|
|
22
|
+
const ORDERED_ARRAY_FIELDS = new Set(['portals']);
|
|
21
23
|
/**
|
|
22
24
|
* Compare one declared field against the stored row. jsonb round-trips lose
|
|
23
25
|
* key order, so structured values must be compared as parsed values — never
|
|
@@ -25,6 +27,9 @@ const METADATA_FIELDS = [
|
|
|
25
27
|
*/
|
|
26
28
|
function fieldDiffers(field, declared, row) {
|
|
27
29
|
const stored = row[field];
|
|
30
|
+
if (Array.isArray(declared) && ORDERED_ARRAY_FIELDS.has(field)) {
|
|
31
|
+
return !(0, node_util_1.isDeepStrictEqual)(declared, stored ?? null);
|
|
32
|
+
}
|
|
28
33
|
if (Array.isArray(declared)) {
|
|
29
34
|
const a = [...declared].sort();
|
|
30
35
|
const b = Array.isArray(stored) ? [...stored].sort() : [];
|
|
@@ -21,7 +21,7 @@ export declare const LIST_ROLES = "\n SELECT role FROM lt_roles ORDER BY role";
|
|
|
21
21
|
*/
|
|
22
22
|
export declare const LIST_CONFIGURED_ROLES = "\n SELECT role FROM lt_roles\n WHERE title IS NOT NULL OR form_schema IS NOT NULL\n ORDER BY role";
|
|
23
23
|
/** One role's full metadata row (plus upstream inputs) for startup diffing. */
|
|
24
|
-
export declare const GET_ROLE_ROW = "\n SELECT\n r.role, r.title, r.description, r.form_schema, r.metadata_schema,\n r.properties, r.ops_visible, r.ops_home_default, r.parent_role,\n r.sla_minutes, r.target_per_hour, r.worker_count,\n r.priority_threshold_minutes, r.priority_facet,\n r.entity_facet, r.entity_state_source,\n r.list_schema, r.default_pins, r.enforce_schema,\n r.current_schema_version, r.current_list_schema_version,\n COALESCE((SELECT array_agg(u.upstream_role ORDER BY u.upstream_role)\n FROM lt_role_upstreams u WHERE u.role = r.role), '{}') AS upstream_roles\n FROM lt_roles r\n WHERE r.role = $1";
|
|
24
|
+
export declare const GET_ROLE_ROW = "\n SELECT\n r.role, r.title, r.description, r.form_schema, r.metadata_schema,\n r.properties, r.ops_visible, r.ops_home_default, r.parent_role,\n r.sla_minutes, r.target_per_hour, r.worker_count,\n r.priority_threshold_minutes, r.priority_facet,\n r.entity_facet, r.entity_state_source,\n r.list_schema, r.default_pins, r.portals, r.enforce_schema,\n r.current_schema_version, r.current_list_schema_version,\n COALESCE((SELECT array_agg(u.upstream_role ORDER BY u.upstream_role)\n FROM lt_role_upstreams u WHERE u.role = r.role), '{}') AS upstream_roles\n FROM lt_roles r\n WHERE r.role = $1";
|
|
25
25
|
export declare const DELETE_ROLE = "\n DELETE FROM lt_roles WHERE role = $1";
|
|
26
26
|
/**
|
|
27
27
|
* PATCH semantics in ONE atomic statement: each column has a boolean
|
|
@@ -66,8 +66,11 @@ export declare const DELETE_ROLE = "\n DELETE FROM lt_roles WHERE role = $1";
|
|
|
66
66
|
* entity_state_source ($39 = provided sentinel, $40 = value) is unversioned
|
|
67
67
|
* config: 'role' | 'subtype' — how this role names its contribution to the
|
|
68
68
|
* entity's state space (the station itself, or its subtypes).
|
|
69
|
+
*
|
|
70
|
+
* portals ($41 = provided sentinel, $42 = value) is unversioned config: the
|
|
71
|
+
* role's named portal views, each a matrix of pin cells rendered as one page.
|
|
69
72
|
*/
|
|
70
|
-
export declare const UPDATE_ROLE_METADATA = "\n WITH home_clear AS (\n UPDATE lt_roles SET ops_home_default = false\n WHERE $35::boolean AND COALESCE($36::boolean, false) AND role <> $1 AND ops_home_default\n ), updated AS (\n UPDATE lt_roles SET\n title = CASE WHEN $2::boolean THEN $3 ELSE title END,\n description = CASE WHEN $4::boolean THEN $5 ELSE description END,\n form_schema = CASE WHEN $6::boolean THEN $7::jsonb ELSE form_schema END,\n metadata_schema = CASE WHEN $8::boolean THEN $9::jsonb ELSE metadata_schema END,\n properties = CASE WHEN $10::boolean THEN COALESCE($11::jsonb, '{}'::jsonb) ELSE properties END,\n ops_visible = CASE WHEN $12::boolean THEN $13::boolean ELSE ops_visible END,\n parent_role = CASE WHEN $14::boolean THEN $15 ELSE parent_role END,\n sla_minutes = CASE WHEN $16::boolean THEN $17::numeric ELSE sla_minutes END,\n target_per_hour = CASE WHEN $18::boolean THEN $19::numeric ELSE target_per_hour END,\n worker_count = CASE WHEN $20::boolean THEN $21::int ELSE worker_count END,\n priority_threshold_minutes\n = CASE WHEN $22::boolean THEN $23::numeric ELSE priority_threshold_minutes END,\n priority_facet = CASE WHEN $24::boolean THEN $25 ELSE priority_facet END,\n entity_facet = CASE WHEN $37::boolean THEN $38 ELSE entity_facet END,\n entity_state_source\n = CASE WHEN $39::boolean THEN COALESCE($40, 'role') ELSE entity_state_source END,\n list_schema = CASE WHEN $29::boolean THEN $30::jsonb ELSE list_schema END,\n default_pins = CASE WHEN $31::boolean THEN $32::jsonb ELSE default_pins END,\n enforce_schema = CASE WHEN $33::boolean THEN COALESCE($34::boolean, false) ELSE enforce_schema END,\n ops_home_default = CASE WHEN $35::boolean THEN COALESCE($36::boolean, false) ELSE ops_home_default END,\n current_schema_version = CASE\n WHEN ($6::boolean AND $7::jsonb IS DISTINCT FROM form_schema)\n OR ($8::boolean AND $9::jsonb IS DISTINCT FROM metadata_schema)\n THEN COALESCE(current_schema_version, 0) + 1\n ELSE current_schema_version END,\n current_list_schema_version = CASE\n WHEN $29::boolean AND $30::jsonb IS DISTINCT FROM list_schema\n THEN COALESCE(current_list_schema_version, 0) + 1\n ELSE current_list_schema_version END\n WHERE role = $1\n RETURNING\n role, title, description, form_schema, metadata_schema, properties,\n ops_visible, ops_home_default, parent_role, sla_minutes, target_per_hour, worker_count,\n priority_threshold_minutes, priority_facet, entity_facet, entity_state_source,\n current_schema_version, list_schema, current_list_schema_version,\n default_pins, enforce_schema\n ), snapshot AS (\n INSERT INTO lt_role_schemas (role, version, form_schema, metadata_schema, change_summary)\n SELECT role, current_schema_version, form_schema, metadata_schema, $26\n FROM updated\n WHERE ($6::boolean OR $8::boolean) AND current_schema_version IS NOT NULL\n ON CONFLICT (role, version) DO NOTHING\n ), list_snapshot AS (\n INSERT INTO lt_role_list_schemas (role, version, list_schema, change_summary)\n SELECT role, current_list_schema_version, list_schema, $26\n FROM updated\n WHERE $29::boolean AND current_list_schema_version IS NOT NULL\n ON CONFLICT (role, version) DO NOTHING\n ), upstream_prune AS (\n DELETE FROM lt_role_upstreams\n WHERE $27::boolean AND role = $1 AND upstream_role <> ALL($28::text[])\n ), upstream_add AS (\n INSERT INTO lt_role_upstreams (role, upstream_role)\n SELECT $1, u FROM unnest($28::text[]) AS u\n WHERE $27::boolean\n ON CONFLICT DO NOTHING\n )\n SELECT * FROM updated";
|
|
73
|
+
export declare const UPDATE_ROLE_METADATA = "\n WITH home_clear AS (\n UPDATE lt_roles SET ops_home_default = false\n WHERE $35::boolean AND COALESCE($36::boolean, false) AND role <> $1 AND ops_home_default\n ), updated AS (\n UPDATE lt_roles SET\n title = CASE WHEN $2::boolean THEN $3 ELSE title END,\n description = CASE WHEN $4::boolean THEN $5 ELSE description END,\n form_schema = CASE WHEN $6::boolean THEN $7::jsonb ELSE form_schema END,\n metadata_schema = CASE WHEN $8::boolean THEN $9::jsonb ELSE metadata_schema END,\n properties = CASE WHEN $10::boolean THEN COALESCE($11::jsonb, '{}'::jsonb) ELSE properties END,\n ops_visible = CASE WHEN $12::boolean THEN $13::boolean ELSE ops_visible END,\n parent_role = CASE WHEN $14::boolean THEN $15 ELSE parent_role END,\n sla_minutes = CASE WHEN $16::boolean THEN $17::numeric ELSE sla_minutes END,\n target_per_hour = CASE WHEN $18::boolean THEN $19::numeric ELSE target_per_hour END,\n worker_count = CASE WHEN $20::boolean THEN $21::int ELSE worker_count END,\n priority_threshold_minutes\n = CASE WHEN $22::boolean THEN $23::numeric ELSE priority_threshold_minutes END,\n priority_facet = CASE WHEN $24::boolean THEN $25 ELSE priority_facet END,\n entity_facet = CASE WHEN $37::boolean THEN $38 ELSE entity_facet END,\n entity_state_source\n = CASE WHEN $39::boolean THEN COALESCE($40, 'role') ELSE entity_state_source END,\n list_schema = CASE WHEN $29::boolean THEN $30::jsonb ELSE list_schema END,\n default_pins = CASE WHEN $31::boolean THEN $32::jsonb ELSE default_pins END,\n portals = CASE WHEN $41::boolean THEN $42::jsonb ELSE portals END,\n enforce_schema = CASE WHEN $33::boolean THEN COALESCE($34::boolean, false) ELSE enforce_schema END,\n ops_home_default = CASE WHEN $35::boolean THEN COALESCE($36::boolean, false) ELSE ops_home_default END,\n current_schema_version = CASE\n WHEN ($6::boolean AND $7::jsonb IS DISTINCT FROM form_schema)\n OR ($8::boolean AND $9::jsonb IS DISTINCT FROM metadata_schema)\n THEN COALESCE(current_schema_version, 0) + 1\n ELSE current_schema_version END,\n current_list_schema_version = CASE\n WHEN $29::boolean AND $30::jsonb IS DISTINCT FROM list_schema\n THEN COALESCE(current_list_schema_version, 0) + 1\n ELSE current_list_schema_version END\n WHERE role = $1\n RETURNING\n role, title, description, form_schema, metadata_schema, properties,\n ops_visible, ops_home_default, parent_role, sla_minutes, target_per_hour, worker_count,\n priority_threshold_minutes, priority_facet, entity_facet, entity_state_source,\n current_schema_version, list_schema, current_list_schema_version,\n default_pins, portals, enforce_schema\n ), snapshot AS (\n INSERT INTO lt_role_schemas (role, version, form_schema, metadata_schema, change_summary)\n SELECT role, current_schema_version, form_schema, metadata_schema, $26\n FROM updated\n WHERE ($6::boolean OR $8::boolean) AND current_schema_version IS NOT NULL\n ON CONFLICT (role, version) DO NOTHING\n ), list_snapshot AS (\n INSERT INTO lt_role_list_schemas (role, version, list_schema, change_summary)\n SELECT role, current_list_schema_version, list_schema, $26\n FROM updated\n WHERE $29::boolean AND current_list_schema_version IS NOT NULL\n ON CONFLICT (role, version) DO NOTHING\n ), upstream_prune AS (\n DELETE FROM lt_role_upstreams\n WHERE $27::boolean AND role = $1 AND upstream_role <> ALL($28::text[])\n ), upstream_add AS (\n INSERT INTO lt_role_upstreams (role, upstream_role)\n SELECT $1, u FROM unnest($28::text[]) AS u\n WHERE $27::boolean\n ON CONFLICT DO NOTHING\n )\n SELECT * FROM updated";
|
|
71
74
|
export declare const GET_ROLE_FORM_SCHEMA = "\n SELECT form_schema FROM lt_roles WHERE role = $1";
|
|
72
75
|
/**
|
|
73
76
|
* The set of roles with server-side resolver validation turned on. Small and
|
|
@@ -92,7 +95,7 @@ export declare const GET_ROLE_LIST_SCHEMA_VERSION = "\n SELECT s.role, s.versio
|
|
|
92
95
|
* never versioned its list schema still answers, with version NULL).
|
|
93
96
|
*/
|
|
94
97
|
export declare const GET_ROLE_LIST_SCHEMA_CURRENT = "\n SELECT r.role, r.current_list_schema_version AS version, r.list_schema,\n s.change_summary, s.created_at,\n r.current_list_schema_version AS latest_version\n FROM lt_roles r\n LEFT JOIN lt_role_list_schemas s\n ON s.role = r.role AND s.version = r.current_list_schema_version\n WHERE r.role = $1";
|
|
95
|
-
export declare const LIST_ROLES_WITH_DETAILS = "\n WITH\n user_counts AS (\n SELECT role, COUNT(DISTINCT user_id)::int AS cnt\n FROM lt_user_roles\n GROUP BY role\n ),\n chain_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM (\n SELECT source_role AS role FROM lt_config_role_escalations\n UNION ALL\n SELECT target_role AS role FROM lt_config_role_escalations\n ) c\n GROUP BY role\n ),\n workflow_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM lt_config_roles\n GROUP BY role\n ),\n upstreams AS (\n SELECT role, array_agg(upstream_role ORDER BY upstream_role) AS ups\n FROM lt_role_upstreams\n GROUP BY role\n )\n SELECT\n r.role,\n r.title,\n r.description,\n r.form_schema,\n r.metadata_schema,\n r.properties,\n r.ops_visible,\n r.ops_home_default,\n r.parent_role,\n r.sla_minutes,\n r.target_per_hour,\n r.worker_count,\n r.priority_threshold_minutes,\n r.priority_facet,\n r.entity_facet,\n r.entity_state_source,\n r.current_schema_version,\n r.list_schema,\n r.current_list_schema_version,\n r.default_pins,\n r.enforce_schema,\n COALESCE(up.ups, '{}') AS upstream_roles,\n COALESCE(uc.cnt, 0) AS user_count,\n COALESCE(cc.cnt, 0) AS chain_count,\n COALESCE(wc.cnt, 0) AS workflow_count\n FROM lt_roles r\n LEFT JOIN user_counts uc ON uc.role = r.role\n LEFT JOIN chain_counts cc ON cc.role = r.role\n LEFT JOIN workflow_counts wc ON wc.role = r.role\n LEFT JOIN upstreams up ON up.role = r.role\n ORDER BY r.role";
|
|
98
|
+
export declare const LIST_ROLES_WITH_DETAILS = "\n WITH\n user_counts AS (\n SELECT role, COUNT(DISTINCT user_id)::int AS cnt\n FROM lt_user_roles\n GROUP BY role\n ),\n chain_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM (\n SELECT source_role AS role FROM lt_config_role_escalations\n UNION ALL\n SELECT target_role AS role FROM lt_config_role_escalations\n ) c\n GROUP BY role\n ),\n workflow_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM lt_config_roles\n GROUP BY role\n ),\n upstreams AS (\n SELECT role, array_agg(upstream_role ORDER BY upstream_role) AS ups\n FROM lt_role_upstreams\n GROUP BY role\n )\n SELECT\n r.role,\n r.title,\n r.description,\n r.form_schema,\n r.metadata_schema,\n r.properties,\n r.ops_visible,\n r.ops_home_default,\n r.parent_role,\n r.sla_minutes,\n r.target_per_hour,\n r.worker_count,\n r.priority_threshold_minutes,\n r.priority_facet,\n r.entity_facet,\n r.entity_state_source,\n r.current_schema_version,\n r.list_schema,\n r.current_list_schema_version,\n r.default_pins,\n r.portals,\n r.enforce_schema,\n COALESCE(up.ups, '{}') AS upstream_roles,\n COALESCE(uc.cnt, 0) AS user_count,\n COALESCE(cc.cnt, 0) AS chain_count,\n COALESCE(wc.cnt, 0) AS workflow_count\n FROM lt_roles r\n LEFT JOIN user_counts uc ON uc.role = r.role\n LEFT JOIN chain_counts cc ON cc.role = r.role\n LEFT JOIN workflow_counts wc ON wc.role = r.role\n LEFT JOIN upstreams up ON up.role = r.role\n ORDER BY r.role";
|
|
96
99
|
export declare const COUNT_USER_ROLE_REFS = "\n SELECT COUNT(*)::int AS cnt FROM lt_user_roles WHERE role = $1";
|
|
97
100
|
export declare const COUNT_CHAIN_REFS = "\n SELECT COUNT(*)::int AS cnt\n FROM lt_config_role_escalations\n WHERE source_role = $1 OR target_role = $1";
|
|
98
101
|
export declare const COUNT_WORKFLOW_REFS = "\n SELECT COUNT(*)::int AS cnt FROM lt_config_roles WHERE role = $1";
|
|
@@ -64,7 +64,7 @@ exports.GET_ROLE_ROW = `
|
|
|
64
64
|
r.sla_minutes, r.target_per_hour, r.worker_count,
|
|
65
65
|
r.priority_threshold_minutes, r.priority_facet,
|
|
66
66
|
r.entity_facet, r.entity_state_source,
|
|
67
|
-
r.list_schema, r.default_pins, r.enforce_schema,
|
|
67
|
+
r.list_schema, r.default_pins, r.portals, r.enforce_schema,
|
|
68
68
|
r.current_schema_version, r.current_list_schema_version,
|
|
69
69
|
COALESCE((SELECT array_agg(u.upstream_role ORDER BY u.upstream_role)
|
|
70
70
|
FROM lt_role_upstreams u WHERE u.role = r.role), '{}') AS upstream_roles
|
|
@@ -115,6 +115,9 @@ exports.DELETE_ROLE = `
|
|
|
115
115
|
* entity_state_source ($39 = provided sentinel, $40 = value) is unversioned
|
|
116
116
|
* config: 'role' | 'subtype' — how this role names its contribution to the
|
|
117
117
|
* entity's state space (the station itself, or its subtypes).
|
|
118
|
+
*
|
|
119
|
+
* portals ($41 = provided sentinel, $42 = value) is unversioned config: the
|
|
120
|
+
* role's named portal views, each a matrix of pin cells rendered as one page.
|
|
118
121
|
*/
|
|
119
122
|
exports.UPDATE_ROLE_METADATA = `
|
|
120
123
|
WITH home_clear AS (
|
|
@@ -140,6 +143,7 @@ exports.UPDATE_ROLE_METADATA = `
|
|
|
140
143
|
= CASE WHEN $39::boolean THEN COALESCE($40, 'role') ELSE entity_state_source END,
|
|
141
144
|
list_schema = CASE WHEN $29::boolean THEN $30::jsonb ELSE list_schema END,
|
|
142
145
|
default_pins = CASE WHEN $31::boolean THEN $32::jsonb ELSE default_pins END,
|
|
146
|
+
portals = CASE WHEN $41::boolean THEN $42::jsonb ELSE portals END,
|
|
143
147
|
enforce_schema = CASE WHEN $33::boolean THEN COALESCE($34::boolean, false) ELSE enforce_schema END,
|
|
144
148
|
ops_home_default = CASE WHEN $35::boolean THEN COALESCE($36::boolean, false) ELSE ops_home_default END,
|
|
145
149
|
current_schema_version = CASE
|
|
@@ -157,7 +161,7 @@ exports.UPDATE_ROLE_METADATA = `
|
|
|
157
161
|
ops_visible, ops_home_default, parent_role, sla_minutes, target_per_hour, worker_count,
|
|
158
162
|
priority_threshold_minutes, priority_facet, entity_facet, entity_state_source,
|
|
159
163
|
current_schema_version, list_schema, current_list_schema_version,
|
|
160
|
-
default_pins, enforce_schema
|
|
164
|
+
default_pins, portals, enforce_schema
|
|
161
165
|
), snapshot AS (
|
|
162
166
|
INSERT INTO lt_role_schemas (role, version, form_schema, metadata_schema, change_summary)
|
|
163
167
|
SELECT role, current_schema_version, form_schema, metadata_schema, $26
|
|
@@ -304,6 +308,7 @@ exports.LIST_ROLES_WITH_DETAILS = `
|
|
|
304
308
|
r.list_schema,
|
|
305
309
|
r.current_list_schema_version,
|
|
306
310
|
r.default_pins,
|
|
311
|
+
r.portals,
|
|
307
312
|
r.enforce_schema,
|
|
308
313
|
COALESCE(up.ups, '{}') AS upstream_roles,
|
|
309
314
|
COALESCE(uc.cnt, 0) AS user_count,
|
|
@@ -35,6 +35,35 @@ export declare const ROLE_PROPERTY_KEYS: {
|
|
|
35
35
|
* binding. Values are strings — jsonb containment is type-sensitive, so
|
|
36
36
|
* numeric facets are not templatable.
|
|
37
37
|
*/
|
|
38
|
+
/** One pinned view: a label over a dashboard-relative URL, optionally badged with its live count. */
|
|
39
|
+
export interface RolePin {
|
|
40
|
+
label: string;
|
|
41
|
+
url: string;
|
|
42
|
+
badge?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/** Bounds for a role's portals: how many, and the matrix of each (rows of cells, each cell a pin). */
|
|
45
|
+
export declare const PORTAL_LIMITS: {
|
|
46
|
+
readonly MAX_PORTALS: 12;
|
|
47
|
+
readonly MAX_ROWS: 4;
|
|
48
|
+
readonly MAX_COLS: 6;
|
|
49
|
+
readonly MAX_COUNTS: 8;
|
|
50
|
+
};
|
|
51
|
+
/** One count tile above a portal: a label, a blurb, and the live total of an escalations-list URL. */
|
|
52
|
+
export interface PortalCount {
|
|
53
|
+
label: string;
|
|
54
|
+
url: string;
|
|
55
|
+
blurb?: string;
|
|
56
|
+
}
|
|
57
|
+
/** A portal key: a short url-safe slug, unique within the role. */
|
|
58
|
+
export declare const PORTAL_KEY: RegExp;
|
|
59
|
+
/** One named portal view: a matrix of pins rendered as one page. */
|
|
60
|
+
export interface RolePortal {
|
|
61
|
+
key: string;
|
|
62
|
+
label: string;
|
|
63
|
+
rows: RolePin[][];
|
|
64
|
+
/** Count tiles shown above the panels, each the live total of a list URL. */
|
|
65
|
+
counts?: PortalCount[];
|
|
66
|
+
}
|
|
38
67
|
export interface RoleLinkVariable {
|
|
39
68
|
name: string;
|
|
40
69
|
label?: string;
|
|
@@ -125,11 +154,12 @@ export interface RoleDetail {
|
|
|
125
154
|
* in their Pinned nav section (marked role-provided); users promote, hide,
|
|
126
155
|
* or reorder them through their own preferences. URLs only — never data.
|
|
127
156
|
*/
|
|
128
|
-
default_pins:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
157
|
+
default_pins: RolePin[] | null;
|
|
158
|
+
/**
|
|
159
|
+
* The role's portals: named matrices of pins, each rendered as one page of
|
|
160
|
+
* live list panels at /portal/:role/:portal. Null when the role declares none.
|
|
161
|
+
*/
|
|
162
|
+
portals: RolePortal[] | null;
|
|
133
163
|
/**
|
|
134
164
|
* Roles this station draws input from that live in OTHER sequences.
|
|
135
165
|
* parent_role is the single "prior step" placing the role in one sequence;
|
|
@@ -185,11 +215,9 @@ export interface UpdateRoleInput {
|
|
|
185
215
|
metadata_schema?: Record<string, any> | null;
|
|
186
216
|
/** JSON contract that richly formats this role's escalation list page. */
|
|
187
217
|
list_schema?: Record<string, any> | null;
|
|
188
|
-
default_pins?:
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
badge?: boolean;
|
|
192
|
-
}[] | null;
|
|
218
|
+
default_pins?: RolePin[] | null;
|
|
219
|
+
/** The role's named portals; null clears. */
|
|
220
|
+
portals?: RolePortal[] | null;
|
|
193
221
|
properties?: Record<string, any> | null;
|
|
194
222
|
ops_visible?: boolean;
|
|
195
223
|
/** Make this role's sequence the home Pace Board's default segment (single-holder). */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/** Type definitions for the role and escalation chain service. */
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.ROLE_PROPERTY_KEYS = void 0;
|
|
4
|
+
exports.PORTAL_KEY = exports.PORTAL_LIMITS = exports.ROLE_PROPERTY_KEYS = void 0;
|
|
5
5
|
/**
|
|
6
6
|
* Reserved keys inside `lt_roles.properties`. Everything else in the bag is
|
|
7
7
|
* user-owned. Readers type-guard (the bag is open, PATCH can write anything).
|
|
@@ -27,3 +27,12 @@ exports.ROLE_PROPERTY_KEYS = {
|
|
|
27
27
|
KIOSK: 'kiosk',
|
|
28
28
|
LINK_VARIABLES: 'link_variables',
|
|
29
29
|
};
|
|
30
|
+
/** Bounds for a role's portals: how many, and the matrix of each (rows of cells, each cell a pin). */
|
|
31
|
+
exports.PORTAL_LIMITS = {
|
|
32
|
+
MAX_PORTALS: 12,
|
|
33
|
+
MAX_ROWS: 4,
|
|
34
|
+
MAX_COLS: 6,
|
|
35
|
+
MAX_COUNTS: 8,
|
|
36
|
+
};
|
|
37
|
+
/** A portal key: a short url-safe slug, unique within the role. */
|
|
38
|
+
exports.PORTAL_KEY = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
@@ -4,6 +4,7 @@ exports.assertValidScheme = assertValidScheme;
|
|
|
4
4
|
exports.assertValidIdentityRule = assertValidIdentityRule;
|
|
5
5
|
exports.assertValidSteps = assertValidSteps;
|
|
6
6
|
const types_1 = require("../../types");
|
|
7
|
+
const facet_sql_1 = require("../escalation/facet-sql");
|
|
7
8
|
const VALID_VERBS = new Set(Object.values(types_1.SCAN_VERBS));
|
|
8
9
|
/** Double-scan selection tokens — short, label-printable, never scheme-shaped. */
|
|
9
10
|
const CHOICE_CODE = /^[A-Za-z0-9_-]{1,32}$/;
|
|
@@ -145,6 +146,21 @@ function assertValidSteps(steps) {
|
|
|
145
146
|
if (step.verb === types_1.SCAN_VERBS.RESOLVE && !step.params?.resolverPayload) {
|
|
146
147
|
throw new Error(`${at}: resolve requires params.resolverPayload`);
|
|
147
148
|
}
|
|
149
|
+
if (step.verb === types_1.SCAN_VERBS.ACCUMULATE) {
|
|
150
|
+
const options = step.params?.accumulate;
|
|
151
|
+
if (options !== undefined && (!options || typeof options !== 'object' || Array.isArray(options))) {
|
|
152
|
+
throw new Error(`${at}: params.accumulate must be an object`);
|
|
153
|
+
}
|
|
154
|
+
if (options?.containerFacet !== undefined && !facet_sql_1.FACET_KEY.test(String(options.containerFacet))) {
|
|
155
|
+
throw new Error(`${at}: params.accumulate.containerFacet must be a facet key`);
|
|
156
|
+
}
|
|
157
|
+
if (options?.containerRoles !== undefined && !Array.isArray(options.containerRoles)) {
|
|
158
|
+
throw new Error(`${at}: params.accumulate.containerRoles must be an array`);
|
|
159
|
+
}
|
|
160
|
+
if (!options?.containerFacet && !step.params?.itemKey) {
|
|
161
|
+
throw new Error(`${at}: accumulate requires params.itemKey or params.accumulate.containerFacet`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
148
164
|
if (step.query && step.query.roles && !Array.isArray(step.query.roles)) {
|
|
149
165
|
throw new Error(`${at}: query.roles must be an array`);
|
|
150
166
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widgets that render from the escalation context and produce no answer of
|
|
3
|
+
* their own: navigation links, embedded records and lists, and invoke
|
|
4
|
+
* controls. Their form slot exists only to place them in the layout, so
|
|
5
|
+
* the payload mapper drops them and the server never sees a value.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DISPLAY_ONLY_WIDGET_NAMES: {
|
|
8
|
+
readonly LINK: "link";
|
|
9
|
+
readonly ESCALATION: "escalation";
|
|
10
|
+
readonly ESCALATION_LIST: "escalation-list";
|
|
11
|
+
readonly INVOKE: "invoke";
|
|
12
|
+
};
|
|
13
|
+
export declare const DISPLAY_ONLY_WIDGETS: ReadonlySet<string>;
|
|
14
|
+
export declare function isDisplayOnlyWidget(name: unknown): boolean;
|
|
15
|
+
/** Whether a property definition renders a display-only widget. */
|
|
16
|
+
export declare function isDisplayOnlyField(def: Record<string, unknown> | null | undefined): boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DISPLAY_ONLY_WIDGETS = exports.DISPLAY_ONLY_WIDGET_NAMES = void 0;
|
|
4
|
+
exports.isDisplayOnlyWidget = isDisplayOnlyWidget;
|
|
5
|
+
exports.isDisplayOnlyField = isDisplayOnlyField;
|
|
6
|
+
/**
|
|
7
|
+
* Widgets that render from the escalation context and produce no answer of
|
|
8
|
+
* their own: navigation links, embedded records and lists, and invoke
|
|
9
|
+
* controls. Their form slot exists only to place them in the layout, so
|
|
10
|
+
* the payload mapper drops them and the server never sees a value.
|
|
11
|
+
*/
|
|
12
|
+
exports.DISPLAY_ONLY_WIDGET_NAMES = {
|
|
13
|
+
LINK: 'link',
|
|
14
|
+
ESCALATION: 'escalation',
|
|
15
|
+
ESCALATION_LIST: 'escalation-list',
|
|
16
|
+
INVOKE: 'invoke',
|
|
17
|
+
};
|
|
18
|
+
exports.DISPLAY_ONLY_WIDGETS = new Set(Object.values(exports.DISPLAY_ONLY_WIDGET_NAMES));
|
|
19
|
+
function isDisplayOnlyWidget(name) {
|
|
20
|
+
return typeof name === 'string' && exports.DISPLAY_ONLY_WIDGETS.has(name);
|
|
21
|
+
}
|
|
22
|
+
/** Whether a property definition renders a display-only widget. */
|
|
23
|
+
function isDisplayOnlyField(def) {
|
|
24
|
+
return isDisplayOnlyWidget(def?.['x-lt-widget']);
|
|
25
|
+
}
|
|
@@ -38,6 +38,7 @@ export declare function resolveChecklistDefault(fieldSchema: Record<string, unkn
|
|
|
38
38
|
* which remains the at-least-one check.
|
|
39
39
|
*/
|
|
40
40
|
export declare function validateRequireAll(value: unknown, fieldSchema: Record<string, unknown> | undefined, ctx?: Record<string, unknown>): string | undefined;
|
|
41
|
+
export declare const INVALID_JSON = "Invalid JSON";
|
|
41
42
|
/**
|
|
42
43
|
* Runtime type check against the field's declared JSON Schema `type`. Guards
|
|
43
44
|
* the payload contract for API-first callers (a form widget already produces
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.X_LT_DEFAULT_CHECKED = void 0;
|
|
3
|
+
exports.INVALID_JSON = exports.X_LT_DEFAULT_CHECKED = void 0;
|
|
4
4
|
exports.resolveChecklistItems = resolveChecklistItems;
|
|
5
5
|
exports.resolveChecklistDefault = resolveChecklistDefault;
|
|
6
6
|
exports.validateRequireAll = validateRequireAll;
|
|
@@ -87,6 +87,18 @@ function validateRequireAll(value, fieldSchema, ctx) {
|
|
|
87
87
|
return undefined;
|
|
88
88
|
return `${incomplete} of ${mandatory.length} checks incomplete`;
|
|
89
89
|
}
|
|
90
|
+
exports.INVALID_JSON = 'Invalid JSON';
|
|
91
|
+
/** The json editor holds unparseable text as a string at the field's key. */
|
|
92
|
+
function isJsonWidget(fieldSchema) {
|
|
93
|
+
return fieldSchema?.['x-lt-widget'] === 'json';
|
|
94
|
+
}
|
|
95
|
+
/** A list is edited through the json editor or a multi-select; any other list value is display only. */
|
|
96
|
+
function isEditableList(fieldSchema) {
|
|
97
|
+
return isJsonWidget(fieldSchema) || fieldSchema?.[x_lt_options_1.X_LT_OPTIONS] !== undefined;
|
|
98
|
+
}
|
|
99
|
+
function plural(n, noun) {
|
|
100
|
+
return `${n} ${noun}${n === 1 ? '' : 's'}`;
|
|
101
|
+
}
|
|
90
102
|
/**
|
|
91
103
|
* Runtime type check against the field's declared JSON Schema `type`. Guards
|
|
92
104
|
* the payload contract for API-first callers (a form widget already produces
|
|
@@ -109,9 +121,13 @@ function validateFieldType(value, fieldSchema) {
|
|
|
109
121
|
case 'boolean':
|
|
110
122
|
return typeof value === 'boolean' ? undefined : 'Expected true or false';
|
|
111
123
|
case 'array':
|
|
112
|
-
|
|
124
|
+
if (Array.isArray(value))
|
|
125
|
+
return undefined;
|
|
126
|
+
return isJsonWidget(fieldSchema) && typeof value === 'string' ? exports.INVALID_JSON : 'Expected a list';
|
|
113
127
|
case 'object':
|
|
114
|
-
|
|
128
|
+
if (typeof value === 'object' && !Array.isArray(value))
|
|
129
|
+
return undefined;
|
|
130
|
+
return isJsonWidget(fieldSchema) && typeof value === 'string' ? exports.INVALID_JSON : 'Expected an object';
|
|
115
131
|
default:
|
|
116
132
|
return undefined;
|
|
117
133
|
}
|
|
@@ -136,7 +152,7 @@ function validateFieldConstraints(value, fieldSchema, ctx) {
|
|
|
136
152
|
// interpolated list that currently offers nothing fails closed — a stale
|
|
137
153
|
// cascade child value never submits.
|
|
138
154
|
const allowed = (0, x_lt_options_1.resolveFieldOptions)(fieldSchema, ctx);
|
|
139
|
-
if (allowed !== undefined && value !== undefined && value !== null && value !== '') {
|
|
155
|
+
if (allowed !== undefined && value !== undefined && value !== null && value !== '' && !Array.isArray(value)) {
|
|
140
156
|
if (allowed.length === 0) {
|
|
141
157
|
return 'No valid options for this selection';
|
|
142
158
|
}
|
|
@@ -144,6 +160,12 @@ function validateFieldConstraints(value, fieldSchema, ctx) {
|
|
|
144
160
|
return `Must be one of: ${allowed.map((o) => String(o.value)).join(', ')}`;
|
|
145
161
|
}
|
|
146
162
|
}
|
|
163
|
+
if (Array.isArray(value)) {
|
|
164
|
+
return isEditableList(fieldSchema) ? validateListConstraints(value, fieldSchema, allowed, ctx) : undefined;
|
|
165
|
+
}
|
|
166
|
+
if (value !== null && typeof value === 'object') {
|
|
167
|
+
return validateMapConstraints(value, fieldSchema, ctx);
|
|
168
|
+
}
|
|
147
169
|
if (typeof value === 'string') {
|
|
148
170
|
const s = value.trim();
|
|
149
171
|
if (s === '')
|
|
@@ -196,6 +218,65 @@ function validateFieldConstraints(value, fieldSchema, ctx) {
|
|
|
196
218
|
}
|
|
197
219
|
return undefined;
|
|
198
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* An edited list: every item must belong to the field's `x-lt-options` when
|
|
223
|
+
* declared, the length must sit within `minItems`/`maxItems`, and each item
|
|
224
|
+
* must satisfy `items`. An empty list passes; presence is the required
|
|
225
|
+
* check's job.
|
|
226
|
+
*/
|
|
227
|
+
function validateListConstraints(value, fieldSchema, allowed, ctx) {
|
|
228
|
+
if (value.length === 0)
|
|
229
|
+
return undefined;
|
|
230
|
+
if (allowed !== undefined) {
|
|
231
|
+
if (allowed.length === 0)
|
|
232
|
+
return 'No valid options for this selection';
|
|
233
|
+
if (value.some((v) => !allowed.some((o) => o.value === v))) {
|
|
234
|
+
return `Must be one of: ${allowed.map((o) => String(o.value)).join(', ')}`;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const minItems = resolveNumericConstraint(fieldSchema.minItems, undefined, ctx);
|
|
238
|
+
if (minItems !== undefined && value.length < minItems)
|
|
239
|
+
return `At least ${plural(minItems, 'item')}`;
|
|
240
|
+
const maxItems = resolveNumericConstraint(fieldSchema.maxItems, undefined, ctx);
|
|
241
|
+
if (maxItems !== undefined && value.length > maxItems)
|
|
242
|
+
return `At most ${plural(maxItems, 'item')}`;
|
|
243
|
+
const items = fieldSchema.items;
|
|
244
|
+
if (items && typeof items === 'object' && !Array.isArray(items)) {
|
|
245
|
+
const itemSchema = items;
|
|
246
|
+
for (let i = 0; i < value.length; i++) {
|
|
247
|
+
const err = validateFieldType(value[i], itemSchema) ?? validateFieldConstraints(value[i], itemSchema, ctx);
|
|
248
|
+
if (err)
|
|
249
|
+
return `Item ${i + 1}: ${err}`;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return undefined;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* A map value: keys must belong to `propertyNames.enum` when declared, and
|
|
256
|
+
* every value must satisfy an object-shaped `additionalProperties`.
|
|
257
|
+
*/
|
|
258
|
+
function validateMapConstraints(value, fieldSchema, ctx) {
|
|
259
|
+
const entries = Object.entries(value);
|
|
260
|
+
if (entries.length === 0)
|
|
261
|
+
return undefined;
|
|
262
|
+
const propertyNames = fieldSchema.propertyNames;
|
|
263
|
+
const allowedKeys = Array.isArray(propertyNames?.enum) ? propertyNames.enum.map(String) : undefined;
|
|
264
|
+
if (allowedKeys) {
|
|
265
|
+
const unknown = entries.find(([k]) => !allowedKeys.includes(k));
|
|
266
|
+
if (unknown)
|
|
267
|
+
return `Unknown key "${unknown[0]}". Allowed: ${allowedKeys.join(', ')}`;
|
|
268
|
+
}
|
|
269
|
+
const ap = fieldSchema.additionalProperties;
|
|
270
|
+
if (ap && typeof ap === 'object' && !Array.isArray(ap)) {
|
|
271
|
+
const valueSchema = ap;
|
|
272
|
+
for (const [k, v] of entries) {
|
|
273
|
+
const err = validateFieldType(v, valueSchema) ?? validateFieldConstraints(v, valueSchema, ctx);
|
|
274
|
+
if (err)
|
|
275
|
+
return `"${k}": ${err}`;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return undefined;
|
|
279
|
+
}
|
|
199
280
|
function resolveNumericConstraint(staticVal, dynamicPath, ctx) {
|
|
200
281
|
if (typeof staticVal === 'number')
|
|
201
282
|
return staticVal;
|
|
@@ -232,13 +313,20 @@ function validateField(value, fieldSchema, isRequired, isTouched, ctx) {
|
|
|
232
313
|
if (isRequired) {
|
|
233
314
|
if (value === undefined || value === null)
|
|
234
315
|
return 'Required';
|
|
235
|
-
|
|
316
|
+
// A checkbox must be checked; a boolean with an option list is answered by either value.
|
|
317
|
+
if (typeof value === 'boolean' && !value && (0, x_lt_options_1.resolveFieldOptions)(fieldSchema, ctx) === undefined)
|
|
236
318
|
return 'Required';
|
|
237
319
|
if (typeof value === 'string' && value.trim() === '')
|
|
238
320
|
return 'Required';
|
|
321
|
+
// A picked or edited list needs one item; a plain list value is not checked.
|
|
322
|
+
if (Array.isArray(value) && value.length === 0 && isEditableList(fieldSchema))
|
|
323
|
+
return 'Required';
|
|
239
324
|
if (typeof value === 'object' && !Array.isArray(value) && value !== null) {
|
|
240
325
|
const vals = Object.values(value);
|
|
241
|
-
if (vals.length === 0
|
|
326
|
+
if (vals.length === 0)
|
|
327
|
+
return 'Required';
|
|
328
|
+
// A json map is answered by any key; every other object needs one truthy value.
|
|
329
|
+
if (!isJsonWidget(fieldSchema) && vals.every((v) => !v))
|
|
242
330
|
return 'Required';
|
|
243
331
|
}
|
|
244
332
|
}
|