@hotmeshio/long-tail 0.19.1 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/build/api/workflows/config.d.ts +3 -0
  2. package/build/api/workflows/config.js +15 -0
  3. package/build/api/workflows/index.d.ts +1 -0
  4. package/build/api/workflows/index.js +3 -1
  5. package/build/api/workflows/input-lookups.d.ts +16 -0
  6. package/build/api/workflows/input-lookups.js +69 -0
  7. package/build/api/workflows/input-validation.d.ts +4 -3
  8. package/build/api/workflows/input-validation.js +7 -4
  9. package/build/api/workflows/invocable.js +1 -0
  10. package/build/api/workflows/invocation.js +1 -1
  11. package/build/lib/db/schemas/035_workflow_input_lookups.sql +9 -0
  12. package/build/routes/workflows/config.js +10 -0
  13. package/build/services/config/cache.js +1 -0
  14. package/build/services/config/read.js +2 -0
  15. package/build/services/config/sql.d.ts +2 -2
  16. package/build/services/config/sql.js +6 -5
  17. package/build/services/config/write.js +10 -1
  18. package/build/services/knowledge/index.d.ts +1 -0
  19. package/build/services/knowledge/index.js +1 -0
  20. package/build/services/knowledge/lookup-refs.d.ts +7 -0
  21. package/build/services/knowledge/lookup-refs.js +26 -0
  22. package/build/services/mcp/db-server/schemas.d.ts +2 -2
  23. package/build/shared/form-validation/field-validator.d.ts +1 -0
  24. package/build/shared/form-validation/field-validator.js +94 -6
  25. package/build/shared/form-validation/invoke-context.d.ts +4 -3
  26. package/build/shared/form-validation/invoke-context.js +5 -4
  27. package/build/shared/form-validation/x-lt-options.d.ts +3 -3
  28. package/build/shared/form-validation/x-lt-options.js +19 -5
  29. package/build/shared/form-validation/x-lt-show-if.d.ts +5 -0
  30. package/build/shared/form-validation/x-lt-show-if.js +10 -0
  31. package/build/start/workers.js +10 -0
  32. package/build/system/mcp-servers/admin/schemas.d.ts +64 -20
  33. package/build/system/mcp-servers/admin/schemas.js +19 -3
  34. package/build/system/mcp-servers/admin/workflow-config.js +54 -9
  35. package/build/system/mcp-servers/admin/workflows.js +9 -7
  36. package/build/system/mcp-servers/db-query/schemas.d.ts +2 -2
  37. package/build/system/seed/tool-manifests-admin.d.ts +517 -54
  38. package/build/system/seed/tool-manifests-admin.js +4 -3
  39. package/build/tsconfig.tsbuildinfo +1 -1
  40. package/build/types/config.d.ts +4 -0
  41. package/build/types/startup.d.ts +6 -0
  42. package/dashboard/dist/assets/{AdminDashboard-Drs-9TRM.js → AdminDashboard-DplvDBti.js} +2 -2
  43. package/dashboard/dist/assets/{AdminDashboard-Drs-9TRM.js.map → AdminDashboard-DplvDBti.js.map} +1 -1
  44. package/dashboard/dist/assets/{AgentConfigPage-BDPDZ7-v.js → AgentConfigPage-D8Bf6YxO.js} +2 -2
  45. package/dashboard/dist/assets/{AgentConfigPage-BDPDZ7-v.js.map → AgentConfigPage-D8Bf6YxO.js.map} +1 -1
  46. package/dashboard/dist/assets/{AgentDetailPage-CGBulM4_.js → AgentDetailPage-BN8g0Y2G.js} +2 -2
  47. package/dashboard/dist/assets/{AgentDetailPage-CGBulM4_.js.map → AgentDetailPage-BN8g0Y2G.js.map} +1 -1
  48. package/dashboard/dist/assets/{AgentsPage-D77JeViQ.js → AgentsPage-7JJBHku8.js} +2 -2
  49. package/dashboard/dist/assets/{AgentsPage-D77JeViQ.js.map → AgentsPage-7JJBHku8.js.map} +1 -1
  50. package/dashboard/dist/assets/{AvailableEscalationsPage-CqM_MOMy.js → AvailableEscalationsPage-lz5qwSjg.js} +2 -2
  51. package/dashboard/dist/assets/{AvailableEscalationsPage-CqM_MOMy.js.map → AvailableEscalationsPage-lz5qwSjg.js.map} +1 -1
  52. package/dashboard/dist/assets/{BotPicker-CC5vI_Sv.js → BotPicker-CGCnIz8I.js} +2 -2
  53. package/dashboard/dist/assets/{BotPicker-CC5vI_Sv.js.map → BotPicker-CGCnIz8I.js.map} +1 -1
  54. package/dashboard/dist/assets/{BulkAssignModal-BXiJnlqt.js → BulkAssignModal-NJBcoj-f.js} +2 -2
  55. package/dashboard/dist/assets/{BulkAssignModal-BXiJnlqt.js.map → BulkAssignModal-NJBcoj-f.js.map} +1 -1
  56. package/dashboard/dist/assets/{CapabilitiesPage-D9TC2iKy.js → CapabilitiesPage-F8dpNn9B.js} +2 -2
  57. package/dashboard/dist/assets/{CapabilitiesPage-D9TC2iKy.js.map → CapabilitiesPage-F8dpNn9B.js.map} +1 -1
  58. package/dashboard/dist/assets/{CollapsibleSection-D10lGw_u.js → CollapsibleSection-BZW6VpCU.js} +2 -2
  59. package/dashboard/dist/assets/{CollapsibleSection-D10lGw_u.js.map → CollapsibleSection-BZW6VpCU.js.map} +1 -1
  60. package/dashboard/dist/assets/{ConfirmDeleteModal-BJdLN6No.js → ConfirmDeleteModal-64adXLdq.js} +2 -2
  61. package/dashboard/dist/assets/{ConfirmDeleteModal-BJdLN6No.js.map → ConfirmDeleteModal-64adXLdq.js.map} +1 -1
  62. package/dashboard/dist/assets/{CountdownTimer-D9B-BjQ7.js → CountdownTimer-BxDub9d2.js} +2 -2
  63. package/dashboard/dist/assets/{CountdownTimer-D9B-BjQ7.js.map → CountdownTimer-BxDub9d2.js.map} +1 -1
  64. package/dashboard/dist/assets/{CredentialsPage-hniUAFBK.js → CredentialsPage-CnLzopLL.js} +2 -2
  65. package/dashboard/dist/assets/{CredentialsPage-hniUAFBK.js.map → CredentialsPage-CnLzopLL.js.map} +1 -1
  66. package/dashboard/dist/assets/{CronLabel-v9DCD2FX.js → CronLabel-CAD5UYDT.js} +2 -2
  67. package/dashboard/dist/assets/{CronLabel-v9DCD2FX.js.map → CronLabel-CAD5UYDT.js.map} +1 -1
  68. package/dashboard/dist/assets/{ElapsedCell-_xvVTK8N.js → ElapsedCell-CwO4ufd0.js} +2 -2
  69. package/dashboard/dist/assets/{ElapsedCell-_xvVTK8N.js.map → ElapsedCell-CwO4ufd0.js.map} +1 -1
  70. package/dashboard/dist/assets/{EntityTimelinePanel-1lT3jkCM.js → EntityTimelinePanel-CkF-oW-m.js} +2 -2
  71. package/dashboard/dist/assets/{EntityTimelinePanel-1lT3jkCM.js.map → EntityTimelinePanel-CkF-oW-m.js.map} +1 -1
  72. package/dashboard/dist/assets/{EscalationListSchemaPage-BeQUTUEO.js → EscalationListSchemaPage-h9JO_q5f.js} +2 -2
  73. package/dashboard/dist/assets/{EscalationListSchemaPage-BeQUTUEO.js.map → EscalationListSchemaPage-h9JO_q5f.js.map} +1 -1
  74. package/dashboard/dist/assets/{EscalationListView-uuZRMSLB.js → EscalationListView-AHW2xtlr.js} +2 -2
  75. package/dashboard/dist/assets/{EscalationListView-uuZRMSLB.js.map → EscalationListView-AHW2xtlr.js.map} +1 -1
  76. package/dashboard/dist/assets/{EscalationSchemaPage-D4VlEwyS.js → EscalationSchemaPage-mJFL5_Se.js} +2 -2
  77. package/dashboard/dist/assets/{EscalationSchemaPage-D4VlEwyS.js.map → EscalationSchemaPage-mJFL5_Se.js.map} +1 -1
  78. package/dashboard/dist/assets/{EscalationsOverview-Bx6Zrzm-.js → EscalationsOverview-DlXUFqWJ.js} +2 -2
  79. package/dashboard/dist/assets/{EscalationsOverview-Bx6Zrzm-.js.map → EscalationsOverview-DlXUFqWJ.js.map} +1 -1
  80. package/dashboard/dist/assets/{EventTable-KEC3YWBf.js → EventTable-Ike2xchn.js} +2 -2
  81. package/dashboard/dist/assets/{EventTable-KEC3YWBf.js.map → EventTable-Ike2xchn.js.map} +1 -1
  82. package/dashboard/dist/assets/{FilterBar-xwN_b5fj.js → FilterBar-DMOR-O1c.js} +2 -2
  83. package/dashboard/dist/assets/{FilterBar-xwN_b5fj.js.map → FilterBar-DMOR-O1c.js.map} +1 -1
  84. package/dashboard/dist/assets/{GraphInvokePage-DV7Y0fe2.js → GraphInvokePage-CKtvWowP.js} +2 -2
  85. package/dashboard/dist/assets/{GraphInvokePage-DV7Y0fe2.js.map → GraphInvokePage-CKtvWowP.js.map} +1 -1
  86. package/dashboard/dist/assets/{HomePage-G785SWcW.js → HomePage-BQ3Q791Q.js} +2 -2
  87. package/dashboard/dist/assets/{HomePage-G785SWcW.js.map → HomePage-BQ3Q791Q.js.map} +1 -1
  88. package/dashboard/dist/assets/{ListToolbar-zPVYPg3W.js → ListToolbar-DdJzj472.js} +2 -2
  89. package/dashboard/dist/assets/{ListToolbar-zPVYPg3W.js.map → ListToolbar-DdJzj472.js.map} +1 -1
  90. package/dashboard/dist/assets/{McpOverview-CMGUq8hx.js → McpOverview-BbtrduWn.js} +2 -2
  91. package/dashboard/dist/assets/{McpOverview-CMGUq8hx.js.map → McpOverview-BbtrduWn.js.map} +1 -1
  92. package/dashboard/dist/assets/{McpQueryDetailPage-CdhLhaKn.js → McpQueryDetailPage-C1L4T-Wt.js} +2 -2
  93. package/dashboard/dist/assets/{McpQueryDetailPage-CdhLhaKn.js.map → McpQueryDetailPage-C1L4T-Wt.js.map} +1 -1
  94. package/dashboard/dist/assets/{McpQueryPage-CNSNMagY.js → McpQueryPage-CfJy7HZ7.js} +2 -2
  95. package/dashboard/dist/assets/{McpQueryPage-CNSNMagY.js.map → McpQueryPage-CfJy7HZ7.js.map} +1 -1
  96. package/dashboard/dist/assets/{McpRunDetailPage-DBm8hUaW.js → McpRunDetailPage-CA9yv7he.js} +2 -2
  97. package/dashboard/dist/assets/{McpRunDetailPage-DBm8hUaW.js.map → McpRunDetailPage-CA9yv7he.js.map} +1 -1
  98. package/dashboard/dist/assets/{McpRunsPage-B6rb5QBf.js → McpRunsPage-D7QXjW9z.js} +2 -2
  99. package/dashboard/dist/assets/{McpRunsPage-B6rb5QBf.js.map → McpRunsPage-D7QXjW9z.js.map} +1 -1
  100. package/dashboard/dist/assets/{OperationsPage-Dxk1fAMg.js → OperationsPage-aLHHAP2X.js} +2 -2
  101. package/dashboard/dist/assets/{OperationsPage-Dxk1fAMg.js.map → OperationsPage-aLHHAP2X.js.map} +1 -1
  102. package/dashboard/dist/assets/{OperatorDashboard-DBOscDnf.js → OperatorDashboard-sXNDh1Ph.js} +2 -2
  103. package/dashboard/dist/assets/{OperatorDashboard-DBOscDnf.js.map → OperatorDashboard-sXNDh1Ph.js.map} +1 -1
  104. package/dashboard/dist/assets/{PersonaDetailPage-BGRdGpeR.js → PersonaDetailPage-NeHD-Gra.js} +2 -2
  105. package/dashboard/dist/assets/{PersonaDetailPage-BGRdGpeR.js.map → PersonaDetailPage-NeHD-Gra.js.map} +1 -1
  106. package/dashboard/dist/assets/{PersonasPage-DRzOZcVa.js → PersonasPage-DavKXRWX.js} +2 -2
  107. package/dashboard/dist/assets/{PersonasPage-DRzOZcVa.js.map → PersonasPage-DavKXRWX.js.map} +1 -1
  108. package/dashboard/dist/assets/{ProcessDetailPage-BLGjZXpM.js → ProcessDetailPage-DkdKJGe6.js} +2 -2
  109. package/dashboard/dist/assets/{ProcessDetailPage-BLGjZXpM.js.map → ProcessDetailPage-DkdKJGe6.js.map} +1 -1
  110. package/dashboard/dist/assets/{ProcessesListPage-5NnysKFC.js → ProcessesListPage-CjwVKe32.js} +2 -2
  111. package/dashboard/dist/assets/{ProcessesListPage-5NnysKFC.js.map → ProcessesListPage-CjwVKe32.js.map} +1 -1
  112. package/dashboard/dist/assets/ResolverForm-Bk-wDkN-.js +3 -0
  113. package/dashboard/dist/assets/ResolverForm-Bk-wDkN-.js.map +1 -0
  114. package/dashboard/dist/assets/{RoleDetailPage-C_LIoe1j.js → RoleDetailPage-WQt0y5l7.js} +3 -3
  115. package/dashboard/dist/assets/{RoleDetailPage-C_LIoe1j.js.map → RoleDetailPage-WQt0y5l7.js.map} +1 -1
  116. package/dashboard/dist/assets/{RolesPage-BmW1LzkU.js → RolesPage-OM9KM8Pg.js} +2 -2
  117. package/dashboard/dist/assets/{RolesPage-BmW1LzkU.js.map → RolesPage-OM9KM8Pg.js.map} +1 -1
  118. package/dashboard/dist/assets/{RunAsSelector-BwZTJ4Yj.js → RunAsSelector-fFMt1bGe.js} +2 -2
  119. package/dashboard/dist/assets/{RunAsSelector-BwZTJ4Yj.js.map → RunAsSelector-fFMt1bGe.js.map} +1 -1
  120. package/dashboard/dist/assets/ScanCodesPage-AujH-pPQ.js +2 -0
  121. package/dashboard/dist/assets/{ScanCodesPage-FiYIYB-m.js.map → ScanCodesPage-AujH-pPQ.js.map} +1 -1
  122. package/dashboard/dist/assets/{ScanSchemeDetailPage-BiAqtD-a.js → ScanSchemeDetailPage-eKQpmsC_.js} +2 -2
  123. package/dashboard/dist/assets/{ScanSchemeDetailPage-BiAqtD-a.js.map → ScanSchemeDetailPage-eKQpmsC_.js.map} +1 -1
  124. package/dashboard/dist/assets/{ScanStationPage-8CdOtbCD.js → ScanStationPage-C1_ppDoZ.js} +2 -2
  125. package/dashboard/dist/assets/{ScanStationPage-8CdOtbCD.js.map → ScanStationPage-C1_ppDoZ.js.map} +1 -1
  126. package/dashboard/dist/assets/{StickyPagination-DRuqKhZt.js → StickyPagination-B91Pk9xh.js} +2 -2
  127. package/dashboard/dist/assets/{StickyPagination-DRuqKhZt.js.map → StickyPagination-B91Pk9xh.js.map} +1 -1
  128. package/dashboard/dist/assets/{StreamMessageDetail-JwlbRiMn.js → StreamMessageDetail-C7SPqaJt.js} +2 -2
  129. package/dashboard/dist/assets/{StreamMessageDetail-JwlbRiMn.js.map → StreamMessageDetail-C7SPqaJt.js.map} +1 -1
  130. package/dashboard/dist/assets/{SwimlaneTimeline-hu3c4bCJ.js → SwimlaneTimeline-BcHR8ylf.js} +2 -2
  131. package/dashboard/dist/assets/{SwimlaneTimeline-hu3c4bCJ.js.map → SwimlaneTimeline-BcHR8ylf.js.map} +1 -1
  132. package/dashboard/dist/assets/{TaskDetailPage-NqVZF3jW.js → TaskDetailPage-Bqj0I_I0.js} +2 -2
  133. package/dashboard/dist/assets/{TaskDetailPage-NqVZF3jW.js.map → TaskDetailPage-Bqj0I_I0.js.map} +1 -1
  134. package/dashboard/dist/assets/{TasksListPage-BQNaSzCn.js → TasksListPage-BB1f79lL.js} +2 -2
  135. package/dashboard/dist/assets/{TasksListPage-BQNaSzCn.js.map → TasksListPage-BB1f79lL.js.map} +1 -1
  136. package/dashboard/dist/assets/{TimeAgo-Cv35DOiI.js → TimeAgo-BFnODmNe.js} +2 -2
  137. package/dashboard/dist/assets/{TimeAgo-Cv35DOiI.js.map → TimeAgo-BFnODmNe.js.map} +1 -1
  138. package/dashboard/dist/assets/{TimestampCell-DHUXey9s.js → TimestampCell-BXgLOBsr.js} +2 -2
  139. package/dashboard/dist/assets/{TimestampCell-DHUXey9s.js.map → TimestampCell-BXgLOBsr.js.map} +1 -1
  140. package/dashboard/dist/assets/{ToolTestPanel-DvuLFWqQ.js → ToolTestPanel-Bwe3J5lj.js} +2 -2
  141. package/dashboard/dist/assets/{ToolTestPanel-DvuLFWqQ.js.map → ToolTestPanel-Bwe3J5lj.js.map} +1 -1
  142. package/dashboard/dist/assets/{TopicDetailPage-TXX3QNSo.js → TopicDetailPage-DAF07vZ9.js} +2 -2
  143. package/dashboard/dist/assets/{TopicDetailPage-TXX3QNSo.js.map → TopicDetailPage-DAF07vZ9.js.map} +1 -1
  144. package/dashboard/dist/assets/{TopicsPage-h-oyTeEJ.js → TopicsPage-C1gxBUap.js} +2 -2
  145. package/dashboard/dist/assets/{TopicsPage-h-oyTeEJ.js.map → TopicsPage-C1gxBUap.js.map} +1 -1
  146. package/dashboard/dist/assets/{UserName-BceRCeDF.js → UserName-BzXJUE6q.js} +2 -2
  147. package/dashboard/dist/assets/{UserName-BceRCeDF.js.map → UserName-BzXJUE6q.js.map} +1 -1
  148. package/dashboard/dist/assets/{WorkflowExecutionPage-CmHGcaN9.js → WorkflowExecutionPage-SkRU5cRX.js} +2 -2
  149. package/dashboard/dist/assets/{WorkflowExecutionPage-CmHGcaN9.js.map → WorkflowExecutionPage-SkRU5cRX.js.map} +1 -1
  150. package/dashboard/dist/assets/{WorkflowsDashboard-B0r2lQXk.js → WorkflowsDashboard-CZAqRk1N.js} +2 -2
  151. package/dashboard/dist/assets/{WorkflowsDashboard-B0r2lQXk.js.map → WorkflowsDashboard-CZAqRk1N.js.map} +1 -1
  152. package/dashboard/dist/assets/{WorkflowsOverview-BTMc2PJ_.js → WorkflowsOverview-BoN44VTE.js} +2 -2
  153. package/dashboard/dist/assets/{WorkflowsOverview-BTMc2PJ_.js.map → WorkflowsOverview-BoN44VTE.js.map} +1 -1
  154. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DUiCVnZp.js → YamlWorkflowDetailPage-CqjhtdJf.js} +2 -2
  155. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DUiCVnZp.js.map → YamlWorkflowDetailPage-CqjhtdJf.js.map} +1 -1
  156. package/dashboard/dist/assets/{YamlWorkflowsPage-BAuXfwi0.js → YamlWorkflowsPage-CwnJkzyb.js} +2 -2
  157. package/dashboard/dist/assets/{YamlWorkflowsPage-BAuXfwi0.js.map → YamlWorkflowsPage-CwnJkzyb.js.map} +1 -1
  158. package/dashboard/dist/assets/{agents-BvmLCk4h.js → agents-gV0Ys-sY.js} +2 -2
  159. package/dashboard/dist/assets/{agents-BvmLCk4h.js.map → agents-gV0Ys-sY.js.map} +1 -1
  160. package/dashboard/dist/assets/{bots-f_tyhl4I.js → bots-B97itB3I.js} +2 -2
  161. package/dashboard/dist/assets/{bots-f_tyhl4I.js.map → bots-B97itB3I.js.map} +1 -1
  162. package/dashboard/dist/assets/{capabilities-DNo5bqLx.js → capabilities-CR9xZgGd.js} +2 -2
  163. package/dashboard/dist/assets/{capabilities-DNo5bqLx.js.map → capabilities-CR9xZgGd.js.map} +1 -1
  164. package/dashboard/dist/assets/{controlplane-Dyyj2Irb.js → controlplane-YxvP1KCa.js} +2 -2
  165. package/dashboard/dist/assets/{controlplane-Dyyj2Irb.js.map → controlplane-YxvP1KCa.js.map} +1 -1
  166. package/dashboard/dist/assets/{escalation-columns-DIigeTOK.js → escalation-columns-uq-IV2aj.js} +2 -2
  167. package/dashboard/dist/assets/{escalation-columns-DIigeTOK.js.map → escalation-columns-uq-IV2aj.js.map} +1 -1
  168. package/dashboard/dist/assets/index-3ezfWLkE.js +6 -0
  169. package/dashboard/dist/assets/index-3ezfWLkE.js.map +1 -0
  170. package/dashboard/dist/assets/{index-CsKiRyhy.js → index-B9BBCqLI.js} +2 -2
  171. package/dashboard/dist/assets/{index-CsKiRyhy.js.map → index-B9BBCqLI.js.map} +1 -1
  172. package/dashboard/dist/assets/{index-DL83W7Gu.js → index-BQpV-DTG.js} +2 -2
  173. package/dashboard/dist/assets/{index-DL83W7Gu.js.map → index-BQpV-DTG.js.map} +1 -1
  174. package/dashboard/dist/assets/index-Bp9KBLT5.js +2 -0
  175. package/dashboard/dist/assets/{index-D7ESqn22.js.map → index-Bp9KBLT5.js.map} +1 -1
  176. package/dashboard/dist/assets/{index-DvxxrFBo.js → index-CFbo9FU9.js} +2 -2
  177. package/dashboard/dist/assets/{index-DvxxrFBo.js.map → index-CFbo9FU9.js.map} +1 -1
  178. package/dashboard/dist/assets/{index-e2X-s0EQ.js → index-CIpHj4di.js} +2 -2
  179. package/dashboard/dist/assets/{index-e2X-s0EQ.js.map → index-CIpHj4di.js.map} +1 -1
  180. package/dashboard/dist/assets/{index-BMlQYOE1.js → index-CIwlVfvV.js} +10 -10
  181. package/dashboard/dist/assets/index-CIwlVfvV.js.map +1 -0
  182. package/dashboard/dist/assets/{index-BNZknxFY.js → index-CUZ6LYye.js} +2 -2
  183. package/dashboard/dist/assets/{index-BNZknxFY.js.map → index-CUZ6LYye.js.map} +1 -1
  184. package/dashboard/dist/assets/index-Cfvkl2J0.js +13 -0
  185. package/dashboard/dist/assets/index-Cfvkl2J0.js.map +1 -0
  186. package/dashboard/dist/assets/{index-DWse7ERF.js → index-DMeaiKgf.js} +2 -2
  187. package/dashboard/dist/assets/{index-DWse7ERF.js.map → index-DMeaiKgf.js.map} +1 -1
  188. package/dashboard/dist/assets/{index-C-Xr2V3F.js → index-DwOnWeu8.js} +2 -2
  189. package/dashboard/dist/assets/{index-C-Xr2V3F.js.map → index-DwOnWeu8.js.map} +1 -1
  190. package/dashboard/dist/assets/index-SGyrXGp8.js +3 -0
  191. package/dashboard/dist/assets/{index-CegPUKpc.js.map → index-SGyrXGp8.js.map} +1 -1
  192. package/dashboard/dist/assets/{index-PcyGjmBm.js → index-ipqwPavs.js} +2 -2
  193. package/dashboard/dist/assets/{index-PcyGjmBm.js.map → index-ipqwPavs.js.map} +1 -1
  194. package/dashboard/dist/assets/invoke-context-DrVyUEfs.js +2 -0
  195. package/dashboard/dist/assets/invoke-context-DrVyUEfs.js.map +1 -0
  196. package/dashboard/dist/assets/{knowledge-Coo6CKzo.js → knowledge-XX6cW4Ob.js} +2 -2
  197. package/dashboard/dist/assets/{knowledge-Coo6CKzo.js.map → knowledge-XX6cW4Ob.js.map} +1 -1
  198. package/dashboard/dist/assets/{mcp-Cz5eFnP_.js → mcp-CH13hNH2.js} +2 -2
  199. package/dashboard/dist/assets/{mcp-Cz5eFnP_.js.map → mcp-CH13hNH2.js.map} +1 -1
  200. package/dashboard/dist/assets/{mcp-query-BtnuO4LF.js → mcp-query-Duydd3JA.js} +2 -2
  201. package/dashboard/dist/assets/{mcp-query-BtnuO4LF.js.map → mcp-query-Duydd3JA.js.map} +1 -1
  202. package/dashboard/dist/assets/{personas-C2-LgpHQ.js → personas-mDk4lLQS.js} +2 -2
  203. package/dashboard/dist/assets/{personas-C2-LgpHQ.js.map → personas-mDk4lLQS.js.map} +1 -1
  204. package/dashboard/dist/assets/{pipelines-TuXQvUA-.js → pipelines-B5GcgCeF.js} +2 -2
  205. package/dashboard/dist/assets/{pipelines-TuXQvUA-.js.map → pipelines-B5GcgCeF.js.map} +1 -1
  206. package/dashboard/dist/assets/{resolver-payload-C1dXB3n6.js → resolver-payload-m9AGKZ3a.js} +2 -2
  207. package/dashboard/dist/assets/{resolver-payload-C1dXB3n6.js.map → resolver-payload-m9AGKZ3a.js.map} +1 -1
  208. package/dashboard/dist/assets/{tasks-OUzpu__z.js → tasks-CItmNsRp.js} +2 -2
  209. package/dashboard/dist/assets/{tasks-OUzpu__z.js.map → tasks-CItmNsRp.js.map} +1 -1
  210. package/dashboard/dist/assets/{topics-B8bdrBaW.js → topics-CJYG7BX5.js} +2 -2
  211. package/dashboard/dist/assets/{topics-B8bdrBaW.js.map → topics-CJYG7BX5.js.map} +1 -1
  212. package/dashboard/dist/assets/{useDebouncedValue-Cp5ZOtVE.js → useDebouncedValue-BrwgXcp8.js} +2 -2
  213. package/dashboard/dist/assets/{useDebouncedValue-Cp5ZOtVE.js.map → useDebouncedValue-BrwgXcp8.js.map} +1 -1
  214. package/dashboard/dist/assets/{useNamespace-DtQe3wZ5.js → useNamespace-CHty0HAS.js} +2 -2
  215. package/dashboard/dist/assets/{useNamespace-DtQe3wZ5.js.map → useNamespace-CHty0HAS.js.map} +1 -1
  216. package/dashboard/dist/assets/{useYamlActivityEvents-CS22c15X.js → useYamlActivityEvents-CoTsia7t.js} +2 -2
  217. package/dashboard/dist/assets/{useYamlActivityEvents-CS22c15X.js.map → useYamlActivityEvents-CoTsia7t.js.map} +1 -1
  218. package/dashboard/dist/assets/{yaml-workflows-HQIki3hI.js → yaml-workflows-CiWwx5rM.js} +2 -2
  219. package/dashboard/dist/assets/{yaml-workflows-HQIki3hI.js.map → yaml-workflows-CiWwx5rM.js.map} +1 -1
  220. package/dashboard/dist/index.html +1 -1
  221. package/docs/api/http/workflows.md +28 -1
  222. package/docs/api/mcp/admin.md +40 -4
  223. package/docs/code-owned-configuration.md +1 -1
  224. package/docs/dashboard.md +1 -1
  225. package/docs/design-principles.md +6 -5
  226. package/docs/hitl/form.md +12 -7
  227. package/docs/hitl/invoke-form.md +6 -3
  228. package/docs/hitl/lookups.md +21 -0
  229. package/docs/hitl/x-lt-validation.md +50 -3
  230. package/docs/hitl/x-lt-widget.md +21 -0
  231. package/docs/hitl-guide.md +5 -2
  232. package/package.json +1 -1
  233. package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js +0 -2
  234. package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js.map +0 -1
  235. package/dashboard/dist/assets/ScanCodesPage-FiYIYB-m.js +0 -2
  236. package/dashboard/dist/assets/index-BMlQYOE1.js.map +0 -1
  237. package/dashboard/dist/assets/index-CegPUKpc.js +0 -3
  238. package/dashboard/dist/assets/index-D7ESqn22.js +0 -2
  239. package/dashboard/dist/assets/index-DPLssnMW.js +0 -6
  240. package/dashboard/dist/assets/index-DPLssnMW.js.map +0 -1
  241. package/dashboard/dist/assets/index-DoETPlJP.js +0 -11
  242. package/dashboard/dist/assets/index-DoETPlJP.js.map +0 -1
  243. package/dashboard/dist/assets/seed-form-json-DvPsISxD.js +0 -2
  244. package/dashboard/dist/assets/seed-form-json-DvPsISxD.js.map +0 -1
