@hotmeshio/long-tail 0.20.0 → 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 (351) 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/index.js +60 -0
  12. package/build/lib/db/schemas/036_role_portals.sql +12 -0
  13. package/build/routes/escalations/accumulate.d.ts +7 -0
  14. package/build/routes/escalations/accumulate.js +150 -0
  15. package/build/routes/escalations/index.js +5 -0
  16. package/build/sdk/index.d.ts +25 -0
  17. package/build/sdk/index.js +8 -0
  18. package/build/services/escalation/accumulate.d.ts +81 -0
  19. package/build/services/escalation/accumulate.js +154 -0
  20. package/build/services/escalation/index.d.ts +1 -0
  21. package/build/services/escalation/index.js +1 -0
  22. package/build/services/mcp/playwright-server/schemas.d.ts +2 -2
  23. package/build/services/orchestrator/condition.d.ts +40 -3
  24. package/build/services/orchestrator/condition.js +42 -2
  25. package/build/services/role/index.js +1 -0
  26. package/build/services/role/seed.js +6 -1
  27. package/build/services/role/sql.d.ts +6 -3
  28. package/build/services/role/sql.js +7 -2
  29. package/build/services/role/types.d.ts +38 -10
  30. package/build/services/role/types.js +10 -1
  31. package/build/services/scan-code/validate.js +16 -0
  32. package/build/shared/form-validation/display-only-widgets.d.ts +16 -0
  33. package/build/shared/form-validation/display-only-widgets.js +25 -0
  34. package/build/shared/form-validation/index.d.ts +2 -0
  35. package/build/shared/form-validation/index.js +2 -0
  36. package/build/shared/form-validation/x-lt-bind.d.ts +2 -14
  37. package/build/shared/form-validation/x-lt-bind.js +12 -8
  38. package/build/shared/form-validation/x-lt-invoke.d.ts +38 -0
  39. package/build/shared/form-validation/x-lt-invoke.js +103 -0
  40. package/build/system/mcp-servers/admin/escalations.js +39 -0
  41. package/build/system/mcp-servers/admin/schemas.d.ts +192 -13
  42. package/build/system/mcp-servers/admin/schemas.js +39 -3
  43. package/build/system/mcp-servers/admin/users.js +1 -0
  44. package/build/system/mcp-servers/docs.js +4 -0
  45. package/build/system/mcp-servers/human-queue-schemas.d.ts +85 -0
  46. package/build/system/mcp-servers/human-queue-schemas.js +19 -1
  47. package/build/system/mcp-servers/human-queue.d.ts +2 -0
  48. package/build/system/mcp-servers/human-queue.js +77 -0
  49. package/build/system/seed/tool-manifests-admin.d.ts +922 -103
  50. package/build/system/seed/tool-manifests-admin.js +4 -1
  51. package/build/system/seed/tool-manifests-escalation.d.ts +174 -0
  52. package/build/system/seed/tool-manifests-escalation.js +56 -0
  53. package/build/tsconfig.tsbuildinfo +1 -1
  54. package/build/types/escalation.d.ts +52 -0
  55. package/build/types/escalation.js +29 -1
  56. package/build/types/index.d.ts +2 -2
  57. package/build/types/index.js +3 -1
  58. package/build/types/scan-code.d.ts +24 -0
  59. package/build/types/scan-code.js +9 -0
  60. package/build/types/startup.d.ts +20 -0
  61. package/dashboard/dist/assets/{AdminDashboard-DplvDBti.js → AdminDashboard-uarpHB88.js} +2 -2
  62. package/dashboard/dist/assets/{AdminDashboard-DplvDBti.js.map → AdminDashboard-uarpHB88.js.map} +1 -1
  63. package/dashboard/dist/assets/{AgentConfigPage-D8Bf6YxO.js → AgentConfigPage-BcUaDD5E.js} +6 -6
  64. package/dashboard/dist/assets/{AgentConfigPage-D8Bf6YxO.js.map → AgentConfigPage-BcUaDD5E.js.map} +1 -1
  65. package/dashboard/dist/assets/{AgentDetailPage-BN8g0Y2G.js → AgentDetailPage-BaZBhK6i.js} +3 -3
  66. package/dashboard/dist/assets/{AgentDetailPage-BN8g0Y2G.js.map → AgentDetailPage-BaZBhK6i.js.map} +1 -1
  67. package/dashboard/dist/assets/AgentsPage-CuVFSDc4.js +2 -0
  68. package/dashboard/dist/assets/{AgentsPage-7JJBHku8.js.map → AgentsPage-CuVFSDc4.js.map} +1 -1
  69. package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js +2 -0
  70. package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js.map +1 -0
  71. package/dashboard/dist/assets/{BotPicker-CGCnIz8I.js → BotPicker-CClMby6B.js} +2 -2
  72. package/dashboard/dist/assets/{BotPicker-CGCnIz8I.js.map → BotPicker-CClMby6B.js.map} +1 -1
  73. package/dashboard/dist/assets/BulkAssignModal-BL8FRgkN.js +2 -0
  74. package/dashboard/dist/assets/{BulkAssignModal-NJBcoj-f.js.map → BulkAssignModal-BL8FRgkN.js.map} +1 -1
  75. package/dashboard/dist/assets/CapabilitiesPage-D53ogPor.js +2 -0
  76. package/dashboard/dist/assets/{CapabilitiesPage-F8dpNn9B.js.map → CapabilitiesPage-D53ogPor.js.map} +1 -1
  77. package/dashboard/dist/assets/{CollapsibleSection-BZW6VpCU.js → CollapsibleSection-ow8jpbtD.js} +2 -2
  78. package/dashboard/dist/assets/{CollapsibleSection-BZW6VpCU.js.map → CollapsibleSection-ow8jpbtD.js.map} +1 -1
  79. package/dashboard/dist/assets/{ConfirmDeleteModal-64adXLdq.js → ConfirmDeleteModal-CeEDt9iJ.js} +2 -2
  80. package/dashboard/dist/assets/{ConfirmDeleteModal-64adXLdq.js.map → ConfirmDeleteModal-CeEDt9iJ.js.map} +1 -1
  81. package/dashboard/dist/assets/{CountdownTimer-BxDub9d2.js → CountdownTimer-CSqyZMCG.js} +2 -2
  82. package/dashboard/dist/assets/{CountdownTimer-BxDub9d2.js.map → CountdownTimer-CSqyZMCG.js.map} +1 -1
  83. package/dashboard/dist/assets/{CredentialsPage-CnLzopLL.js → CredentialsPage-Dx7SxA23.js} +2 -2
  84. package/dashboard/dist/assets/{CredentialsPage-CnLzopLL.js.map → CredentialsPage-Dx7SxA23.js.map} +1 -1
  85. package/dashboard/dist/assets/{CronLabel-CAD5UYDT.js → CronLabel-LYPxpvNN.js} +2 -2
  86. package/dashboard/dist/assets/{CronLabel-CAD5UYDT.js.map → CronLabel-LYPxpvNN.js.map} +1 -1
  87. package/dashboard/dist/assets/DataTable-spX1dFyb.js +2 -0
  88. package/dashboard/dist/assets/DataTable-spX1dFyb.js.map +1 -0
  89. package/dashboard/dist/assets/{DropZone-XlcY8hEH.js → DropZone-f1o-GLM8.js} +2 -2
  90. package/dashboard/dist/assets/{DropZone-XlcY8hEH.js.map → DropZone-f1o-GLM8.js.map} +1 -1
  91. package/dashboard/dist/assets/{ElapsedCell-CwO4ufd0.js → ElapsedCell-BZJTSm9N.js} +2 -2
  92. package/dashboard/dist/assets/{ElapsedCell-CwO4ufd0.js.map → ElapsedCell-BZJTSm9N.js.map} +1 -1
  93. package/dashboard/dist/assets/EntityTimelinePanel-0wIIW2en.js +2 -0
  94. package/dashboard/dist/assets/{EntityTimelinePanel-CkF-oW-m.js.map → EntityTimelinePanel-0wIIW2en.js.map} +1 -1
  95. package/dashboard/dist/assets/{EscalationListSchemaPage-h9JO_q5f.js → EscalationListSchemaPage-CoYvtMzj.js} +3 -3
  96. package/dashboard/dist/assets/{EscalationListSchemaPage-h9JO_q5f.js.map → EscalationListSchemaPage-CoYvtMzj.js.map} +1 -1
  97. package/dashboard/dist/assets/EscalationListView-DWFHPufv.js +2 -0
  98. package/dashboard/dist/assets/EscalationListView-DWFHPufv.js.map +1 -0
  99. package/dashboard/dist/assets/{EscalationSchemaPage-mJFL5_Se.js → EscalationSchemaPage-C9Xu_A25.js} +3 -3
  100. package/dashboard/dist/assets/{EscalationSchemaPage-mJFL5_Se.js.map → EscalationSchemaPage-C9Xu_A25.js.map} +1 -1
  101. package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js +2 -0
  102. package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js.map +1 -0
  103. package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js +2 -0
  104. package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js.map +1 -0
  105. package/dashboard/dist/assets/{EscalationsOverview-DlXUFqWJ.js → EscalationsOverview-CW57FaP9.js} +2 -2
  106. package/dashboard/dist/assets/{EscalationsOverview-DlXUFqWJ.js.map → EscalationsOverview-CW57FaP9.js.map} +1 -1
  107. package/dashboard/dist/assets/{EventTable-Ike2xchn.js → EventTable-D1ctWhKf.js} +2 -2
  108. package/dashboard/dist/assets/{EventTable-Ike2xchn.js.map → EventTable-D1ctWhKf.js.map} +1 -1
  109. package/dashboard/dist/assets/{FilterBar-DMOR-O1c.js → FilterBar-C-iur-Nj.js} +2 -2
  110. package/dashboard/dist/assets/{FilterBar-DMOR-O1c.js.map → FilterBar-C-iur-Nj.js.map} +1 -1
  111. package/dashboard/dist/assets/GraphInvokePage-CcA_44M4.js +2 -0
  112. package/dashboard/dist/assets/{GraphInvokePage-CKtvWowP.js.map → GraphInvokePage-CcA_44M4.js.map} +1 -1
  113. package/dashboard/dist/assets/HomePage-Dc085ghJ.js +2 -0
  114. package/dashboard/dist/assets/{HomePage-BQ3Q791Q.js.map → HomePage-Dc085ghJ.js.map} +1 -1
  115. package/dashboard/dist/assets/ListToolbar-h_ziBt4O.js +2 -0
  116. package/dashboard/dist/assets/{ListToolbar-DdJzj472.js.map → ListToolbar-h_ziBt4O.js.map} +1 -1
  117. package/dashboard/dist/assets/{McpOverview-BbtrduWn.js → McpOverview-qXXhbNWV.js} +2 -2
  118. package/dashboard/dist/assets/{McpOverview-BbtrduWn.js.map → McpOverview-qXXhbNWV.js.map} +1 -1
  119. package/dashboard/dist/assets/{McpQueryDetailPage-C1L4T-Wt.js → McpQueryDetailPage-SEzSbZrd.js} +2 -2
  120. package/dashboard/dist/assets/{McpQueryDetailPage-C1L4T-Wt.js.map → McpQueryDetailPage-SEzSbZrd.js.map} +1 -1
  121. package/dashboard/dist/assets/McpQueryPage-Cy0V0kv9.js +2 -0
  122. package/dashboard/dist/assets/{McpQueryPage-CfJy7HZ7.js.map → McpQueryPage-Cy0V0kv9.js.map} +1 -1
  123. package/dashboard/dist/assets/{McpRunDetailPage-CA9yv7he.js → McpRunDetailPage-DjJO5vSb.js} +2 -2
  124. package/dashboard/dist/assets/{McpRunDetailPage-CA9yv7he.js.map → McpRunDetailPage-DjJO5vSb.js.map} +1 -1
  125. package/dashboard/dist/assets/McpRunsPage-BfjiJ8mM.js +2 -0
  126. package/dashboard/dist/assets/{McpRunsPage-D7QXjW9z.js.map → McpRunsPage-BfjiJ8mM.js.map} +1 -1
  127. package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js → NamespacePill-DADRJOUl.js} +2 -2
  128. package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js.map → NamespacePill-DADRJOUl.js.map} +1 -1
  129. package/dashboard/dist/assets/OperationsPage-dJcER0T_.js +3 -0
  130. package/dashboard/dist/assets/OperationsPage-dJcER0T_.js.map +1 -0
  131. package/dashboard/dist/assets/OperatorDashboard-zCkW4eqk.js +2 -0
  132. package/dashboard/dist/assets/{OperatorDashboard-sXNDh1Ph.js.map → OperatorDashboard-zCkW4eqk.js.map} +1 -1
  133. package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js → PageHeader-Csq434-v.js} +2 -2
  134. package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js.map → PageHeader-Csq434-v.js.map} +1 -1
  135. package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js → PageHeaderWithStats-CSnk1p5A.js} +2 -2
  136. package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js.map → PageHeaderWithStats-CSnk1p5A.js.map} +1 -1
  137. package/dashboard/dist/assets/{PersonaDetailPage-NeHD-Gra.js → PersonaDetailPage-Cx6L3Jvu.js} +2 -2
  138. package/dashboard/dist/assets/{PersonaDetailPage-NeHD-Gra.js.map → PersonaDetailPage-Cx6L3Jvu.js.map} +1 -1
  139. package/dashboard/dist/assets/{PersonasPage-DavKXRWX.js → PersonasPage-DOgGUlJl.js} +2 -2
  140. package/dashboard/dist/assets/{PersonasPage-DavKXRWX.js.map → PersonasPage-DOgGUlJl.js.map} +1 -1
  141. package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js +2 -0
  142. package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js.map +1 -0
  143. package/dashboard/dist/assets/{ProcessDetailPage-DkdKJGe6.js → ProcessDetailPage-BFcFSDUv.js} +2 -2
  144. package/dashboard/dist/assets/{ProcessDetailPage-DkdKJGe6.js.map → ProcessDetailPage-BFcFSDUv.js.map} +1 -1
  145. package/dashboard/dist/assets/ProcessesListPage-BaHV2cXp.js +2 -0
  146. package/dashboard/dist/assets/{ProcessesListPage-CjwVKe32.js.map → ProcessesListPage-BaHV2cXp.js.map} +1 -1
  147. package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js +7 -0
  148. package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js.map +1 -0
  149. package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js +8 -0
  150. package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js.map +1 -0
  151. package/dashboard/dist/assets/{RolePill-DhnVPK4q.js → RolePill-BafrASDX.js} +2 -2
  152. package/dashboard/dist/assets/{RolePill-DhnVPK4q.js.map → RolePill-BafrASDX.js.map} +1 -1
  153. package/dashboard/dist/assets/{RolesPage-OM9KM8Pg.js → RolesPage-DSqqKPbv.js} +2 -2
  154. package/dashboard/dist/assets/{RolesPage-OM9KM8Pg.js.map → RolesPage-DSqqKPbv.js.map} +1 -1
  155. package/dashboard/dist/assets/RunAsSelector-B29iWwel.js +2 -0
  156. package/dashboard/dist/assets/{RunAsSelector-fFMt1bGe.js.map → RunAsSelector-B29iWwel.js.map} +1 -1
  157. package/dashboard/dist/assets/{ScanCodesPage-AujH-pPQ.js → ScanCodesPage-S8aAJfnC.js} +2 -2
  158. package/dashboard/dist/assets/{ScanCodesPage-AujH-pPQ.js.map → ScanCodesPage-S8aAJfnC.js.map} +1 -1
  159. package/dashboard/dist/assets/{ScanSchemeDetailPage-eKQpmsC_.js → ScanSchemeDetailPage-CUBRAtmJ.js} +2 -2
  160. package/dashboard/dist/assets/{ScanSchemeDetailPage-eKQpmsC_.js.map → ScanSchemeDetailPage-CUBRAtmJ.js.map} +1 -1
  161. package/dashboard/dist/assets/ScanStationPage-R9t1-CeQ.js +2 -0
  162. package/dashboard/dist/assets/{ScanStationPage-C1_ppDoZ.js.map → ScanStationPage-R9t1-CeQ.js.map} +1 -1
  163. package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js → ScopeBadge-b6MIBiYD.js} +2 -2
  164. package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js.map → ScopeBadge-b6MIBiYD.js.map} +1 -1
  165. package/dashboard/dist/assets/{StickyPagination-B91Pk9xh.js → StickyPagination-CkW_A507.js} +2 -2
  166. package/dashboard/dist/assets/{StickyPagination-B91Pk9xh.js.map → StickyPagination-CkW_A507.js.map} +1 -1
  167. package/dashboard/dist/assets/{StreamMessageDetail-C7SPqaJt.js → StreamMessageDetail-yzWX0wac.js} +2 -2
  168. package/dashboard/dist/assets/{StreamMessageDetail-C7SPqaJt.js.map → StreamMessageDetail-yzWX0wac.js.map} +1 -1
  169. package/dashboard/dist/assets/{SwimlaneTimeline-BcHR8ylf.js → SwimlaneTimeline-Cf4DXFxj.js} +2 -2
  170. package/dashboard/dist/assets/{SwimlaneTimeline-BcHR8ylf.js.map → SwimlaneTimeline-Cf4DXFxj.js.map} +1 -1
  171. package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js → TagInput-ZrIIrEUP.js} +2 -2
  172. package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js.map → TagInput-ZrIIrEUP.js.map} +1 -1
  173. package/dashboard/dist/assets/{TaskDetailPage-Bqj0I_I0.js → TaskDetailPage-DCDcEps9.js} +2 -2
  174. package/dashboard/dist/assets/{TaskDetailPage-Bqj0I_I0.js.map → TaskDetailPage-DCDcEps9.js.map} +1 -1
  175. package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js → TaskQueuePill-DkQ1uc6y.js} +2 -2
  176. package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js.map → TaskQueuePill-DkQ1uc6y.js.map} +1 -1
  177. package/dashboard/dist/assets/TasksListPage-BBATgpf7.js +2 -0
  178. package/dashboard/dist/assets/{TasksListPage-BB1f79lL.js.map → TasksListPage-BBATgpf7.js.map} +1 -1
  179. package/dashboard/dist/assets/{TimeAgo-BFnODmNe.js → TimeAgo-CSNVEjch.js} +2 -2
  180. package/dashboard/dist/assets/{TimeAgo-BFnODmNe.js.map → TimeAgo-CSNVEjch.js.map} +1 -1
  181. package/dashboard/dist/assets/{TimestampCell-BXgLOBsr.js → TimestampCell-Du1nBrPn.js} +2 -2
  182. package/dashboard/dist/assets/{TimestampCell-BXgLOBsr.js.map → TimestampCell-Du1nBrPn.js.map} +1 -1
  183. package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js → ToolPill-Baxm02L6.js} +2 -2
  184. package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js.map → ToolPill-Baxm02L6.js.map} +1 -1
  185. package/dashboard/dist/assets/ToolTestPanel-CF-h_5Rg.js +2 -0
  186. package/dashboard/dist/assets/{ToolTestPanel-Bwe3J5lj.js.map → ToolTestPanel-CF-h_5Rg.js.map} +1 -1
  187. package/dashboard/dist/assets/{TopicDetailPage-DAF07vZ9.js → TopicDetailPage-Dr1UmWcp.js} +3 -3
  188. package/dashboard/dist/assets/{TopicDetailPage-DAF07vZ9.js.map → TopicDetailPage-Dr1UmWcp.js.map} +1 -1
  189. package/dashboard/dist/assets/TopicsPage-CUUo-Ylf.js +2 -0
  190. package/dashboard/dist/assets/{TopicsPage-C1gxBUap.js.map → TopicsPage-CUUo-Ylf.js.map} +1 -1
  191. package/dashboard/dist/assets/{UserName-BzXJUE6q.js → UserName-kBh1dc39.js} +2 -2
  192. package/dashboard/dist/assets/{UserName-BzXJUE6q.js.map → UserName-kBh1dc39.js.map} +1 -1
  193. package/dashboard/dist/assets/{WorkflowExecutionPage-SkRU5cRX.js → WorkflowExecutionPage-CCRSbnDx.js} +2 -2
  194. package/dashboard/dist/assets/{WorkflowExecutionPage-SkRU5cRX.js.map → WorkflowExecutionPage-CCRSbnDx.js.map} +1 -1
  195. package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js → WorkflowPill-ZepbO_ny.js} +2 -2
  196. package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js.map → WorkflowPill-ZepbO_ny.js.map} +1 -1
  197. package/dashboard/dist/assets/WorkflowsDashboard-BNQVvyek.js +2 -0
  198. package/dashboard/dist/assets/{WorkflowsDashboard-CZAqRk1N.js.map → WorkflowsDashboard-BNQVvyek.js.map} +1 -1
  199. package/dashboard/dist/assets/{WorkflowsOverview-BoN44VTE.js → WorkflowsOverview-DswubNJN.js} +2 -2
  200. package/dashboard/dist/assets/{WorkflowsOverview-BoN44VTE.js.map → WorkflowsOverview-DswubNJN.js.map} +1 -1
  201. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CqjhtdJf.js → YamlWorkflowDetailPage-Cw9Dlmup.js} +11 -11
  202. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CqjhtdJf.js.map → YamlWorkflowDetailPage-Cw9Dlmup.js.map} +1 -1
  203. package/dashboard/dist/assets/{YamlWorkflowsPage-CwnJkzyb.js → YamlWorkflowsPage-DB8xnIXy.js} +2 -2
  204. package/dashboard/dist/assets/{YamlWorkflowsPage-CwnJkzyb.js.map → YamlWorkflowsPage-DB8xnIXy.js.map} +1 -1
  205. package/dashboard/dist/assets/{agents-gV0Ys-sY.js → agents-BwEnf6N9.js} +2 -2
  206. package/dashboard/dist/assets/{agents-gV0Ys-sY.js.map → agents-BwEnf6N9.js.map} +1 -1
  207. package/dashboard/dist/assets/{bots-B97itB3I.js → bots-CCmJTT2u.js} +2 -2
  208. package/dashboard/dist/assets/{bots-B97itB3I.js.map → bots-CCmJTT2u.js.map} +1 -1
  209. package/dashboard/dist/assets/{capabilities-CR9xZgGd.js → capabilities-BZHgp_nh.js} +2 -2
  210. package/dashboard/dist/assets/{capabilities-CR9xZgGd.js.map → capabilities-BZHgp_nh.js.map} +1 -1
  211. package/dashboard/dist/assets/{constants-BHkpVaqx.js → constants-CeBBTzf5.js} +2 -2
  212. package/dashboard/dist/assets/{constants-BHkpVaqx.js.map → constants-CeBBTzf5.js.map} +1 -1
  213. package/dashboard/dist/assets/{controlplane-YxvP1KCa.js → controlplane-CyfwUlFA.js} +2 -2
  214. package/dashboard/dist/assets/{controlplane-YxvP1KCa.js.map → controlplane-CyfwUlFA.js.map} +1 -1
  215. package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js +2 -0
  216. package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js.map +1 -0
  217. package/dashboard/dist/assets/index-3gbd5neL.js +67 -0
  218. package/dashboard/dist/assets/index-3gbd5neL.js.map +1 -0
  219. package/dashboard/dist/assets/index-BAAVTyZ-.js +2 -0
  220. package/dashboard/dist/assets/{index-BQpV-DTG.js.map → index-BAAVTyZ-.js.map} +1 -1
  221. package/dashboard/dist/assets/{index-B9BBCqLI.js → index-BC6Jenlo.js} +2 -2
  222. package/dashboard/dist/assets/{index-B9BBCqLI.js.map → index-BC6Jenlo.js.map} +1 -1
  223. package/dashboard/dist/assets/index-C7KHqOTQ.js +2 -0
  224. package/dashboard/dist/assets/{index-Bp9KBLT5.js.map → index-C7KHqOTQ.js.map} +1 -1
  225. package/dashboard/dist/assets/index-CDrqqbSR.js +3 -0
  226. package/dashboard/dist/assets/index-CDrqqbSR.js.map +1 -0
  227. package/dashboard/dist/assets/index-CVwzCZ43.js +2 -0
  228. package/dashboard/dist/assets/{index-CFbo9FU9.js.map → index-CVwzCZ43.js.map} +1 -1
  229. package/dashboard/dist/assets/index-CaGF6TCC.js +2 -0
  230. package/dashboard/dist/assets/index-CaGF6TCC.js.map +1 -0
  231. package/dashboard/dist/assets/index-ClVbfe4z.js +13 -0
  232. package/dashboard/dist/assets/{index-Cfvkl2J0.js.map → index-ClVbfe4z.js.map} +1 -1
  233. package/dashboard/dist/assets/{index-DMeaiKgf.js → index-CuVkSmj5.js} +2 -2
  234. package/dashboard/dist/assets/{index-DMeaiKgf.js.map → index-CuVkSmj5.js.map} +1 -1
  235. package/dashboard/dist/assets/{index-ipqwPavs.js → index-DAuX_PlL.js} +2 -2
  236. package/dashboard/dist/assets/{index-ipqwPavs.js.map → index-DAuX_PlL.js.map} +1 -1
  237. package/dashboard/dist/assets/{index-CIpHj4di.js → index-DBWS5QL8.js} +2 -2
  238. package/dashboard/dist/assets/{index-CIpHj4di.js.map → index-DBWS5QL8.js.map} +1 -1
  239. package/dashboard/dist/assets/index-DIWCI6HC.js +2 -0
  240. package/dashboard/dist/assets/{index-CUZ6LYye.js.map → index-DIWCI6HC.js.map} +1 -1
  241. package/dashboard/dist/assets/{index-DwOnWeu8.js → index-DZ8X_Gp4.js} +2 -2
  242. package/dashboard/dist/assets/{index-DwOnWeu8.js.map → index-DZ8X_Gp4.js.map} +1 -1
  243. package/dashboard/dist/assets/index-Dh8MJl3L.css +1 -0
  244. package/dashboard/dist/assets/{knowledge-XX6cW4Ob.js → knowledge-CqyLhUMg.js} +2 -2
  245. package/dashboard/dist/assets/{knowledge-XX6cW4Ob.js.map → knowledge-CqyLhUMg.js.map} +1 -1
  246. package/dashboard/dist/assets/{mcp-CH13hNH2.js → mcp-Cvu6bFYH.js} +2 -2
  247. package/dashboard/dist/assets/{mcp-CH13hNH2.js.map → mcp-Cvu6bFYH.js.map} +1 -1
  248. package/dashboard/dist/assets/{mcp-query-Duydd3JA.js → mcp-query-qC6A3e9l.js} +2 -2
  249. package/dashboard/dist/assets/{mcp-query-Duydd3JA.js.map → mcp-query-qC6A3e9l.js.map} +1 -1
  250. package/dashboard/dist/assets/metadata-display-COo3mMCr.js +2 -0
  251. package/dashboard/dist/assets/metadata-display-COo3mMCr.js.map +1 -0
  252. package/dashboard/dist/assets/{personas-mDk4lLQS.js → personas-BKN_lJuV.js} +2 -2
  253. package/dashboard/dist/assets/{personas-mDk4lLQS.js.map → personas-BKN_lJuV.js.map} +1 -1
  254. package/dashboard/dist/assets/{pipelines-B5GcgCeF.js → pipelines-BldIfv85.js} +2 -2
  255. package/dashboard/dist/assets/{pipelines-B5GcgCeF.js.map → pipelines-BldIfv85.js.map} +1 -1
  256. package/dashboard/dist/assets/{tasks-CItmNsRp.js → tasks-B-Uay8uL.js} +2 -2
  257. package/dashboard/dist/assets/{tasks-CItmNsRp.js.map → tasks-B-Uay8uL.js.map} +1 -1
  258. package/dashboard/dist/assets/{topics-CJYG7BX5.js → topics-438EQogt.js} +2 -2
  259. package/dashboard/dist/assets/{topics-CJYG7BX5.js.map → topics-438EQogt.js.map} +1 -1
  260. package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js +2 -0
  261. package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js.map +1 -0
  262. package/dashboard/dist/assets/{useDebouncedValue-BrwgXcp8.js → useDebouncedValue-Cw8hYZ8y.js} +2 -2
  263. package/dashboard/dist/assets/{useDebouncedValue-BrwgXcp8.js.map → useDebouncedValue-Cw8hYZ8y.js.map} +1 -1
  264. package/dashboard/dist/assets/{useNamespace-CHty0HAS.js → useNamespace-D1218GQ8.js} +2 -2
  265. package/dashboard/dist/assets/{useNamespace-CHty0HAS.js.map → useNamespace-D1218GQ8.js.map} +1 -1
  266. package/dashboard/dist/assets/{useYamlActivityEvents-CoTsia7t.js → useYamlActivityEvents-BAQf_y_U.js} +2 -2
  267. package/dashboard/dist/assets/{useYamlActivityEvents-CoTsia7t.js.map → useYamlActivityEvents-BAQf_y_U.js.map} +1 -1
  268. package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js → vendor-icons-B7OcUM6b.js} +2 -2
  269. package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js.map → vendor-icons-B7OcUM6b.js.map} +1 -1
  270. package/dashboard/dist/assets/{yaml-workflows-CiWwx5rM.js → yaml-workflows-CN01gEB0.js} +2 -2
  271. package/dashboard/dist/assets/{yaml-workflows-CiWwx5rM.js.map → yaml-workflows-CN01gEB0.js.map} +1 -1
  272. package/dashboard/dist/index.html +3 -3
  273. package/docs/accumulator.md +113 -0
  274. package/docs/api/http/escalations.md +89 -0
  275. package/docs/api/http/roles.md +1 -0
  276. package/docs/api/sdk/escalations.md +91 -0
  277. package/docs/api/sdk/roles.md +2 -0
  278. package/docs/architecture.md +1 -1
  279. package/docs/code-owned-configuration.md +2 -1
  280. package/docs/dashboard.md +10 -4
  281. package/docs/hitl/design.md +1 -1
  282. package/docs/hitl/escalation.md +37 -1
  283. package/docs/hitl/invoke-form.md +4 -0
  284. package/docs/hitl/pinned-views.md +4 -0
  285. package/docs/hitl/portal.md +97 -0
  286. package/docs/hitl/resolution.md +41 -0
  287. package/docs/hitl/x-lt-embed.md +1 -1
  288. package/docs/hitl/x-lt-invoke.md +95 -0
  289. package/docs/hitl/x-lt-list-schema.md +3 -1
  290. package/docs/hitl/x-lt-widget.md +1 -0
  291. package/docs/hitl-guide.md +8 -1
  292. package/docs/scan-codes.md +15 -2
  293. package/docs/sdk.md +1 -1
  294. package/docs/workflows.md +2 -2
  295. package/package.json +4 -2
  296. package/dashboard/dist/assets/AgentsPage-7JJBHku8.js +0 -2
  297. package/dashboard/dist/assets/AvailableEscalationsPage-lz5qwSjg.js +0 -2
  298. package/dashboard/dist/assets/AvailableEscalationsPage-lz5qwSjg.js.map +0 -1
  299. package/dashboard/dist/assets/BulkAssignModal-NJBcoj-f.js +0 -2
  300. package/dashboard/dist/assets/CapabilitiesPage-F8dpNn9B.js +0 -2
  301. package/dashboard/dist/assets/DataTable-7C7riavf.js +0 -2
  302. package/dashboard/dist/assets/DataTable-7C7riavf.js.map +0 -1
  303. package/dashboard/dist/assets/EntityTimelinePanel-CkF-oW-m.js +0 -2
  304. package/dashboard/dist/assets/EscalationListView-AHW2xtlr.js +0 -2
  305. package/dashboard/dist/assets/EscalationListView-AHW2xtlr.js.map +0 -1
  306. package/dashboard/dist/assets/GraphInvokePage-CKtvWowP.js +0 -2
  307. package/dashboard/dist/assets/HomePage-BQ3Q791Q.js +0 -2
  308. package/dashboard/dist/assets/ListToolbar-DdJzj472.js +0 -2
  309. package/dashboard/dist/assets/McpQueryPage-CfJy7HZ7.js +0 -2
  310. package/dashboard/dist/assets/McpRunsPage-D7QXjW9z.js +0 -2
  311. package/dashboard/dist/assets/OperationsPage-aLHHAP2X.js +0 -3
  312. package/dashboard/dist/assets/OperationsPage-aLHHAP2X.js.map +0 -1
  313. package/dashboard/dist/assets/OperatorDashboard-sXNDh1Ph.js +0 -2
  314. package/dashboard/dist/assets/ProcessesListPage-CjwVKe32.js +0 -2
  315. package/dashboard/dist/assets/ResolverForm-Bk-wDkN-.js +0 -3
  316. package/dashboard/dist/assets/ResolverForm-Bk-wDkN-.js.map +0 -1
  317. package/dashboard/dist/assets/RoleDetailPage-WQt0y5l7.js +0 -8
  318. package/dashboard/dist/assets/RoleDetailPage-WQt0y5l7.js.map +0 -1
  319. package/dashboard/dist/assets/RunAsSelector-fFMt1bGe.js +0 -2
  320. package/dashboard/dist/assets/ScanStationPage-C1_ppDoZ.js +0 -2
  321. package/dashboard/dist/assets/TasksListPage-BB1f79lL.js +0 -2
  322. package/dashboard/dist/assets/ToolTestPanel-Bwe3J5lj.js +0 -2
  323. package/dashboard/dist/assets/TopicsPage-C1gxBUap.js +0 -2
  324. package/dashboard/dist/assets/WorkflowsDashboard-CZAqRk1N.js +0 -2
  325. package/dashboard/dist/assets/escalation-columns-uq-IV2aj.js +0 -2
  326. package/dashboard/dist/assets/escalation-columns-uq-IV2aj.js.map +0 -1
  327. package/dashboard/dist/assets/index-3ezfWLkE.js +0 -6
  328. package/dashboard/dist/assets/index-3ezfWLkE.js.map +0 -1
  329. package/dashboard/dist/assets/index-BQpV-DTG.js +0 -2
  330. package/dashboard/dist/assets/index-Bp9KBLT5.js +0 -2
  331. package/dashboard/dist/assets/index-Bpvfr4OW.css +0 -1
  332. package/dashboard/dist/assets/index-CFbo9FU9.js +0 -2
  333. package/dashboard/dist/assets/index-CIwlVfvV.js +0 -67
  334. package/dashboard/dist/assets/index-CIwlVfvV.js.map +0 -1
  335. package/dashboard/dist/assets/index-CUZ6LYye.js +0 -2
  336. package/dashboard/dist/assets/index-Cfvkl2J0.js +0 -13
  337. package/dashboard/dist/assets/index-SGyrXGp8.js +0 -3
  338. package/dashboard/dist/assets/index-SGyrXGp8.js.map +0 -1
  339. package/dashboard/dist/assets/invoke-context-DrVyUEfs.js +0 -2
  340. package/dashboard/dist/assets/invoke-context-DrVyUEfs.js.map +0 -1
  341. package/dashboard/dist/assets/metadata-display--TzK0REC.js +0 -2
  342. package/dashboard/dist/assets/metadata-display--TzK0REC.js.map +0 -1
  343. package/dashboard/dist/assets/resolver-payload-m9AGKZ3a.js +0 -2
  344. package/dashboard/dist/assets/resolver-payload-m9AGKZ3a.js.map +0 -1
  345. package/docs/compilation.md +0 -152
  346. package/docs/compiler.md +0 -311
  347. package/docs/contributing.md +0 -56
  348. package/docs/design-principles.md +0 -245
  349. package/docs/schema-exchange.md +0 -173
  350. package/docs/self-test.md +0 -106
  351. package/docs/story.md +0 -184
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolver-payload-m9AGKZ3a.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,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.
package/docs/compiler.md DELETED
@@ -1,311 +0,0 @@
1
- # The Workflow Compiler
2
-
3
- You wrote a durable workflow. It works. `proxyActivities`, `sleep`, `condition` — the durable API is productive and familiar. But under the hood, the durable engine replays the entire workflow function on every wake-up. Sleep three times in a ten-step workflow? Steps 1–3 replay on wake one. Steps 1–6 replay on wake two. Steps 1–9 replay on wake three. The replay is deterministic — it skips completed activities — but the function still executes from the top every time.
4
-
5
- The compiled YAML DAG does the same work without replay. Each step fires exactly once. State flows explicitly between activities through input mappings. No function re-execution, no replay loop, no wasted cycles.
6
-
7
- `ltc` is the compiler. It reads your TypeScript source and produces an equivalent YAML DAG. Write procedural because it's productive. Run the DAG because it's fast.
8
-
9
- ---
10
-
11
- ## The Analogy
12
-
13
- `tsc` compiles TypeScript to JavaScript. You write in the language that's expressive. You run the artifact that's efficient. The source is authoritative — you edit it, test it, review it. The compiled output is what actually executes.
14
-
15
- `ltc` does the same for workflows:
16
-
17
- ```
18
- TypeScript source ltc compile YAML DAG
19
- (developer-friendly) ──────────────────→ (execution-optimized)
20
-
21
- assembly-line.ts → assembly-line.compiled.yaml
22
- ```
23
-
24
- The `.ts` file is the spec. The `.compiled.yaml` is the optimized execution. Both live in the repo. A reviewer reads both side-by-side and traces every line of orchestration logic to its DAG equivalent.
25
-
26
- ---
27
-
28
- ## Quick Start
29
-
30
- ```bash
31
- npm install -g @hotmeshio/long-tail
32
- export ANTHROPIC_API_KEY=sk-ant-...
33
-
34
- ltc compile workflows/basic-echo/index.ts
35
- ```
36
-
37
- Output:
38
-
39
- ```
40
- ✓ index.ts → workflows/basic-echo/index.compiled.yaml
41
- 1 activities · 2 inputs (message, sleepSeconds) · topic: basic.echo
42
-
43
- Compiled 1 workflow in 18.1s
44
- ```
45
-
46
- The compiled YAML appears adjacent to the source file.
47
-
48
- ---
49
-
50
- ## Before and After
51
-
52
- ### The source (procedural)
53
-
54
- ```typescript
55
- import { Durable } from '@hotmeshio/hotmesh';
56
- import * as activities from './activities';
57
-
58
- const { echo } = Durable.workflow.proxyActivities<typeof activities>({
59
- activities,
60
- });
61
-
62
- export async function basicEcho(envelope: LTEnvelope): Promise<any> {
63
- const { message = 'Hello, Long Tail!', sleepSeconds = 1 } = envelope.data;
64
-
65
- // 1. Durable sleep — the engine replays to this point on wake-up
66
- await Durable.workflow.sleep(`${sleepSeconds} seconds`);
67
-
68
- // 2. Activity call — replayed as a no-op if already completed
69
- const echoResult = await echo({ message });
70
-
71
- return {
72
- type: 'return' as const,
73
- data: { ...echoResult, sleepSeconds, userId: envelope.lt?.userId },
74
- };
75
- }
76
- ```
77
-
78
- This function executes three times: once on initial invocation, once when the sleep timer fires, and once when the echo activity completes. Each time, the engine replays from the top, skipping completed steps. For a two-step workflow this is fine. For a twenty-step workflow with multiple sleeps, the replay cost compounds.
79
-
80
- ### The compiled output (DAG)
81
-
82
- ```yaml
83
- app:
84
- id: longtail
85
- version: '1'
86
- graphs:
87
- - subscribes: basic.echo
88
- expire: 300
89
- input:
90
- schema:
91
- type: object
92
- properties:
93
- message:
94
- type: string
95
- default: 'Hello, Long Tail!'
96
- sleepSeconds:
97
- type: number
98
- default: 1
99
- activities:
100
- trigger_m7qz:
101
- type: trigger
102
- output:
103
- schema:
104
- type: object
105
- properties:
106
- message: { type: string }
107
- sleepSeconds: { type: number }
108
-
109
- delay_m7qz:
110
- type: hook
111
- sleep: '{trigger_m7qz.output.data.sleepSeconds}'
112
-
113
- echo_m7qz:
114
- type: worker
115
- topic: basic.echo
116
- input:
117
- maps:
118
- message: '{trigger_m7qz.output.data.message}'
119
- workflowName: echo
120
-
121
- transitions:
122
- trigger_m7qz:
123
- - to: delay_m7qz
124
- delay_m7qz:
125
- - to: echo_m7qz
126
- ```
127
-
128
- ### The mapping
129
-
130
- | TypeScript | YAML | What happens |
131
- |---|---|---|
132
- | `envelope.data` destructuring | `trigger` activity with input schema | Inputs declared as typed schema with defaults |
133
- | `Durable.workflow.sleep(N)` | `hook` activity with `sleep` field | Engine sets a timer; no replay on wake |
134
- | `await echo({ message })` | `worker` activity with input `maps` | Worker fires once; result stored in job hash |
135
- | `return { data: ... }` | `job.maps` on the final activity | Output fields plucked from activity results |
136
-
137
- Each step executes exactly once. The `sleep` hook pauses the DAG. When the timer fires, execution resumes at `echo_m7qz` — not from the top of the function.
138
-
139
- ---
140
-
141
- ## Discovery
142
-
143
- Point `ltc` at a directory and it finds workflow files automatically:
144
-
145
- ```bash
146
- ltc compile examples/workflows/ --dry-run
147
- ```
148
-
149
- ```
150
- Found 10 workflows:
151
-
152
- ● assembly-line/index.ts
153
- Function: assemblyLine · HotMesh Durable
154
- Control flow: startChild, condition
155
-
156
- ● basic-echo/index.ts
157
- Function: basicEcho · HotMesh Durable
158
- Activities: echo
159
- Control flow: sleep
160
-
161
- ● basic-signal/index.ts
162
- Function: basicSignal · HotMesh Durable
163
- Activities: ltCreateEscalation, processApproval
164
- Control flow: conditional
165
-
166
- ● kitchen-sink/index.ts
167
- Function: kitchenSink · HotMesh Durable
168
- Activities: greet, fetchData, transformData, notifyComplete
169
- Control flow: sleep, executeLT
170
- ```
171
-
172
- ### What the scanner looks for
173
-
174
- | Pattern | Classification |
175
- |---|---|
176
- | `proxyActivities` / `Durable.workflow.proxyActivities` | HotMesh Durable workflow |
177
- | `@temporalio/workflow` import | Temporal workflow |
178
- | `sleep`, `condition`, `signal` | Control flow primitives |
179
- | `startChild`, `executeChild`, `executeLT` | Composition (parent workflow) |
180
- | Exported async function | Workflow entry point |
181
-
182
- Files in `node_modules/`, `build/`, `dist/`, and test files (`*.test.ts`, `*.spec.ts`) are excluded.
183
-
184
- ---
185
-
186
- ## How Compilation Works
187
-
188
- The compiler is not an AST parser. It uses the LLM to translate orchestration logic, grounded by structural metadata extracted from the source.
189
-
190
- 1. **Read source** — file or inline string
191
- 2. **Extract metadata** — lightweight regex extraction: activity names, durable primitives, envelope fields, import paths, control flow markers (loops, Promise.all, conditionals, escalation)
192
- 3. **Resolve activities** — if the source imports activity modules, the compiler reads them too and includes them in the LLM context
193
- 4. **LLM translation** — the source code, extracted metadata, and the full HotMesh YAML specification are sent to the LLM. Temperature 0. Up to 3 retry attempts on parse failure.
194
- 5. **Fix patterns** — known LLM anti-patterns in YAML pipe expressions are corrected deterministically
195
-
196
- The metadata extraction is intentionally lightweight — regex, not a TypeScript AST. It gives the LLM structural hints (which functions are activities, which primitives are used) without requiring `ts-morph` or the TypeScript compiler API as a dependency.
197
-
198
- ---
199
-
200
- ## Composition
201
-
202
- When a workflow uses `startChild` or `executeChild`, the compiler resolves the child workflow source through imports and compiles children first (leaf-first ordering). The parent's compiled YAML references each child by topic using the `await` activity type — the same mechanism used by the Pipeline Designer's Plan Build mode.
203
-
204
- ```
205
- parent.ts ──→ parent.compiled.yaml
206
- └─ startChild(worker)
207
- └─ worker.ts ──→ worker.compiled.yaml
208
- ```
209
-
210
- All compiled workflows in the same composition share the same `app.id` namespace, enabling cross-graph invocation.
211
-
212
- ---
213
-
214
- ## Three Surfaces
215
-
216
- The compiler is the same function regardless of how you invoke it.
217
-
218
- ### CLI
219
-
220
- ```bash
221
- ltc compile workflows/assembly-line.ts
222
- ltc compile src/workflows/ --dry-run
223
- ltc compile --model claude-sonnet-4-6
224
- ```
225
-
226
- ### HTTP API
227
-
228
- ```bash
229
- curl -X POST http://localhost:3000/api/yaml-workflows/from-durable \
230
- -H "Authorization: Bearer $TOKEN" \
231
- -H "Content-Type: application/json" \
232
- -d '{
233
- "source": "export async function basicEcho(envelope) { ... }",
234
- "workflow_name": "basicEcho",
235
- "name": "basic_echo"
236
- }'
237
- ```
238
-
239
- ### SDK
240
-
241
- ```typescript
242
- import { createClient } from '@hotmeshio/long-tail/sdk';
243
-
244
- const lt = createClient({ auth: { userId: 'system' } });
245
-
246
- const result = await lt.yamlWorkflows.compileDurable({
247
- source: fs.readFileSync('workflows/assembly-line.ts', 'utf-8'),
248
- workflow_name: 'assemblyLine',
249
- name: 'assembly_line',
250
- });
251
- ```
252
-
253
- The CLI writes `.compiled.yaml` files to disk. The HTTP and SDK surfaces store the compiled workflow in the database and return the record. All three use the same underlying `compileDurableToYaml()` function.
254
-
255
- ---
256
-
257
- ## Configuration
258
-
259
- | Variable | Default | Description |
260
- |---|---|---|
261
- | `ANTHROPIC_API_KEY` | — | Required for Claude models |
262
- | `OPENAI_API_KEY` | — | Required for OpenAI models |
263
- | `LT_LLM_MODEL_PRIMARY` | `claude-sonnet-4-6` | Model used for compilation |
264
- | `LT_LLM_BASE_URL` | — | Custom endpoint for OpenAI-compatible models |
265
-
266
- The CLI loads `.env` automatically if present in the current directory.
267
-
268
- ---
269
-
270
- ## CLI Reference
271
-
272
- ```
273
- Usage: ltc compile [options] [target]
274
-
275
- Compile durable TypeScript workflows to YAML DAGs
276
-
277
- Arguments:
278
- target File or directory to compile (default: current directory)
279
-
280
- Options:
281
- --dry-run Show discovered workflows without compiling
282
- -o, --output <dir> Output directory (default: adjacent to source file)
283
- --model <model> LLM model to use (default: claude-sonnet-4-6)
284
- --function <name> Workflow function name (auto-detected if omitted)
285
- -h, --help Display help
286
- ```
287
-
288
- ### Examples
289
-
290
- ```bash
291
- # Compile a single file
292
- ltc compile workflows/basic-echo/index.ts
293
-
294
- # Scan and compile all workflows in a directory
295
- ltc compile src/workflows/
296
-
297
- # Compile everything in the current directory
298
- ltc compile
299
-
300
- # Preview what would be compiled
301
- ltc compile examples/workflows/ --dry-run
302
-
303
- # Use a specific model
304
- ltc compile workflows/complex.ts --model claude-opus-4-6
305
-
306
- # Write output to a separate directory
307
- ltc compile workflows/ -o compiled/
308
-
309
- # Compile a specific function from a multi-export file
310
- ltc compile workflows/multi.ts --function assemblyLine
311
- ```
@@ -1,56 +0,0 @@
1
- # Contributing
2
-
3
- ## Running the Demo
4
-
5
- The repository includes a working server with example workflows (`reviewContent`, `kitchenSink`, `basicEcho`, and more), Postgres, NATS, and a React dashboard.
6
-
7
- ### Prerequisites
8
-
9
- - [Docker](https://docs.docker.com/get-docker/)
10
-
11
- ### Run
12
-
13
- ```bash
14
- git clone https://github.com/hotmeshio/long-tail.git
15
- cd long-tail
16
- docker compose up
17
- ```
18
-
19
- Postgres, NATS, the API server, and the dashboard start together. The dashboard is built during the Docker image build and served as static assets. Migrations run automatically.
20
-
21
- Default ports are `3000` (API), `5432` (Postgres), `4222`/`8222` (NATS). Override any of them:
22
-
23
- ```bash
24
- LT_PORT=3001 LT_PG_PORT=5433 LT_NATS_PORT=4223 docker compose up
25
- ```
26
-
27
- ## Testing
28
-
29
- ```bash
30
- # Start Postgres and NATS
31
- docker compose up -d postgres nats
32
-
33
- # Run all tests
34
- npm test
35
-
36
- # Run workflow tests
37
- npm run test:workflows
38
- ```
39
-
40
- ## Development Setup
41
-
42
- 1. Fork the repository and clone your fork
43
- 2. Install dependencies: `npm install`
44
- 3. Start infrastructure: `docker compose up -d postgres nats`
45
- 4. Run tests to verify your setup: `npm test`
46
-
47
- ## Pull Requests
48
-
49
- - Create a feature branch from `main`
50
- - Keep changes focused — one concern per PR
51
- - Add or update tests for any new behavior
52
- - Run `npm test` before submitting
53
-
54
- ## Issues
55
-
56
- Report bugs and request features at [github.com/hotmeshio/long-tail/issues](https://github.com/hotmeshio/long-tail/issues).