@hotmeshio/long-tail 0.31.1 → 0.32.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.
Files changed (320) hide show
  1. package/build/api/escalations/create.js +17 -6
  2. package/build/api/escalations/files.d.ts +18 -0
  3. package/build/api/escalations/files.js +73 -0
  4. package/build/api/escalations/index.d.ts +1 -0
  5. package/build/api/escalations/index.js +4 -2
  6. package/build/api/escalations/metadata.js +5 -4
  7. package/build/api/escalations/resolve.js +6 -4
  8. package/build/bin/ltc.js +4 -2
  9. package/build/index.d.ts +2 -0
  10. package/build/index.js +13 -2
  11. package/build/lib/cli/commands/escalations.d.ts +2 -0
  12. package/build/lib/cli/commands/escalations.js +12 -4
  13. package/build/lib/storage/s3.js +1 -0
  14. package/build/modules/config.d.ts +9 -0
  15. package/build/modules/config.js +9 -0
  16. package/build/routes/escalations/single.js +11 -0
  17. package/build/sdk/index.d.ts +4 -0
  18. package/build/sdk/index.js +2 -0
  19. package/build/services/escalation/aggregate-resolved-sql.d.ts +19 -0
  20. package/build/services/escalation/aggregate-resolved-sql.js +57 -0
  21. package/build/services/escalation/aggregate-sql.d.ts +6 -1
  22. package/build/services/escalation/aggregate-sql.js +33 -12
  23. package/build/services/escalation/aggregate-validate.d.ts +5 -2
  24. package/build/services/escalation/aggregate-validate.js +7 -4
  25. package/build/services/escalation/aggregates.js +5 -3
  26. package/build/services/escalation/crud.js +3 -0
  27. package/build/services/escalation/file-links.d.ts +39 -0
  28. package/build/services/escalation/file-links.js +118 -0
  29. package/build/services/escalation/resolver-validation.d.ts +33 -0
  30. package/build/services/escalation/resolver-validation.js +22 -6
  31. package/build/services/orchestrator/condition.d.ts +20 -4
  32. package/build/services/orchestrator/condition.js +27 -8
  33. package/build/shared/form-validation/display-only-widgets.d.ts +3 -2
  34. package/build/shared/form-validation/display-only-widgets.js +3 -2
  35. package/build/shared/form-validation/index.d.ts +2 -0
  36. package/build/shared/form-validation/index.js +2 -0
  37. package/build/shared/form-validation/x-lt-confidence-facets.d.ts +27 -0
  38. package/build/shared/form-validation/x-lt-confidence-facets.js +60 -0
  39. package/build/shared/form-validation/x-lt-confidence.d.ts +57 -0
  40. package/build/shared/form-validation/x-lt-confidence.js +177 -0
  41. package/build/shared/form-validation/x-lt-help.d.ts +1 -1
  42. package/build/shared/form-validation/x-lt-help.js +1 -1
  43. package/build/system/mcp-servers/admin/escalations.js +4 -2
  44. package/build/system/mcp-servers/admin/labels-schemas.d.ts +4 -4
  45. package/build/system/mcp-servers/admin/schemas.d.ts +111 -70
  46. package/build/system/mcp-servers/admin/schemas.js +8 -3
  47. package/build/system/mcp-servers/human-queue-files.d.ts +8 -0
  48. package/build/system/mcp-servers/human-queue-files.js +32 -0
  49. package/build/system/mcp-servers/human-queue-schemas.d.ts +7 -0
  50. package/build/system/mcp-servers/human-queue-schemas.js +4 -1
  51. package/build/system/mcp-servers/human-queue.d.ts +1 -0
  52. package/build/system/mcp-servers/human-queue.js +23 -16
  53. package/build/system/seed/tool-manifests-admin.js +1 -1
  54. package/build/system/seed/tool-manifests-escalation.js +13 -0
  55. package/build/tsconfig.tsbuildinfo +1 -1
  56. package/build/types/analytics.d.ts +14 -3
  57. package/build/types/analytics.js +3 -1
  58. package/build/types/escalation.d.ts +34 -0
  59. package/build/types/escalation.js +72 -1
  60. package/build/types/index.d.ts +4 -4
  61. package/build/types/index.js +5 -1
  62. package/dashboard/dist/assets/{AdminDashboard-BafKaq50.js → AdminDashboard-C25co77C.js} +2 -2
  63. package/dashboard/dist/assets/{AdminDashboard-BafKaq50.js.map → AdminDashboard-C25co77C.js.map} +1 -1
  64. package/dashboard/dist/assets/{AgentConfigPage-CFHf31DT.js → AgentConfigPage-CsCpI15j.js} +5 -5
  65. package/dashboard/dist/assets/{AgentConfigPage-CFHf31DT.js.map → AgentConfigPage-CsCpI15j.js.map} +1 -1
  66. package/dashboard/dist/assets/{AgentDetailPage-CEvz5rJr.js → AgentDetailPage-ByaepsB5.js} +3 -3
  67. package/dashboard/dist/assets/{AgentDetailPage-CEvz5rJr.js.map → AgentDetailPage-ByaepsB5.js.map} +1 -1
  68. package/dashboard/dist/assets/{AgentsPage-DjQaio0O.js → AgentsPage-ByHU42SO.js} +2 -2
  69. package/dashboard/dist/assets/{AgentsPage-DjQaio0O.js.map → AgentsPage-ByHU42SO.js.map} +1 -1
  70. package/dashboard/dist/assets/{AvailableEscalationsPage-UB03VTJx.js → AvailableEscalationsPage--o6qcz7-.js} +2 -2
  71. package/dashboard/dist/assets/{AvailableEscalationsPage-UB03VTJx.js.map → AvailableEscalationsPage--o6qcz7-.js.map} +1 -1
  72. package/dashboard/dist/assets/{BotPicker-C7MNWOF7.js → BotPicker-B3y3H3fs.js} +2 -2
  73. package/dashboard/dist/assets/{BotPicker-C7MNWOF7.js.map → BotPicker-B3y3H3fs.js.map} +1 -1
  74. package/dashboard/dist/assets/{BulkAssignModal-h5fX-_cV.js → BulkAssignModal-DMNIkIn6.js} +2 -2
  75. package/dashboard/dist/assets/{BulkAssignModal-h5fX-_cV.js.map → BulkAssignModal-DMNIkIn6.js.map} +1 -1
  76. package/dashboard/dist/assets/{CapabilitiesPage-BIzDl-ZT.js → CapabilitiesPage-BekfKHlk.js} +2 -2
  77. package/dashboard/dist/assets/{CapabilitiesPage-BIzDl-ZT.js.map → CapabilitiesPage-BekfKHlk.js.map} +1 -1
  78. package/dashboard/dist/assets/{CollapsibleSection-B5TivtEg.js → CollapsibleSection-BAteHgBG.js} +2 -2
  79. package/dashboard/dist/assets/{CollapsibleSection-B5TivtEg.js.map → CollapsibleSection-BAteHgBG.js.map} +1 -1
  80. package/dashboard/dist/assets/{ConfirmDeleteModal-CB4nKePb.js → ConfirmDeleteModal-BNY287W9.js} +2 -2
  81. package/dashboard/dist/assets/{ConfirmDeleteModal-CB4nKePb.js.map → ConfirmDeleteModal-BNY287W9.js.map} +1 -1
  82. package/dashboard/dist/assets/{ConnectedAppsPage-B3S5gVWw.js → ConnectedAppsPage-LLiiH3da.js} +2 -2
  83. package/dashboard/dist/assets/{ConnectedAppsPage-B3S5gVWw.js.map → ConnectedAppsPage-LLiiH3da.js.map} +1 -1
  84. package/dashboard/dist/assets/{CountdownTimer-BHVIq3kA.js → CountdownTimer-DBLURjxh.js} +2 -2
  85. package/dashboard/dist/assets/{CountdownTimer-BHVIq3kA.js.map → CountdownTimer-DBLURjxh.js.map} +1 -1
  86. package/dashboard/dist/assets/{CredentialConfirmModal-w0AGmCIe.js → CredentialConfirmModal-BqpY3yen.js} +2 -2
  87. package/dashboard/dist/assets/{CredentialConfirmModal-w0AGmCIe.js.map → CredentialConfirmModal-BqpY3yen.js.map} +1 -1
  88. package/dashboard/dist/assets/{CredentialsPage-BtCGBJrT.js → CredentialsPage-CW3_dbm2.js} +2 -2
  89. package/dashboard/dist/assets/{CredentialsPage-BtCGBJrT.js.map → CredentialsPage-CW3_dbm2.js.map} +1 -1
  90. package/dashboard/dist/assets/{CronLabel-BG1rZK-5.js → CronLabel-CR6DiZZr.js} +2 -2
  91. package/dashboard/dist/assets/{CronLabel-BG1rZK-5.js.map → CronLabel-CR6DiZZr.js.map} +1 -1
  92. package/dashboard/dist/assets/{DataTable-FjFhx0SE.js → DataTable-C-IlbLhY.js} +2 -2
  93. package/dashboard/dist/assets/{DataTable-FjFhx0SE.js.map → DataTable-C-IlbLhY.js.map} +1 -1
  94. package/dashboard/dist/assets/{DropZone-D8ZVdEb5.js → DropZone-CHmz59w4.js} +2 -2
  95. package/dashboard/dist/assets/{DropZone-D8ZVdEb5.js.map → DropZone-CHmz59w4.js.map} +1 -1
  96. package/dashboard/dist/assets/{ElapsedCell-l4m8Yvfv.js → ElapsedCell-CEapQvgU.js} +2 -2
  97. package/dashboard/dist/assets/{ElapsedCell-l4m8Yvfv.js.map → ElapsedCell-CEapQvgU.js.map} +1 -1
  98. package/dashboard/dist/assets/{EntityTimelinePanel-BOHlIaxF.js → EntityTimelinePanel-DqD_BpJM.js} +2 -2
  99. package/dashboard/dist/assets/{EntityTimelinePanel-BOHlIaxF.js.map → EntityTimelinePanel-DqD_BpJM.js.map} +1 -1
  100. package/dashboard/dist/assets/{EscalationListSchemaPage-BotlwlX3.js → EscalationListSchemaPage-DDKcrVbb.js} +3 -3
  101. package/dashboard/dist/assets/{EscalationListSchemaPage-BotlwlX3.js.map → EscalationListSchemaPage-DDKcrVbb.js.map} +1 -1
  102. package/dashboard/dist/assets/{EscalationSchemaPage-CfZSVOSD.js → EscalationSchemaPage-BZHZfJiQ.js} +3 -3
  103. package/dashboard/dist/assets/{EscalationSchemaPage-CfZSVOSD.js.map → EscalationSchemaPage-BZHZfJiQ.js.map} +1 -1
  104. package/dashboard/dist/assets/{EscalationTimeline-CCKpuRBU.js → EscalationTimeline-Dv0XUgQX.js} +2 -2
  105. package/dashboard/dist/assets/{EscalationTimeline-CCKpuRBU.js.map → EscalationTimeline-Dv0XUgQX.js.map} +1 -1
  106. package/dashboard/dist/assets/{EscalationTitleSelect-cpTzPHiW.js → EscalationTitleSelect-BN7D52wT.js} +2 -2
  107. package/dashboard/dist/assets/{EscalationTitleSelect-cpTzPHiW.js.map → EscalationTitleSelect-BN7D52wT.js.map} +1 -1
  108. package/dashboard/dist/assets/{EscalationsOverview-DS-nK0qV.js → EscalationsOverview-DE6EPkhT.js} +2 -2
  109. package/dashboard/dist/assets/{EscalationsOverview-DS-nK0qV.js.map → EscalationsOverview-DE6EPkhT.js.map} +1 -1
  110. package/dashboard/dist/assets/{EventTable-UfebhJf0.js → EventTable-CiV62txY.js} +2 -2
  111. package/dashboard/dist/assets/{EventTable-UfebhJf0.js.map → EventTable-CiV62txY.js.map} +1 -1
  112. package/dashboard/dist/assets/{FilterBar-newA5l-X.js → FilterBar-WyNQPyQ1.js} +2 -2
  113. package/dashboard/dist/assets/{FilterBar-newA5l-X.js.map → FilterBar-WyNQPyQ1.js.map} +1 -1
  114. package/dashboard/dist/assets/{GraphInvokePage-6SCDyQcK.js → GraphInvokePage--gn48yUD.js} +2 -2
  115. package/dashboard/dist/assets/{GraphInvokePage-6SCDyQcK.js.map → GraphInvokePage--gn48yUD.js.map} +1 -1
  116. package/dashboard/dist/assets/{HomePage-BEc-XdKj.js → HomePage-IR_jgBE8.js} +2 -2
  117. package/dashboard/dist/assets/{HomePage-BEc-XdKj.js.map → HomePage-IR_jgBE8.js.map} +1 -1
  118. package/dashboard/dist/assets/{LabelJobsPage-BO50zXT5.js → LabelJobsPage-C8LSts4O.js} +2 -2
  119. package/dashboard/dist/assets/{LabelJobsPage-BO50zXT5.js.map → LabelJobsPage-C8LSts4O.js.map} +1 -1
  120. package/dashboard/dist/assets/{LinePage-NYxJQ-ex.js → LinePage-CS7uUv00.js} +2 -2
  121. package/dashboard/dist/assets/{LinePage-NYxJQ-ex.js.map → LinePage-CS7uUv00.js.map} +1 -1
  122. package/dashboard/dist/assets/{LinesPage-RbWTaQRh.js → LinesPage-CJprjG39.js} +3 -3
  123. package/dashboard/dist/assets/{LinesPage-RbWTaQRh.js.map → LinesPage-CJprjG39.js.map} +1 -1
  124. package/dashboard/dist/assets/{ListToolbar-B-E9-toh.js → ListToolbar-YP3uwvXC.js} +2 -2
  125. package/dashboard/dist/assets/{ListToolbar-B-E9-toh.js.map → ListToolbar-YP3uwvXC.js.map} +1 -1
  126. package/dashboard/dist/assets/{McpOverview-Shcf9QhZ.js → McpOverview-Ce-m2JON.js} +2 -2
  127. package/dashboard/dist/assets/{McpOverview-Shcf9QhZ.js.map → McpOverview-Ce-m2JON.js.map} +1 -1
  128. package/dashboard/dist/assets/{McpQueryDetailPage-D8kmjy2v.js → McpQueryDetailPage-CtnUqO1v.js} +2 -2
  129. package/dashboard/dist/assets/{McpQueryDetailPage-D8kmjy2v.js.map → McpQueryDetailPage-CtnUqO1v.js.map} +1 -1
  130. package/dashboard/dist/assets/{McpQueryPage-ck-o5m8A.js → McpQueryPage-C-lqUPlg.js} +2 -2
  131. package/dashboard/dist/assets/{McpQueryPage-ck-o5m8A.js.map → McpQueryPage-C-lqUPlg.js.map} +1 -1
  132. package/dashboard/dist/assets/{McpRunDetailPage-BJKkM9-3.js → McpRunDetailPage-MnIe0hwz.js} +2 -2
  133. package/dashboard/dist/assets/{McpRunDetailPage-BJKkM9-3.js.map → McpRunDetailPage-MnIe0hwz.js.map} +1 -1
  134. package/dashboard/dist/assets/{McpRunsPage-DqhHfD5G.js → McpRunsPage-CpYLXVPF.js} +2 -2
  135. package/dashboard/dist/assets/{McpRunsPage-DqhHfD5G.js.map → McpRunsPage-CpYLXVPF.js.map} +1 -1
  136. package/dashboard/dist/assets/{NamespacePill--uIaGtrN.js → NamespacePill-DilSgLyE.js} +2 -2
  137. package/dashboard/dist/assets/{NamespacePill--uIaGtrN.js.map → NamespacePill-DilSgLyE.js.map} +1 -1
  138. package/dashboard/dist/assets/{OperationsPage-D6B9Vv__.js → OperationsPage-xe6bAwaq.js} +2 -2
  139. package/dashboard/dist/assets/{OperationsPage-D6B9Vv__.js.map → OperationsPage-xe6bAwaq.js.map} +1 -1
  140. package/dashboard/dist/assets/{OperatorDashboard-CIH1cxjQ.js → OperatorDashboard-Cm9_C0EP.js} +2 -2
  141. package/dashboard/dist/assets/{OperatorDashboard-CIH1cxjQ.js.map → OperatorDashboard-Cm9_C0EP.js.map} +1 -1
  142. package/dashboard/dist/assets/{PageHeader-DClJ33fV.js → PageHeader-B7SOvLT8.js} +2 -2
  143. package/dashboard/dist/assets/{PageHeader-DClJ33fV.js.map → PageHeader-B7SOvLT8.js.map} +1 -1
  144. package/dashboard/dist/assets/{PageHeaderWithStats-C-TrbKQL.js → PageHeaderWithStats-DWKap7gs.js} +2 -2
  145. package/dashboard/dist/assets/{PageHeaderWithStats-C-TrbKQL.js.map → PageHeaderWithStats-DWKap7gs.js.map} +1 -1
  146. package/dashboard/dist/assets/{PersonaDetailPage-DjvfyIph.js → PersonaDetailPage-CvstNkh3.js} +2 -2
  147. package/dashboard/dist/assets/{PersonaDetailPage-DjvfyIph.js.map → PersonaDetailPage-CvstNkh3.js.map} +1 -1
  148. package/dashboard/dist/assets/{PersonasPage-D7ryA8Vc.js → PersonasPage-ba1KeInW.js} +2 -2
  149. package/dashboard/dist/assets/{PersonasPage-D7ryA8Vc.js.map → PersonasPage-ba1KeInW.js.map} +1 -1
  150. package/dashboard/dist/assets/{PortalPage-D3ybr0mo.js → PortalPage-GDgG88TM.js} +2 -2
  151. package/dashboard/dist/assets/{PortalPage-D3ybr0mo.js.map → PortalPage-GDgG88TM.js.map} +1 -1
  152. package/dashboard/dist/assets/{PrintLabelsPanel-D0HF5x8b.js → PrintLabelsPanel-BkUN00Qd.js} +2 -2
  153. package/dashboard/dist/assets/{PrintLabelsPanel-D0HF5x8b.js.map → PrintLabelsPanel-BkUN00Qd.js.map} +1 -1
  154. package/dashboard/dist/assets/{ProcessDetailPage-0xS9EdHe.js → ProcessDetailPage-BKu9_wWv.js} +2 -2
  155. package/dashboard/dist/assets/{ProcessDetailPage-0xS9EdHe.js.map → ProcessDetailPage-BKu9_wWv.js.map} +1 -1
  156. package/dashboard/dist/assets/{ProcessesListPage-93SMj1Fd.js → ProcessesListPage-BfJYTU_v.js} +2 -2
  157. package/dashboard/dist/assets/{ProcessesListPage-93SMj1Fd.js.map → ProcessesListPage-BfJYTU_v.js.map} +1 -1
  158. package/dashboard/dist/assets/ResolverForm-DZmY6wJV.js +8 -0
  159. package/dashboard/dist/assets/ResolverForm-DZmY6wJV.js.map +1 -0
  160. package/dashboard/dist/assets/{RoleDetailPage-DlUOJWSB.js → RoleDetailPage-vGeth3ve.js} +3 -3
  161. package/dashboard/dist/assets/{RoleDetailPage-DlUOJWSB.js.map → RoleDetailPage-vGeth3ve.js.map} +1 -1
  162. package/dashboard/dist/assets/{RolePill-BjD1Qw5y.js → RolePill-KhT-Yehm.js} +2 -2
  163. package/dashboard/dist/assets/{RolePill-BjD1Qw5y.js.map → RolePill-KhT-Yehm.js.map} +1 -1
  164. package/dashboard/dist/assets/{RolesPage-DqhHSvaw.js → RolesPage-CwxHOkqF.js} +2 -2
  165. package/dashboard/dist/assets/{RolesPage-DqhHSvaw.js.map → RolesPage-CwxHOkqF.js.map} +1 -1
  166. package/dashboard/dist/assets/{RosterWidget-BrIq61HR.js → RosterWidget-DRVj9xyk.js} +2 -2
  167. package/dashboard/dist/assets/{RosterWidget-BrIq61HR.js.map → RosterWidget-DRVj9xyk.js.map} +1 -1
  168. package/dashboard/dist/assets/{RunAsSelector-D6zQrCNr.js → RunAsSelector-DvPX3XmA.js} +2 -2
  169. package/dashboard/dist/assets/{RunAsSelector-D6zQrCNr.js.map → RunAsSelector-DvPX3XmA.js.map} +1 -1
  170. package/dashboard/dist/assets/{ScanCodesPage-B2S9DR2f.js → ScanCodesPage-Cptbe7h8.js} +2 -2
  171. package/dashboard/dist/assets/{ScanCodesPage-B2S9DR2f.js.map → ScanCodesPage-Cptbe7h8.js.map} +1 -1
  172. package/dashboard/dist/assets/{ScanSchemeDetailPage-gpxKN-pL.js → ScanSchemeDetailPage-DquNJ7Or.js} +4 -4
  173. package/dashboard/dist/assets/{ScanSchemeDetailPage-gpxKN-pL.js.map → ScanSchemeDetailPage-DquNJ7Or.js.map} +1 -1
  174. package/dashboard/dist/assets/{ScanStationPage-B-UTgXsG.js → ScanStationPage-DaRfGGa8.js} +2 -2
  175. package/dashboard/dist/assets/{ScanStationPage-B-UTgXsG.js.map → ScanStationPage-DaRfGGa8.js.map} +1 -1
  176. package/dashboard/dist/assets/{SchemeMatchFields-BK24aa7K.js → SchemeMatchFields-w-pffi98.js} +2 -2
  177. package/dashboard/dist/assets/{SchemeMatchFields-BK24aa7K.js.map → SchemeMatchFields-w-pffi98.js.map} +1 -1
  178. package/dashboard/dist/assets/{ScopeBadge-ofLQ6HW-.js → ScopeBadge-HeuiMJhW.js} +2 -2
  179. package/dashboard/dist/assets/{ScopeBadge-ofLQ6HW-.js.map → ScopeBadge-HeuiMJhW.js.map} +1 -1
  180. package/dashboard/dist/assets/{StickyPagination-CgVv7vc_.js → StickyPagination-D6fDHCcJ.js} +2 -2
  181. package/dashboard/dist/assets/{StickyPagination-CgVv7vc_.js.map → StickyPagination-D6fDHCcJ.js.map} +1 -1
  182. package/dashboard/dist/assets/{StreamMessageDetail-B9sxDVw4.js → StreamMessageDetail-BmYVQrzl.js} +2 -2
  183. package/dashboard/dist/assets/{StreamMessageDetail-B9sxDVw4.js.map → StreamMessageDetail-BmYVQrzl.js.map} +1 -1
  184. package/dashboard/dist/assets/{SwimlaneTimeline-DQc0CYSL.js → SwimlaneTimeline-KCqA-PeL.js} +2 -2
  185. package/dashboard/dist/assets/{SwimlaneTimeline-DQc0CYSL.js.map → SwimlaneTimeline-KCqA-PeL.js.map} +1 -1
  186. package/dashboard/dist/assets/{TagInput-47qVYzke.js → TagInput-CZBAu1Hy.js} +2 -2
  187. package/dashboard/dist/assets/{TagInput-47qVYzke.js.map → TagInput-CZBAu1Hy.js.map} +1 -1
  188. package/dashboard/dist/assets/{TaskDetailPage-D6VOsA1f.js → TaskDetailPage-WtVv2z7T.js} +2 -2
  189. package/dashboard/dist/assets/{TaskDetailPage-D6VOsA1f.js.map → TaskDetailPage-WtVv2z7T.js.map} +1 -1
  190. package/dashboard/dist/assets/{TaskQueuePill-C5KmdXAl.js → TaskQueuePill-DWGn3CWx.js} +2 -2
  191. package/dashboard/dist/assets/{TaskQueuePill-C5KmdXAl.js.map → TaskQueuePill-DWGn3CWx.js.map} +1 -1
  192. package/dashboard/dist/assets/{TasksListPage-DG8hvO8G.js → TasksListPage-DMYQNDIw.js} +2 -2
  193. package/dashboard/dist/assets/{TasksListPage-DG8hvO8G.js.map → TasksListPage-DMYQNDIw.js.map} +1 -1
  194. package/dashboard/dist/assets/{TimeAgo-CL02EhFi.js → TimeAgo-BkY4lahi.js} +2 -2
  195. package/dashboard/dist/assets/{TimeAgo-CL02EhFi.js.map → TimeAgo-BkY4lahi.js.map} +1 -1
  196. package/dashboard/dist/assets/{TimestampCell-BE7oKVJg.js → TimestampCell-BBPb9TI2.js} +2 -2
  197. package/dashboard/dist/assets/{TimestampCell-BE7oKVJg.js.map → TimestampCell-BBPb9TI2.js.map} +1 -1
  198. package/dashboard/dist/assets/{ToolPill-Cp9Drk1s.js → ToolPill-B2aRk0o1.js} +2 -2
  199. package/dashboard/dist/assets/{ToolPill-Cp9Drk1s.js.map → ToolPill-B2aRk0o1.js.map} +1 -1
  200. package/dashboard/dist/assets/{ToolTestPanel-CRecLh6S.js → ToolTestPanel-CNMbmymK.js} +2 -2
  201. package/dashboard/dist/assets/{ToolTestPanel-CRecLh6S.js.map → ToolTestPanel-CNMbmymK.js.map} +1 -1
  202. package/dashboard/dist/assets/{TopicDetailPage-QzkinTfN.js → TopicDetailPage-CodBRylU.js} +2 -2
  203. package/dashboard/dist/assets/{TopicDetailPage-QzkinTfN.js.map → TopicDetailPage-CodBRylU.js.map} +1 -1
  204. package/dashboard/dist/assets/TopicsPage-BtD8jTU7.js +2 -0
  205. package/dashboard/dist/assets/{TopicsPage-D8dW6J65.js.map → TopicsPage-BtD8jTU7.js.map} +1 -1
  206. package/dashboard/dist/assets/{UserName-Dw3R_zrl.js → UserName-D6y9AnuY.js} +2 -2
  207. package/dashboard/dist/assets/{UserName-Dw3R_zrl.js.map → UserName-D6y9AnuY.js.map} +1 -1
  208. package/dashboard/dist/assets/{WorkflowExecutionPage-BTocv8or.js → WorkflowExecutionPage-BeffqV13.js} +2 -2
  209. package/dashboard/dist/assets/{WorkflowExecutionPage-BTocv8or.js.map → WorkflowExecutionPage-BeffqV13.js.map} +1 -1
  210. package/dashboard/dist/assets/{WorkflowPill-BiLYq__w.js → WorkflowPill-BNm3R4pP.js} +2 -2
  211. package/dashboard/dist/assets/{WorkflowPill-BiLYq__w.js.map → WorkflowPill-BNm3R4pP.js.map} +1 -1
  212. package/dashboard/dist/assets/{WorkflowsDashboard-CIPEt3et.js → WorkflowsDashboard-m4Co5diK.js} +2 -2
  213. package/dashboard/dist/assets/{WorkflowsDashboard-CIPEt3et.js.map → WorkflowsDashboard-m4Co5diK.js.map} +1 -1
  214. package/dashboard/dist/assets/{WorkflowsOverview-Bj4MJIE-.js → WorkflowsOverview-DNoI9qY8.js} +2 -2
  215. package/dashboard/dist/assets/{WorkflowsOverview-Bj4MJIE-.js.map → WorkflowsOverview-DNoI9qY8.js.map} +1 -1
  216. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DMEk5k9-.js → YamlWorkflowDetailPage-8Vpc4Oxy.js} +2 -2
  217. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DMEk5k9-.js.map → YamlWorkflowDetailPage-8Vpc4Oxy.js.map} +1 -1
  218. package/dashboard/dist/assets/{YamlWorkflowsPage-F2yyyoiB.js → YamlWorkflowsPage-D1JNwDSg.js} +2 -2
  219. package/dashboard/dist/assets/{YamlWorkflowsPage-F2yyyoiB.js.map → YamlWorkflowsPage-D1JNwDSg.js.map} +1 -1
  220. package/dashboard/dist/assets/{agents-mSgxEPpI.js → agents-LTHUsfv3.js} +2 -2
  221. package/dashboard/dist/assets/{agents-mSgxEPpI.js.map → agents-LTHUsfv3.js.map} +1 -1
  222. package/dashboard/dist/assets/{bots-p4Hp0CV6.js → bots-CQxehfBo.js} +2 -2
  223. package/dashboard/dist/assets/{bots-p4Hp0CV6.js.map → bots-CQxehfBo.js.map} +1 -1
  224. package/dashboard/dist/assets/{capabilities-D_-I_SXR.js → capabilities-DECTnJrK.js} +2 -2
  225. package/dashboard/dist/assets/{capabilities-D_-I_SXR.js.map → capabilities-DECTnJrK.js.map} +1 -1
  226. package/dashboard/dist/assets/{controlplane-DjdoQnRU.js → controlplane-Dx20db5g.js} +2 -2
  227. package/dashboard/dist/assets/{controlplane-DjdoQnRU.js.map → controlplane-Dx20db5g.js.map} +1 -1
  228. package/dashboard/dist/assets/{escalation-columns-R_IEVQjQ.js → escalation-columns-CVFGUB79.js} +2 -2
  229. package/dashboard/dist/assets/{escalation-columns-R_IEVQjQ.js.map → escalation-columns-CVFGUB79.js.map} +1 -1
  230. package/dashboard/dist/assets/escalation-items-Bj7bkwWy.js +2 -0
  231. package/dashboard/dist/assets/escalation-items-Bj7bkwWy.js.map +1 -0
  232. package/dashboard/dist/assets/index-BD4O-ISx.js +13 -0
  233. package/dashboard/dist/assets/{index-Dk2KKo0z.js.map → index-BD4O-ISx.js.map} +1 -1
  234. package/dashboard/dist/assets/{index-D9RAN9sA.js → index-BL8XOMHT.js} +2 -2
  235. package/dashboard/dist/assets/{index-D9RAN9sA.js.map → index-BL8XOMHT.js.map} +1 -1
  236. package/dashboard/dist/assets/index-C2vRDf96.js +2 -0
  237. package/dashboard/dist/assets/{index-C5osluV3.js.map → index-C2vRDf96.js.map} +1 -1
  238. package/dashboard/dist/assets/{index-DUYAGxwc.js → index-CNgyKRQ8.js} +2 -2
  239. package/dashboard/dist/assets/{index-DUYAGxwc.js.map → index-CNgyKRQ8.js.map} +1 -1
  240. package/dashboard/dist/assets/{index-DlJkZ12b.js → index-CdXPbBgs.js} +2 -2
  241. package/dashboard/dist/assets/{index-DlJkZ12b.js.map → index-CdXPbBgs.js.map} +1 -1
  242. package/dashboard/dist/assets/{index-BuCEhhnl.js → index-CnBUFCV7.js} +2 -2
  243. package/dashboard/dist/assets/{index-BuCEhhnl.js.map → index-CnBUFCV7.js.map} +1 -1
  244. package/dashboard/dist/assets/index-CoLciFzq.css +1 -0
  245. package/dashboard/dist/assets/{index-D-FYj9jT.js → index-D_TSx-k_.js} +2 -2
  246. package/dashboard/dist/assets/{index-D-FYj9jT.js.map → index-D_TSx-k_.js.map} +1 -1
  247. package/dashboard/dist/assets/{index-C_dAJUzh.js → index-Do9Y6Fgt.js} +16 -16
  248. package/dashboard/dist/assets/index-Do9Y6Fgt.js.map +1 -0
  249. package/dashboard/dist/assets/{index-D6K_IgCz.js → index-Dq1zjilj.js} +2 -2
  250. package/dashboard/dist/assets/{index-D6K_IgCz.js.map → index-Dq1zjilj.js.map} +1 -1
  251. package/dashboard/dist/assets/{index-BEMdD58x.js → index-Dz4LSzA2.js} +2 -2
  252. package/dashboard/dist/assets/{index-BEMdD58x.js.map → index-Dz4LSzA2.js.map} +1 -1
  253. package/dashboard/dist/assets/{index-D7L_VoBD.js → index-g1MmARVR.js} +2 -2
  254. package/dashboard/dist/assets/{index-D7L_VoBD.js.map → index-g1MmARVR.js.map} +1 -1
  255. package/dashboard/dist/assets/{index-BxbQmeqh.js → index-qEd4FVmN.js} +2 -2
  256. package/dashboard/dist/assets/{index-BxbQmeqh.js.map → index-qEd4FVmN.js.map} +1 -1
  257. package/dashboard/dist/assets/index-v4rQ8ctJ.js +3 -0
  258. package/dashboard/dist/assets/index-v4rQ8ctJ.js.map +1 -0
  259. package/dashboard/dist/assets/{knowledge-DSsPTqkK.js → knowledge-CT1I1t1S.js} +2 -2
  260. package/dashboard/dist/assets/{knowledge-DSsPTqkK.js.map → knowledge-CT1I1t1S.js.map} +1 -1
  261. package/dashboard/dist/assets/{machines-DSgGtqqr.js → machines-Dsuw-l1y.js} +2 -2
  262. package/dashboard/dist/assets/{machines-DSgGtqqr.js.map → machines-Dsuw-l1y.js.map} +1 -1
  263. package/dashboard/dist/assets/{mcp-Cg-_uLw8.js → mcp-C3o5wzO8.js} +2 -2
  264. package/dashboard/dist/assets/{mcp-Cg-_uLw8.js.map → mcp-C3o5wzO8.js.map} +1 -1
  265. package/dashboard/dist/assets/{mcp-query-DQombEK_.js → mcp-query-IvkIG7gH.js} +2 -2
  266. package/dashboard/dist/assets/{mcp-query-DQombEK_.js.map → mcp-query-IvkIG7gH.js.map} +1 -1
  267. package/dashboard/dist/assets/pdf-CcZYcL52.js +13 -0
  268. package/dashboard/dist/assets/pdf-CcZYcL52.js.map +1 -0
  269. package/dashboard/dist/assets/pdf.worker.min-DgRcL-GR.js +2 -0
  270. package/dashboard/dist/assets/pdf.worker.min-DgRcL-GR.js.map +1 -0
  271. package/dashboard/dist/assets/pdf.worker.min-yatZIOMy.mjs +21 -0
  272. package/dashboard/dist/assets/{personas-DYrcoVBu.js → personas-zWlWjj6j.js} +2 -2
  273. package/dashboard/dist/assets/{personas-DYrcoVBu.js.map → personas-zWlWjj6j.js.map} +1 -1
  274. package/dashboard/dist/assets/{pipelines-wdb4xsey.js → pipelines-BKNvBMdf.js} +2 -2
  275. package/dashboard/dist/assets/{pipelines-wdb4xsey.js.map → pipelines-BKNvBMdf.js.map} +1 -1
  276. package/dashboard/dist/assets/{tasks-Bil7gvm9.js → tasks-BQSO3Sjv.js} +2 -2
  277. package/dashboard/dist/assets/{tasks-Bil7gvm9.js.map → tasks-BQSO3Sjv.js.map} +1 -1
  278. package/dashboard/dist/assets/{topics-wBqaVhRR.js → topics-Dr_1TtUM.js} +2 -2
  279. package/dashboard/dist/assets/{topics-wBqaVhRR.js.map → topics-Dr_1TtUM.js.map} +1 -1
  280. package/dashboard/dist/assets/{useContainerWidth-DSLp1gEm.js → useContainerWidth-D38m8eub.js} +2 -2
  281. package/dashboard/dist/assets/{useContainerWidth-DSLp1gEm.js.map → useContainerWidth-D38m8eub.js.map} +1 -1
  282. package/dashboard/dist/assets/{useDebouncedValue-CwrY8TpV.js → useDebouncedValue-C5ESASfo.js} +2 -2
  283. package/dashboard/dist/assets/{useDebouncedValue-CwrY8TpV.js.map → useDebouncedValue-C5ESASfo.js.map} +1 -1
  284. package/dashboard/dist/assets/{useNamespace-Sod_xApz.js → useNamespace-DLLOJRYY.js} +2 -2
  285. package/dashboard/dist/assets/{useNamespace-Sod_xApz.js.map → useNamespace-DLLOJRYY.js.map} +1 -1
  286. package/dashboard/dist/assets/{useYamlActivityEvents-CKLInV3C.js → useYamlActivityEvents-D0XNXli1.js} +2 -2
  287. package/dashboard/dist/assets/{useYamlActivityEvents-CKLInV3C.js.map → useYamlActivityEvents-D0XNXli1.js.map} +1 -1
  288. package/dashboard/dist/assets/{validate-CYhW1xMJ.js → validate-Be4GWnJ1.js} +2 -2
  289. package/dashboard/dist/assets/{validate-CYhW1xMJ.js.map → validate-Be4GWnJ1.js.map} +1 -1
  290. package/dashboard/dist/assets/{vendor-icons-ed7mYQw4.js → vendor-icons-D48ijXZU.js} +209 -189
  291. package/dashboard/dist/assets/vendor-icons-D48ijXZU.js.map +1 -0
  292. package/dashboard/dist/assets/{yaml-workflows-C20qHo3L.js → yaml-workflows-BQpO-G-I.js} +2 -2
  293. package/dashboard/dist/assets/{yaml-workflows-C20qHo3L.js.map → yaml-workflows-BQpO-G-I.js.map} +1 -1
  294. package/dashboard/dist/index.html +3 -3
  295. package/docs/api/http/escalations.md +54 -7
  296. package/docs/api/mcp/admin.md +7 -5
  297. package/docs/api/mcp/human-queue.md +17 -1
  298. package/docs/api/sdk/escalations.md +30 -4
  299. package/docs/api/sdk/files.md +19 -0
  300. package/docs/cli.md +4 -1
  301. package/docs/escalation-analytics.md +17 -0
  302. package/docs/hitl/files.md +104 -0
  303. package/docs/hitl/x-lt-confidence.md +139 -0
  304. package/docs/hitl/x-lt-layout.md +19 -0
  305. package/docs/hitl/x-lt-widget.md +20 -0
  306. package/docs/hitl-guide.md +6 -0
  307. package/docs/mcp.md +2 -1
  308. package/package.json +1 -1
  309. package/dashboard/dist/assets/ResolverForm-DfogHDzl.js +0 -8
  310. package/dashboard/dist/assets/ResolverForm-DfogHDzl.js.map +0 -1
  311. package/dashboard/dist/assets/TopicsPage-D8dW6J65.js +0 -2
  312. package/dashboard/dist/assets/escalation-items-BGZlJMpk.js +0 -2
  313. package/dashboard/dist/assets/escalation-items-BGZlJMpk.js.map +0 -1
  314. package/dashboard/dist/assets/index-BUmz0NMg.css +0 -1
  315. package/dashboard/dist/assets/index-C5osluV3.js +0 -2
  316. package/dashboard/dist/assets/index-C_dAJUzh.js.map +0 -1
  317. package/dashboard/dist/assets/index-Dk2KKo0z.js +0 -13
  318. package/dashboard/dist/assets/index-FiNThtNU.js +0 -3
  319. package/dashboard/dist/assets/index-FiNThtNU.js.map +0 -1
  320. package/dashboard/dist/assets/vendor-icons-ed7mYQw4.js.map +0 -1