@@ -1,3 +1,4 @@
1
+ import { type EscalationLookupRef } from '../../types/escalation';
1
2
  import type { LTApiResult } from '../../types/sdk';
2
3
  /**
3
4
  * List all registered workflow configurations.
@@ -38,6 +39,7 @@ export declare function getWorkflowConfig(input: {
38
39
  * @param input.envelope_schema — JSON template that pre-fills the invoke form
39
40
  * @param input.input_schema — x-lt-* JSON Schema for the rich invoke form; invoke validates data against it
40
41
  * @param input.icon — curated icon name (WORKFLOW_ICONS); anything else is refused
42
+ * @param input.input_lookups: versioned knowledge refs the invoke form reads as `lookup.<as ?? key>`; malformed refs are refused
41
43
  * @param input.resolver_schema — JSON Schema for resolver payload validation
42
44
  * @param input.cron_schedule — cron expression for scheduled execution
43
45
  * @returns `{ status: 200, data: <saved config> }`
@@ -57,6 +59,7 @@ export declare function upsertWorkflowConfig(input: {
57
59
  envelope_schema?: any;
58
60
  input_schema?: any;
59
61
  icon?: string | null;
62
+ input_lookups?: EscalationLookupRef[] | null;
60
63
  resolver_schema?: any;
61
64
  cron_schedule?: string | null;
62
65
  read_safe?: boolean;
@@ -39,6 +39,8 @@ exports.upsertWorkflowConfig = upsertWorkflowConfig;
39
39
  exports.deleteWorkflowConfig = deleteWorkflowConfig;
40
40
  const configService = __importStar(require("../../services/config"));
41
41
  const workflow_icons_1 = require("../../types/workflow-icons");
42
+ const escalation_1 = require("../../types/escalation");
43
+ const lookup_refs_1 = require("../../services/knowledge/lookup-refs");
42
44
  const cron_1 = require("../../services/cron");
43
45
  const ltconfig_1 = require("../../modules/ltconfig");
44
46
  /**
@@ -97,6 +99,7 @@ async function getWorkflowConfig(input) {
97
99
  * @param input.envelope_schema — JSON template that pre-fills the invoke form
98
100
  * @param input.input_schema — x-lt-* JSON Schema for the rich invoke form; invoke validates data against it
99
101
  * @param input.icon — curated icon name (WORKFLOW_ICONS); anything else is refused
102
+ * @param input.input_lookups: versioned knowledge refs the invoke form reads as `lookup.<as ?? key>`; malformed refs are refused
100
103
  * @param input.resolver_schema — JSON Schema for resolver payload validation
101
104
  * @param input.cron_schedule — cron expression for scheduled execution
102
105
  * @returns `{ status: 200, data: <saved config> }`
@@ -106,6 +109,17 @@ async function upsertWorkflowConfig(input) {
106
109
  if (input.icon && !(0, workflow_icons_1.isWorkflowIcon)(input.icon)) {
107
110
  return { status: 400, error: `Unknown workflow icon "${input.icon}"; choose one of WORKFLOW_ICONS` };
108
111
  }
112
+ if (input.input_lookups != null) {
113
+ try {
114
+ (0, escalation_1.assertLookupRefs)(input.input_lookups);
115
+ }
116
+ catch (err) {
117
+ return { status: 400, error: err.message };
118
+ }
119
+ const missing = await (0, lookup_refs_1.describeMissingLookupRefs)(input.input_lookups);
120
+ if (missing.length)
121
+ return { status: 400, error: missing.join('; ') };
122
+ }
109
123
  // Validate cron expression before persisting
110
124
  if (input.cron_schedule) {
111
125
  const { validateCronSchedule } = await Promise.resolve().then(() => __importStar(require('../../services/cron')));
@@ -126,6 +140,7 @@ async function upsertWorkflowConfig(input) {
126
140
  envelope_schema: input.envelope_schema ?? null,
127
141
  input_schema: input.input_schema ?? null,
128
142
  icon: input.icon ?? null,
143
+ input_lookups: input.input_lookups ?? null,
129
144
  resolver_schema: input.resolver_schema ?? null,
130
145
  cron_schedule: input.cron_schedule ?? null,
131
146
  read_safe: input.read_safe ?? false,
@@ -3,4 +3,5 @@ export { listWorkers, listDiscoveredWorkflows, getCronStatus, } from './discover
3
3
  export { listInvocableWorkflows, WORKFLOW_TIERS } from './invocable';
4
4
  export type { InvocableWorkflowEntry, WorkflowTier } from './invocable';
5
5
  export { checkInvokeInput, inputValidationFailure } from './input-validation';
6
+ export { getWorkflowInputLookups } from './input-lookups';
6
7
  export { listWorkflowConfigs, getWorkflowConfig, upsertWorkflowConfig, deleteWorkflowConfig, } from './config';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.deleteWorkflowConfig = exports.upsertWorkflowConfig = exports.getWorkflowConfig = exports.listWorkflowConfigs = exports.inputValidationFailure = exports.checkInvokeInput = exports.WORKFLOW_TIERS = exports.listInvocableWorkflows = exports.getCronStatus = exports.listDiscoveredWorkflows = exports.listWorkers = exports.exportWorkflow = exports.terminateWorkflow = exports.getWorkflowResult = exports.getWorkflowStatus = exports.invokeWorkflow = void 0;
3
+ exports.deleteWorkflowConfig = exports.upsertWorkflowConfig = exports.getWorkflowConfig = exports.listWorkflowConfigs = exports.getWorkflowInputLookups = exports.inputValidationFailure = exports.checkInvokeInput = exports.WORKFLOW_TIERS = exports.listInvocableWorkflows = exports.getCronStatus = exports.listDiscoveredWorkflows = exports.listWorkers = exports.exportWorkflow = exports.terminateWorkflow = exports.getWorkflowResult = exports.getWorkflowStatus = exports.invokeWorkflow = void 0;
4
4
  var invocation_1 = require("./invocation");
5
5
  Object.defineProperty(exports, "invokeWorkflow", { enumerable: true, get: function () { return invocation_1.invokeWorkflow; } });
6
6
  Object.defineProperty(exports, "getWorkflowStatus", { enumerable: true, get: function () { return invocation_1.getWorkflowStatus; } });
@@ -17,6 +17,8 @@ Object.defineProperty(exports, "WORKFLOW_TIERS", { enumerable: true, get: functi
17
17
  var input_validation_1 = require("./input-validation");
18
18
  Object.defineProperty(exports, "checkInvokeInput", { enumerable: true, get: function () { return input_validation_1.checkInvokeInput; } });
19
19
  Object.defineProperty(exports, "inputValidationFailure", { enumerable: true, get: function () { return input_validation_1.inputValidationFailure; } });
20
+ var input_lookups_1 = require("./input-lookups");
21
+ Object.defineProperty(exports, "getWorkflowInputLookups", { enumerable: true, get: function () { return input_lookups_1.getWorkflowInputLookups; } });
20
22
  var config_1 = require("./config");
21
23
  Object.defineProperty(exports, "listWorkflowConfigs", { enumerable: true, get: function () { return config_1.listWorkflowConfigs; } });
22
24
  Object.defineProperty(exports, "getWorkflowConfig", { enumerable: true, get: function () { return config_1.getWorkflowConfig; } });
@@ -0,0 +1,16 @@
1
+ import type { LTApiResult, LTApiAuth } from '../../types/sdk';
2
+ /**
3
+ * Resolve the versioned knowledge lookups pinned on a workflow config.
4
+ *
5
+ * The refs on `input_lookups` ARE the grant: any caller who may invoke the
6
+ * workflow may read exactly the pinned editions it names. A ref whose
7
+ * snapshot does not exist answers with `missing: true`; the batch never
8
+ * fails.
9
+ *
10
+ * @param input.type: workflow type name
11
+ * @param auth: authenticated caller; must pass the invoke predicate
12
+ * @returns `{ status: 200, data: { lookups: [{ domain, key, version, as?, data, missing? }] } }`
13
+ */
14
+ export declare function getWorkflowInputLookups(input: {
15
+ type: string;
16
+ }, auth: LTApiAuth): Promise<LTApiResult>;
@@ -0,0 +1,69 @@
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.getWorkflowInputLookups = getWorkflowInputLookups;
37
+ const configService = __importStar(require("../../services/config"));
38
+ const userService = __importStar(require("../../services/user"));
39
+ const invocation_access_1 = require("../../services/invocation-access");
40
+ const knowledge_1 = require("../../services/knowledge");
41
+ /**
42
+ * Resolve the versioned knowledge lookups pinned on a workflow config.
43
+ *
44
+ * The refs on `input_lookups` ARE the grant: any caller who may invoke the
45
+ * workflow may read exactly the pinned editions it names. A ref whose
46
+ * snapshot does not exist answers with `missing: true`; the batch never
47
+ * fails.
48
+ *
49
+ * @param input.type: workflow type name
50
+ * @param auth: authenticated caller; must pass the invoke predicate
51
+ * @returns `{ status: 200, data: { lookups: [{ domain, key, version, as?, data, missing? }] } }`
52
+ */
53
+ async function getWorkflowInputLookups(input, auth) {
54
+ try {
55
+ const config = await configService.getWorkflowConfig(input.type);
56
+ if (!config) {
57
+ return { status: 404, error: 'Workflow config not found' };
58
+ }
59
+ const user = auth.userId ? await userService.getUser(auth.userId) : null;
60
+ if (!(0, invocation_access_1.canInvokeWorkflow)(config, user?.roles ?? [], auth.role)) {
61
+ return { status: 403, error: 'Not authorized to invoke this workflow' };
62
+ }
63
+ const lookups = await (0, knowledge_1.resolveLookupRefs)(config.input_lookups ?? []);
64
+ return { status: 200, data: { lookups } };
65
+ }
66
+ catch (err) {
67
+ return { status: 500, error: err.message };
68
+ }
69
+ }
@@ -5,9 +5,10 @@ import type { LTApiResult } from '../../types/sdk';
5
5
  * The invoke input gate. A workflow that declares input_schema has its
