@hotmeshio/long-tail 0.10.9 → 0.10.10

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 (265) hide show
  1. package/build/api/index.d.ts +1 -0
  2. package/build/api/index.js +2 -1
  3. package/build/api/personas.d.ts +121 -0
  4. package/build/api/personas.js +341 -0
  5. package/build/bin/ltc.js +23 -0
  6. package/build/lib/cli/commands/personas.d.ts +16 -0
  7. package/build/lib/cli/commands/personas.js +42 -0
  8. package/build/lib/db/schemas/024_personas.sql +53 -0
  9. package/build/routes/index.js +2 -0
  10. package/build/routes/personas.d.ts +2 -0
  11. package/build/routes/personas.js +118 -0
  12. package/build/routes/users.js +35 -0
  13. package/build/sdk/index.d.ts +15 -0
  14. package/build/sdk/index.js +16 -0
  15. package/build/services/persona/index.d.ts +92 -0
  16. package/build/services/persona/index.js +217 -0
  17. package/build/services/persona/sql.d.ts +24 -0
  18. package/build/services/persona/sql.js +158 -0
  19. package/build/services/persona/types.d.ts +23 -0
  20. package/build/services/persona/types.js +33 -0
  21. package/build/services/user/sql.d.ts +8 -5
  22. package/build/services/user/sql.js +15 -5
  23. package/build/system/mcp-servers/admin/index.d.ts +1 -0
  24. package/build/system/mcp-servers/admin/index.js +5 -2
  25. package/build/system/mcp-servers/admin/personas.d.ts +8 -0
  26. package/build/system/mcp-servers/admin/personas.js +186 -0
  27. package/build/system/mcp-servers/admin/schemas.d.ts +91 -0
  28. package/build/system/mcp-servers/admin/schemas.js +42 -2
  29. package/build/system/seed/tool-manifests-admin.d.ts +975 -0
  30. package/build/system/seed/tool-manifests-admin.js +11 -0
  31. package/build/tsconfig.tsbuildinfo +1 -1
  32. package/build/types/index.d.ts +1 -0
  33. package/build/types/persona.d.ts +56 -0
  34. package/build/types/persona.js +2 -0
  35. package/build/types/user.d.ts +2 -0
  36. package/dashboard/dist/assets/{AdminDashboard-DWSYdAeW.js → AdminDashboard-cGYuppUP.js} +2 -2
  37. package/dashboard/dist/assets/{AdminDashboard-DWSYdAeW.js.map → AdminDashboard-cGYuppUP.js.map} +1 -1
  38. package/dashboard/dist/assets/{AgentConfigPage-Dm6gL76m.js → AgentConfigPage-DwaUyoCy.js} +2 -2
  39. package/dashboard/dist/assets/{AgentConfigPage-Dm6gL76m.js.map → AgentConfigPage-DwaUyoCy.js.map} +1 -1
  40. package/dashboard/dist/assets/AgentDetailPage-DxpFaltM.js +4 -0
  41. package/dashboard/dist/assets/AgentDetailPage-DxpFaltM.js.map +1 -0
  42. package/dashboard/dist/assets/{AgentsPage-DKaDRk-Y.js → AgentsPage-ByOoA8oT.js} +2 -2
  43. package/dashboard/dist/assets/{AgentsPage-DKaDRk-Y.js.map → AgentsPage-ByOoA8oT.js.map} +1 -1
  44. package/dashboard/dist/assets/AutoGrowTextarea-y-oNY51_.js +2 -0
  45. package/dashboard/dist/assets/AutoGrowTextarea-y-oNY51_.js.map +1 -0
  46. package/dashboard/dist/assets/{AvailableEscalationsPage-B-aHvGKD.js → AvailableEscalationsPage-C1vtTvqP.js} +2 -2
  47. package/dashboard/dist/assets/{AvailableEscalationsPage-B-aHvGKD.js.map → AvailableEscalationsPage-C1vtTvqP.js.map} +1 -1
  48. package/dashboard/dist/assets/{BotPicker-DRv_orzI.js → BotPicker-Dohv8dhR.js} +2 -2
  49. package/dashboard/dist/assets/{BotPicker-DRv_orzI.js.map → BotPicker-Dohv8dhR.js.map} +1 -1
  50. package/dashboard/dist/assets/{CapabilitiesPage-DqRVzMol.js → CapabilitiesPage-DeijFG3J.js} +2 -2
  51. package/dashboard/dist/assets/{CapabilitiesPage-DqRVzMol.js.map → CapabilitiesPage-DeijFG3J.js.map} +1 -1
  52. package/dashboard/dist/assets/{CollapsibleSection-D0psvw8i.js → CollapsibleSection-BPNwS4eO.js} +2 -2
  53. package/dashboard/dist/assets/{CollapsibleSection-D0psvw8i.js.map → CollapsibleSection-BPNwS4eO.js.map} +1 -1
  54. package/dashboard/dist/assets/CountdownTimer-BF71ldGF.js +2 -0
  55. package/dashboard/dist/assets/CountdownTimer-BF71ldGF.js.map +1 -0
  56. package/dashboard/dist/assets/{CredentialsPage-Axdci1z-.js → CredentialsPage-oeNmMzTM.js} +2 -2
  57. package/dashboard/dist/assets/{CredentialsPage-Axdci1z-.js.map → CredentialsPage-oeNmMzTM.js.map} +1 -1
  58. package/dashboard/dist/assets/{CronLabel-BjZ_wZA8.js → CronLabel-CebR1m2k.js} +2 -2
  59. package/dashboard/dist/assets/{CronLabel-BjZ_wZA8.js.map → CronLabel-CebR1m2k.js.map} +1 -1
  60. package/dashboard/dist/assets/{CustomDurationPicker-CkUCMUfk.js → CustomDurationPicker-Bh9QdBVw.js} +2 -2
  61. package/dashboard/dist/assets/{CustomDurationPicker-CkUCMUfk.js.map → CustomDurationPicker-Bh9QdBVw.js.map} +1 -1
  62. package/dashboard/dist/assets/{DropZone-_tmC3jEe.js → DropZone-Bavzt2QR.js} +2 -2
  63. package/dashboard/dist/assets/{DropZone-_tmC3jEe.js.map → DropZone-Bavzt2QR.js.map} +1 -1
  64. package/dashboard/dist/assets/ElapsedCell-Caa6CU_y.js +2 -0
  65. package/dashboard/dist/assets/{ElapsedCell-BE_CN5sP.js.map → ElapsedCell-Caa6CU_y.js.map} +1 -1
  66. package/dashboard/dist/assets/{EscalationListSchemaPage-CgcVIiYR.js → EscalationListSchemaPage-CAGfq0eK.js} +3 -3
  67. package/dashboard/dist/assets/{EscalationListSchemaPage-CgcVIiYR.js.map → EscalationListSchemaPage-CAGfq0eK.js.map} +1 -1
  68. package/dashboard/dist/assets/{EscalationSchemaPage-BaAn1Hcr.js → EscalationSchemaPage-qDD4ur6P.js} +3 -3
  69. package/dashboard/dist/assets/{EscalationSchemaPage-BaAn1Hcr.js.map → EscalationSchemaPage-qDD4ur6P.js.map} +1 -1
  70. package/dashboard/dist/assets/{EscalationsOverview-Dbq7tKzr.js → EscalationsOverview-CC1wRTzy.js} +2 -2
  71. package/dashboard/dist/assets/{EscalationsOverview-Dbq7tKzr.js.map → EscalationsOverview-CC1wRTzy.js.map} +1 -1
  72. package/dashboard/dist/assets/{EventTable-0RUK9jqt.js → EventTable-4JeTcXr_.js} +2 -2
  73. package/dashboard/dist/assets/{EventTable-0RUK9jqt.js.map → EventTable-4JeTcXr_.js.map} +1 -1
  74. package/dashboard/dist/assets/{FilterBar-B_dy2Jhj.js → FilterBar-BOV8DWIO.js} +2 -2
  75. package/dashboard/dist/assets/{FilterBar-B_dy2Jhj.js.map → FilterBar-BOV8DWIO.js.map} +1 -1
  76. package/dashboard/dist/assets/{GraphInvokePage-CvLYp1nL.js → GraphInvokePage-C0i1speW.js} +2 -2
  77. package/dashboard/dist/assets/{GraphInvokePage-CvLYp1nL.js.map → GraphInvokePage-C0i1speW.js.map} +1 -1
  78. package/dashboard/dist/assets/{HomePage-B6s1ZeyA.js → HomePage-HPCd8SjF.js} +2 -2
  79. package/dashboard/dist/assets/{HomePage-B6s1ZeyA.js.map → HomePage-HPCd8SjF.js.map} +1 -1
  80. package/dashboard/dist/assets/{ListToolbar-DVhlAKZ3.js → ListToolbar-BFHVOba6.js} +2 -2
  81. package/dashboard/dist/assets/{ListToolbar-DVhlAKZ3.js.map → ListToolbar-BFHVOba6.js.map} +1 -1
  82. package/dashboard/dist/assets/{McpOverview-Ca8cpc8g.js → McpOverview-Chn2zIXr.js} +2 -2
  83. package/dashboard/dist/assets/{McpOverview-Ca8cpc8g.js.map → McpOverview-Chn2zIXr.js.map} +1 -1
  84. package/dashboard/dist/assets/McpQueryDetailPage-Cv1FKrvw.js +5 -0
  85. package/dashboard/dist/assets/McpQueryDetailPage-Cv1FKrvw.js.map +1 -0
  86. package/dashboard/dist/assets/McpQueryPage-Dzn8JE4E.js +2 -0
  87. package/dashboard/dist/assets/McpQueryPage-Dzn8JE4E.js.map +1 -0
  88. package/dashboard/dist/assets/{McpRunDetailPage-C76mfUtG.js → McpRunDetailPage-CuNtR4Ed.js} +2 -2
  89. package/dashboard/dist/assets/{McpRunDetailPage-C76mfUtG.js.map → McpRunDetailPage-CuNtR4Ed.js.map} +1 -1
  90. package/dashboard/dist/assets/{McpRunsPage-B43BqEyw.js → McpRunsPage-C8iifeKN.js} +2 -2
  91. package/dashboard/dist/assets/{McpRunsPage-B43BqEyw.js.map → McpRunsPage-C8iifeKN.js.map} +1 -1
  92. package/dashboard/dist/assets/{NamespacePill-B5gHotsd.js → NamespacePill-ep9Zmokr.js} +2 -2
  93. package/dashboard/dist/assets/{NamespacePill-B5gHotsd.js.map → NamespacePill-ep9Zmokr.js.map} +1 -1
  94. package/dashboard/dist/assets/{OperationsPage-DbHzQCuE.js → OperationsPage-flrZ-EJ9.js} +2 -2
  95. package/dashboard/dist/assets/{OperationsPage-DbHzQCuE.js.map → OperationsPage-flrZ-EJ9.js.map} +1 -1
  96. package/dashboard/dist/assets/OperatorDashboard-Dhs2eo8p.js +2 -0
  97. package/dashboard/dist/assets/{OperatorDashboard-B70nS_Ah.js.map → OperatorDashboard-Dhs2eo8p.js.map} +1 -1
  98. package/dashboard/dist/assets/{PageHeader-DrbNMGxm.js → PageHeader-Bw8RNkqR.js} +2 -2
  99. package/dashboard/dist/assets/{PageHeader-DrbNMGxm.js.map → PageHeader-Bw8RNkqR.js.map} +1 -1
  100. package/dashboard/dist/assets/{PageHeaderWithStats-SbQkaQLG.js → PageHeaderWithStats-NR_4idn6.js} +2 -2
  101. package/dashboard/dist/assets/{PageHeaderWithStats-SbQkaQLG.js.map → PageHeaderWithStats-NR_4idn6.js.map} +1 -1
  102. package/dashboard/dist/assets/PersonaDetailPage-DKILoUqL.js +2 -0
  103. package/dashboard/dist/assets/PersonaDetailPage-DKILoUqL.js.map +1 -0
  104. package/dashboard/dist/assets/PersonasPage-qvzHTrFw.js +2 -0
  105. package/dashboard/dist/assets/PersonasPage-qvzHTrFw.js.map +1 -0
  106. package/dashboard/dist/assets/ProcessDetailPage-C3LfeKvi.js +2 -0
  107. package/dashboard/dist/assets/ProcessDetailPage-C3LfeKvi.js.map +1 -0
  108. package/dashboard/dist/assets/{ProcessesListPage-Di0n8TR4.js → ProcessesListPage-OoZ_u4ty.js} +2 -2
  109. package/dashboard/dist/assets/{ProcessesListPage-Di0n8TR4.js.map → ProcessesListPage-OoZ_u4ty.js.map} +1 -1
  110. package/dashboard/dist/assets/RoleDetailPage-D70jTLZm.js +8 -0
  111. package/dashboard/dist/assets/RoleDetailPage-D70jTLZm.js.map +1 -0
  112. package/dashboard/dist/assets/{RolePill-Cz-AAWqA.js → RolePill-TySZq7dB.js} +2 -2
  113. package/dashboard/dist/assets/{RolePill-Cz-AAWqA.js.map → RolePill-TySZq7dB.js.map} +1 -1
  114. package/dashboard/dist/assets/RolesPage-CNueMVuJ.js +2 -0
  115. package/dashboard/dist/assets/RolesPage-CNueMVuJ.js.map +1 -0
  116. package/dashboard/dist/assets/{RunAsSelector-DFv0VNVZ.js → RunAsSelector-CwWEpiSF.js} +2 -2
  117. package/dashboard/dist/assets/{RunAsSelector-DFv0VNVZ.js.map → RunAsSelector-CwWEpiSF.js.map} +1 -1
  118. package/dashboard/dist/assets/ScopeBadge-C7Uixtmk.js +2 -0
  119. package/dashboard/dist/assets/ScopeBadge-C7Uixtmk.js.map +1 -0
  120. package/dashboard/dist/assets/StatCard-Ca-ngCaD.js +2 -0
  121. package/dashboard/dist/assets/StatCard-Ca-ngCaD.js.map +1 -0
  122. package/dashboard/dist/assets/{StatusBadge-BbqghFMi.js → StatusBadge-BwUvykDo.js} +2 -2
  123. package/dashboard/dist/assets/{StatusBadge-BbqghFMi.js.map → StatusBadge-BwUvykDo.js.map} +1 -1
  124. package/dashboard/dist/assets/{StickyPagination-D5zxe_l9.js → StickyPagination-DvIF3kQK.js} +2 -2
  125. package/dashboard/dist/assets/{StickyPagination-D5zxe_l9.js.map → StickyPagination-DvIF3kQK.js.map} +1 -1
  126. package/dashboard/dist/assets/{StreamMessageDetail-BmBfNSEr.js → StreamMessageDetail-DkFK_XGD.js} +2 -2
  127. package/dashboard/dist/assets/StreamMessageDetail-DkFK_XGD.js.map +1 -0
  128. package/dashboard/dist/assets/{SwimlaneTimeline-CA0TKDIi.js → SwimlaneTimeline-CMw-Et6h.js} +2 -2
  129. package/dashboard/dist/assets/{SwimlaneTimeline-CA0TKDIi.js.map → SwimlaneTimeline-CMw-Et6h.js.map} +1 -1
  130. package/dashboard/dist/assets/{TagInput-Bf9dZSG6.js → TagInput-D8gSp48D.js} +2 -2
  131. package/dashboard/dist/assets/{TagInput-Bf9dZSG6.js.map → TagInput-D8gSp48D.js.map} +1 -1
  132. package/dashboard/dist/assets/{TaskDetailPage-C15nADUW.js → TaskDetailPage-BhXuChOf.js} +2 -2
  133. package/dashboard/dist/assets/{TaskDetailPage-C15nADUW.js.map → TaskDetailPage-BhXuChOf.js.map} +1 -1
  134. package/dashboard/dist/assets/{TaskQueuePill-DfiBYQy2.js → TaskQueuePill-CHqolBmU.js} +2 -2
  135. package/dashboard/dist/assets/{TaskQueuePill-DfiBYQy2.js.map → TaskQueuePill-CHqolBmU.js.map} +1 -1
  136. package/dashboard/dist/assets/{TasksListPage-DQdAayqc.js → TasksListPage-6JHQQ5QZ.js} +2 -2
  137. package/dashboard/dist/assets/{TasksListPage-DQdAayqc.js.map → TasksListPage-6JHQQ5QZ.js.map} +1 -1
  138. package/dashboard/dist/assets/{TimeAgo-CvslqTB7.js → TimeAgo-CInx-vzY.js} +2 -2
  139. package/dashboard/dist/assets/{TimeAgo-CvslqTB7.js.map → TimeAgo-CInx-vzY.js.map} +1 -1
  140. package/dashboard/dist/assets/{TimestampCell-BZCQQONl.js → TimestampCell-Fq17Zrsu.js} +2 -2
  141. package/dashboard/dist/assets/{TimestampCell-BZCQQONl.js.map → TimestampCell-Fq17Zrsu.js.map} +1 -1
  142. package/dashboard/dist/assets/{ToolPill-gA4sXukc.js → ToolPill-BbgMDhaE.js} +2 -2
  143. package/dashboard/dist/assets/{ToolPill-gA4sXukc.js.map → ToolPill-BbgMDhaE.js.map} +1 -1
  144. package/dashboard/dist/assets/{ToolTestPanel-BgLVc6R5.js → ToolTestPanel-DhjEe59s.js} +2 -2
  145. package/dashboard/dist/assets/{ToolTestPanel-BgLVc6R5.js.map → ToolTestPanel-DhjEe59s.js.map} +1 -1
  146. package/dashboard/dist/assets/{TopicDetailPage-9A0aPb4t.js → TopicDetailPage-DbIdmQpQ.js} +3 -3
  147. package/dashboard/dist/assets/{TopicDetailPage-9A0aPb4t.js.map → TopicDetailPage-DbIdmQpQ.js.map} +1 -1
  148. package/dashboard/dist/assets/TopicsPage-CAP-GUbr.js +2 -0
  149. package/dashboard/dist/assets/{TopicsPage-o0EZxKbR.js.map → TopicsPage-CAP-GUbr.js.map} +1 -1
  150. package/dashboard/dist/assets/{UserName-DKMLxBJ5.js → UserName-DggcLkSc.js} +2 -2
  151. package/dashboard/dist/assets/{UserName-DKMLxBJ5.js.map → UserName-DggcLkSc.js.map} +1 -1
  152. package/dashboard/dist/assets/{WorkflowExecutionPage-C-snB_dD.js → WorkflowExecutionPage-Bmra5fVt.js} +2 -2
  153. package/dashboard/dist/assets/{WorkflowExecutionPage-C-snB_dD.js.map → WorkflowExecutionPage-Bmra5fVt.js.map} +1 -1
  154. package/dashboard/dist/assets/{WorkflowPill-Djt2AtZk.js → WorkflowPill-CcUUVugA.js} +2 -2
  155. package/dashboard/dist/assets/{WorkflowPill-Djt2AtZk.js.map → WorkflowPill-CcUUVugA.js.map} +1 -1
  156. package/dashboard/dist/assets/{WorkflowsDashboard-BRQmgsLR.js → WorkflowsDashboard-BQsZAGYU.js} +2 -2
  157. package/dashboard/dist/assets/{WorkflowsDashboard-BRQmgsLR.js.map → WorkflowsDashboard-BQsZAGYU.js.map} +1 -1
  158. package/dashboard/dist/assets/{WorkflowsOverview-DmMdIRHQ.js → WorkflowsOverview-CeliraHZ.js} +2 -2
  159. package/dashboard/dist/assets/{WorkflowsOverview-DmMdIRHQ.js.map → WorkflowsOverview-CeliraHZ.js.map} +1 -1
  160. package/dashboard/dist/assets/{YamlWorkflowDetailPage-Bj7QkCry.js → YamlWorkflowDetailPage-DGxlonrV.js} +2 -2
  161. package/dashboard/dist/assets/{YamlWorkflowDetailPage-Bj7QkCry.js.map → YamlWorkflowDetailPage-DGxlonrV.js.map} +1 -1
  162. package/dashboard/dist/assets/{YamlWorkflowsPage-BIi77mE0.js → YamlWorkflowsPage-DnT8UiyQ.js} +2 -2
  163. package/dashboard/dist/assets/{YamlWorkflowsPage-BIi77mE0.js.map → YamlWorkflowsPage-DnT8UiyQ.js.map} +1 -1
  164. package/dashboard/dist/assets/{agents-EBIsjLCr.js → agents-mRV7m4sh.js} +2 -2
  165. package/dashboard/dist/assets/{agents-EBIsjLCr.js.map → agents-mRV7m4sh.js.map} +1 -1
  166. package/dashboard/dist/assets/{bots-BXzxybS6.js → bots-SONCZlCM.js} +2 -2
  167. package/dashboard/dist/assets/{bots-BXzxybS6.js.map → bots-SONCZlCM.js.map} +1 -1
  168. package/dashboard/dist/assets/{capabilities-CnprG6q_.js → capabilities-DZjCMN32.js} +2 -2
  169. package/dashboard/dist/assets/{capabilities-CnprG6q_.js.map → capabilities-DZjCMN32.js.map} +1 -1
  170. package/dashboard/dist/assets/{controlplane-DiC0xtNq.js → controlplane-RQNXjna2.js} +2 -2
  171. package/dashboard/dist/assets/{controlplane-DiC0xtNq.js.map → controlplane-RQNXjna2.js.map} +1 -1
  172. package/dashboard/dist/assets/{escalation-columns-D0aYpJkF.js → escalation-columns-XLEcZRCg.js} +2 -2
  173. package/dashboard/dist/assets/{escalation-columns-D0aYpJkF.js.map → escalation-columns-XLEcZRCg.js.map} +1 -1
  174. package/dashboard/dist/assets/index-2BwHxjCw.css +1 -0
  175. package/dashboard/dist/assets/{index-CcMIca5t.js → index-C6GsrvX1.js} +2 -2
  176. package/dashboard/dist/assets/{index-CcMIca5t.js.map → index-C6GsrvX1.js.map} +1 -1
  177. package/dashboard/dist/assets/{index-C7KY8GTF.js → index-CK-6m8e_.js} +2 -2
  178. package/dashboard/dist/assets/{index-C7KY8GTF.js.map → index-CK-6m8e_.js.map} +1 -1
  179. package/dashboard/dist/assets/index-CkeSxuZ0.js +2 -0
  180. package/dashboard/dist/assets/{index-CjBdB8Ht.js.map → index-CkeSxuZ0.js.map} +1 -1
  181. package/dashboard/dist/assets/{index-B6ldRx_s.js → index-CxVGlkK6.js} +2 -2
  182. package/dashboard/dist/assets/{index-B6ldRx_s.js.map → index-CxVGlkK6.js.map} +1 -1
  183. package/dashboard/dist/assets/{index-DVmC_UfQ.js → index-D2CfSx_x.js} +4 -4
  184. package/dashboard/dist/assets/{index-DVmC_UfQ.js.map → index-D2CfSx_x.js.map} +1 -1
  185. package/dashboard/dist/assets/{index-BHAjQoOy.js → index-DFJF8aWz.js} +3 -3
  186. package/dashboard/dist/assets/{index-BHAjQoOy.js.map → index-DFJF8aWz.js.map} +1 -1
  187. package/dashboard/dist/assets/index-DYKRtstT.js +2 -0
  188. package/dashboard/dist/assets/index-DYKRtstT.js.map +1 -0
  189. package/dashboard/dist/assets/index-DY_hlZCQ.js +2 -0
  190. package/dashboard/dist/assets/index-DY_hlZCQ.js.map +1 -0
  191. package/dashboard/dist/assets/{index-Dht0ihGT.js → index-DbZpL10z.js} +2 -2
  192. package/dashboard/dist/assets/{index-Dht0ihGT.js.map → index-DbZpL10z.js.map} +1 -1
  193. package/dashboard/dist/assets/{index-CSTwyrwu.js → index-Dh3CVChT.js} +18 -18
  194. package/dashboard/dist/assets/index-Dh3CVChT.js.map +1 -0
  195. package/dashboard/dist/assets/{index-gBnGEubX.js → index-DqsLfO-0.js} +2 -2
  196. package/dashboard/dist/assets/{index-gBnGEubX.js.map → index-DqsLfO-0.js.map} +1 -1
  197. package/dashboard/dist/assets/{index-BzRXMicE.js → index-iHV3d7o3.js} +2 -2
  198. package/dashboard/dist/assets/{index-BzRXMicE.js.map → index-iHV3d7o3.js.map} +1 -1
  199. package/dashboard/dist/assets/{index-ovFEZ9SV.js → index-ymm58cTW.js} +2 -2
  200. package/dashboard/dist/assets/{index-ovFEZ9SV.js.map → index-ymm58cTW.js.map} +1 -1
  201. package/dashboard/dist/assets/{knowledge-W5QSKkYQ.js → knowledge-Bawo8u7l.js} +2 -2
  202. package/dashboard/dist/assets/{knowledge-W5QSKkYQ.js.map → knowledge-Bawo8u7l.js.map} +1 -1
  203. package/dashboard/dist/assets/{mcp-n877HyOj.js → mcp-CKIpbpRZ.js} +2 -2
  204. package/dashboard/dist/assets/{mcp-n877HyOj.js.map → mcp-CKIpbpRZ.js.map} +1 -1
  205. package/dashboard/dist/assets/{mcp-query-C9kV4sUm.js → mcp-query-vld4hYxQ.js} +2 -2
  206. package/dashboard/dist/assets/{mcp-query-C9kV4sUm.js.map → mcp-query-vld4hYxQ.js.map} +1 -1
  207. package/dashboard/dist/assets/personas-BsARc3df.js +2 -0
  208. package/dashboard/dist/assets/personas-BsARc3df.js.map +1 -0
  209. package/dashboard/dist/assets/{pipelines-CBR68T8R.js → pipelines-BTSL-5ko.js} +2 -2
  210. package/dashboard/dist/assets/{pipelines-CBR68T8R.js.map → pipelines-BTSL-5ko.js.map} +1 -1
  211. package/dashboard/dist/assets/{tasks-DHpWqKMk.js → tasks-DggQdNbj.js} +2 -2
  212. package/dashboard/dist/assets/{tasks-DHpWqKMk.js.map → tasks-DggQdNbj.js.map} +1 -1
  213. package/dashboard/dist/assets/{topics-CaLtyqSh.js → topics-DzAKa34X.js} +2 -2
  214. package/dashboard/dist/assets/{topics-CaLtyqSh.js.map → topics-DzAKa34X.js.map} +1 -1
  215. package/dashboard/dist/assets/{useEventHooks-B8p56JlB.js → useEventHooks-5uI9oI5W.js} +2 -2
  216. package/dashboard/dist/assets/{useEventHooks-B8p56JlB.js.map → useEventHooks-5uI9oI5W.js.map} +1 -1
  217. package/dashboard/dist/assets/{useNamespace-ej71FCvu.js → useNamespace-CEKzFIqe.js} +2 -2
  218. package/dashboard/dist/assets/{useNamespace-ej71FCvu.js.map → useNamespace-CEKzFIqe.js.map} +1 -1
  219. package/dashboard/dist/assets/{useYamlActivityEvents-DgpiFXib.js → useYamlActivityEvents-hHgX1Z50.js} +2 -2
  220. package/dashboard/dist/assets/{useYamlActivityEvents-DgpiFXib.js.map → useYamlActivityEvents-hHgX1Z50.js.map} +1 -1
  221. package/dashboard/dist/assets/{users-CHnjI_Ca.js → users-AO8lUyNr.js} +2 -2
  222. package/dashboard/dist/assets/{users-CHnjI_Ca.js.map → users-AO8lUyNr.js.map} +1 -1
  223. package/dashboard/dist/assets/{vendor-icons-Bg6eJX4Z.js → vendor-icons-DN9yGSuM.js} +141 -131
  224. package/dashboard/dist/assets/vendor-icons-DN9yGSuM.js.map +1 -0
  225. package/dashboard/dist/assets/{workflows-DtnXUL0U.js → workflows-PtnlRK09.js} +2 -2
  226. package/dashboard/dist/assets/{workflows-DtnXUL0U.js.map → workflows-PtnlRK09.js.map} +1 -1
  227. package/dashboard/dist/assets/{yaml-workflows-DDclYAID.js → yaml-workflows-DPu3Y8vG.js} +2 -2
  228. package/dashboard/dist/assets/{yaml-workflows-DDclYAID.js.map → yaml-workflows-DPu3Y8vG.js.map} +1 -1
  229. package/dashboard/dist/index.html +3 -3
  230. package/docs/api/http/personas.md +160 -0
  231. package/docs/cli.md +12 -0
  232. package/docs/dashboard.md +16 -1
  233. package/docs/design-principles.md +9 -5
  234. package/docs/hitl/x-lt-list-schema.md +2 -3
  235. package/docs/iam.md +47 -0
  236. package/docs/sdk.md +1 -0
  237. package/package.json +1 -1
  238. package/dashboard/dist/assets/AgentDetailPage-D-Xbyrb6.js +0 -4
  239. package/dashboard/dist/assets/AgentDetailPage-D-Xbyrb6.js.map +0 -1
  240. package/dashboard/dist/assets/CountdownTimer-BhF3oqS8.js +0 -2
  241. package/dashboard/dist/assets/CountdownTimer-BhF3oqS8.js.map +0 -1
  242. package/dashboard/dist/assets/ElapsedCell-BE_CN5sP.js +0 -2
  243. package/dashboard/dist/assets/McpQueryDetailPage-D0r2lyZg.js +0 -5
  244. package/dashboard/dist/assets/McpQueryDetailPage-D0r2lyZg.js.map +0 -1
  245. package/dashboard/dist/assets/McpQueryPage-DPP6BB3d.js +0 -2
  246. package/dashboard/dist/assets/McpQueryPage-DPP6BB3d.js.map +0 -1
  247. package/dashboard/dist/assets/OperatorDashboard-B70nS_Ah.js +0 -2
  248. package/dashboard/dist/assets/ProcessDetailPage-eLLUCWFf.js +0 -2
  249. package/dashboard/dist/assets/ProcessDetailPage-eLLUCWFf.js.map +0 -1
  250. package/dashboard/dist/assets/RoleDetailPage-Dhn9zU5l.js +0 -8
  251. package/dashboard/dist/assets/RoleDetailPage-Dhn9zU5l.js.map +0 -1
  252. package/dashboard/dist/assets/RolesPage-BnAwjUiG.js +0 -2
  253. package/dashboard/dist/assets/RolesPage-BnAwjUiG.js.map +0 -1
  254. package/dashboard/dist/assets/StatCard-DBANWIss.js +0 -2
  255. package/dashboard/dist/assets/StatCard-DBANWIss.js.map +0 -1
  256. package/dashboard/dist/assets/StreamMessageDetail-BmBfNSEr.js.map +0 -1
  257. package/dashboard/dist/assets/TopicsPage-o0EZxKbR.js +0 -2
  258. package/dashboard/dist/assets/index-B2iZG_HP.css +0 -1
  259. package/dashboard/dist/assets/index-CSTwyrwu.js.map +0 -1
  260. package/dashboard/dist/assets/index-CjBdB8Ht.js +0 -2
  261. package/dashboard/dist/assets/index-D-7mT0ew.js +0 -2
  262. package/dashboard/dist/assets/index-D-7mT0ew.js.map +0 -1
  263. package/dashboard/dist/assets/index-DDA7FvqT.js +0 -2
  264. package/dashboard/dist/assets/index-DDA7FvqT.js.map +0 -1
  265. package/dashboard/dist/assets/vendor-icons-Bg6eJX4Z.js.map +0 -1
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ // ─── Persona CRUD ─────────────────────────────────────────────────────────────
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ENSURE_ROLES_EXIST = exports.GET_PERSONA_ID_BY_KEY = exports.GET_USER_COMPOSED_ROLES = exports.GET_USER_PERSONAS = exports.RECOMPUTE_PERSONA_MEMBERSHIPS = exports.LIST_SUSTAINED_USER_IDS = exports.LIST_PERSONA_HOLDER_IDS = exports.DELETE_USER_PERSONA = exports.INSERT_USER_PERSONA = exports.SYNC_PERSONA_ROLES = exports.DELETE_PERSONA_ROLE = exports.UPSERT_PERSONA_ROLE = exports.GET_PERSONA_ASSIGNEES = exports.DELETE_PERSONA = exports.UPDATE_PERSONA = exports.UPSERT_PERSONA = exports.CREATE_PERSONA = exports.GET_PERSONA_BY_KEY = exports.LIST_PERSONAS = void 0;
5
+ /** Aggregated role links for one persona, as a JSON array column. */
6
+ const ROLES_LATERAL = `LEFT JOIN LATERAL (
7
+ SELECT COALESCE(json_agg(json_build_object('role', pr.role, 'relationship', pr.relationship)
8
+ ORDER BY pr.created_at, pr.role), '[]'::json) AS roles
9
+ FROM lt_persona_roles pr WHERE pr.persona_id = p.id
10
+ ) r ON true
11
+ LEFT JOIN LATERAL (
12
+ SELECT COUNT(*)::int AS user_count FROM lt_user_personas up WHERE up.persona_id = p.id
13
+ ) u ON true`;
14
+ exports.LIST_PERSONAS = `SELECT p.id, p.key, p.title, p.description, r.roles, u.user_count, p.created_at, p.updated_at
15
+ FROM lt_personas p
16
+ ${ROLES_LATERAL}
17
+ ORDER BY p.key`;
18
+ exports.GET_PERSONA_BY_KEY = `SELECT p.id, p.key, p.title, p.description, r.roles, u.user_count, p.created_at, p.updated_at
19
+ FROM lt_personas p
20
+ ${ROLES_LATERAL}
21
+ WHERE p.key = $1`;
22
+ exports.CREATE_PERSONA = `INSERT INTO lt_personas (key, title, description) VALUES ($1, $2, $3)
23
+ RETURNING id, key, title, description, created_at, updated_at`;
24
+ /** Declarative upsert for the seed pass — the spec is authoritative for title/description. */
25
+ exports.UPSERT_PERSONA = `INSERT INTO lt_personas (key, title, description) VALUES ($1, $2, $3)
26
+ ON CONFLICT (key) DO UPDATE SET
27
+ title = EXCLUDED.title,
28
+ description = EXCLUDED.description,
29
+ updated_at = NOW()
30
+ RETURNING id`;
31
+ /** PATCH semantics: $2/$4 are set-sentinels gating whether $3/$5 write. */
32
+ exports.UPDATE_PERSONA = `UPDATE lt_personas SET
33
+ title = CASE WHEN $2 THEN $3 ELSE title END,
34
+ description = CASE WHEN $4 THEN $5 ELSE description END,
35
+ updated_at = NOW()
36
+ WHERE key = $1
37
+ RETURNING id, key, title, description, created_at, updated_at`;
38
+ exports.DELETE_PERSONA = 'DELETE FROM lt_personas WHERE id = $1';
39
+ exports.GET_PERSONA_ASSIGNEES = `SELECT us.id, us.external_id, us.display_name, us.email, up.created_at AS assigned_at
40
+ FROM lt_user_personas up
41
+ JOIN lt_users us ON us.id = up.user_id
42
+ WHERE up.persona_id = $1
43
+ ORDER BY up.created_at, us.external_id`;
44
+ // ─── Role links ───────────────────────────────────────────────────────────────
45
+ exports.UPSERT_PERSONA_ROLE = `INSERT INTO lt_persona_roles (persona_id, role, relationship) VALUES ($1, $2, $3)
46
+ ON CONFLICT (persona_id, role) DO UPDATE SET relationship = EXCLUDED.relationship
47
+ RETURNING role, relationship`;
48
+ exports.DELETE_PERSONA_ROLE = 'DELETE FROM lt_persona_roles WHERE persona_id = $1 AND role = $2';
49
+ /** Replace a persona's links declaratively: prune links not in $2, upsert the rest. */
50
+ exports.SYNC_PERSONA_ROLES = `WITH incoming AS (
51
+ SELECT x.role, x.relationship
52
+ FROM unnest($2::text[], $3::text[]) AS x(role, relationship)
53
+ ), pruned AS (
54
+ DELETE FROM lt_persona_roles pr
55
+ WHERE pr.persona_id = $1 AND pr.role NOT IN (SELECT role FROM incoming)
56
+ )
57
+ INSERT INTO lt_persona_roles (persona_id, role, relationship)
58
+ SELECT $1, role, relationship FROM incoming
59
+ ON CONFLICT (persona_id, role) DO UPDATE SET relationship = EXCLUDED.relationship`;
60
+ // ─── Assignment ───────────────────────────────────────────────────────────────
61
+ exports.INSERT_USER_PERSONA = `INSERT INTO lt_user_personas (user_id, persona_id) VALUES ($1, $2)
62
+ ON CONFLICT DO NOTHING`;
63
+ exports.DELETE_USER_PERSONA = 'DELETE FROM lt_user_personas WHERE user_id = $1 AND persona_id = $2';
64
+ exports.LIST_PERSONA_HOLDER_IDS = 'SELECT user_id FROM lt_user_personas WHERE persona_id = $1';
65
+ /** Users with a membership row still sustained by this persona (drift guard for delete). */
66
+ exports.LIST_SUSTAINED_USER_IDS = 'SELECT DISTINCT user_id FROM lt_user_roles WHERE granted_by_persona = $1';
67
+ // ─── Recompute: materialize persona grants into lt_user_roles ────────────────
68
+ //
69
+ // The single reconciliation statement behind assign, unassign, link edits,
70
+ // persona deletion, and seeding. For every user in $1::uuid[], it derives the
71
+ // highest-allowance union of the user's currently-held personas and reconciles
72
+ // lt_user_roles against it:
73
+ //
74
+ // removed — persona-sustained rows no held persona still grants
75
+ // refreshed — persona-sustained rows overlaid fresh (union scope, re-homed
76
+ // provenance so unassigning one persona never drops a role a
77
+ // sibling persona still grants)
78
+ // raised — DIRECT rows lifted to at least the union (highest allowance
79
+ // wins); scope is never lowered, type and provenance untouched
80
+ // granted — missing rows inserted as scoped members
81
+ //
82
+ // Direct rows (granted_by_persona IS NULL) are never deleted here — persona
83
+ // removal must not touch hand-tuned memberships. Write-rank encoding:
84
+ // write-all=2 (all), write-self=1 (self), read-all=0 (none).
85
+ exports.RECOMPUTE_PERSONA_MEMBERSHIPS = `WITH affected AS (
86
+ SELECT unnest($1::uuid[]) AS user_id
87
+ ), grants AS (
88
+ SELECT up.user_id, pr.role,
89
+ MAX(CASE pr.relationship WHEN 'write-all' THEN 2 WHEN 'write-self' THEN 1 ELSE 0 END) AS write_rank,
90
+ (MIN(pr.persona_id::text))::uuid AS sustaining_persona
91
+ FROM lt_user_personas up
92
+ JOIN lt_persona_roles pr ON pr.persona_id = up.persona_id
93
+ JOIN affected a ON a.user_id = up.user_id
94
+ GROUP BY up.user_id, pr.role
95
+ ), removed AS (
96
+ DELETE FROM lt_user_roles ur
97
+ USING affected a
98
+ WHERE ur.user_id = a.user_id
99
+ AND ur.granted_by_persona IS NOT NULL
100
+ AND NOT EXISTS (SELECT 1 FROM grants g WHERE g.user_id = ur.user_id AND g.role = ur.role)
101
+ RETURNING ur.user_id, ur.role
102
+ ), refreshed AS (
103
+ UPDATE lt_user_roles ur
104
+ SET read_scope = 'all',
105
+ write_scope = CASE g.write_rank WHEN 2 THEN 'all' WHEN 1 THEN 'self' ELSE 'none' END,
106
+ granted_by_persona = g.sustaining_persona
107
+ FROM grants g
108
+ WHERE ur.user_id = g.user_id AND ur.role = g.role
109
+ AND ur.granted_by_persona IS NOT NULL
110
+ RETURNING ur.user_id, ur.role
111
+ ), raised AS (
112
+ UPDATE lt_user_roles ur
113
+ SET read_scope = 'all',
114
+ write_scope = CASE
115
+ WHEN g.write_rank = 2 THEN 'all'
116
+ WHEN g.write_rank = 1 AND ur.write_scope = 'none' THEN 'self'
117
+ ELSE ur.write_scope
118
+ END
119
+ FROM grants g
120
+ WHERE ur.user_id = g.user_id AND ur.role = g.role
121
+ AND ur.granted_by_persona IS NULL
122
+ AND (ur.read_scope <> 'all'
123
+ OR g.write_rank > CASE ur.write_scope WHEN 'all' THEN 2 WHEN 'self' THEN 1 ELSE 0 END)
124
+ RETURNING ur.user_id, ur.role
125
+ ), granted AS (
126
+ INSERT INTO lt_user_roles (user_id, role, type, read_scope, write_scope, granted_by_persona)
127
+ SELECT g.user_id, g.role, 'member', 'all',
128
+ CASE g.write_rank WHEN 2 THEN 'all' WHEN 1 THEN 'self' ELSE 'none' END,
129
+ g.sustaining_persona
130
+ FROM grants g
131
+ WHERE NOT EXISTS (SELECT 1 FROM lt_user_roles ur WHERE ur.user_id = g.user_id AND ur.role = g.role)
132
+ RETURNING user_id, role
133
+ )
134
+ SELECT
135
+ (SELECT COUNT(*)::int FROM granted) AS granted,
136
+ (SELECT COUNT(*)::int FROM refreshed) AS refreshed,
137
+ (SELECT COUNT(*)::int FROM raised) AS raised,
138
+ (SELECT COUNT(*)::int FROM removed) AS removed`;
139
+ // ─── forUser ──────────────────────────────────────────────────────────────────
140
+ exports.GET_USER_PERSONAS = `SELECT p.id, p.key, p.title, p.description, r.roles, up.created_at AS assigned_at
141
+ FROM lt_user_personas up
142
+ JOIN lt_personas p ON p.id = up.persona_id
143
+ LEFT JOIN LATERAL (
144
+ SELECT COALESCE(json_agg(json_build_object('role', pr.role, 'relationship', pr.relationship)
145
+ ORDER BY pr.created_at, pr.role), '[]'::json) AS roles
146
+ FROM lt_persona_roles pr WHERE pr.persona_id = p.id
147
+ ) r ON true
148
+ WHERE up.user_id = $1
149
+ ORDER BY p.key`;
150
+ /** The composed role/scope map: every membership with its sustaining persona key (null = direct). */
151
+ exports.GET_USER_COMPOSED_ROLES = `SELECT ur.role, ur.read_scope, ur.write_scope, p.key AS granted_by_persona
152
+ FROM lt_user_roles ur
153
+ LEFT JOIN lt_personas p ON p.id = ur.granted_by_persona
154
+ WHERE ur.user_id = $1
155
+ ORDER BY ur.role`;
156
+ // ─── Shared ───────────────────────────────────────────────────────────────────
157
+ exports.GET_PERSONA_ID_BY_KEY = 'SELECT id FROM lt_personas WHERE key = $1';
158
+ exports.ENSURE_ROLES_EXIST = `INSERT INTO lt_roles (role) SELECT DISTINCT unnest($1::text[]) ON CONFLICT DO NOTHING`;
@@ -0,0 +1,23 @@
1
+ import type { LTPersonaRelationship, LTWriteScope } from '../../types';
2
+ /**
3
+ * Canonical relationship values, ordered by allowance (highest first). A
4
+ * persona grant is always a `member` membership; the relationship selects the
5
+ * point on the work-surface scope lattice the membership stores.
6
+ */
7
+ export declare const PERSONA_RELATIONSHIPS: LTPersonaRelationship[];
8
+ /** Normalize an input relationship (canonical or alias) — null if unknown. */
9
+ export declare function normalizeRelationship(value: string): LTPersonaRelationship | null;
10
+ /**
11
+ * The membership scope a relationship grants. Read is always `all` (an
12
+ * observer sees the whole pond); write is the axis the relationship selects.
13
+ */
14
+ export declare function relationshipToWriteScope(relationship: LTPersonaRelationship): LTWriteScope;
15
+ export interface CreatePersonaInput {
16
+ key: string;
17
+ title?: string;
18
+ description?: string;
19
+ }
20
+ export interface UpdatePersonaInput {
21
+ title?: string | null;
22
+ description?: string | null;
23
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PERSONA_RELATIONSHIPS = void 0;
4
+ exports.normalizeRelationship = normalizeRelationship;
5
+ exports.relationshipToWriteScope = relationshipToWriteScope;
6
+ /**
7
+ * Canonical relationship values, ordered by allowance (highest first). A
8
+ * persona grant is always a `member` membership; the relationship selects the
9
+ * point on the work-surface scope lattice the membership stores.
10
+ */
11
+ exports.PERSONA_RELATIONSHIPS = ['write-all', 'write-self', 'read-all'];
12
+ /** Input synonyms accepted at every surface and normalized to canonical values. */
13
+ const RELATIONSHIP_ALIASES = {
14
+ 'write-none': 'read-all',
15
+ };
16
+ /** Normalize an input relationship (canonical or alias) — null if unknown. */
17
+ function normalizeRelationship(value) {
18
+ if (exports.PERSONA_RELATIONSHIPS.includes(value)) {
19
+ return value;
20
+ }
21
+ return RELATIONSHIP_ALIASES[value] ?? null;
22
+ }
23
+ /**
24
+ * The membership scope a relationship grants. Read is always `all` (an
25
+ * observer sees the whole pond); write is the axis the relationship selects.
26
+ */
27
+ function relationshipToWriteScope(relationship) {
28
+ switch (relationship) {
29
+ case 'write-all': return 'all';
30
+ case 'write-self': return 'self';
31
+ case 'read-all': return 'none';
32
+ }
33
+ }
@@ -1,7 +1,8 @@
1
1
  /** Ensure a role name exists in the lt_roles lookup table (FK target). */
2
2
  export declare const ENSURE_ROLE_EXISTS = "INSERT INTO lt_roles (role) VALUES ($1) ON CONFLICT DO NOTHING";
3
- /** Fetch roles for a single user, ordered by creation time. */
4
- export declare const GET_ROLES_BY_USER_ID = "SELECT role, type, read_scope, write_scope, created_at FROM lt_user_roles WHERE user_id = $1 ORDER BY created_at";
3
+ /** Fetch roles for a single user, ordered by creation time. granted_by_persona
4
+ * is the sustaining persona's key (null = direct grant). */
5
+ export declare const GET_ROLES_BY_USER_ID = "SELECT r.role, r.type, r.read_scope, r.write_scope, r.created_at, p.key AS granted_by_persona\n FROM lt_user_roles r\n LEFT JOIN lt_personas p ON p.id = r.granted_by_persona\n WHERE r.user_id = $1 ORDER BY r.created_at";
5
6
  /** Fetch a user row by external_id. */
6
7
  export declare const GET_USER_BY_EXTERNAL_ID = "SELECT * FROM lt_users WHERE external_id = $1";
7
8
  /**
@@ -23,9 +24,11 @@ export declare const VERIFY_USER_BY_ID = "SELECT id FROM lt_users WHERE id = $1
23
24
  export declare const GET_USER_WITH_ROLES = "SELECT u.id, u.external_id, u.display_name, u.status, u.metadata,\n r.role, r.type AS role_type, r.read_scope, r.write_scope\n FROM lt_users u\n LEFT JOIN lt_user_roles r ON r.user_id = u.id\n WHERE u.external_id = $1\n ORDER BY r.created_at";
24
25
  export declare const DELETE_USER_BY_ID = "DELETE FROM lt_users WHERE id = $1";
25
26
  /** Batch-load roles for many users (avoids N+1). */
26
- export declare const GET_ROLES_BY_USER_IDS = "SELECT user_id, role, type, read_scope, write_scope, created_at FROM lt_user_roles WHERE user_id = ANY($1) ORDER BY created_at";
27
- /** Upsert a user–role assignment, promoting the type/scope if the row exists. */
28
- export declare const UPSERT_USER_ROLE = "INSERT INTO lt_user_roles (user_id, role, type, read_scope, write_scope) VALUES ($1, $2, $3, $4, $5)\n ON CONFLICT (user_id, role) DO UPDATE SET\n type = EXCLUDED.type,\n read_scope = EXCLUDED.read_scope,\n write_scope = EXCLUDED.write_scope\n RETURNING role, type, read_scope, write_scope, created_at";
27
+ export declare const GET_ROLES_BY_USER_IDS = "SELECT r.user_id, r.role, r.type, r.read_scope, r.write_scope, r.created_at, p.key AS granted_by_persona\n FROM lt_user_roles r\n LEFT JOIN lt_personas p ON p.id = r.granted_by_persona\n WHERE r.user_id = ANY($1) ORDER BY r.created_at";
28
+ /** Upsert a user–role assignment, promoting the type/scope if the row exists.
29
+ * A direct grant takes the row over: granted_by_persona resets to NULL, so a
30
+ * later persona unassign can never remove a membership an admin set by hand. */
31
+ export declare const UPSERT_USER_ROLE = "INSERT INTO lt_user_roles (user_id, role, type, read_scope, write_scope) VALUES ($1, $2, $3, $4, $5)\n ON CONFLICT (user_id, role) DO UPDATE SET\n type = EXCLUDED.type,\n read_scope = EXCLUDED.read_scope,\n write_scope = EXCLUDED.write_scope,\n granted_by_persona = NULL\n RETURNING role, type, read_scope, write_scope, created_at";
29
32
  export declare const DELETE_USER_ROLE = "DELETE FROM lt_user_roles WHERE user_id = $1 AND role = $2";
30
33
  export declare const HAS_ROLE = "SELECT 1 FROM lt_user_roles WHERE user_id = $1 AND role = $2 LIMIT 1";
31
34
  export declare const HAS_ROLE_TYPE = "SELECT 1 FROM lt_user_roles WHERE user_id = $1 AND type = $2 LIMIT 1";
@@ -4,8 +4,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.IS_GROUP_ADMIN = exports.GET_ROLE_SCOPE = exports.HAS_ROLE_TYPE = exports.HAS_ROLE = exports.DELETE_USER_ROLE = exports.UPSERT_USER_ROLE = exports.GET_ROLES_BY_USER_IDS = exports.DELETE_USER_BY_ID = exports.GET_USER_WITH_ROLES = exports.VERIFY_USER_BY_ID = exports.GET_USER_BY_ID = exports.GET_USER_BY_EMAIL = exports.CREATE_USER_WITH_ROLES = exports.GET_USER_BY_EXTERNAL_ID = exports.GET_ROLES_BY_USER_ID = exports.ENSURE_ROLE_EXISTS = void 0;
5
5
  /** Ensure a role name exists in the lt_roles lookup table (FK target). */
6
6
  exports.ENSURE_ROLE_EXISTS = 'INSERT INTO lt_roles (role) VALUES ($1) ON CONFLICT DO NOTHING';
7
- /** Fetch roles for a single user, ordered by creation time. */
8
- exports.GET_ROLES_BY_USER_ID = 'SELECT role, type, read_scope, write_scope, created_at FROM lt_user_roles WHERE user_id = $1 ORDER BY created_at';
7
+ /** Fetch roles for a single user, ordered by creation time. granted_by_persona
8
+ * is the sustaining persona's key (null = direct grant). */
9
+ exports.GET_ROLES_BY_USER_ID = `SELECT r.role, r.type, r.read_scope, r.write_scope, r.created_at, p.key AS granted_by_persona
10
+ FROM lt_user_roles r
11
+ LEFT JOIN lt_personas p ON p.id = r.granted_by_persona
12
+ WHERE r.user_id = $1 ORDER BY r.created_at`;
9
13
  /** Fetch a user row by external_id. */
10
14
  exports.GET_USER_BY_EXTERNAL_ID = 'SELECT * FROM lt_users WHERE external_id = $1';
11
15
  // ─── User CRUD ───────────────────────────────────────────────────────────────
@@ -48,13 +52,19 @@ exports.GET_USER_WITH_ROLES = `SELECT u.id, u.external_id, u.display_name, u.sta
48
52
  exports.DELETE_USER_BY_ID = 'DELETE FROM lt_users WHERE id = $1';
49
53
  // ─── Role management ─────────────────────────────────────────────────────────
50
54
  /** Batch-load roles for many users (avoids N+1). */
51
- exports.GET_ROLES_BY_USER_IDS = 'SELECT user_id, role, type, read_scope, write_scope, created_at FROM lt_user_roles WHERE user_id = ANY($1) ORDER BY created_at';
52
- /** Upsert a user–role assignment, promoting the type/scope if the row exists. */
55
+ exports.GET_ROLES_BY_USER_IDS = `SELECT r.user_id, r.role, r.type, r.read_scope, r.write_scope, r.created_at, p.key AS granted_by_persona
56
+ FROM lt_user_roles r
57
+ LEFT JOIN lt_personas p ON p.id = r.granted_by_persona
58
+ WHERE r.user_id = ANY($1) ORDER BY r.created_at`;
59
+ /** Upsert a user–role assignment, promoting the type/scope if the row exists.
60
+ * A direct grant takes the row over: granted_by_persona resets to NULL, so a
61
+ * later persona unassign can never remove a membership an admin set by hand. */
53
62
  exports.UPSERT_USER_ROLE = `INSERT INTO lt_user_roles (user_id, role, type, read_scope, write_scope) VALUES ($1, $2, $3, $4, $5)
54
63
  ON CONFLICT (user_id, role) DO UPDATE SET
55
64
  type = EXCLUDED.type,
56
65
  read_scope = EXCLUDED.read_scope,
57
- write_scope = EXCLUDED.write_scope
66
+ write_scope = EXCLUDED.write_scope,
67
+ granted_by_persona = NULL
58
68
  RETURNING role, type, read_scope, write_scope, created_at`;
59
69
  exports.DELETE_USER_ROLE = 'DELETE FROM lt_user_roles WHERE user_id = $1 AND role = $2';
60
70
  exports.HAS_ROLE = 'SELECT 1 FROM lt_user_roles WHERE user_id = $1 AND role = $2 LIMIT 1';
@@ -11,6 +11,7 @@
11
11
  * mcp-servers.ts — routes/mcp.ts
12
12
  * yaml-workflows.ts — routes/yaml-workflows/
13
13
  * users.ts — routes/users.ts + routes/roles.ts
14
+ * personas.ts — routes/personas.ts + persona sub-routes on routes/users.ts
14
15
  * maintenance.ts — routes/dba.ts
15
16
  * agents.ts — routes/agents.ts
16
17
  * agent-subscriptions.ts — routes/agents.ts (subscription sub-routes)
@@ -16,6 +16,7 @@ exports.stopAdminServer = stopAdminServer;
16
16
  * mcp-servers.ts — routes/mcp.ts
17
17
  * yaml-workflows.ts — routes/yaml-workflows/
18
18
  * users.ts — routes/users.ts + routes/roles.ts
19
+ * personas.ts — routes/personas.ts + persona sub-routes on routes/users.ts
19
20
  * maintenance.ts — routes/dba.ts
20
21
  * agents.ts — routes/agents.ts
21
22
  * agent-subscriptions.ts — routes/agents.ts (subscription sub-routes)
@@ -44,6 +45,7 @@ const workflows_1 = require("./workflows");
44
45
  const mcp_servers_1 = require("./mcp-servers");
45
46
  const yaml_workflows_1 = require("./yaml-workflows");
46
47
  const users_1 = require("./users");
48
+ const personas_1 = require("./personas");
47
49
  const maintenance_1 = require("./maintenance");
48
50
  const agents_1 = require("./agents");
49
51
  const agent_subscriptions_1 = require("./agent-subscriptions");
@@ -56,7 +58,7 @@ const exports_1 = require("./exports");
56
58
  const overview_1 = require("./overview");
57
59
  const diagnostics_1 = require("./diagnostics");
58
60
  const ortho_1 = require("./ortho");
59
- const TOOL_COUNT = 90;
61
+ const TOOL_COUNT = 100;
60
62
  let server = null;
61
63
  async function createAdminServer(options) {
62
64
  if (server && !options?.fresh)
@@ -73,6 +75,7 @@ async function createAdminServer(options) {
73
75
  (0, mcp_servers_1.registerMcpServerTools)(instance); // 4 tools
74
76
  (0, yaml_workflows_1.registerYamlWorkflowTools)(instance); // 5 tools
75
77
  (0, users_1.registerUserTools)(instance); // 10 tools (users + roles + role schemas)
78
+ (0, personas_1.registerPersonaTools)(instance); // 10 tools (persona CRUD + links + assignment)
76
79
  (0, maintenance_1.registerMaintenanceTools)(instance); // 1 tool
77
80
  (0, agents_1.registerAgentTools)(instance); // 5 tools
78
81
  (0, agent_subscriptions_1.registerAgentSubscriptionTools)(instance); // 3 tools
@@ -85,7 +88,7 @@ async function createAdminServer(options) {
85
88
  (0, overview_1.registerOverviewTools)(instance); // 1 tool
86
89
  (0, diagnostics_1.registerDiagnosticsTools)(instance); // 3 tools
87
90
  (0, ortho_1.registerOrthoTools)(instance); // 4 tools
88
- // Total: 90
91
+ // Total: 100
89
92
  logger_1.loggerRegistry.info(`[lt-mcp:admin] ${name} ready (${TOOL_COUNT} tools registered)`);
90
93
  return instance;
91
94
  }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Persona management tools — mirrors routes/personas.ts plus the persona
3
+ * sub-routes on routes/users.ts. A persona is a named bundle of roles with a
4
+ * per-role relationship scope; assigning one fans out to ordinary scoped role
5
+ * memberships (lt_user_roles stays the single source of authorization truth).
6
+ */
7
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
8
+ export declare function registerPersonaTools(server: McpServer): void;
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.registerPersonaTools = registerPersonaTools;
37
+ const personaService = __importStar(require("../../../services/persona"));
38
+ const schemas_1 = require("./schemas");
39
+ const PERSONA_KEY = /^[a-z][a-z0-9_-]*$/;
40
+ function errorResult(message) {
41
+ return {
42
+ content: [{ type: 'text', text: JSON.stringify({ error: message }) }],
43
+ isError: true,
44
+ };
45
+ }
46
+ function jsonResult(data) {
47
+ return {
48
+ content: [{ type: 'text', text: JSON.stringify(data) }],
49
+ };
50
+ }
51
+ function registerPersonaTools(server) {
52
+ // mirrors GET /api/personas
53
+ server.registerTool('list_personas', {
54
+ title: 'List Personas',
55
+ description: 'List all personas — named role bundles with per-role relationship ' +
56
+ 'scope — with their role links and holder counts.',
57
+ inputSchema: schemas_1.listPersonasSchema,
58
+ }, async (_args) => {
59
+ const personas = await personaService.listPersonas();
60
+ return jsonResult({ personas });
61
+ });
62
+ // mirrors GET /api/personas/:key
63
+ server.registerTool('get_persona', {
64
+ title: 'Get Persona',
65
+ description: 'Fetch one persona with its role links and current assignees.',
66
+ inputSchema: schemas_1.getPersonaSchema,
67
+ }, async (args) => {
68
+ const persona = await personaService.getPersona(args.key);
69
+ if (!persona)
70
+ return errorResult(`Persona '${args.key}' not found`);
71
+ return jsonResult(persona);
72
+ });
73
+ // mirrors POST /api/personas
74
+ server.registerTool('create_persona', {
75
+ title: 'Create Persona',
76
+ description: 'Create a persona. Link roles with link_persona_role, then assign ' +
77
+ 'users with assign_persona.',
78
+ inputSchema: schemas_1.createPersonaSchema,
79
+ }, async (args) => {
80
+ const key = args.key.trim().toLowerCase();
81
+ if (!PERSONA_KEY.test(key)) {
82
+ return errorResult('key must start with a letter and contain only lowercase letters, numbers, hyphens, and underscores');
83
+ }
84
+ const persona = await personaService.createPersona({
85
+ key,
86
+ title: args.title,
87
+ description: args.description,
88
+ });
89
+ return jsonResult(persona);
90
+ });
91
+ // mirrors PATCH /api/personas/:key
92
+ server.registerTool('update_persona', {
93
+ title: 'Update Persona',
94
+ description: 'Update a persona\'s title/description with PATCH semantics — omitted fields keep their values; null clears.',
95
+ inputSchema: schemas_1.updatePersonaSchema,
96
+ }, async (args) => {
97
+ const persona = await personaService.updatePersona(args.key, {
98
+ title: args.title,
99
+ description: args.description,
100
+ });
101
+ if (!persona)
102
+ return errorResult(`Persona '${args.key}' not found`);
103
+ return jsonResult(persona);
104
+ });
105
+ // mirrors DELETE /api/personas/:key
106
+ server.registerTool('delete_persona', {
107
+ title: 'Delete Persona',
108
+ description: 'Delete a persona. Memberships it sustains are removed (or re-homed ' +
109
+ 'to a sibling persona the user still holds); direct grants are never touched.',
110
+ inputSchema: schemas_1.deletePersonaSchema,
111
+ }, async (args) => {
112
+ const result = await personaService.deletePersona(args.key);
113
+ if (!result.deleted)
114
+ return errorResult(`Persona '${args.key}' not found`);
115
+ return jsonResult({ deleted: true, recompute: result.recompute });
116
+ });
117
+ // mirrors PUT /api/personas/:key/roles/:role
118
+ server.registerTool('link_persona_role', {
119
+ title: 'Link Persona Role',
120
+ description: 'Link a role to a persona (or change the link\'s relationship). Every ' +
121
+ 'current holder\'s memberships are reconciled in the same transaction.',
122
+ inputSchema: schemas_1.linkPersonaRoleSchema,
123
+ }, async (args) => {
124
+ const relationship = personaService.normalizeRelationship(args.relationship);
125
+ if (!relationship) {
126
+ return errorResult('relationship must be write-all, write-self, or read-all (write-none is accepted as read-all)');
127
+ }
128
+ const result = await personaService.linkPersonaRole(args.key, args.role.trim().toLowerCase(), relationship);
129
+ if (!result)
130
+ return errorResult(`Persona '${args.key}' not found`);
131
+ return jsonResult(result);
132
+ });
133
+ // mirrors DELETE /api/personas/:key/roles/:role
134
+ server.registerTool('unlink_persona_role', {
135
+ title: 'Unlink Persona Role',
136
+ description: 'Remove a role link from a persona and reconcile every holder\'s memberships.',
137
+ inputSchema: schemas_1.unlinkPersonaRoleSchema,
138
+ }, async (args) => {
139
+ const result = await personaService.unlinkPersonaRole(args.key, args.role);
140
+ if (!result.personaFound)
141
+ return errorResult(`Persona '${args.key}' not found`);
142
+ if (!result.unlinked)
143
+ return errorResult(`Persona '${args.key}' does not link role '${args.role}'`);
144
+ return jsonResult({ unlinked: true, recompute: result.recompute });
145
+ });
146
+ // mirrors POST /api/users/:id/personas
147
+ server.registerTool('assign_persona', {
148
+ title: 'Assign Persona',
149
+ description: 'Assign a persona to a user — shorthand for adding the user to each ' +
150
+ 'linked role at the linked scope. Idempotent: re-assigning overlays ' +
151
+ 'fresh from the persona\'s current links. Highest allowance wins when ' +
152
+ 'bundles overlap; direct grants are only ever raised, never lowered.',
153
+ inputSchema: schemas_1.assignPersonaSchema,
154
+ }, async (args) => {
155
+ const recompute = await personaService.assignPersona(args.user_id, args.key);
156
+ if (!recompute)
157
+ return errorResult(`Persona '${args.key}' not found`);
158
+ return jsonResult({ assigned: true, recompute });
159
+ });
160
+ // mirrors DELETE /api/users/:id/personas/:key
161
+ server.registerTool('unassign_persona', {
162
+ title: 'Unassign Persona',
163
+ description: 'Unassign a persona from a user. Removes only memberships the persona ' +
164
+ 'sustains — rows another held persona still grants are re-homed to it, ' +
165
+ 'and direct grants are never touched.',
166
+ inputSchema: schemas_1.unassignPersonaSchema,
167
+ }, async (args) => {
168
+ const result = await personaService.unassignPersona(args.user_id, args.key);
169
+ if (!result.personaFound)
170
+ return errorResult(`Persona '${args.key}' not found`);
171
+ if (!result.unassigned)
172
+ return errorResult(`User does not hold persona '${args.key}'`);
173
+ return jsonResult({ unassigned: true, recompute: result.recompute });
174
+ });
175
+ // mirrors GET /api/users/:id/personas
176
+ server.registerTool('get_user_personas', {
177
+ title: 'Get User Personas',
178
+ description: 'The personas a user holds plus the composed role/scope map their ' +
179
+ 'memberships form (each row names the sustaining persona, or null for ' +
180
+ 'a direct grant).',
181
+ inputSchema: schemas_1.getUserPersonasSchema,
182
+ }, async (args) => {
183
+ const result = await personaService.getUserPersonas(args.user_id);
184
+ return jsonResult(result);
185
+ });
186
+ }
@@ -648,6 +648,97 @@ export declare const listRoleSchemaVersionsSchema: z.ZodObject<{
648
648
  }, {
649
649
  role: string;
650
650
  }>;
651
+ export declare const listPersonasSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
652
+ export declare const getPersonaSchema: z.ZodObject<{
653
+ key: z.ZodString;
654
+ }, "strip", z.ZodTypeAny, {
655
+ key: string;
656
+ }, {
657
+ key: string;
658
+ }>;
659
+ export declare const createPersonaSchema: z.ZodObject<{
660
+ key: z.ZodString;
661
+ title: z.ZodOptional<z.ZodString>;
662
+ description: z.ZodOptional<z.ZodString>;
663
+ }, "strip", z.ZodTypeAny, {
664
+ key: string;
665
+ description?: string | undefined;
666
+ title?: string | undefined;
667
+ }, {
668
+ key: string;
669
+ description?: string | undefined;
670
+ title?: string | undefined;
671
+ }>;
672
+ export declare const updatePersonaSchema: z.ZodObject<{
673
+ key: z.ZodString;
674
+ title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
675
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
676
+ }, "strip", z.ZodTypeAny, {
677
+ key: string;
678
+ description?: string | null | undefined;
679
+ title?: string | null | undefined;
680
+ }, {
681
+ key: string;
682
+ description?: string | null | undefined;
683
+ title?: string | null | undefined;
684
+ }>;
685
+ export declare const deletePersonaSchema: z.ZodObject<{
686
+ key: z.ZodString;
687
+ }, "strip", z.ZodTypeAny, {
688
+ key: string;
689
+ }, {
690
+ key: string;
691
+ }>;
692
+ export declare const linkPersonaRoleSchema: z.ZodObject<{
693
+ key: z.ZodString;
694
+ role: z.ZodString;
695
+ relationship: z.ZodEnum<["write-all", "write-self", "read-all", "write-none"]>;
696
+ }, "strip", z.ZodTypeAny, {
697
+ role: string;
698
+ key: string;
699
+ relationship: "write-all" | "write-self" | "read-all" | "write-none";
700
+ }, {
701
+ role: string;
702
+ key: string;
703
+ relationship: "write-all" | "write-self" | "read-all" | "write-none";
704
+ }>;
705
+ export declare const unlinkPersonaRoleSchema: z.ZodObject<{
706
+ key: z.ZodString;
707
+ role: z.ZodString;
708
+ }, "strip", z.ZodTypeAny, {
709
+ role: string;
710
+ key: string;
711
+ }, {
712
+ role: string;
713
+ key: string;
714
+ }>;
715
+ export declare const assignPersonaSchema: z.ZodObject<{
716
+ user_id: z.ZodString;
717
+ key: z.ZodString;
718
+ }, "strip", z.ZodTypeAny, {
719
+ key: string;
720
+ user_id: string;
721
+ }, {
722
+ key: string;
723
+ user_id: string;
724
+ }>;
725
+ export declare const unassignPersonaSchema: z.ZodObject<{
726
+ user_id: z.ZodString;
727
+ key: z.ZodString;
728
+ }, "strip", z.ZodTypeAny, {
729
+ key: string;
730
+ user_id: string;
731
+ }, {
732
+ key: string;
733
+ user_id: string;
734
+ }>;
735
+ export declare const getUserPersonasSchema: z.ZodObject<{
736
+ user_id: z.ZodString;
737
+ }, "strip", z.ZodTypeAny, {
738
+ user_id: string;
739
+ }, {
740
+ user_id: string;
741
+ }>;
651
742
  export declare const pruneSchema: z.ZodObject<{
652
743
  app_id: z.ZodDefault<z.ZodOptional<z.ZodString>>;
653
744
  expire: z.ZodDefault<z.ZodOptional<z.ZodString>>;