@hotmeshio/long-tail 0.5.11 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/build/api/diagnostics.d.ts +5 -0
- package/build/api/diagnostics.js +5 -1
- package/build/api/escalations/bulk.js +9 -1
- package/build/api/escalations/cancel.js +5 -7
- package/build/api/escalations/claim.js +18 -15
- package/build/api/escalations/create.d.ts +6 -0
- package/build/api/escalations/create.js +11 -8
- package/build/api/escalations/facets.d.ts +18 -0
- package/build/api/escalations/facets.js +115 -0
- package/build/api/escalations/helpers.d.ts +70 -1
- package/build/api/escalations/helpers.js +101 -7
- package/build/api/escalations/index.d.ts +3 -2
- package/build/api/escalations/index.js +7 -1
- package/build/api/escalations/list.d.ts +23 -2
- package/build/api/escalations/list.js +111 -10
- package/build/api/escalations/metadata.js +22 -27
- package/build/api/escalations/resolve.d.ts +19 -1
- package/build/api/escalations/resolve.js +111 -26
- package/build/api/escalations/single.js +8 -8
- package/build/api/settings.d.ts +1 -1
- package/build/api/settings.js +3 -1
- package/build/api/users.d.ts +6 -0
- package/build/api/users.js +29 -1
- package/build/api/workflows/invocation.d.ts +6 -0
- package/build/api/workflows/invocation.js +6 -2
- package/build/bin/ltc.js +40 -0
- package/build/lib/cli/commands/escalations.d.ts +36 -0
- package/build/lib/cli/commands/escalations.js +98 -0
- package/build/lib/db/schemas/001_schema.sql +10 -5
- package/build/lib/db/schemas/012_lt_tasks_workflow_id_unique.sql +20 -0
- package/build/lib/db/schemas/013_role_scope.sql +37 -0
- package/build/modules/features.d.ts +19 -0
- package/build/modules/features.js +16 -0
- package/build/modules/version.d.ts +10 -5
- package/build/modules/version.js +27 -11
- package/build/routes/diagnostics.js +15 -2
- package/build/routes/escalations/facets.d.ts +7 -0
- package/build/routes/escalations/facets.js +81 -0
- package/build/routes/escalations/index.js +3 -0
- package/build/routes/escalations/list.js +48 -0
- package/build/routes/escalations/resolve.js +22 -4
- package/build/routes/users.js +9 -5
- package/build/routes/workflows/invocation.js +12 -4
- package/build/sdk/index.d.ts +35 -2
- package/build/sdk/index.js +7 -0
- package/build/services/diagnostics/index.d.ts +40 -6
- package/build/services/diagnostics/index.js +54 -5
- package/build/services/escalation/crud.d.ts +56 -6
- package/build/services/escalation/crud.js +102 -31
- package/build/services/escalation/facet-sql.d.ts +18 -0
- package/build/services/escalation/facet-sql.js +118 -0
- package/build/services/escalation/facets.d.ts +45 -0
- package/build/services/escalation/facets.js +218 -0
- package/build/services/escalation/index.d.ts +1 -0
- package/build/services/escalation/index.js +8 -1
- package/build/services/escalation/queries.d.ts +47 -0
- package/build/services/escalation/queries.js +185 -2
- package/build/services/escalation/sql.d.ts +15 -2
- package/build/services/escalation/sql.js +80 -3
- package/build/services/interceptor/activities/escalation.d.ts +2 -0
- package/build/services/interceptor/activities/escalation.js +1 -1
- package/build/services/interceptor/lifecycle.js +4 -0
- package/build/services/mcp/server-tools.js +10 -4
- package/build/services/orchestrator/condition.js +6 -2
- package/build/services/role/index.js +2 -3
- package/build/services/role/sql.d.ts +8 -0
- package/build/services/role/sql.js +17 -1
- package/build/services/task/crud.js +22 -14
- package/build/services/task/process.js +3 -21
- package/build/services/task/resolve.d.ts +5 -3
- package/build/services/task/resolve.js +9 -6
- package/build/services/task/sql.d.ts +30 -2
- package/build/services/task/sql.js +72 -2
- package/build/services/user/crud.d.ts +1 -0
- package/build/services/user/crud.js +29 -11
- package/build/services/user/index.d.ts +2 -1
- package/build/services/user/index.js +12 -1
- package/build/services/user/rbac.d.ts +18 -0
- package/build/services/user/rbac.js +27 -0
- package/build/services/user/roles.d.ts +7 -2
- package/build/services/user/roles.js +21 -5
- package/build/services/user/scope.d.ts +22 -0
- package/build/services/user/scope.js +50 -0
- package/build/services/user/seed-admin.js +34 -17
- package/build/services/user/sql.d.ts +18 -7
- package/build/services/user/sql.js +38 -13
- package/build/services/user/sso-provision.js +41 -24
- package/build/services/user/types.d.ts +9 -5
- package/build/start/adapters.js +3 -0
- package/build/system/mcp-servers/admin/diagnostics.d.ts +5 -4
- package/build/system/mcp-servers/admin/diagnostics.js +12 -10
- package/build/system/mcp-servers/admin/escalations.d.ts +6 -0
- package/build/system/mcp-servers/admin/escalations.js +247 -54
- package/build/system/mcp-servers/admin/index.js +3 -3
- package/build/system/mcp-servers/admin/schemas.d.ts +417 -3
- package/build/system/mcp-servers/admin/schemas.js +101 -5
- package/build/system/mcp-servers/admin/users.js +28 -2
- package/build/system/mcp-servers/admin/workflows.js +23 -12
- package/build/system/seed/tool-manifests-admin.d.ts +1324 -562
- package/build/system/seed/tool-manifests-admin.js +10 -2
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/envelope.d.ts +7 -0
- package/build/types/facets.d.ts +60 -0
- package/build/types/facets.js +10 -0
- package/build/types/index.d.ts +2 -1
- package/build/types/startup.d.ts +9 -0
- package/build/types/user.d.ts +11 -0
- package/dashboard/dist/assets/AdminDashboard-2CZ8py9X.js +2 -0
- package/dashboard/dist/assets/{AdminDashboard-DZpduYdW.js.map → AdminDashboard-2CZ8py9X.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-SFnHMIP6.js → AgentConfigPage-D68sodgo.js} +7 -7
- package/dashboard/dist/assets/{AgentConfigPage-SFnHMIP6.js.map → AgentConfigPage-D68sodgo.js.map} +1 -1
- package/dashboard/dist/assets/AgentDetailPage-BmhuWbKi.js +4 -0
- package/dashboard/dist/assets/AgentDetailPage-BmhuWbKi.js.map +1 -0
- package/dashboard/dist/assets/AgentsPage-C4SKQVeU.js +2 -0
- package/dashboard/dist/assets/AgentsPage-C4SKQVeU.js.map +1 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-9RBEYwkt.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-9RBEYwkt.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-Dse2jW4b.js → BotPicker-D-FvXJOM.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-Dse2jW4b.js.map → BotPicker-D-FvXJOM.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-ByDf6WJr.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-DTfKCzBQ.js.map → CapabilitiesPage-ByDf6WJr.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-8vf38J6K.js → CollapsibleSection-BjGNYEvh.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-8vf38J6K.js.map → CollapsibleSection-BjGNYEvh.js.map} +1 -1
- package/dashboard/dist/assets/CopyableId-blg-gZvT.js +2 -0
- package/dashboard/dist/assets/CopyableId-blg-gZvT.js.map +1 -0
- package/dashboard/dist/assets/{CredentialsPage-7C4M-hrH.js → CredentialsPage-DvCA-wQN.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-7C4M-hrH.js.map → CredentialsPage-DvCA-wQN.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-DrGWtaSY.js → CronLabel-DBMurd_c.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-DrGWtaSY.js.map → CronLabel-DBMurd_c.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-Vcmr4LiR.js → CustomDurationPicker-DHflFoEa.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-Vcmr4LiR.js.map → CustomDurationPicker-DHflFoEa.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-Dwpgbueb.js → DropZone-CUtdp99Z.js} +2 -2
- package/dashboard/dist/assets/{DropZone-Dwpgbueb.js.map → DropZone-CUtdp99Z.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-BNexhR5d.js → ElapsedCell-CSjcVOpo.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-BNexhR5d.js.map → ElapsedCell-CSjcVOpo.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-BI3DEwYP.js → EscalationsOverview-BUqRNJbK.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-BI3DEwYP.js.map → EscalationsOverview-BUqRNJbK.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CwvX_L9t.js → EventTable-Chz-6XPE.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CwvX_L9t.js.map → EventTable-Chz-6XPE.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-C-3b8WK0.js → GraphInvokePage-BXdgciWg.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-C-3b8WK0.js.map → GraphInvokePage-BXdgciWg.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-BS_-jcHr.js → HomePage-CEMxnk0r.js} +2 -2
- package/dashboard/dist/assets/{HomePage-BS_-jcHr.js.map → HomePage-CEMxnk0r.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-BH9rwQVE.js → ListToolbar-_73JCdbB.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-BH9rwQVE.js.map → ListToolbar-_73JCdbB.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-C9iOdE7E.js → McpOverview-DfdqxhSz.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-C9iOdE7E.js.map → McpOverview-DfdqxhSz.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DMN-yqvJ.js → McpQueryDetailPage-DPAljieY.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DMN-yqvJ.js.map → McpQueryDetailPage-DPAljieY.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryPage-D5cSziYS.js +2 -0
- package/dashboard/dist/assets/McpQueryPage-D5cSziYS.js.map +1 -0
- package/dashboard/dist/assets/{McpRunDetailPage-Wb47sRvo.js → McpRunDetailPage-DwNb9wZg.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-Wb47sRvo.js.map → McpRunDetailPage-DwNb9wZg.js.map} +1 -1
- package/dashboard/dist/assets/McpRunsPage-O5H6yStl.js +2 -0
- package/dashboard/dist/assets/McpRunsPage-O5H6yStl.js.map +1 -0
- package/dashboard/dist/assets/{NamespacePill-DnJl4Lre.js → NamespacePill-uW-xOedj.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-DnJl4Lre.js.map → NamespacePill-uW-xOedj.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-DYw9Ekv5.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-DYw9Ekv5.js.map +1 -0
- package/dashboard/dist/assets/PageHeader-DVOZjBfL.js +2 -0
- package/dashboard/dist/assets/PageHeader-DVOZjBfL.js.map +1 -0
- package/dashboard/dist/assets/{PageHeaderWithStats-BuKc9MKt.js → PageHeaderWithStats-DtTpDHOd.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-BuKc9MKt.js.map → PageHeaderWithStats-DtTpDHOd.js.map} +1 -1
- package/dashboard/dist/assets/PriorityBadge-B4ykBH7f.js +2 -0
- package/dashboard/dist/assets/PriorityBadge-B4ykBH7f.js.map +1 -0
- package/dashboard/dist/assets/{ProcessDetailPage-CvPx-h8y.js → ProcessDetailPage-B0Dokcx9.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-CvPx-h8y.js.map → ProcessDetailPage-B0Dokcx9.js.map} +1 -1
- package/dashboard/dist/assets/ProcessesListPage-Cc87WIjL.js +2 -0
- package/dashboard/dist/assets/ProcessesListPage-Cc87WIjL.js.map +1 -0
- package/dashboard/dist/assets/RolePill-BaW-30TC.js +2 -0
- package/dashboard/dist/assets/RolePill-BaW-30TC.js.map +1 -0
- package/dashboard/dist/assets/{RolesPage-W5ZjOHpg.js → RolesPage-cp6PiF08.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-W5ZjOHpg.js.map → RolesPage-cp6PiF08.js.map} +1 -1
- package/dashboard/dist/assets/RowActions-BA9L9djf.js +2 -0
- package/dashboard/dist/assets/RowActions-BA9L9djf.js.map +1 -0
- package/dashboard/dist/assets/{RunAsSelector-CvxGTNGT.js → RunAsSelector-2LWkjSnO.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-CvxGTNGT.js.map → RunAsSelector-2LWkjSnO.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-BWhFSr2d.js → StickyPagination-BQEm--kI.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-BWhFSr2d.js.map → StickyPagination-BQEm--kI.js.map} +1 -1
- package/dashboard/dist/assets/StreamMessageDetail-BTtw3GjX.js +2 -0
- package/dashboard/dist/assets/{StreamMessageDetail-BF0tM0cd.js.map → StreamMessageDetail-BTtw3GjX.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-Bv-KHY9s.js → SwimlaneTimeline-DdXxP4fO.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-Bv-KHY9s.js.map → SwimlaneTimeline-DdXxP4fO.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-B00uqhjX.js → TagInput-x9XTuqMb.js} +2 -2
- package/dashboard/dist/assets/{TagInput-B00uqhjX.js.map → TagInput-x9XTuqMb.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-Bzb_fuLy.js → TaskDetailPage-B8veYG4X.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-Bzb_fuLy.js.map → TaskDetailPage-B8veYG4X.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-CUsofm0X.js → TaskQueuePill-DSEQZ-HT.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-CUsofm0X.js.map → TaskQueuePill-DSEQZ-HT.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-CBezWaZL.js → TasksListPage-CsN1gZj5.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-CBezWaZL.js.map → TasksListPage-CsN1gZj5.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-CKHfTzat.js → TimeAgo-n182EcLx.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-CKHfTzat.js.map → TimeAgo-n182EcLx.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-Dsje8GH-.js → TimestampCell-2dlcQAfX.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-Dsje8GH-.js.map → TimestampCell-2dlcQAfX.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-DjvedZSn.js → ToolPill-B_e4eT77.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-DjvedZSn.js.map → ToolPill-B_e4eT77.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-3OcG18e5.js → ToolTestPanel-Bhnncc6M.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-3OcG18e5.js.map → ToolTestPanel-Bhnncc6M.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-DCtv91hH.js → TopicDetailPage-29lsNsqI.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-DCtv91hH.js.map → TopicDetailPage-29lsNsqI.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-DVGSNc_E.js → TopicsPage-KJ7_LAvo.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-DVGSNc_E.js.map → TopicsPage-KJ7_LAvo.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-xHAgkk8M.js → UserName-CMoFi9zb.js} +2 -2
- package/dashboard/dist/assets/{UserName-xHAgkk8M.js.map → UserName-CMoFi9zb.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-CWNxsS8a.js → WorkflowExecutionPage-Cymfx-Bp.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-CWNxsS8a.js.map → WorkflowExecutionPage-Cymfx-Bp.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-F1oKUzmc.js → WorkflowPill-B66_AnaY.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-F1oKUzmc.js.map → WorkflowPill-B66_AnaY.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-CqLN8spd.js +2 -0
- package/dashboard/dist/assets/WorkflowsDashboard-CqLN8spd.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowsOverview-e7jWSj_n.js → WorkflowsOverview-0Rc2WT6q.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-e7jWSj_n.js.map → WorkflowsOverview-0Rc2WT6q.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CdAeam76.js → YamlWorkflowDetailPage-CARQ7_LN.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CdAeam76.js.map → YamlWorkflowDetailPage-CARQ7_LN.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-S_gKs2Di.js → YamlWorkflowsPage-B-7sz1nf.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-S_gKs2Di.js.map → YamlWorkflowsPage-B-7sz1nf.js.map} +1 -1
- package/dashboard/dist/assets/{agents-JE4aL07D.js → agents-zM43d5Yf.js} +2 -2
- package/dashboard/dist/assets/{agents-JE4aL07D.js.map → agents-zM43d5Yf.js.map} +1 -1
- package/dashboard/dist/assets/api-path-u2Jf9QXS.js +2 -0
- package/dashboard/dist/assets/api-path-u2Jf9QXS.js.map +1 -0
- package/dashboard/dist/assets/{bots-cAzKkDtQ.js → bots-D5BasOGz.js} +2 -2
- package/dashboard/dist/assets/{bots-cAzKkDtQ.js.map → bots-D5BasOGz.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-RBFXLAXF.js → capabilities-BT3PW9CZ.js} +2 -2
- package/dashboard/dist/assets/{capabilities-RBFXLAXF.js.map → capabilities-BT3PW9CZ.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-DGhv3rwI.js → controlplane-NpJr49rN.js} +2 -2
- package/dashboard/dist/assets/{controlplane-DGhv3rwI.js.map → controlplane-NpJr49rN.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-ne7dIaPa.js → escalation-DrzQolPG.js} +2 -2
- package/dashboard/dist/assets/{escalation-ne7dIaPa.js.map → escalation-DrzQolPG.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-QzwmtD60.js +2 -0
- package/dashboard/dist/assets/escalation-columns-QzwmtD60.js.map +1 -0
- package/dashboard/dist/assets/index-B5w4Gjyk.js +6 -0
- package/dashboard/dist/assets/index-B5w4Gjyk.js.map +1 -0
- package/dashboard/dist/assets/{index-CByjpYlU.js → index-BCT4kqGR.js} +2 -2
- package/dashboard/dist/assets/{index-CByjpYlU.js.map → index-BCT4kqGR.js.map} +1 -1
- package/dashboard/dist/assets/{index-CgyucK0e.js → index-C69XvBfg.js} +2 -2
- package/dashboard/dist/assets/{index-CgyucK0e.js.map → index-C69XvBfg.js.map} +1 -1
- package/dashboard/dist/assets/index-CHw4Fl0t.css +1 -0
- package/dashboard/dist/assets/index-C_NwHTMh.js +2 -0
- package/dashboard/dist/assets/index-C_NwHTMh.js.map +1 -0
- package/dashboard/dist/assets/{index-DgzgRTNg.js → index-Cq0trGqf.js} +2 -2
- package/dashboard/dist/assets/{index-DgzgRTNg.js.map → index-Cq0trGqf.js.map} +1 -1
- package/dashboard/dist/assets/{index-DPJW96d2.js → index-DE0r9SEX.js} +26 -26
- package/dashboard/dist/assets/index-DE0r9SEX.js.map +1 -0
- package/dashboard/dist/assets/{index-BTqhAT6p.js → index-DH_CiD0W.js} +2 -2
- package/dashboard/dist/assets/{index-BTqhAT6p.js.map → index-DH_CiD0W.js.map} +1 -1
- package/dashboard/dist/assets/{index-C2l4GcZ7.js → index-K23FdS-T.js} +3 -3
- package/dashboard/dist/assets/{index-C2l4GcZ7.js.map → index-K23FdS-T.js.map} +1 -1
- package/dashboard/dist/assets/index-f6K1UNrn.js +2 -0
- package/dashboard/dist/assets/index-f6K1UNrn.js.map +1 -0
- package/dashboard/dist/assets/{index-BbJuC9kg.js → index-qr1fndqM.js} +2 -2
- package/dashboard/dist/assets/{index-BbJuC9kg.js.map → index-qr1fndqM.js.map} +1 -1
- package/dashboard/dist/assets/index-vKTvJ_li.js +2 -0
- package/dashboard/dist/assets/index-vKTvJ_li.js.map +1 -0
- package/dashboard/dist/assets/{index-CQDn-bLr.js → index-y-3ODtEE.js} +2 -2
- package/dashboard/dist/assets/{index-CQDn-bLr.js.map → index-y-3ODtEE.js.map} +1 -1
- package/dashboard/dist/assets/{index-QxAYCJ1S.js → index-y56Ds-LB.js} +2 -2
- package/dashboard/dist/assets/{index-QxAYCJ1S.js.map → index-y56Ds-LB.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-DzRpsm3D.js → knowledge-DSSATOTX.js} +2 -2
- package/dashboard/dist/assets/{knowledge-DzRpsm3D.js.map → knowledge-DSSATOTX.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-B1lc6nL4.js → mcp-CfJFVo5k.js} +2 -2
- package/dashboard/dist/assets/{mcp-B1lc6nL4.js.map → mcp-CfJFVo5k.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-CXuweaN3.js → mcp-query-DKVx2Q-X.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-CXuweaN3.js.map → mcp-query-DKVx2Q-X.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-D4VLWDvu.js → pipelines-BSWzE-6M.js} +2 -2
- package/dashboard/dist/assets/{pipelines-D4VLWDvu.js.map → pipelines-BSWzE-6M.js.map} +1 -1
- package/dashboard/dist/assets/{roles-CSpHRRu8.js → roles-t9HzhI5N.js} +2 -2
- package/dashboard/dist/assets/{roles-CSpHRRu8.js.map → roles-t9HzhI5N.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-CWUsKhM4.js → tasks-B7rUihoH.js} +2 -2
- package/dashboard/dist/assets/{tasks-CWUsKhM4.js.map → tasks-B7rUihoH.js.map} +1 -1
- package/dashboard/dist/assets/{topics-BXwstrzB.js → topics-PC2fEiyD.js} +2 -2
- package/dashboard/dist/assets/{topics-BXwstrzB.js.map → topics-PC2fEiyD.js.map} +1 -1
- package/dashboard/dist/assets/useDebouncedValue-BA5S7V54.js +2 -0
- package/dashboard/dist/assets/useDebouncedValue-BA5S7V54.js.map +1 -0
- package/dashboard/dist/assets/{useEventHooks-CjygrbYy.js → useEventHooks-DK9mw1cI.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-CjygrbYy.js.map → useEventHooks-DK9mw1cI.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-CsepDyR5.js → useNamespace-3IjtUtAw.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-CsepDyR5.js.map → useNamespace-3IjtUtAw.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-gWIG6akB.js → useYamlActivityEvents-uxukp3gO.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-gWIG6akB.js.map → useYamlActivityEvents-uxukp3gO.js.map} +1 -1
- package/dashboard/dist/assets/users-CC4B5Fm5.js +2 -0
- package/dashboard/dist/assets/users-CC4B5Fm5.js.map +1 -0
- package/dashboard/dist/assets/{vendor-icons-Dj2F0Jrb.js → vendor-icons-Dy5Jpknf.js} +114 -109
- package/dashboard/dist/assets/vendor-icons-Dy5Jpknf.js.map +1 -0
- package/dashboard/dist/assets/{workflows-C7Cam2Ok.js → workflows-S7MF1nNk.js} +2 -2
- package/dashboard/dist/assets/{workflows-C7Cam2Ok.js.map → workflows-S7MF1nNk.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-ChUOE22W.js → yaml-workflows-WfdaMHNn.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-ChUOE22W.js.map → yaml-workflows-WfdaMHNn.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/api/http/escalations.md +131 -10
- package/docs/api/http/roles.md +44 -9
- package/docs/api/http/users.md +15 -6
- package/docs/api/mcp/admin.md +164 -14
- package/docs/api/mcp/human-queue.md +34 -2
- package/docs/api/sdk/escalations.md +155 -2
- package/docs/api/sdk/roles.md +11 -0
- package/docs/api/sdk/users.md +26 -1
- package/docs/auth.md +1 -1
- package/docs/dashboard.md +5 -4
- package/docs/data.md +9 -2
- package/docs/faceted-routing.md +221 -0
- package/docs/hitl-guide.md +50 -0
- package/docs/iam.md +31 -0
- package/docs/mcp.md +8 -0
- package/package.json +2 -2
- package/dashboard/dist/assets/AdminDashboard-DZpduYdW.js +0 -2
- package/dashboard/dist/assets/AgentDetailPage-C-2iSaDs.js +0 -4
- package/dashboard/dist/assets/AgentDetailPage-C-2iSaDs.js.map +0 -1
- package/dashboard/dist/assets/AgentsPage-C3FztFd_.js +0 -2
- package/dashboard/dist/assets/AgentsPage-C3FztFd_.js.map +0 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-DIqdBCwe.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-DIqdBCwe.js.map +0 -1
- package/dashboard/dist/assets/CapabilitiesPage-DTfKCzBQ.js +0 -2
- package/dashboard/dist/assets/CopyableId-DaT0ZRHg.js +0 -2
- package/dashboard/dist/assets/CopyableId-DaT0ZRHg.js.map +0 -1
- package/dashboard/dist/assets/McpQueryPage-Db1LUKVs.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-Db1LUKVs.js.map +0 -1
- package/dashboard/dist/assets/McpRunsPage--tgT5uo7.js +0 -2
- package/dashboard/dist/assets/McpRunsPage--tgT5uo7.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-BWVUbJkZ.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-BWVUbJkZ.js.map +0 -1
- package/dashboard/dist/assets/PageHeader-Bnt2iQQa.js +0 -2
- package/dashboard/dist/assets/PageHeader-Bnt2iQQa.js.map +0 -1
- package/dashboard/dist/assets/PriorityBadge-DfQY9St9.js +0 -2
- package/dashboard/dist/assets/PriorityBadge-DfQY9St9.js.map +0 -1
- package/dashboard/dist/assets/ProcessesListPage-CWiRM_h3.js +0 -2
- package/dashboard/dist/assets/ProcessesListPage-CWiRM_h3.js.map +0 -1
- package/dashboard/dist/assets/RolePill-DQTT1s9v.js +0 -2
- package/dashboard/dist/assets/RolePill-DQTT1s9v.js.map +0 -1
- package/dashboard/dist/assets/RowActions-Dg-Fsm5O.js +0 -2
- package/dashboard/dist/assets/RowActions-Dg-Fsm5O.js.map +0 -1
- package/dashboard/dist/assets/StreamMessageDetail-BF0tM0cd.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-M13lIaw7.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-M13lIaw7.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-DqTkKbCv.js +0 -2
- package/dashboard/dist/assets/escalation-columns-DqTkKbCv.js.map +0 -1
- package/dashboard/dist/assets/index-CEpw_Fh8.js +0 -2
- package/dashboard/dist/assets/index-CEpw_Fh8.js.map +0 -1
- package/dashboard/dist/assets/index-ClvYSNZd.css +0 -1
- package/dashboard/dist/assets/index-CucXk58o.js +0 -6
- package/dashboard/dist/assets/index-CucXk58o.js.map +0 -1
- package/dashboard/dist/assets/index-DPJW96d2.js.map +0 -1
- package/dashboard/dist/assets/index-DeZhNCf5.js +0 -2
- package/dashboard/dist/assets/index-DeZhNCf5.js.map +0 -1
- package/dashboard/dist/assets/index-Do8Xp3pa.js +0 -2
- package/dashboard/dist/assets/index-Do8Xp3pa.js.map +0 -1
- package/dashboard/dist/assets/users-DvhHbR0R.js +0 -2
- package/dashboard/dist/assets/users-DvhHbR0R.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-Dj2F0Jrb.js.map +0 -1
package/build/api/users.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { LTRoleType } from '../types';
|
|
|
6
6
|
* @param input.role — filter by role name
|
|
7
7
|
* @param input.roleType — filter by role type (superadmin, admin, member)
|
|
8
8
|
* @param input.status — filter by user status
|
|
9
|
+
* @param input.search — free-text match on display name, email, or external_id
|
|
9
10
|
* @param input.limit — maximum number of users to return
|
|
10
11
|
* @param input.offset — number of users to skip for pagination
|
|
11
12
|
* @returns `{ status: 200, data: User[] }` on success
|
|
@@ -14,6 +15,7 @@ export declare function listUsers(input: {
|
|
|
14
15
|
role?: string;
|
|
15
16
|
roleType?: LTRoleType;
|
|
16
17
|
status?: string;
|
|
18
|
+
search?: string;
|
|
17
19
|
limit?: number;
|
|
18
20
|
offset?: number;
|
|
19
21
|
}): Promise<LTApiResult>;
|
|
@@ -47,6 +49,8 @@ export declare function createUser(input: {
|
|
|
47
49
|
roles?: {
|
|
48
50
|
role: string;
|
|
49
51
|
type: string;
|
|
52
|
+
read_scope?: string;
|
|
53
|
+
write_scope?: string;
|
|
50
54
|
}[];
|
|
51
55
|
metadata?: Record<string, any>;
|
|
52
56
|
}): Promise<LTApiResult>;
|
|
@@ -103,6 +107,8 @@ export declare function addUserRole(input: {
|
|
|
103
107
|
id: string;
|
|
104
108
|
role: string;
|
|
105
109
|
type: string;
|
|
110
|
+
read_scope?: string;
|
|
111
|
+
write_scope?: string;
|
|
106
112
|
}): Promise<LTApiResult>;
|
|
107
113
|
/**
|
|
108
114
|
* Remove a role from a user. Requires admin privileges.
|
package/build/api/users.js
CHANGED
|
@@ -48,6 +48,7 @@ const userService = __importStar(require("../services/user"));
|
|
|
48
48
|
* @param input.role — filter by role name
|
|
49
49
|
* @param input.roleType — filter by role type (superadmin, admin, member)
|
|
50
50
|
* @param input.status — filter by user status
|
|
51
|
+
* @param input.search — free-text match on display name, email, or external_id
|
|
51
52
|
* @param input.limit — maximum number of users to return
|
|
52
53
|
* @param input.offset — number of users to skip for pagination
|
|
53
54
|
* @returns `{ status: 200, data: User[] }` on success
|
|
@@ -105,6 +106,17 @@ async function createUser(input) {
|
|
|
105
106
|
error: 'Each role must have a role name and type (superadmin, admin, member)',
|
|
106
107
|
};
|
|
107
108
|
}
|
|
109
|
+
if (r.read_scope !== undefined && !userService.isValidReadScope(r.read_scope)) {
|
|
110
|
+
return { status: 400, error: 'read_scope must be self or all' };
|
|
111
|
+
}
|
|
112
|
+
if (r.write_scope !== undefined && !userService.isValidWriteScope(r.write_scope)) {
|
|
113
|
+
return { status: 400, error: 'write_scope must be none, self, or all' };
|
|
114
|
+
}
|
|
115
|
+
const read = (r.read_scope ?? userService.DEFAULT_READ_SCOPE);
|
|
116
|
+
const write = (r.write_scope ?? userService.DEFAULT_WRITE_SCOPE);
|
|
117
|
+
if (!userService.isValidScopePair(read, write)) {
|
|
118
|
+
return { status: 400, error: 'write_scope=all requires read_scope=all' };
|
|
119
|
+
}
|
|
108
120
|
}
|
|
109
121
|
}
|
|
110
122
|
const user = await userService.createUser({
|
|
@@ -201,7 +213,23 @@ async function addUserRole(input) {
|
|
|
201
213
|
if (!userService.isValidRoleType(input.type)) {
|
|
202
214
|
return { status: 400, error: 'type must be superadmin, admin, or member' };
|
|
203
215
|
}
|
|
204
|
-
|
|
216
|
+
// Work-surface scope (optional; defaults to all/all = full worker). Only
|
|
217
|
+
// meaningful for `member`; admin/superadmin normalize to all/all.
|
|
218
|
+
if (input.read_scope !== undefined && !userService.isValidReadScope(input.read_scope)) {
|
|
219
|
+
return { status: 400, error: 'read_scope must be self or all' };
|
|
220
|
+
}
|
|
221
|
+
if (input.write_scope !== undefined && !userService.isValidWriteScope(input.write_scope)) {
|
|
222
|
+
return { status: 400, error: 'write_scope must be none, self, or all' };
|
|
223
|
+
}
|
|
224
|
+
const read = (input.read_scope ?? userService.DEFAULT_READ_SCOPE);
|
|
225
|
+
const write = (input.write_scope ?? userService.DEFAULT_WRITE_SCOPE);
|
|
226
|
+
if (!userService.isValidScopePair(read, write)) {
|
|
227
|
+
return { status: 400, error: 'write_scope=all requires read_scope=all (cannot act on what you cannot see)' };
|
|
228
|
+
}
|
|
229
|
+
const result = await userService.addUserRole(input.id, input.role, input.type, {
|
|
230
|
+
read_scope: read,
|
|
231
|
+
write_scope: write,
|
|
232
|
+
});
|
|
205
233
|
return { status: 201, data: result };
|
|
206
234
|
}
|
|
207
235
|
catch (err) {
|
|
@@ -23,12 +23,16 @@ export declare function invokeWorkflow(input: {
|
|
|
23
23
|
*
|
|
24
24
|
* Returns the HotMesh status code (0 = completed, 1 = running).
|
|
25
25
|
* Resolves the workflow handle via task record or worker registry.
|
|
26
|
+
* `appId` selects the namespace for the job-entity fallback so a child
|
|
27
|
+
* running in another app resolves instead of 404ing against `durable`.
|
|
26
28
|
*
|
|
27
29
|
* @param input.workflowId — HotMesh workflow ID
|
|
30
|
+
* @param input.appId — HotMesh namespace for resolution (default: durable)
|
|
28
31
|
* @returns `{ status: 200, data: { workflowId, status } }` or 404
|
|
29
32
|
*/
|
|
30
33
|
export declare function getWorkflowStatus(input: {
|
|
31
34
|
workflowId: string;
|
|
35
|
+
appId?: string;
|
|
32
36
|
}): Promise<LTApiResult>;
|
|
33
37
|
/**
|
|
34
38
|
* Get the result of a completed workflow.
|
|
@@ -37,10 +41,12 @@ export declare function getWorkflowStatus(input: {
|
|
|
37
41
|
* payload when complete. Never blocks — always returns immediately.
|
|
38
42
|
*
|
|
39
43
|
* @param input.workflowId — HotMesh workflow ID
|
|
44
|
+
* @param input.appId — HotMesh namespace for resolution (default: durable)
|
|
40
45
|
* @returns `{ status: 200, data: { workflowId, result } }` or 202 if running
|
|
41
46
|
*/
|
|
42
47
|
export declare function getWorkflowResult(input: {
|
|
43
48
|
workflowId: string;
|
|
49
|
+
appId?: string;
|
|
44
50
|
}): Promise<LTApiResult>;
|
|
45
51
|
/**
|
|
46
52
|
* Terminate a running workflow.
|
|
@@ -87,13 +87,16 @@ async function invokeWorkflow(input, auth) {
|
|
|
87
87
|
*
|
|
88
88
|
* Returns the HotMesh status code (0 = completed, 1 = running).
|
|
89
89
|
* Resolves the workflow handle via task record or worker registry.
|
|
90
|
+
* `appId` selects the namespace for the job-entity fallback so a child
|
|
91
|
+
* running in another app resolves instead of 404ing against `durable`.
|
|
90
92
|
*
|
|
91
93
|
* @param input.workflowId — HotMesh workflow ID
|
|
94
|
+
* @param input.appId — HotMesh namespace for resolution (default: durable)
|
|
92
95
|
* @returns `{ status: 200, data: { workflowId, status } }` or 404
|
|
93
96
|
*/
|
|
94
97
|
async function getWorkflowStatus(input) {
|
|
95
98
|
try {
|
|
96
|
-
const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId);
|
|
99
|
+
const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId, input.appId);
|
|
97
100
|
const client = (0, workers_1.createClient)();
|
|
98
101
|
const handle = await client.workflow.getHandle(resolved.taskQueue, resolved.workflowName, input.workflowId);
|
|
99
102
|
const status = await handle.status();
|
|
@@ -115,11 +118,12 @@ async function getWorkflowStatus(input) {
|
|
|
115
118
|
* payload when complete. Never blocks — always returns immediately.
|
|
116
119
|
*
|
|
117
120
|
* @param input.workflowId — HotMesh workflow ID
|
|
121
|
+
* @param input.appId — HotMesh namespace for resolution (default: durable)
|
|
118
122
|
* @returns `{ status: 200, data: { workflowId, result } }` or 202 if running
|
|
119
123
|
*/
|
|
120
124
|
async function getWorkflowResult(input) {
|
|
121
125
|
try {
|
|
122
|
-
const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId);
|
|
126
|
+
const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId, input.appId);
|
|
123
127
|
const client = (0, workers_1.createClient)();
|
|
124
128
|
const handle = await client.workflow.getHandle(resolved.taskQueue, resolved.workflowName, input.workflowId);
|
|
125
129
|
const status = await handle.status();
|
package/build/bin/ltc.js
CHANGED
|
@@ -120,6 +120,13 @@ escCmd.command('list')
|
|
|
120
120
|
.option('--status <status>', 'Filter by status (pending, resolved, cancelled)')
|
|
121
121
|
.option('--role <role>', 'Filter by role')
|
|
122
122
|
.option('--limit <n>', 'Max results')
|
|
123
|
+
.option('--facets <json>', 'Required metadata facets, JSON object (metadata @>), e.g. \'{"filament":"pla"}\'')
|
|
124
|
+
.option('--block <json>', 'Exclude rows containing ANY of these facet sets, JSON array')
|
|
125
|
+
.option('--range <json>', 'Numeric ranges over facets, JSON array e.g. \'[{"facet":"confidence","op":"<=","value":0.7}]\'')
|
|
126
|
+
.option('--exists <json>', 'Metadata keys that must be present, JSON array of strings')
|
|
127
|
+
.option('--roles <json>', 'Restrict to these roles, JSON array (narrows within scope)')
|
|
128
|
+
.option('--available <bool>', 'true = unclaimed/expired only; false = held now')
|
|
129
|
+
.option('--order-by <json>', 'Sort keys, JSON array e.g. \'[{"field":"metadata.confidence","numeric":true,"direction":"asc"}]\'')
|
|
123
130
|
.option('--json', 'JSON output')
|
|
124
131
|
.option('-q, --quiet', 'IDs only')
|
|
125
132
|
.action(wrap(esc.listEscalations));
|
|
@@ -153,6 +160,39 @@ escCmd.command('resolve-by-meta <key> <value>')
|
|
|
153
160
|
.option('--assignee <external_id>', 'Resolve on behalf of user (external_id)')
|
|
154
161
|
.option('--meta <json>', 'Merge metadata (JSON object)')
|
|
155
162
|
.action(wrap(esc.resolveByMetadata));
|
|
163
|
+
escCmd.command('resolve-by-ids <ids...>')
|
|
164
|
+
.description('Resolve a set of escalations by id')
|
|
165
|
+
.requiredOption('--payload <json>', 'Resolver payload (JSON string)')
|
|
166
|
+
.option('--metadata <json>', 'Merge metadata (JSON object)')
|
|
167
|
+
.action(wrap(esc.resolveByIds));
|
|
168
|
+
escCmd.command('search-facets')
|
|
169
|
+
.description('Item-level faceted search over a pond (role-scoped)')
|
|
170
|
+
.requiredOption('--role <role>', 'Pond role to search')
|
|
171
|
+
.option('--status <status>', 'Filter by status')
|
|
172
|
+
.option('--available', 'Only available (unclaimed/expired)')
|
|
173
|
+
.option('--facets <json>', 'Required facets (JSON object)')
|
|
174
|
+
.option('--limit <n>', 'Max results')
|
|
175
|
+
.option('--json', 'JSON output')
|
|
176
|
+
.option('-q, --quiet', 'IDs only')
|
|
177
|
+
.action(wrap(esc.searchByFacets));
|
|
178
|
+
escCmd.command('claim-groups')
|
|
179
|
+
.description('Batch-claim complete origin groups in priority order')
|
|
180
|
+
.requiredOption('--role <role>', 'Pond role to claim from')
|
|
181
|
+
.option('--facets <json>', 'Required facets (JSON object)')
|
|
182
|
+
.option('--limit <n>', 'Max groups to claim')
|
|
183
|
+
.option('--duration <minutes>', 'Claim duration in minutes')
|
|
184
|
+
.option('--size-facet <key>', 'Metadata facet declaring group size')
|
|
185
|
+
.option('--json', 'JSON output')
|
|
186
|
+
.action(wrap(esc.claimGroups));
|
|
187
|
+
escCmd.command('claim-by-facets')
|
|
188
|
+
.description('Batch-claim individual rows matching facets')
|
|
189
|
+
.requiredOption('--role <role>', 'Pond role to claim from')
|
|
190
|
+
.option('--facets <json>', 'Required facets (JSON object)')
|
|
191
|
+
.option('--limit <n>', 'Max rows to claim')
|
|
192
|
+
.option('--duration <minutes>', 'Claim duration in minutes')
|
|
193
|
+
.option('--all-or-none', 'Claim all matched rows or none')
|
|
194
|
+
.option('--json', 'JSON output')
|
|
195
|
+
.action(wrap(esc.claimByFacets));
|
|
156
196
|
// ── Workflows ────────────────────────────────────────────────────────────
|
|
157
197
|
const wfCmd = commander_1.program.command('workflows').alias('wf').description('Manage durable workflows');
|
|
158
198
|
wfCmd.command('list')
|
|
@@ -4,6 +4,13 @@ interface ListOptions {
|
|
|
4
4
|
limit?: string;
|
|
5
5
|
json?: boolean;
|
|
6
6
|
quiet?: boolean;
|
|
7
|
+
facets?: string;
|
|
8
|
+
block?: string;
|
|
9
|
+
range?: string;
|
|
10
|
+
exists?: string;
|
|
11
|
+
roles?: string;
|
|
12
|
+
available?: string;
|
|
13
|
+
orderBy?: string;
|
|
7
14
|
}
|
|
8
15
|
export declare function listEscalations(opts: ListOptions): Promise<void>;
|
|
9
16
|
export declare function getEscalation(id: string, opts: {
|
|
@@ -27,4 +34,33 @@ export declare function resolveByMetadata(key: string, value: string, opts: {
|
|
|
27
34
|
assignee?: string;
|
|
28
35
|
meta?: string;
|
|
29
36
|
}): Promise<void>;
|
|
37
|
+
export declare function resolveByIds(ids: string[], opts: {
|
|
38
|
+
payload: string;
|
|
39
|
+
metadata?: string;
|
|
40
|
+
}): Promise<void>;
|
|
41
|
+
export declare function searchByFacets(opts: {
|
|
42
|
+
role: string;
|
|
43
|
+
status?: string;
|
|
44
|
+
available?: boolean;
|
|
45
|
+
facets?: string;
|
|
46
|
+
limit?: string;
|
|
47
|
+
json?: boolean;
|
|
48
|
+
quiet?: boolean;
|
|
49
|
+
}): Promise<void>;
|
|
50
|
+
export declare function claimGroups(opts: {
|
|
51
|
+
role: string;
|
|
52
|
+
facets?: string;
|
|
53
|
+
limit?: string;
|
|
54
|
+
duration?: string;
|
|
55
|
+
sizeFacet?: string;
|
|
56
|
+
json?: boolean;
|
|
57
|
+
}): Promise<void>;
|
|
58
|
+
export declare function claimByFacets(opts: {
|
|
59
|
+
role: string;
|
|
60
|
+
facets?: string;
|
|
61
|
+
limit?: string;
|
|
62
|
+
duration?: string;
|
|
63
|
+
allOrNone?: boolean;
|
|
64
|
+
json?: boolean;
|
|
65
|
+
}): Promise<void>;
|
|
30
66
|
export {};
|
|
@@ -11,6 +11,10 @@ exports.resolveEscalation = resolveEscalation;
|
|
|
11
11
|
exports.findByMetadata = findByMetadata;
|
|
12
12
|
exports.claimByMetadata = claimByMetadata;
|
|
13
13
|
exports.resolveByMetadata = resolveByMetadata;
|
|
14
|
+
exports.resolveByIds = resolveByIds;
|
|
15
|
+
exports.searchByFacets = searchByFacets;
|
|
16
|
+
exports.claimGroups = claimGroups;
|
|
17
|
+
exports.claimByFacets = claimByFacets;
|
|
14
18
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
15
19
|
const client_1 = require("../client");
|
|
16
20
|
const format_1 = require("../format");
|
|
@@ -30,6 +34,22 @@ async function listEscalations(opts) {
|
|
|
30
34
|
params.set('role', opts.role);
|
|
31
35
|
if (opts.limit)
|
|
32
36
|
params.set('limit', opts.limit);
|
|
37
|
+
// Faceted query elements travel as JSON-encoded query params (the route JSON-parses
|
|
38
|
+
// them). parseJsonOption validates the input and throws a friendly error on bad JSON.
|
|
39
|
+
if (opts.facets)
|
|
40
|
+
params.set('facets', JSON.stringify(parseJsonOption('--facets', opts.facets)));
|
|
41
|
+
if (opts.block)
|
|
42
|
+
params.set('block', JSON.stringify(parseJsonOption('--block', opts.block)));
|
|
43
|
+
if (opts.range)
|
|
44
|
+
params.set('range', JSON.stringify(parseJsonOption('--range', opts.range)));
|
|
45
|
+
if (opts.exists)
|
|
46
|
+
params.set('exists', JSON.stringify(parseJsonOption('--exists', opts.exists)));
|
|
47
|
+
if (opts.roles)
|
|
48
|
+
params.set('roles', JSON.stringify(parseJsonOption('--roles', opts.roles)));
|
|
49
|
+
if (opts.orderBy)
|
|
50
|
+
params.set('orderBy', JSON.stringify(parseJsonOption('--order-by', opts.orderBy)));
|
|
51
|
+
if (opts.available != null)
|
|
52
|
+
params.set('available', opts.available);
|
|
33
53
|
const data = await (0, client_1.apiFetch)(`/escalations?${params}`);
|
|
34
54
|
(0, format_1.output)(data, data.escalations || [], COLUMNS, opts);
|
|
35
55
|
}
|
|
@@ -107,3 +127,81 @@ async function resolveByMetadata(key, value, opts) {
|
|
|
107
127
|
});
|
|
108
128
|
console.log(`\n ${picocolors_1.default.green('✓')} Resolved by ${key}=${value}\n`);
|
|
109
129
|
}
|
|
130
|
+
// --- Faceted routing commands -----------------------------------------------
|
|
131
|
+
function parseJsonOption(label, raw) {
|
|
132
|
+
try {
|
|
133
|
+
return JSON.parse(raw);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
throw new Error(`Invalid JSON for ${label}: ${raw}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async function resolveByIds(ids, opts) {
|
|
140
|
+
const resolverPayload = parseJsonOption('--payload', opts.payload);
|
|
141
|
+
const body = { ids, resolverPayload };
|
|
142
|
+
if (opts.metadata)
|
|
143
|
+
body.metadata = parseJsonOption('--metadata', opts.metadata);
|
|
144
|
+
const data = await (0, client_1.apiFetch)('/escalations/resolve-by-ids', {
|
|
145
|
+
method: 'POST',
|
|
146
|
+
body: JSON.stringify(body),
|
|
147
|
+
});
|
|
148
|
+
console.log(`\n ${picocolors_1.default.green('✓')} Resolved ${data.resolved} escalation(s)\n`);
|
|
149
|
+
}
|
|
150
|
+
async function searchByFacets(opts) {
|
|
151
|
+
const query = { role: opts.role };
|
|
152
|
+
if (opts.status)
|
|
153
|
+
query.status = opts.status;
|
|
154
|
+
if (opts.available)
|
|
155
|
+
query.available = true;
|
|
156
|
+
if (opts.facets)
|
|
157
|
+
query.facets = parseJsonOption('--facets', opts.facets);
|
|
158
|
+
if (opts.limit)
|
|
159
|
+
query.limit = parseInt(opts.limit, 10);
|
|
160
|
+
const data = await (0, client_1.apiFetch)('/escalations/search-by-facets', {
|
|
161
|
+
method: 'POST',
|
|
162
|
+
body: JSON.stringify(query),
|
|
163
|
+
});
|
|
164
|
+
(0, format_1.output)(data, data.escalations || [], COLUMNS, opts);
|
|
165
|
+
}
|
|
166
|
+
async function claimGroups(opts) {
|
|
167
|
+
const query = { role: opts.role };
|
|
168
|
+
if (opts.facets)
|
|
169
|
+
query.facets = parseJsonOption('--facets', opts.facets);
|
|
170
|
+
const body = { query };
|
|
171
|
+
if (opts.limit)
|
|
172
|
+
body.limit = parseInt(opts.limit, 10);
|
|
173
|
+
if (opts.duration)
|
|
174
|
+
body.durationMinutes = parseInt(opts.duration, 10);
|
|
175
|
+
if (opts.sizeFacet)
|
|
176
|
+
body.sizeFacet = opts.sizeFacet;
|
|
177
|
+
const data = await (0, client_1.apiFetch)('/escalations/claim-groups', {
|
|
178
|
+
method: 'POST',
|
|
179
|
+
body: JSON.stringify(body),
|
|
180
|
+
});
|
|
181
|
+
if (opts.json) {
|
|
182
|
+
console.log(JSON.stringify(data, null, 2));
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
console.log(`\n ${picocolors_1.default.green('✓')} Claimed ${data.groups?.length || 0} group(s)\n`);
|
|
186
|
+
}
|
|
187
|
+
async function claimByFacets(opts) {
|
|
188
|
+
const query = { role: opts.role };
|
|
189
|
+
if (opts.facets)
|
|
190
|
+
query.facets = parseJsonOption('--facets', opts.facets);
|
|
191
|
+
const body = { query };
|
|
192
|
+
if (opts.limit)
|
|
193
|
+
body.limit = parseInt(opts.limit, 10);
|
|
194
|
+
if (opts.duration)
|
|
195
|
+
body.durationMinutes = parseInt(opts.duration, 10);
|
|
196
|
+
if (opts.allOrNone)
|
|
197
|
+
body.allOrNone = true;
|
|
198
|
+
const data = await (0, client_1.apiFetch)('/escalations/claim-by-facets', {
|
|
199
|
+
method: 'POST',
|
|
200
|
+
body: JSON.stringify(body),
|
|
201
|
+
});
|
|
202
|
+
if (opts.json) {
|
|
203
|
+
console.log(JSON.stringify(data, null, 2));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
console.log(`\n ${picocolors_1.default.green('✓')} Claimed ${data.claimed?.length || 0} escalation(s)\n`);
|
|
207
|
+
}
|
|
@@ -99,11 +99,16 @@ CREATE OR REPLACE TRIGGER lt_users_updated_at
|
|
|
99
99
|
-- ─── lt_user_roles ───────────────────────────────────────────────────────────
|
|
100
100
|
|
|
101
101
|
CREATE TABLE IF NOT EXISTS lt_user_roles (
|
|
102
|
-
user_id
|
|
103
|
-
role
|
|
104
|
-
type
|
|
105
|
-
|
|
106
|
-
|
|
102
|
+
user_id UUID NOT NULL REFERENCES lt_users(id) ON DELETE CASCADE,
|
|
103
|
+
role TEXT NOT NULL REFERENCES lt_roles(role),
|
|
104
|
+
type TEXT NOT NULL DEFAULT 'member' CHECK (type IN ('superadmin', 'admin', 'member')),
|
|
105
|
+
-- Work-surface scope (orthogonal to `type`, ignored for admin/superadmin).
|
|
106
|
+
-- read governs search, write governs claim/ack/delete. write ⊆ read.
|
|
107
|
+
read_scope TEXT NOT NULL DEFAULT 'all' CHECK (read_scope IN ('self', 'all')),
|
|
108
|
+
write_scope TEXT NOT NULL DEFAULT 'all' CHECK (write_scope IN ('none', 'self', 'all')),
|
|
109
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
110
|
+
PRIMARY KEY (user_id, role),
|
|
111
|
+
CONSTRAINT chk_lt_user_roles_scope CHECK (NOT (write_scope = 'all' AND read_scope = 'self'))
|
|
107
112
|
);
|
|
108
113
|
|
|
109
114
|
CREATE INDEX IF NOT EXISTS idx_lt_user_roles_type ON lt_user_roles (type);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- ─── 012: lt_tasks.workflow_id uniqueness ─────────────────────────────────────
|
|
2
|
+
-- A task is 1:1 with its workflow_id. Every createTask caller keys the row by a
|
|
3
|
+
-- deterministic workflow_id (orchestrator childWorkflowId, interceptor
|
|
4
|
+
-- wf.workflowId, escalation triage-<id>), and createTask runs inside a
|
|
5
|
+
-- proxyActivity with retry { maximumAttempts: 3 }. Without a unique constraint a
|
|
6
|
+
-- retry — or a re-driven triage saga — double-inserts a task row. The unique
|
|
7
|
+
-- index lets createTask use ON CONFLICT (workflow_id) so retries converge instead
|
|
8
|
+
-- of duplicating, matching how HotMesh upserts the sibling job by (workflowId, app_id).
|
|
9
|
+
|
|
10
|
+
-- Collapse any pre-existing duplicates, keeping the most recent row per workflow_id
|
|
11
|
+
-- (tie-break on id so exactly one survives and the unique index can be built).
|
|
12
|
+
DELETE FROM lt_tasks a
|
|
13
|
+
USING lt_tasks b
|
|
14
|
+
WHERE a.workflow_id = b.workflow_id
|
|
15
|
+
AND (a.created_at < b.created_at
|
|
16
|
+
OR (a.created_at = b.created_at AND a.id < b.id));
|
|
17
|
+
|
|
18
|
+
-- Replace the non-unique lookup index with a unique one (it still serves lookups).
|
|
19
|
+
DROP INDEX IF EXISTS idx_lt_tasks_workflow_id;
|
|
20
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_lt_tasks_workflow_id ON lt_tasks (workflow_id);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
-- ─── lt_user_roles: read/write work-surface scope ──────────────────────────
|
|
2
|
+
--
|
|
3
|
+
-- Open roles split the worker capability into two orthogonal axes so that
|
|
4
|
+
-- one-time and limited-surface users are first-class:
|
|
5
|
+
--
|
|
6
|
+
-- read_scope (self | all) → governs SEARCH (which items appear)
|
|
7
|
+
-- write_scope (none | self | all) → governs CLAIM / ACK / DELETE
|
|
8
|
+
--
|
|
9
|
+
-- `self` = escalations assigned to the user (assigned_to = userId); `all` = the
|
|
10
|
+
-- whole role queue. The only constraint is write ⊆ read (you cannot act on what
|
|
11
|
+
-- you cannot see). `type` (member/admin/superadmin) is unchanged — it remains the
|
|
12
|
+
-- management/global tier, and admin/superadmin ignore scope (always act on all).
|
|
13
|
+
--
|
|
14
|
+
-- Existing rows default to ('all','all') = today's `member` behavior, so this is
|
|
15
|
+
-- backward compatible with zero data backfill. Idempotent: no-op on fresh installs
|
|
16
|
+
-- where 001_schema.sql already created the columns and the named constraint.
|
|
17
|
+
|
|
18
|
+
ALTER TABLE lt_user_roles
|
|
19
|
+
ADD COLUMN IF NOT EXISTS read_scope TEXT NOT NULL DEFAULT 'all'
|
|
20
|
+
CHECK (read_scope IN ('self', 'all'));
|
|
21
|
+
|
|
22
|
+
ALTER TABLE lt_user_roles
|
|
23
|
+
ADD COLUMN IF NOT EXISTS write_scope TEXT NOT NULL DEFAULT 'all'
|
|
24
|
+
CHECK (write_scope IN ('none', 'self', 'all'));
|
|
25
|
+
|
|
26
|
+
-- write ⊆ read: cannot act on the whole queue while only reading your own.
|
|
27
|
+
-- Guarded so a re-run (or a fresh install where 001 already added it) is a no-op.
|
|
28
|
+
DO $$
|
|
29
|
+
BEGIN
|
|
30
|
+
IF NOT EXISTS (
|
|
31
|
+
SELECT 1 FROM pg_constraint WHERE conname = 'chk_lt_user_roles_scope'
|
|
32
|
+
) THEN
|
|
33
|
+
ALTER TABLE lt_user_roles
|
|
34
|
+
ADD CONSTRAINT chk_lt_user_roles_scope
|
|
35
|
+
CHECK (NOT (write_scope = 'all' AND read_scope = 'self'));
|
|
36
|
+
END IF;
|
|
37
|
+
END $$;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime feature flags surfaced to the dashboard via /api/settings.
|
|
3
|
+
*
|
|
4
|
+
* These gate UI affordances (nav entries, routes) that some deployments want to
|
|
5
|
+
* hide. Defaults are permissive (everything on); a deployment opts OUT through
|
|
6
|
+
* the `features` block of the `start()` config. The dashboard reads the resolved
|
|
7
|
+
* flags from `settings.features` and hides the corresponding nav item + route.
|
|
8
|
+
*/
|
|
9
|
+
export interface FeatureFlags {
|
|
10
|
+
/**
|
|
11
|
+
* Show the DB Maintenance admin page (nav entry + route).
|
|
12
|
+
* Default: true. Set `features.dbMaintenance: false` in start config to hide it.
|
|
13
|
+
*/
|
|
14
|
+
dbMaintenance: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** Merge a partial set of flags from the start config. Unspecified flags keep their default. */
|
|
17
|
+
export declare function configureFeatureFlags(patch?: Partial<FeatureFlags>): void;
|
|
18
|
+
/** The resolved feature flags reported to the dashboard. */
|
|
19
|
+
export declare function getFeatureFlags(): FeatureFlags;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureFeatureFlags = configureFeatureFlags;
|
|
4
|
+
exports.getFeatureFlags = getFeatureFlags;
|
|
5
|
+
const DEFAULT_FLAGS = {
|
|
6
|
+
dbMaintenance: true,
|
|
7
|
+
};
|
|
8
|
+
let flags = { ...DEFAULT_FLAGS };
|
|
9
|
+
/** Merge a partial set of flags from the start config. Unspecified flags keep their default. */
|
|
10
|
+
function configureFeatureFlags(patch) {
|
|
11
|
+
flags = { ...DEFAULT_FLAGS, ...(patch ?? {}) };
|
|
12
|
+
}
|
|
13
|
+
/** The resolved feature flags reported to the dashboard. */
|
|
14
|
+
function getFeatureFlags() {
|
|
15
|
+
return { ...flags };
|
|
16
|
+
}
|
|
@@ -7,10 +7,15 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export declare const HOTMESH_VERSION: string;
|
|
9
9
|
/**
|
|
10
|
-
* The long-tail
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* The long-tail package version.
|
|
11
|
+
*
|
|
12
|
+
* Resolved from long-tail's OWN package.json by walking up from this module's
|
|
13
|
+
* directory to the first package.json named `@hotmeshio/long-tail`. Reading
|
|
14
|
+
* `process.cwd()/package.json` is wrong when long-tail is consumed as a
|
|
15
|
+
* dependency (e.g. mounted as a NestJS module) — cwd is then the HOST app's
|
|
16
|
+
* root, so it reported the host's version. The upward walk resolves correctly in
|
|
17
|
+
* dev (source tree), the standalone Docker image (`/app`), and under
|
|
18
|
+
* `node_modules/@hotmeshio/long-tail`. A static `../package.json` import can't be
|
|
19
|
+
* used: post-compile it resolves to `build/package.json`, which is not shipped.
|
|
15
20
|
*/
|
|
16
21
|
export declare const LONG_TAIL_VERSION: string;
|
package/build/modules/version.js
CHANGED
|
@@ -15,20 +15,36 @@ const package_json_1 = __importDefault(require("@hotmeshio/hotmesh/package.json"
|
|
|
15
15
|
* node_modules), and resolveJsonModule handles the static import at compile time.
|
|
16
16
|
*/
|
|
17
17
|
exports.HOTMESH_VERSION = package_json_1.default.version ?? 'unknown';
|
|
18
|
+
const LONG_TAIL_PACKAGE_NAME = '@hotmeshio/long-tail';
|
|
18
19
|
/**
|
|
19
|
-
* The long-tail
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* The long-tail package version.
|
|
21
|
+
*
|
|
22
|
+
* Resolved from long-tail's OWN package.json by walking up from this module's
|
|
23
|
+
* directory to the first package.json named `@hotmeshio/long-tail`. Reading
|
|
24
|
+
* `process.cwd()/package.json` is wrong when long-tail is consumed as a
|
|
25
|
+
* dependency (e.g. mounted as a NestJS module) — cwd is then the HOST app's
|
|
26
|
+
* root, so it reported the host's version. The upward walk resolves correctly in
|
|
27
|
+
* dev (source tree), the standalone Docker image (`/app`), and under
|
|
28
|
+
* `node_modules/@hotmeshio/long-tail`. A static `../package.json` import can't be
|
|
29
|
+
* used: post-compile it resolves to `build/package.json`, which is not shipped.
|
|
24
30
|
*/
|
|
25
31
|
exports.LONG_TAIL_VERSION = readLongTailVersion();
|
|
26
32
|
function readLongTailVersion() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
let dir = __dirname;
|
|
34
|
+
const { root } = (0, path_1.parse)(dir);
|
|
35
|
+
// eslint-disable-next-line no-constant-condition
|
|
36
|
+
while (true) {
|
|
37
|
+
try {
|
|
38
|
+
const pkg = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(dir, 'package.json'), 'utf8'));
|
|
39
|
+
if (pkg.name === LONG_TAIL_PACKAGE_NAME)
|
|
40
|
+
return pkg.version ?? 'unknown';
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
/* no readable package.json here — keep walking up */
|
|
44
|
+
}
|
|
45
|
+
if (dir === root)
|
|
46
|
+
break;
|
|
47
|
+
dir = (0, path_1.dirname)(dir);
|
|
33
48
|
}
|
|
49
|
+
return 'unknown';
|
|
34
50
|
}
|
|
@@ -37,19 +37,32 @@ const express_1 = require("express");
|
|
|
37
37
|
const api = __importStar(require("../api/diagnostics"));
|
|
38
38
|
const auth_1 = require("../modules/auth");
|
|
39
39
|
const router = (0, express_1.Router)();
|
|
40
|
+
const VALID_SECTIONS = new Set(['events', 'streams']);
|
|
41
|
+
/** Parse a comma-separated `include` query param into the recognized heavy sections. */
|
|
42
|
+
function parseInclude(raw) {
|
|
43
|
+
if (typeof raw !== 'string' || raw.trim() === '')
|
|
44
|
+
return undefined;
|
|
45
|
+
const sections = raw.split(',').map((s) => s.trim()).filter((s) => VALID_SECTIONS.has(s));
|
|
46
|
+
return sections.length > 0 ? sections : undefined;
|
|
47
|
+
}
|
|
40
48
|
/**
|
|
41
49
|
* GET /api/diagnostics/jobs/:workflowId
|
|
42
|
-
*
|
|
50
|
+
* Compact diagnosis for a single workflow job — the verdict only by default
|
|
51
|
+
* (status, idle time, stream counts, escalation, findings).
|
|
43
52
|
*
|
|
44
53
|
* Query params:
|
|
45
54
|
* app_id — HotMesh namespace (default: durable)
|
|
46
|
-
* max_events — cap on events returned (most recent kept; default: 500)
|
|
55
|
+
* max_events — cap on events returned when included (most recent kept; default: 500)
|
|
56
|
+
* include — comma-separated heavy sections to add: events, streams
|
|
57
|
+
* verbosity — 'summary' (default, verdict only) or 'full' (events + streams)
|
|
47
58
|
*/
|
|
48
59
|
router.get('/jobs/:workflowId', auth_1.requireAdmin, async (req, res) => {
|
|
49
60
|
const result = await api.diagnose({
|
|
50
61
|
workflowId: req.params.workflowId,
|
|
51
62
|
appId: typeof req.query.app_id === 'string' ? req.query.app_id : undefined,
|
|
52
63
|
maxEvents: req.query.max_events ? Number(req.query.max_events) : undefined,
|
|
64
|
+
include: parseInclude(req.query.include),
|
|
65
|
+
verbosity: req.query.verbosity === 'full' ? 'full' : undefined,
|
|
53
66
|
});
|
|
54
67
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
55
68
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* Faceted-routing HTTP surface — pond search + batch claim. Each operation targets a
|
|
4
|
+
* single pond `role` and is RBAC-scoped to it (the api layer enforces the gate). These
|
|
5
|
+
* mirror the SDK `escalations.searchByFacets / claimGroups / claimByFacets`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function registerFacetRoutes(router: Router): void;
|