@@ -38,6 +38,7 @@ const escalationService = __importStar(require("../../services/escalation"));
38
38
  const roleService = __importStar(require("../../services/role"));
39
39
  const schema_validator_1 = require("../../services/role/schema-validator");
40
40
  const escalation_1 = require("../../types/escalation");
41
+ const capabilities_1 = require("../../modules/capabilities");
41
42
  const helpers_1 = require("./helpers");
42
43
  // ── Create ────────────────────────────────────────────────────────────────
43
44
  /**
@@ -80,15 +81,20 @@ async function createEscalation(input, auth) {
80
81
  // stamped here — omitting it means the resolve UI renders the role's latest
81
82
  // form at fetch time.
82
83
  const metadata = input.metadata ?? {};
83
- // Lookup refs ride the envelope under a reserved key with a fixed
84
- // contract: version required — a ref pins an immutable knowledge edition,
85
- // never a moving target.
84
+ // Lookup and file refs ride the envelope under reserved keys with fixed
85
+ // contracts, checked before the row exists.
86
+ let carriesFiles = false;
86
87
  if (input.envelope) {
87
88
  try {
88
89
  const envelopeObj = JSON.parse(input.envelope);
89
- if (envelopeObj && typeof envelopeObj === 'object'
90
- && envelopeObj[escalation_1.ESCALATION_ENVELOPE_KEYS.LOOKUPS] !== undefined) {
91
- (0, escalation_1.assertLookupRefs)(envelopeObj[escalation_1.ESCALATION_ENVELOPE_KEYS.LOOKUPS]);
90
+ if (envelopeObj && typeof envelopeObj === 'object') {
91
+ if (envelopeObj[escalation_1.ESCALATION_ENVELOPE_KEYS.LOOKUPS] !== undefined) {
92
+ (0, escalation_1.assertLookupRefs)(envelopeObj[escalation_1.ESCALATION_ENVELOPE_KEYS.LOOKUPS]);
93
+ }
94
+ if (envelopeObj[escalation_1.ESCALATION_ENVELOPE_KEYS.FILES] !== undefined) {
95
+ (0, escalation_1.assertFileRefs)(envelopeObj[escalation_1.ESCALATION_ENVELOPE_KEYS.FILES]);
96
+ carriesFiles = true;
97
+ }
92
98
  }
93
99
  }
94
100
  catch (refErr) {
@@ -98,6 +104,11 @@ async function createEscalation(input, auth) {
98
104
  return { status: 400, error: refErr.message };
99
105
  }
100
106
  }
107
+ // A file ref grants every reader of the row a link to that object, so
108
+ // naming one takes the same authority as reading storage directly.
109
+ if (carriesFiles && !(await (0, capabilities_1.mayBuild)(auth))) {
110
+ return { status: 403, error: 'Referencing stored files takes builder access (superadmin or engineer)' };
111
+ }
101
112
  const metadataSchema = await roleService.getRoleMetadataSchema(role);
102
113
  if (metadataSchema) {
103
114
  let validate;
@@ -0,0 +1,18 @@
1
+ import type { LTApiResult, LTApiAuth } from '../../types/sdk';
2
+ /**
3
+ * Sign an escalation's stored files.
4
+ *
5
+ * The refs on `envelope.files` ARE the grant: any user who may read the
6
+ * escalation receives a time-limited link to exactly the files it names,
7
+ * nothing else in storage. A link lives for the ref's `expiresIn` (else the
8
+ * default), stretched to cover the reader's own live claim, within the
9
+ * configured bounds. A ref that is malformed or cannot be signed answers
10
+ * with `error`; the batch never fails.
11
+ *
12
+ * @param input.id: escalation UUID
13
+ * @param auth: authenticated user context (must hold the escalation's role)
14
+ * @returns `{ status: 200, data: { files: [{ as, path, name, contentType, url?, expiresAt?, error? }] } }`
15
+ */
16
+ export declare function getEscalationFiles(input: {
17
+ id: string;
18
+ }, auth: LTApiAuth): Promise<LTApiResult>;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getEscalationFiles = getEscalationFiles;
37
+ const escalationService = __importStar(require("../../services/escalation"));
38
+ const file_links_1 = require("../../services/escalation/file-links");
39
+ const helpers_1 = require("./helpers");
40
+ /**
41
+ * Sign an escalation's stored files.
42
+ *
43
+ * The refs on `envelope.files` ARE the grant: any user who may read the
44
+ * escalation receives a time-limited link to exactly the files it names,
45
+ * nothing else in storage. A link lives for the ref's `expiresIn` (else the
46
+ * default), stretched to cover the reader's own live claim, within the
47
+ * configured bounds. A ref that is malformed or cannot be signed answers
48
+ * with `error`; the batch never fails.
49
+ *
50
+ * @param input.id: escalation UUID
51
+ * @param auth: authenticated user context (must hold the escalation's role)
52
+ * @returns `{ status: 200, data: { files: [{ as, path, name, contentType, url?, expiresAt?, error? }] } }`
53
+ */
54
+ async function getEscalationFiles(input, auth) {
55
+ try {
56
+ const escalation = await escalationService.getEscalation(input.id);
57
+ if (!escalation) {
58
+ return { status: 404, error: 'Escalation not found' };
59
+ }
60
+ const denied = await (0, helpers_1.assertReadAccess)(auth.userId, escalation);
61
+ if (denied)
62
+ return denied;
63
+ const refs = (0, file_links_1.readFileRefs)(escalation.envelope);
64
+ if (refs.length === 0) {
65
+ return { status: 200, data: { files: [] } };
66
+ }
67
+ const files = await (0, file_links_1.signFileRefs)(refs, (0, file_links_1.claimSecondsLeft)(escalation, auth.userId));
68
+ return { status: 200, data: { files } };
69
+ }
70
+ catch (err) {
71
+ return { status: 500, error: err.message };
72
+ }
73
+ }
@@ -2,6 +2,7 @@ export { createEscalation } from './create';
2
2
  export { listEscalations, listAvailableEscalations, listDistinctTypes, listFacetKeys, listFacetValues, getEscalationStats, getStationMetrics } from './list';
