@hotmeshio/long-tail 0.19.0 → 0.20.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/build/api/workflows/config.d.ts +8 -1
- package/build/api/workflows/config.js +24 -1
- package/build/api/workflows/index.d.ts +4 -0
- package/build/api/workflows/index.js +9 -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 +14 -0
- package/build/api/workflows/input-validation.js +41 -0
- package/build/api/workflows/invocable.d.ts +19 -0
- package/build/api/workflows/invocable.js +107 -0
- package/build/api/workflows/invocation.js +6 -0
- package/build/lib/db/schemas/034_workflow_input_schema.sql +13 -0
- package/build/lib/db/schemas/035_workflow_input_lookups.sql +9 -0
- package/build/routes/workflows/config.js +12 -0
- package/build/routes/workflows/discovery.js +14 -0
- package/build/services/config/cache.js +3 -0
- package/build/services/config/read.js +6 -0
- package/build/services/config/sql.d.ts +2 -2
- package/build/services/config/sql.js +8 -5
- package/build/services/config/write.js +20 -1
- package/build/services/interceptor/index.js +7 -0
- package/build/services/invocation-access.d.ts +18 -0
- package/build/services/invocation-access.js +32 -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/workflow-invocation.js +4 -9
- 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 +1 -0
- package/build/shared/form-validation/index.js +1 -0
- package/build/shared/form-validation/invoke-context.d.ts +8 -0
- package/build/shared/form-validation/invoke-context.js +12 -0
- package/build/shared/form-validation/validate-resolver-payload.d.ts +1 -1
- package/build/shared/form-validation/validate-resolver-payload.js +1 -0
- package/build/shared/form-validation/x-lt-help.d.ts +2 -2
- package/build/shared/form-validation/x-lt-help.js +2 -2
- 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 +6 -0
- package/build/shared/form-validation/x-lt-show-if.js +13 -0
- package/build/start/workers.js +12 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +64 -20
- package/build/system/mcp-servers/admin/schemas.js +19 -3
- package/build/system/mcp-servers/admin/workflow-config.js +54 -9
- package/build/system/mcp-servers/admin/workflows.js +18 -3
- package/build/system/mcp-servers/db-query/schemas.d.ts +2 -2
- package/build/system/seed/tool-manifests-admin.d.ts +517 -54
- package/build/system/seed/tool-manifests-admin.js +4 -3
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/config.d.ts +10 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/index.js +4 -1
- package/build/types/startup.d.ts +16 -0
- package/build/types/validation.d.ts +4 -2
- package/build/types/workflow-icons.d.ts +86 -0
- package/build/types/workflow-icons.js +92 -0
- package/dashboard/dist/assets/{AdminDashboard-DPkWtPc1.js → AdminDashboard-DplvDBti.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-DPkWtPc1.js.map → AdminDashboard-DplvDBti.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-DRfnLiQS.js → AgentConfigPage-D8Bf6YxO.js} +3 -3
- package/dashboard/dist/assets/{AgentConfigPage-DRfnLiQS.js.map → AgentConfigPage-D8Bf6YxO.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-CufRZXnT.js → AgentDetailPage-BN8g0Y2G.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-CufRZXnT.js.map → AgentDetailPage-BN8g0Y2G.js.map} +1 -1
- package/dashboard/dist/assets/AgentsPage-7JJBHku8.js +2 -0
- package/dashboard/dist/assets/{AgentsPage-CoCWGhUd.js.map → AgentsPage-7JJBHku8.js.map} +1 -1
- package/dashboard/dist/assets/{AutoGrowTextarea-DgEQeRQw.js → AutoGrowTextarea-7X3T9La8.js} +2 -2
- package/dashboard/dist/assets/{AutoGrowTextarea-DgEQeRQw.js.map → AutoGrowTextarea-7X3T9La8.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-lz5qwSjg.js +2 -0
- package/dashboard/dist/assets/{AvailableEscalationsPage-BSqOctep.js.map → AvailableEscalationsPage-lz5qwSjg.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-DMojDLlV.js → BotPicker-CGCnIz8I.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-DMojDLlV.js.map → BotPicker-CGCnIz8I.js.map} +1 -1
- package/dashboard/dist/assets/BulkAssignModal-NJBcoj-f.js +2 -0
- package/dashboard/dist/assets/{BulkAssignModal-DYbM_6Or.js.map → BulkAssignModal-NJBcoj-f.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-CDQ5JHNP.js → CapabilitiesPage-F8dpNn9B.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-CDQ5JHNP.js.map → CapabilitiesPage-F8dpNn9B.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-D4VlCEbD.js → CollapsibleSection-BZW6VpCU.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-D4VlCEbD.js.map → CollapsibleSection-BZW6VpCU.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-DnNHjJtD.js → ConfirmDeleteModal-64adXLdq.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-DnNHjJtD.js.map → ConfirmDeleteModal-64adXLdq.js.map} +1 -1
- package/dashboard/dist/assets/{CopyableId-4Lqlc5cU.js → CopyableId-Bn02zYxt.js} +2 -2
- package/dashboard/dist/assets/{CopyableId-4Lqlc5cU.js.map → CopyableId-Bn02zYxt.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-BxDub9d2.js +2 -0
- package/dashboard/dist/assets/CountdownTimer-BxDub9d2.js.map +1 -0
- package/dashboard/dist/assets/{CredentialsPage-CSYZw-rL.js → CredentialsPage-CnLzopLL.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-CSYZw-rL.js.map → CredentialsPage-CnLzopLL.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-CpmqDrlJ.js → CronLabel-CAD5UYDT.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-CpmqDrlJ.js.map → CronLabel-CAD5UYDT.js.map} +1 -1
- package/dashboard/dist/assets/{DataTable-DFPMeqyQ.js → DataTable-7C7riavf.js} +2 -2
- package/dashboard/dist/assets/{DataTable-DFPMeqyQ.js.map → DataTable-7C7riavf.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-BbXlQnYB.js → DropZone-XlcY8hEH.js} +2 -2
- package/dashboard/dist/assets/{DropZone-BbXlQnYB.js.map → DropZone-XlcY8hEH.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-Cul22qBS.js → ElapsedCell-CwO4ufd0.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-Cul22qBS.js.map → ElapsedCell-CwO4ufd0.js.map} +1 -1
- package/dashboard/dist/assets/{EmptyState-lpUFYfun.js → EmptyState-DgC_6njU.js} +2 -2
- package/dashboard/dist/assets/{EmptyState-lpUFYfun.js.map → EmptyState-DgC_6njU.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-CtzpJ-j2.js → EntityTimelinePanel-CkF-oW-m.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-CtzpJ-j2.js.map → EntityTimelinePanel-CkF-oW-m.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-BZQ8Y_UH.js → EscalationListSchemaPage-h9JO_q5f.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-BZQ8Y_UH.js.map → EscalationListSchemaPage-h9JO_q5f.js.map} +1 -1
- package/dashboard/dist/assets/EscalationListView-AHW2xtlr.js +2 -0
- package/dashboard/dist/assets/EscalationListView-AHW2xtlr.js.map +1 -0
- package/dashboard/dist/assets/{EscalationSchemaPage-CydTtq_A.js → EscalationSchemaPage-mJFL5_Se.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-CydTtq_A.js.map → EscalationSchemaPage-mJFL5_Se.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-DSYC0nI7.js → EscalationsOverview-DlXUFqWJ.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-DSYC0nI7.js.map → EscalationsOverview-DlXUFqWJ.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-s48cTXIw.js → EventTable-Ike2xchn.js} +2 -2
- package/dashboard/dist/assets/{EventTable-s48cTXIw.js.map → EventTable-Ike2xchn.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-B61qKmFD.js → FilterBar-DMOR-O1c.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-B61qKmFD.js.map → FilterBar-DMOR-O1c.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-DxZv_KC2.js → GraphInvokePage-CKtvWowP.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-DxZv_KC2.js.map → GraphInvokePage-CKtvWowP.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-BQ3Q791Q.js +2 -0
- package/dashboard/dist/assets/{HomePage-zK3VP_9g.js.map → HomePage-BQ3Q791Q.js.map} +1 -1
- package/dashboard/dist/assets/ListToolbar-DdJzj472.js +2 -0
- package/dashboard/dist/assets/{ListToolbar-DaxloPQc.js.map → ListToolbar-DdJzj472.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-Ciq8r6-p.js → McpOverview-BbtrduWn.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-Ciq8r6-p.js.map → McpOverview-BbtrduWn.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DIC0FEEb.js → McpQueryDetailPage-C1L4T-Wt.js} +3 -3
- package/dashboard/dist/assets/{McpQueryDetailPage-DIC0FEEb.js.map → McpQueryDetailPage-C1L4T-Wt.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-BBy0NSNg.js → McpQueryPage-CfJy7HZ7.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-BBy0NSNg.js.map → McpQueryPage-CfJy7HZ7.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-BqKNmIyW.js → McpRunDetailPage-CA9yv7he.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-BqKNmIyW.js.map → McpRunDetailPage-CA9yv7he.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-D0RlOpzR.js → McpRunsPage-D7QXjW9z.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-D0RlOpzR.js.map → McpRunsPage-D7QXjW9z.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-Dbtm9R2T.js → NamespacePill-Bb3revqD.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-Dbtm9R2T.js.map → NamespacePill-Bb3revqD.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-BX0SFizr.js → OperationsPage-aLHHAP2X.js} +3 -3
- package/dashboard/dist/assets/{OperationsPage-BX0SFizr.js.map → OperationsPage-aLHHAP2X.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-sXNDh1Ph.js +2 -0
- package/dashboard/dist/assets/{OperatorDashboard-vXG0TjAQ.js.map → OperatorDashboard-sXNDh1Ph.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-xB92ELs3.js → PageHeader-Di5Sz3an.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-xB92ELs3.js.map → PageHeader-Di5Sz3an.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-DVo_qqn1.js → PageHeaderWithStats-DutKJ-h2.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-DVo_qqn1.js.map → PageHeaderWithStats-DutKJ-h2.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-w5TXcn4Q.js → PersonaDetailPage-NeHD-Gra.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-w5TXcn4Q.js.map → PersonaDetailPage-NeHD-Gra.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-Dzcinl1L.js → PersonasPage-DavKXRWX.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-Dzcinl1L.js.map → PersonasPage-DavKXRWX.js.map} +1 -1
- package/dashboard/dist/assets/{PriorityBadge-BETdj4M-.js → PriorityBadge-r33mpDju.js} +2 -2
- package/dashboard/dist/assets/{PriorityBadge-BETdj4M-.js.map → PriorityBadge-r33mpDju.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-BVXieFX1.js → ProcessDetailPage-DkdKJGe6.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-BVXieFX1.js.map → ProcessDetailPage-DkdKJGe6.js.map} +1 -1
- package/dashboard/dist/assets/ProcessesListPage-CjwVKe32.js +2 -0
- package/dashboard/dist/assets/{ProcessesListPage-CKKNpk4z.js.map → ProcessesListPage-CjwVKe32.js.map} +1 -1
- package/dashboard/dist/assets/ResolverForm-Bk-wDkN-.js +3 -0
- package/dashboard/dist/assets/ResolverForm-Bk-wDkN-.js.map +1 -0
- package/dashboard/dist/assets/{RoleDetailPage-BytSo-YE.js → RoleDetailPage-WQt0y5l7.js} +3 -3
- package/dashboard/dist/assets/{RoleDetailPage-BytSo-YE.js.map → RoleDetailPage-WQt0y5l7.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-CYpL3a2d.js → RolePill-DhnVPK4q.js} +2 -2
- package/dashboard/dist/assets/{RolePill-CYpL3a2d.js.map → RolePill-DhnVPK4q.js.map} +1 -1
- package/dashboard/dist/assets/RolesPage-OM9KM8Pg.js +2 -0
- package/dashboard/dist/assets/{RolesPage-eayR9H4f.js.map → RolesPage-OM9KM8Pg.js.map} +1 -1
- package/dashboard/dist/assets/{RowActions-eYrzgQSj.js → RowActions-Bdd7z4eB.js} +2 -2
- package/dashboard/dist/assets/{RowActions-eYrzgQSj.js.map → RowActions-Bdd7z4eB.js.map} +1 -1
- package/dashboard/dist/assets/RunAsSelector-fFMt1bGe.js +2 -0
- package/dashboard/dist/assets/{RunAsSelector-D7RPwaAl.js.map → RunAsSelector-fFMt1bGe.js.map} +1 -1
- package/dashboard/dist/assets/{ScanCodesPage-C8-ZBXF5.js → ScanCodesPage-AujH-pPQ.js} +2 -2
- package/dashboard/dist/assets/{ScanCodesPage-C8-ZBXF5.js.map → ScanCodesPage-AujH-pPQ.js.map} +1 -1
- package/dashboard/dist/assets/{ScanSchemeDetailPage-tQhEgFKf.js → ScanSchemeDetailPage-eKQpmsC_.js} +2 -2
- package/dashboard/dist/assets/{ScanSchemeDetailPage-tQhEgFKf.js.map → ScanSchemeDetailPage-eKQpmsC_.js.map} +1 -1
- package/dashboard/dist/assets/ScanStationPage-C1_ppDoZ.js +2 -0
- package/dashboard/dist/assets/{ScanStationPage-CuhqsBKo.js.map → ScanStationPage-C1_ppDoZ.js.map} +1 -1
- package/dashboard/dist/assets/{ScopeBadge-BmNzZlSj.js → ScopeBadge-CXUg0FHo.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-BmNzZlSj.js.map → ScopeBadge-CXUg0FHo.js.map} +1 -1
- package/dashboard/dist/assets/{SegmentedTabs-DXNzY05q.js → SegmentedTabs-BpJh4Hwn.js} +2 -2
- package/dashboard/dist/assets/{SegmentedTabs-DXNzY05q.js.map → SegmentedTabs-BpJh4Hwn.js.map} +1 -1
- package/dashboard/dist/assets/{StatCard-BXQ8dD9Y.js → StatCard-nWY4sndl.js} +2 -2
- package/dashboard/dist/assets/{StatCard-BXQ8dD9Y.js.map → StatCard-nWY4sndl.js.map} +1 -1
- package/dashboard/dist/assets/{StatusBadge-BDeUwPtb.js → StatusBadge-DHVwxre2.js} +2 -2
- package/dashboard/dist/assets/{StatusBadge-BDeUwPtb.js.map → StatusBadge-DHVwxre2.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-BIVTAMnP.js → StickyPagination-B91Pk9xh.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-BIVTAMnP.js.map → StickyPagination-B91Pk9xh.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-CYSC2cO1.js → StreamMessageDetail-C7SPqaJt.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-CYSC2cO1.js.map → StreamMessageDetail-C7SPqaJt.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-BMZAs_2K.js → SwimlaneTimeline-BcHR8ylf.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-BMZAs_2K.js.map → SwimlaneTimeline-BcHR8ylf.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-D1uszNd2.js → TagInput-BZ8vb2oW.js} +2 -2
- package/dashboard/dist/assets/{TagInput-D1uszNd2.js.map → TagInput-BZ8vb2oW.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-CVUDUU5Q.js → TaskDetailPage-Bqj0I_I0.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-CVUDUU5Q.js.map → TaskDetailPage-Bqj0I_I0.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-C2H8oRfn.js → TaskQueuePill-Bxir8WRl.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-C2H8oRfn.js.map → TaskQueuePill-Bxir8WRl.js.map} +1 -1
- package/dashboard/dist/assets/TasksListPage-BB1f79lL.js +2 -0
- package/dashboard/dist/assets/{TasksListPage-DEQymbXC.js.map → TasksListPage-BB1f79lL.js.map} +1 -1
- package/dashboard/dist/assets/TimeAgo-BFnODmNe.js +2 -0
- package/dashboard/dist/assets/{TimeAgo-CCxP67Rb.js.map → TimeAgo-BFnODmNe.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-CE5ZUYhV.js → TimestampCell-BXgLOBsr.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-CE5ZUYhV.js.map → TimestampCell-BXgLOBsr.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-D-h8AoB8.js → ToolPill-FkgTXIhq.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-D-h8AoB8.js.map → ToolPill-FkgTXIhq.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-BHuQTyBY.js → ToolTestPanel-Bwe3J5lj.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-BHuQTyBY.js.map → ToolTestPanel-Bwe3J5lj.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-SFuiludx.js → TopicDetailPage-DAF07vZ9.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-SFuiludx.js.map → TopicDetailPage-DAF07vZ9.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-DO8pUmng.js → TopicsPage-C1gxBUap.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-DO8pUmng.js.map → TopicsPage-C1gxBUap.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-CsLnT75E.js → UserName-BzXJUE6q.js} +2 -2
- package/dashboard/dist/assets/{UserName-CsLnT75E.js.map → UserName-BzXJUE6q.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-SkRU5cRX.js +2 -0
- package/dashboard/dist/assets/{WorkflowExecutionPage-BttnEvOd.js.map → WorkflowExecutionPage-SkRU5cRX.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-CZvBbkn4.js → WorkflowPill--AYMW7u_.js} +2 -2
- package/dashboard/dist/assets/WorkflowPill--AYMW7u_.js.map +1 -0
- package/dashboard/dist/assets/WorkflowsDashboard-CZAqRk1N.js +2 -0
- package/dashboard/dist/assets/{WorkflowsDashboard-BRboBhlK.js.map → WorkflowsDashboard-CZAqRk1N.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsOverview-BoN44VTE.js +2 -0
- package/dashboard/dist/assets/{WorkflowsOverview-CDFTYeQo.js.map → WorkflowsOverview-BoN44VTE.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CmnZFevp.js → YamlWorkflowDetailPage-CqjhtdJf.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CmnZFevp.js.map → YamlWorkflowDetailPage-CqjhtdJf.js.map} +1 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-CwnJkzyb.js +2 -0
- package/dashboard/dist/assets/{YamlWorkflowsPage-Qq1jfcrH.js.map → YamlWorkflowsPage-CwnJkzyb.js.map} +1 -1
- package/dashboard/dist/assets/{agents-C7vUIO7e.js → agents-gV0Ys-sY.js} +2 -2
- package/dashboard/dist/assets/{agents-C7vUIO7e.js.map → agents-gV0Ys-sY.js.map} +1 -1
- package/dashboard/dist/assets/{bots-BaOblnW4.js → bots-B97itB3I.js} +2 -2
- package/dashboard/dist/assets/{bots-BaOblnW4.js.map → bots-B97itB3I.js.map} +1 -1
- package/dashboard/dist/assets/capabilities-CR9xZgGd.js +2 -0
- package/dashboard/dist/assets/{capabilities-RZpmDWoy.js.map → capabilities-CR9xZgGd.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-BwGdcwXR.js → controlplane-YxvP1KCa.js} +2 -2
- package/dashboard/dist/assets/{controlplane-BwGdcwXR.js.map → controlplane-YxvP1KCa.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-uq-IV2aj.js +2 -0
- package/dashboard/dist/assets/{escalation-columns-B4DG_5v8.js.map → escalation-columns-uq-IV2aj.js.map} +1 -1
- package/dashboard/dist/assets/index-3ezfWLkE.js +6 -0
- package/dashboard/dist/assets/index-3ezfWLkE.js.map +1 -0
- package/dashboard/dist/assets/{index-xNFTmmsv.js → index-B9BBCqLI.js} +2 -2
- package/dashboard/dist/assets/{index-xNFTmmsv.js.map → index-B9BBCqLI.js.map} +1 -1
- package/dashboard/dist/assets/{index-iegzyfMv.js → index-BQpV-DTG.js} +2 -2
- package/dashboard/dist/assets/{index-iegzyfMv.js.map → index-BQpV-DTG.js.map} +1 -1
- package/dashboard/dist/assets/index-Bp9KBLT5.js +2 -0
- package/dashboard/dist/assets/{index-IWufkcH9.js.map → index-Bp9KBLT5.js.map} +1 -1
- package/dashboard/dist/assets/index-Bpvfr4OW.css +1 -0
- package/dashboard/dist/assets/{index-D9NtDRtp.js → index-CFbo9FU9.js} +2 -2
- package/dashboard/dist/assets/{index-D9NtDRtp.js.map → index-CFbo9FU9.js.map} +1 -1
- package/dashboard/dist/assets/{index-BQPUlmmz.js → index-CIpHj4di.js} +2 -2
- package/dashboard/dist/assets/{index-BQPUlmmz.js.map → index-CIpHj4di.js.map} +1 -1
- package/dashboard/dist/assets/index-CIwlVfvV.js +67 -0
- package/dashboard/dist/assets/index-CIwlVfvV.js.map +1 -0
- package/dashboard/dist/assets/{index-BICLHYJJ.js → index-CUZ6LYye.js} +2 -2
- package/dashboard/dist/assets/{index-BICLHYJJ.js.map → index-CUZ6LYye.js.map} +1 -1
- package/dashboard/dist/assets/index-Cfvkl2J0.js +13 -0
- package/dashboard/dist/assets/index-Cfvkl2J0.js.map +1 -0
- package/dashboard/dist/assets/{index-BuqpU6ow.js → index-DMeaiKgf.js} +2 -2
- package/dashboard/dist/assets/{index-BuqpU6ow.js.map → index-DMeaiKgf.js.map} +1 -1
- package/dashboard/dist/assets/{index-G3NmdMjt.js → index-DwOnWeu8.js} +2 -2
- package/dashboard/dist/assets/{index-G3NmdMjt.js.map → index-DwOnWeu8.js.map} +1 -1
- package/dashboard/dist/assets/index-SGyrXGp8.js +3 -0
- package/dashboard/dist/assets/index-SGyrXGp8.js.map +1 -0
- package/dashboard/dist/assets/{index-DU9-flEo.js → index-ipqwPavs.js} +2 -2
- package/dashboard/dist/assets/{index-DU9-flEo.js.map → index-ipqwPavs.js.map} +1 -1
- package/dashboard/dist/assets/invoke-context-DrVyUEfs.js +2 -0
- package/dashboard/dist/assets/invoke-context-DrVyUEfs.js.map +1 -0
- package/dashboard/dist/assets/{knowledge-CjwCbm3E.js → knowledge-XX6cW4Ob.js} +2 -2
- package/dashboard/dist/assets/{knowledge-CjwCbm3E.js.map → knowledge-XX6cW4Ob.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-C-DMktCT.js → mcp-CH13hNH2.js} +2 -2
- package/dashboard/dist/assets/{mcp-C-DMktCT.js.map → mcp-CH13hNH2.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-KBeBNHb4.js → mcp-query-Duydd3JA.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-KBeBNHb4.js.map → mcp-query-Duydd3JA.js.map} +1 -1
- package/dashboard/dist/assets/{personas-B32sSCxm.js → personas-mDk4lLQS.js} +2 -2
- package/dashboard/dist/assets/{personas-B32sSCxm.js.map → personas-mDk4lLQS.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-DNLwDumm.js → pipelines-B5GcgCeF.js} +2 -2
- package/dashboard/dist/assets/{pipelines-DNLwDumm.js.map → pipelines-B5GcgCeF.js.map} +1 -1
- package/dashboard/dist/assets/resolver-payload-m9AGKZ3a.js +2 -0
- package/dashboard/dist/assets/resolver-payload-m9AGKZ3a.js.map +1 -0
- package/dashboard/dist/assets/{tasks-DrWSrjmj.js → tasks-CItmNsRp.js} +2 -2
- package/dashboard/dist/assets/{tasks-DrWSrjmj.js.map → tasks-CItmNsRp.js.map} +1 -1
- package/dashboard/dist/assets/{topics-DgzGU-vR.js → topics-CJYG7BX5.js} +2 -2
- package/dashboard/dist/assets/{topics-DgzGU-vR.js.map → topics-CJYG7BX5.js.map} +1 -1
- package/dashboard/dist/assets/useDebouncedValue-BrwgXcp8.js +2 -0
- package/dashboard/dist/assets/{useDebouncedValue-DG5JOj1F.js.map → useDebouncedValue-BrwgXcp8.js.map} +1 -1
- package/dashboard/dist/assets/{useFilterParams-crmlBw_l.js → useFilterParams-DBRw1Hcv.js} +2 -2
- package/dashboard/dist/assets/{useFilterParams-crmlBw_l.js.map → useFilterParams-DBRw1Hcv.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-CdgF7Jxo.js → useNamespace-CHty0HAS.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-CdgF7Jxo.js.map → useNamespace-CHty0HAS.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-BEaOtgSZ.js → useYamlActivityEvents-CoTsia7t.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-BEaOtgSZ.js.map → useYamlActivityEvents-CoTsia7t.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-BCWsItQ7.js → vendor-icons-DeBdvyKJ.js} +364 -144
- package/dashboard/dist/assets/vendor-icons-DeBdvyKJ.js.map +1 -0
- package/dashboard/dist/assets/vendor-query-DvWWuNIB.js +18 -0
- package/dashboard/dist/assets/vendor-query-DvWWuNIB.js.map +1 -0
- package/dashboard/dist/assets/{vendor-react-CdqEC2zv.js → vendor-react-_9U4mKFr.js} +2 -2
- package/dashboard/dist/assets/{vendor-react-CdqEC2zv.js.map → vendor-react-_9U4mKFr.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-YASUDPo0.js → yaml-workflows-CiWwx5rM.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-YASUDPo0.js.map → yaml-workflows-CiWwx5rM.js.map} +1 -1
- package/dashboard/dist/index.html +5 -5
- package/docs/api/http/workflows.md +52 -1
- package/docs/api/mcp/admin.md +40 -4
- package/docs/code-owned-configuration.md +1 -1
- package/docs/dashboard.md +45 -19
- package/docs/design-principles.md +6 -5
- package/docs/events.md +3 -1
- package/docs/faceted-routing.md +1 -1
- package/docs/hitl/form.md +12 -7
- package/docs/hitl/iframe.md +35 -6
- package/docs/hitl/invoke-form.md +101 -0
- package/docs/hitl/lookups.md +21 -0
- package/docs/hitl/x-lt-show-if.md +11 -0
- package/docs/hitl/x-lt-validation.md +50 -3
- package/docs/hitl/x-lt-widget.md +21 -0
- package/docs/hitl-guide.md +9 -4
- package/docs/iam.md +1 -1
- package/docs/scan-codes.md +13 -4
- package/docs/workflows.md +1 -1
- package/package.json +1 -1
- package/dashboard/dist/assets/AgentsPage-CoCWGhUd.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-BSqOctep.js +0 -2
- package/dashboard/dist/assets/BulkAssignModal-DYbM_6Or.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-DPHMBmgz.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-DPHMBmgz.js.map +0 -1
- package/dashboard/dist/assets/HomePage-zK3VP_9g.js +0 -2
- package/dashboard/dist/assets/ListToolbar-DaxloPQc.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-vXG0TjAQ.js +0 -2
- package/dashboard/dist/assets/ProcessesListPage-CKKNpk4z.js +0 -2
- package/dashboard/dist/assets/RolesPage-eayR9H4f.js +0 -2
- package/dashboard/dist/assets/RunAsSelector-D7RPwaAl.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-CuhqsBKo.js +0 -2
- package/dashboard/dist/assets/TasksListPage-DEQymbXC.js +0 -2
- package/dashboard/dist/assets/TimeAgo-CCxP67Rb.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-BttnEvOd.js +0 -2
- package/dashboard/dist/assets/WorkflowPill-CZvBbkn4.js.map +0 -1
- package/dashboard/dist/assets/WorkflowsDashboard-BRboBhlK.js +0 -2
- package/dashboard/dist/assets/WorkflowsOverview-CDFTYeQo.js +0 -2
- package/dashboard/dist/assets/YamlWorkflowsPage-Qq1jfcrH.js +0 -2
- package/dashboard/dist/assets/capabilities-RZpmDWoy.js +0 -2
- package/dashboard/dist/assets/escalation-columns-B4DG_5v8.js +0 -2
- package/dashboard/dist/assets/index-8LIpvj2e.js +0 -3
- package/dashboard/dist/assets/index-8LIpvj2e.js.map +0 -1
- package/dashboard/dist/assets/index-BaC3sbJH.js +0 -67
- package/dashboard/dist/assets/index-BaC3sbJH.js.map +0 -1
- package/dashboard/dist/assets/index-CD6jtND1.css +0 -1
- package/dashboard/dist/assets/index-CsIw-ZLk.js +0 -6
- package/dashboard/dist/assets/index-CsIw-ZLk.js.map +0 -1
- package/dashboard/dist/assets/index-CtJkvX9e.js +0 -5
- package/dashboard/dist/assets/index-CtJkvX9e.js.map +0 -1
- package/dashboard/dist/assets/index-IWufkcH9.js +0 -2
- package/dashboard/dist/assets/useDebouncedValue-DG5JOj1F.js +0 -2
- package/dashboard/dist/assets/vendor-icons-BCWsItQ7.js.map +0 -1
- package/dashboard/dist/assets/vendor-query-RUZdMvN6.js +0 -18
- package/dashboard/dist/assets/vendor-query-RUZdMvN6.js.map +0 -1
- package/dashboard/dist/assets/workflows-CX_oarls.js +0 -2
- package/dashboard/dist/assets/workflows-CX_oarls.js.map +0 -1
|
@@ -47,6 +47,11 @@ const context_2 = require("../iam/context");
|
|
|
47
47
|
const publish_1 = require("../../lib/events/publish");
|
|
48
48
|
const envelope_1 = require("../iam/envelope");
|
|
49
49
|
const DEFAULT_ACTIVITY_QUEUE = 'lt-interceptor';
|
|
50
|
+
/** The result payload a completed event carries: the workflow's `data` when it returned the envelope shape. */
|
|
51
|
+
function resultData(result) {
|
|
52
|
+
const data = result?.data;
|
|
53
|
+
return data && typeof data === 'object' && !Array.isArray(data) ? data : undefined;
|
|
54
|
+
}
|
|
50
55
|
/**
|
|
51
56
|
* Register the Long Tail interceptors in a single call.
|
|
52
57
|
*
|
|
@@ -120,6 +125,7 @@ function createLTInterceptor(options) {
|
|
|
120
125
|
workflowName: wf.workflowName,
|
|
121
126
|
taskQueue: taskQueue0,
|
|
122
127
|
status: 'completed',
|
|
128
|
+
data: resultData(result0),
|
|
123
129
|
});
|
|
124
130
|
return result0;
|
|
125
131
|
}
|
|
@@ -138,6 +144,7 @@ function createLTInterceptor(options) {
|
|
|
138
144
|
workflowName: wf.workflowName,
|
|
139
145
|
taskQueue: taskQueue2,
|
|
140
146
|
status: 'completed',
|
|
147
|
+
data: resultData(result2),
|
|
141
148
|
});
|
|
142
149
|
return result2;
|
|
143
150
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { LTWorkflowConfig } from '../types/config';
|
|
2
|
+
export interface InvocationRoleGrant {
|
|
3
|
+
role: string;
|
|
4
|
+
type: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const INVOCATION_ROLE_TYPES: {
|
|
7
|
+
readonly SUPERADMIN: "superadmin";
|
|
8
|
+
readonly ADMIN: "admin";
|
|
9
|
+
};
|
|
10
|
+
export declare const ADMIN_ROLE = "admin";
|
|
11
|
+
/** Superadmin anywhere, or the named admin role held as admin type, invokes every workflow. */
|
|
12
|
+
export declare function hasGlobalInvocationAccess(roles: readonly InvocationRoleGrant[], authRole?: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* The one invocation predicate, shared by the invoke gate and the per-caller
|
|
15
|
+
* list so the two can never disagree. An empty invocation_roles list opens
|
|
16
|
+
* the workflow to every authenticated caller.
|
|
17
|
+
*/
|
|
18
|
+
export declare function canInvokeWorkflow(config: Pick<LTWorkflowConfig, 'invocable' | 'invocation_roles'>, roles: readonly InvocationRoleGrant[], authRole?: string): boolean;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ADMIN_ROLE = exports.INVOCATION_ROLE_TYPES = void 0;
|
|
4
|
+
exports.hasGlobalInvocationAccess = hasGlobalInvocationAccess;
|
|
5
|
+
exports.canInvokeWorkflow = canInvokeWorkflow;
|
|
6
|
+
exports.INVOCATION_ROLE_TYPES = {
|
|
7
|
+
SUPERADMIN: 'superadmin',
|
|
8
|
+
ADMIN: 'admin',
|
|
9
|
+
};
|
|
10
|
+
exports.ADMIN_ROLE = 'admin';
|
|
11
|
+
/** Superadmin anywhere, or the named admin role held as admin type, invokes every workflow. */
|
|
12
|
+
function hasGlobalInvocationAccess(roles, authRole) {
|
|
13
|
+
if (authRole === exports.INVOCATION_ROLE_TYPES.SUPERADMIN)
|
|
14
|
+
return true;
|
|
15
|
+
return roles.some((r) => r.type === exports.INVOCATION_ROLE_TYPES.SUPERADMIN)
|
|
16
|
+
|| roles.some((r) => r.role === exports.ADMIN_ROLE && r.type === exports.INVOCATION_ROLE_TYPES.ADMIN);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The one invocation predicate, shared by the invoke gate and the per-caller
|
|
20
|
+
* list so the two can never disagree. An empty invocation_roles list opens
|
|
21
|
+
* the workflow to every authenticated caller.
|
|
22
|
+
*/
|
|
23
|
+
function canInvokeWorkflow(config, roles, authRole) {
|
|
24
|
+
if (!config.invocable)
|
|
25
|
+
return false;
|
|
26
|
+
if (config.invocation_roles.length === 0)
|
|
27
|
+
return true;
|
|
28
|
+
if (hasGlobalInvocationAccess(roles, authRole))
|
|
29
|
+
return true;
|
|
30
|
+
const held = new Set(roles.map((r) => r.role));
|
|
31
|
+
return config.invocation_roles.some((r) => held.has(r));
|
|
32
|
+
}
|
|
@@ -24,6 +24,7 @@ exports.listKnowledgeVersions = listKnowledgeVersions;
|
|
|
24
24
|
const db_1 = require("../../lib/db");
|
|
25
25
|
const sql_1 = require("./sql");
|
|
26
26
|
__exportStar(require("./lookup-cache"), exports);
|
|
27
|
+
__exportStar(require("./lookup-refs"), exports);
|
|
27
28
|
/** The immutable snapshot at (domain, key, version), uncached full shape. */
|
|
28
29
|
async function getKnowledgeVersion(domain, key, version) {
|
|
29
30
|
const pool = (0, db_1.getPool)();
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { EscalationLookupRef } from '../../types/escalation';
|
|
2
|
+
/**
|
|
3
|
+
* One message per ref whose pinned edition does not exist, naming what does.
|
|
4
|
+
* Shape is the caller's job (assertLookupRefs); this answers the second
|
|
5
|
+
* question a saver has: is there an edition behind the pin.
|
|
6
|
+
*/
|
|
7
|
+
export declare function describeMissingLookupRefs(refs: EscalationLookupRef[]): Promise<string[]>;
|
|
@@ -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;
|
|
@@ -46,6 +46,7 @@ exports.InvocationError = void 0;
|
|
|
46
46
|
exports.invokeWorkflow = invokeWorkflow;
|
|
47
47
|
exports.checkInvocationRoles = checkInvocationRoles;
|
|
48
48
|
const hotmesh_1 = require("@hotmeshio/hotmesh");
|
|
49
|
+
const invocation_access_1 = require("./invocation-access");
|
|
49
50
|
const workers_1 = require("../workers");
|
|
50
51
|
const configService = __importStar(require("./config"));
|
|
51
52
|
const userService = __importStar(require("./user"));
|
|
@@ -152,15 +153,9 @@ async function checkInvocationRoles(workflowType, userId, authRole) {
|
|
|
152
153
|
if (!user) {
|
|
153
154
|
throw new InvocationError('User not registered', 403);
|
|
154
155
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
// superadmin and admin/admin bypass role checks
|
|
159
|
-
const hasGlobalAccess = user.roles.some((r) => r.type === 'superadmin')
|
|
160
|
-
|| user.roles.some((r) => r.role === 'admin' && r.type === 'admin');
|
|
161
|
-
if (!hasGlobalAccess) {
|
|
162
|
-
throw new InvocationError('Insufficient role for invocation', 403);
|
|
163
|
-
}
|
|
156
|
+
// invocable is resolveTaskQueue's concern; this gate decides roles only.
|
|
157
|
+
if (!(0, invocation_access_1.canInvokeWorkflow)({ ...wfConfig, invocable: true }, user.roles, authRole)) {
|
|
158
|
+
throw new InvocationError('Insufficient role for invocation', 403);
|
|
164
159
|
}
|
|
165
160
|
}
|
|
166
161
|
/**
|
|
@@ -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
|
}
|
|
@@ -35,3 +35,4 @@ __exportStar(require("./x-lt-options"), exports);
|
|
|
35
35
|
__exportStar(require("./ctx-path"), exports);
|
|
36
36
|
__exportStar(require("./field-validator"), exports);
|
|
37
37
|
__exportStar(require("./validate-resolver-payload"), exports);
|
|
38
|
+
__exportStar(require("./invoke-context"), exports);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ResolverValidationContext } from './validate-resolver-payload';
|
|
2
|
+
/**
|
|
3
|
+
* The context an invoke form validates and renders against. The pass itself
|
|
4
|
+
* supplies the live values under `input` and `resolver`; `metadata` is the
|
|
5
|
+
* envelope metadata and `lookup` holds resolved versioned knowledge editions
|
|
6
|
+
* keyed by `as ?? key`. The lookup domain is present only when supplied.
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildInvokeFormContext(metadata: Record<string, unknown> | null | undefined, lookup?: Record<string, unknown> | null): ResolverValidationContext;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildInvokeFormContext = buildInvokeFormContext;
|
|
4
|
+
/**
|
|
5
|
+
* The context an invoke form validates and renders against. The pass itself
|
|
6
|
+
* supplies the live values under `input` and `resolver`; `metadata` is the
|
|
7
|
+
* envelope metadata and `lookup` holds resolved versioned knowledge editions
|
|
8
|
+
* keyed by `as ?? key`. The lookup domain is present only when supplied.
|
|
9
|
+
*/
|
|
10
|
+
function buildInvokeFormContext(metadata, lookup) {
|
|
11
|
+
return { metadata: metadata ?? {}, ...(lookup ? { lookup } : {}) };
|
|
12
|
+
}
|
|
@@ -31,7 +31,7 @@ export type { FieldError } from './field-validator';
|
|
|
31
31
|
* dynamic constraints against. `resolver` is supplied by the pass itself
|
|
32
32
|
* (the flat form values under validation) — callers provide the rest.
|
|
33
33
|
*/
|
|
34
|
-
export type ResolverValidationContext = Omit<ShowIfContext, 'resolver'>;
|
|
34
|
+
export type ResolverValidationContext = Omit<ShowIfContext, 'resolver' | 'input'>;
|
|
35
35
|
/**
|
|
36
36
|
* Validate FLAT form values against the form schema. This is the dashboard's
|
|
37
37
|
* entry point (the values the user edits, keyed by field name).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/** The token domains a help template may reference. */
|
|
2
|
-
export declare const HELP_DOMAINS: readonly ["escalation", "metadata", "envelope", "payload", "resolver", "lookup"];
|
|
1
|
+
/** The token domains a help template may reference. `input` is the invoke-form name for the live values `resolver` also carries. */
|
|
2
|
+
export declare const HELP_DOMAINS: readonly ["escalation", "metadata", "envelope", "payload", "resolver", "lookup", "input"];
|
|
3
3
|
export type HelpDomain = (typeof HELP_DOMAINS)[number];
|
|
4
4
|
export type HelpTokenContext = Partial<Record<HelpDomain, Record<string, unknown> | null>>;
|
|
5
5
|
/** Replace every `{{domain.path}}` token with its value from the context. */
|
|
@@ -23,8 +23,8 @@ exports.defaultHelpMarkdown = defaultHelpMarkdown;
|
|
|
23
23
|
* `x-lt-help` is absent.
|
|
24
24
|
*/
|
|
25
25
|
const x_lt_bind_1 = require("./x-lt-bind");
|
|
26
|
-
/** The token domains a help template may reference. */
|
|
27
|
-
exports.HELP_DOMAINS = ['escalation', 'metadata', 'envelope', 'payload', 'resolver', 'lookup'];
|
|
26
|
+
/** The token domains a help template may reference. `input` is the invoke-form name for the live values `resolver` also carries. */
|
|
27
|
+
exports.HELP_DOMAINS = ['escalation', 'metadata', 'envelope', 'payload', 'resolver', 'lookup', 'input'];
|
|
28
28
|
const TOKEN_PATTERN = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
29
29
|
const MISSING_VALUE = '—';
|
|
30
30
|
function formatTokenValue(value) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export declare const X_LT_OPTIONS = "x-lt-options";
|
|
2
|
-
export type OptionValue = string | number;
|
|
2
|
+
export type OptionValue = string | number | boolean;
|
|
3
3
|
/** One resolved option: the payload value and the rendered label. */
|
|
4
4
|
export interface ResolvedOption {
|
|
5
5
|
value: OptionValue;
|
|
6
6
|
label: string;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* The field's effective option list: the static `enum` when present, else
|
|
10
|
-
* entries at the token's `"domain.path"`.
|
|
9
|
+
* The field's effective option list: the static `enum` when present, else an
|
|
10
|
+
* inline literal list, else the entries at the token's `"domain.path"`.
|
|
11
11
|
*/
|
|
12
12
|
export declare function resolveFieldOptions(fieldSchema: Record<string, unknown> | null | undefined, ctx: Record<string, unknown> | undefined): ResolvedOption[] | undefined;
|
|
@@ -10,7 +10,9 @@ exports.resolveFieldOptions = resolveFieldOptions;
|
|
|
10
10
|
* offer a different legal set per escalation (e.g. `[1..N]` where N rides the
|
|
11
11
|
* envelope, or a versioned knowledge lookup under the `lookup` domain).
|
|
12
12
|
*
|
|
13
|
-
* x-lt-options "domain.path"
|
|
13
|
+
* x-lt-options "domain.path", an ORDERED array of paths, or an inline
|
|
14
|
+
* literal list (an array with no string entries: `{ value,
|
|
15
|
+
* label }` objects, numbers, or booleans) — e.g.
|
|
14
16
|
* "envelope.left_quantity_options" or
|
|
15
17
|
* ["lookup.reasons.items", "envelope.reject_reason_items"].
|
|
16
18
|
* With an array, the first entry that resolves to options
|
|
@@ -42,7 +44,15 @@ exports.resolveFieldOptions = resolveFieldOptions;
|
|
|
42
44
|
const ctx_path_1 = require("./ctx-path");
|
|
43
45
|
exports.X_LT_OPTIONS = 'x-lt-options';
|
|
44
46
|
function isScalar(v) {
|
|
45
|
-
return typeof v === 'string' || (typeof v === 'number' && Number.isFinite(v));
|
|
47
|
+
return typeof v === 'string' || typeof v === 'boolean' || (typeof v === 'number' && Number.isFinite(v));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* An array token with no string entries is the option list itself, written
|
|
51
|
+
* inline. A bare string is always a context path, so a literal string value
|
|
52
|
+
* is written as `{ value, label }`.
|
|
53
|
+
*/
|
|
54
|
+
function isLiteralList(token) {
|
|
55
|
+
return Array.isArray(token) && token.length > 0 && !token.some((e) => typeof e === 'string');
|
|
46
56
|
}
|
|
47
57
|
/** Normalize one array entry, mixed arrays resolving each entry independently. */
|
|
48
58
|
function toOption(entry) {
|
|
@@ -58,19 +68,23 @@ function toOption(entry) {
|
|
|
58
68
|
return null;
|
|
59
69
|
}
|
|
60
70
|
/**
|
|
61
|
-
* The field's effective option list: the static `enum` when present, else
|
|
62
|
-
* entries at the token's `"domain.path"`.
|
|
71
|
+
* The field's effective option list: the static `enum` when present, else an
|
|
72
|
+
* inline literal list, else the entries at the token's `"domain.path"`.
|
|
63
73
|
*/
|
|
64
74
|
function resolveFieldOptions(fieldSchema, ctx) {
|
|
65
75
|
if (!fieldSchema)
|
|
66
76
|
return undefined;
|
|
67
77
|
// Enum entries pass through verbatim as values (whatever their type), each
|
|
68
|
-
// labeled by its string form
|
|
78
|
+
// labeled by its string form.
|
|
69
79
|
const staticEnum = fieldSchema.enum;
|
|
70
80
|
if (Array.isArray(staticEnum) && staticEnum.length > 0) {
|
|
71
81
|
return staticEnum.map((v) => ({ value: v, label: String(v) }));
|
|
72
82
|
}
|
|
73
83
|
const token = fieldSchema[exports.X_LT_OPTIONS];
|
|
84
|
+
if (isLiteralList(token)) {
|
|
85
|
+
const options = token.map(toOption).filter((o) => o !== null);
|
|
86
|
+
return options.length > 0 ? options : undefined;
|
|
87
|
+
}
|
|
74
88
|
const paths = (typeof token === 'string' ? [token] : Array.isArray(token) ? token : [])
|
|
75
89
|
.filter((p) => typeof p === 'string' && p.length > 0);
|
|
76
90
|
if (paths.length === 0)
|
|
@@ -3,5 +3,11 @@ export type ShowIfContext = HelpTokenContext;
|
|
|
3
3
|
/**
|
|
4
4
|
* Evaluates an x-lt-showIf condition. Returns true when the field should be
|
|
5
5
|
* shown. Returns true when condition is absent, non-string, or context is null.
|
|
6
|
+
* An array of conditions shows the field only when every one holds.
|
|
6
7
|
*/
|
|
7
8
|
export declare function evaluateShowIf(condition: unknown, ctx: ShowIfContext | null | undefined): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* `x-lt-hide-if-empty`: the field is suppressed while its value is empty
|
|
11
|
+
* (null, undefined, '', false, or 0). Render and validation share this test.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isHiddenIfEmpty(fieldSchema: Record<string, unknown> | undefined, value: unknown): boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.evaluateShowIf = evaluateShowIf;
|
|
4
|
+
exports.isHiddenIfEmpty = isHiddenIfEmpty;
|
|
4
5
|
/**
|
|
5
6
|
* x-lt-showIf — conditional field visibility. A form_schema property may
|
|
6
7
|
* declare `x-lt-showIf: "domain.path"` to show the field only when the value
|
|
@@ -54,8 +55,11 @@ function resolvePath(expr, ctx) {
|
|
|
54
55
|
/**
|
|
55
56
|
* Evaluates an x-lt-showIf condition. Returns true when the field should be
|
|
56
57
|
* shown. Returns true when condition is absent, non-string, or context is null.
|
|
58
|
+
* An array of conditions shows the field only when every one holds.
|
|
57
59
|
*/
|
|
58
60
|
function evaluateShowIf(condition, ctx) {
|
|
61
|
+
if (Array.isArray(condition))
|
|
62
|
+
return condition.every((c) => evaluateShowIf(c, ctx));
|
|
59
63
|
if (typeof condition !== 'string' || condition.length === 0)
|
|
60
64
|
return true;
|
|
61
65
|
if (!ctx)
|
|
@@ -82,3 +86,12 @@ function evaluateShowIf(condition, ctx) {
|
|
|
82
86
|
return true;
|
|
83
87
|
return negate ? !isTruthy(value) : isTruthy(value);
|
|
84
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* `x-lt-hide-if-empty`: the field is suppressed while its value is empty
|
|
91
|
+
* (null, undefined, '', false, or 0). Render and validation share this test.
|
|
92
|
+
*/
|
|
93
|
+
function isHiddenIfEmpty(fieldSchema, value) {
|
|
94
|
+
if (fieldSchema?.['x-lt-hide-if-empty'] !== true)
|
|
95
|
+
return false;
|
|
96
|
+
return value === null || value === undefined || value === '' || value === false || value === 0;
|
|
97
|
+
}
|
package/build/start/workers.js
CHANGED
|
@@ -51,6 +51,8 @@ const mcp_1 = require("../services/mcp");
|
|
|
51
51
|
const yamlWorkflowWorkers = __importStar(require("../services/yaml-workflow/workers"));
|
|
52
52
|
const migrate_1 = require("../lib/db/migrate");
|
|
53
53
|
const apply_report_1 = require("./apply-report");
|
|
54
|
+
const escalation_2 = require("../types/escalation");
|
|
55
|
+
const lookup_refs_1 = require("../services/knowledge/lookup-refs");
|
|
54
56
|
/**
|
|
55
57
|
* Create a named no-op workflow function for readonly/observer workers.
|
|
56
58
|
* The function name is used by `registerWorker` for discovery.
|
|
@@ -221,6 +223,13 @@ async function startWorkers(startConfig, workers, builtinMcpServerFactories) {
|
|
|
221
223
|
for (const w of workersWithConfig) {
|
|
222
224
|
const workflowType = w.workflow.name;
|
|
223
225
|
const c = w.config;
|
|
226
|
+
if (c.inputLookups !== undefined) {
|
|
227
|
+
(0, escalation_2.assertLookupRefs)(c.inputLookups);
|
|
228
|
+
// Editions may be seeded after registration; a missing pin warns here and surfaces on the Invoke Tool page.
|
|
229
|
+
for (const problem of await (0, lookup_refs_1.describeMissingLookupRefs)(c.inputLookups)) {
|
|
230
|
+
logger_1.loggerRegistry.warn(`[long-tail] ${workflowType}: ${problem}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
224
233
|
const declaration = {
|
|
225
234
|
workflow_type: workflowType,
|
|
226
235
|
task_queue: w.taskQueue,
|
|
@@ -233,6 +242,9 @@ async function startWorkers(startConfig, workers, builtinMcpServerFactories) {
|
|
|
233
242
|
consumes: c.consumes ?? [],
|
|
234
243
|
tool_tags: c.toolTags ?? [],
|
|
235
244
|
envelope_schema: c.envelopeSchema ?? null,
|
|
245
|
+
input_schema: c.inputSchema ?? null,
|
|
246
|
+
icon: c.icon ?? null,
|
|
247
|
+
input_lookups: c.inputLookups ?? null,
|
|
236
248
|
resolver_schema: c.resolverSchema ?? null,
|
|
237
249
|
cron_schedule: c.cronSchedule ?? null,
|
|
238
250
|
execute_as: c.executeAs ?? null,
|