6
6
  * submitted data validated by the same shared pass the dashboard form runs,
7
7
  * so a payload the form accepts is accepted here and a rejection lists the
8
- * exact violations the form would show. No schema, no gate; a data value
9
- * that is not an object is left to the service's own 400.
8
+ * exact violations the form would show. Pinned input_lookups resolve into
9
+ * the `lookup` domain first. No schema, no gate; a data value that is not
10
+ * an object is left to the service's own 400.
10
11
  */
11
- export declare function checkInvokeInput(config: Pick<LTWorkflowConfig, 'workflow_type' | 'input_schema'> | null | undefined, data: unknown, metadata: Record<string, unknown> | null | undefined): LTValidationErrorBody | null;
12
+ export declare function checkInvokeInput(config: Pick<LTWorkflowConfig, 'workflow_type' | 'input_schema' | 'input_lookups'> | null | undefined, data: unknown, metadata: Record<string, unknown> | null | undefined): Promise<LTValidationErrorBody | null>;
12
13
  /** The canonical 422 result; the route serializes `data` as the body. */
13
14
  export declare function inputValidationFailure(body: LTValidationErrorBody): LTApiResult;
@@ -4,6 +4,7 @@ exports.checkInvokeInput = checkInvokeInput;
4
4
  exports.inputValidationFailure = inputValidationFailure;