3
3
  export { getEscalation, getEscalationsByWorkflowId, escalateToRole } from './single';
4
4
  export { getEscalationLookups } from './lookups';
5
+ export { getEscalationFiles } from './files';
5
6
  export { claimEscalation, releaseEscalation } from './claim';
6
7
  export { releaseExpiredClaims, updatePriority, bulkClaim, bulkAssign, bulkUnassign, bulkEscalate, bulkTriage } from './bulk';
7
8
  export { resolveEscalation, resolveBySignalKey, resolveByIds, resolveAllOrNone } from './resolve';
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.claimGroups = exports.searchByFacets = exports.bulkCancel = exports.cancelSingleEscalation = exports.resolveByMetadata = exports.claimByMetadata = exports.findByMetadata = exports.itemsView = exports.getEscalationItemsBySignalKey = exports.getEscalationItems = exports.removeItemByMetadata = exports.removeItemBySignalKey = exports.removeItem = exports.accumulateItemByMetadata = exports.accumulateItemBySignalKey = exports.accumulateItem = exports.ROSTER_SCAN_OUTCOMES = exports.runRosterScan = exports.ROSTER_ACTION_OUTCOMES = exports.runRosterAction = exports.unflagBatchItem = exports.flagBatchItem = exports.resolveBatchItemByMetadata = exports.resolveBatchItemBySignalKey = exports.resolveBatchItem = exports.resolveAllOrNone = exports.resolveByIds = exports.resolveBySignalKey = exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkUnassign = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.getEscalationLookups = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getStationMetrics = exports.getEscalationStats = exports.listFacetValues = exports.listFacetKeys = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
4
- exports.getRelatedRows = exports.getRelatedAggregates = exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = void 0;
3
+ exports.searchByFacets = exports.bulkCancel = exports.cancelSingleEscalation = exports.resolveByMetadata = exports.claimByMetadata = exports.findByMetadata = exports.itemsView = exports.getEscalationItemsBySignalKey = exports.getEscalationItems = exports.removeItemByMetadata = exports.removeItemBySignalKey = exports.removeItem = exports.accumulateItemByMetadata = exports.accumulateItemBySignalKey = exports.accumulateItem = exports.ROSTER_SCAN_OUTCOMES = exports.runRosterScan = exports.ROSTER_ACTION_OUTCOMES = exports.runRosterAction = exports.unflagBatchItem = exports.flagBatchItem = exports.resolveBatchItemByMetadata = exports.resolveBatchItemBySignalKey = exports.resolveBatchItem = exports.resolveAllOrNone = exports.resolveByIds = exports.resolveBySignalKey = exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkUnassign = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.getEscalationFiles = exports.getEscalationLookups = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getStationMetrics = exports.getEscalationStats = exports.listFacetValues = exports.listFacetKeys = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
4
+ exports.getRelatedRows = exports.getRelatedAggregates = exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = exports.claimGroups = void 0;
5
5
  var create_1 = require("./create");
