@hotmeshio/long-tail 0.19.1 → 0.21.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 (393) hide show
  1. package/README.md +4 -4
  2. package/build/api/escalations/accumulate.d.ts +96 -0
  3. package/build/api/escalations/accumulate.js +516 -0
  4. package/build/api/escalations/index.d.ts +1 -0
  5. package/build/api/escalations/index.js +10 -1
  6. package/build/api/roles.d.ts +4 -5
  7. package/build/api/roles.js +53 -4
  8. package/build/api/scan-codes/execute.js +2 -0
  9. package/build/api/scan-codes/verbs.d.ts +15 -0
  10. package/build/api/scan-codes/verbs.js +65 -0
  11. package/build/api/workflows/config.d.ts +3 -0
  12. package/build/api/workflows/config.js +15 -0
  13. package/build/api/workflows/index.d.ts +1 -0
  14. package/build/api/workflows/index.js +3 -1
  15. package/build/api/workflows/input-lookups.d.ts +16 -0
  16. package/build/api/workflows/input-lookups.js +69 -0
  17. package/build/api/workflows/input-validation.d.ts +4 -3
  18. package/build/api/workflows/input-validation.js +7 -4
  19. package/build/api/workflows/invocable.js +1 -0
  20. package/build/api/workflows/invocation.js +1 -1
  21. package/build/index.js +60 -0
  22. package/build/lib/db/schemas/035_workflow_input_lookups.sql +9 -0
  23. package/build/lib/db/schemas/036_role_portals.sql +12 -0
  24. package/build/routes/escalations/accumulate.d.ts +7 -0
  25. package/build/routes/escalations/accumulate.js +150 -0
  26. package/build/routes/escalations/index.js +5 -0
  27. package/build/routes/workflows/config.js +10 -0
  28. package/build/sdk/index.d.ts +25 -0
  29. package/build/sdk/index.js +8 -0
  30. package/build/services/config/cache.js +1 -0
  31. package/build/services/config/read.js +2 -0
  32. package/build/services/config/sql.d.ts +2 -2
  33. package/build/services/config/sql.js +6 -5
  34. package/build/services/config/write.js +10 -1
  35. package/build/services/escalation/accumulate.d.ts +81 -0
  36. package/build/services/escalation/accumulate.js +154 -0
  37. package/build/services/escalation/index.d.ts +1 -0
  38. package/build/services/escalation/index.js +1 -0
  39. package/build/services/knowledge/index.d.ts +1 -0
  40. package/build/services/knowledge/index.js +1 -0
  41. package/build/services/knowledge/lookup-refs.d.ts +7 -0
  42. package/build/services/knowledge/lookup-refs.js +26 -0
  43. package/build/services/mcp/db-server/schemas.d.ts +2 -2
  44. package/build/services/mcp/playwright-server/schemas.d.ts +2 -2
  45. package/build/services/orchestrator/condition.d.ts +40 -3
  46. package/build/services/orchestrator/condition.js +42 -2
  47. package/build/services/role/index.js +1 -0
  48. package/build/services/role/seed.js +6 -1
  49. package/build/services/role/sql.d.ts +6 -3
  50. package/build/services/role/sql.js +7 -2
  51. package/build/services/role/types.d.ts +38 -10
  52. package/build/services/role/types.js +10 -1
  53. package/build/services/scan-code/validate.js +16 -0
  54. package/build/shared/form-validation/display-only-widgets.d.ts +16 -0
  55. package/build/shared/form-validation/display-only-widgets.js +25 -0
  56. package/build/shared/form-validation/field-validator.d.ts +1 -0
  57. package/build/shared/form-validation/field-validator.js +94 -6
  58. package/build/shared/form-validation/index.d.ts +2 -0
  59. package/build/shared/form-validation/index.js +2 -0
  60. package/build/shared/form-validation/invoke-context.d.ts +4 -3
  61. package/build/shared/form-validation/invoke-context.js +5 -4
  62. package/build/shared/form-validation/x-lt-bind.d.ts +2 -14
  63. package/build/shared/form-validation/x-lt-bind.js +12 -8
  64. package/build/shared/form-validation/x-lt-invoke.d.ts +38 -0
  65. package/build/shared/form-validation/x-lt-invoke.js +103 -0
  66. package/build/shared/form-validation/x-lt-options.d.ts +3 -3
  67. package/build/shared/form-validation/x-lt-options.js +19 -5
  68. package/build/shared/form-validation/x-lt-show-if.d.ts +5 -0
  69. package/build/shared/form-validation/x-lt-show-if.js +10 -0
  70. package/build/start/workers.js +10 -0
  71. package/build/system/mcp-servers/admin/escalations.js +39 -0
  72. package/build/system/mcp-servers/admin/schemas.d.ts +256 -33
  73. package/build/system/mcp-servers/admin/schemas.js +55 -3
  74. package/build/system/mcp-servers/admin/users.js +1 -0
  75. package/build/system/mcp-servers/admin/workflow-config.js +54 -9
  76. package/build/system/mcp-servers/admin/workflows.js +9 -7
  77. package/build/system/mcp-servers/db-query/schemas.d.ts +2 -2
  78. package/build/system/mcp-servers/docs.js +4 -0
  79. package/build/system/mcp-servers/human-queue-schemas.d.ts +85 -0
  80. package/build/system/mcp-servers/human-queue-schemas.js +19 -1
  81. package/build/system/mcp-servers/human-queue.d.ts +2 -0
  82. package/build/system/mcp-servers/human-queue.js +77 -0
  83. package/build/system/seed/tool-manifests-admin.d.ts +1509 -227
  84. package/build/system/seed/tool-manifests-admin.js +8 -4
  85. package/build/system/seed/tool-manifests-escalation.d.ts +174 -0
  86. package/build/system/seed/tool-manifests-escalation.js +56 -0
  87. package/build/tsconfig.tsbuildinfo +1 -1
  88. package/build/types/config.d.ts +4 -0
  89. package/build/types/escalation.d.ts +52 -0
  90. package/build/types/escalation.js +29 -1
  91. package/build/types/index.d.ts +2 -2
  92. package/build/types/index.js +3 -1
  93. package/build/types/scan-code.d.ts +24 -0
  94. package/build/types/scan-code.js +9 -0
  95. package/build/types/startup.d.ts +26 -0
  96. package/dashboard/dist/assets/{AdminDashboard-Drs-9TRM.js → AdminDashboard-uarpHB88.js} +2 -2
  97. package/dashboard/dist/assets/{AdminDashboard-Drs-9TRM.js.map → AdminDashboard-uarpHB88.js.map} +1 -1
  98. package/dashboard/dist/assets/{AgentConfigPage-BDPDZ7-v.js → AgentConfigPage-BcUaDD5E.js} +6 -6
  99. package/dashboard/dist/assets/{AgentConfigPage-BDPDZ7-v.js.map → AgentConfigPage-BcUaDD5E.js.map} +1 -1
  100. package/dashboard/dist/assets/{AgentDetailPage-CGBulM4_.js → AgentDetailPage-BaZBhK6i.js} +3 -3
  101. package/dashboard/dist/assets/{AgentDetailPage-CGBulM4_.js.map → AgentDetailPage-BaZBhK6i.js.map} +1 -1
  102. package/dashboard/dist/assets/AgentsPage-CuVFSDc4.js +2 -0
  103. package/dashboard/dist/assets/{AgentsPage-D77JeViQ.js.map → AgentsPage-CuVFSDc4.js.map} +1 -1
  104. package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js +2 -0
  105. package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js.map +1 -0
  106. package/dashboard/dist/assets/{BotPicker-CC5vI_Sv.js → BotPicker-CClMby6B.js} +2 -2
  107. package/dashboard/dist/assets/{BotPicker-CC5vI_Sv.js.map → BotPicker-CClMby6B.js.map} +1 -1
  108. package/dashboard/dist/assets/BulkAssignModal-BL8FRgkN.js +2 -0
  109. package/dashboard/dist/assets/{BulkAssignModal-BXiJnlqt.js.map → BulkAssignModal-BL8FRgkN.js.map} +1 -1
  110. package/dashboard/dist/assets/CapabilitiesPage-D53ogPor.js +2 -0
  111. package/dashboard/dist/assets/{CapabilitiesPage-D9TC2iKy.js.map → CapabilitiesPage-D53ogPor.js.map} +1 -1
  112. package/dashboard/dist/assets/{CollapsibleSection-D10lGw_u.js → CollapsibleSection-ow8jpbtD.js} +2 -2
  113. package/dashboard/dist/assets/{CollapsibleSection-D10lGw_u.js.map → CollapsibleSection-ow8jpbtD.js.map} +1 -1
  114. package/dashboard/dist/assets/{ConfirmDeleteModal-BJdLN6No.js → ConfirmDeleteModal-CeEDt9iJ.js} +2 -2
  115. package/dashboard/dist/assets/{ConfirmDeleteModal-BJdLN6No.js.map → ConfirmDeleteModal-CeEDt9iJ.js.map} +1 -1
  116. package/dashboard/dist/assets/{CountdownTimer-D9B-BjQ7.js → CountdownTimer-CSqyZMCG.js} +2 -2
  117. package/dashboard/dist/assets/{CountdownTimer-D9B-BjQ7.js.map → CountdownTimer-CSqyZMCG.js.map} +1 -1
  118. package/dashboard/dist/assets/{CredentialsPage-hniUAFBK.js → CredentialsPage-Dx7SxA23.js} +2 -2
  119. package/dashboard/dist/assets/{CredentialsPage-hniUAFBK.js.map → CredentialsPage-Dx7SxA23.js.map} +1 -1
  120. package/dashboard/dist/assets/{CronLabel-v9DCD2FX.js → CronLabel-LYPxpvNN.js} +2 -2
  121. package/dashboard/dist/assets/{CronLabel-v9DCD2FX.js.map → CronLabel-LYPxpvNN.js.map} +1 -1
  122. package/dashboard/dist/assets/DataTable-spX1dFyb.js +2 -0
  123. package/dashboard/dist/assets/DataTable-spX1dFyb.js.map +1 -0
  124. package/dashboard/dist/assets/{DropZone-XlcY8hEH.js → DropZone-f1o-GLM8.js} +2 -2
  125. package/dashboard/dist/assets/{DropZone-XlcY8hEH.js.map → DropZone-f1o-GLM8.js.map} +1 -1
  126. package/dashboard/dist/assets/{ElapsedCell-_xvVTK8N.js → ElapsedCell-BZJTSm9N.js} +2 -2
  127. package/dashboard/dist/assets/{ElapsedCell-_xvVTK8N.js.map → ElapsedCell-BZJTSm9N.js.map} +1 -1
  128. package/dashboard/dist/assets/EntityTimelinePanel-0wIIW2en.js +2 -0
  129. package/dashboard/dist/assets/{EntityTimelinePanel-1lT3jkCM.js.map → EntityTimelinePanel-0wIIW2en.js.map} +1 -1
  130. package/dashboard/dist/assets/{EscalationListSchemaPage-BeQUTUEO.js → EscalationListSchemaPage-CoYvtMzj.js} +3 -3
  131. package/dashboard/dist/assets/{EscalationListSchemaPage-BeQUTUEO.js.map → EscalationListSchemaPage-CoYvtMzj.js.map} +1 -1
  132. package/dashboard/dist/assets/EscalationListView-DWFHPufv.js +2 -0
  133. package/dashboard/dist/assets/EscalationListView-DWFHPufv.js.map +1 -0
  134. package/dashboard/dist/assets/{EscalationSchemaPage-D4VlEwyS.js → EscalationSchemaPage-C9Xu_A25.js} +3 -3
  135. package/dashboard/dist/assets/{EscalationSchemaPage-D4VlEwyS.js.map → EscalationSchemaPage-C9Xu_A25.js.map} +1 -1
  136. package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js +2 -0
  137. package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js.map +1 -0
  138. package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js +2 -0
  139. package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js.map +1 -0
  140. package/dashboard/dist/assets/{EscalationsOverview-Bx6Zrzm-.js → EscalationsOverview-CW57FaP9.js} +2 -2
  141. package/dashboard/dist/assets/{EscalationsOverview-Bx6Zrzm-.js.map → EscalationsOverview-CW57FaP9.js.map} +1 -1
  142. package/dashboard/dist/assets/{EventTable-KEC3YWBf.js → EventTable-D1ctWhKf.js} +2 -2
  143. package/dashboard/dist/assets/{EventTable-KEC3YWBf.js.map → EventTable-D1ctWhKf.js.map} +1 -1
  144. package/dashboard/dist/assets/{FilterBar-xwN_b5fj.js → FilterBar-C-iur-Nj.js} +2 -2
  145. package/dashboard/dist/assets/{FilterBar-xwN_b5fj.js.map → FilterBar-C-iur-Nj.js.map} +1 -1
  146. package/dashboard/dist/assets/GraphInvokePage-CcA_44M4.js +2 -0
  147. package/dashboard/dist/assets/{GraphInvokePage-DV7Y0fe2.js.map → GraphInvokePage-CcA_44M4.js.map} +1 -1
  148. package/dashboard/dist/assets/HomePage-Dc085ghJ.js +2 -0
  149. package/dashboard/dist/assets/{HomePage-G785SWcW.js.map → HomePage-Dc085ghJ.js.map} +1 -1
  150. package/dashboard/dist/assets/ListToolbar-h_ziBt4O.js +2 -0
  151. package/dashboard/dist/assets/{ListToolbar-zPVYPg3W.js.map → ListToolbar-h_ziBt4O.js.map} +1 -1
  152. package/dashboard/dist/assets/{McpOverview-CMGUq8hx.js → McpOverview-qXXhbNWV.js} +2 -2
  153. package/dashboard/dist/assets/{McpOverview-CMGUq8hx.js.map → McpOverview-qXXhbNWV.js.map} +1 -1
  154. package/dashboard/dist/assets/{McpQueryDetailPage-CdhLhaKn.js → McpQueryDetailPage-SEzSbZrd.js} +2 -2
  155. package/dashboard/dist/assets/{McpQueryDetailPage-CdhLhaKn.js.map → McpQueryDetailPage-SEzSbZrd.js.map} +1 -1
  156. package/dashboard/dist/assets/McpQueryPage-Cy0V0kv9.js +2 -0
  157. package/dashboard/dist/assets/{McpQueryPage-CNSNMagY.js.map → McpQueryPage-Cy0V0kv9.js.map} +1 -1
  158. package/dashboard/dist/assets/{McpRunDetailPage-DBm8hUaW.js → McpRunDetailPage-DjJO5vSb.js} +2 -2
  159. package/dashboard/dist/assets/{McpRunDetailPage-DBm8hUaW.js.map → McpRunDetailPage-DjJO5vSb.js.map} +1 -1
  160. package/dashboard/dist/assets/McpRunsPage-BfjiJ8mM.js +2 -0
  161. package/dashboard/dist/assets/{McpRunsPage-B6rb5QBf.js.map → McpRunsPage-BfjiJ8mM.js.map} +1 -1
  162. package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js → NamespacePill-DADRJOUl.js} +2 -2
  163. package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js.map → NamespacePill-DADRJOUl.js.map} +1 -1
  164. package/dashboard/dist/assets/OperationsPage-dJcER0T_.js +3 -0
  165. package/dashboard/dist/assets/OperationsPage-dJcER0T_.js.map +1 -0
  166. package/dashboard/dist/assets/OperatorDashboard-zCkW4eqk.js +2 -0
  167. package/dashboard/dist/assets/{OperatorDashboard-DBOscDnf.js.map → OperatorDashboard-zCkW4eqk.js.map} +1 -1
  168. package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js → PageHeader-Csq434-v.js} +2 -2
  169. package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js.map → PageHeader-Csq434-v.js.map} +1 -1
  170. package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js → PageHeaderWithStats-CSnk1p5A.js} +2 -2
  171. package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js.map → PageHeaderWithStats-CSnk1p5A.js.map} +1 -1
  172. package/dashboard/dist/assets/{PersonaDetailPage-BGRdGpeR.js → PersonaDetailPage-Cx6L3Jvu.js} +2 -2
  173. package/dashboard/dist/assets/{PersonaDetailPage-BGRdGpeR.js.map → PersonaDetailPage-Cx6L3Jvu.js.map} +1 -1
  174. package/dashboard/dist/assets/{PersonasPage-DRzOZcVa.js → PersonasPage-DOgGUlJl.js} +2 -2
  175. package/dashboard/dist/assets/{PersonasPage-DRzOZcVa.js.map → PersonasPage-DOgGUlJl.js.map} +1 -1
  176. package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js +2 -0
  177. package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js.map +1 -0
  178. package/dashboard/dist/assets/{ProcessDetailPage-BLGjZXpM.js → ProcessDetailPage-BFcFSDUv.js} +2 -2
  179. package/dashboard/dist/assets/{ProcessDetailPage-BLGjZXpM.js.map → ProcessDetailPage-BFcFSDUv.js.map} +1 -1
  180. package/dashboard/dist/assets/ProcessesListPage-BaHV2cXp.js +2 -0
  181. package/dashboard/dist/assets/{ProcessesListPage-5NnysKFC.js.map → ProcessesListPage-BaHV2cXp.js.map} +1 -1
  182. package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js +7 -0
  183. package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js.map +1 -0
  184. package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js +8 -0
  185. package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js.map +1 -0
  186. package/dashboard/dist/assets/{RolePill-DhnVPK4q.js → RolePill-BafrASDX.js} +2 -2
  187. package/dashboard/dist/assets/{RolePill-DhnVPK4q.js.map → RolePill-BafrASDX.js.map} +1 -1
  188. package/dashboard/dist/assets/{RolesPage-BmW1LzkU.js → RolesPage-DSqqKPbv.js} +2 -2
  189. package/dashboard/dist/assets/{RolesPage-BmW1LzkU.js.map → RolesPage-DSqqKPbv.js.map} +1 -1
  190. package/dashboard/dist/assets/RunAsSelector-B29iWwel.js +2 -0
  191. package/dashboard/dist/assets/{RunAsSelector-BwZTJ4Yj.js.map → RunAsSelector-B29iWwel.js.map} +1 -1
  192. package/dashboard/dist/assets/ScanCodesPage-S8aAJfnC.js +2 -0
  193. package/dashboard/dist/assets/{ScanCodesPage-FiYIYB-m.js.map → ScanCodesPage-S8aAJfnC.js.map} +1 -1
  194. package/dashboard/dist/assets/{ScanSchemeDetailPage-BiAqtD-a.js → ScanSchemeDetailPage-CUBRAtmJ.js} +2 -2
  195. package/dashboard/dist/assets/{ScanSchemeDetailPage-BiAqtD-a.js.map → ScanSchemeDetailPage-CUBRAtmJ.js.map} +1 -1
  196. package/dashboard/dist/assets/ScanStationPage-R9t1-CeQ.js +2 -0
  197. package/dashboard/dist/assets/{ScanStationPage-8CdOtbCD.js.map → ScanStationPage-R9t1-CeQ.js.map} +1 -1
  198. package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js → ScopeBadge-b6MIBiYD.js} +2 -2
  199. package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js.map → ScopeBadge-b6MIBiYD.js.map} +1 -1
  200. package/dashboard/dist/assets/{StickyPagination-DRuqKhZt.js → StickyPagination-CkW_A507.js} +2 -2
  201. package/dashboard/dist/assets/{StickyPagination-DRuqKhZt.js.map → StickyPagination-CkW_A507.js.map} +1 -1
  202. package/dashboard/dist/assets/{StreamMessageDetail-JwlbRiMn.js → StreamMessageDetail-yzWX0wac.js} +2 -2
  203. package/dashboard/dist/assets/{StreamMessageDetail-JwlbRiMn.js.map → StreamMessageDetail-yzWX0wac.js.map} +1 -1
  204. package/dashboard/dist/assets/{SwimlaneTimeline-hu3c4bCJ.js → SwimlaneTimeline-Cf4DXFxj.js} +2 -2
  205. package/dashboard/dist/assets/{SwimlaneTimeline-hu3c4bCJ.js.map → SwimlaneTimeline-Cf4DXFxj.js.map} +1 -1
  206. package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js → TagInput-ZrIIrEUP.js} +2 -2
  207. package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js.map → TagInput-ZrIIrEUP.js.map} +1 -1
  208. package/dashboard/dist/assets/{TaskDetailPage-NqVZF3jW.js → TaskDetailPage-DCDcEps9.js} +2 -2
  209. package/dashboard/dist/assets/{TaskDetailPage-NqVZF3jW.js.map → TaskDetailPage-DCDcEps9.js.map} +1 -1
  210. package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js → TaskQueuePill-DkQ1uc6y.js} +2 -2
  211. package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js.map → TaskQueuePill-DkQ1uc6y.js.map} +1 -1
  212. package/dashboard/dist/assets/TasksListPage-BBATgpf7.js +2 -0
  213. package/dashboard/dist/assets/{TasksListPage-BQNaSzCn.js.map → TasksListPage-BBATgpf7.js.map} +1 -1
  214. package/dashboard/dist/assets/{TimeAgo-Cv35DOiI.js → TimeAgo-CSNVEjch.js} +2 -2
  215. package/dashboard/dist/assets/{TimeAgo-Cv35DOiI.js.map → TimeAgo-CSNVEjch.js.map} +1 -1
  216. package/dashboard/dist/assets/{TimestampCell-DHUXey9s.js → TimestampCell-Du1nBrPn.js} +2 -2
  217. package/dashboard/dist/assets/{TimestampCell-DHUXey9s.js.map → TimestampCell-Du1nBrPn.js.map} +1 -1
  218. package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js → ToolPill-Baxm02L6.js} +2 -2
  219. package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js.map → ToolPill-Baxm02L6.js.map} +1 -1
  220. package/dashboard/dist/assets/ToolTestPanel-CF-h_5Rg.js +2 -0
  221. package/dashboard/dist/assets/{ToolTestPanel-DvuLFWqQ.js.map → ToolTestPanel-CF-h_5Rg.js.map} +1 -1
  222. package/dashboard/dist/assets/{TopicDetailPage-TXX3QNSo.js → TopicDetailPage-Dr1UmWcp.js} +3 -3
  223. package/dashboard/dist/assets/{TopicDetailPage-TXX3QNSo.js.map → TopicDetailPage-Dr1UmWcp.js.map} +1 -1
  224. package/dashboard/dist/assets/TopicsPage-CUUo-Ylf.js +2 -0
  225. package/dashboard/dist/assets/{TopicsPage-h-oyTeEJ.js.map → TopicsPage-CUUo-Ylf.js.map} +1 -1
  226. package/dashboard/dist/assets/{UserName-BceRCeDF.js → UserName-kBh1dc39.js} +2 -2
  227. package/dashboard/dist/assets/{UserName-BceRCeDF.js.map → UserName-kBh1dc39.js.map} +1 -1
  228. package/dashboard/dist/assets/{WorkflowExecutionPage-CmHGcaN9.js → WorkflowExecutionPage-CCRSbnDx.js} +2 -2
  229. package/dashboard/dist/assets/{WorkflowExecutionPage-CmHGcaN9.js.map → WorkflowExecutionPage-CCRSbnDx.js.map} +1 -1
  230. package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js → WorkflowPill-ZepbO_ny.js} +2 -2
  231. package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js.map → WorkflowPill-ZepbO_ny.js.map} +1 -1
  232. package/dashboard/dist/assets/WorkflowsDashboard-BNQVvyek.js +2 -0
  233. package/dashboard/dist/assets/{WorkflowsDashboard-B0r2lQXk.js.map → WorkflowsDashboard-BNQVvyek.js.map} +1 -1
  234. package/dashboard/dist/assets/{WorkflowsOverview-BTMc2PJ_.js → WorkflowsOverview-DswubNJN.js} +2 -2
  235. package/dashboard/dist/assets/{WorkflowsOverview-BTMc2PJ_.js.map → WorkflowsOverview-DswubNJN.js.map} +1 -1
  236. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DUiCVnZp.js → YamlWorkflowDetailPage-Cw9Dlmup.js} +11 -11
  237. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DUiCVnZp.js.map → YamlWorkflowDetailPage-Cw9Dlmup.js.map} +1 -1
  238. package/dashboard/dist/assets/{YamlWorkflowsPage-BAuXfwi0.js → YamlWorkflowsPage-DB8xnIXy.js} +2 -2
  239. package/dashboard/dist/assets/{YamlWorkflowsPage-BAuXfwi0.js.map → YamlWorkflowsPage-DB8xnIXy.js.map} +1 -1
  240. package/dashboard/dist/assets/{agents-BvmLCk4h.js → agents-BwEnf6N9.js} +2 -2
  241. package/dashboard/dist/assets/{agents-BvmLCk4h.js.map → agents-BwEnf6N9.js.map} +1 -1
  242. package/dashboard/dist/assets/{bots-f_tyhl4I.js → bots-CCmJTT2u.js} +2 -2
  243. package/dashboard/dist/assets/{bots-f_tyhl4I.js.map → bots-CCmJTT2u.js.map} +1 -1
  244. package/dashboard/dist/assets/{capabilities-DNo5bqLx.js → capabilities-BZHgp_nh.js} +2 -2
  245. package/dashboard/dist/assets/{capabilities-DNo5bqLx.js.map → capabilities-BZHgp_nh.js.map} +1 -1
  246. package/dashboard/dist/assets/{constants-BHkpVaqx.js → constants-CeBBTzf5.js} +2 -2
  247. package/dashboard/dist/assets/{constants-BHkpVaqx.js.map → constants-CeBBTzf5.js.map} +1 -1
  248. package/dashboard/dist/assets/{controlplane-Dyyj2Irb.js → controlplane-CyfwUlFA.js} +2 -2
  249. package/dashboard/dist/assets/{controlplane-Dyyj2Irb.js.map → controlplane-CyfwUlFA.js.map} +1 -1
  250. package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js +2 -0
  251. package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js.map +1 -0
  252. package/dashboard/dist/assets/index-3gbd5neL.js +67 -0
  253. package/dashboard/dist/assets/index-3gbd5neL.js.map +1 -0
  254. package/dashboard/dist/assets/index-BAAVTyZ-.js +2 -0
  255. package/dashboard/dist/assets/{index-DL83W7Gu.js.map → index-BAAVTyZ-.js.map} +1 -1
  256. package/dashboard/dist/assets/{index-CsKiRyhy.js → index-BC6Jenlo.js} +2 -2
  257. package/dashboard/dist/assets/{index-CsKiRyhy.js.map → index-BC6Jenlo.js.map} +1 -1
  258. package/dashboard/dist/assets/index-C7KHqOTQ.js +2 -0
  259. package/dashboard/dist/assets/{index-D7ESqn22.js.map → index-C7KHqOTQ.js.map} +1 -1
  260. package/dashboard/dist/assets/index-CDrqqbSR.js +3 -0
  261. package/dashboard/dist/assets/index-CDrqqbSR.js.map +1 -0
  262. package/dashboard/dist/assets/index-CVwzCZ43.js +2 -0
  263. package/dashboard/dist/assets/{index-DvxxrFBo.js.map → index-CVwzCZ43.js.map} +1 -1
  264. package/dashboard/dist/assets/index-CaGF6TCC.js +2 -0
  265. package/dashboard/dist/assets/index-CaGF6TCC.js.map +1 -0
  266. package/dashboard/dist/assets/index-ClVbfe4z.js +13 -0
  267. package/dashboard/dist/assets/index-ClVbfe4z.js.map +1 -0
  268. package/dashboard/dist/assets/{index-DWse7ERF.js → index-CuVkSmj5.js} +2 -2
  269. package/dashboard/dist/assets/{index-DWse7ERF.js.map → index-CuVkSmj5.js.map} +1 -1
  270. package/dashboard/dist/assets/{index-PcyGjmBm.js → index-DAuX_PlL.js} +2 -2
  271. package/dashboard/dist/assets/{index-PcyGjmBm.js.map → index-DAuX_PlL.js.map} +1 -1
  272. package/dashboard/dist/assets/{index-e2X-s0EQ.js → index-DBWS5QL8.js} +2 -2
  273. package/dashboard/dist/assets/{index-e2X-s0EQ.js.map → index-DBWS5QL8.js.map} +1 -1
  274. package/dashboard/dist/assets/index-DIWCI6HC.js +2 -0
  275. package/dashboard/dist/assets/{index-BNZknxFY.js.map → index-DIWCI6HC.js.map} +1 -1
  276. package/dashboard/dist/assets/{index-C-Xr2V3F.js → index-DZ8X_Gp4.js} +2 -2
  277. package/dashboard/dist/assets/{index-C-Xr2V3F.js.map → index-DZ8X_Gp4.js.map} +1 -1
  278. package/dashboard/dist/assets/index-Dh8MJl3L.css +1 -0
  279. package/dashboard/dist/assets/{knowledge-Coo6CKzo.js → knowledge-CqyLhUMg.js} +2 -2
  280. package/dashboard/dist/assets/{knowledge-Coo6CKzo.js.map → knowledge-CqyLhUMg.js.map} +1 -1
  281. package/dashboard/dist/assets/{mcp-Cz5eFnP_.js → mcp-Cvu6bFYH.js} +2 -2
  282. package/dashboard/dist/assets/{mcp-Cz5eFnP_.js.map → mcp-Cvu6bFYH.js.map} +1 -1
  283. package/dashboard/dist/assets/{mcp-query-BtnuO4LF.js → mcp-query-qC6A3e9l.js} +2 -2
  284. package/dashboard/dist/assets/{mcp-query-BtnuO4LF.js.map → mcp-query-qC6A3e9l.js.map} +1 -1
  285. package/dashboard/dist/assets/metadata-display-COo3mMCr.js +2 -0
  286. package/dashboard/dist/assets/metadata-display-COo3mMCr.js.map +1 -0
  287. package/dashboard/dist/assets/{personas-C2-LgpHQ.js → personas-BKN_lJuV.js} +2 -2
  288. package/dashboard/dist/assets/{personas-C2-LgpHQ.js.map → personas-BKN_lJuV.js.map} +1 -1
  289. package/dashboard/dist/assets/{pipelines-TuXQvUA-.js → pipelines-BldIfv85.js} +2 -2
  290. package/dashboard/dist/assets/{pipelines-TuXQvUA-.js.map → pipelines-BldIfv85.js.map} +1 -1
  291. package/dashboard/dist/assets/{tasks-OUzpu__z.js → tasks-B-Uay8uL.js} +2 -2
  292. package/dashboard/dist/assets/{tasks-OUzpu__z.js.map → tasks-B-Uay8uL.js.map} +1 -1
  293. package/dashboard/dist/assets/{topics-B8bdrBaW.js → topics-438EQogt.js} +2 -2
  294. package/dashboard/dist/assets/{topics-B8bdrBaW.js.map → topics-438EQogt.js.map} +1 -1
  295. package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js +2 -0
  296. package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js.map +1 -0
  297. package/dashboard/dist/assets/{useDebouncedValue-Cp5ZOtVE.js → useDebouncedValue-Cw8hYZ8y.js} +2 -2
  298. package/dashboard/dist/assets/{useDebouncedValue-Cp5ZOtVE.js.map → useDebouncedValue-Cw8hYZ8y.js.map} +1 -1
  299. package/dashboard/dist/assets/{useNamespace-DtQe3wZ5.js → useNamespace-D1218GQ8.js} +2 -2
  300. package/dashboard/dist/assets/{useNamespace-DtQe3wZ5.js.map → useNamespace-D1218GQ8.js.map} +1 -1
  301. package/dashboard/dist/assets/{useYamlActivityEvents-CS22c15X.js → useYamlActivityEvents-BAQf_y_U.js} +2 -2
  302. package/dashboard/dist/assets/{useYamlActivityEvents-CS22c15X.js.map → useYamlActivityEvents-BAQf_y_U.js.map} +1 -1
  303. package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js → vendor-icons-B7OcUM6b.js} +2 -2
  304. package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js.map → vendor-icons-B7OcUM6b.js.map} +1 -1
  305. package/dashboard/dist/assets/{yaml-workflows-HQIki3hI.js → yaml-workflows-CN01gEB0.js} +2 -2
  306. package/dashboard/dist/assets/{yaml-workflows-HQIki3hI.js.map → yaml-workflows-CN01gEB0.js.map} +1 -1
  307. package/dashboard/dist/index.html +3 -3
  308. package/docs/accumulator.md +113 -0
  309. package/docs/api/http/escalations.md +89 -0
  310. package/docs/api/http/roles.md +1 -0
  311. package/docs/api/http/workflows.md +28 -1
  312. package/docs/api/mcp/admin.md +40 -4
  313. package/docs/api/sdk/escalations.md +91 -0
  314. package/docs/api/sdk/roles.md +2 -0
  315. package/docs/architecture.md +1 -1
  316. package/docs/code-owned-configuration.md +3 -2
  317. package/docs/dashboard.md +11 -5
  318. package/docs/hitl/design.md +1 -1
  319. package/docs/hitl/escalation.md +37 -1
  320. package/docs/hitl/form.md +12 -7
  321. package/docs/hitl/invoke-form.md +10 -3
  322. package/docs/hitl/lookups.md +21 -0
  323. package/docs/hitl/pinned-views.md +4 -0
  324. package/docs/hitl/portal.md +97 -0
  325. package/docs/hitl/resolution.md +41 -0
  326. package/docs/hitl/x-lt-embed.md +1 -1
  327. package/docs/hitl/x-lt-invoke.md +95 -0
  328. package/docs/hitl/x-lt-list-schema.md +3 -1
  329. package/docs/hitl/x-lt-validation.md +50 -3
  330. package/docs/hitl/x-lt-widget.md +22 -0
  331. package/docs/hitl-guide.md +12 -2
  332. package/docs/scan-codes.md +15 -2
  333. package/docs/sdk.md +1 -1
  334. package/docs/workflows.md +2 -2
  335. package/package.json +4 -2
  336. package/dashboard/dist/assets/AgentsPage-D77JeViQ.js +0 -2
  337. package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js +0 -2
  338. package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js.map +0 -1
  339. package/dashboard/dist/assets/BulkAssignModal-BXiJnlqt.js +0 -2
  340. package/dashboard/dist/assets/CapabilitiesPage-D9TC2iKy.js +0 -2
  341. package/dashboard/dist/assets/DataTable-7C7riavf.js +0 -2
  342. package/dashboard/dist/assets/DataTable-7C7riavf.js.map +0 -1
  343. package/dashboard/dist/assets/EntityTimelinePanel-1lT3jkCM.js +0 -2
  344. package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js +0 -2
  345. package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js.map +0 -1
  346. package/dashboard/dist/assets/GraphInvokePage-DV7Y0fe2.js +0 -2
  347. package/dashboard/dist/assets/HomePage-G785SWcW.js +0 -2
  348. package/dashboard/dist/assets/ListToolbar-zPVYPg3W.js +0 -2
  349. package/dashboard/dist/assets/McpQueryPage-CNSNMagY.js +0 -2
  350. package/dashboard/dist/assets/McpRunsPage-B6rb5QBf.js +0 -2
  351. package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js +0 -3
  352. package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js.map +0 -1
  353. package/dashboard/dist/assets/OperatorDashboard-DBOscDnf.js +0 -2
  354. package/dashboard/dist/assets/ProcessesListPage-5NnysKFC.js +0 -2
  355. package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js +0 -2
  356. package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js.map +0 -1
  357. package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js +0 -8
  358. package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js.map +0 -1
  359. package/dashboard/dist/assets/RunAsSelector-BwZTJ4Yj.js +0 -2
  360. package/dashboard/dist/assets/ScanCodesPage-FiYIYB-m.js +0 -2
  361. package/dashboard/dist/assets/ScanStationPage-8CdOtbCD.js +0 -2
  362. package/dashboard/dist/assets/TasksListPage-BQNaSzCn.js +0 -2
  363. package/dashboard/dist/assets/ToolTestPanel-DvuLFWqQ.js +0 -2
  364. package/dashboard/dist/assets/TopicsPage-h-oyTeEJ.js +0 -2
  365. package/dashboard/dist/assets/WorkflowsDashboard-B0r2lQXk.js +0 -2
  366. package/dashboard/dist/assets/escalation-columns-DIigeTOK.js +0 -2
  367. package/dashboard/dist/assets/escalation-columns-DIigeTOK.js.map +0 -1
  368. package/dashboard/dist/assets/index-BMlQYOE1.js +0 -67
  369. package/dashboard/dist/assets/index-BMlQYOE1.js.map +0 -1
  370. package/dashboard/dist/assets/index-BNZknxFY.js +0 -2
  371. package/dashboard/dist/assets/index-Bpvfr4OW.css +0 -1
  372. package/dashboard/dist/assets/index-CegPUKpc.js +0 -3
  373. package/dashboard/dist/assets/index-CegPUKpc.js.map +0 -1
  374. package/dashboard/dist/assets/index-D7ESqn22.js +0 -2
  375. package/dashboard/dist/assets/index-DL83W7Gu.js +0 -2
  376. package/dashboard/dist/assets/index-DPLssnMW.js +0 -6
  377. package/dashboard/dist/assets/index-DPLssnMW.js.map +0 -1
  378. package/dashboard/dist/assets/index-DoETPlJP.js +0 -11
  379. package/dashboard/dist/assets/index-DoETPlJP.js.map +0 -1
  380. package/dashboard/dist/assets/index-DvxxrFBo.js +0 -2
  381. package/dashboard/dist/assets/metadata-display--TzK0REC.js +0 -2
  382. package/dashboard/dist/assets/metadata-display--TzK0REC.js.map +0 -1
  383. package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js +0 -2
  384. package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js.map +0 -1
  385. package/dashboard/dist/assets/seed-form-json-DvPsISxD.js +0 -2
  386. package/dashboard/dist/assets/seed-form-json-DvPsISxD.js.map +0 -1
  387. package/docs/compilation.md +0 -152
  388. package/docs/compiler.md +0 -311
  389. package/docs/contributing.md +0 -56
  390. package/docs/design-principles.md +0 -244
  391. package/docs/schema-exchange.md +0 -173
  392. package/docs/self-test.md +0 -106
  393. package/docs/story.md +0 -184
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-DoETPlJP.js","sources":["../../src/pages/workflows/registry/WorkflowConfigsPage.tsx","../../src/components/common/form/RolePicker.tsx","../../src/lib/parse.ts","../../src/pages/workflows/registry/config-form-types.ts","../../src/pages/workflows/registry/InputFormPreview.tsx","../../src/components/common/form/WorkflowIconPicker.tsx","../../src/pages/workflows/registry/WorkflowConfigDetailPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n useDiscoveredWorkflows,\n useDeleteWorkflowConfig,\n} from '../../../api/workflows';\nimport {\n Server,\n ShieldCheck, ShieldPlus, ShieldOff, Settings, Wrench, Play, UserCheck,\n} from 'lucide-react';\nimport { FilterBar, FilterSelect, FilterInput } from '../../../components/common/data/FilterBar';\nimport { ConfirmDeleteModal } from '../../../components/common/modal/ConfirmDeleteModal';\nimport { RolePill } from '../../../components/common/display/RolePill';\nimport { WorkflowPill } from '../../../components/common/display/WorkflowPill';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport type { DiscoveredWorkflow } from '../../../api/types';\n\n// ── Tier badge ─────────────────────────────────────────────────────────────────\n\nfunction TierBadge({ tier }: { tier: string }) {\n if (tier === 'certified')\n return <span className=\"inline-flex items-center gap-1 text-2xs font-medium text-status-success\"><ShieldCheck className=\"w-3 h-3\" />Certified</span>;\n if (tier === 'registered')\n return <span className=\"inline-flex items-center gap-1 text-2xs font-medium text-text-secondary\"><Settings className=\"w-3 h-3\" />Registered</span>;\n return <span className=\"inline-flex items-center gap-1 text-2xs font-medium text-text-quaternary\"><Wrench className=\"w-3 h-3\" />Durable</span>;\n}\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function WorkflowConfigsPage() {\n const navigate = useNavigate();\n const { data, isLoading } = useDiscoveredWorkflows();\n const deleteConfig = useDeleteWorkflowConfig();\n\n const [search, setSearch] = useState('');\n const [activeQueue, setActiveQueue] = useState<string | null>(null);\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n\n const allWorkflows: DiscoveredWorkflow[] = data ?? [];\n\n const queues = useMemo(\n () => [...new Set(allWorkflows.map((w) => w.task_queue).filter(Boolean) as string[])].sort(),\n [allWorkflows],\n );\n\n const grouped = useMemo(() => {\n const q = search.toLowerCase().trim();\n const targetQueues = activeQueue ? [activeQueue] : queues;\n return targetQueues\n .map((queue) => ({\n queue,\n workflows: allWorkflows.filter(\n (w) =>\n w.task_queue === queue &&\n (!q ||\n w.workflow_type.toLowerCase().includes(q) ||\n w.description?.toLowerCase().includes(q)),\n ),\n }))\n .filter((g) => g.workflows.length > 0);\n }, [allWorkflows, queues, search, activeQueue]);\n\n // Workflows with no queue\n const ungrouped = useMemo(() => {\n const q = search.toLowerCase().trim();\n if (activeQueue) return [];\n return allWorkflows.filter(\n (w) =>\n !w.task_queue &&\n (!q || w.workflow_type.toLowerCase().includes(q) || w.description?.toLowerCase().includes(q)),\n );\n }, [allWorkflows, search, activeQueue]);\n\n const handleRowClick = (row: DiscoveredWorkflow) => {\n if (row.registered) {\n navigate(`/workflows/registry/${encodeURIComponent(row.workflow_type)}`);\n } else {\n navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.workflow_type)}&task_queue=${encodeURIComponent(row.task_queue ?? '')}`);\n }\n };\n\n const handleDelete = () => {\n if (!confirmDelete) return;\n deleteConfig.mutate(confirmDelete, { onSuccess: () => setConfirmDelete(null) });\n };\n\n return (\n <div>\n <PageHeader\n title=\"Registered Workflows\"\n docsHash=\"#docs:dashboard.md:workflow-registry\"\n actions={\n <button onClick={() => navigate('/workflows/registry/new')} className=\"btn-primary text-xs\">\n Register Workflow\n </button>\n }\n />\n\n {/* Sticky filter bar: queue select + search */}\n {!isLoading && queues.length > 0 && (\n <FilterBar>\n <FilterSelect\n label=\"Queue\"\n value={activeQueue ?? ''}\n onChange={(v) => setActiveQueue(v || null)}\n options={queues.map((q) => ({ value: q, label: q }))}\n />\n <FilterInput\n label=\"Search\"\n value={search}\n onChange={setSearch}\n placeholder={`${allWorkflows.length} workflows…`}\n />\n </FilterBar>\n )}\n\n {/* Content */}\n {isLoading ? (\n <LoadingSkeleton />\n ) : grouped.length === 0 && ungrouped.length === 0 ? (\n <p className=\"text-sm text-text-tertiary mt-8\">\n {search || activeQueue ? 'No workflows match your filter.' : 'No workflows discovered yet.'}\n </p>\n ) : (\n <div className=\"space-y-10\">\n {grouped.map(({ queue, workflows }) => (\n <div key={queue}>\n <div className=\"sticky top-[60px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border\">\n <Server className=\"w-3 h-3 text-accent\" strokeWidth={1.5} />\n <h2 className=\"section-h2\">{queue}</h2>\n <span className=\"text-xs text-text-quaternary\">{workflows.length}</span>\n </div>\n <WorkflowTableHeader />\n <div className=\"divide-y divide-surface-border/30\">\n {workflows.map((wf) => (\n <WorkflowRow\n key={wf.workflow_type}\n wf={wf}\n onRowClick={handleRowClick}\n onDelete={setConfirmDelete}\n onNavigate={navigate}\n />\n ))}\n </div>\n </div>\n ))}\n\n {ungrouped.length > 0 && (\n <div>\n <div className=\"sticky top-[60px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border\">\n <Wrench className=\"w-3 h-3 text-text-quaternary\" strokeWidth={1.5} />\n <h2 className=\"section-h2\">No Queue</h2>\n <span className=\"text-xs text-text-quaternary\">{ungrouped.length}</span>\n </div>\n <WorkflowTableHeader />\n <div className=\"divide-y divide-surface-border/30\">\n {ungrouped.map((wf) => (\n <WorkflowRow\n key={wf.workflow_type}\n wf={wf}\n onRowClick={handleRowClick}\n onDelete={setConfirmDelete}\n onNavigate={navigate}\n />\n ))}\n </div>\n </div>\n )}\n </div>\n )}\n\n <ConfirmDeleteModal\n open={!!confirmDelete}\n onClose={() => setConfirmDelete(null)}\n onConfirm={handleDelete}\n title=\"Unregister Workflow\"\n description={\n <>\n Delete the registration for{' '}\n <span className=\"font-mono font-medium text-text-primary\">{confirmDelete}</span>? This\n removes its invocation settings, certification, and interceptor treatment; the workflow\n keeps running as a plain durable workflow. To demote certified → registered instead,\n open the workflow and uncheck Certify — that keeps every setting.\n </>\n }\n isPending={deleteConfig.isPending}\n error={deleteConfig.error as Error | null}\n />\n </div>\n );\n}\n\n// ── Column layout ─────────────────────────────────────────────────────────────\n// [Workflow 1fr] [Tier 7rem] [Access 13rem] [Actions 4.5rem]\nconst ROW_GRID = 'grid grid-cols-[minmax(0,1fr)_7rem_13rem_4.5rem] gap-x-6';\n\nfunction WorkflowTableHeader() {\n return (\n <div className={`${ROW_GRID} px-3 pb-2 pt-1`}>\n <span className=\"text-2xs font-medium text-text-quaternary\">Workflow</span>\n <span className=\"text-2xs font-medium text-text-quaternary\">Tier</span>\n <span className=\"text-2xs font-medium text-text-quaternary\">Access</span>\n <span />\n </div>\n );\n}\n\n// ── Workflow row ───────────────────────────────────────────────────────────────\n\nfunction WorkflowRow({\n wf,\n onRowClick,\n onDelete,\n onNavigate,\n}: {\n wf: DiscoveredWorkflow;\n onRowClick: (wf: DiscoveredWorkflow) => void;\n onDelete: (type: string) => void;\n onNavigate: (path: string) => void;\n}) {\n const escRoles = wf.roles ?? [];\n const invokeRoles = wf.invocation_roles ?? [];\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => onRowClick(wf)}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') onRowClick(wf); }}\n className={`group ${ROW_GRID} py-2 px-3 -mx-3 rounded-md cursor-pointer transition-colors items-center`}\n >\n {/* Col 1: Workflow name + description, single line */}\n <div className=\"flex items-center gap-3 min-w-0\">\n <WorkflowPill\n type={wf.workflow_type}\n size=\"md\"\n variant={wf.tier === 'certified' ? 'certified' : wf.tier === 'registered' ? 'registered' : 'durable'}\n />\n {wf.description && (\n <p className=\"flex-1 min-w-0 truncate text-2xs text-text-tertiary group-hover:text-text-secondary transition-colors\">\n {wf.description}\n </p>\n )}\n </div>\n\n {/* Col 2: Tier */}\n <div>\n <TierBadge tier={wf.tier ?? 'durable'} />\n </div>\n\n {/* Col 3: Access — escalation + invocation roles, single line */}\n <div className=\"flex items-center gap-1.5 min-w-0 overflow-hidden whitespace-nowrap\">\n {escRoles.length > 0 && (\n <>\n <span title=\"Escalation roles\"><ShieldCheck className=\"w-3 h-3 text-text-quaternary shrink-0\" /></span>\n {escRoles.map((r) => <RolePill key={`e-${r}`} role={r} />)}\n </>\n )}\n {invokeRoles.length > 0 && (\n <>\n <span title=\"Invocation roles\"><UserCheck className=\"w-3 h-3 text-text-quaternary shrink-0\" /></span>\n {invokeRoles.map((r) => <RolePill key={`i-${r}`} role={r} />)}\n </>\n )}\n {escRoles.length === 0 && invokeRoles.length === 0 && (\n <span className=\"text-xs text-text-quaternary\">—</span>\n )}\n </div>\n\n {/* Col 4: Actions — revealed on hover */}\n <div className=\"flex items-center justify-end gap-2.5 opacity-0 group-hover:opacity-100 transition-opacity\">\n {wf.invocable && (\n <button\n title=\"Invoke workflow\"\n onClick={(e) => { e.stopPropagation(); onNavigate(`/workflows/start?type=${encodeURIComponent(wf.workflow_type)}&mode=now`); }}\n className=\"text-text-quaternary hover:text-status-success transition-colors\"\n >\n <Play className=\"w-3.5 h-3.5\" />\n </button>\n )}\n {wf.tier === 'durable' && (\n <button\n title=\"Configure workflow\"\n onClick={(e) => { e.stopPropagation(); onNavigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(wf.workflow_type)}&task_queue=${encodeURIComponent(wf.task_queue ?? '')}`); }}\n className=\"text-text-quaternary hover:text-status-info transition-colors\"\n >\n <Wrench className=\"w-3.5 h-3.5\" />\n </button>\n )}\n {wf.tier === 'registered' && (\n <button\n title=\"Certify workflow\"\n onClick={(e) => { e.stopPropagation(); onNavigate(`/workflows/registry/${encodeURIComponent(wf.workflow_type)}`); }}\n className=\"text-text-quaternary hover:text-status-success transition-colors\"\n >\n <ShieldPlus className=\"w-3.5 h-3.5\" />\n </button>\n )}\n {wf.registered && (\n <button\n title=\"Unregister workflow\"\n onClick={(e) => { e.stopPropagation(); onDelete(wf.workflow_type); }}\n className=\"text-text-quaternary hover:text-status-warning transition-colors\"\n >\n <ShieldOff className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </div>\n </div>\n );\n}\n\n// ── Loading skeleton ───────────────────────────────────────────────────────────\n\nfunction LoadingSkeleton() {\n return (\n <div className=\"animate-pulse space-y-8 mt-4\">\n {[1, 2].map((i) => (\n <div key={i}>\n <div className=\"h-4 bg-surface-sunken rounded w-36 mb-4\" />\n <div className=\"space-y-4\">\n {[1, 2, 3].map((j) => (\n <div key={j} className=\"space-y-1.5\">\n <div className=\"h-3 bg-surface-sunken rounded w-48\" />\n <div className=\"h-3 bg-surface-sunken rounded w-full\" />\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { User, X, ChevronDown, Check } from 'lucide-react';\nimport { useRoles } from '../../../api/roles';\n\ninterface RolePickerProps {\n selected: string[];\n onChange: (roles: string[]) => void;\n /** Only allow one selection */\n single?: boolean;\n placeholder?: string;\n}\n\nexport function RolePicker({ selected, onChange, single, placeholder }: RolePickerProps) {\n const { data } = useRoles();\n const allRoles = data?.roles ?? [];\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n const toggle = (role: string) => {\n if (single) {\n onChange(selected.includes(role) ? [] : [role]);\n setOpen(false);\n } else {\n onChange(\n selected.includes(role)\n ? selected.filter((r) => r !== role)\n : [...selected, role],\n );\n }\n };\n\n const remove = (role: string) => {\n onChange(selected.filter((r) => r !== role));\n };\n\n const placeholderText = placeholder ?? (single ? 'Select role...' : 'Add roles...');\n\n return (\n <div ref={ref} className=\"relative\">\n {/* Selected pills + trigger */}\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className=\"flex flex-wrap items-center gap-1.5 w-full min-h-[34px] px-2 py-1.5 bg-surface-sunken border border-surface-border rounded-md text-left cursor-pointer hover:border-accent/40 transition-colors focus:ring-1 focus:ring-accent focus:outline-none\"\n >\n {selected.length === 0 && (\n <span className=\"text-xs text-text-tertiary\">{placeholderText}</span>\n )}\n {selected.map((role) => (\n <span\n key={role}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-2xs\"\n >\n <User className=\"w-2.5 h-2.5 shrink-0 text-accent/75\" />\n {role}\n <span\n role=\"button\"\n onClick={(e) => { e.stopPropagation(); remove(role); }}\n className=\"ml-0.5 hover:text-status-error transition-colors\"\n >\n <X className=\"w-2.5 h-2.5\" />\n </span>\n </span>\n ))}\n <ChevronDown className={`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${open ? 'rotate-180' : ''}`} />\n </button>\n\n {/* Dropdown */}\n {open && (\n <div className=\"absolute z-[100] mt-1 w-full bg-surface-raised border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto\">\n {allRoles.length === 0 ? (\n <p className=\"px-3 py-2 text-xs text-text-tertiary\">No roles defined</p>\n ) : (\n allRoles.map((role) => {\n const isSelected = selected.includes(role);\n return (\n <button\n key={role}\n type=\"button\"\n onClick={() => toggle(role)}\n className={`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${\n isSelected\n ? 'bg-accent/[0.06] text-accent'\n : 'text-text-primary hover:bg-surface-sunken'\n }`}\n >\n <User className=\"w-3 h-3 shrink-0 text-accent/60\" />\n <span className=\"flex-1\">{role}</span>\n {isSelected && <Check className=\"w-3 h-3 shrink-0\" />}\n </button>\n );\n })\n )}\n </div>\n )}\n </div>\n );\n}\n","export function splitCsv(s: string): string[] {\n return s\n .split(',')\n .map((v) => v.trim())\n .filter(Boolean);\n}\n\nexport function safeParseJson<T = unknown>(\n json: string,\n): { ok: true; data: T } | { ok: false; error: string } {\n try {\n return { ok: true, data: JSON.parse(json) as T };\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : 'Invalid JSON';\n return { ok: false, error: message };\n }\n}\n","import type { LTWorkflowConfig } from '../../../api/types';\n\nexport interface ConfigFormState {\n workflow_type: string;\n description: string;\n task_queue: string;\n default_role: string;\n invocable: boolean;\n roles: string;\n invocation_roles: string;\n consumes: string;\n envelope_schema: string;\n /** The x-lt-* input form the Invoke Tool page renders and the API enforces; empty = envelope template form. */\n input_schema: string;\n /** Curated icon name; empty = tier glyph. */\n icon: string;\n resolver_schema: string;\n cron_schedule: string;\n execute_as: string;\n /**\n * Explicit HITL certification, persisted on the registration. Unchecking\n * demotes certified → registered on save and keeps roles/consumes intact.\n */\n certified: boolean;\n}\n\nexport const EMPTY_FORM: ConfigFormState = {\n workflow_type: '',\n description: '',\n task_queue: '',\n default_role: 'reviewer',\n invocable: false,\n roles: '',\n invocation_roles: '',\n consumes: '',\n envelope_schema: '',\n input_schema: '',\n icon: '',\n resolver_schema: '',\n cron_schedule: '',\n execute_as: '',\n certified: false,\n};\n\nexport function configToForm(c: LTWorkflowConfig): ConfigFormState {\n const roles = (c.roles ?? []).join(', ');\n const consumes = (c.consumes ?? []).join(', ');\n return {\n workflow_type: c.workflow_type,\n description: c.description ?? '',\n task_queue: c.task_queue ?? '',\n default_role: c.default_role,\n invocable: c.invocable,\n roles,\n invocation_roles: (c.invocation_roles ?? []).join(', '),\n consumes,\n envelope_schema: c.envelope_schema ? JSON.stringify(c.envelope_schema, null, 2) : '',\n input_schema: c.input_schema ? JSON.stringify(c.input_schema, null, 2) : '',\n icon: c.icon ?? '',\n resolver_schema: c.resolver_schema ? JSON.stringify(c.resolver_schema, null, 2) : '',\n cron_schedule: c.cron_schedule ?? '',\n execute_as: c.execute_as ?? '',\n certified: c.certified,\n };\n}\n\nexport const STEP_LABELS = ['Identity', 'Invocation', 'Advanced'];\n\nexport function jsonValid(v: string): boolean {\n if (!v.trim()) return true;\n try { JSON.parse(v); return true; } catch { return false; }\n}\n\nexport function isStepValid(step: number, form: ConfigFormState): boolean {\n if (step === 1) return !!form.workflow_type.trim();\n if (step === 2) return jsonValid(form.envelope_schema) && jsonValid(form.input_schema);\n if (step === 3) return jsonValid(form.resolver_schema);\n return true;\n}\n\nexport const labelCls = 'label';\nexport const hintCls = 'hint';\nexport const jsonCls = 'input-json w-full';\n\nexport const DEFAULT_ENVELOPE = '{\\n \"data\": {},\\n \"metadata\": {}\\n}';\n","import { useEffect, useMemo, useState } from 'react';\nimport { ResolverForm } from '../../../components/escalation/ResolverForm';\nimport { seedFormJson } from '../../../lib/seed-form-json';\nimport { buildInvokeFormContext } from '../../../lib/invoke-context';\nimport type { ShowIfContext } from '../../../lib/x-lt-show-if';\n\nfunction parseSchema(text: string): Record<string, unknown> | null {\n if (!text.trim()) return null;\n try {\n const parsed = JSON.parse(text);\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) && parsed.properties ? parsed : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The input form rendered live from the editor text through the same\n * ResolverForm the Invoke Tool page uses. Interactive, so conditional sections\n * can be walked before saving. Nothing here submits.\n */\nexport function InputFormPreview({ schemaText }: { schemaText: string }) {\n const schema = useMemo(() => parseSchema(schemaText), [schemaText]);\n const seed = useMemo(() => (schema ? seedFormJson(schema) : ''), [schema]);\n const [json, setJson] = useState(seed);\n useEffect(() => { setJson(seed); }, [seed]);\n const context = useMemo<ShowIfContext>(() => ({ ...buildInvokeFormContext({}), resolver: null }), []);\n\n if (!schema) {\n return (\n <p className=\"text-2xs text-text-tertiary\">\n A schema with <code className=\"font-mono\">properties</code> previews here as the operator's form.\n </p>\n );\n }\n\n return (\n <div className=\"@container\" data-testid=\"input-form-preview\">\n <ResolverForm value={json} onChange={setJson} escalationContext={context} />\n </div>\n );\n}\n","import { useMemo, useState } from 'react';\nimport { Ban } from 'lucide-react';\nimport { filterWorkflowIcons, workflowIconGlyph } from '../../../lib/workflow-icons';\n\n/**\n * The curated icon grid with a filter above it: type part of a name or its\n * constant key to narrow the tiles. The current choice reads in accent; the\n * leading \"none\" tile returns to the tier glyph.\n */\nexport function WorkflowIconPicker({ value, onChange }: { value: string; onChange: (name: string) => void }) {\n const [query, setQuery] = useState('');\n const names = useMemo(() => filterWorkflowIcons(query), [query]);\n const Chosen = workflowIconGlyph(value);\n\n return (\n <div className=\"space-y-2\" data-testid=\"workflow-icon-picker\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Filter icons…\"\n aria-label=\"Filter icons\"\n className=\"input text-2xs py-1 w-40\"\n />\n <span className=\"flex items-center gap-1.5 text-2xs text-text-tertiary min-w-0\">\n {Chosen ? <Chosen className=\"w-3.5 h-3.5 text-accent shrink-0\" strokeWidth={1.5} /> : <Ban className=\"w-3.5 h-3.5 shrink-0\" strokeWidth={1.5} />}\n <span className=\"font-mono truncate\">{value || 'tier glyph'}</span>\n </span>\n </div>\n <div className=\"flex flex-wrap gap-1\" role=\"listbox\" aria-label=\"Workflow icon\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={!value}\n title=\"No icon (tier glyph)\"\n onClick={() => onChange('')}\n className={`p-1.5 rounded-md border transition-colors ${!value ? 'border-accent bg-accent/10 text-accent' : 'border-transparent text-text-quaternary hover:bg-surface-hover hover:text-text-secondary'}`}\n >\n <Ban className=\"w-4 h-4\" strokeWidth={1.5} />\n </button>\n {names.map((name) => {\n const Glyph = workflowIconGlyph(name)!;\n const active = value === name;\n return (\n <button\n key={name}\n type=\"button\"\n role=\"option\"\n aria-selected={active}\n title={name}\n onClick={() => onChange(name)}\n className={`p-1.5 rounded-md border transition-colors ${active ? 'border-accent bg-accent/10 text-accent' : 'border-transparent text-text-tertiary hover:bg-surface-hover hover:text-text-primary'}`}\n >\n <Glyph className=\"w-4 h-4\" strokeWidth={1.5} />\n </button>\n );\n })}\n {names.length === 0 && <p className=\"text-2xs text-text-tertiary px-1 py-1.5\">No icon matches.</p>}\n </div>\n </div>\n );\n}\n","import { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useParams, useNavigate, useSearchParams } from 'react-router-dom';\nimport {\n Code2, Play, ShieldOff, Eye,\n} from 'lucide-react';\nimport { useWorkflowConfigs, useUpsertWorkflowConfig, useDeleteWorkflowConfig, useJobs } from '../../../api/workflows';\nimport { ConfirmDeleteModal } from '../../../components/common/modal/ConfirmDeleteModal';\nimport { RolePicker } from '../../../components/common/form/RolePicker';\nimport { BotPicker } from '../../../components/common/form/BotPicker';\nimport { NamespacePill } from '../../../components/common/display/NamespacePill';\nimport { splitCsv } from '../../../lib/parse';\nimport { EMPTY_FORM, configToForm, jsonValid } from './config-form-types';\nimport { InputFormPreview } from './InputFormPreview';\nimport { WorkflowIconPicker } from '../../../components/common/form/WorkflowIconPicker';\nimport type { ConfigFormState } from './config-form-types';\n\n// ── Local helpers ─────────────────────────────────────────────────────────────\n\nfunction SectionHeader({ icon: Icon, color, children }: { icon: React.ElementType; color: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2 mb-4 pb-2 border-b border-surface-border\">\n <Icon className={`w-4 h-4 ${color}`} strokeWidth={1.5} />\n <h2 className=\"section-h2\">{children}</h2>\n </div>\n );\n}\n\nfunction Field({ label, hint, children }: { label: string; hint?: React.ReactNode; children: React.ReactNode }) {\n return (\n <div className=\"space-y-1.5\">\n <label className=\"label\">{label}</label>\n {children}\n {hint && <p className=\"hint\">{hint}</p>}\n </div>\n );\n}\n\nconst jsonCls = 'input-json w-full';\n\nfunction csvToArray(csv: string): string[] { return splitCsv(csv); }\nfunction arrayToCsv(arr: string[]): string { return arr.join(', '); }\n\nconst SYSTEM_WORKFLOWS = new Set([\n 'mcpQuery', 'mcpDeterministic', 'mcpQueryRouter', 'mcpTriage',\n 'mcpTriageRouter', 'mcpTriageDeterministic', 'insightQuery',\n]);\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function WorkflowConfigDetailPage() {\n const { workflowType } = useParams<{ workflowType: string }>();\n const isNew = !workflowType;\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { data: configs, isLoading } = useWorkflowConfigs();\n const upsert = useUpsertWorkflowConfig();\n const deleteConfig = useDeleteWorkflowConfig();\n const [confirmUnregister, setConfirmUnregister] = useState(false);\n\n const editing = configs?.find((c) => c.workflow_type === workflowType) ?? null;\n\n const { data: jobsData } = useJobs({ limit: 500 });\n const unregisteredTypes = useMemo(() => {\n const registeredSet = new Set((configs ?? []).map((c) => c.workflow_type));\n const allEntities = new Set((jobsData?.jobs ?? []).map((j: any) => j.entity));\n return [...allEntities]\n .filter((e: string) => !registeredSet.has(e) && !SYSTEM_WORKFLOWS.has(e))\n .sort();\n }, [configs, jobsData]);\n\n const prefillForm = useMemo((): ConfigFormState => {\n if (!isNew) return EMPTY_FORM;\n const prefillType = searchParams.get('workflow_type') ?? '';\n const prefillQueue = searchParams.get('task_queue') ?? '';\n return prefillType || prefillQueue\n ? { ...EMPTY_FORM, workflow_type: prefillType, task_queue: prefillQueue }\n : EMPTY_FORM;\n }, [isNew, searchParams]);\n\n const [form, setForm] = useState<ConfigFormState>(prefillForm);\n const [schemaError, setSchemaError] = useState('');\n const [initialized, setInitialized] = useState(false);\n\n const set = useCallback(\n (field: keyof ConfigFormState, value: string | boolean) =>\n setForm((f) => ({ ...f, [field]: value })),\n [],\n );\n\n useEffect(() => {\n if (initialized) return;\n if (isNew) { setForm(prefillForm); setInitialized(true); return; }\n if (editing) { setForm(configToForm(editing)); setInitialized(true); }\n }, [editing, isNew, initialized, prefillForm]);\n\n const handleSave = () => {\n if (!form.workflow_type.trim()) return;\n setSchemaError('');\n\n let envelope_schema: Record<string, unknown> | null = null;\n let input_schema: Record<string, unknown> | null = null;\n let resolver_schema: Record<string, unknown> | null = null;\n try {\n if (form.envelope_schema.trim()) envelope_schema = JSON.parse(form.envelope_schema);\n } catch { setSchemaError('Invalid JSON in Envelope Schema'); return; }\n try {\n if (form.input_schema.trim()) input_schema = JSON.parse(form.input_schema);\n } catch { setSchemaError('Invalid JSON in Input Form'); return; }\n try {\n if (form.resolver_schema.trim()) resolver_schema = JSON.parse(form.resolver_schema);\n } catch { setSchemaError('Invalid JSON in Resolver Schema'); return; }\n\n upsert.mutate(\n {\n workflow_type: form.workflow_type.trim(),\n description: form.description.trim() || null,\n task_queue: form.task_queue.trim() || null,\n default_role: form.default_role.trim() || 'reviewer',\n invocable: form.invocable,\n certified: form.certified,\n roles: splitCsv(form.roles),\n invocation_roles: splitCsv(form.invocation_roles),\n consumes: splitCsv(form.consumes),\n envelope_schema,\n input_schema,\n icon: form.icon || null,\n resolver_schema,\n cron_schedule: form.cron_schedule.trim() || null,\n execute_as: form.execute_as.trim() || null,\n },\n { onSuccess: () => navigate('/workflows/registry') },\n );\n };\n\n if (isLoading) {\n return (\n <div className=\"animate-pulse space-y-4\">\n <div className=\"h-8 bg-surface-sunken rounded w-64\" />\n <div className=\"h-40 bg-surface-sunken rounded\" />\n </div>\n );\n }\n if (!isNew && !editing) {\n return <p className=\"text-sm text-text-secondary\">Config not found.</p>;\n }\n\n const canSave = !!form.workflow_type.trim() && jsonValid(form.envelope_schema) && jsonValid(form.input_schema) && jsonValid(form.resolver_schema);\n const showPickList = isNew && !form.workflow_type && unregisteredTypes.length > 0;\n\n return (\n <div>\n {/* Hero */}\n <div className=\"flex items-start justify-between mb-8\">\n <div>\n <h1 className=\"text-3xl font-light font-mono text-text-primary\">\n {isNew ? 'New Workflow' : editing?.workflow_type ?? ''}\n </h1>\n {editing && (\n <div className=\"flex items-center gap-2 mt-2\">\n <NamespacePill namespace=\"durable\" />\n </div>\n )}\n </div>\n <div className=\"flex items-center gap-3 mt-1\">\n {editing && (\n <button\n onClick={() => setConfirmUnregister(true)}\n className=\"flex items-center gap-1.5 text-2xs text-status-warning hover:underline mr-3\"\n title=\"Delete this registration — the workflow returns to plain durable\"\n >\n <ShieldOff className=\"w-3 h-3\" strokeWidth={1.5} /> Unregister\n </button>\n )}\n <button onClick={() => navigate('/workflows/registry')} className=\"btn-ghost text-xs\">\n Cancel\n </button>\n <button\n onClick={handleSave}\n disabled={!canSave || upsert.isPending}\n className=\"btn-primary text-xs\"\n >\n {upsert.isPending ? 'Saving…' : isNew ? 'Register' : 'Save'}\n </button>\n </div>\n </div>\n\n {/* Three-column form */}\n <div className=\"grid grid-cols-1 @wall:grid-cols-3 gap-x-14 gap-y-10\">\n\n {/* ── Identity ─────────────────────────────────────────────────── */}\n <div>\n <SectionHeader icon={Code2} color=\"text-accent\">Identity</SectionHeader>\n <div className=\"space-y-5\">\n <Field\n label=\"Workflow Type\"\n hint=\"Register a workflow to configure invocation and HITL escalation routing.\"\n >\n {showPickList ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs text-text-secondary\">Select a durable workflow to register:</p>\n <div className=\"grid gap-1\">\n {(unregisteredTypes as string[]).map((type) => (\n <button\n key={type}\n onClick={() => set('workflow_type', type)}\n className=\"flex items-center gap-2 px-3 py-2 text-left text-xs font-mono rounded-md border border-surface-border hover:border-accent/50 hover:bg-accent/[0.04] transition-colors\"\n >\n {type}\n </button>\n ))}\n </div>\n <div className=\"flex items-center gap-2 pt-1\">\n <span className=\"text-2xs text-text-tertiary\">or</span>\n <input\n type=\"text\"\n onChange={(e) => set('workflow_type', e.target.value)}\n placeholder=\"Enter type manually\"\n className=\"input font-mono flex-1\"\n />\n </div>\n </div>\n ) : (\n <>\n <input\n type=\"text\"\n value={form.workflow_type}\n onChange={(e) => set('workflow_type', e.target.value)}\n disabled={!isNew}\n placeholder=\"reviewContent\"\n className=\"input font-mono w-full\"\n />\n {isNew && form.workflow_type && unregisteredTypes.length > 0 && (\n <button\n onClick={() => set('workflow_type', '')}\n className=\"text-2xs text-accent hover:underline mt-1\"\n >\n Choose from durable workflows\n </button>\n )}\n </>\n )}\n </Field>\n\n <Field label=\"Icon\" hint=\"Leads the workflow's row and heading on the Invoke Tool page so operators tell tools apart at a glance. Declared in code as WORKFLOW_ICONS.*\">\n <WorkflowIconPicker value={form.icon} onChange={(name) => set('icon', name)} />\n </Field>\n\n <Field label=\"Description\">\n <input\n type=\"text\"\n value={form.description}\n onChange={(e) => set('description', e.target.value)}\n placeholder=\"Describe what this workflow does\"\n className=\"input text-xs w-full\"\n />\n </Field>\n\n <Field label=\"Task Queue\" hint=\"Durable task queue this workflow listens on.\">\n <input\n type=\"text\"\n value={form.task_queue}\n onChange={(e) => set('task_queue', e.target.value)}\n placeholder=\"lt-review\"\n className=\"input font-mono w-full\"\n />\n </Field>\n </div>\n </div>\n\n {/* ── Invocation ───────────────────────────────────────────────── */}\n <div>\n <SectionHeader icon={Play} color=\"text-accent\">Invocation</SectionHeader>\n <div className=\"space-y-5\">\n <div className=\"space-y-1\">\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={form.invocable}\n onChange={(e) => set('invocable', e.target.checked)}\n className=\"w-4 h-4 rounded border-border accent-accent\"\n />\n <span className=\"text-xs text-text-primary font-medium\">Invocable</span>\n </label>\n <p className=\"hint\">Allow this workflow to be started from the dashboard or API.</p>\n </div>\n\n {form.invocable ? (\n <>\n <Field label=\"Run As\" hint=\"Bot identity to run under. Default runs as the invoking user.\">\n <BotPicker selected={form.execute_as} onChange={(id) => set('execute_as', id)} />\n </Field>\n\n <Field label=\"Invocation Roles\" hint=\"Only users with these roles can start this workflow. Empty = all authenticated users.\">\n <RolePicker\n selected={csvToArray(form.invocation_roles)}\n onChange={(roles) => set('invocation_roles', arrayToCsv(roles))}\n placeholder=\"Select roles…\"\n />\n </Field>\n\n <Field\n label=\"Input Form\"\n hint={<button type=\"button\" onClick={() => { window.location.hash = '#docs:hitl/invoke-form.md'; }} className=\"text-accent hover:underline\">Authoring reference →</button>}\n >\n <textarea\n value={form.input_schema}\n onChange={(e) => set('input_schema', e.target.value)}\n placeholder={'{\\n \"x-lt-layout\": \"two-column\",\\n \"required\": [\"serialNumber\"],\\n \"properties\": {\\n \"serialNumber\": { \"type\": \"string\", \"title\": \"Serial number\", \"description\": \"Read it off the label\" }\\n }\\n}'}\n className={jsonCls}\n rows={14}\n spellCheck={false}\n data-testid=\"input-form-editor\"\n />\n {form.input_schema.trim() && !jsonValid(form.input_schema) && (\n <p className=\"text-2xs text-status-error mt-1\">Invalid JSON</p>\n )}\n </Field>\n\n <Field\n label={form.input_schema.trim() ? 'Envelope Metadata' : 'Envelope Schema'}\n hint={form.input_schema.trim()\n ? <>With an input form, only <code className=\"font-mono\">metadata</code> is read from here and stamped on every run; <code className=\"font-mono\">data</code> comes from the form.</>\n : <>Pre-fills the JSON editor when invoking. Include <code className=\"font-mono\">data</code> (input) and optional <code className=\"font-mono\">metadata</code>. Declare an input form above for a rich, validated form instead.</>}\n >\n <textarea\n value={form.envelope_schema}\n onChange={(e) => set('envelope_schema', e.target.value)}\n placeholder={'{\\n \"data\": {},\\n \"metadata\": {}\\n}'}\n className={jsonCls}\n rows={8}\n spellCheck={false}\n />\n {form.envelope_schema.trim() && !jsonValid(form.envelope_schema) && (\n <p className=\"text-2xs text-status-error mt-1\">Invalid JSON</p>\n )}\n </Field>\n </>\n ) : (\n <p className=\"text-2xs text-text-tertiary py-2\">\n Enable <span className=\"font-medium text-text-secondary\">Invocable</span> to configure invocation roles and an input template.\n </p>\n )}\n </div>\n </div>\n\n {/* ── Preview ─────────────────────────────────────────────────── */}\n <div className=\"@wall:sticky @wall:top-0 self-start max-h-[calc(100vh-6rem)] overflow-y-auto\">\n <SectionHeader icon={Eye} color=\"text-accent\">Preview</SectionHeader>\n {form.invocable && form.input_schema.trim() && jsonValid(form.input_schema) ? (\n <InputFormPreview schemaText={form.input_schema} />\n ) : (\n <p className=\"text-2xs text-text-tertiary leading-relaxed\">\n {form.invocable\n ? 'Declare an Input Form and it previews here as the operator\\'s form, live as you type.'\n : 'Enable Invocable and declare an Input Form to preview the operator\\'s form here.'}\n </p>\n )}\n </div>\n </div>\n\n {(schemaError || upsert.error) && (\n <p className=\"text-xs text-status-error mt-8\">\n {schemaError || (upsert.error as Error).message}\n </p>\n )}\n\n <ConfirmDeleteModal\n open={confirmUnregister}\n onClose={() => setConfirmUnregister(false)}\n onConfirm={() =>\n deleteConfig.mutate(editing!.workflow_type, {\n onSuccess: () => navigate('/workflows/registry'),\n })\n }\n title=\"Unregister Workflow\"\n description={\n <>\n Delete the registration for{' '}\n <span className=\"font-mono font-medium text-text-primary\">{editing?.workflow_type}</span>?\n This removes its invocation settings, certification, and interceptor treatment; the\n workflow keeps running as a plain durable workflow. Escalation schemas versioned on\n roles are untouched.\n </>\n }\n isPending={deleteConfig.isPending}\n error={deleteConfig.error as Error | null}\n />\n </div>\n );\n}\n"],"names":["TierBadge","tier","jsxs","jsx","ShieldCheck","Settings","Wrench","WorkflowConfigsPage","navigate","useNavigate","data","isLoading","useDiscoveredWorkflows","deleteConfig","useDeleteWorkflowConfig","search","setSearch","useState","activeQueue","setActiveQueue","confirmDelete","setConfirmDelete","allWorkflows","queues","useMemo","w","grouped","q","queue","_a","g","ungrouped","handleRowClick","row","handleDelete","PageHeader","FilterBar","FilterSelect","v","FilterInput","LoadingSkeleton","workflows","Server","WorkflowTableHeader","wf","WorkflowRow","ConfirmDeleteModal","Fragment","ROW_GRID","onRowClick","onDelete","onNavigate","escRoles","invokeRoles","e","WorkflowPill","r","RolePill","UserCheck","Play","ShieldPlus","ShieldOff","i","j","RolePicker","selected","onChange","single","placeholder","useRoles","allRoles","open","setOpen","ref","useRef","useEffect","handler","toggle","role","remove","placeholderText","User","X","ChevronDown","isSelected","Check","splitCsv","s","EMPTY_FORM","configToForm","c","roles","consumes","jsonValid","parseSchema","text","parsed","InputFormPreview","schemaText","schema","seed","seedFormJson","json","setJson","context","buildInvokeFormContext","ResolverForm","WorkflowIconPicker","value","query","setQuery","names","filterWorkflowIcons","Chosen","workflowIconGlyph","Ban","name","Glyph","active","SectionHeader","Icon","color","children","Field","label","hint","jsonCls","csvToArray","csv","arrayToCsv","arr","SYSTEM_WORKFLOWS","WorkflowConfigDetailPage","workflowType","useParams","isNew","searchParams","useSearchParams","configs","useWorkflowConfigs","upsert","useUpsertWorkflowConfig","confirmUnregister","setConfirmUnregister","editing","jobsData","useJobs","unregisteredTypes","registeredSet","prefillForm","prefillType","prefillQueue","form","setForm","schemaError","setSchemaError","initialized","setInitialized","set","useCallback","field","f","handleSave","envelope_schema","input_schema","resolver_schema","canSave","showPickList","NamespacePill","Code2","type","BotPicker","id","Eye"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{a as d,j as s}from"./vendor-query-DvWWuNIB.js";import{h as F,i as C,g as u}from"./index-BMlQYOE1.js";import{u as M,a as T,b as O,S as $,c as A,d as D,e as R}from"./StreamMessageDetail-JwlbRiMn.js";import{u as z}from"./useFilterParams-DBRw1Hcv.js";import{u as E}from"./useNamespace-DtQe3wZ5.js";import{b as L}from"./api-path-u2Jf9QXS.js";import{D as I}from"./DataTable-7C7riavf.js";import{S as U}from"./StickyPagination-DRuqKhZt.js";import{F as q,b as x,a as _}from"./FilterBar-xwN_b5fj.js";import{P as B}from"./PageHeader-Di5Sz3an.js";import{L as V}from"./ListToolbar-zPVYPg3W.js";import{X as H,a1 as J}from"./vendor-icons-DeBdvyKJ.js";import"./vendor-react-_9U4mKFr.js";import"./controlplane-Dyyj2Irb.js";import"./EmptyState-DgC_6njU.js";function W(l,n){if(l.length<=n)return l;const a=Math.floor((n-1)/2);return`${l.slice(0,a)}…${l.slice(-a)}`}function ce(){const{namespace:l,available:n}=E("namespace"),{filters:a,setFilter:t,pagination:r,sort:c,setSort:h}=z({filters:{namespace:"",source:"worker",status:"",stream_name:"",msg_type:"",topic:"",workflow_name:"",jid:"",aid:""}}),[m,g]=d.useState(null),v=d.useMemo(()=>n.map(e=>({value:e,label:e})),[n]),{data:i,isLoading:b,refetch:j,isFetching:w}=M({namespace:a.namespace||l,source:a.source||"worker",limit:r.pageSize,offset:r.offset,sort_by:c.sort_by||"created_at",order:c.order||"desc",status:a.status||void 0,stream_name:a.stream_name||void 0,msg_type:a.msg_type||void 0,topic:a.topic||void 0,workflow_name:a.workflow_name||void 0,jid:a.jid||void 0,aid:a.aid||void 0}),p=(i==null?void 0:i.messages)??[],f=(i==null?void 0:i.total)??0,o=d.useMemo(()=>m?p.find(e=>e.id===m.id&&e.source===m.source)??m:null,[p,m]),S=!!o,[k,N]=d.useState(null);d.useEffect(()=>{o&&N(o)},[o]);const y=o??k,P=[{key:"stream_name",label:"Stream",sortable:!0,render:e=>s.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[s.jsx("span",{className:`w-2.5 h-2.5 shrink-0 rounded-full dot-ring ${D[e.status]}`,title:A[e.status]}),s.jsx("span",{className:"font-mono text-xs text-text-secondary truncate",title:e.stream_name,children:e.stream_name})]})},{key:"source",label:"Source",render:e=>s.jsx("span",{className:R,children:e.source}),className:"w-24"},{key:"created_at",label:"Created",sortable:!0,render:e=>s.jsx(u,{date:e.created_at,format:"relative",className:"text-xs text-text-secondary whitespace-nowrap"}),className:"w-32"},{key:"reserved_at",label:"Reserved",render:e=>e.reserved_at?s.jsx(u,{date:e.reserved_at,format:"relative",className:"text-xs text-text-secondary whitespace-nowrap"}):s.jsx("span",{className:"text-xs text-text-tertiary",children:"—"}),className:"w-32"},{key:"expired_at",label:"Processed",render:e=>e.expired_at?s.jsx(u,{date:e.expired_at,format:"relative",className:"text-xs text-text-secondary whitespace-nowrap"}):s.jsx("span",{className:"text-xs text-text-tertiary",children:"—"}),className:"w-32"},{key:"priority",label:"Pri",sortable:!0,render:e=>s.jsx("span",{className:"text-xs text-text-secondary",children:e.priority}),className:"w-14 text-right"},{key:"retry_attempt",label:"Retries",render:e=>s.jsxs("span",{className:"text-xs text-text-secondary whitespace-nowrap",children:[e.retry_attempt,"/",e.max_retry_attempts]}),className:"w-20"}];return s.jsxs("div",{className:"flex items-stretch min-w-0 -mt-10 -mr-10 -mb-16",children:[s.jsxs("div",{className:"flex-1 min-w-0 pt-10 pr-10",children:[s.jsx(B,{title:"Messages",docsHash:"#docs:dashboard.md:messages"}),s.jsxs(q,{actions:s.jsx(V,{onRefresh:()=>j(),isFetching:w,apiPath:L("/controlplane/stream-messages",{namespace:a.namespace||l,source:a.source||"worker",limit:r.pageSize,offset:r.offset,sort_by:c.sort_by||"created_at",order:c.order||"desc",status:a.status||void 0,stream_name:a.stream_name||void 0,msg_type:a.msg_type||void 0,topic:a.topic||void 0,workflow_name:a.workflow_name||void 0,jid:a.jid||void 0,aid:a.aid||void 0})}),children:[s.jsx(x,{label:"Namespace",value:a.namespace,onChange:e=>t("namespace",e),options:v,required:!0}),s.jsx(x,{label:"Source",value:a.source,onChange:e=>t("source",e),options:T,required:!0}),s.jsx(x,{label:"Status",value:a.status,onChange:e=>t("status",e),options:O}),s.jsx(_,{label:"Stream",value:a.stream_name,onChange:e=>t("stream_name",e),placeholder:"Filter by stream name…"}),s.jsx(_,{label:"Job ID",value:a.jid,onChange:e=>t("jid",e),placeholder:"Filter by jid…"}),[{key:"topic",label:"Topic",value:a.topic},{key:"workflow_name",label:"Workflow",value:a.workflow_name},{key:"aid",label:"Activity",value:a.aid},{key:"msg_type",label:"Type",value:a.msg_type}].filter(e=>e.value).map(e=>s.jsxs("button",{onClick:()=>t(e.key,""),className:"inline-flex items-center gap-1 px-2 py-0.5 text-2xs font-mono rounded-full bg-accent/15 text-accent hover:bg-accent/25 transition-colors",title:`Clear ${e.label} filter: ${e.value}`,children:[e.label,": ",W(e.value,12),s.jsx(H,{className:"w-2.5 h-2.5"})]},e.key))]}),s.jsx(I,{columns:P,data:p,keyFn:e=>`${e.source}:${e.id}`,isLoading:b,emptyMessage:"No stream messages found",onRowClick:e=>g(e),activeRowKey:o?`${o.source}:${o.id}`:null,sort:c,onSort:h,layout:"fixed"}),s.jsx(U,{page:r.page,totalPages:r.totalPages(f),onPageChange:r.setPage,total:f,pageSize:r.pageSize,onPageSizeChange:r.setPageSize})]}),s.jsx(F,{open:S,width:416,className:"self-stretch",children:s.jsx("div",{className:"h-full pl-4",children:s.jsx(C,{views:[{id:"detail",icon:J,label:"Message Detail",content:y?s.jsx($,{message:y,filters:{onFilterStatus:e=>t("status",e),onFilterStreamName:e=>t("stream_name",e),onFilterMsgType:e=>t("msg_type",e),onFilterTopic:e=>t("topic",e),onFilterWorkflow:e=>t("workflow_name",e),onFilterJid:e=>t("jid",e),onFilterAid:e=>t("aid",e)}}):null}],activeId:"detail",onViewChange:()=>{},onClose:()=>g(null),stickyClassName:"sticky top-0 z-10 h-[calc(100vh-5.25rem)] pt-9"})})})]})}export{ce as StreamMessagesPage};
2
- //# sourceMappingURL=index-DvxxrFBo.js.map
@@ -1,2 +0,0 @@
1
- const s=new Set(["form_schema","batch_keys"]);function a(e){return Object.entries(e??{}).filter(([t])=>!t.startsWith("_")&&!s.has(t))}export{a as d};
2
- //# sourceMappingURL=metadata-display--TzK0REC.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"metadata-display--TzK0REC.js","sources":["../../src/lib/metadata-display.ts"],"sourcesContent":["/** Metadata keys that are plumbing, not information for the person working the item.\n * batch_pending/batch_count stay visible — they are the batch progress facets. */\nconst HIDDEN_METADATA_KEYS = new Set(['form_schema', 'batch_keys']);\n\n/**\n * The metadata entries a person should see: platform plumbing (the embedded\n * form schema, underscore-prefixed keys) is filtered out of every facet\n * listing — the side panel, the scan info-choice screen, and any future\n * surface that walks a row's metadata.\n */\nexport function displayMetadataEntries(\n metadata: Record<string, unknown> | null | undefined,\n): [string, unknown][] {\n return Object.entries(metadata ?? {}).filter(\n ([k]) => !k.startsWith('_') && !HIDDEN_METADATA_KEYS.has(k),\n );\n}\n"],"names":["HIDDEN_METADATA_KEYS","displayMetadataEntries","metadata","k"],"mappings":"AAEA,MAAMA,EAAuB,IAAI,IAAI,CAAC,cAAe,YAAY,CAAC,EAQ3D,SAASC,EACdC,EACqB,CACrB,OAAO,OAAO,QAAQA,GAAY,CAAA,CAAE,EAAE,OACpC,CAAC,CAACC,CAAC,IAAM,CAACA,EAAE,WAAW,GAAG,GAAK,CAACH,EAAqB,IAAIG,CAAC,CAAA,CAE9D"}
@@ -1,2 +0,0 @@
1
- import{j as u}from"./vendor-query-DvWWuNIB.js";import{d as x,e as d,v as y}from"./ResolverForm-Dy0yirtP.js";import{ah as g}from"./vendor-icons-DeBdvyKJ.js";import{e as h}from"./EscalationListView-uuZRMSLB.js";const b={SCHEMA_VALIDATION:"schema_validation"};function C(t){return typeof t=="object"&&t!==null&&t.code===b.SCHEMA_VALIDATION&&Array.isArray(t.violations)}function O({errors:t,schema:e}){const i=r=>{const l=document.querySelector(`[data-field-key="${r}"]`);l&&(l.scrollIntoView({behavior:"smooth",block:"center"}),l.focus({preventScroll:!0}))};return t.length===0?u.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No errors to display."}):u.jsxs("div",{className:"space-y-1",role:"alert","aria-live":"polite",children:[u.jsxs("p",{className:"text-2xs font-semibold uppercase tracking-wider text-status-error mb-4",children:[t.length," ",t.length===1?"issue":"issues"," to resolve"]}),u.jsx("div",{className:"space-y-1.5",children:t.map(({field:r,message:l})=>{var o;return u.jsxs("button",{onClick:()=>i(r),className:"w-full text-left flex items-start gap-3 px-3 py-2.5 rounded hover:bg-status-error/5 transition-colors group",children:[u.jsx(g,{className:"w-3.5 h-3.5 mt-0.5 shrink-0 text-status-error/60 group-hover:text-status-error transition-colors"}),u.jsxs("div",{children:[u.jsx("p",{className:"text-2xs font-semibold text-text-primary leading-snug",children:x(r,(o=e==null?void 0:e.properties)==null?void 0:o[r])}),u.jsx("p",{className:"text-2xs text-text-tertiary group-hover:text-text-secondary transition-colors leading-snug mt-0.5",children:l})]})]},r)})}),u.jsx("p",{className:"text-2xs text-text-quaternary mt-4 px-3",children:"Click an issue to scroll to and focus the field."})]})}const A="x-lt-require-any";function v(t){const e=t==null?void 0:t[A];return Array.isArray(e)?e.filter(i=>Array.isArray(i)).map(i=>i.filter(r=>typeof r=="string"&&r.length>0)).filter(i=>i.length>0):[]}function N(t){return t==null?!1:typeof t=="string"?t.trim().length>0:!0}const j="x-lt-require-sum";function E(t){const e=t==null?void 0:t[j];if(!Array.isArray(e))return[];const i=[];for(const r of e){if(!r||typeof r!="object"||Array.isArray(r))continue;const{fields:l,minimum:o}=r;if(!Array.isArray(l))continue;const a=l.filter(n=>typeof n=="string"&&n.length>0);a.length!==0&&(o!==void 0&&typeof o!="number"||i.push({fields:a,minimum:typeof o=="number"?o:1}))}return i}function _(t){if(typeof t=="number"&&Number.isFinite(t))return t;if(typeof t=="string"&&t.trim()!==""){const e=Number(t);if(!Number.isNaN(e))return e}return 0}function R(t,e,i){if(!t)return[];const r=t.properties??{},l=new Set(t.required??[]),o={...i??{},resolver:e,input:e},a=[];for(const[n,s]of Object.entries(r)){if(!d(s["x-lt-showIf"],o))continue;const p=y(e[n],s,l.has(n),!0,o);p&&a.push({field:n,message:p})}for(const n of v(t)){const s=n.filter(c=>r[c]&&d(r[c]["x-lt-showIf"],o));if(s.length===0||s.some(c=>N(e[c])))continue;const p=s.map(c=>r[c].title??c);a.push({field:s[0],message:`Enter a value for at least one of: ${p.join(", ")}`})}for(const n of E(t)){const s=n.fields.filter(f=>r[f]&&d(r[f]["x-lt-showIf"],o));if(s.length===0||s.reduce((f,m)=>f+_(e[m]),0)>=n.minimum)continue;const c=s.map(f=>r[f].title??f);a.push({field:s[0],message:`Combined value of ${c.join(", ")} must be at least ${n.minimum}`})}return a}function F(t,e){let i;try{i=JSON.parse(t)}catch{return{payload:null,errors:[],parseError:"Invalid JSON"}}const r=i._form_schema;if(r){const a=R(r,i,e);if(a.length>0)return{payload:null,errors:a,parseError:null}}const{_form_schema:l,...o}=i;return{payload:h(o,r),errors:[],parseError:null}}export{O as E,F as b,C as i,R as v};
2
- //# sourceMappingURL=resolver-payload-C1dXB3n6.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolver-payload-C1dXB3n6.js","sources":["../../../types/validation.ts","../../src/components/escalation/ErrorsPanel.tsx","../../../shared/form-validation/x-lt-require-any.ts","../../../shared/form-validation/x-lt-require-sum.ts","../../../shared/form-validation/validate-resolver-payload.ts","../../src/lib/resolver-payload.ts"],"sourcesContent":["/**\n * Canonical validation-error shapes — one vocabulary across every surface.\n *\n * When server-side resolver schema enforcement rejects a payload, the API\n * layer returns status 422 with `LTValidationErrorBody` as the response body.\n * The same body shape flows to every consumer:\n * - HTTP routes serialize it as the JSON response body\n * - SDK callers receive it as `result.data` (with `result.code` set)\n * - MCP resolve tools return it as the tool's JSON error content\n * - the CLI prints the violation list beneath the error line\n * - the dashboard maps `violations` into the same errors panel the\n * pre-submission pass feeds\n */\n\n/** Machine-readable error codes carried on error envelopes and bodies. */\nexport const LT_ERROR_CODES = {\n /** The resolver payload failed the role's enforced form schema. */\n SCHEMA_VALIDATION: 'schema_validation',\n} as const;\n\nexport type LTErrorCode = (typeof LT_ERROR_CODES)[keyof typeof LT_ERROR_CODES];\n\n/**\n * One field-level violation — the same `{ field, message }` pair the dashboard\n * validation panel renders. Bulk surfaces add `escalationId` so a violation is\n * attributable to the row that produced it.\n */\nexport interface LTFieldViolation {\n field: string;\n message: string;\n escalationId?: string;\n}\n\n/** The 422 response body for a schema-validation rejection. */\nexport interface LTValidationErrorBody {\n /** Human-readable summary, e.g. \"resolverPayload failed schema validation (2 violations)\". */\n error: string;\n code: typeof LT_ERROR_CODES.SCHEMA_VALIDATION;\n /** Every field-level violation, in schema property order. */\n violations: LTFieldViolation[];\n /** The role whose enforced schema rejected the payload; null for a workflow input schema. */\n role: string | null;\n /** The schema version validated against; null when the role's live (unversioned) schema applied. */\n schemaVersion: number | null;\n /** The workflow whose input_schema rejected the data (invoke surface only). */\n workflowType?: string;\n}\n\n/** Narrow an unknown response body to the canonical validation-error shape. */\nexport function isValidationErrorBody(body: unknown): body is LTValidationErrorBody {\n return (\n typeof body === 'object' && body !== null\n && (body as Record<string, unknown>).code === LT_ERROR_CODES.SCHEMA_VALIDATION\n && Array.isArray((body as Record<string, unknown>).violations)\n );\n}\n","import { AlertCircle } from 'lucide-react';\nimport { deriveFieldLabel } from '../../lib/derive-field-label';\nimport type { FieldError } from '../../lib/field-validator';\n\n/**\n * The form's issue list. Each row names the field through its schema title\n * and, on click, scrolls to and focuses the input carrying that\n * data-field-key. Shared by the escalation side panel and the invoke panel.\n */\nexport function ErrorsPanel({ errors, schema }: { errors: FieldError[]; schema?: Record<string, unknown> | null }) {\n const focusField = (field: string) => {\n const el = document.querySelector<HTMLElement>(`[data-field-key=\"${field}\"]`);\n if (!el) return;\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n el.focus({ preventScroll: true });\n };\n\n if (errors.length === 0) {\n return <p className=\"text-xs text-text-tertiary italic\">No errors to display.</p>;\n }\n\n return (\n <div className=\"space-y-1\" role=\"alert\" aria-live=\"polite\">\n <p className=\"text-2xs font-semibold uppercase tracking-wider text-status-error mb-4\">\n {errors.length} {errors.length === 1 ? 'issue' : 'issues'} to resolve\n </p>\n <div className=\"space-y-1.5\">\n {errors.map(({ field, message }) => (\n <button\n key={field}\n onClick={() => focusField(field)}\n className=\"w-full text-left flex items-start gap-3 px-3 py-2.5 rounded hover:bg-status-error/5 transition-colors group\"\n >\n <AlertCircle className=\"w-3.5 h-3.5 mt-0.5 shrink-0 text-status-error/60 group-hover:text-status-error transition-colors\" />\n <div>\n <p className=\"text-2xs font-semibold text-text-primary leading-snug\">\n {deriveFieldLabel(field, (schema?.properties as Record<string, Record<string, unknown>> | undefined)?.[field])}\n </p>\n <p className=\"text-2xs text-text-tertiary group-hover:text-text-secondary transition-colors leading-snug mt-0.5\">\n {message}\n </p>\n </div>\n </button>\n ))}\n </div>\n <p className=\"text-2xs text-text-quaternary mt-4 px-3\">\n Click an issue to scroll to and focus the field.\n </p>\n </div>\n );\n}\n","/**\n * x-lt-require-any — \"at least one of this set\" as a root-schema token. A\n * form_schema declares groups of field names; a submission passes when every\n * group has a value in at least one member. The canonical case: a Left\n * quantity and a Right quantity where either satisfies, but blank-both fails.\n *\n * x-lt-require-any string[][] — e.g. [[\"left_quantity\", \"right_quantity\"]]\n *\n * Visibility rules compose: a member hidden by its `x-lt-showIf` (or naming\n * no schema property) can neither satisfy the group nor be demanded of the\n * submitter, and a group whose members are ALL hidden is waived. `false` and\n * `0` are answers; `''`, null, and undefined are not.\n */\n\nexport const X_LT_REQUIRE_ANY = 'x-lt-require-any';\n\n/**\n * The schema's require-any groups. Malformed declarations (non-array token,\n * non-array groups, non-string members) read as no groups — a bad token never\n * bricks submission.\n */\nexport function readRequireAnyGroups(\n schema: Record<string, unknown> | null | undefined,\n): string[][] {\n const raw = schema?.[X_LT_REQUIRE_ANY];\n if (!Array.isArray(raw)) return [];\n return raw\n .filter((group): group is unknown[] => Array.isArray(group))\n .map((group) => group.filter((m): m is string => typeof m === 'string' && m.length > 0))\n .filter((group) => group.length > 0);\n}\n\n/** Present = an actual answer: `false` and `0` count; `''`/null/undefined do not. */\nexport function hasRequireAnyValue(value: unknown): boolean {\n if (value === undefined || value === null) return false;\n if (typeof value === 'string') return value.trim().length > 0;\n return true;\n}\n","/**\n * x-lt-require-sum — \"these quantities must total at least N\" as a\n * root-schema token. Where x-lt-require-any asks that one member carry any\n * answer (so a count defaulting to `0` vacuously satisfies it), require-sum\n * reads the members as numbers and demands their sum reach a minimum. The\n * canonical case: a Left quantity and a Right quantity that both default to\n * `0`, where at least one side must be positive.\n *\n * x-lt-require-sum { fields: string[], minimum?: number }[]\n * — e.g. [{ \"fields\": [\"left_quantity\", \"right_quantity\"] }]\n *\n * `minimum` defaults to 1. Numbers contribute their value and numeric strings\n * coerce (the same reading as dynamic bounds); everything else contributes 0.\n * Visibility rules compose the same way as require-any: a member hidden by\n * its `x-lt-showIf` (or naming no schema property) contributes nothing and is\n * not demanded, and a group whose members are ALL hidden is waived.\n */\n\nexport const X_LT_REQUIRE_SUM = 'x-lt-require-sum';\n\nexport interface RequireSumGroup {\n fields: string[];\n minimum: number;\n}\n\n/**\n * The schema's require-sum groups. Malformed declarations (non-array token,\n * groups without a fields array, non-string members, non-numeric minimum)\n * read as no groups — a bad token never bricks submission.\n */\nexport function readRequireSumGroups(\n schema: Record<string, unknown> | null | undefined,\n): RequireSumGroup[] {\n const raw = schema?.[X_LT_REQUIRE_SUM];\n if (!Array.isArray(raw)) return [];\n const groups: RequireSumGroup[] = [];\n for (const entry of raw) {\n if (!entry || typeof entry !== 'object' || Array.isArray(entry)) continue;\n const { fields, minimum } = entry as Record<string, unknown>;\n if (!Array.isArray(fields)) continue;\n const members = fields.filter((m): m is string => typeof m === 'string' && m.length > 0);\n if (members.length === 0) continue;\n if (minimum !== undefined && typeof minimum !== 'number') continue;\n groups.push({ fields: members, minimum: typeof minimum === 'number' ? minimum : 1 });\n }\n return groups;\n}\n\n/** A member's numeric contribution: numbers as-is, numeric strings coerced, all else 0. */\nexport function requireSumContribution(value: unknown): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim() !== '') {\n const n = Number(value);\n if (!Number.isNaN(n)) return n;\n }\n return 0;\n}\n","/**\n * The full pre-submission validation pass over a resolver form schema — the\n * same pass on both sides of the wire. The dashboard runs it on the flat form\n * values before submitting; the API layer runs it on the submitted (bound,\n * nested) payload by inverting x-lt-bind first. Because both entry points\n * funnel into one loop, a payload that passes the client panel passes the\n * server gate, and a 422's violation list is exactly what the panel shows.\n *\n * Semantics per field:\n * - x-lt-showIf-hidden fields are skipped entirely (a field the submitter\n * cannot see never blocks submission)\n * - required (schema.required membership), with checklist/empty-object rules\n * - declared-type check (string/number/integer/boolean/array/object)\n * - enum membership\n * - x-lt-require-all against the checklist items resolved from context\n * - static + dynamic bounds (minimum/x-lt-minimum, lengths, patterns)\n *\n * Root-level x-lt-require-any groups run after the per-field pass: each group\n * needs a value in at least one visible member (all-hidden groups are waived).\n * x-lt-require-sum groups follow the same visibility rules but read members\n * as numbers: the group's visible members must sum to at least its minimum.\n *\n * The showIf/`resolver.*` domain is always the FLAT form representation, so a\n * condition like `resolver.approved` reads the same on both sides.\n */\nimport { type FieldError, validateField } from './field-validator';\nimport { evaluateShowIf, type ShowIfContext } from './x-lt-show-if';\nimport { mapPayloadToForm } from './x-lt-bind';\nimport { readRequireAnyGroups, hasRequireAnyValue } from './x-lt-require-any';\nimport { readRequireSumGroups, requireSumContribution } from './x-lt-require-sum';\n\nexport type { FieldError } from './field-validator';\n\n/**\n * The escalation-surface context the pass evaluates showIf conditions and\n * dynamic constraints against. `resolver` is supplied by the pass itself\n * (the flat form values under validation) — callers provide the rest.\n */\nexport type ResolverValidationContext = Omit<ShowIfContext, 'resolver' | 'input'>;\n\n/**\n * Validate FLAT form values against the form schema. This is the dashboard's\n * entry point (the values the user edits, keyed by field name).\n */\nexport function validateResolverForm(\n schema: Record<string, unknown> | null | undefined,\n formValues: Record<string, unknown>,\n ctx?: ResolverValidationContext | null,\n): FieldError[] {\n if (!schema) return [];\n const properties = (schema.properties ?? {}) as Record<string, Record<string, unknown>>;\n const required = new Set((schema.required as string[] | undefined) ?? []);\n const liveCtx: ShowIfContext = {\n ...(ctx ?? {}),\n resolver: formValues as Record<string, unknown>,\n input: formValues as Record<string, unknown>,\n };\n\n const errors: FieldError[] = [];\n for (const [field, fieldSchema] of Object.entries(properties)) {\n if (!evaluateShowIf(fieldSchema['x-lt-showIf'], liveCtx)) continue;\n const err = validateField(\n formValues[field],\n fieldSchema,\n required.has(field),\n true,\n liveCtx as Record<string, unknown>,\n );\n if (err) errors.push({ field, message: err });\n }\n\n // Require-any groups: at least one VISIBLE member per group carries a value.\n // A member hidden by showIf (or naming no property) can neither satisfy nor\n // be demanded; an all-hidden group is waived.\n for (const group of readRequireAnyGroups(schema)) {\n const visible = group.filter(\n (k) => properties[k] && evaluateShowIf(properties[k]['x-lt-showIf'], liveCtx),\n );\n if (visible.length === 0) continue;\n if (visible.some((k) => hasRequireAnyValue(formValues[k]))) continue;\n const titles = visible.map((k) => (properties[k].title as string | undefined) ?? k);\n errors.push({\n field: visible[0],\n message: `Enter a value for at least one of: ${titles.join(', ')}`,\n });\n }\n\n // Require-sum groups: the numeric values of VISIBLE members must total at\n // least the group's minimum. A `0` is a real number here — unlike\n // require-any, defaulted-zero quantities do not satisfy the group.\n for (const group of readRequireSumGroups(schema)) {\n const visible = group.fields.filter(\n (k) => properties[k] && evaluateShowIf(properties[k]['x-lt-showIf'], liveCtx),\n );\n if (visible.length === 0) continue;\n const total = visible.reduce((sum, k) => sum + requireSumContribution(formValues[k]), 0);\n if (total >= group.minimum) continue;\n const titles = visible.map((k) => (properties[k].title as string | undefined) ?? k);\n errors.push({\n field: visible[0],\n message: `Combined value of ${titles.join(', ')} must be at least ${group.minimum}`,\n });\n }\n return errors;\n}\n\n/**\n * Validate a SUBMITTED resolver payload (the bound, nested shape the workflow\n * consumes) against the form schema. This is the API layer's entry point: the\n * payload is inverted through each field's x-lt-bind path back to the flat\n * form representation, then run through the same pass the client uses.\n */\nexport function validateResolverPayload(\n schema: Record<string, unknown> | null | undefined,\n payload: Record<string, unknown>,\n ctx?: ResolverValidationContext | null,\n): FieldError[] {\n if (!schema) return [];\n const formValues = mapPayloadToForm(payload, schema as Record<string, any>);\n return validateResolverForm(schema, formValues, ctx);\n}\n","import { mapFormToPayload } from './x-lt-bind';\nimport { validateResolverForm, type FieldError } from './field-validator';\nimport type { ShowIfContext } from './x-lt-show-if';\n\nexport interface ResolverPayloadResult {\n /** The resolver payload ready to submit — null when the JSON is unparseable or validation failed. */\n payload: Record<string, unknown> | null;\n /** Field errors against the embedded _form_schema (empty when the form is valid). */\n errors: FieldError[];\n /** Set when the edited JSON string itself is malformed. */\n parseError: string | null;\n}\n\n/**\n * Build the resolver payload from the form's edited JSON string.\n *\n * 1. Parse the JSON — a malformed string yields `parseError`.\n * 2. Validate every visible field against the embedded `_form_schema` — hidden\n * fields (x-lt-showIf falsy against the live context) are skipped, matching\n * the server's enforcement pass. Any failures yield `errors`.\n * 3. Strip the UI-only schema and map flat form fields into their nested shape\n * via x-lt-bind — the payload IS the payload.\n *\n * The single path shared by the footer's Submit button and the submit-on-claim\n * shortcut, so both produce identical payloads and identical error lists.\n */\nexport function buildResolverPayload(\n json: string,\n context?: ShowIfContext,\n): ResolverPayloadResult {\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(json) as Record<string, unknown>;\n } catch {\n return { payload: null, errors: [], parseError: 'Invalid JSON' };\n }\n\n const schema = parsed._form_schema as Record<string, unknown> | undefined;\n if (schema) {\n const errors = validateResolverForm(schema, parsed, context);\n if (errors.length > 0) return { payload: null, errors, parseError: null };\n }\n\n const { _form_schema, ...formValues } = parsed;\n return {\n payload: mapFormToPayload(formValues, schema as Record<string, any> | undefined),\n errors: [],\n parseError: null,\n };\n}\n"],"names":["LT_ERROR_CODES","isValidationErrorBody","body","ErrorsPanel","errors","schema","focusField","field","el","jsx","jsxs","message","AlertCircle","deriveFieldLabel","_a","X_LT_REQUIRE_ANY","readRequireAnyGroups","raw","group","m","hasRequireAnyValue","value","X_LT_REQUIRE_SUM","readRequireSumGroups","groups","entry","fields","minimum","members","requireSumContribution","n","validateResolverForm","formValues","ctx","properties","required","liveCtx","fieldSchema","evaluateShowIf","err","validateField","visible","k","titles","sum","buildResolverPayload","json","context","parsed","_form_schema","mapFormToPayload"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{Z as i,aA as S,aJ as E,aK as C,l as A,o as R,U as L,aL as b,aM as T,y as p,aN as u,aO as O,aP as d,aQ as f,aR as P,aS as I,S as g,aT as h,aU as k,aD as B,J as F,z as W,b as m,aV as M,a as D,aW as N,aX as U,aY as w,ae as y,ao as H,aZ as K,a_ as G,a$ as _,b0 as Y,b1 as v,b2 as x,b3 as j,b4 as Z,a1 as q,M as J,b5 as V,b6 as X,al as z,L as Q,b7 as $,b8 as aa,a0 as ea,b9 as sa,ba as ra,bb as oa,bc as ta,G as la,bd as na,be as ca,bf as ia,bg as Sa,bh as Ea,bi as Ca,bj as Aa,p as Ra,a5 as La,bk as ba,ar as Ta,bl as pa,bm as ua,bn as Oa,bo as da,bp as fa,bq as Pa,br as Ia,f as ga,as as ha,bs as ka,bt as Ba,bu as Fa,ap as Wa,Y as ma}from"./vendor-icons-DeBdvyKJ.js";import{m as Ma}from"./EscalationListView-uuZRMSLB.js";const r={ACTIVITY:"Activity",ALERT:"AlertTriangle",ARCHIVE:"Archive",AWARD:"Award",BARCODE:"Barcode",BELL:"Bell",BOT:"Bot",BOX:"Box",BOXES:"Boxes",BUILDING:"Building2",CALENDAR:"Calendar",CAMERA:"Camera",CHECKLIST:"ListChecks",CLIPBOARD:"ClipboardList",CLIPBOARD_CHECK:"ClipboardCheck",CLOCK:"Clock",COG:"Cog",CPU:"Cpu",DATABASE:"Database",DOWNLOAD:"Download",DROPLETS:"Droplets",FACTORY:"Factory",FAN:"Fan",FILE:"FileText",FLAG:"Flag",FLAME:"Flame",GAUGE:"Gauge",HAMMER:"Hammer",HEART:"Heart",IMAGE:"Image",KEY:"Key",LAYERS:"Layers",LEAF:"Leaf",LIFEBUOY:"LifeBuoy",LOCK:"Lock",MAIL:"Mail",MAP:"Map",MEGAPHONE:"Megaphone",MESSAGE:"MessageSquare",PACKAGE:"Package",PALETTE:"Palette",PEN:"PenTool",PILL:"Pill",POWER:"Power",PRINTER:"Printer",RECEIPT:"Receipt",RECYCLE:"Recycle",REFRESH:"RefreshCw",ROCKET:"Rocket",ROUTE:"Route",RULER:"Ruler",SCALE:"Scale",SCAN:"ScanBarcode",SCISSORS:"Scissors",SEARCH:"Search",SEND:"Send",SERVER:"Server",SHIELD:"ShieldCheck",SHOPPING_CART:"ShoppingCart",SNOWFLAKE:"Snowflake",SPARKLES:"Sparkles",STAR:"Star",STORE:"Store",SUN:"Sun",TAG:"Tag",TEST_TUBE:"TestTube",THERMOMETER:"Thermometer",TRASH:"Trash2",TRUCK:"Truck",UPLOAD:"Upload",USER:"User",USERS:"Users",WAND:"Wand2",WAREHOUSE:"Warehouse",WIFI:"Wifi",WRENCH:"Wrench",ZAP:"Zap"},Da=new Set(Object.values(r));function Na(a){return typeof a=="string"&&Da.has(a)}const Ua={Activity:ma,AlertTriangle:Wa,Archive:Fa,Award:Ba,Barcode:ka,Bell:ha,Bot:ga,Box:Ia,Boxes:Pa,Building2:fa,Calendar:da,Camera:Oa,ClipboardCheck:ua,ClipboardList:pa,Clock:Ta,Cog:ba,Cpu:La,Database:Ra,Download:Aa,Droplets:Ca,Factory:Ea,Fan:Sa,FileText:ia,Flag:ca,Flame:na,Gauge:la,Hammer:ta,Heart:oa,Image:ra,Key:sa,Layers:ea,Leaf:aa,LifeBuoy:$,ListChecks:Q,Lock:z,Mail:X,Map:V,Megaphone:J,MessageSquare:q,Package:Z,Palette:j,PenTool:x,Pill:v,Power:Y,Printer:_,Receipt:G,Recycle:K,RefreshCw:H,Rocket:y,Route:w,Ruler:U,Scale:N,ScanBarcode:D,Scissors:M,Search:m,Send:W,Server:F,ShieldCheck:B,ShoppingCart:k,Snowflake:h,Sparkles:g,Star:I,Store:P,Sun:f,Tag:d,TestTube:O,Thermometer:u,Trash2:p,Truck:T,Upload:b,User:L,Users:R,Wand2:A,Warehouse:C,Wifi:E,Wrench:S,Zap:i},n=Object.values(r),wa=Object.fromEntries(Object.entries(r).map(([a,e])=>[e,a]));function Ka(a){return Na(a)?Ua[a]:null}function Ga(a){const e=a.trim().toLowerCase().replace(/[\s_-]+/g,"");return e?n.filter(s=>s.toLowerCase().includes(e)||wa[s].toLowerCase().replace(/_/g,"").includes(e)):[...n]}function _a(a){return{metadata:a??{}}}function Ya(a,e={}){const s=Ma(e,a),o={_form_schema:a};for(const[t,l]of Object.entries(a.properties??{})){const c=l.type==="object"?{}:"";o[t]=s[t]??l.default??c}return JSON.stringify(o,null,2)}export{_a as b,Ga as f,Ya as s,Ka as w};
2
- //# sourceMappingURL=seed-form-json-DvPsISxD.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed-form-json-DvPsISxD.js","sources":["../../../types/workflow-icons.ts","../../src/lib/workflow-icons.ts","../../../shared/form-validation/invoke-context.ts","../../src/lib/seed-form-json.ts"],"sourcesContent":["/**\n * The curated icon set a workflow may declare. Names are lucide icon names;\n * the dashboard maps each to its glyph and falls back to the tier glyph for\n * anything else. Declare in code as `icon: WORKFLOW_ICONS.PRINTER`.\n */\nexport const WORKFLOW_ICONS = {\n ACTIVITY: 'Activity',\n ALERT: 'AlertTriangle',\n ARCHIVE: 'Archive',\n AWARD: 'Award',\n BARCODE: 'Barcode',\n BELL: 'Bell',\n BOT: 'Bot',\n BOX: 'Box',\n BOXES: 'Boxes',\n BUILDING: 'Building2',\n CALENDAR: 'Calendar',\n CAMERA: 'Camera',\n CHECKLIST: 'ListChecks',\n CLIPBOARD: 'ClipboardList',\n CLIPBOARD_CHECK: 'ClipboardCheck',\n CLOCK: 'Clock',\n COG: 'Cog',\n CPU: 'Cpu',\n DATABASE: 'Database',\n DOWNLOAD: 'Download',\n DROPLETS: 'Droplets',\n FACTORY: 'Factory',\n FAN: 'Fan',\n FILE: 'FileText',\n FLAG: 'Flag',\n FLAME: 'Flame',\n GAUGE: 'Gauge',\n HAMMER: 'Hammer',\n HEART: 'Heart',\n IMAGE: 'Image',\n KEY: 'Key',\n LAYERS: 'Layers',\n LEAF: 'Leaf',\n LIFEBUOY: 'LifeBuoy',\n LOCK: 'Lock',\n MAIL: 'Mail',\n MAP: 'Map',\n MEGAPHONE: 'Megaphone',\n MESSAGE: 'MessageSquare',\n PACKAGE: 'Package',\n PALETTE: 'Palette',\n PEN: 'PenTool',\n PILL: 'Pill',\n POWER: 'Power',\n PRINTER: 'Printer',\n RECEIPT: 'Receipt',\n RECYCLE: 'Recycle',\n REFRESH: 'RefreshCw',\n ROCKET: 'Rocket',\n ROUTE: 'Route',\n RULER: 'Ruler',\n SCALE: 'Scale',\n SCAN: 'ScanBarcode',\n SCISSORS: 'Scissors',\n SEARCH: 'Search',\n SEND: 'Send',\n SERVER: 'Server',\n SHIELD: 'ShieldCheck',\n SHOPPING_CART: 'ShoppingCart',\n SNOWFLAKE: 'Snowflake',\n SPARKLES: 'Sparkles',\n STAR: 'Star',\n STORE: 'Store',\n SUN: 'Sun',\n TAG: 'Tag',\n TEST_TUBE: 'TestTube',\n THERMOMETER: 'Thermometer',\n TRASH: 'Trash2',\n TRUCK: 'Truck',\n UPLOAD: 'Upload',\n USER: 'User',\n USERS: 'Users',\n WAND: 'Wand2',\n WAREHOUSE: 'Warehouse',\n WIFI: 'Wifi',\n WRENCH: 'Wrench',\n ZAP: 'Zap',\n} as const;\n\nexport type WorkflowIconName = (typeof WORKFLOW_ICONS)[keyof typeof WORKFLOW_ICONS];\n\nconst NAMES = new Set<string>(Object.values(WORKFLOW_ICONS));\n\nexport function isWorkflowIcon(value: unknown): value is WorkflowIconName {\n return typeof value === 'string' && NAMES.has(value);\n}\n","import {\n Activity,\n AlertTriangle,\n Archive,\n Award,\n Barcode,\n Bell,\n Bot,\n Box,\n Boxes,\n Building2,\n Calendar,\n Camera,\n ClipboardCheck,\n ClipboardList,\n Clock,\n Cog,\n Cpu,\n Database,\n Download,\n Droplets,\n Factory,\n Fan,\n FileText,\n Flag,\n Flame,\n Gauge,\n Hammer,\n Heart,\n Image,\n Key,\n Layers,\n Leaf,\n LifeBuoy,\n ListChecks,\n Lock,\n Mail,\n Map,\n Megaphone,\n MessageSquare,\n Package,\n Palette,\n PenTool,\n Pill,\n Power,\n Printer,\n Receipt,\n Recycle,\n RefreshCw,\n Rocket,\n Route,\n Ruler,\n Scale,\n ScanBarcode,\n Scissors,\n Search,\n Send,\n Server,\n ShieldCheck,\n ShoppingCart,\n Snowflake,\n Sparkles,\n Star,\n Store,\n Sun,\n Tag,\n TestTube,\n Thermometer,\n Trash2,\n Truck,\n Upload,\n User,\n Users,\n Wand2,\n Warehouse,\n Wifi,\n Wrench,\n Zap,\n type LucideIcon,\n} from 'lucide-react';\nimport { WORKFLOW_ICONS, isWorkflowIcon, type WorkflowIconName } from '../../../types/workflow-icons';\n\nexport { WORKFLOW_ICONS, isWorkflowIcon };\nexport type { WorkflowIconName };\n\n// Static named imports keep the bundle to these glyphs alone; a namespace\n// lookup would ship the whole library.\nconst GLYPHS: Record<WorkflowIconName, LucideIcon> = {\n Activity,\n AlertTriangle,\n Archive,\n Award,\n Barcode,\n Bell,\n Bot,\n Box,\n Boxes,\n Building2,\n Calendar,\n Camera,\n ClipboardCheck,\n ClipboardList,\n Clock,\n Cog,\n Cpu,\n Database,\n Download,\n Droplets,\n Factory,\n Fan,\n FileText,\n Flag,\n Flame,\n Gauge,\n Hammer,\n Heart,\n Image,\n Key,\n Layers,\n Leaf,\n LifeBuoy,\n ListChecks,\n Lock,\n Mail,\n Map,\n Megaphone,\n MessageSquare,\n Package,\n Palette,\n PenTool,\n Pill,\n Power,\n Printer,\n Receipt,\n Recycle,\n RefreshCw,\n Rocket,\n Route,\n Ruler,\n Scale,\n ScanBarcode,\n Scissors,\n Search,\n Send,\n Server,\n ShieldCheck,\n ShoppingCart,\n Snowflake,\n Sparkles,\n Star,\n Store,\n Sun,\n Tag,\n TestTube,\n Thermometer,\n Trash2,\n Truck,\n Upload,\n User,\n Users,\n Wand2,\n Warehouse,\n Wifi,\n Wrench,\n Zap,\n};\n\n/** Every curated icon, in the order the picker shows them. */\nexport const WORKFLOW_ICON_NAMES: readonly WorkflowIconName[] = Object.values(WORKFLOW_ICONS);\n\n/** The constant key for a name (`Wrench` → `WRENCH`), for filtering by either. */\nexport const WORKFLOW_ICON_KEYS: Readonly<Record<WorkflowIconName, string>> = Object.fromEntries(\n Object.entries(WORKFLOW_ICONS).map(([key, name]) => [name, key]),\n) as Record<WorkflowIconName, string>;\n\n/** The glyph for a declared icon name; null for anything outside the curated set. */\nexport function workflowIconGlyph(name: string | null | undefined): LucideIcon | null {\n return isWorkflowIcon(name) ? GLYPHS[name] : null;\n}\n\n/** Names whose lucide name or constant key contains the query, case-insensitive. */\nexport function filterWorkflowIcons(query: string): WorkflowIconName[] {\n const q = query.trim().toLowerCase().replace(/[\\s_-]+/g, '');\n if (!q) return [...WORKFLOW_ICON_NAMES];\n return WORKFLOW_ICON_NAMES.filter((name) =>\n name.toLowerCase().includes(q) || WORKFLOW_ICON_KEYS[name].toLowerCase().replace(/_/g, '').includes(q));\n}\n","import type { ResolverValidationContext } from './validate-resolver-payload';\n\n/**\n * The context an invoke form validates and renders against. The pass itself\n * supplies the live values under `input` and `resolver`; the envelope\n * metadata is the only other domain an invoke form can reference.\n */\nexport function buildInvokeFormContext(\n metadata: Record<string, unknown> | null | undefined,\n): ResolverValidationContext {\n return { metadata: metadata ?? {} };\n}\n","import { mapPayloadToForm } from './x-lt-bind';\n\n/**\n * The initial JSON an x-lt-* form edits: the schema rides along as the\n * `_form_schema` sidecar and every property starts at its prefill, its\n * declared default, or the zero value for its type. Object fields start as\n * {} so a checklist round-trips as an object from the first interaction.\n */\nexport function seedFormJson(\n formSchema: Record<string, any>,\n prefillPayload: Record<string, unknown> = {},\n): string {\n const prefill = mapPayloadToForm(prefillPayload, formSchema);\n const initial: Record<string, unknown> = { _form_schema: formSchema };\n for (const [key, def] of Object.entries((formSchema.properties ?? {}) as Record<string, Record<string, any>>)) {\n const zero = def.type === 'object' ? {} : '';\n initial[key] = prefill[key] ?? def.default ?? zero;\n }\n return JSON.stringify(initial, null, 2);\n}\n"],"names":["WORKFLOW_ICONS","NAMES","isWorkflowIcon","value","GLYPHS","Activity","AlertTriangle","Archive","Award","Barcode","Bell","Bot","Box","Boxes","Building2","Calendar","Camera","ClipboardCheck","ClipboardList","Clock","Cog","Cpu","Database","Download","Droplets","Factory","Fan","FileText","Flag","Flame","Gauge","Hammer","Heart","Image","Key","Layers","Leaf","LifeBuoy","ListChecks","Lock","Mail","Map","Megaphone","MessageSquare","Package","Palette","PenTool","Pill","Power","Printer","Receipt","Recycle","RefreshCw","Rocket","Route","Ruler","Scale","ScanBarcode","Scissors","Search","Send","Server","ShieldCheck","ShoppingCart","Snowflake","Sparkles","Star","Store","Sun","Tag","TestTube","Thermometer","Trash2","Truck","Upload","User","Users","Wand2","Warehouse","Wifi","Wrench","Zap","WORKFLOW_ICON_NAMES","WORKFLOW_ICON_KEYS","key","name","workflowIconGlyph","filterWorkflowIcons","query","q","buildInvokeFormContext","metadata","seedFormJson","formSchema","prefillPayload","prefill","mapPayloadToForm","initial","def","zero"],"mappings":"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"}
@@ -1,152 +0,0 @@
1
- # The Compilation Pipeline
2
-
3
- Every AI-driven execution carries cost. An LLM reasons through each step, selects tools, interprets results, and decides what to do next. It works, but it is slow, non-deterministic, and consumes tokens on every run.
4
-
5
- Long Tail records what the LLM did, extracts the pattern, and compiles it into a deterministic workflow. The next time the same problem appears, it runs without an LLM — no reasoning, no token cost, same result.
6
-
7
- This guide follows a single query through the full lifecycle: dynamic execution, compilation, deterministic replay, and automatic routing. All steps take place in the dashboard's **Pipeline Designer** page (sidebar: **MCP Workflows → Pipeline Designer**).
8
-
9
- ---
10
-
11
- ## The Dynamic Execution
12
-
13
- Open **Pipeline Designer** from the sidebar. The page lists previous MCP query runs and provides a prompt field to start a new one. Describe what you need in natural language — for example, "Log into the dashboard, discover all navigation pages, and screenshot each one." Optionally constrain which MCP tool tags to search.
14
-
15
- When the query is submitted, the `mcpQuery` workflow starts. It discovers available tools by tag (GIN-indexed full-text search), then enters an agentic loop: the LLM selects a tool, calls it, reads the result, and decides the next step. Every tool call is checkpointed by the workflow engine. If the process crashes mid-execution, it resumes from the last checkpoint — no work is lost, no step runs twice.
16
-
17
- The run appears in the **Pipeline Designer** list once it completes. Click into it to open the **Compilation Wizard**.
18
-
19
- ---
20
-
21
- ## The Compilation Wizard
22
-
23
- The wizard has six steps, shown as numbered circles in a sticky bar at the top of the page. Each step represents one stage of converting the dynamic execution into a deployable deterministic workflow:
24
-
25
- 1. **Describe**
26
- 2. **Discover**
27
- 3. **Compile**
28
- 4. **Deploy**
29
- 5. **Test**
30
- 6. **Verify**
31
-
32
- Steps unlock sequentially — you must complete each before advancing.
33
-
34
- ### 1. Describe
35
-
36
- **Subtitle:** *Dynamic LLM-orchestrated execution — the discovery run*
37
-
38
- The first panel displays what the LLM produced: the input envelope on the left and the structured output on the right. Duration is shown. This is the reference point — whatever the compiled workflow produces will be compared against it.
39
-
40
- ### 2. Discover
41
-
42
- **Subtitle:** *Activity swimlane showing tool calls and their durations*
43
-
44
- A swimlane visualization of the execution. Each row is an MCP server, each block is a tool call, positioned on a time axis. The pattern is visible at a glance: the LLM logged in, extracted navigation links, then looped through each page to capture a screenshot.
45
-
46
- ### 3. Compile
47
-
48
- **Subtitle:** *Define the deterministic workflow tool from this execution*
49
-
50
- The workflow needs an identity. This panel presents a form with:
51
-
52
- - **Namespace** — a required alphanumeric identifier for the workflow's application scope.
53
- - **Tool Name** — the workflow's MCP tool name for discovery. This is how other agents and workflows will find and invoke it.
54
- - **Description** — auto-generated from the execution trace. Editable.
55
- - **Tags** — suggested from the execution trace. Add or remove tags to control discoverability.
56
-
57
- An optional **Refine compilation** toggle reveals a feedback textarea where you can provide additional instructions to the compiler.
58
-
59
- Clicking **Compile Pipeline** triggers the five-stage compilation pipeline:
60
-
61
- 1. **Extract** — parse the execution trace into an ordered step sequence
62
- 2. **Analyze** — detect iteration patterns (the screenshot loop), classify inputs as dynamic (user-provided) or fixed (implementation detail)
63
- 3. **Compile** — an LLM produces a blueprint with data-flow edges and session threading, guided by per-server **compile hints** stored in the database (e.g., which output fields to use as transform sources, how to thread browser session handles)
64
- 4. **Build** — generate a deterministic YAML DAG with activity wiring
65
- 5. **Validate** — check for missing wiring, lost session handles, broken iteration boundaries
66
-
67
- Once compilation succeeds, the panel switches to a read-only view showing the workflow name, status badge, namespace, topic, description, activity pipeline chain, and tags.
68
-
69
- ### 4. Deploy
70
-
71
- **Subtitle:** *Review configuration, input/output schemas, and YAML definition*
72
-
73
- The deploy panel displays the compiled YAML definition, input schema, and output schema. The YAML encodes the DAG: each step names an MCP tool, declares its inputs (either from the user's request or from a prior step's output), and specifies data-flow edges.
74
-
75
- Two toggle buttons are available:
76
-
77
- - **Recompile with Feedback** — provide notes to the compiler and regenerate the YAML.
78
- - **Manual Edit** — directly edit the YAML, schemas, or activity manifest.
79
-
80
- A version history panel on the right tracks all edits. The step label changes from "Deploy" to "Redeploy" when the workflow is already active.
81
-
82
- Clicking **Deploy & Activate** registers the workflow as a live MCP tool — tagged for discovery, versioned, invocable by any agent, workflow, or API call.
83
-
84
- ### 5. Test
85
-
86
- **Header:** *Compare Runs*
87
-
88
- The test panel runs the compiled workflow and compares it against the original dynamic execution. Two columns show:
89
-
90
- - **Left — Original MCP Query**: the dynamic LLM-orchestrated run with its input, output, and duration.
91
- - **Right — Compiled Pipeline Run**: the deterministic run with its input, output, and duration. A dropdown allows selecting from multiple test runs.
92
-
93
- Click **Run Test** to invoke the compiled workflow with the original input. An invocation modal appears with the pre-populated input schema.
94
-
95
- The difference is structural:
96
-
97
- | | Dynamic (LLM) | Deterministic |
98
- |---|---|---|
99
- | **Tool calls** | N (LLM selects each) | 1 pipeline (pre-wired DAG) |
100
- | **LLM usage** | Every step | Route + input extraction only |
101
- | **Determinism** | Varies per run | Identical every time |
102
-
103
- The deterministic path is faster because the LLM is used only at the edges — routing the request and extracting structured inputs from the prompt. The DAG itself executes tool calls directly with pre-wired data flow. No per-step reasoning, no tool selection, no interpretation.
104
-
105
- ### 6. Verify
106
-
107
- **Header:** *End-to-End Verification*
108
-
109
- The final panel confirms end-to-end routing. The original prompt is pre-filled in an editable textarea on the left. Click **Submit** to send it through the `mcpQueryRouter` — the same entry point any future request would use. A **Reset to original** button restores the prompt if you modify it.
110
-
111
- The right column shows the result: a status badge, confidence percentage (when the deterministic path is used), and the full output in a JSON viewer. A **RouterProgressTracker** displays real-time routing progress during execution.
112
-
113
- The router performs full-text search and tag matching to find candidate workflows, then uses an LLM judge to confirm scope. When confidence exceeds the threshold, the request goes straight to the compiled workflow.
114
-
115
- ```
116
- User prompt → Router → Discovery (FTS + tags) → LLM Judge
117
- │ │
118
- │ confidence ≥ 0.7 │ no match
119
- ▼ ▼
120
- Deterministic Dynamic
121
- (compiled DAG, no LLM) (agentic loop)
122
- ```
123
-
124
- ---
125
-
126
- ## How It Accumulates
127
-
128
- The first time a problem appears, the dynamic path runs. An LLM reasons through it — slow and expensive, but it works.
129
-
130
- The wizard compiles the solution into a deterministic pipeline. A human reviews the DAG, adjusts if needed, and deploys.
131
-
132
- Every subsequent occurrence is routed automatically. A single LLM call extracts structured inputs from the prompt, then the DAG executes without further reasoning.
133
-
134
- Each compiled workflow is itself a discoverable MCP tool. Other workflows and agents can invoke it. Solutions compose. The inventory of deterministic pathways grows with every problem the system solves, and the fraction of requests that require LLM reasoning shrinks.
135
-
136
- The dynamic path remains for genuinely new problems. But the long tail gets shorter.
137
-
138
- ---
139
-
140
- ## Compilation from Source Code
141
-
142
- The Pipeline Designer compiles from execution traces — the dynamic path. But there's a second entry point: compiling directly from source code.
143
-
144
- If you've written a durable workflow using the durable workflow API (`proxyActivities`, `sleep`, `condition`, `startChild`), you can compile it to a YAML DAG without executing it first. The `ltc` CLI reads your TypeScript source, extracts the orchestration structure, and produces an equivalent DAG that runs without replay overhead.
145
-
146
- ```bash
147
- ltc compile workflows/assembly-line.ts
148
- ```
149
-
150
- The source is the spec. The compiled YAML is the optimized execution. Both live in the repo.
151
-
152
- See the [Compiler Guide](compiler.md) for the full walkthrough.