@hotmeshio/long-tail 0.16.2 → 0.17.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/exports.d.ts +15 -0
- package/build/api/exports.js +35 -0
- package/build/api/users.d.ts +31 -1
- package/build/api/users.js +54 -1
- package/build/bin/ltc.js +11 -0
- package/build/lib/cli/commands/users.d.ts +11 -0
- package/build/lib/cli/commands/users.js +59 -0
- package/build/lib/cli/commands/workflows.d.ts +3 -0
- package/build/lib/cli/commands/workflows.js +22 -0
- package/build/routes/exports.js +11 -0
- package/build/routes/users.js +26 -0
- package/build/sdk/index.d.ts +3 -0
- package/build/sdk/index.js +3 -0
- package/build/services/export/index.d.ts +19 -0
- package/build/services/export/index.js +53 -33
- package/build/services/user/crud.d.ts +32 -1
- package/build/services/user/crud.js +108 -0
- package/build/services/user/index.d.ts +2 -2
- package/build/services/user/index.js +5 -1
- package/build/services/user/sql.d.ts +16 -0
- package/build/services/user/sql.js +33 -1
- package/build/services/user/types.d.ts +11 -0
- package/build/shared/form-validation/field-validator.d.ts +8 -6
- package/build/shared/form-validation/field-validator.js +23 -15
- package/build/shared/form-validation/x-lt-options.js +35 -21
- package/build/system/mcp-servers/admin/exports.js +15 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +37 -14
- package/build/system/mcp-servers/admin/schemas.js +12 -3
- package/build/system/mcp-servers/admin/users.js +26 -0
- package/build/system/seed/tool-manifests-admin.d.ts +445 -0
- package/build/system/seed/tool-manifests-admin.js +2 -0
- package/dashboard/dist/assets/{AdminDashboard-BrOvvDHF.js → AdminDashboard-Bx5G6Qb_.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-BrOvvDHF.js.map → AdminDashboard-Bx5G6Qb_.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-CtVq8J0L.js → AgentConfigPage-S-YfPwCG.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-CtVq8J0L.js.map → AgentConfigPage-S-YfPwCG.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-DTfTQDug.js → AgentDetailPage-pFVqLY4c.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-DTfTQDug.js.map → AgentDetailPage-pFVqLY4c.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-vCTc3Qvj.js → AgentsPage-DjAluFkM.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-vCTc3Qvj.js.map → AgentsPage-DjAluFkM.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-DJODShd7.js → AvailableEscalationsPage-BHsRZk4v.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-DJODShd7.js.map → AvailableEscalationsPage-BHsRZk4v.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-GU44inXA.js → BotPicker-h2YrxQS2.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-GU44inXA.js.map → BotPicker-h2YrxQS2.js.map} +1 -1
- package/dashboard/dist/assets/{BulkAssignModal-ChqzG6FY.js → BulkAssignModal-CNKZBgK5.js} +2 -2
- package/dashboard/dist/assets/{BulkAssignModal-ChqzG6FY.js.map → BulkAssignModal-CNKZBgK5.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-Y2hycdPY.js → CapabilitiesPage-DGsnIiJi.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-Y2hycdPY.js.map → CapabilitiesPage-DGsnIiJi.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-CmCwt_Rs.js → CollapsibleSection-ptEsXSl6.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-CmCwt_Rs.js.map → CollapsibleSection-ptEsXSl6.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-Bx2XXJOd.js → CountdownTimer-Cvif0QtN.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-Bx2XXJOd.js.map → CountdownTimer-Cvif0QtN.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-CoX_PNBe.js → CredentialsPage-CwKUAtAR.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-CoX_PNBe.js.map → CredentialsPage-CwKUAtAR.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-CVYKRipP.js → CronLabel-B9RbqMR-.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-CVYKRipP.js.map → CronLabel-B9RbqMR-.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-jRURiCRW.js → ElapsedCell-BirS3yZq.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-jRURiCRW.js.map → ElapsedCell-BirS3yZq.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-G6nzvgpl.js → EntityTimelinePanel-D3QNqDiL.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-G6nzvgpl.js.map → EntityTimelinePanel-D3QNqDiL.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-D-rVTQ1m.js → EscalationListSchemaPage-Bke-30FY.js} +2 -2
- package/dashboard/dist/assets/{EscalationListSchemaPage-D-rVTQ1m.js.map → EscalationListSchemaPage-Bke-30FY.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-CV0R_xY9.js → EscalationSchemaPage-CTFE9vko.js} +2 -2
- package/dashboard/dist/assets/{EscalationSchemaPage-CV0R_xY9.js.map → EscalationSchemaPage-CTFE9vko.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-DMdx15CQ.js → EscalationsOverview-C2FaSmXk.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-DMdx15CQ.js.map → EscalationsOverview-C2FaSmXk.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CIvsdt-q.js → EventTable-zFqzbEdC.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CIvsdt-q.js.map → EventTable-zFqzbEdC.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-DWYGkVRH.js → FilterBar-fwUqeM-5.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-DWYGkVRH.js.map → FilterBar-fwUqeM-5.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-BGHlXh4r.js → GraphInvokePage-CA_XYI2W.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-BGHlXh4r.js.map → GraphInvokePage-CA_XYI2W.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-BHOnp8SK.js → HomePage-C2HnqdFX.js} +2 -2
- package/dashboard/dist/assets/{HomePage-BHOnp8SK.js.map → HomePage-C2HnqdFX.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-iOgn_db5.js → ListToolbar-BEogxu1f.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-iOgn_db5.js.map → ListToolbar-BEogxu1f.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-Be9sMKCA.js → McpOverview-CdMR-5qh.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-Be9sMKCA.js.map → McpOverview-CdMR-5qh.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-BIgpmGJN.js → McpQueryDetailPage-BXo4UjJF.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-BIgpmGJN.js.map → McpQueryDetailPage-BXo4UjJF.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-Okcxw_Um.js → McpQueryPage-BvvM0Ya1.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-Okcxw_Um.js.map → McpQueryPage-BvvM0Ya1.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-DT8kOfih.js → McpRunDetailPage-5eaJeupC.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-DT8kOfih.js.map → McpRunDetailPage-5eaJeupC.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-BXhoP77D.js → McpRunsPage-B5_-3NUF.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-BXhoP77D.js.map → McpRunsPage-B5_-3NUF.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-rVhC8JPv.js → OperationsPage-CJXTw02Z.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-rVhC8JPv.js.map → OperationsPage-CJXTw02Z.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-CIt061hu.js → OperatorDashboard-Dx7639os.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-CIt061hu.js.map → OperatorDashboard-Dx7639os.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-r46uNF4E.js → PersonaDetailPage-BHQ44UIu.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-r46uNF4E.js.map → PersonaDetailPage-BHQ44UIu.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-CayYv9-j.js → PersonasPage-Cnmb4uox.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-CayYv9-j.js.map → PersonasPage-Cnmb4uox.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-dn7lkM4c.js → ProcessDetailPage-CZ09xiWf.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-dn7lkM4c.js.map → ProcessDetailPage-CZ09xiWf.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-DOp5J6Be.js → ProcessesListPage-BT76_7bW.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-DOp5J6Be.js.map → ProcessesListPage-BT76_7bW.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-DOlNoiAK.js → RoleDetailPage-CDsJKPvV.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-DOlNoiAK.js.map → RoleDetailPage-CDsJKPvV.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-DPppT6Zl.js → RolesPage-D2cV92bL.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-DPppT6Zl.js.map → RolesPage-D2cV92bL.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-BgntKfSA.js → RunAsSelector-Cvi8x8xx.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-BgntKfSA.js.map → RunAsSelector-Cvi8x8xx.js.map} +1 -1
- package/dashboard/dist/assets/{ScanCodesPage-DPm1lG79.js → ScanCodesPage-BWt_iRCu.js} +2 -2
- package/dashboard/dist/assets/{ScanCodesPage-DPm1lG79.js.map → ScanCodesPage-BWt_iRCu.js.map} +1 -1
- package/dashboard/dist/assets/{ScanSchemeDetailPage-CuoG89q1.js → ScanSchemeDetailPage-C6mRYkxL.js} +2 -2
- package/dashboard/dist/assets/{ScanSchemeDetailPage-CuoG89q1.js.map → ScanSchemeDetailPage-C6mRYkxL.js.map} +1 -1
- package/dashboard/dist/assets/{ScanStationPage-2SLXqqs0.js → ScanStationPage-YQiijAKy.js} +2 -2
- package/dashboard/dist/assets/{ScanStationPage-2SLXqqs0.js.map → ScanStationPage-YQiijAKy.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-Bc_Mzu_R.js → StickyPagination-BsbSade1.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-Bc_Mzu_R.js.map → StickyPagination-BsbSade1.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-S1cnLGkf.js → StreamMessageDetail-jczXwuBw.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-S1cnLGkf.js.map → StreamMessageDetail-jczXwuBw.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-BUu2sPmY.js → SwimlaneTimeline-DSO6QXmX.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-BUu2sPmY.js.map → SwimlaneTimeline-DSO6QXmX.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-BMfNNtbN.js → TaskDetailPage-DWLfcAF4.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-BMfNNtbN.js.map → TaskDetailPage-DWLfcAF4.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-BmNnopOU.js → TasksListPage-B0at3vJ3.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-BmNnopOU.js.map → TasksListPage-B0at3vJ3.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-Dip7gQQx.js → TimeAgo-poxwErGl.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-Dip7gQQx.js.map → TimeAgo-poxwErGl.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DRAYnIrx.js → TimestampCell-Be6tvFQd.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DRAYnIrx.js.map → TimestampCell-Be6tvFQd.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-CQVYC3Ba.js → ToolTestPanel-CYOqnqMz.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-CQVYC3Ba.js.map → ToolTestPanel-CYOqnqMz.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-Bmtwuksg.js → TopicDetailPage-C82WIKaU.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-Bmtwuksg.js.map → TopicDetailPage-C82WIKaU.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-DIgF7-mJ.js → TopicsPage-COH547ZD.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-DIgF7-mJ.js.map → TopicsPage-COH547ZD.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DNKFz7X9.js → UserName-D2SoVbe9.js} +2 -2
- package/dashboard/dist/assets/{UserName-DNKFz7X9.js.map → UserName-D2SoVbe9.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-DraIBNpl.js → WorkflowExecutionPage-C82Q-TYC.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-DraIBNpl.js.map → WorkflowExecutionPage-C82Q-TYC.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-BH7kmFjM.js → WorkflowsDashboard-DDWwCT-v.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-BH7kmFjM.js.map → WorkflowsDashboard-DDWwCT-v.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-C98pCjQX.js → WorkflowsOverview-DdKRtWdK.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-C98pCjQX.js.map → WorkflowsOverview-DdKRtWdK.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BWQjXenZ.js → YamlWorkflowDetailPage-D3qvyy_4.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BWQjXenZ.js.map → YamlWorkflowDetailPage-D3qvyy_4.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BGTI_sdP.js → YamlWorkflowsPage-BJsxZOBC.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BGTI_sdP.js.map → YamlWorkflowsPage-BJsxZOBC.js.map} +1 -1
- package/dashboard/dist/assets/{agents-DfMrlw54.js → agents-OQHCkIfJ.js} +2 -2
- package/dashboard/dist/assets/{agents-DfMrlw54.js.map → agents-OQHCkIfJ.js.map} +1 -1
- package/dashboard/dist/assets/{bots-B9zS0z7D.js → bots-e8jsNOf4.js} +2 -2
- package/dashboard/dist/assets/{bots-B9zS0z7D.js.map → bots-e8jsNOf4.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DkLM1xgH.js → capabilities-CEo0AB79.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DkLM1xgH.js.map → capabilities-CEo0AB79.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-SJK1yvbm.js → controlplane-CD6ti-QB.js} +2 -2
- package/dashboard/dist/assets/{controlplane-SJK1yvbm.js.map → controlplane-CD6ti-QB.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-BvAylNM1.js → escalation-columns-CUtDSbxl.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-BvAylNM1.js.map → escalation-columns-CUtDSbxl.js.map} +1 -1
- package/dashboard/dist/assets/{index-DSfY8oDp.js → index-B0C6wSrQ.js} +2 -2
- package/dashboard/dist/assets/{index-DSfY8oDp.js.map → index-B0C6wSrQ.js.map} +1 -1
- package/dashboard/dist/assets/index-B2aiEKtM.js +2 -0
- package/dashboard/dist/assets/index-B2aiEKtM.js.map +1 -0
- package/dashboard/dist/assets/{index-DKXOIcO3.js → index-B76fjEom.js} +2 -2
- package/dashboard/dist/assets/{index-DKXOIcO3.js.map → index-B76fjEom.js.map} +1 -1
- package/dashboard/dist/assets/{index-DvmyIGeZ.js → index-BYIN0l5M.js} +2 -2
- package/dashboard/dist/assets/{index-DvmyIGeZ.js.map → index-BYIN0l5M.js.map} +1 -1
- package/dashboard/dist/assets/{index-CXe2d5kg.js → index-Bf4IPu7I.js} +2 -2
- package/dashboard/dist/assets/{index-CXe2d5kg.js.map → index-Bf4IPu7I.js.map} +1 -1
- package/dashboard/dist/assets/index-BpwkKV5f.js +3 -0
- package/dashboard/dist/assets/index-BpwkKV5f.js.map +1 -0
- package/dashboard/dist/assets/{index-Cw-V0VhS.js → index-BsP7vujM.js} +2 -2
- package/dashboard/dist/assets/{index-Cw-V0VhS.js.map → index-BsP7vujM.js.map} +1 -1
- package/dashboard/dist/assets/{index-PjiXOVdw.js → index-C8VhbKFU.js} +2 -2
- package/dashboard/dist/assets/{index-PjiXOVdw.js.map → index-C8VhbKFU.js.map} +1 -1
- package/dashboard/dist/assets/{index-D2IRxjSf.js → index-COUj4v_W.js} +2 -2
- package/dashboard/dist/assets/{index-D2IRxjSf.js.map → index-COUj4v_W.js.map} +1 -1
- package/dashboard/dist/assets/{index-ClVNU3G3.js → index-CTZEzzN3.js} +2 -2
- package/dashboard/dist/assets/{index-ClVNU3G3.js.map → index-CTZEzzN3.js.map} +1 -1
- package/dashboard/dist/assets/{index-DazfFRUx.js → index-DIHr2CvI.js} +2 -2
- package/dashboard/dist/assets/{index-DazfFRUx.js.map → index-DIHr2CvI.js.map} +1 -1
- package/dashboard/dist/assets/{index-zrTQcPjB.js → index-DSdqso-_.js} +3 -3
- package/dashboard/dist/assets/{index-zrTQcPjB.js.map → index-DSdqso-_.js.map} +1 -1
- package/dashboard/dist/assets/{index-CLxuBb17.js → index-VsZyCFz8.js} +2 -2
- package/dashboard/dist/assets/{index-CLxuBb17.js.map → index-VsZyCFz8.js.map} +1 -1
- package/dashboard/dist/assets/{index-CJV2pWNH.css → index-fUqvRHOe.css} +1 -1
- package/dashboard/dist/assets/{knowledge-BNp6MH-4.js → knowledge-C89zT4Qe.js} +2 -2
- package/dashboard/dist/assets/{knowledge-BNp6MH-4.js.map → knowledge-C89zT4Qe.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-Bb1k5rv-.js → mcp-BLKHykZS.js} +2 -2
- package/dashboard/dist/assets/{mcp-Bb1k5rv-.js.map → mcp-BLKHykZS.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-QVakMQnS.js → mcp-query-CfiqUNDV.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-QVakMQnS.js.map → mcp-query-CfiqUNDV.js.map} +1 -1
- package/dashboard/dist/assets/{personas-DV2JUjVj.js → personas-B1HzC94M.js} +2 -2
- package/dashboard/dist/assets/{personas-DV2JUjVj.js.map → personas-B1HzC94M.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-BkVB7Q0p.js → pipelines-C73X50ES.js} +2 -2
- package/dashboard/dist/assets/{pipelines-BkVB7Q0p.js.map → pipelines-C73X50ES.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-DvYWcASM.js → tasks-DHbFpQk4.js} +2 -2
- package/dashboard/dist/assets/{tasks-DvYWcASM.js.map → tasks-DHbFpQk4.js.map} +1 -1
- package/dashboard/dist/assets/{topics-B9zXFuVG.js → topics-Fu8qCUOd.js} +2 -2
- package/dashboard/dist/assets/{topics-B9zXFuVG.js.map → topics-Fu8qCUOd.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-JDpifqGZ.js → useEventHooks-DL3Vhz4g.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-JDpifqGZ.js.map → useEventHooks-DL3Vhz4g.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-Bqr-LdWx.js → useNamespace-CpO5Hogb.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-Bqr-LdWx.js.map → useNamespace-CpO5Hogb.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-n3naCEbw.js → useYamlActivityEvents-BwIl6_d2.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-n3naCEbw.js.map → useYamlActivityEvents-BwIl6_d2.js.map} +1 -1
- package/dashboard/dist/assets/users-C0ke1Z-8.js +2 -0
- package/dashboard/dist/assets/users-C0ke1Z-8.js.map +1 -0
- package/dashboard/dist/assets/{workflows-D8uMBPvQ.js → workflows-DR9OQcuq.js} +2 -2
- package/dashboard/dist/assets/{workflows-D8uMBPvQ.js.map → workflows-DR9OQcuq.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-DVDOQM3Y.js → yaml-workflows-DjEHh9Wy.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-DVDOQM3Y.js.map → yaml-workflows-DjEHh9Wy.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/api/http/users.md +53 -1
- package/docs/api/http/workflows.md +35 -0
- package/docs/api/mcp/admin.md +31 -0
- package/docs/api/sdk/users.md +24 -0
- package/docs/api/sdk/workflows.md +21 -0
- package/docs/dashboard.md +1 -1
- package/docs/hitl/lookups.md +10 -0
- package/docs/hitl/x-lt-validation.md +2 -1
- package/docs/hitl/x-lt-widget.md +1 -1
- package/docs/hitl-guide.md +2 -2
- package/package.json +2 -2
- package/dashboard/dist/assets/index-DTZxHZJO.js +0 -3
- package/dashboard/dist/assets/index-DTZxHZJO.js.map +0 -1
- package/dashboard/dist/assets/index-DamcWcqG.js +0 -2
- package/dashboard/dist/assets/index-DamcWcqG.js.map +0 -1
- package/dashboard/dist/assets/users-BNXLRVTS.js +0 -2
- package/dashboard/dist/assets/users-BNXLRVTS.js.map +0 -1
package/build/api/exports.d.ts
CHANGED
|
@@ -77,6 +77,21 @@ export declare function exportWorkflowExecution(input: {
|
|
|
77
77
|
export declare function getWorkflowStatus(input: {
|
|
78
78
|
workflowId: string;
|
|
79
79
|
}): Promise<LTApiResult>;
|
|
80
|
+
/**
|
|
81
|
+
* Get a workflow's input and output envelopes — the effortless read.
|
|
82
|
+
*
|
|
83
|
+
* Two narrow lookups (no event stream, no full export): the input is
|
|
84
|
+
* available for the life of the job; the output is null with
|
|
85
|
+
* `status: 'running'` until the workflow completes, making this the natural
|
|
86
|
+
* polling body. A failed run answers `status: 'failed'` with the workflow's
|
|
87
|
+
* error message.
|
|
88
|
+
*
|
|
89
|
+
* @param input.workflowId — the workflow's unique identifier
|
|
90
|
+
* @returns `{ status: 200, data: { workflow_id, status, input, output, error? } }`
|
|
91
|
+
*/
|
|
92
|
+
export declare function getWorkflowEnvelopes(input: {
|
|
93
|
+
workflowId: string;
|
|
94
|
+
}): Promise<LTApiResult>;
|
|
80
95
|
/**
|
|
81
96
|
* Get the current state data of a workflow.
|
|
82
97
|
*
|
package/build/api/exports.js
CHANGED
|
@@ -37,6 +37,7 @@ exports.listJobs = listJobs;
|
|
|
37
37
|
exports.exportWorkflowState = exportWorkflowState;
|
|
38
38
|
exports.exportWorkflowExecution = exportWorkflowExecution;
|
|
39
39
|
exports.getWorkflowStatus = getWorkflowStatus;
|
|
40
|
+
exports.getWorkflowEnvelopes = getWorkflowEnvelopes;
|
|
40
41
|
exports.getWorkflowState = getWorkflowState;
|
|
41
42
|
const exportService = __importStar(require("../services/export"));
|
|
42
43
|
const resolve_1 = require("../services/task/resolve");
|
|
@@ -171,6 +172,40 @@ async function getWorkflowStatus(input) {
|
|
|
171
172
|
};
|
|
172
173
|
}
|
|
173
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Get a workflow's input and output envelopes — the effortless read.
|
|
177
|
+
*
|
|
178
|
+
* Two narrow lookups (no event stream, no full export): the input is
|
|
179
|
+
* available for the life of the job; the output is null with
|
|
180
|
+
* `status: 'running'` until the workflow completes, making this the natural
|
|
181
|
+
* polling body. A failed run answers `status: 'failed'` with the workflow's
|
|
182
|
+
* error message.
|
|
183
|
+
*
|
|
184
|
+
* @param input.workflowId — the workflow's unique identifier
|
|
185
|
+
* @returns `{ status: 200, data: { workflow_id, status, input, output, error? } }`
|
|
186
|
+
*/
|
|
187
|
+
async function getWorkflowEnvelopes(input) {
|
|
188
|
+
try {
|
|
189
|
+
let resolved;
|
|
190
|
+
try {
|
|
191
|
+
resolved = await (0, resolve_1.resolveWorkflowHandle)(input.workflowId);
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
return { status: 404, error: 'Workflow not found' };
|
|
195
|
+
}
|
|
196
|
+
const result = await exportService.getWorkflowEnvelopes(input.workflowId, resolved.taskQueue, resolved.workflowName);
|
|
197
|
+
return { status: 200, data: result };
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
const status = err.status === 404 || err.message?.includes('Not Found') ? 404 : 500;
|
|
201
|
+
return {
|
|
202
|
+
status,
|
|
203
|
+
error: status === 404
|
|
204
|
+
? 'Workflow data is no longer available (job may have expired)'
|
|
205
|
+
: err.message,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
174
209
|
/**
|
|
175
210
|
* Get the current state data of a workflow.
|
|
176
211
|
*
|
package/build/api/users.d.ts
CHANGED
|
@@ -63,7 +63,8 @@ export declare function createUser(input: {
|
|
|
63
63
|
* @param input.email — new email address
|
|
64
64
|
* @param input.display_name — new display name
|
|
65
65
|
* @param input.status — new user status
|
|
66
|
-
* @param input.metadata —
|
|
66
|
+
* @param input.metadata — REPLACES the whole properties dictionary; for
|
|
67
|
+
* per-key edits use patchUserProperties (never clobbers siblings)
|
|
67
68
|
* @returns `{ status: 200, data: User }` on success, or `{ status: 404 }` if not found
|
|
68
69
|
*/
|
|
69
70
|
export declare function updateUser(input: {
|
|
@@ -74,6 +75,35 @@ export declare function updateUser(input: {
|
|
|
74
75
|
status?: string;
|
|
75
76
|
metadata?: Record<string, any>;
|
|
76
77
|
}): Promise<LTApiResult>;
|
|
78
|
+
/**
|
|
79
|
+
* Atomically patch the user's properties dictionary (lt_users.metadata) —
|
|
80
|
+
* one statement, never read-merge-write. Deleting a key is explicit
|
|
81
|
+
* (`remove`); a key absent from the patch is kept. `rename` preserves the
|
|
82
|
+
* value with no key-absent window. Identity-binding keys (badge scan
|
|
83
|
+
* scheme target facets) assert uniqueness among active users in the same
|
|
84
|
+
* statement.
|
|
85
|
+
*
|
|
86
|
+
* @param input.id — the user's unique identifier
|
|
87
|
+
* @param input.set — properties to set (typed JSON values)
|
|
88
|
+
* @param input.remove — property keys to delete
|
|
89
|
+
* @param input.rename — `{ oldKey: newKey }` renames, values preserved
|
|
90
|
+
* @returns `{ status: 200, data: User }`; 400 malformed patch; 404 unknown
|
|
91
|
+
* user; 409 when an identity value already belongs to another active user
|
|
92
|
+
*/
|
|
93
|
+
export declare function patchUserProperties(input: {
|
|
94
|
+
id: string;
|
|
95
|
+
set?: Record<string, unknown>;
|
|
96
|
+
remove?: string[];
|
|
97
|
+
rename?: Record<string, string>;
|
|
98
|
+
}): Promise<LTApiResult>;
|
|
99
|
+
/**
|
|
100
|
+
* The property keys the platform itself resolves identities against — every
|
|
101
|
+
* enabled identity scan scheme's target facet. The dashboard marks these as
|
|
102
|
+
* system properties.
|
|
103
|
+
*
|
|
104
|
+
* @returns `{ status: 200, data: { keys: string[] } }`
|
|
105
|
+
*/
|
|
106
|
+
export declare function getSystemPropertyKeys(): Promise<LTApiResult>;
|
|
77
107
|
/**
|
|
78
108
|
* Delete a user by ID. Requires admin privileges.
|
|
79
109
|
*
|
package/build/api/users.js
CHANGED
|
@@ -37,6 +37,8 @@ exports.listUsers = listUsers;
|
|
|
37
37
|
exports.getUser = getUser;
|
|
38
38
|
exports.createUser = createUser;
|
|
39
39
|
exports.updateUser = updateUser;
|
|
40
|
+
exports.patchUserProperties = patchUserProperties;
|
|
41
|
+
exports.getSystemPropertyKeys = getSystemPropertyKeys;
|
|
40
42
|
exports.deleteUser = deleteUser;
|
|
41
43
|
exports.getUserRoles = getUserRoles;
|
|
42
44
|
exports.addUserRole = addUserRole;
|
|
@@ -145,7 +147,8 @@ async function createUser(input) {
|
|
|
145
147
|
* @param input.email — new email address
|
|
146
148
|
* @param input.display_name — new display name
|
|
147
149
|
* @param input.status — new user status
|
|
148
|
-
* @param input.metadata —
|
|
150
|
+
* @param input.metadata — REPLACES the whole properties dictionary; for
|
|
151
|
+
* per-key edits use patchUserProperties (never clobbers siblings)
|
|
149
152
|
* @returns `{ status: 200, data: User }` on success, or `{ status: 404 }` if not found
|
|
150
153
|
*/
|
|
151
154
|
async function updateUser(input) {
|
|
@@ -161,6 +164,56 @@ async function updateUser(input) {
|
|
|
161
164
|
return { status: 500, error: err.message };
|
|
162
165
|
}
|
|
163
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Atomically patch the user's properties dictionary (lt_users.metadata) —
|
|
169
|
+
* one statement, never read-merge-write. Deleting a key is explicit
|
|
170
|
+
* (`remove`); a key absent from the patch is kept. `rename` preserves the
|
|
171
|
+
* value with no key-absent window. Identity-binding keys (badge scan
|
|
172
|
+
* scheme target facets) assert uniqueness among active users in the same
|
|
173
|
+
* statement.
|
|
174
|
+
*
|
|
175
|
+
* @param input.id — the user's unique identifier
|
|
176
|
+
* @param input.set — properties to set (typed JSON values)
|
|
177
|
+
* @param input.remove — property keys to delete
|
|
178
|
+
* @param input.rename — `{ oldKey: newKey }` renames, values preserved
|
|
179
|
+
* @returns `{ status: 200, data: User }`; 400 malformed patch; 404 unknown
|
|
180
|
+
* user; 409 when an identity value already belongs to another active user
|
|
181
|
+
*/
|
|
182
|
+
async function patchUserProperties(input) {
|
|
183
|
+
try {
|
|
184
|
+
const user = await userService.patchUserProperties(input.id, {
|
|
185
|
+
set: input.set,
|
|
186
|
+
remove: input.remove,
|
|
187
|
+
rename: input.rename,
|
|
188
|
+
});
|
|
189
|
+
if (!user) {
|
|
190
|
+
return { status: 404, error: 'User not found' };
|
|
191
|
+
}
|
|
192
|
+
return { status: 200, data: user };
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
if (err.status === 400 || err.status === 409) {
|
|
196
|
+
return { status: err.status, error: err.message };
|
|
197
|
+
}
|
|
198
|
+
return { status: 500, error: err.message };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* The property keys the platform itself resolves identities against — every
|
|
203
|
+
* enabled identity scan scheme's target facet. The dashboard marks these as
|
|
204
|
+
* system properties.
|
|
205
|
+
*
|
|
206
|
+
* @returns `{ status: 200, data: { keys: string[] } }`
|
|
207
|
+
*/
|
|
208
|
+
async function getSystemPropertyKeys() {
|
|
209
|
+
try {
|
|
210
|
+
const keys = await userService.getIdentityPropertyKeys();
|
|
211
|
+
return { status: 200, data: { keys } };
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
return { status: 500, error: err.message };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
164
217
|
/**
|
|
165
218
|
* Delete a user by ID. Requires admin privileges.
|
|
166
219
|
*
|
package/build/bin/ltc.js
CHANGED
|
@@ -259,6 +259,10 @@ wfCmd.command('status <id>')
|
|
|
259
259
|
wfCmd.command('result <id>')
|
|
260
260
|
.option('--json', 'JSON output')
|
|
261
261
|
.action(wrap(wf.getWorkflowResult));
|
|
262
|
+
wfCmd.command('envelopes <id>')
|
|
263
|
+
.description('The workflow\'s input and output envelopes — light, never blocks')
|
|
264
|
+
.option('--json', 'JSON output')
|
|
265
|
+
.action(wrap(wf.getWorkflowEnvelopes));
|
|
262
266
|
wfCmd.command('terminate <id>')
|
|
263
267
|
.action(wrap(wf.terminateWorkflow));
|
|
264
268
|
// ── Pipelines (YAML Workflows) ──────────────────────────────────────────
|
|
@@ -331,6 +335,13 @@ usrCmd.command('list')
|
|
|
331
335
|
usrCmd.command('get <id>')
|
|
332
336
|
.option('--json', 'JSON output')
|
|
333
337
|
.action(wrap(usr.getUser));
|
|
338
|
+
usrCmd.command('props <id>')
|
|
339
|
+
.description('View or atomically patch the user\'s properties dictionary')
|
|
340
|
+
.option('--set <key=value...>', 'Set a property (repeatable; value JSON-parsed, string fallback)')
|
|
341
|
+
.option('--remove <key...>', 'Delete a property (repeatable)')
|
|
342
|
+
.option('--rename <old=new...>', 'Rename a property, value preserved (repeatable)')
|
|
343
|
+
.option('--json', 'JSON output')
|
|
344
|
+
.action(wrap(usr.userProps));
|
|
334
345
|
// ── Roles ────────────────────────────────────────────────────────────────
|
|
335
346
|
const rolesCmd = commander_1.program.command('roles').description('Roles — the queue-backed work surfaces where workflows hand off to people');
|
|
336
347
|
rolesCmd.command('list')
|
|
@@ -5,3 +5,14 @@ export declare function listUsers(opts: {
|
|
|
5
5
|
export declare function getUser(id: string, opts: {
|
|
6
6
|
json?: boolean;
|
|
7
7
|
}): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* View or atomically patch a user's properties dictionary. With no flags,
|
|
10
|
+
* prints the dictionary; with --set/--remove/--rename, applies ONE atomic
|
|
11
|
+
* patch (never read-merge-write) and prints the result.
|
|
12
|
+
*/
|
|
13
|
+
export declare function userProps(id: string, opts: {
|
|
14
|
+
set?: string[];
|
|
15
|
+
remove?: string[];
|
|
16
|
+
rename?: string[];
|
|
17
|
+
json?: boolean;
|
|
18
|
+
}): Promise<void>;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.listUsers = listUsers;
|
|
4
7
|
exports.getUser = getUser;
|
|
8
|
+
exports.userProps = userProps;
|
|
9
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
5
10
|
const client_1 = require("../client");
|
|
6
11
|
const format_1 = require("../format");
|
|
7
12
|
const COLUMNS = [
|
|
@@ -23,3 +28,57 @@ async function getUser(id, opts) {
|
|
|
23
28
|
}
|
|
24
29
|
console.log(JSON.stringify(data, null, 2));
|
|
25
30
|
}
|
|
31
|
+
/** Parse a repeatable `key=value` flag; values JSON-parse with string fallback. */
|
|
32
|
+
function parsePairs(pairs) {
|
|
33
|
+
if (!pairs?.length)
|
|
34
|
+
return undefined;
|
|
35
|
+
const out = {};
|
|
36
|
+
for (const pair of pairs) {
|
|
37
|
+
const eq = pair.indexOf('=');
|
|
38
|
+
if (eq <= 0)
|
|
39
|
+
throw new Error(`Expected key=value, got "${pair}"`);
|
|
40
|
+
const key = pair.slice(0, eq);
|
|
41
|
+
const raw = pair.slice(eq + 1);
|
|
42
|
+
try {
|
|
43
|
+
out[key] = JSON.parse(raw);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
out[key] = raw;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* View or atomically patch a user's properties dictionary. With no flags,
|
|
53
|
+
* prints the dictionary; with --set/--remove/--rename, applies ONE atomic
|
|
54
|
+
* patch (never read-merge-write) and prints the result.
|
|
55
|
+
*/
|
|
56
|
+
async function userProps(id, opts) {
|
|
57
|
+
const set = parsePairs(opts.set);
|
|
58
|
+
const rename = parsePairs(opts.rename);
|
|
59
|
+
const remove = opts.remove?.length ? opts.remove : undefined;
|
|
60
|
+
let user;
|
|
61
|
+
if (set || remove || rename) {
|
|
62
|
+
user = await (0, client_1.apiFetch)(`/users/${id}/properties`, {
|
|
63
|
+
method: 'PATCH',
|
|
64
|
+
body: JSON.stringify({ set, remove, rename }),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
user = await (0, client_1.apiFetch)(`/users/${id}`);
|
|
69
|
+
}
|
|
70
|
+
if (opts.json) {
|
|
71
|
+
console.log(JSON.stringify(user.metadata ?? {}, null, 2));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const props = Object.entries(user.metadata ?? {});
|
|
75
|
+
console.log(`\n ${picocolors_1.default.bold(user.display_name ?? user.external_id ?? id)} ${picocolors_1.default.dim(user.id ?? id)}`);
|
|
76
|
+
if (props.length === 0) {
|
|
77
|
+
console.log(picocolors_1.default.dim(' (no properties)\n'));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
for (const [key, value] of props) {
|
|
81
|
+
console.log(` ${picocolors_1.default.bold(key)} = ${typeof value === 'string' ? value : JSON.stringify(value)}`);
|
|
82
|
+
}
|
|
83
|
+
console.log();
|
|
84
|
+
}
|
|
@@ -13,4 +13,7 @@ export declare function getWorkflowStatus(id: string, opts: {
|
|
|
13
13
|
export declare function getWorkflowResult(id: string, opts: {
|
|
14
14
|
json?: boolean;
|
|
15
15
|
}): Promise<void>;
|
|
16
|
+
export declare function getWorkflowEnvelopes(id: string, opts: {
|
|
17
|
+
json?: boolean;
|
|
18
|
+
}): Promise<void>;
|
|
16
19
|
export declare function terminateWorkflow(id: string): Promise<void>;
|
|
@@ -40,6 +40,7 @@ exports.listWorkflows = listWorkflows;
|
|
|
40
40
|
exports.invokeWorkflow = invokeWorkflow;
|
|
41
41
|
exports.getWorkflowStatus = getWorkflowStatus;
|
|
42
42
|
exports.getWorkflowResult = getWorkflowResult;
|
|
43
|
+
exports.getWorkflowEnvelopes = getWorkflowEnvelopes;
|
|
43
44
|
exports.terminateWorkflow = terminateWorkflow;
|
|
44
45
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
45
46
|
const client_1 = require("../client");
|
|
@@ -98,6 +99,27 @@ async function getWorkflowResult(id, opts) {
|
|
|
98
99
|
console.log();
|
|
99
100
|
}
|
|
100
101
|
}
|
|
102
|
+
async function getWorkflowEnvelopes(id, opts) {
|
|
103
|
+
const data = await (0, client_1.apiFetch)(`/workflow-states/${id}/envelopes`);
|
|
104
|
+
if (opts.json) {
|
|
105
|
+
console.log(JSON.stringify(data, null, 2));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const status = data.status === 'completed' ? picocolors_1.default.green(data.status)
|
|
109
|
+
: data.status === 'failed' ? picocolors_1.default.red(data.status)
|
|
110
|
+
: picocolors_1.default.blue(data.status);
|
|
111
|
+
console.log(`\n ${picocolors_1.default.dim(data.workflow_id)} ${status}`);
|
|
112
|
+
console.log(`\n ${picocolors_1.default.bold('Input')}`);
|
|
113
|
+
console.log(JSON.stringify(data.input, null, 2));
|
|
114
|
+
console.log(`\n ${picocolors_1.default.bold('Output')}`);
|
|
115
|
+
if (data.error) {
|
|
116
|
+
console.log(picocolors_1.default.red(data.error));
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
console.log(data.output === null ? picocolors_1.default.dim('(not yet — still running)') : JSON.stringify(data.output, null, 2));
|
|
120
|
+
}
|
|
121
|
+
console.log();
|
|
122
|
+
}
|
|
101
123
|
async function terminateWorkflow(id) {
|
|
102
124
|
await (0, client_1.apiFetch)(`/workflows/terminate/${id}`, { method: 'POST' });
|
|
103
125
|
console.log(`\n ${picocolors_1.default.green('✓')} Terminated ${picocolors_1.default.dim(id)}\n`);
|
package/build/routes/exports.js
CHANGED
|
@@ -95,6 +95,17 @@ router.get('/:workflowId/execution', async (req, res) => {
|
|
|
95
95
|
});
|
|
96
96
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
97
97
|
});
|
|
98
|
+
/**
|
|
99
|
+
* GET /api/workflow-states/:workflowId/envelopes
|
|
100
|
+
* The workflow's input and output envelopes — two narrow lookups, no event
|
|
101
|
+
* stream. Output is null with status 'running' until the workflow completes.
|
|
102
|
+
*/
|
|
103
|
+
router.get('/:workflowId/envelopes', async (req, res) => {
|
|
104
|
+
const result = await api.getWorkflowEnvelopes({
|
|
105
|
+
workflowId: req.params.workflowId,
|
|
106
|
+
});
|
|
107
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
108
|
+
});
|
|
98
109
|
/**
|
|
99
110
|
* GET /api/workflow-states/:workflowId/status
|
|
100
111
|
* Return only the numeric status semaphore.
|
package/build/routes/users.js
CHANGED
|
@@ -55,6 +55,16 @@ router.get('/', async (req, res) => {
|
|
|
55
55
|
});
|
|
56
56
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
57
57
|
});
|
|
58
|
+
/**
|
|
59
|
+
* GET /api/users/system-property-keys
|
|
60
|
+
* The property keys the platform resolves identities against (enabled
|
|
61
|
+
* identity scan schemes' target facets) — marked as system properties in
|
|
62
|
+
* the dashboard editor. Registered before /:id so the literal wins.
|
|
63
|
+
*/
|
|
64
|
+
router.get('/system-property-keys', async (_req, res) => {
|
|
65
|
+
const result = await api.getSystemPropertyKeys();
|
|
66
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
67
|
+
});
|
|
58
68
|
/**
|
|
59
69
|
* GET /api/users/:id
|
|
60
70
|
* Get a single user by ID.
|
|
@@ -81,6 +91,22 @@ router.put('/:id', auth_1.requireBuilder, async (req, res) => {
|
|
|
81
91
|
const result = await api.updateUser({ id: req.params.id, ...(req.body || {}) });
|
|
82
92
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
83
93
|
});
|
|
94
|
+
/**
|
|
95
|
+
* PATCH /api/users/:id/properties
|
|
96
|
+
* Atomically patch the user's properties dictionary. Builder only — the
|
|
97
|
+
* same gate as every other user write.
|
|
98
|
+
* Body: { set?: { key: value }, remove?: [key], rename?: { old: new } }
|
|
99
|
+
*/
|
|
100
|
+
router.patch('/:id/properties', auth_1.requireBuilder, async (req, res) => {
|
|
101
|
+
const { set, remove, rename } = req.body || {};
|
|
102
|
+
const result = await api.patchUserProperties({
|
|
103
|
+
id: req.params.id,
|
|
104
|
+
set,
|
|
105
|
+
remove,
|
|
106
|
+
rename,
|
|
107
|
+
});
|
|
108
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
109
|
+
});
|
|
84
110
|
/**
|
|
85
111
|
* DELETE /api/users/:id
|
|
86
112
|
* Delete a user. Builder only.
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -247,6 +247,7 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
247
247
|
options?: Record<string, any>;
|
|
248
248
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
249
249
|
getStatus: typeof workflowsApi.getWorkflowStatus;
|
|
250
|
+
getEnvelopes: typeof exportsApi.getWorkflowEnvelopes;
|
|
250
251
|
getResult: typeof workflowsApi.getWorkflowResult;
|
|
251
252
|
terminate: typeof workflowsApi.terminateWorkflow;
|
|
252
253
|
export: typeof workflowsApi.exportWorkflow;
|
|
@@ -289,6 +290,8 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
289
290
|
get: typeof usersApi.getUser;
|
|
290
291
|
create: typeof usersApi.createUser;
|
|
291
292
|
update: typeof usersApi.updateUser;
|
|
293
|
+
patchProperties: typeof usersApi.patchUserProperties;
|
|
294
|
+
getSystemPropertyKeys: typeof usersApi.getSystemPropertyKeys;
|
|
292
295
|
delete: typeof usersApi.deleteUser;
|
|
293
296
|
getRoles: typeof usersApi.getUserRoles;
|
|
294
297
|
addRole: typeof usersApi.addUserRole;
|
package/build/sdk/index.js
CHANGED
|
@@ -155,6 +155,7 @@ function createClient(options = {}) {
|
|
|
155
155
|
workflows: {
|
|
156
156
|
invoke: bindAuth(workflowsApi.invokeWorkflow, auth),
|
|
157
157
|
getStatus: workflowsApi.getWorkflowStatus,
|
|
158
|
+
getEnvelopes: exportsApi.getWorkflowEnvelopes,
|
|
158
159
|
getResult: workflowsApi.getWorkflowResult,
|
|
159
160
|
terminate: workflowsApi.terminateWorkflow,
|
|
160
161
|
export: workflowsApi.exportWorkflow,
|
|
@@ -193,6 +194,8 @@ function createClient(options = {}) {
|
|
|
193
194
|
get: usersApi.getUser,
|
|
194
195
|
create: usersApi.createUser,
|
|
195
196
|
update: usersApi.updateUser,
|
|
197
|
+
patchProperties: usersApi.patchUserProperties,
|
|
198
|
+
getSystemPropertyKeys: usersApi.getSystemPropertyKeys,
|
|
196
199
|
delete: usersApi.deleteUser,
|
|
197
200
|
getRoles: usersApi.getUserRoles,
|
|
198
201
|
addRole: usersApi.addUserRole,
|
|
@@ -24,6 +24,25 @@ export declare function getWorkflowStatus(workflowId: string, taskQueue: string,
|
|
|
24
24
|
* system/user classification, and a summary.
|
|
25
25
|
*/
|
|
26
26
|
export declare function exportWorkflowExecution(workflowId: string, taskQueue: string, workflowName: string, options?: ExecutionExportOptions): Promise<WorkflowExecution>;
|
|
27
|
+
/** The input/output envelope pair plus the derived run status. */
|
|
28
|
+
export interface WorkflowEnvelopes {
|
|
29
|
+
workflow_id: string;
|
|
30
|
+
status: 'running' | 'completed' | 'failed';
|
|
31
|
+
/** The workflow's input — the single LTEnvelope for one-arg workflows, else the args array. */
|
|
32
|
+
input: unknown;
|
|
33
|
+
/** The workflow's return envelope, or null while it is still running or when it failed. */
|
|
34
|
+
output: unknown;
|
|
35
|
+
/** The workflow's error message, present only when status is 'failed'. */
|
|
36
|
+
error?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The effortless read: what went in, what came out. Two narrow lookups —
|
|
40
|
+
* `handle.input()` (one field read, available for the life of the job) and
|
|
41
|
+
* `handle.output()` (one state read, never blocks) — no event stream, no
|
|
42
|
+
* full export. While the workflow runs, `output` is null and `status` says
|
|
43
|
+
* so, making this the natural polling body.
|
|
44
|
+
*/
|
|
45
|
+
export declare function getWorkflowEnvelopes(workflowId: string, taskQueue: string, workflowName: string): Promise<WorkflowEnvelopes>;
|
|
27
46
|
/**
|
|
28
47
|
* Return the current job state of a workflow.
|
|
29
48
|
* If the workflow is complete this is also the output.
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.exportWorkflow = exportWorkflow;
|
|
4
4
|
exports.getWorkflowStatus = getWorkflowStatus;
|
|
5
5
|
exports.exportWorkflowExecution = exportWorkflowExecution;
|
|
6
|
+
exports.getWorkflowEnvelopes = getWorkflowEnvelopes;
|
|
6
7
|
exports.getWorkflowState = getWorkflowState;
|
|
7
8
|
exports.listJobs = listJobs;
|
|
8
9
|
const db_1 = require("../../lib/db");
|
|
@@ -66,21 +67,14 @@ async function getWorkflowStatus(workflowId, taskQueue, workflowName) {
|
|
|
66
67
|
async function exportWorkflowExecution(workflowId, taskQueue, workflowName, options) {
|
|
67
68
|
try {
|
|
68
69
|
const handle = await (0, client_1.getHandle)(taskQueue, workflowName, workflowId);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (!processed.parent_workflow_id) {
|
|
78
|
-
const pj = extractParentJobId(raw);
|
|
79
|
-
if (pj && pj !== workflowId) {
|
|
80
|
-
processed.parent_workflow_id = pj;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return processed;
|
|
70
|
+
// include_lineage populates parent_workflow_id/origin_id from the jobs
|
|
71
|
+
// table in one indexed lookup — no second export call.
|
|
72
|
+
const execution = await handle.exportExecution({
|
|
73
|
+
...options,
|
|
74
|
+
enrich_inputs: true,
|
|
75
|
+
include_lineage: true,
|
|
76
|
+
});
|
|
77
|
+
return (0, post_process_1.postProcessExecution)(execution);
|
|
84
78
|
}
|
|
85
79
|
catch (err) {
|
|
86
80
|
if (err instanceof WorkflowNotFoundError)
|
|
@@ -89,25 +83,51 @@ async function exportWorkflowExecution(workflowId, taskQueue, workflowName, opti
|
|
|
89
83
|
}
|
|
90
84
|
}
|
|
91
85
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
86
|
+
* The effortless read: what went in, what came out. Two narrow lookups —
|
|
87
|
+
* `handle.input()` (one field read, available for the life of the job) and
|
|
88
|
+
* `handle.output()` (one state read, never blocks) — no event stream, no
|
|
89
|
+
* full export. While the workflow runs, `output` is null and `status` says
|
|
90
|
+
* so, making this the natural polling body.
|
|
95
91
|
*/
|
|
96
|
-
function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
92
|
+
async function getWorkflowEnvelopes(workflowId, taskQueue, workflowName) {
|
|
93
|
+
let handle;
|
|
94
|
+
try {
|
|
95
|
+
handle = await (0, client_1.getHandle)(taskQueue, workflowName, workflowId);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
throw new WorkflowNotFoundError(workflowId);
|
|
99
|
+
}
|
|
100
|
+
const [statusCode, args] = await Promise.all([
|
|
101
|
+
handle.status(),
|
|
102
|
+
handle.input().catch(() => undefined),
|
|
103
|
+
]).catch(() => {
|
|
104
|
+
throw new WorkflowNotFoundError(workflowId);
|
|
105
|
+
});
|
|
106
|
+
// Long-tail workflows take a single LTEnvelope argument — unwrap it;
|
|
107
|
+
// multi-arg workflows keep the args array verbatim.
|
|
108
|
+
const input = Array.isArray(args) && args.length === 1 ? args[0] : args ?? null;
|
|
109
|
+
if (statusCode > 0) {
|
|
110
|
+
return { workflow_id: workflowId, status: 'running', input, output: null };
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const output = await handle.output();
|
|
114
|
+
return {
|
|
115
|
+
workflow_id: workflowId,
|
|
116
|
+
status: statusCode === 0 ? 'completed' : 'failed',
|
|
117
|
+
input,
|
|
118
|
+
output: output ?? null,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
// output() throws the workflow's own error for failed runs — that IS the outcome.
|
|
123
|
+
return {
|
|
124
|
+
workflow_id: workflowId,
|
|
125
|
+
status: 'failed',
|
|
126
|
+
input,
|
|
127
|
+
output: null,
|
|
128
|
+
error: err?.message ?? String(err),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
111
131
|
}
|
|
112
132
|
/**
|
|
113
133
|
* Return the current job state of a workflow.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LTUserRecord, LTRoleType, LTUserStatus } from '../../types';
|
|
2
|
-
import type { CreateUserInput, UpdateUserInput } from './types';
|
|
2
|
+
import type { CreateUserInput, UpdateUserInput, UserPropertyOps } from './types';
|
|
3
3
|
export declare function attachRoles(user: any): Promise<LTUserRecord>;
|
|
4
4
|
export declare function createUser(input: CreateUserInput): Promise<LTUserRecord>;
|
|
5
5
|
export declare function getUser(id: string): Promise<LTUserRecord | null>;
|
|
@@ -12,6 +12,37 @@ export declare function getUserByEmail(email: string): Promise<LTUserRecord | nu
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function getUserByMetadataValue(key: string, value: string): Promise<LTUserRecord | null>;
|
|
14
14
|
export declare function updateUser(id: string, input: UpdateUserInput): Promise<LTUserRecord | null>;
|
|
15
|
+
/** A property write that would create an ambiguous identity binding. */
|
|
16
|
+
export declare class UserPropertyConflictError extends Error {
|
|
17
|
+
status: number;
|
|
18
|
+
constructor(key: string);
|
|
19
|
+
}
|
|
20
|
+
/** A malformed property patch — rejected before any write. */
|
|
21
|
+
export declare class UserPropertyValidationError extends Error {
|
|
22
|
+
status: number;
|
|
23
|
+
constructor(message: string);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The lt_users.metadata keys the platform itself resolves identities against:
|
|
27
|
+
* every enabled identity scan scheme's target_facet (e.g. badge_id). Writes
|
|
28
|
+
* to these keys carry a uniqueness guard; the dashboard marks them as system
|
|
29
|
+
* properties.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getIdentityPropertyKeys(): Promise<string[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Atomic per-key patch of the user's properties dictionary (lt_users.metadata).
|
|
34
|
+
* One statement — never read-merge-write: concurrent patches of different
|
|
35
|
+
* keys both land, a rename never opens a key-absent window, and deleting is
|
|
36
|
+
* explicit (`remove`) — an absent key means keep. Precedence on collision:
|
|
37
|
+
* set > rename > existing. Values are raw JSON, so numbers/booleans/objects
|
|
38
|
+
* round-trip typed.
|
|
39
|
+
*
|
|
40
|
+
* Identity-binding keys (getIdentityPropertyKeys) additionally assert, in the
|
|
41
|
+
* same statement, that no OTHER active user carries the value — the
|
|
42
|
+
* write-side counterpart of getUserByMetadataValue's ambiguity throw.
|
|
43
|
+
* A tripped guard raises UserPropertyConflictError (409).
|
|
44
|
+
*/
|
|
45
|
+
export declare function patchUserProperties(id: string, ops: UserPropertyOps): Promise<LTUserRecord | null>;
|
|
15
46
|
export declare function deleteUser(id: string): Promise<boolean>;
|
|
16
47
|
export declare function listUsers(filters: {
|
|
17
48
|
role?: string;
|