6
6
  Object.defineProperty(exports, "createEscalation", { enumerable: true, get: function () { return create_1.createEscalation; } });
7
7
  var list_1 = require("./list");
@@ -18,6 +18,8 @@ Object.defineProperty(exports, "getEscalationsByWorkflowId", { enumerable: true,
18
18
  Object.defineProperty(exports, "escalateToRole", { enumerable: true, get: function () { return single_1.escalateToRole; } });
19
19
  var lookups_1 = require("./lookups");
20
20
  Object.defineProperty(exports, "getEscalationLookups", { enumerable: true, get: function () { return lookups_1.getEscalationLookups; } });
21
+ var files_1 = require("./files");
22
+ Object.defineProperty(exports, "getEscalationFiles", { enumerable: true, get: function () { return files_1.getEscalationFiles; } });
21
23
  var claim_1 = require("./claim");
22
24
  Object.defineProperty(exports, "claimEscalation", { enumerable: true, get: function () { return claim_1.claimEscalation; } });
23
25
  Object.defineProperty(exports, "releaseEscalation", { enumerable: true, get: function () { return claim_1.releaseEscalation; } });
@@ -176,12 +176,13 @@ async function resolveByMetadata(input, auth) {
176
176
  // writing; the payload validates here, then a second asserted pass claims
177
177
  // + resolves the same row with pending re-checked inside the statement.
178
178
  const enforcing = await (0, enforcement_cache_1.getEnforcingRoles)();
179
- const outcome = { ...input.metadata, resolved_by: auth.userId };
179
+ let outcome = { ...input.metadata, resolved_by: auth.userId };
180
180
  let result = await escalationService.resolveByMetadataAtomic(input.key, input.value, resolveUserId, input.resolverPayload, outcome, writeAllRoles, writeSelfRoles, enforcing.size > 0 ? [...enforcing] : null, input.assertId ?? null, input.extraFacets, input.availability);
181
181
  if (result.outcome === 'validation_required' && result.row) {
182
- const report = await (0, resolver_validation_1.checkResolverPayload)(result.row, input.resolverPayload, undefined, resolveUserId);
183
- if (report)
184
- return (0, resolve_1.validationFailure)(report);
182
+ const { violation, facets } = await (0, resolver_validation_1.assessResolverPayload)(result.row, input.resolverPayload, undefined, resolveUserId);
183
+ if (violation)
184
+ return (0, resolve_1.validationFailure)(violation);
185
+ outcome = { ...input.metadata, ...facets, resolved_by: auth.userId };
185
186
  result = await escalationService.resolveByMetadataAtomic(input.key, input.value, resolveUserId, input.resolverPayload, outcome, writeAllRoles, writeSelfRoles, null, result.row.id, input.extraFacets, input.availability);
186
187
  // The asserted row left pending between the two passes — a concurrent
187
188
  // resolution won the row; surface it as the conflict it is.
@@ -100,7 +100,7 @@ async function resolveEscalation(input, auth) {
100
100
  // the escalation's resolved form schema BEFORE any resolution path runs.
101
101
  // Costs nothing when the role does not enforce (cached role set); the
102
102
  // task-fallback envelope read only happens for enforcing roles.
103
- const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload, () => reconstructEnvelope(escalation), auth.userId);
103
+ const { violation, facets } = await (0, resolver_validation_1.assessResolverPayload)(escalation, resolverPayload, () => reconstructEnvelope(escalation), auth.userId);
104
104
  if (violation)
105
105
  return validationFailure(violation);
106
106
  // The resolver payload is stored exactly as submitted — its shape is the
@@ -111,8 +111,10 @@ async function resolveEscalation(input, auth) {
111
111
  // `resolved_by` merges into the row's GIN-indexed metadata inside the same
112
112
  // atomic resolve, making "who resolved it" `@>`-queryable without a
113
113
  // follow-up read.
114
+ // Review facets (x-lt-confidence facets) are computed by the server, so
115
+ // they win over a caller's metadata of the same name.
114
116
  const resolvedBy = await resolverIdentity(auth);
115
- const outcome = { ...metadata, resolved_by: auth.userId };
117
+ const outcome = { ...metadata, ...facets, resolved_by: auth.userId };
116
118
  // `outcome` (the outcome patch) is never written separately — it rides WITH the
117
119
  // resolverPayload to whichever path performs the resolve, so it merges inside the
118
120
  // single status='pending'-guarded UPDATE (HotMesh `resolve(metadata)`). Paths that
@@ -183,7 +185,7 @@ async function resolveBySignalKey(input, auth) {
183
185
  return { status: 404, error: 'Escalation not found' };
184
186
  // Schema enforcement — the row (envelope included) is already loaded, so
185
187
  // this costs zero extra reads beyond the cached schema.
186
- const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload, undefined, auth.userId);
188
+ const { violation, facets } = await (0, resolver_validation_1.assessResolverPayload)(escalation, resolverPayload, undefined, auth.userId);
187
189
  if (violation)
188
190
  return validationFailure(violation);
189
191
  // The payload is delivered as the signal the parked workflow's condition()
@@ -191,7 +193,7 @@ async function resolveBySignalKey(input, auth) {
191
193
  // Same provenance contract as the interactive path: identity on the signal,
192
194
  // resolved_by in the row metadata.
193
195
  const resolvedBy = await resolverIdentity(auth);
194
- const outcome = { ...metadata, resolved_by: auth.userId };
196
+ const outcome = { ...metadata, ...facets, resolved_by: auth.userId };
195
197
  return resolveViaSignalKey(escalation, resolverPayload, outcome, undefined, resolvedBy);
196
198
  }
197
199
  catch (err) {
package/build/bin/ltc.js CHANGED
@@ -210,7 +210,7 @@ escCmd.command('claim-by-facets')
210
210
  .option('--json', 'JSON output')
211
211
  .action(wrap(esc.claimByFacets));
212
212
  escCmd.command('aggregate-facets')
213
- .description('Grouped analytics over escalation intervals: membership at an instant, or dwell over a window')
213
+ .description('Grouped analytics over escalation intervals: membership at an instant, dwell over a window, or rows resolved in a window')
214
214
  .option('--role <role>', 'Single pond role')
215
215
  .option('--roles <json>', 'Multiple roles, JSON array (no role at all = every pond; global principals only)')
216
216
  .option('--entity <key>', "Entity facet key (e.g. serialNumber) — scopes to every role declaring it (the entity's system)")
@@ -223,7 +223,9 @@ escCmd.command('aggregate-facets')
223
223
  .option('--group-facets <list>', 'Comma-separated metadata keys to group by')
224
224
  .option('--as-of <iso>', 'Membership at this ISO instant (default: now; past reconstructs the live set then)')
225
225
  .option('--window <json>', 'Dwell window {"from":"...","to":"..."} — switches the measure to dwell')
226
- .option('--distinct-by <key>', 'Count DISTINCT of this facet (entities, not rows; membership only)')
226
+ .option('--resolved <json>', 'Count rows resolved in this window {"from":"...","to":"..."}; needs a role scope')
227
+ .option('--bucket <unit>', 'With --resolved: count per day, week or month (UTC)')
228
+ .option('--distinct-by <key>', 'Count DISTINCT of this facet (entities, not rows; membership and resolved)')
227
229
  .option('--live-statuses <list>', 'Comma-separated statuses considered live (default: pending)')
228
230
  .option('--order-by <json>', 'Result-group order, JSON array e.g. \'[{"field":"count","direction":"desc"}]\'')
229
231
  .option('--limit <n>', 'Max result groups')
package/build/index.d.ts CHANGED
@@ -4,6 +4,8 @@ export { registerLT, createLTInterceptor } from './services/interceptor';
4
4
  export { createLTActivityInterceptor } from './services/interceptor/activity-interceptor';
5
5
  export { executeLT } from './services/orchestrator';
6
6
  export { conditional, conditionLT, conditionalAccumulator } from './services/orchestrator/condition';
7
+ export { readConfidenceSpec, buildFormReview, summarizeReview, differsFromProposal, trancheFor, CONFIDENCE_TONES, type ConfidenceSpec, type ConfidenceTranche, type FieldReview, } from './shared/form-validation/x-lt-confidence';
8
+ export { buildReviewFacets, REVIEW_FACET_KEYS, REVIEW_OUTCOMES, type ReviewFacets, } from './shared/form-validation/x-lt-confidence-facets';
7
9
  export type { ConditionEscalationConfig, ConditionAccumulatorConfig } from './services/orchestrator/condition';
8
10
  export type { ExecuteLTOptions } from './services/orchestrator/types';
9
11
  export { JwtAuthAdapter, createAuthMiddleware, requireAuth, requireAdmin, signToken, setAuthAdapter } from './modules/auth';
package/build/index.js CHANGED
@@ -36,8 +36,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
36
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.loggerRegistry = exports.HoneycombTelemetryAdapter = exports.telemetryRegistry = exports.jsPermissions = exports.renderNatsConf = exports.NatsMessagingProvider = exports.labelTransportRegistry = exports.DELIVERY = exports.MemoryMessagingProvider = exports.messagingRegistry = exports.publishKnowledgeEvent = exports.publishAgentEvent = exports.publishWorkflowEvent = exports.publishActivityEvent = exports.publishEscalationEvent = exports.publishTaskEvent = exports.publishMilestoneEvent = exports.SocketIOEventAdapter = exports.InMemoryEventAdapter = exports.NatsEventAdapter = exports.eventRegistry = exports.ltConfig = exports.seedConfigTopics = exports.seedSystemTopics = exports.TopicService = exports.displayGtin = exports.normalizeGtin = exports.isValidGtin = exports.assertValidScanIdentityRule = exports.assertValidScanSteps = exports.assertValidScanScheme = exports.UserService = exports.ConfigService = exports.EscalationService = exports.TaskService = exports.setAuthAdapter = exports.signToken = exports.requireAdmin = exports.requireAuth = exports.createAuthMiddleware = exports.JwtAuthAdapter = exports.conditionalAccumulator = exports.conditionLT = exports.conditional = exports.executeLT = exports.createLTActivityInterceptor = exports.createLTInterceptor = exports.registerLT = exports.midnightTheme = exports.start = void 0;
40
- exports.LTExpressAdapter = exports.Machines = exports.api = exports.KnowledgeApi = exports.resolveCredential = exports.mimeFromPath = exports.getStorageBackend = exports.listOAuthConnections = exports.getFreshAccessToken = exports.createClient = exports.CallbackEventAdapter = exports.builtinMcpServerFactories = exports.getSystemAgents = exports.getSystemWorkers = exports.registerMcpTool = exports.getToolContext = exports.getActivityIdentity = exports.McpEscalationStrategy = exports.DefaultEscalationStrategy = exports.escalationStrategyRegistry = exports.McpVisionServer = exports.McpTranslationServer = exports.McpServer = exports.McpClient = exports.McpService = exports.BuiltInMcpAdapter = exports.mcpRegistry = exports.defaultMaintenanceConfig = exports.maintenanceRegistry = exports.PinoLoggerAdapter = void 0;
39
+ exports.messagingRegistry = exports.publishKnowledgeEvent = exports.publishAgentEvent = exports.publishWorkflowEvent = exports.publishActivityEvent = exports.publishEscalationEvent = exports.publishTaskEvent = exports.publishMilestoneEvent = exports.SocketIOEventAdapter = exports.InMemoryEventAdapter = exports.NatsEventAdapter = exports.eventRegistry = exports.ltConfig = exports.seedConfigTopics = exports.seedSystemTopics = exports.TopicService = exports.displayGtin = exports.normalizeGtin = exports.isValidGtin = exports.assertValidScanIdentityRule = exports.assertValidScanSteps = exports.assertValidScanScheme = exports.UserService = exports.ConfigService = exports.EscalationService = exports.TaskService = exports.setAuthAdapter = exports.signToken = exports.requireAdmin = exports.requireAuth = exports.createAuthMiddleware = exports.JwtAuthAdapter = exports.REVIEW_OUTCOMES = exports.REVIEW_FACET_KEYS = exports.buildReviewFacets = exports.CONFIDENCE_TONES = exports.trancheFor = exports.differsFromProposal = exports.summarizeReview = exports.buildFormReview = exports.readConfidenceSpec = exports.conditionalAccumulator = exports.conditionLT = exports.conditional = exports.executeLT = exports.createLTActivityInterceptor = exports.createLTInterceptor = exports.registerLT = exports.midnightTheme = exports.start = void 0;
40
+ exports.LTExpressAdapter = exports.Machines = exports.api = exports.KnowledgeApi = exports.resolveCredential = exports.mimeFromPath = exports.getStorageBackend = exports.listOAuthConnections = exports.getFreshAccessToken = exports.createClient = exports.CallbackEventAdapter = exports.builtinMcpServerFactories = exports.getSystemAgents = exports.getSystemWorkers = exports.registerMcpTool = exports.getToolContext = exports.getActivityIdentity = exports.McpEscalationStrategy = exports.DefaultEscalationStrategy = exports.escalationStrategyRegistry = exports.McpVisionServer = exports.McpTranslationServer = exports.McpServer = exports.McpClient = exports.McpService = exports.BuiltInMcpAdapter = exports.mcpRegistry = exports.defaultMaintenanceConfig = exports.maintenanceRegistry = exports.PinoLoggerAdapter = exports.loggerRegistry = exports.HoneycombTelemetryAdapter = exports.telemetryRegistry = exports.jsPermissions = exports.renderNatsConf = exports.NatsMessagingProvider = exports.labelTransportRegistry = exports.DELIVERY = exports.MemoryMessagingProvider = void 0;
41
41
  const config_1 = require("./modules/config");
42
42
  const logger_1 = require("./lib/logger");
43
43
  const midnight_1 = require("./themes/midnight");
@@ -60,6 +60,17 @@ var condition_1 = require("./services/orchestrator/condition");
60
60
  Object.defineProperty(exports, "conditional", { enumerable: true, get: function () { return condition_1.conditional; } });
61
61
  Object.defineProperty(exports, "conditionLT", { enumerable: true, get: function () { return condition_1.conditionLT; } });
62
62
  Object.defineProperty(exports, "conditionalAccumulator", { enumerable: true, get: function () { return condition_1.conditionalAccumulator; } });
63
+ var x_lt_confidence_1 = require("./shared/form-validation/x-lt-confidence");
64
+ Object.defineProperty(exports, "readConfidenceSpec", { enumerable: true, get: function () { return x_lt_confidence_1.readConfidenceSpec; } });
65
+ Object.defineProperty(exports, "buildFormReview", { enumerable: true, get: function () { return x_lt_confidence_1.buildFormReview; } });
66
+ Object.defineProperty(exports, "summarizeReview", { enumerable: true, get: function () { return x_lt_confidence_1.summarizeReview; } });
67
+ Object.defineProperty(exports, "differsFromProposal", { enumerable: true, get: function () { return x_lt_confidence_1.differsFromProposal; } });
68
+ Object.defineProperty(exports, "trancheFor", { enumerable: true, get: function () { return x_lt_confidence_1.trancheFor; } });
69
+ Object.defineProperty(exports, "CONFIDENCE_TONES", { enumerable: true, get: function () { return x_lt_confidence_1.CONFIDENCE_TONES; } });
70
+ var x_lt_confidence_facets_1 = require("./shared/form-validation/x-lt-confidence-facets");
71
+ Object.defineProperty(exports, "buildReviewFacets", { enumerable: true, get: function () { return x_lt_confidence_facets_1.buildReviewFacets; } });
72
+ Object.defineProperty(exports, "REVIEW_FACET_KEYS", { enumerable: true, get: function () { return x_lt_confidence_facets_1.REVIEW_FACET_KEYS; } });
73
+ Object.defineProperty(exports, "REVIEW_OUTCOMES", { enumerable: true, get: function () { return x_lt_confidence_facets_1.REVIEW_OUTCOMES; } });
63
74
  var auth_1 = require("./modules/auth");
64
75
  Object.defineProperty(exports, "JwtAuthAdapter", { enumerable: true, get: function () { return auth_1.JwtAuthAdapter; } });
65
76
  Object.defineProperty(exports, "createAuthMiddleware", { enumerable: true, get: function () { return auth_1.createAuthMiddleware; } });
@@ -80,6 +80,8 @@ export declare function aggregateByFacets(opts: {
80
80
  groupState?: boolean;
81
81
  asOf?: string;
82
82
  window?: string;
83
+ resolved?: string;
84
+ bucket?: string;
83
85
  distinctBy?: string;
84
86
  liveStatuses?: string;
85
87
  orderBy?: string;
@@ -236,6 +236,7 @@ async function claimByFacets(opts) {
236
236
  }
237
237
  // --- Analytics commands -------------------------------------------------------
238
238
  const AGG_COLUMNS = [
239
+ { key: 'bucket', label: 'Bucket', width: 12, format: (v) => (v ? String(v).slice(0, 10) : '') },
239
240
  { key: 'state', label: 'State', width: 16 },
240
241
  { key: 'role', label: 'Role', width: 16 },
241
242
  { key: 'subtype', label: 'Subtype', width: 16 },
@@ -275,10 +276,17 @@ async function aggregateByFacets(opts) {
275
276
  groupBy.facets = opts.groupFacets.split(',').map((s) => s.trim());
276
277
  if (opts.groupState)
277
278
  groupBy.state = true;
278
- // --window switches the measure to dwell; otherwise membership (at --as-of, default now).
279
- const measure = opts.window
280
- ? { kind: 'dwell', window: parseJsonOption('--window', opts.window) }
281
- : { kind: 'membership', ...(opts.asOf ? { asOf: opts.asOf } : {}) };
279
+ // --resolved counts rows resolved in a window, --window measures dwell;
280
+ // otherwise membership (at --as-of, default now).
281
+ if (opts.resolved && opts.window)
282
+ throw new Error('Use one of --resolved (rows resolved) or --window (dwell)');
283
+ if (opts.bucket && !opts.resolved)
284
+ throw new Error('--bucket applies to --resolved');
285
+ const measure = opts.resolved
286
+ ? { kind: 'resolved', window: parseJsonOption('--resolved', opts.resolved), ...(opts.bucket ? { bucket: opts.bucket } : {}) }
287
+ : opts.window
288
+ ? { kind: 'dwell', window: parseJsonOption('--window', opts.window) }
289
+ : { kind: 'membership', ...(opts.asOf ? { asOf: opts.asOf } : {}) };
282
290
  const body = { query, groupBy, measure };
283
291
  if (opts.distinctBy)
284
292
  body.distinctBy = opts.distinctBy;
@@ -99,6 +99,7 @@ class S3StorageBackend {
99
99
  Bucket: this.bucket,
100
100
  Key: normalizeKey(key),
101
101
  Body: data,
102
+ ContentType: (0, mime_1.mimeFromPath)(key),
102
103
  ...(options?.sha256 ? { Metadata: { [SHA256_METADATA]: options.sha256 } } : {}),
103
104
  }));
104
105
  return { ref: key, size: data.length };
@@ -38,9 +38,18 @@ export declare const config: {
38
38
  ROLE_ENFORCEMENT_CACHE_TTL_MS: number;
39
39
  LT_ANALYTICS_MAX_GROUPS: number;
40
40
  LT_ANALYTICS_MAX_WINDOW_DAYS: number;
41
+ LT_ANALYTICS_MAX_RESOLVED_WINDOW_DAYS: number;
41
42
  LT_ANALYTICS_CACHE_TTL_MS: number;
42
43
  LT_ANALYTICS_PAST_CACHE_TTL_MS: number;
43
44
  LT_ANALYTICS_CACHE_MAX_ENTRIES: number;
45
+ /**
46
+ * Escalation file links: the default signed-link lifetime, and its bounds.
47
+ * A ref's expiresIn and the reader's live claim stretch the link within
48
+ * these bounds; nothing signs past the max.
49
+ */
50
+ LT_ESCALATION_FILE_URL_TTL_SECONDS: number;
51
+ LT_ESCALATION_FILE_URL_MIN_SECONDS: number;
52
+ LT_ESCALATION_FILE_URL_MAX_SECONDS: number;
44
53
  /** Identity keys (badge tokens) leave user reads and need credentialIssuer to write. `false` keeps the earlier behavior. */
45
54
  LT_PROTECT_IDENTITY_KEYS: boolean;
46
55
  /** Label sheets: the media a job prints on when neither the job nor the template names one. */
@@ -64,9 +64,18 @@ exports.config = {
64
64
  // live longer; MAX_ENTRIES LRU-bounds the past cache.
65
65
  LT_ANALYTICS_MAX_GROUPS: parseInt(process.env.LT_ANALYTICS_MAX_GROUPS || '5000', 10),
66
66
  LT_ANALYTICS_MAX_WINDOW_DAYS: parseInt(process.env.LT_ANALYTICS_MAX_WINDOW_DAYS || '35', 10),
67
+ LT_ANALYTICS_MAX_RESOLVED_WINDOW_DAYS: parseInt(process.env.LT_ANALYTICS_MAX_RESOLVED_WINDOW_DAYS || '366', 10),
67
68
  LT_ANALYTICS_CACHE_TTL_MS: parseInt(process.env.LT_ANALYTICS_CACHE_TTL_MS || '30000', 10),
68
69
  LT_ANALYTICS_PAST_CACHE_TTL_MS: parseInt(process.env.LT_ANALYTICS_PAST_CACHE_TTL_MS || '600000', 10),
69
70
  LT_ANALYTICS_CACHE_MAX_ENTRIES: parseInt(process.env.LT_ANALYTICS_CACHE_MAX_ENTRIES || '512', 10),
71
+ /**
72
+ * Escalation file links: the default signed-link lifetime, and its bounds.
73
+ * A ref's expiresIn and the reader's live claim stretch the link within
74
+ * these bounds; nothing signs past the max.
75
+ */
76
+ LT_ESCALATION_FILE_URL_TTL_SECONDS: positiveInt('LT_ESCALATION_FILE_URL_TTL_SECONDS', 900),
77
+ LT_ESCALATION_FILE_URL_MIN_SECONDS: positiveInt('LT_ESCALATION_FILE_URL_MIN_SECONDS', 60),
78
+ LT_ESCALATION_FILE_URL_MAX_SECONDS: positiveInt('LT_ESCALATION_FILE_URL_MAX_SECONDS', 14400),
70
79
  /** Identity keys (badge tokens) leave user reads and need credentialIssuer to write. `false` keeps the earlier behavior. */
71
80
  LT_PROTECT_IDENTITY_KEYS: process.env.LT_PROTECT_IDENTITY_KEYS !== 'false',
72
81
  /** Label sheets: the media a job prints on when neither the job nor the template names one. */
@@ -67,6 +67,17 @@ function registerSingleRoutes(router) {
67
67
  const result = await api.getEscalationLookups({ id: req.params.id }, req.auth);
68
68
  res.status(result.status).json(result.data ?? { error: result.error });
69
69
  });
70
+ /**
71
+ * GET /api/escalations/:id/files
72
+ * Sign the escalation's stored files. The refs on the row are the grant:
73
+ * readers of the escalation receive time-limited links to exactly the
74
+ * files it names.
75
+ */
76
+ router.get('/:id/files', async (req, res) => {
77
+ const result = await api.getEscalationFiles({ id: req.params.id }, req.auth);
78
+ res.set('Cache-Control', 'no-store');
79
+ res.status(result.status).json(result.data ?? { error: result.error });
80
+ });
70
81
  /**
71
82
  * GET /api/escalations/:id
72
83
  * Get a single escalation by ID.
@@ -131,6 +131,9 @@ export declare function createClient(options?: LTClientOptions): {
131
131
  getLookups: (input: {
132
132
  id: string;
133
133
  }, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
134
+ getFiles: (input: {
135
+ id: string;
136
+ }, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
134
137
  getByWorkflowId: typeof escalationsApi.getEscalationsByWorkflowId;
135
138
  escalate: (input: {
136
139
  id: string;
@@ -537,6 +540,7 @@ export declare function createClient(options?: LTClientOptions): {
537
540
  getMetadata: typeof filesApi.getFileMetadata;
538
541
  delete: typeof filesApi.deleteFile;
539
542
  generateSignedUrl: typeof filesApi.generateSignedUrl;
543
+ upload: typeof filesApi.uploadFile;
540
544
  };
541
545
  knowledge: {
542
546
  listDomains: typeof knowledgeApi.listDomains;
@@ -125,6 +125,7 @@ function createClient(options = {}) {
125
125
  getStationMetrics: bindAuth(escalationsApi.getStationMetrics, auth),
126
126
  get: bindAuth(escalationsApi.getEscalation, auth),
127
127
  getLookups: bindAuth(escalationsApi.getEscalationLookups, auth),
128
+ getFiles: bindAuth(escalationsApi.getEscalationFiles, auth),
128
129
  getByWorkflowId: escalationsApi.getEscalationsByWorkflowId,
129
130
  escalate: bindAuth(escalationsApi.escalateToRole, auth),
130
131
  claim: bindAuth(escalationsApi.claimEscalation, auth),
@@ -361,6 +362,7 @@ function createClient(options = {}) {
361
362
  getMetadata: filesApi.getFileMetadata,
362
363
  delete: filesApi.deleteFile,
363
364
  generateSignedUrl: filesApi.generateSignedUrl,
365
+ upload: filesApi.uploadFile,
364
366
  },
365
367
  // ── Knowledge ─────────────────────────────────────────────────────────
366
368
  knowledge: {
@@ -0,0 +1,19 @@
1
+ import type { AnalyticsWindow, ResolvedBucket } from '../../types';
2
+ /** The bucket, validated against the closed set; it inlines into date_trunc. */
3
+ export declare function resolveBucket(bucket: unknown): ResolvedBucket | null;
4
+ export declare function buildResolvedAggregate(input: {
5
+ window: AnalyticsWindow;
6
+ bucket: ResolvedBucket | null;
7
+ where: string;
8
+ params: unknown[];
9
+ groupSelect: string[];
10
+ groupKeys: string[];
11
+ order: string;
12
+ distinctBy?: string;
13
+ pageLimit: number;
14
+ offset: number;
15
+ }): {
16
+ sql: string;
17
+ params: unknown[];
18
+ nowAnchored: boolean;
19
+ };
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // The resolved measure: rows resolved within a half-open window, counted per
4
+ // group and optionally per UTC calendar bucket. `status = 'resolved'` inlines
5
+ // as a literal and the role scope is required, so the planner reads the
6
+ // role-led idx_hmsh_esc_resolved_cover range (role, resolved_at) instead of
7
+ // sweeping every queue's history. Cost grows with the rows resolved in the
8
+ // window for the scoped roles.
9
+ // ---------------------------------------------------------------------------
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.resolveBucket = resolveBucket;
12
+ exports.buildResolvedAggregate = buildResolvedAggregate;
13
+ const config_1 = require("../../modules/config");
14
+ const aggregate_validate_1 = require("./aggregate-validate");
15
+ const types_1 = require("../../types");
16
+ /** The bucket, validated against the closed set; it inlines into date_trunc. */
17
+ function resolveBucket(bucket) {
18
+ if (bucket === undefined)
19
+ return null;
20
+ if (!types_1.RESOLVED_BUCKETS.includes(bucket)) {
21
+ throw new aggregate_validate_1.AnalyticsInputError(`measure.bucket "${String(bucket)}" is not one of ${types_1.RESOLVED_BUCKETS.join(', ')}`);
22
+ }
23
+ return bucket;
24
+ }
25
+ function buildResolvedAggregate(input) {
26
+ const win = (0, aggregate_validate_1.resolveWindow)(input.window, 'measure.window', {
27
+ days: config_1.config.LT_ANALYTICS_MAX_RESOLVED_WINDOW_DAYS,
28
+ envVar: 'LT_ANALYTICS_MAX_RESOLVED_WINDOW_DAYS',
29
+ });
30
+ if (!win)
31
+ throw new aggregate_validate_1.AnalyticsInputError('measure.window is required for resolved');
32
+ const { params } = input;
33
+ params.push(win.from.toISOString());
34
+ const fromP = `$${params.length}::timestamptz`;
35
+ params.push(win.to.toISOString());
36
+ const toP = `$${params.length}::timestamptz`;
37
+ const select = [...input.groupSelect];
38
+ const keys = [...input.groupKeys];
39
+ if (input.bucket) {
40
+ select.unshift(`(date_trunc('${input.bucket}', resolved_at AT TIME ZONE 'UTC') AT TIME ZONE 'UTC') AS bucket`);
41
+ keys.unshift('bucket');
42
+ }
43
+ const countExpr = input.distinctBy
44
+ ? `count(DISTINCT (metadata->>'${input.distinctBy}'))::int`
45
+ : 'count(*)::int';
46
+ const groupBySql = keys.length ? `GROUP BY ${keys.join(', ')}\n` : '';
47
+ params.push(input.pageLimit + 1, input.offset);
48
+ const sql = `SELECT ${[...select, `${countExpr} AS "count"`, 'count(*)::int AS sample_count'].join(',\n ')}
49
+ FROM public.lt_escalations
50
+ WHERE ${input.where}
51
+ AND status = 'resolved'
52
+ AND resolved_at >= ${fromP}
53
+ AND resolved_at < ${toP}
54
+ ${groupBySql}ORDER BY ${input.order}
55
+ LIMIT $${params.length - 1} OFFSET $${params.length}`;
56
+ return { sql, params, nowAnchored: win.nowAnchored };
57
+ }
@@ -9,10 +9,13 @@ export interface BuiltAggregateQuery {
9
9
  facets: string[];
10
10
  /** true when grouped by the derived state label (groupBy.state). */
11
11
  stateGrouped: boolean;
12
- measureKind: 'membership' | 'dwell';
12
+ measureKind: AggregateMeasureKind;
13
+ /** true when the resolved measure groups by calendar bucket. */
14
+ bucketed: boolean;
13
15
  /** true = the anchor touches now (short cache); false = fully past (immutable). */
14
16
  nowAnchored: boolean;
15
17
  }
18
+ export type AggregateMeasureKind = 'membership' | 'dwell' | 'resolved';
16
19
  /** Per-role state naming, from lt_roles.entity_state_source. */
17
20
  export type StateSources = Record<string, 'role' | 'subtype'>;
18
21
  export interface BuiltTimelineQuery {
@@ -23,6 +26,8 @@ export interface BuiltTimelineQuery {
23
26
  facets: string[];
24
27
  nowAnchored: boolean;
25
28
  }
29
+ /** The projected-facet output alias; the key is FACET_KEY-validated. */
30
+ export declare function facetAlias(key: string): string;
26
31
  /**
27
32
  * Build the grouped aggregate (membership or dwell) as one parameterized
28
33
  * query. `query.entity` must be RESOLVED by the caller before building