5
5
  const validate_resolver_payload_1 = require("../../shared/form-validation/validate-resolver-payload");
6
6
  const invoke_context_1 = require("../../shared/form-validation/invoke-context");
7
+ const lookup_cache_1 = require("../../services/knowledge/lookup-cache");
7
8
  const validation_1 = require("../../types/validation");
8
9
  function isPlainObject(value) {
9
10
  return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -12,14 +13,16 @@ function isPlainObject(value) {
12
13
  * The invoke input gate. A workflow that declares input_schema has its
13
14
  * submitted data validated by the same shared pass the dashboard form runs,
14
15
  * so a payload the form accepts is accepted here and a rejection lists the
15
- * exact violations the form would show. No schema, no gate; a data value
16
- * that is not an object is left to the service's own 400.
16
+ * exact violations the form would show. Pinned input_lookups resolve into
17
+ * the `lookup` domain first. No schema, no gate; a data value that is not
18
+ * an object is left to the service's own 400.
17
19
  */
18
- function checkInvokeInput(config, data, metadata) {
20
+ async function checkInvokeInput(config, data, metadata) {
19
21
  const schema = config?.input_schema;
20
22
  if (!schema || !isPlainObject(data))
21
23
  return null;
22
- const violations = (0, validate_resolver_payload_1.validateResolverPayload)(schema, data, (0, invoke_context_1.buildInvokeFormContext)(metadata));
24
+ const lookup = await (0, lookup_cache_1.resolveLookupContext)(config?.input_lookups);
25
+ const violations = (0, validate_resolver_payload_1.validateResolverPayload)(schema, data, (0, invoke_context_1.buildInvokeFormContext)(metadata, lookup));
23
26
  if (violations.length === 0)
24
27
  return null;
25
28
  const n = violations.length;
@@ -65,6 +65,7 @@ function durableEntry(workflowType, taskQueue) {
65
65
  envelope_schema: null,
66
66
  input_schema: null,
67
67
  icon: null,
68
+ input_lookups: null,
68
69
  resolver_schema: null,
69
70
  cron_schedule: null,
70
71
  execute_as: null,
@@ -63,7 +63,7 @@ async function invokeWorkflow(input, auth) {
63
63
  try {
64
64
  await (0, workflow_invocation_1.checkInvocationRoles)(input.type, auth.userId, auth.role);
65
65
  const config = await configService.getWorkflowConfig(input.type);
66
- const violation = (0, input_validation_1.checkInvokeInput)(config, input.data, input.metadata);
66
+ const violation = await (0, input_validation_1.checkInvokeInput)(config, input.data, input.metadata);
67
67
  if (violation)
68
68
  return (0, input_validation_1.inputValidationFailure)(violation);
69
69
  const result = await (0, workflow_invocation_1.invokeWorkflow)({
@@ -0,0 +1,9 @@
1
+ -- Migration 035: workflow input lookups
2
+ --
3
+ -- One opt-in column on the workflow registration:
4
+ -- input_lookups: versioned knowledge refs ({ domain, key, version, as? }[])
5
+ -- the invoke form reads under the `lookup.<as ?? key>`
6
+ -- context domain. NULL renders the form with no lookups.
7
+
8
+ ALTER TABLE lt_config_workflows
9
+ ADD COLUMN IF NOT EXISTS input_lookups JSONB;
@@ -54,6 +54,15 @@ router.get('/:type/config', async (req, res) => {
54
54
  const result = await api.getWorkflowConfig({ type: req.params.type });
55
55
  res.status(result.status).json(result.data ?? { error: result.error });
56
56
  });
57
+ /**
58
+ * GET /api/workflows/:type/input-lookups
59
+ * Resolve the versioned knowledge lookups pinned on a workflow config.
60
+ * Open to any caller the invoke gate admits for that workflow.
61
+ */
62
+ router.get('/:type/input-lookups', async (req, res) => {
63
+ const result = await api.getWorkflowInputLookups({ type: req.params.type }, { userId: req.auth?.userId ?? '', role: req.auth?.role, scopes: req.auth?.scopes });
64
+ res.status(result.status).json(result.data ?? { error: result.error });
65
+ });
57
66
  /**
58
67
  * PUT /api/workflows/:type/config
59
68
  * Create or replace a workflow configuration.
@@ -75,6 +84,7 @@ router.put('/:type/config', auth_1.requireAdmin, async (req, res) => {
75
84
  envelope_schema: req.body.envelope_schema,
76
85
  input_schema: req.body.input_schema,
77
86
  icon: req.body.icon,
87
+ input_lookups: req.body.input_lookups,
78
88
  resolver_schema: req.body.resolver_schema,
79
89
  cron_schedule: req.body.cron_schedule,
80
90
  });
@@ -18,6 +18,7 @@ async function loadAllConfigs() {
18
18
  envelopeSchema: c.envelope_schema ?? null,
19
19
  inputSchema: c.input_schema ?? null,
20
20
  icon: c.icon ?? null,
21
+ inputLookups: c.input_lookups ?? null,
21
22
  resolverSchema: c.resolver_schema ?? null,
22
23
  cronSchedule: c.cron_schedule ?? null,
23
24
  executeAs: c.execute_as ?? null,
@@ -28,6 +28,7 @@ async function getWorkflowConfig(workflowType) {
28
28
  envelope_schema: wf.envelope_schema ?? null,
29
29
  input_schema: wf.input_schema ?? null,
30
30
  icon: wf.icon ?? null,
31
+ input_lookups: wf.input_lookups ?? null,
31
32
  resolver_schema: wf.resolver_schema ?? null,
32
33
  cron_schedule: wf.cron_schedule ?? null,
33
34
  execute_as: wf.execute_as ?? null,
@@ -68,6 +69,7 @@ async function listWorkflowConfigs() {
68
69
  envelope_schema: wf.envelope_schema ?? null,
69
70
  input_schema: wf.input_schema ?? null,
70
71
  icon: wf.icon ?? null,
72
+ input_lookups: wf.input_lookups ?? null,
71
73
  resolver_schema: wf.resolver_schema ?? null,
72
74
  cron_schedule: wf.cron_schedule ?? null,
73
75
  execute_as: wf.execute_as ?? null,
@@ -5,13 +5,13 @@ export declare const LIST_ALL_WORKFLOWS = "SELECT * FROM lt_config_workflows ORD
5
5
  export declare const LIST_ALL_ROLES = "SELECT * FROM lt_config_roles ORDER BY workflow_type, role";
6
6
  export declare const LIST_ALL_INVOCATION_ROLES = "SELECT * FROM lt_config_invocation_roles ORDER BY workflow_type, role";
7
7
  export declare const ENSURE_ROLE_EXISTS = "INSERT INTO lt_roles (role) VALUES ($1) ON CONFLICT DO NOTHING";
8
- export declare const UPSERT_WORKFLOW = "INSERT INTO lt_config_workflows\n (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified, read_safe, input_schema, icon)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)\nON CONFLICT (workflow_type) DO UPDATE SET\n invocable = EXCLUDED.invocable,\n task_queue = EXCLUDED.task_queue,\n default_role = EXCLUDED.default_role,\n description = EXCLUDED.description,\n consumes = EXCLUDED.consumes,\n envelope_schema = EXCLUDED.envelope_schema,\n resolver_schema = EXCLUDED.resolver_schema,\n cron_schedule = EXCLUDED.cron_schedule,\n tool_tags = EXCLUDED.tool_tags,\n execute_as = EXCLUDED.execute_as,\n certified = EXCLUDED.certified,\n read_safe = EXCLUDED.read_safe,\n input_schema = EXCLUDED.input_schema,\n icon = EXCLUDED.icon";
8
+ export declare const UPSERT_WORKFLOW = "INSERT INTO lt_config_workflows\n (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified, read_safe, input_schema, icon, input_lookups)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)\nON CONFLICT (workflow_type) DO UPDATE SET\n invocable = EXCLUDED.invocable,\n task_queue = EXCLUDED.task_queue,\n default_role = EXCLUDED.default_role,\n description = EXCLUDED.description,\n consumes = EXCLUDED.consumes,\n envelope_schema = EXCLUDED.envelope_schema,\n resolver_schema = EXCLUDED.resolver_schema,\n cron_schedule = EXCLUDED.cron_schedule,\n tool_tags = EXCLUDED.tool_tags,\n execute_as = EXCLUDED.execute_as,\n certified = EXCLUDED.certified,\n read_safe = EXCLUDED.read_safe,\n input_schema = EXCLUDED.input_schema,\n icon = EXCLUDED.icon,\n input_lookups = EXCLUDED.input_lookups";
9
9
  export declare const DELETE_CONFIG_ROLES = "DELETE FROM lt_config_roles WHERE workflow_type = $1";
10
10
  export declare const INSERT_CONFIG_ROLE = "INSERT INTO lt_config_roles (workflow_type, role) VALUES ($1, $2)";
11
11
  export declare const DELETE_INVOCATION_ROLES = "DELETE FROM lt_config_invocation_roles WHERE workflow_type = $1";
12
12
  export declare const INSERT_INVOCATION_ROLE = "INSERT INTO lt_config_invocation_roles (workflow_type, role) VALUES ($1, $2)";
13
13
  export declare const DELETE_WORKFLOW = "DELETE FROM lt_config_workflows WHERE workflow_type = $1";
14
- export declare const SEED_WORKFLOW_CONFIG = "INSERT INTO lt_config_workflows\n (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified, read_safe, input_schema, icon)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)\nON CONFLICT (workflow_type) DO NOTHING";
14
+ export declare const SEED_WORKFLOW_CONFIG = "INSERT INTO lt_config_workflows\n (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified, read_safe, input_schema, icon, input_lookups)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)\nON CONFLICT (workflow_type) DO NOTHING";
15
15
  export declare const SEED_CONFIG_ROLE = "INSERT INTO lt_config_roles (workflow_type, role) VALUES ($1, $2)\nON CONFLICT (workflow_type, role) DO NOTHING";
16
16
  export declare const SEED_INVOCATION_ROLE = "INSERT INTO lt_config_invocation_roles (workflow_type, role) VALUES ($1, $2)\nON CONFLICT (workflow_type, role) DO NOTHING";
17
17
  export declare const GET_PROVIDER_DATA = "SELECT workflow_type, data, completed_at\n FROM lt_tasks\n WHERE origin_id = $1\n AND workflow_type = ANY($2)\n AND status = 'completed'\n ORDER BY completed_at DESC";
@@ -23,8 +23,8 @@ exports.ENSURE_ROLE_EXISTS = `\
23
23
  INSERT INTO lt_roles (role) VALUES ($1) ON CONFLICT DO NOTHING`;
24
24
  exports.UPSERT_WORKFLOW = `\
25
25
  INSERT INTO lt_config_workflows
26
- (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified, read_safe, input_schema, icon)
27
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
26
+ (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified, read_safe, input_schema, icon, input_lookups)
27
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
28
28
  ON CONFLICT (workflow_type) DO UPDATE SET
29
29
  invocable = EXCLUDED.invocable,
30
30
  task_queue = EXCLUDED.task_queue,
@@ -39,7 +39,8 @@ ON CONFLICT (workflow_type) DO UPDATE SET
39
39
  certified = EXCLUDED.certified,
40
40
  read_safe = EXCLUDED.read_safe,
41
41
  input_schema = EXCLUDED.input_schema,
42
- icon = EXCLUDED.icon`;
42
+ icon = EXCLUDED.icon,
43
+ input_lookups = EXCLUDED.input_lookups`;
43
44
  exports.DELETE_CONFIG_ROLES = `\
44
45
  DELETE FROM lt_config_roles WHERE workflow_type = $1`;
45
46
  exports.INSERT_CONFIG_ROLE = `\
@@ -55,8 +56,8 @@ DELETE FROM lt_config_workflows WHERE workflow_type = $1`;
55
56
  // ------------------------------------------------------------------ //
56
57
  exports.SEED_WORKFLOW_CONFIG = `\
57
58
  INSERT INTO lt_config_workflows
58
- (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified, read_safe, input_schema, icon)
59
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
59
+ (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified, read_safe, input_schema, icon, input_lookups)
60
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
60
61
  ON CONFLICT (workflow_type) DO NOTHING`;
61
62
  exports.SEED_CONFIG_ROLE = `\
62
63
  INSERT INTO lt_config_roles (workflow_type, role) VALUES ($1, $2)
@@ -14,6 +14,10 @@ const sql_1 = require("./sql");
14
14
  * seed blocks without `certified`): derived from roles/consumes presence —
15
15
  * the rule that governed the tier before the flag existed.
16
16
  */
17
+ /** pg binds JS arrays as Postgres arrays; jsonb columns take the JSON text. */
18
+ function toJsonb(value) {
19
+ return value == null ? null : JSON.stringify(value);
20
+ }
17
21
  function resolveCertified(config) {
18
22
  return (config.certified ??
19
23
  ((config.roles?.length ?? 0) > 0 || (config.consumes?.length ?? 0) > 0));
@@ -55,6 +59,7 @@ async function replaceWorkflowConfig(config, certified) {
55
59
  config.read_safe ?? false,
56
60
  config.input_schema ?? null,
57
61
  config.icon ?? null,
62
+ toJsonb(config.input_lookups),
58
63
  ]);
59
64
  // Replace roles
60
65
  await client.query(sql_1.DELETE_CONFIG_ROLES, [config.workflow_type]);
@@ -118,6 +123,7 @@ async function seedWorkflowConfig(config) {
118
123
  config.read_safe ?? false,
119
124
  config.input_schema ?? null,
120
125
  config.icon ?? null,
126
+ toJsonb(config.input_lookups),
121
127
  ]);
122
128
  const inserted = (rowCount ?? 0) > 0;
123
129
  if (inserted) {
@@ -152,6 +158,8 @@ async function seedWorkflowConfig(config) {
152
158
  drifts.push('input_schema');
153
159
  if ((config.icon ?? null) !== (existing.icon ?? null))
154
160
  drifts.push('icon');
161
+ if (JSON.stringify(config.input_lookups ?? null) !== JSON.stringify(existing.input_lookups ?? null))
162
+ drifts.push('input_lookups');
155
163
  if (drifts.length) {
156
164
  logger_1.loggerRegistry.warn(`[long-tail] config drift: ${config.workflow_type} — ${drifts.join(', ')} differ between code and DB`);
157
165
  }
@@ -191,7 +199,8 @@ async function applyWorkflowConfig(config) {
191
199
  (0, node_util_1.isDeepStrictEqual)(existing.envelope_schema ?? null, config.envelope_schema ?? null) &&
192
200
  (0, node_util_1.isDeepStrictEqual)(existing.resolver_schema ?? null, config.resolver_schema ?? null) &&
193
201
  (0, node_util_1.isDeepStrictEqual)(existing.input_schema ?? null, config.input_schema ?? null) &&
194
- (existing.icon ?? null) === (config.icon ?? null);
202
+ (existing.icon ?? null) === (config.icon ?? null) &&
203
+ (0, node_util_1.isDeepStrictEqual)(existing.input_lookups ?? null, config.input_lookups ?? null);
195
204
  if (unchanged)
196
205
  return 'unchanged';
197
206
  }
@@ -1,4 +1,5 @@
1
1
  export * from './lookup-cache';
2
+ export * from './lookup-refs';
2
3
  export interface KnowledgeVersionMeta {
3
4
  version: number;
4
5
  change_summary: string | null;
@@ -24,6 +24,7 @@ exports.listKnowledgeVersions = listKnowledgeVersions;
24
24
  const db_1 = require("../../lib/db");
25
25
  const sql_1 = require("./sql");
26
26
  __exportStar(require("./lookup-cache"), exports);
27
+ __exportStar(require("./lookup-refs"), exports);
27
28
  /** The immutable snapshot at (domain, key, version), uncached full shape. */
28
29
  async function getKnowledgeVersion(domain, key, version) {
29
30
  const pool = (0, db_1.getPool)();
@@ -0,0 +1,7 @@
1
+ import type { EscalationLookupRef } from '../../types/escalation';
2
+ /**
3
+ * One message per ref whose pinned edition does not exist, naming what does.
4
+ * Shape is the caller's job (assertLookupRefs); this answers the second
5
+ * question a saver has: is there an edition behind the pin.
6
+ */
7
+ export declare function describeMissingLookupRefs(refs: EscalationLookupRef[]): Promise<string[]>;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.describeMissingLookupRefs = describeMissingLookupRefs;
4
+ const db_1 = require("../../lib/db");
5
+ const lookup_cache_1 = require("./lookup-cache");
6
+ const sql_1 = require("./sql");
7
+ /**
8
+ * One message per ref whose pinned edition does not exist, naming what does.
9
+ * Shape is the caller's job (assertLookupRefs); this answers the second
10
+ * question a saver has: is there an edition behind the pin.
11
+ */
12
+ async function describeMissingLookupRefs(refs) {
13
+ const problems = [];
14
+ for (const ref of refs) {
15
+ const snapshot = await (0, lookup_cache_1.getKnowledgeSnapshot)(ref.domain, ref.key, ref.version);
16
+ if (snapshot)
17
+ continue;
18
+ const { rows } = await (0, db_1.getPool)().query(sql_1.LIST_KNOWLEDGE_VERSIONS, [ref.domain, ref.key]);
19
+ const versions = rows.map((r) => Number(r.version)).sort((a, b) => a - b);
20
+ const where = versions.length
21
+ ? `editions: ${versions.map((v) => `v${v}`).join(', ')}`
22
+ : `no knowledge entry ${ref.domain}/${ref.key}`;
23
+ problems.push(`Lookup ref ${ref.domain}/${ref.key} v${ref.version} names no edition (${where})`);
24
+ }
25
+ return problems;
26
+ }
@@ -7,12 +7,12 @@ export declare const findTasksSchema: z.ZodObject<{
7
7
  limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
8
8
  }, "strip", z.ZodTypeAny, {
9
9
  limit: number;
10
- status?: "pending" | "in_progress" | "completed" | "needs_intervention" | "failed" | undefined;
10
+ status?: "completed" | "pending" | "in_progress" | "needs_intervention" | "failed" | undefined;
11
11
  workflow_type?: string | undefined;
12
12
  workflow_id?: string | undefined;
13
13
  origin_id?: string | undefined;
14
14
  }, {
15
- status?: "pending" | "in_progress" | "completed" | "needs_intervention" | "failed" | undefined;
15
+ status?: "completed" | "pending" | "in_progress" | "needs_intervention" | "failed" | undefined;
16
16
  workflow_type?: string | undefined;
17
17
  workflow_id?: string | undefined;
18
18
  origin_id?: string | undefined;
@@ -38,6 +38,7 @@ export declare function resolveChecklistDefault(fieldSchema: Record<string, unkn
38
38
  * which remains the at-least-one check.
39
39
  */
40
40
  export declare function validateRequireAll(value: unknown, fieldSchema: Record<string, unknown> | undefined, ctx?: Record<string, unknown>): string | undefined;
41
+ export declare const INVALID_JSON = "Invalid JSON";
41
42
  /**
42
43
  * Runtime type check against the field's declared JSON Schema `type`. Guards
43
44
  * the payload contract for API-first callers (a form widget already produces
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.X_LT_DEFAULT_CHECKED = void 0;
3
+ exports.INVALID_JSON = exports.X_LT_DEFAULT_CHECKED = void 0;
4
4
  exports.resolveChecklistItems = resolveChecklistItems;
5
5
  exports.resolveChecklistDefault = resolveChecklistDefault;
6
6
  exports.validateRequireAll = validateRequireAll;
@@ -87,6 +87,18 @@ function validateRequireAll(value, fieldSchema, ctx) {
87
87
  return undefined;
88
88
  return `${incomplete} of ${mandatory.length} checks incomplete`;
89
89
  }
90
+ exports.INVALID_JSON = 'Invalid JSON';
91
+ /** The json editor holds unparseable text as a string at the field's key. */
92
+ function isJsonWidget(fieldSchema) {
93
+ return fieldSchema?.['x-lt-widget'] === 'json';
94
+ }
95
+ /** A list is edited through the json editor or a multi-select; any other list value is display only. */
96
+ function isEditableList(fieldSchema) {
97
+ return isJsonWidget(fieldSchema) || fieldSchema?.[x_lt_options_1.X_LT_OPTIONS] !== undefined;
98
+ }
99
+ function plural(n, noun) {
100
+ return `${n} ${noun}${n === 1 ? '' : 's'}`;
101
+ }
90
102
  /**
91
103
  * Runtime type check against the field's declared JSON Schema `type`. Guards
92
104
  * the payload contract for API-first callers (a form widget already produces
@@ -109,9 +121,13 @@ function validateFieldType(value, fieldSchema) {
109
121
  case 'boolean':
110
122
  return typeof value === 'boolean' ? undefined : 'Expected true or false';
111
123
  case 'array':
112
- return Array.isArray(value) ? undefined : 'Expected a list';
124
+ if (Array.isArray(value))
125
+ return undefined;
126
+ return isJsonWidget(fieldSchema) && typeof value === 'string' ? exports.INVALID_JSON : 'Expected a list';
113
127
  case 'object':
114
- return typeof value === 'object' && !Array.isArray(value) ? undefined : 'Expected an object';
128
+ if (typeof value === 'object' && !Array.isArray(value))
129
+ return undefined;
130
+ return isJsonWidget(fieldSchema) && typeof value === 'string' ? exports.INVALID_JSON : 'Expected an object';
115
131
  default:
116
132
  return undefined;
117
133
  }
@@ -136,7 +152,7 @@ function validateFieldConstraints(value, fieldSchema, ctx) {
136
152
  // interpolated list that currently offers nothing fails closed — a stale
137
153
  // cascade child value never submits.
138
154
  const allowed = (0, x_lt_options_1.resolveFieldOptions)(fieldSchema, ctx);
139
- if (allowed !== undefined && value !== undefined && value !== null && value !== '') {
155
+ if (allowed !== undefined && value !== undefined && value !== null && value !== '' && !Array.isArray(value)) {
140
156
  if (allowed.length === 0) {
141
157
  return 'No valid options for this selection';
142
158
  }
@@ -144,6 +160,12 @@ function validateFieldConstraints(value, fieldSchema, ctx) {
144
160
  return `Must be one of: ${allowed.map((o) => String(o.value)).join(', ')}`;
145
161
  }
146
162
  }
163
+ if (Array.isArray(value)) {
164
+ return isEditableList(fieldSchema) ? validateListConstraints(value, fieldSchema, allowed, ctx) : undefined;
165
+ }
166
+ if (value !== null && typeof value === 'object') {
167
+ return validateMapConstraints(value, fieldSchema, ctx);
168
+ }
147
169
  if (typeof value === 'string') {
148
170
  const s = value.trim();
149
171
  if (s === '')
@@ -196,6 +218,65 @@ function validateFieldConstraints(value, fieldSchema, ctx) {
196
218
  }
197
219
  return undefined;
198
220
  }
221
+ /**
222
+ * An edited list: every item must belong to the field's `x-lt-options` when
223
+ * declared, the length must sit within `minItems`/`maxItems`, and each item
224
+ * must satisfy `items`. An empty list passes; presence is the required
225
+ * check's job.
226
+ */
227
+ function validateListConstraints(value, fieldSchema, allowed, ctx) {
228
+ if (value.length === 0)
229
+ return undefined;
230
+ if (allowed !== undefined) {
231
+ if (allowed.length === 0)
232
+ return 'No valid options for this selection';
233
+ if (value.some((v) => !allowed.some((o) => o.value === v))) {
234
+ return `Must be one of: ${allowed.map((o) => String(o.value)).join(', ')}`;
235
+ }
236
+ }
237
+ const minItems = resolveNumericConstraint(fieldSchema.minItems, undefined, ctx);
238
+ if (minItems !== undefined && value.length < minItems)
239
+ return `At least ${plural(minItems, 'item')}`;
240
+ const maxItems = resolveNumericConstraint(fieldSchema.maxItems, undefined, ctx);
241
+ if (maxItems !== undefined && value.length > maxItems)
242
+ return `At most ${plural(maxItems, 'item')}`;
243
+ const items = fieldSchema.items;
244
+ if (items && typeof items === 'object' && !Array.isArray(items)) {
245
+ const itemSchema = items;
246
+ for (let i = 0; i < value.length; i++) {
247
+ const err = validateFieldType(value[i], itemSchema) ?? validateFieldConstraints(value[i], itemSchema, ctx);
248
+ if (err)
249
+ return `Item ${i + 1}: ${err}`;
250
+ }
251
+ }
252
+ return undefined;
253
+ }
254
+ /**
255
+ * A map value: keys must belong to `propertyNames.enum` when declared, and
256
+ * every value must satisfy an object-shaped `additionalProperties`.
257
+ */
258
+ function validateMapConstraints(value, fieldSchema, ctx) {
259
+ const entries = Object.entries(value);
260
+ if (entries.length === 0)
261
+ return undefined;
262
+ const propertyNames = fieldSchema.propertyNames;
263
+ const allowedKeys = Array.isArray(propertyNames?.enum) ? propertyNames.enum.map(String) : undefined;
264
+ if (allowedKeys) {
265
+ const unknown = entries.find(([k]) => !allowedKeys.includes(k));
266
+ if (unknown)
267
+ return `Unknown key "${unknown[0]}". Allowed: ${allowedKeys.join(', ')}`;
268
+ }
269
+ const ap = fieldSchema.additionalProperties;
270
+ if (ap && typeof ap === 'object' && !Array.isArray(ap)) {
271
+ const valueSchema = ap;
272
+ for (const [k, v] of entries) {
273
+ const err = validateFieldType(v, valueSchema) ?? validateFieldConstraints(v, valueSchema, ctx);
274
+ if (err)
275
+ return `"${k}": ${err}`;
276
+ }
277
+ }
278
+ return undefined;
279
+ }
199
280
  function resolveNumericConstraint(staticVal, dynamicPath, ctx) {
200
281
  if (typeof staticVal === 'number')
201
282
  return staticVal;
@@ -232,13 +313,20 @@ function validateField(value, fieldSchema, isRequired, isTouched, ctx) {
232
313
  if (isRequired) {
233
314
  if (value === undefined || value === null)
234
315
  return 'Required';
235
- if (typeof value === 'boolean' && !value)
316
+ // A checkbox must be checked; a boolean with an option list is answered by either value.
317
+ if (typeof value === 'boolean' && !value && (0, x_lt_options_1.resolveFieldOptions)(fieldSchema, ctx) === undefined)
236
318
  return 'Required';
237
319
  if (typeof value === 'string' && value.trim() === '')
238
320
  return 'Required';
321
+ // A picked or edited list needs one item; a plain list value is not checked.
322
+ if (Array.isArray(value) && value.length === 0 && isEditableList(fieldSchema))
323
+ return 'Required';
239
324
  if (typeof value === 'object' && !Array.isArray(value) && value !== null) {
240
325
  const vals = Object.values(value);
241
- if (vals.length === 0 || vals.every((v) => !v))
326
+ if (vals.length === 0)
327
+ return 'Required';
328
+ // A json map is answered by any key; every other object needs one truthy value.
329
+ if (!isJsonWidget(fieldSchema) && vals.every((v) => !v))
242
330
  return 'Required';
243
331
  }
244
332
  }