@hotmeshio/long-tail 0.10.9 → 0.10.11
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.
- package/build/api/escalations/list.js +11 -4
- package/build/api/index.d.ts +1 -0
- package/build/api/index.js +2 -1
- package/build/api/personas.d.ts +121 -0
- package/build/api/personas.js +341 -0
- package/build/api/roles.d.ts +2 -0
- package/build/api/roles.js +4 -0
- package/build/bin/ltc.js +23 -0
- package/build/lib/cli/commands/personas.d.ts +16 -0
- package/build/lib/cli/commands/personas.js +42 -0
- package/build/lib/db/schemas/024_personas.sql +53 -0
- package/build/lib/db/schemas/025_ops_home_default.sql +11 -0
- package/build/modules/features.d.ts +9 -0
- package/build/modules/features.js +1 -0
- package/build/routes/index.js +2 -0
- package/build/routes/personas.d.ts +2 -0
- package/build/routes/personas.js +118 -0
- package/build/routes/users.js +35 -0
- package/build/sdk/index.d.ts +15 -0
- package/build/sdk/index.js +16 -0
- package/build/services/persona/index.d.ts +92 -0
- package/build/services/persona/index.js +217 -0
- package/build/services/persona/sql.d.ts +24 -0
- package/build/services/persona/sql.js +158 -0
- package/build/services/persona/types.d.ts +23 -0
- package/build/services/persona/types.js +33 -0
- package/build/services/role/index.js +1 -0
- package/build/services/role/sql.d.ts +6 -2
- package/build/services/role/sql.js +11 -2
- package/build/services/role/types.d.ts +9 -0
- package/build/services/user/sql.d.ts +8 -5
- package/build/services/user/sql.js +15 -5
- package/build/system/mcp-servers/admin/index.d.ts +1 -0
- package/build/system/mcp-servers/admin/index.js +5 -2
- package/build/system/mcp-servers/admin/personas.d.ts +8 -0
- package/build/system/mcp-servers/admin/personas.js +186 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +94 -0
- package/build/system/mcp-servers/admin/schemas.js +43 -2
- package/build/system/mcp-servers/admin/users.js +1 -0
- package/build/system/seed/tool-manifests-admin.d.ts +1057 -0
- package/build/system/seed/tool-manifests-admin.js +12 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/index.d.ts +1 -0
- package/build/types/persona.d.ts +56 -0
- package/build/types/persona.js +2 -0
- package/build/types/startup.d.ts +8 -0
- package/build/types/user.d.ts +2 -0
- package/dashboard/dist/assets/{AdminDashboard-DWSYdAeW.js → AdminDashboard-CkTbRfY9.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-DWSYdAeW.js.map → AdminDashboard-CkTbRfY9.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-Dm6gL76m.js → AgentConfigPage-Cm8FRpXi.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-Dm6gL76m.js.map → AgentConfigPage-Cm8FRpXi.js.map} +1 -1
- package/dashboard/dist/assets/AgentDetailPage-sQ1-UT46.js +4 -0
- package/dashboard/dist/assets/AgentDetailPage-sQ1-UT46.js.map +1 -0
- package/dashboard/dist/assets/{AgentsPage-DKaDRk-Y.js → AgentsPage-bSx_mdae.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-DKaDRk-Y.js.map → AgentsPage-bSx_mdae.js.map} +1 -1
- package/dashboard/dist/assets/AutoGrowTextarea-y-oNY51_.js +2 -0
- package/dashboard/dist/assets/AutoGrowTextarea-y-oNY51_.js.map +1 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-8pMC7Xv6.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-8pMC7Xv6.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-DRv_orzI.js → BotPicker-C4uGH2x9.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-DRv_orzI.js.map → BotPicker-C4uGH2x9.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-DqRVzMol.js → CapabilitiesPage-BRoOeKcc.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-DqRVzMol.js.map → CapabilitiesPage-BRoOeKcc.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-D0psvw8i.js → CollapsibleSection-CIj8Adc9.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-D0psvw8i.js.map → CollapsibleSection-CIj8Adc9.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-DD7SEMeX.js → ConfirmDeleteModal-Ugi_9Ukq.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-DD7SEMeX.js.map → ConfirmDeleteModal-Ugi_9Ukq.js.map} +1 -1
- package/dashboard/dist/assets/{CopyableId-BpB-NvDh.js → CopyableId-GUEdiiL5.js} +2 -2
- package/dashboard/dist/assets/{CopyableId-BpB-NvDh.js.map → CopyableId-GUEdiiL5.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-D3t0XMhE.js +2 -0
- package/dashboard/dist/assets/CountdownTimer-D3t0XMhE.js.map +1 -0
- package/dashboard/dist/assets/{CredentialsPage-Axdci1z-.js → CredentialsPage-B73Si6K1.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-Axdci1z-.js.map → CredentialsPage-B73Si6K1.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-BjZ_wZA8.js → CronLabel-Ca1aHolt.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-BjZ_wZA8.js.map → CronLabel-Ca1aHolt.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-CkUCMUfk.js → CustomDurationPicker-_9E9x1YN.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-CkUCMUfk.js.map → CustomDurationPicker-_9E9x1YN.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-_tmC3jEe.js → DropZone-NYn6TWHz.js} +2 -2
- package/dashboard/dist/assets/{DropZone-_tmC3jEe.js.map → DropZone-NYn6TWHz.js.map} +1 -1
- package/dashboard/dist/assets/ElapsedCell-karxia93.js +2 -0
- package/dashboard/dist/assets/{ElapsedCell-BE_CN5sP.js.map → ElapsedCell-karxia93.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-CgcVIiYR.js → EscalationListSchemaPage-CDaNmbUA.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-CgcVIiYR.js.map → EscalationListSchemaPage-CDaNmbUA.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-BaAn1Hcr.js → EscalationSchemaPage-k-2hFT2t.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-BaAn1Hcr.js.map → EscalationSchemaPage-k-2hFT2t.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-Dbq7tKzr.js → EscalationsOverview-C1e7IPn_.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-Dbq7tKzr.js.map → EscalationsOverview-C1e7IPn_.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-0RUK9jqt.js → EventTable-CIrrtL7_.js} +2 -2
- package/dashboard/dist/assets/{EventTable-0RUK9jqt.js.map → EventTable-CIrrtL7_.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-B_dy2Jhj.js → FilterBar-CzjtH74v.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-B_dy2Jhj.js.map → FilterBar-CzjtH74v.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-CvLYp1nL.js → GraphInvokePage-LMpWw8z1.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-CvLYp1nL.js.map → GraphInvokePage-LMpWw8z1.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-Kl2DBG6l.js +2 -0
- package/dashboard/dist/assets/HomePage-Kl2DBG6l.js.map +1 -0
- package/dashboard/dist/assets/ListToolbar-B2fub0DY.js +2 -0
- package/dashboard/dist/assets/ListToolbar-B2fub0DY.js.map +1 -0
- package/dashboard/dist/assets/{McpOverview-Ca8cpc8g.js → McpOverview-odYnCZCC.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-Ca8cpc8g.js.map → McpOverview-odYnCZCC.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryDetailPage-BtqwHUAg.js +5 -0
- package/dashboard/dist/assets/McpQueryDetailPage-BtqwHUAg.js.map +1 -0
- package/dashboard/dist/assets/McpQueryPage-CPkVwNIK.js +2 -0
- package/dashboard/dist/assets/McpQueryPage-CPkVwNIK.js.map +1 -0
- package/dashboard/dist/assets/{McpRunDetailPage-C76mfUtG.js → McpRunDetailPage-D-Rz9MRw.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-C76mfUtG.js.map → McpRunDetailPage-D-Rz9MRw.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-B43BqEyw.js → McpRunsPage-rdpZ2yMh.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-B43BqEyw.js.map → McpRunsPage-rdpZ2yMh.js.map} +1 -1
- package/dashboard/dist/assets/{Modal-CA2Iv02H.js → Modal-Dr1Xy0j0.js} +2 -2
- package/dashboard/dist/assets/{Modal-CA2Iv02H.js.map → Modal-Dr1Xy0j0.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-B5gHotsd.js → NamespacePill-GwO-WfhX.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-B5gHotsd.js.map → NamespacePill-GwO-WfhX.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-DlyGLPAs.js +2 -0
- package/dashboard/dist/assets/OperationsPage-DlyGLPAs.js.map +1 -0
- package/dashboard/dist/assets/OperatorDashboard-Csei5vj-.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-Csei5vj-.js.map +1 -0
- package/dashboard/dist/assets/{PageHeader-DrbNMGxm.js → PageHeader-Bo9BU9pK.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-DrbNMGxm.js.map → PageHeader-Bo9BU9pK.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-SbQkaQLG.js → PageHeaderWithStats-8_5cOSKL.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-SbQkaQLG.js.map → PageHeaderWithStats-8_5cOSKL.js.map} +1 -1
- package/dashboard/dist/assets/PersonaDetailPage--ZL6Or6v.js +2 -0
- package/dashboard/dist/assets/PersonaDetailPage--ZL6Or6v.js.map +1 -0
- package/dashboard/dist/assets/PersonasPage-Bdcoay3P.js +2 -0
- package/dashboard/dist/assets/PersonasPage-Bdcoay3P.js.map +1 -0
- package/dashboard/dist/assets/ProcessDetailPage-HrmVQq7S.js +2 -0
- package/dashboard/dist/assets/ProcessDetailPage-HrmVQq7S.js.map +1 -0
- package/dashboard/dist/assets/{ProcessesListPage-Di0n8TR4.js → ProcessesListPage-_xmj6Bo-.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-Di0n8TR4.js.map → ProcessesListPage-_xmj6Bo-.js.map} +1 -1
- package/dashboard/dist/assets/RoleDetailPage-C0ju2-4K.js +8 -0
- package/dashboard/dist/assets/RoleDetailPage-C0ju2-4K.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-Cz-AAWqA.js → RolePill-CQlnEWkK.js} +2 -2
- package/dashboard/dist/assets/{RolePill-Cz-AAWqA.js.map → RolePill-CQlnEWkK.js.map} +1 -1
- package/dashboard/dist/assets/RolesPage-CKluVSpB.js +2 -0
- package/dashboard/dist/assets/RolesPage-CKluVSpB.js.map +1 -0
- package/dashboard/dist/assets/{RunAsSelector-DFv0VNVZ.js → RunAsSelector-DdfecQ1U.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-DFv0VNVZ.js.map → RunAsSelector-DdfecQ1U.js.map} +1 -1
- package/dashboard/dist/assets/ScopeBadge-BBYkevuR.js +2 -0
- package/dashboard/dist/assets/ScopeBadge-BBYkevuR.js.map +1 -0
- package/dashboard/dist/assets/StatCard-Ca-ngCaD.js +2 -0
- package/dashboard/dist/assets/StatCard-Ca-ngCaD.js.map +1 -0
- package/dashboard/dist/assets/{StatusBadge-BbqghFMi.js → StatusBadge-BwUvykDo.js} +2 -2
- package/dashboard/dist/assets/{StatusBadge-BbqghFMi.js.map → StatusBadge-BwUvykDo.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-D5zxe_l9.js → StickyPagination-cLddIdtT.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-D5zxe_l9.js.map → StickyPagination-cLddIdtT.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-BmBfNSEr.js → StreamMessageDetail-CZXWDawC.js} +2 -2
- package/dashboard/dist/assets/StreamMessageDetail-CZXWDawC.js.map +1 -0
- package/dashboard/dist/assets/{SwimlaneTimeline-CA0TKDIi.js → SwimlaneTimeline-fWY0gaf3.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-CA0TKDIi.js.map → SwimlaneTimeline-fWY0gaf3.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-Bf9dZSG6.js → TagInput-CDKbslLx.js} +2 -2
- package/dashboard/dist/assets/{TagInput-Bf9dZSG6.js.map → TagInput-CDKbslLx.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-C15nADUW.js → TaskDetailPage-BjE4G2yn.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-C15nADUW.js.map → TaskDetailPage-BjE4G2yn.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-DfiBYQy2.js → TaskQueuePill-G3RuYRNZ.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-DfiBYQy2.js.map → TaskQueuePill-G3RuYRNZ.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-DQdAayqc.js → TasksListPage-KAhmCWB2.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-DQdAayqc.js.map → TasksListPage-KAhmCWB2.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-CvslqTB7.js → TimeAgo-C_H2TyZw.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-CvslqTB7.js.map → TimeAgo-C_H2TyZw.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-BZCQQONl.js → TimestampCell-COG_4Flg.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-BZCQQONl.js.map → TimestampCell-COG_4Flg.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-gA4sXukc.js → ToolPill-ChSyRJZC.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-gA4sXukc.js.map → ToolPill-ChSyRJZC.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-BgLVc6R5.js → ToolTestPanel-BPdJECW0.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-BgLVc6R5.js.map → ToolTestPanel-BPdJECW0.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-9A0aPb4t.js → TopicDetailPage-DAqx5JqA.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-9A0aPb4t.js.map → TopicDetailPage-DAqx5JqA.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-o0EZxKbR.js → TopicsPage-DoGqAdPm.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-o0EZxKbR.js.map → TopicsPage-DoGqAdPm.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DKMLxBJ5.js → UserName-CKO_rk1R.js} +2 -2
- package/dashboard/dist/assets/{UserName-DKMLxBJ5.js.map → UserName-CKO_rk1R.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-C-snB_dD.js → WorkflowExecutionPage-D3VQ9iQV.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-C-snB_dD.js.map → WorkflowExecutionPage-D3VQ9iQV.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-Djt2AtZk.js → WorkflowPill-CNbwug5p.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-Djt2AtZk.js.map → WorkflowPill-CNbwug5p.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-BRQmgsLR.js → WorkflowsDashboard-DdJ86We6.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-BRQmgsLR.js.map → WorkflowsDashboard-DdJ86We6.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-DmMdIRHQ.js → WorkflowsOverview-ZfFBzePp.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-DmMdIRHQ.js.map → WorkflowsOverview-ZfFBzePp.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-Bj7QkCry.js → YamlWorkflowDetailPage-4bd5yXdA.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-Bj7QkCry.js.map → YamlWorkflowDetailPage-4bd5yXdA.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BIi77mE0.js → YamlWorkflowsPage-iHPNXjQj.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BIi77mE0.js.map → YamlWorkflowsPage-iHPNXjQj.js.map} +1 -1
- package/dashboard/dist/assets/{agents-EBIsjLCr.js → agents-DjD5U3Wb.js} +2 -2
- package/dashboard/dist/assets/{agents-EBIsjLCr.js.map → agents-DjD5U3Wb.js.map} +1 -1
- package/dashboard/dist/assets/{bots-BXzxybS6.js → bots-DiljVapH.js} +2 -2
- package/dashboard/dist/assets/{bots-BXzxybS6.js.map → bots-DiljVapH.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-CnprG6q_.js → capabilities-DV_5ghHT.js} +2 -2
- package/dashboard/dist/assets/{capabilities-CnprG6q_.js.map → capabilities-DV_5ghHT.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-DiC0xtNq.js → controlplane-BKMvfWCB.js} +2 -2
- package/dashboard/dist/assets/{controlplane-DiC0xtNq.js.map → controlplane-BKMvfWCB.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-BQpCaJId.js +2 -0
- package/dashboard/dist/assets/escalation-columns-BQpCaJId.js.map +1 -0
- package/dashboard/dist/assets/{index-BzRXMicE.js → index-B-WkiNRN.js} +2 -2
- package/dashboard/dist/assets/{index-BzRXMicE.js.map → index-B-WkiNRN.js.map} +1 -1
- package/dashboard/dist/assets/index-BO-7S9Xw.js +2 -0
- package/dashboard/dist/assets/index-BO-7S9Xw.js.map +1 -0
- package/dashboard/dist/assets/{index-C7KY8GTF.js → index-BaV3l0UE.js} +2 -2
- package/dashboard/dist/assets/{index-C7KY8GTF.js.map → index-BaV3l0UE.js.map} +1 -1
- package/dashboard/dist/assets/{index-B6ldRx_s.js → index-BsOxMMmb.js} +2 -2
- package/dashboard/dist/assets/{index-B6ldRx_s.js.map → index-BsOxMMmb.js.map} +1 -1
- package/dashboard/dist/assets/index-CI8rrKjx.js +2 -0
- package/dashboard/dist/assets/{index-CjBdB8Ht.js.map → index-CI8rrKjx.js.map} +1 -1
- package/dashboard/dist/assets/index-CItsikDw.js +2 -0
- package/dashboard/dist/assets/index-CItsikDw.js.map +1 -0
- package/dashboard/dist/assets/{index-CcMIca5t.js → index-CStR4uIU.js} +2 -2
- package/dashboard/dist/assets/{index-CcMIca5t.js.map → index-CStR4uIU.js.map} +1 -1
- package/dashboard/dist/assets/{index-CSTwyrwu.js → index-DbTD-dio.js} +26 -26
- package/dashboard/dist/assets/index-DbTD-dio.js.map +1 -0
- package/dashboard/dist/assets/{index-gBnGEubX.js → index-DhATO1cS.js} +2 -2
- package/dashboard/dist/assets/{index-gBnGEubX.js.map → index-DhATO1cS.js.map} +1 -1
- package/dashboard/dist/assets/index-DnlsDaAw.css +1 -0
- package/dashboard/dist/assets/{index-ovFEZ9SV.js → index-Tx_ETzcH.js} +2 -2
- package/dashboard/dist/assets/{index-ovFEZ9SV.js.map → index-Tx_ETzcH.js.map} +1 -1
- package/dashboard/dist/assets/{index-DVmC_UfQ.js → index-kzIIeVbx.js} +4 -4
- package/dashboard/dist/assets/{index-DVmC_UfQ.js.map → index-kzIIeVbx.js.map} +1 -1
- package/dashboard/dist/assets/{index-BHAjQoOy.js → index-nIrYejxe.js} +3 -3
- package/dashboard/dist/assets/{index-BHAjQoOy.js.map → index-nIrYejxe.js.map} +1 -1
- package/dashboard/dist/assets/{index-Dht0ihGT.js → index-xZqQxqu2.js} +2 -2
- package/dashboard/dist/assets/{index-Dht0ihGT.js.map → index-xZqQxqu2.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-W5QSKkYQ.js → knowledge-BocTnSiA.js} +2 -2
- package/dashboard/dist/assets/{knowledge-W5QSKkYQ.js.map → knowledge-BocTnSiA.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-n877HyOj.js → mcp-C1KBjKQ_.js} +2 -2
- package/dashboard/dist/assets/{mcp-n877HyOj.js.map → mcp-C1KBjKQ_.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-C9kV4sUm.js → mcp-query-B3cjukkA.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-C9kV4sUm.js.map → mcp-query-B3cjukkA.js.map} +1 -1
- package/dashboard/dist/assets/personas-DiA2bJaX.js +2 -0
- package/dashboard/dist/assets/personas-DiA2bJaX.js.map +1 -0
- package/dashboard/dist/assets/{pipelines-CBR68T8R.js → pipelines-Dt2d2EFR.js} +2 -2
- package/dashboard/dist/assets/{pipelines-CBR68T8R.js.map → pipelines-Dt2d2EFR.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-DHpWqKMk.js → tasks-cDh2hNml.js} +2 -2
- package/dashboard/dist/assets/{tasks-DHpWqKMk.js.map → tasks-cDh2hNml.js.map} +1 -1
- package/dashboard/dist/assets/{topics-CaLtyqSh.js → topics-yFlGF-u1.js} +2 -2
- package/dashboard/dist/assets/{topics-CaLtyqSh.js.map → topics-yFlGF-u1.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-B8p56JlB.js → useEventHooks-D2R_ckS8.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-B8p56JlB.js.map → useEventHooks-D2R_ckS8.js.map} +1 -1
- package/dashboard/dist/assets/{useFilterParams-CvRyYHJN.js → useFilterParams-B7suPsIK.js} +2 -2
- package/dashboard/dist/assets/{useFilterParams-CvRyYHJN.js.map → useFilterParams-B7suPsIK.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-ej71FCvu.js → useNamespace-u-V1GVUD.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-ej71FCvu.js.map → useNamespace-u-V1GVUD.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-DgpiFXib.js → useYamlActivityEvents-BhOZeqgE.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-DgpiFXib.js.map → useYamlActivityEvents-BhOZeqgE.js.map} +1 -1
- package/dashboard/dist/assets/{users-CHnjI_Ca.js → users-BoXPwdee.js} +2 -2
- package/dashboard/dist/assets/{users-CHnjI_Ca.js.map → users-BoXPwdee.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-Bg6eJX4Z.js → vendor-icons-D71XjkNy.js} +133 -128
- package/dashboard/dist/assets/vendor-icons-D71XjkNy.js.map +1 -0
- package/dashboard/dist/assets/{vendor-react-BpdAFEQc.js → vendor-react-C1YOyCSV.js} +2 -2
- package/dashboard/dist/assets/{vendor-react-BpdAFEQc.js.map → vendor-react-C1YOyCSV.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-DtnXUL0U.js → workflows-mCoyKuLZ.js} +2 -2
- package/dashboard/dist/assets/{workflows-DtnXUL0U.js.map → workflows-mCoyKuLZ.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-DDclYAID.js → yaml-workflows-CWxXGDpn.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-DDclYAID.js.map → yaml-workflows-CWxXGDpn.js.map} +1 -1
- package/dashboard/dist/index.html +4 -4
- package/docs/api/http/personas.md +160 -0
- package/docs/cli.md +12 -0
- package/docs/dashboard.md +25 -3
- package/docs/design-principles.md +13 -5
- package/docs/hitl/pinned-views.md +3 -3
- package/docs/hitl/x-lt-list-schema.md +2 -3
- package/docs/iam.md +47 -0
- package/docs/operations.md +1 -1
- package/docs/sdk.md +1 -0
- package/package.json +1 -1
- package/dashboard/dist/assets/AgentDetailPage-D-Xbyrb6.js +0 -4
- package/dashboard/dist/assets/AgentDetailPage-D-Xbyrb6.js.map +0 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-B-aHvGKD.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-B-aHvGKD.js.map +0 -1
- package/dashboard/dist/assets/CountdownTimer-BhF3oqS8.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-BhF3oqS8.js.map +0 -1
- package/dashboard/dist/assets/ElapsedCell-BE_CN5sP.js +0 -2
- package/dashboard/dist/assets/HomePage-B6s1ZeyA.js +0 -2
- package/dashboard/dist/assets/HomePage-B6s1ZeyA.js.map +0 -1
- package/dashboard/dist/assets/ListToolbar-DVhlAKZ3.js +0 -2
- package/dashboard/dist/assets/ListToolbar-DVhlAKZ3.js.map +0 -1
- package/dashboard/dist/assets/McpQueryDetailPage-D0r2lyZg.js +0 -5
- package/dashboard/dist/assets/McpQueryDetailPage-D0r2lyZg.js.map +0 -1
- package/dashboard/dist/assets/McpQueryPage-DPP6BB3d.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-DPP6BB3d.js.map +0 -1
- package/dashboard/dist/assets/OperationsPage-DbHzQCuE.js +0 -2
- package/dashboard/dist/assets/OperationsPage-DbHzQCuE.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-B70nS_Ah.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-B70nS_Ah.js.map +0 -1
- package/dashboard/dist/assets/ProcessDetailPage-eLLUCWFf.js +0 -2
- package/dashboard/dist/assets/ProcessDetailPage-eLLUCWFf.js.map +0 -1
- package/dashboard/dist/assets/RoleDetailPage-Dhn9zU5l.js +0 -8
- package/dashboard/dist/assets/RoleDetailPage-Dhn9zU5l.js.map +0 -1
- package/dashboard/dist/assets/RolesPage-BnAwjUiG.js +0 -2
- package/dashboard/dist/assets/RolesPage-BnAwjUiG.js.map +0 -1
- package/dashboard/dist/assets/StatCard-DBANWIss.js +0 -2
- package/dashboard/dist/assets/StatCard-DBANWIss.js.map +0 -1
- package/dashboard/dist/assets/StreamMessageDetail-BmBfNSEr.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-D0aYpJkF.js +0 -2
- package/dashboard/dist/assets/escalation-columns-D0aYpJkF.js.map +0 -1
- package/dashboard/dist/assets/index-B2iZG_HP.css +0 -1
- package/dashboard/dist/assets/index-CSTwyrwu.js.map +0 -1
- package/dashboard/dist/assets/index-CjBdB8Ht.js +0 -2
- package/dashboard/dist/assets/index-D-7mT0ew.js +0 -2
- package/dashboard/dist/assets/index-D-7mT0ew.js.map +0 -1
- package/dashboard/dist/assets/index-DDA7FvqT.js +0 -2
- package/dashboard/dist/assets/index-DDA7FvqT.js.map +0 -1
- package/dashboard/dist/assets/role-display-Dvo2lDpU.js +0 -2
- package/dashboard/dist/assets/role-display-Dvo2lDpU.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-Bg6eJX4Z.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as n,b as t,c as u}from"./vendor-query-B2UbickB.js";import{d as s}from"./index-
|
|
2
|
-
//# sourceMappingURL=workflows-
|
|
1
|
+
import{u as n,b as t,c as u}from"./vendor-query-B2UbickB.js";import{d as s}from"./index-DbTD-dio.js";function f(){return n({queryKey:["activeWorkers"],queryFn:async()=>(await s("/workflows/workers")).workers})}function w(){return n({queryKey:["discoveredWorkflows"],queryFn:async()=>(await s("/workflows/discovered")).workflows})}function l(){return n({queryKey:["workflowConfigs"],queryFn:async()=>(await s("/workflows/config")).workflows})}function d(){return n({queryKey:["cronStatus"],queryFn:async()=>(await s("/workflows/cron/status")).schedules})}function k(e){return n({queryKey:["workflowExecution",e],queryFn:()=>s(`/workflow-states/${e}/execution`),enabled:!!e})}function m(e,o){const r=new URLSearchParams;return e.limit&&r.set("limit",String(e.limit)),e.offset!==void 0&&r.set("offset",String(e.offset)),e.entity&&r.set("entity",e.entity),e.search&&r.set("search",e.search),e.status&&r.set("status",e.status),e.sort_by&&r.set("sort_by",e.sort_by),e.order&&r.set("order",e.order),e.registered&&r.set("registered",e.registered),e.namespace&&r.set("namespace",e.namespace),n({queryKey:["jobs",e],queryFn:()=>s(`/workflow-states/jobs?${r}`),enabled:(o==null?void 0:o.enabled)??!0})}function q(){const e=t();return u({mutationFn:o=>s(`/workflows/${o}/terminate`,{method:"POST"}),onSuccess:(o,r)=>{e.invalidateQueries({queryKey:["workflowExecution",r],refetchType:"all"}),e.invalidateQueries({queryKey:["jobs"],refetchType:"all"})}})}function g(){const e=t();return u({mutationFn:({workflow_type:o,...r})=>s(`/workflows/${encodeURIComponent(o)}/config`,{method:"PUT",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:["workflowConfigs"],refetchType:"all"})}})}function h(){const e=t();return u({mutationFn:o=>s(`/workflows/${encodeURIComponent(o)}/config`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:["workflowConfigs"],refetchType:"all"})}})}function b(){const e=t();return u({mutationFn:({workflowType:o,data:r,metadata:i,execute_as:a})=>s(`/workflows/${o}/invoke`,{method:"POST",body:JSON.stringify({data:r,metadata:i,...a?{execute_as:a}:{}})}),onSuccess:()=>{e.invalidateQueries({queryKey:["tasks"],refetchType:"all"}),e.invalidateQueries({queryKey:["jobs"],refetchType:"all"})}})}export{k as a,m as b,b as c,w as d,d as e,q as f,f as g,h,g as i,l as u};
|
|
2
|
+
//# sourceMappingURL=workflows-mCoyKuLZ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflows-
|
|
1
|
+
{"version":3,"file":"workflows-mCoyKuLZ.js","sources":["../../src/api/workflows.ts"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { ActiveWorker, CronScheduleEntry, DiscoveredWorkflow, LTJob, LTWorkflowConfig, WorkflowExecution } from './types';\n\nexport function useActiveWorkers() {\n return useQuery<ActiveWorker[]>({\n queryKey: ['activeWorkers'],\n queryFn: async () => {\n const res = await apiFetch<{ workers: ActiveWorker[] }>('/workflows/workers');\n return res.workers;\n },\n });\n}\n\nexport function useDiscoveredWorkflows() {\n return useQuery<DiscoveredWorkflow[]>({\n queryKey: ['discoveredWorkflows'],\n queryFn: async () => {\n const res = await apiFetch<{ workflows: DiscoveredWorkflow[] }>('/workflows/discovered');\n return res.workflows;\n },\n });\n}\n\nexport function useWorkflowConfigs() {\n return useQuery<LTWorkflowConfig[]>({\n queryKey: ['workflowConfigs'],\n queryFn: async () => {\n const res = await apiFetch<{ workflows: LTWorkflowConfig[] }>('/workflows/config');\n return res.workflows;\n },\n });\n}\n\nexport function useCronStatus() {\n return useQuery<CronScheduleEntry[]>({\n queryKey: ['cronStatus'],\n queryFn: async () => {\n const res = await apiFetch<{ schedules: CronScheduleEntry[] }>('/workflows/cron/status');\n return res.schedules;\n },\n });\n}\n\nexport function useWorkflowExecution(workflowId: string) {\n return useQuery<WorkflowExecution>({\n queryKey: ['workflowExecution', workflowId],\n queryFn: () =>\n apiFetch(`/workflow-states/${workflowId}/execution`),\n enabled: !!workflowId,\n });\n}\n\nexport function useWorkflowState(workflowId: string) {\n return useQuery<{ workflow_id: string; state: Record<string, unknown> }>({\n queryKey: ['workflowState', workflowId],\n queryFn: () => apiFetch(`/workflow-states/${workflowId}/state`),\n enabled: !!workflowId,\n });\n}\n\nexport function useJobs(filters: {\n limit?: number;\n offset?: number;\n entity?: string;\n search?: string;\n status?: string;\n sort_by?: string;\n order?: string;\n registered?: string;\n namespace?: string;\n}, options?: { enabled?: boolean }) {\n const params = new URLSearchParams();\n if (filters.limit) params.set('limit', String(filters.limit));\n if (filters.offset !== undefined) params.set('offset', String(filters.offset));\n if (filters.entity) params.set('entity', filters.entity);\n if (filters.search) params.set('search', filters.search);\n if (filters.status) params.set('status', filters.status);\n if (filters.sort_by) params.set('sort_by', filters.sort_by);\n if (filters.order) params.set('order', filters.order);\n if (filters.registered) params.set('registered', filters.registered);\n if (filters.namespace) params.set('namespace', filters.namespace);\n\n return useQuery<{ jobs: LTJob[]; total: number }>({\n queryKey: ['jobs', filters],\n queryFn: () => apiFetch(`/workflow-states/jobs?${params}`),\n enabled: options?.enabled ?? true,\n });\n}\n\nexport function useTerminateWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (workflowId: string) =>\n apiFetch(`/workflows/${workflowId}/terminate`, { method: 'POST' }),\n onSuccess: (_data, workflowId) => {\n queryClient.invalidateQueries({ queryKey: ['workflowExecution', workflowId], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['jobs'], refetchType: 'all' });\n },\n });\n}\n\nexport function useUpsertWorkflowConfig() {\n const queryClient = useQueryClient();\n return useMutation<\n LTWorkflowConfig,\n Error,\n {\n workflow_type: string;\n description?: string | null;\n\n invocable?: boolean;\n certified?: boolean;\n task_queue?: string | null;\n default_role?: string;\n roles?: string[];\n invocation_roles?: string[];\n consumes?: string[];\n envelope_schema?: Record<string, unknown> | null;\n resolver_schema?: Record<string, unknown> | null;\n cron_schedule?: string | null;\n execute_as?: string | null;\n }\n >({\n mutationFn: ({ workflow_type, ...body }) =>\n apiFetch(`/workflows/${encodeURIComponent(workflow_type)}/config`, {\n method: 'PUT',\n body: JSON.stringify(body),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['workflowConfigs'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeleteWorkflowConfig() {\n const queryClient = useQueryClient();\n return useMutation<{ deleted: boolean; workflow_type: string }, Error, string>({\n mutationFn: (workflowType) =>\n apiFetch(`/workflows/${encodeURIComponent(workflowType)}/config`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['workflowConfigs'], refetchType: 'all' });\n },\n });\n}\n\nexport function useSetCronSchedule() {\n const queryClient = useQueryClient();\n return useMutation<\n LTWorkflowConfig,\n Error,\n { config: LTWorkflowConfig; cron_schedule: string | null; envelope_schema?: Record<string, unknown> | null }\n >({\n mutationFn: ({ config, cron_schedule, envelope_schema }) =>\n apiFetch(`/workflows/${encodeURIComponent(config.workflow_type)}/config`, {\n method: 'PUT',\n body: JSON.stringify({\n ...config,\n cron_schedule,\n ...(envelope_schema !== undefined ? { envelope_schema } : {}),\n }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['workflowConfigs'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['cronStatus'], refetchType: 'all' });\n },\n });\n}\n\nexport function useInvokeWorkflow() {\n const queryClient = useQueryClient();\n return useMutation<\n { workflowId: string; message: string },\n Error,\n { workflowType: string; data: Record<string, unknown>; metadata?: Record<string, unknown>; execute_as?: string }\n >({\n mutationFn: ({ workflowType, data, metadata, execute_as }) =>\n apiFetch(`/workflows/${workflowType}/invoke`, {\n method: 'POST',\n body: JSON.stringify({ data, metadata, ...(execute_as ? { execute_as } : {}) }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['tasks'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['jobs'], refetchType: 'all' });\n },\n });\n}\n"],"names":["useActiveWorkers","useQuery","apiFetch","useDiscoveredWorkflows","useWorkflowConfigs","useCronStatus","useWorkflowExecution","workflowId","useJobs","filters","options","params","useTerminateWorkflow","queryClient","useQueryClient","useMutation","_data","useUpsertWorkflowConfig","workflow_type","body","useDeleteWorkflowConfig","workflowType","useInvokeWorkflow","data","metadata","execute_as"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as l,b as a,c as s}from"./vendor-query-B2UbickB.js";import{d as r}from"./index-
|
|
2
|
-
//# sourceMappingURL=yaml-workflows-
|
|
1
|
+
import{u as l,b as a,c as s}from"./vendor-query-B2UbickB.js";import{d as r}from"./index-DbTD-dio.js";function f(e={}){const o=new URLSearchParams;return e.status&&o.set("status",e.status),e.graph_topic&&o.set("graph_topic",e.graph_topic),e.app_id&&o.set("app_id",e.app_id),e.search&&o.set("search",e.search),e.set_id&&o.set("set_id",e.set_id),e.limit&&o.set("limit",String(e.limit)),e.offset!==void 0&&o.set("offset",String(e.offset)),l({queryKey:["yamlWorkflows",e],queryFn:()=>r(`/yaml-workflows?${o}`)})}function m(){return l({queryKey:["yamlWorkflowAppIds"],queryFn:()=>r("/yaml-workflows/app-ids")})}function c(e){return l({queryKey:["yamlWorkflows",e],queryFn:()=>r(`/yaml-workflows/${e}`),enabled:!!e})}function w(){const e=a();return s({mutationFn:o=>r("/yaml-workflows",{method:"POST",body:JSON.stringify(o)}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function k(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/deploy`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function p(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/activate`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function d(){const e=a();return s({mutationFn:({id:o,data:t,sync:n,execute_as:u})=>r(`/yaml-workflows/${o}/invoke`,{method:"POST",body:JSON.stringify({data:t,sync:n,...u?{execute_as:u}:{}})}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function h(){const e=a();return s({mutationFn:({id:o,task_queue:t,compilation_feedback:n})=>r(`/yaml-workflows/${o}/regenerate`,{method:"POST",body:JSON.stringify({task_queue:t,compilation_feedback:n})}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function q(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/archive`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function W(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/restore`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"}),e.invalidateQueries({queryKey:["yamlWorkflow"],refetchType:"all"})}})}function S(){const e=a();return s({mutationFn:({id:o,...t})=>r(`/yaml-workflows/${o}`,{method:"PUT",body:JSON.stringify(t)}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function v(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function T(e){return l({queryKey:["yamlWorkflows",e,"versions"],queryFn:()=>r(`/yaml-workflows/${e}/versions`),enabled:!!e})}function F(e,o){return l({queryKey:["yamlWorkflows",e,"versions",o],queryFn:()=>r(`/yaml-workflows/${e}/versions/${o}`),enabled:!!e&&o!==null})}export{m as a,S as b,c,T as d,k as e,p as f,q as g,W as h,v as i,h as j,F as k,d as l,w as m,f as u};
|
|
2
|
+
//# sourceMappingURL=yaml-workflows-CWxXGDpn.js.map
|
package/dashboard/dist/assets/{yaml-workflows-DDclYAID.js.map → yaml-workflows-CWxXGDpn.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml-workflows-DDclYAID.js","sources":["../../src/api/yaml-workflows.ts"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { LTYamlWorkflowRecord, LTYamlWorkflowStatus, LTYamlWorkflowVersion } from './types';\n\ninterface YamlWorkflowListResponse {\n workflows: LTYamlWorkflowRecord[];\n total: number;\n}\n\ninterface YamlWorkflowFilters {\n status?: LTYamlWorkflowStatus;\n graph_topic?: string;\n app_id?: string;\n search?: string;\n set_id?: string;\n limit?: number;\n offset?: number;\n}\n\nexport function useYamlWorkflows(filters: YamlWorkflowFilters = {}) {\n const params = new URLSearchParams();\n if (filters.status) params.set('status', filters.status);\n if (filters.graph_topic) params.set('graph_topic', filters.graph_topic);\n if (filters.app_id) params.set('app_id', filters.app_id);\n if (filters.search) params.set('search', filters.search);\n if (filters.set_id) params.set('set_id', filters.set_id);\n if (filters.limit) params.set('limit', String(filters.limit));\n if (filters.offset !== undefined) params.set('offset', String(filters.offset));\n\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', filters],\n queryFn: () => apiFetch(`/yaml-workflows?${params}`),\n });\n}\n\nexport function useYamlWorkflowAppIds() {\n return useQuery<{ app_ids: string[] }>({\n queryKey: ['yamlWorkflowAppIds'],\n queryFn: () => apiFetch('/yaml-workflows/app-ids'),\n });\n}\n\nexport function useYamlWorkflowByTopic(graphTopic: string | undefined, appId?: string) {\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', 'byTopic', graphTopic, appId],\n queryFn: () => {\n const params = new URLSearchParams({ graph_topic: graphTopic!, limit: '1' });\n if (appId) params.set('app_id', appId);\n return apiFetch(`/yaml-workflows?${params}`);\n },\n enabled: !!graphTopic,\n });\n}\n\nexport function useYamlWorkflow(id: string) {\n return useQuery<LTYamlWorkflowRecord>({\n queryKey: ['yamlWorkflows', id],\n queryFn: () => apiFetch(`/yaml-workflows/${id}`),\n enabled: !!id,\n });\n}\n\nexport function useCreateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (input: {\n workflow_id: string;\n task_queue: string;\n workflow_name: string;\n name: string;\n description?: string;\n app_id?: string;\n subscribes?: string;\n tags?: string[];\n compilation_feedback?: string;\n }) =>\n apiFetch<LTYamlWorkflowRecord>('/yaml-workflows', {\n method: 'POST',\n body: JSON.stringify(input),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeployYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/deploy`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useActivateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/activate`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useInvokeYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data, sync, execute_as }: { id: string; data: Record<string, unknown>; sync?: boolean; execute_as?: string }) =>\n apiFetch<{ result?: unknown; job_id?: string }>(`/yaml-workflows/${id}/invoke`, {\n method: 'POST',\n body: JSON.stringify({ data, sync, ...(execute_as ? { execute_as } : {}) }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRegenerateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, task_queue, compilation_feedback }: { id: string; task_queue?: string; compilation_feedback?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/regenerate`, {\n method: 'POST',\n body: JSON.stringify({ task_queue, compilation_feedback }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useArchiveYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/archive`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRestoreYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/restore`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflow'], refetchType: 'all' });\n },\n });\n}\n\nexport function useUpdateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, ...updates }: { id: string; yaml_content?: string; name?: string; description?: string; input_schema?: Record<string, unknown>; output_schema?: Record<string, unknown>; tags?: string[]; app_id?: string; graph_topic?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}`, {\n method: 'PUT',\n body: JSON.stringify(updates),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeleteYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<{ deleted: boolean }>(`/yaml-workflows/${id}`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Cron scheduling ─────────────────────────────────────────────\n\nexport function useSetYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, cron_schedule, cron_envelope, execute_as }: {\n id: string;\n cron_schedule: string;\n cron_envelope?: Record<string, unknown> | null;\n execute_as?: string | null;\n }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'PUT',\n body: JSON.stringify({ cron_schedule, cron_envelope, execute_as }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useClearYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Version history ─────────────────────────────────────────────\n\nexport function useYamlWorkflowVersions(id: string) {\n return useQuery<{ versions: LTYamlWorkflowVersion[]; total: number }>({\n queryKey: ['yamlWorkflows', id, 'versions'],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions`),\n enabled: !!id,\n });\n}\n\nexport function useYamlWorkflowVersion(id: string, version: number | null) {\n return useQuery<LTYamlWorkflowVersion>({\n queryKey: ['yamlWorkflows', id, 'versions', version],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions/${version}`),\n enabled: !!id && version !== null,\n });\n}\n"],"names":["useYamlWorkflows","filters","params","useQuery","apiFetch","useYamlWorkflowAppIds","useYamlWorkflow","id","useCreateYamlWorkflow","queryClient","useQueryClient","useMutation","input","useDeployYamlWorkflow","useActivateYamlWorkflow","useInvokeYamlWorkflow","data","sync","execute_as","useRegenerateYamlWorkflow","task_queue","compilation_feedback","useArchiveYamlWorkflow","useRestoreYamlWorkflow","useUpdateYamlWorkflow","updates","useDeleteYamlWorkflow","useYamlWorkflowVersions","useYamlWorkflowVersion","version"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"yaml-workflows-CWxXGDpn.js","sources":["../../src/api/yaml-workflows.ts"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { LTYamlWorkflowRecord, LTYamlWorkflowStatus, LTYamlWorkflowVersion } from './types';\n\ninterface YamlWorkflowListResponse {\n workflows: LTYamlWorkflowRecord[];\n total: number;\n}\n\ninterface YamlWorkflowFilters {\n status?: LTYamlWorkflowStatus;\n graph_topic?: string;\n app_id?: string;\n search?: string;\n set_id?: string;\n limit?: number;\n offset?: number;\n}\n\nexport function useYamlWorkflows(filters: YamlWorkflowFilters = {}) {\n const params = new URLSearchParams();\n if (filters.status) params.set('status', filters.status);\n if (filters.graph_topic) params.set('graph_topic', filters.graph_topic);\n if (filters.app_id) params.set('app_id', filters.app_id);\n if (filters.search) params.set('search', filters.search);\n if (filters.set_id) params.set('set_id', filters.set_id);\n if (filters.limit) params.set('limit', String(filters.limit));\n if (filters.offset !== undefined) params.set('offset', String(filters.offset));\n\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', filters],\n queryFn: () => apiFetch(`/yaml-workflows?${params}`),\n });\n}\n\nexport function useYamlWorkflowAppIds() {\n return useQuery<{ app_ids: string[] }>({\n queryKey: ['yamlWorkflowAppIds'],\n queryFn: () => apiFetch('/yaml-workflows/app-ids'),\n });\n}\n\nexport function useYamlWorkflowByTopic(graphTopic: string | undefined, appId?: string) {\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', 'byTopic', graphTopic, appId],\n queryFn: () => {\n const params = new URLSearchParams({ graph_topic: graphTopic!, limit: '1' });\n if (appId) params.set('app_id', appId);\n return apiFetch(`/yaml-workflows?${params}`);\n },\n enabled: !!graphTopic,\n });\n}\n\nexport function useYamlWorkflow(id: string) {\n return useQuery<LTYamlWorkflowRecord>({\n queryKey: ['yamlWorkflows', id],\n queryFn: () => apiFetch(`/yaml-workflows/${id}`),\n enabled: !!id,\n });\n}\n\nexport function useCreateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (input: {\n workflow_id: string;\n task_queue: string;\n workflow_name: string;\n name: string;\n description?: string;\n app_id?: string;\n subscribes?: string;\n tags?: string[];\n compilation_feedback?: string;\n }) =>\n apiFetch<LTYamlWorkflowRecord>('/yaml-workflows', {\n method: 'POST',\n body: JSON.stringify(input),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeployYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/deploy`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useActivateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/activate`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useInvokeYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data, sync, execute_as }: { id: string; data: Record<string, unknown>; sync?: boolean; execute_as?: string }) =>\n apiFetch<{ result?: unknown; job_id?: string }>(`/yaml-workflows/${id}/invoke`, {\n method: 'POST',\n body: JSON.stringify({ data, sync, ...(execute_as ? { execute_as } : {}) }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRegenerateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, task_queue, compilation_feedback }: { id: string; task_queue?: string; compilation_feedback?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/regenerate`, {\n method: 'POST',\n body: JSON.stringify({ task_queue, compilation_feedback }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useArchiveYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/archive`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRestoreYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/restore`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflow'], refetchType: 'all' });\n },\n });\n}\n\nexport function useUpdateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, ...updates }: { id: string; yaml_content?: string; name?: string; description?: string; input_schema?: Record<string, unknown>; output_schema?: Record<string, unknown>; tags?: string[]; app_id?: string; graph_topic?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}`, {\n method: 'PUT',\n body: JSON.stringify(updates),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeleteYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<{ deleted: boolean }>(`/yaml-workflows/${id}`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Cron scheduling ─────────────────────────────────────────────\n\nexport function useSetYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, cron_schedule, cron_envelope, execute_as }: {\n id: string;\n cron_schedule: string;\n cron_envelope?: Record<string, unknown> | null;\n execute_as?: string | null;\n }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'PUT',\n body: JSON.stringify({ cron_schedule, cron_envelope, execute_as }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useClearYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Version history ─────────────────────────────────────────────\n\nexport function useYamlWorkflowVersions(id: string) {\n return useQuery<{ versions: LTYamlWorkflowVersion[]; total: number }>({\n queryKey: ['yamlWorkflows', id, 'versions'],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions`),\n enabled: !!id,\n });\n}\n\nexport function useYamlWorkflowVersion(id: string, version: number | null) {\n return useQuery<LTYamlWorkflowVersion>({\n queryKey: ['yamlWorkflows', id, 'versions', version],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions/${version}`),\n enabled: !!id && version !== null,\n });\n}\n"],"names":["useYamlWorkflows","filters","params","useQuery","apiFetch","useYamlWorkflowAppIds","useYamlWorkflow","id","useCreateYamlWorkflow","queryClient","useQueryClient","useMutation","input","useDeployYamlWorkflow","useActivateYamlWorkflow","useInvokeYamlWorkflow","data","sync","execute_as","useRegenerateYamlWorkflow","task_queue","compilation_feedback","useArchiveYamlWorkflow","useRestoreYamlWorkflow","useUpdateYamlWorkflow","updates","useDeleteYamlWorkflow","useYamlWorkflowVersions","useYamlWorkflowVersion","version"],"mappings":"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"}
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
9
9
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
10
10
|
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
11
|
-
<script type="module" crossorigin src="./assets/index-
|
|
11
|
+
<script type="module" crossorigin src="./assets/index-DbTD-dio.js"></script>
|
|
12
12
|
<link rel="modulepreload" crossorigin href="./assets/vendor-query-B2UbickB.js">
|
|
13
|
-
<link rel="modulepreload" crossorigin href="./assets/vendor-react-
|
|
14
|
-
<link rel="modulepreload" crossorigin href="./assets/vendor-icons-
|
|
15
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
13
|
+
<link rel="modulepreload" crossorigin href="./assets/vendor-react-C1YOyCSV.js">
|
|
14
|
+
<link rel="modulepreload" crossorigin href="./assets/vendor-icons-D71XjkNy.js">
|
|
15
|
+
<link rel="stylesheet" crossorigin href="./assets/index-DnlsDaAw.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
|
18
18
|
<div id="root"></div>
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Personas API
|
|
2
|
+
|
|
3
|
+
A persona is a named bundle of roles with a per-role **relationship** scope — shorthand for adding a user to each linked role at the linked scope. Assignment fans out to ordinary role memberships (`lt_user_roles` stays the single source of authorization truth); the persona records why the memberships exist. Full semantics — provenance, highest-allowance union, overlay-on-reassign — are in [iam.md](../../iam.md#personas).
|
|
4
|
+
|
|
5
|
+
All endpoints require authentication plus role-management access (`admin` type, `superadmin`, or the `engineer` role) — the same audience that manages users and roles.
|
|
6
|
+
|
|
7
|
+
Relationship values map onto the member scope lattice:
|
|
8
|
+
|
|
9
|
+
| relationship | read_scope | write_scope |
|
|
10
|
+
|--------------|-----------|-------------|
|
|
11
|
+
| `write-all` | `all` | `all` |
|
|
12
|
+
| `write-self` | `all` | `self` |
|
|
13
|
+
| `read-all` | `all` | `none` |
|
|
14
|
+
|
|
15
|
+
`write-none` is accepted anywhere as a synonym for `read-all`.
|
|
16
|
+
|
|
17
|
+
## List personas
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
GET /api/personas
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Response 200:**
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"personas": [
|
|
28
|
+
{
|
|
29
|
+
"id": "a1b2c3d4-...",
|
|
30
|
+
"key": "production-manager",
|
|
31
|
+
"title": "Production Manager",
|
|
32
|
+
"description": "Runs the pipeline: works design and review, watches print and the fleet.",
|
|
33
|
+
"roles": [
|
|
34
|
+
{ "role": "design", "relationship": "write-all" },
|
|
35
|
+
{ "role": "review", "relationship": "write-all" },
|
|
36
|
+
{ "role": "print", "relationship": "read-all" }
|
|
37
|
+
],
|
|
38
|
+
"user_count": 2,
|
|
39
|
+
"created_at": "2026-07-01T08:00:00.000Z",
|
|
40
|
+
"updated_at": "2026-07-01T08:00:00.000Z"
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Get a persona
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
GET /api/personas/:key
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Response 200:** the persona record plus `assignees` — `[{ id, external_id, display_name, email, assigned_at }]`. **404** when the key is unknown.
|
|
53
|
+
|
|
54
|
+
## Create a persona
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
POST /api/personas
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Body:**
|
|
61
|
+
|
|
62
|
+
| Field | Type | Description |
|
|
63
|
+
|-------|------|-------------|
|
|
64
|
+
| `key` | `string` | Required. Stable identifier, role-name alphabet (`^[a-z][a-z0-9_-]*$`) |
|
|
65
|
+
| `title` | `string` | Display title |
|
|
66
|
+
| `description` | `string` | The day-in-the-life, one paragraph |
|
|
67
|
+
|
|
68
|
+
**Response 201** with the created record. **409** when the key already exists.
|
|
69
|
+
|
|
70
|
+
## Update a persona
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
PATCH /api/personas/:key
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
PATCH semantics on `title` and `description` — omitted fields keep their values; `null` clears.
|
|
77
|
+
|
|
78
|
+
## Delete a persona
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
DELETE /api/personas/:key
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Memberships the persona sustains are removed — or re-homed to a sibling persona the user still holds — before the persona row is deleted. Direct grants are never touched.
|
|
85
|
+
|
|
86
|
+
**Response 200:** `{ "deleted": true, "recompute": { "granted": 0, "refreshed": 0, "raised": 0, "removed": 3 } }`
|
|
87
|
+
|
|
88
|
+
## Link a role
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
PUT /api/personas/:key/roles/:role
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Body:** `{ "relationship": "write-all" }` — also updates an existing link's relationship. The role is created if absent, and every current holder's memberships are reconciled in the same transaction.
|
|
95
|
+
|
|
96
|
+
**Response 201:** `{ "role": "design", "relationship": "write-all", "recompute": { ... } }`
|
|
97
|
+
|
|
98
|
+
## Unlink a role
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
DELETE /api/personas/:key/roles/:role
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Removes the link and reconciles every holder. **Response 200:** `{ "unlinked": true, "recompute": { ... } }`
|
|
105
|
+
|
|
106
|
+
## Seed personas (declarative)
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
POST /api/personas/seed
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Body:** `{ "personas": [{ "key", "title?", "description?", "roles": [{ "role", "relationship" }] }] }`
|
|
113
|
+
|
|
114
|
+
Idempotent and authoritative per spec: title/description are overlaid, role links are synced (links absent from the spec are pruned), linked roles are ensured as FK targets, and every current holder is reconciled. The SDK twin is `lt.personas.seed(specs)` — declare personas in the same seed pass that declares roles and `default_pins`.
|
|
115
|
+
|
|
116
|
+
**Response 200:** `{ "personas": 2, "links": 6, "recompute": { ... } }`
|
|
117
|
+
|
|
118
|
+
## Personas for a user
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
GET /api/users/:id/personas
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Response 200:**
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"personas": [
|
|
129
|
+
{ "id": "a1b2c3d4-...", "key": "production-manager", "title": "Production Manager", "description": "...", "roles": [ ... ], "assigned_at": "2026-07-10T12:00:00.000Z" }
|
|
130
|
+
],
|
|
131
|
+
"roles": [
|
|
132
|
+
{ "role": "design", "read_scope": "all", "write_scope": "all", "granted_by_persona": "production-manager" },
|
|
133
|
+
{ "role": "review", "read_scope": "all", "write_scope": "all", "granted_by_persona": null }
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`roles` is the composed role/scope map: every membership with the persona sustaining it (`null` = direct grant).
|
|
139
|
+
|
|
140
|
+
## Assign a persona
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
POST /api/users/:id/personas
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Body:** `{ "persona": "production-manager" }`
|
|
147
|
+
|
|
148
|
+
Idempotent — re-assigning overlays fresh from the persona's current role links. Highest allowance wins across held personas; a direct grant's scope is only ever raised toward the union, never lowered.
|
|
149
|
+
|
|
150
|
+
**Response 200:** `{ "assigned": true, "recompute": { "granted": 3, "refreshed": 0, "raised": 1, "removed": 0 } }` — `granted` = memberships inserted, `refreshed` = persona-sustained rows overlaid, `raised` = direct rows lifted to the union, `removed` = sustained rows no held persona still grants.
|
|
151
|
+
|
|
152
|
+
## Unassign a persona
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
DELETE /api/users/:id/personas/:key
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Removes only memberships the persona sustains; rows another held persona still grants are re-homed to it. Direct grants — including a membership added directly on top of a persona grant — are never touched.
|
|
159
|
+
|
|
160
|
+
**Response 200:** `{ "unassigned": true, "recompute": { ... } }`. **404** when the user does not hold the persona.
|
package/docs/cli.md
CHANGED
|
@@ -140,6 +140,18 @@ ltc roles save-schema reviewer --file schema.json --summary "Added lotNumber"
|
|
|
140
140
|
# Save the escalation form schema (a change creates the next version)
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
+
### Personas
|
|
144
|
+
|
|
145
|
+
Personas bundle roles into one-step assignments — each link carries a relationship scope (`write-all`, `write-self`, `read-all`). See [iam.md](iam.md#personas) for the semantics.
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
ltc personas list # Personas with role and holder counts
|
|
149
|
+
ltc personas get production-manager # Role links + assignees
|
|
150
|
+
ltc personas assign production-manager USER_ID
|
|
151
|
+
ltc personas unassign production-manager USER_ID
|
|
152
|
+
ltc personas for-user USER_ID # Personas held + composed role/scope map
|
|
153
|
+
```
|
|
154
|
+
|
|
143
155
|
### Compiler
|
|
144
156
|
|
|
145
157
|
```bash
|
package/docs/dashboard.md
CHANGED
|
@@ -12,7 +12,7 @@ The reactive, event-driven surface — where operations watch the floor and buil
|
|
|
12
12
|
|
|
13
13
|
| Page | Route | Purpose |
|
|
14
14
|
|------|-------|---------|
|
|
15
|
-
| **Pace Board** | `/operations` | COO shop-floor view — pace chart of actual-vs-target flow across every station role, station table with live metrics, and the station detail panel.
|
|
15
|
+
| **Pace Board** | `/operations` | COO shop-floor view — pace chart of actual-vs-target flow across every station role, station table with live metrics, and the station detail panel. Readable by every login (aggregate counts and trends) while `features.publicPaceBoard`, default on, stands. |
|
|
16
16
|
| **Event Topics** | `/topics` | Topic catalog — browse all known event topics with descriptions, schemas, and subscriber counts. |
|
|
17
17
|
| **Agents** | `/agents` | Autonomous event-driven automations (labeled **Automations** when AI is not configured). Configure subscriptions, schedules, and knowledge domains. |
|
|
18
18
|
| **Capabilities** | `/capabilities` | Browse MCP tools grouped by capability category, with a live run panel. |
|
|
@@ -57,6 +57,7 @@ The LLM authoring add-on. Appears when an Anthropic key is configured.
|
|
|
57
57
|
|------|-------|---------|
|
|
58
58
|
| **Accounts** | `/admin/users` | User accounts and service accounts (bots). Create, edit, assign roles, manage API keys. |
|
|
59
59
|
| **Roles** | `/admin/roles` | Define roles — the queues, forms, and membership that connect workflows to people. Escalation chains, capacity settings, and versioned schemas live here. |
|
|
60
|
+
| **Personas** | `/admin/personas` | Bundle roles into named, one-step assignments. Each linked role carries a relationship scope (write-all, write-self, read-all); assigning a persona composes the member's whole surface from its roles' pins and schemas. |
|
|
60
61
|
|
|
61
62
|
### Infrastructure
|
|
62
63
|
|
|
@@ -81,7 +82,7 @@ The top navigation bar contains:
|
|
|
81
82
|
|
|
82
83
|
## Home — Recent Activity
|
|
83
84
|
|
|
84
|
-
The home page
|
|
85
|
+
The home page leads with the **Pace Board** for every login — the operational heartbeat on top, **All Escalations** and **My Escalations** panels below (each server-scoped to what the viewer may see). A role flagged **Home Segment** (Role Detail → Pace Board settings) picks which sequence the home board opens on; unset, the first sequence leads. When a deployment sets `features.publicPaceBoard: false`, homes re-tier: admins keep this layout, engineers see escalation panels beside their recent **Procedural** and **Graph** executions, and operators get their per-lane task-queue cards.
|
|
85
86
|
|
|
86
87
|
## Key Pages
|
|
87
88
|
|
|
@@ -210,8 +211,9 @@ User Accounts and Service Accounts live on the same page, separated by a tab tog
|
|
|
210
211
|
- **User Accounts** — human operators. Create users, assign display names, and grant roles. Roles determine which escalations a user can see and claim, and which workflows they can invoke from the dashboard. A `member` grant carries a work-surface scope (read/write breadth) chosen from the Scope picker; the five named profiles are documented under [Role Detail](#role-detail).
|
|
211
212
|
- **Service Accounts** — programmatic callers (bots, CI pipelines, external systems). Each service account has an API key for authentication. Assign roles to control access just like human users. Service accounts with the `reviewer` role can claim and resolve escalations programmatically.
|
|
212
213
|
- **Role assignment** — both account types participate in the same role system. Click any account to edit roles, change display name, or manage credentials.
|
|
214
|
+
- **Personas** — the role panel also assigns [personas](#personas): pick one to add the account to every linked role at the linked scope in one step. Memberships a persona sustains show a mask icon; direct grants show none and survive persona unassignment.
|
|
213
215
|
|
|
214
|
-
**API:** `GET /api/users` lists accounts. `POST /api/users` creates. `PUT /api/users/:id/roles` assigns roles.
|
|
216
|
+
**API:** `GET /api/users` lists accounts. `POST /api/users` creates. `PUT /api/users/:id/roles` assigns roles. `GET/POST /api/users/:id/personas` reads and assigns personas.
|
|
215
217
|
|
|
216
218
|
### Roles
|
|
217
219
|
|
|
@@ -276,6 +278,19 @@ Accessible at `/admin/roles/:role/list-schema`. The versioned rich view for the
|
|
|
276
278
|
|
|
277
279
|
**API:** `GET /api/roles/:role/list-schema` (latest or `?version=`), `GET /api/roles/:role/list-schema/versions`, and `PATCH /api/roles/:role` with `list_schema` (+ optional `change_summary`).
|
|
278
280
|
|
|
281
|
+
### Personas
|
|
282
|
+
|
|
283
|
+
Accessible at `/admin/personas` for admins, superadmins, and engineers — the same audience that manages [Accounts](#accounts) and [Roles](#roles). A persona is a named bundle of roles with a per-role relationship scope: assigning it adds a user to every linked role at the linked scope in one step, and each role's own pins and schemas compose the member's sidebar and forms — the composition ("this human runs the floor, which means these roles") is a first-class, auditable record. Full semantics — provenance, highest-allowance union, overlay-on-reassign — are in [iam.md](iam.md#personas).
|
|
284
|
+
|
|
285
|
+
**Master list** — the working surface. One row per persona: display title, key, description, a preview of the linked role pills, and the holder count; search matches all of them. Select a row to target the **Assignees** panel on the right — assign a user there and they join every linked role in one step, sidebar pins and forms composing from the roles. Unassign from the same panel, or from the account's role panel on [Accounts](#accounts). The row's pencil opens configuration.
|
|
286
|
+
|
|
287
|
+
**Configuration** (`/admin/personas/:key`) —
|
|
288
|
+
|
|
289
|
+
- **Identity** — title and description, PATCH-saved.
|
|
290
|
+
- **Roles** — the bundle's rules. Each link shows the role pill, its scope badge, and a relationship picker (`Write · act on all`, `Write · act on self`, `Read-only observer`); changing a relationship or unlinking reconciles every holder immediately. Link new roles from the role picker.
|
|
291
|
+
|
|
292
|
+
**API:** `GET /api/personas` lists. `POST /api/personas` creates; `PATCH`/`DELETE /api/personas/:key` edit and remove. `PUT`/`DELETE /api/personas/:key/roles/:role` manage links. `POST /api/personas/seed` applies a declarative spec set idempotently.
|
|
293
|
+
|
|
279
294
|
### DB Maintenance
|
|
280
295
|
|
|
281
296
|
Database housekeeping tools for keeping PostgreSQL healthy under sustained workflow load.
|
|
@@ -316,6 +331,7 @@ Messages are read-only. Status is derived from timestamps: pending (no timestamp
|
|
|
316
331
|
|
|
317
332
|
The central queue for all escalation activity across every workflow.
|
|
318
333
|
|
|
334
|
+
- **Title = queue selector** — the page title reads as the selected role's friendly title, or "All Escalations" when unfiltered; clicking it switches queues over the same `?role=` param the filter bar mirrors. The **My Escalations** personal inbox (`/escalations/queue`) carries the identical control, titling itself "My Escalations" or the filtered role's title.
|
|
319
335
|
- **Filter bar** — filter by status (pending/claimed/resolved), role, workflow type, priority, and time window.
|
|
320
336
|
- **Columns:** Escalation ID, workflow type, role, status, priority, created time, and claimed-by user.
|
|
321
337
|
- **Rich list view** — when the list is scoped to exactly one role (`?role=<role>`) and that role owns a [list schema](#escalations-list-schema), a role-authored view renders in place of the table (the live item as a card, plus a load-on-demand history), with a **Table view** toggle back to the columns.
|
|
@@ -435,6 +451,12 @@ The Inbox icon in the header shows a badge count when the current user has pendi
|
|
|
435
451
|
|
|
436
452
|
The bottom bar contains a collapsible live event stream showing workflow start/completion events, task state transitions, escalation activity, and activity checkpoints. Events stream via NATS subscription.
|
|
437
453
|
|
|
454
|
+
### Claim Hand-off
|
|
455
|
+
|
|
456
|
+
The shell monitors the role-scoped `claimed` events across the viewer's roles; when one carries `assigned_to = viewer`, the dashboard navigates to that escalation's detail page. Pre-assignment is the system saying "this is yours next," and the UI honors it: a resolve → side-effect → follow-on chain (e.g. submit, a label prints, the harvest task opens) lands the user on the next step instead of history's previous page.
|
|
457
|
+
|
|
458
|
+
Workflows need no UI coupling — assigning the follow-on escalation to the resolving user is the whole contract. The gesture is naturally idempotent: a claim the user made themselves resolves to the page their click already opened.
|
|
459
|
+
|
|
438
460
|
### Contextual Documentation
|
|
439
461
|
|
|
440
462
|
Each page header includes a documentation icon that opens the in-app docs drawer to the relevant section. The drawer supports navigation history, anchor linking, and markdown rendering.
|
|
@@ -35,6 +35,10 @@ Chroma is spent, not spread.
|
|
|
35
35
|
inverted — never a flat white page with white sections.
|
|
36
36
|
- **The accent appears in small doses**: links, buttons, checks, pills,
|
|
37
37
|
section labels, focus states. Because it is scarce, it reads as "act here."
|
|
38
|
+
Icon links follow the same rule in every theme: clickable glyphs (toolbar
|
|
39
|
+
icons, view toggles) render through the `.icon-link` recipe — muted accent
|
|
40
|
+
at rest, full accent on hover — never a neutral text tone, which reads as
|
|
41
|
+
a static mark.
|
|
38
42
|
- **Dark themes are the same principle, inverted** — near-black neutral
|
|
39
43
|
surfaces, the identical accent discipline. Midnight is not a different
|
|
40
44
|
design; it is the same design at night.
|
|
@@ -207,11 +211,15 @@ Nothing loops, nothing floats.
|
|
|
207
211
|
owner, urgency, age — always renders. Enrichment columns (workflow,
|
|
208
212
|
metadata facets) return only when the table's container has room
|
|
209
213
|
(`showFrom: '@split' | '@wall'`); below that they fold into card pairs.
|
|
210
|
-
The list is a jumping-off spot: the
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
214
|
+
The list is a jumping-off spot: the ELK-style drill the whole product
|
|
215
|
+
surfaces.
|
|
216
|
+
6. **Refining is a ROW gesture, never a cell tax.** Cells spend their full
|
|
217
|
+
width on data. One always-visible magnifier per row (or board card)
|
|
218
|
+
opens the refine dialog: the row's metadata-bound facts as full-width
|
|
219
|
+
touch rows, multi-select ANDing facets, with filter-in-role /
|
|
220
|
+
search-everywhere / add-to-filters actions. Per-cell icon pairs are a
|
|
221
|
+
defect — twelve columns × two icons starves every value into an
|
|
222
|
+
ellipsis. Hover-only affordances do not exist on the floor.
|
|
215
223
|
7. **Disclosure order**: drop priority-3 columns, fold priority-2 into
|
|
216
224
|
pairs, keep priority-1 always.
|
|
217
225
|
8. **Touch parity**: every hover-only affordance has a tap equivalent —
|
|
@@ -26,13 +26,13 @@ The merge is a single guarded statement (no read-then-write) and the document is
|
|
|
26
26
|
|
|
27
27
|
## The Pinned Section
|
|
28
28
|
|
|
29
|
-
Pins render as
|
|
29
|
+
Pins render as first-class nav sections: each role's pins sit under the role's **display title**, styled exactly like the built-in categories (Monitor, Orchestrate, Storage) — the same composition the persona config screen previews. There is no "Pinned" umbrella; the role names are the categories. The user's own pins, when present, lead as their own **Pinned** section (stored order, drag to reorder, ✕ to remove). A section heading exists only over visible pins (a role whose pins are all hidden or promoted contributes no heading) and pins sit flush at the nav's left edge — the heading labels, it never indents. Every pin carries its full label as a tooltip. **Pin this view** on the escalations list captures the live filter set into a new pin, prompting only for a label.
|
|
30
30
|
|
|
31
|
-
`badge: true` renders a live count
|
|
31
|
+
`badge: true` renders a live count as bare superscript digits on the row's right rail — tabular, right-aligned so counts read as a column — using the same server-side predicate the pin opens onto (the pin's URL is parsed back into its query and counted with `limit: 1`), so the badge and the list always agree, including `jeopardy=1` pins. Counts refresh on escalation events, and a pin whose URL isn't a countable escalations list renders without a badge.
|
|
32
32
|
|
|
33
33
|
## Role Default Pins
|
|
34
34
|
|
|
35
|
-
A role may declare `default_pins: [{ label, url, badge? }]` (edited on Role Detail → Default Pins). Members see them in their Pinned section from first login,
|
|
35
|
+
A role may declare `default_pins: [{ label, url, badge? }]` (edited on Role Detail → Default Pins). Members see them in their Pinned section from first login, grouped under the role's display title, and may:
|
|
36
36
|
|
|
37
37
|
- **Promote** — copy into their own pins (an own pin with the same label supersedes the role default)
|
|
38
38
|
- **Hide** — dismiss it (recorded in `hiddenRolePins`)
|
|
@@ -99,7 +99,7 @@ The table renders through the same engine as the platform's built-in tables: pad
|
|
|
99
99
|
|
|
100
100
|
The seeded `print` role (ortho pipeline) is the reference example for this layout, including fold priorities.
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
Cells carry data only — the full column width belongs to the value, with the full text on hover. Refining is a **row** gesture: every row with at least one pure metadata binding (`{{metadata.key}}`) carries a magnifier that opens the refine dialog — the row's metadata-bound facts as touch-sized rows, each a toggle. Pick one or several (selections AND into one query) and drill: **Filter <role>** narrows this role's queue, **Search everywhere** spans every role, **Add to filters** merges the selection into the live filter set. A row with a single fact arrives preselected — two taps to drill.
|
|
103
103
|
|
|
104
104
|
### `"facet-board"` — entity board
|
|
105
105
|
|
|
@@ -127,7 +127,6 @@ Cards are fully interactive (`x-lt-group-by` should be a `metadata.*` path so th
|
|
|
127
127
|
|
|
128
128
|
- **Click** opens the group's latest row in the detail view.
|
|
129
129
|
- **⇧ click** adds the entity's facet to the live filter set — additive, so shift-clicking narrows the board in place and the facet chips row shows each condition with its own remove.
|
|
130
|
-
- **
|
|
131
|
-
- **Fields bound to a pure `{{metadata.KEY}}` token** carry the same hover pair the table's metadata cells offer: **filter** (narrows within the current role; ⇧ click adds to the current filters) and **search** (the facet across all roles).
|
|
130
|
+
- **The header magnifier** opens the card's refine dialog — the entity identity plus every field bound to a pure `{{metadata.KEY}}` token, as touch-sized toggle rows. Selections AND into one query: **Filter <role>**, **Search everywhere**, or **Add to filters** (merge into the live set). The same row gesture the facet table carries, always visible — no hover required.
|
|
132
131
|
|
|
133
132
|
The reference: `examples/seed-fleet-sim.ts` — one advert per machine, a `format: "age"` "Since" field, and role default pins (see [pinned-views.md](pinned-views.md)).
|
package/docs/iam.md
CHANGED
|
@@ -41,6 +41,53 @@ Scope makes limited-surface users first-class. A workflow assigns an escalation
|
|
|
41
41
|
|
|
42
42
|
See the [Roles API](api/http/roles.md#work-surface-scope) for the assignment contract and [roles.md](hitl/roles.md#role-based-routing) in the HITL guide for the workflow-side flow.
|
|
43
43
|
|
|
44
|
+
## Personas
|
|
45
|
+
|
|
46
|
+
A persona is a named bundle of roles with a per-role **relationship** scope — shorthand for "add this user to these roles with these scoped privileges." Assigning a persona performs the equivalent of adding the user to each linked role at the linked scope; because each role carries its own pins, list schema, and form schema, one assignment composes the member's entire dashboard surface. Personas are a suggestion, the same way a `default_pins` entry is: admins can always hand-tune memberships per user through the existing users/roles surfaces, and the persona is the repeatable 95% path.
|
|
47
|
+
|
|
48
|
+
The relationship names a point on the member scope lattice (a persona grant is always `type=member`):
|
|
49
|
+
|
|
50
|
+
| relationship | read_scope | write_scope | Grants |
|
|
51
|
+
|--------------|-----------|-------------|--------|
|
|
52
|
+
| `write-all` | `all` | `all` | Full worker — claim, resolve, submit forms |
|
|
53
|
+
| `write-self` | `all` | `self` | Sees the whole queue, acts only on own assignments |
|
|
54
|
+
| `read-all` | `all` | `none` | Observer — sees the pond, the pins, the counts; cannot act |
|
|
55
|
+
|
|
56
|
+
`write-none` is accepted everywhere as a synonym for `read-all`.
|
|
57
|
+
|
|
58
|
+
### Membership stays the source of truth
|
|
59
|
+
|
|
60
|
+
Personas are not a second authorization path. Assignment fans out to ordinary `lt_user_roles` rows; every RBAC query reads memberships exactly as before. The persona record explains *why* the memberships exist:
|
|
61
|
+
|
|
62
|
+
- **Provenance.** Each membership carries `granted_by_persona` — the persona sustaining it, or null for a direct grant. Unassigning a persona removes only the rows it sustains. A row a sibling persona still grants is re-homed to that persona instead of being removed. A direct role-add on a persona-sustained row takes the row over (provenance flips to direct), so a later unassign never removes a membership an admin set by hand.
|
|
63
|
+
- **Highest allowance wins.** A user holding several personas (or a direct grant) gets the union per role — the membership row stores the highest scope any grantor supplies. Direct grants are only ever raised toward the persona union, never lowered.
|
|
64
|
+
- **Overlay on re-assign.** Assignment is idempotent: re-assigning a persona reconciles the user's memberships against the persona's *current* role links, so "apply and reapply" is one call. Editing a persona's links (or its link relationships) reconciles every current holder in the same transaction.
|
|
65
|
+
- **Deletion is exact.** Deleting a persona removes the memberships it sustains (re-homing rows a sibling persona still grants) before the persona row goes away; direct grants are untouched.
|
|
66
|
+
|
|
67
|
+
### Declaring personas
|
|
68
|
+
|
|
69
|
+
Personas are managed three equivalent ways — dashboard (**Admin → Personas**, visible to admins, superadmins, and engineers, the same audience that manages roles and users), API/SDK, and a declarative seed pass that lives in git beside the role declarations:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
await lt.personas.seed([
|
|
73
|
+
{
|
|
74
|
+
key: 'production-manager',
|
|
75
|
+
title: 'Production Manager',
|
|
76
|
+
description: 'Runs the pipeline: works design and review, watches print and the fleet.',
|
|
77
|
+
roles: [
|
|
78
|
+
{ role: 'design', relationship: 'write-all' },
|
|
79
|
+
{ role: 'review', relationship: 'write-all' },
|
|
80
|
+
{ role: 'print', relationship: 'read-all' },
|
|
81
|
+
{ role: 'fleet-servicer', relationship: 'read-all' },
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
]);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The seed is idempotent and authoritative per spec: title/description are overlaid, role links are synced (links absent from the spec are pruned), linked roles are ensured as FK targets, and every current holder is reconciled — re-running the seed after editing a spec re-applies it to everyone holding the persona.
|
|
88
|
+
|
|
89
|
+
HTTP surface: `GET/POST /api/personas`, `GET/PATCH/DELETE /api/personas/:key`, `PUT/DELETE /api/personas/:key/roles/:role`, `POST /api/personas/seed`, and per-user `GET/POST /api/users/:id/personas` plus `DELETE /api/users/:id/personas/:key`. `GET /api/users/:id/personas` returns the personas held and the composed role/scope map (each row naming its sustaining persona, or null for a direct grant) — the profile-page view. The same operations exist as `lt.personas.*` in the SDK, `ltc personas` in the CLI, and `*_persona` tools on the `long-tail-admin` MCP server.
|
|
90
|
+
|
|
44
91
|
### Enforcement
|
|
45
92
|
|
|
46
93
|
Scope folds into the SQL, so it is atomic with no TOCTOU window. Read scope becomes part of the escalation search query — a member sees a row when `role ∈ allRoles OR (role ∈ selfRoles AND assigned_to = me)`. Write scope folds into the atomic resolve-by-metadata query and gates the by-id claim/resolve/cancel paths. `assigned_to` is indexed, so `self` scope scales to large queues.
|
package/docs/operations.md
CHANGED
|
@@ -123,4 +123,4 @@ See [MCP Admin Tools — Ortho Pipeline](api/mcp/admin.md#ortho-pipeline) for th
|
|
|
123
123
|
|
|
124
124
|
## Navigation
|
|
125
125
|
|
|
126
|
-
The Operations entry lives in the choreography sidebar (the left rail visible on `/operations` and `/escalations`), separate from the Admin sidebar. The `/operations` route admits
|
|
126
|
+
The Operations entry lives in the choreography sidebar (the left rail visible on `/operations` and `/escalations`), separate from the Admin sidebar. The `/operations` route admits every authenticated user — the board is aggregate counts and trends, readonly by nature. Station metrics span all roles for any login while the `features.publicPaceBoard` flag (default on) stands; a deployment that sets it false (e.g. one provisioning external one-time accounts) narrows metrics back to role membership and the board back to admin-type users and superadmins.
|
package/docs/sdk.md
CHANGED
|
@@ -68,6 +68,7 @@ The client mirrors the REST route structure:
|
|
|
68
68
|
| `lt.yamlWorkflows` | `/api/yaml-workflows` | `list`, `get`, `create`, `deploy`, `activate`, `invoke`, `archive` |
|
|
69
69
|
| `lt.users` | `/api/users` | `list`, `get`, `create`, `update`, `delete`, `getRoles`, `addRole`, `removeRole` |
|
|
70
70
|
| `lt.roles` | `/api/roles` | `list`, `listWithDetails`, `create`, `delete`, `getEscalationChains` |
|
|
71
|
+
| `lt.personas` | `/api/personas` | `list`, `get`, `create`, `update`, `delete`, `linkRole`, `unlinkRole`, `assign`, `unassign`, `forUser`, `seed` |
|
|
71
72
|
| `lt.auth` | `/api/auth` | `login` |
|
|
72
73
|
| `lt.mcp` | `/api/mcp` | `listServers`, `createServer`, `getServer`, `connectServer`, `listTools`, `callTool` |
|
|
73
74
|
| `lt.pipelines` | `/api/pipelines` | `listEntities`, `listJobs`, `getExecution`, `interrupt` |
|
package/package.json
CHANGED