@burdenoff/microfe-botmanor 2026.1108.1 → 2026.1109.2

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 (335) hide show
  1. package/dist/botlit/BotlitRoutes.d.ts +2 -0
  2. package/dist/botlit/BotlitRoutes.js +40 -52
  3. package/dist/botlit/BotlitRoutes.js.map +1 -1
  4. package/dist/botlit/BotmanorRoot.d.ts +3 -0
  5. package/dist/botlit/BotmanorRoot.js +1 -2
  6. package/dist/botlit/BotmanorRoot.js.map +1 -1
  7. package/dist/botlit/BotmanorRootInner.d.ts +3 -0
  8. package/dist/botlit/BotmanorRootInner.js +9 -10
  9. package/dist/botlit/BotmanorRootInner.js.map +1 -1
  10. package/dist/botlit/components/AgentApprovalPanel.d.ts +20 -0
  11. package/dist/botlit/components/AgentApprovalPanel.js +49 -50
  12. package/dist/botlit/components/AgentApprovalPanel.js.map +1 -1
  13. package/dist/botlit/components/AiOperationsPanel.d.ts +14 -0
  14. package/dist/botlit/components/AiOperationsPanel.js +54 -55
  15. package/dist/botlit/components/AiOperationsPanel.js.map +1 -1
  16. package/dist/botlit/components/AssistantChannelPanel.d.ts +3 -0
  17. package/dist/botlit/components/AssistantChannelPanel.js +12 -13
  18. package/dist/botlit/components/AssistantChannelPanel.js.map +1 -1
  19. package/dist/botlit/components/AssistantRuntimeSetupPanel.d.ts +4 -0
  20. package/dist/botlit/components/AssistantRuntimeSetupPanel.js +14 -14
  21. package/dist/botlit/components/AssistantRuntimeSetupPanel.js.map +1 -1
  22. package/dist/botlit/components/AssistantWebsitePanel.d.ts +5 -0
  23. package/dist/botlit/components/AssistantWebsitePanel.js +15 -16
  24. package/dist/botlit/components/AssistantWebsitePanel.js.map +1 -1
  25. package/dist/botlit/components/Badge.d.ts +9 -0
  26. package/dist/botlit/components/Badge.js +1 -2
  27. package/dist/botlit/components/Badge.js.map +1 -1
  28. package/dist/botlit/components/Button.d.ts +10 -0
  29. package/dist/botlit/components/Button.js +1 -2
  30. package/dist/botlit/components/Button.js.map +1 -1
  31. package/dist/botlit/components/Card.d.ts +16 -0
  32. package/dist/botlit/components/Card.js +1 -2
  33. package/dist/botlit/components/Card.js.map +1 -1
  34. package/dist/botlit/components/ChannelSelectorSheet.d.ts +23 -0
  35. package/dist/botlit/components/ChannelSelectorSheet.js +1 -2
  36. package/dist/botlit/components/ChannelSelectorSheet.js.map +1 -1
  37. package/dist/botlit/components/EmptyState.d.ts +12 -0
  38. package/dist/botlit/components/EmptyState.js +1 -2
  39. package/dist/botlit/components/EmptyState.js.map +1 -1
  40. package/dist/botlit/components/ErrorState.d.ts +10 -0
  41. package/dist/botlit/components/ErrorState.js +5 -6
  42. package/dist/botlit/components/ErrorState.js.map +1 -1
  43. package/dist/botlit/components/Input.d.ts +27 -0
  44. package/dist/botlit/components/Input.js +1 -2
  45. package/dist/botlit/components/Input.js.map +1 -1
  46. package/dist/botlit/components/KnowledgeSourceImportPanel.d.ts +3 -0
  47. package/dist/botlit/components/KnowledgeSourceImportPanel.js +12 -13
  48. package/dist/botlit/components/KnowledgeSourceImportPanel.js.map +1 -1
  49. package/dist/botlit/components/ModelRegistrationPanel.d.ts +5 -0
  50. package/dist/botlit/components/ModelRegistrationPanel.js +1 -2
  51. package/dist/botlit/components/ModelRegistrationPanel.js.map +1 -1
  52. package/dist/botlit/components/PageLayout.d.ts +12 -0
  53. package/dist/botlit/components/PageLayout.js +1 -2
  54. package/dist/botlit/components/PageLayout.js.map +1 -1
  55. package/dist/botlit/components/QuotaExhaustedDialog.d.ts +9 -0
  56. package/dist/botlit/components/QuotaExhaustedDialog.js +1 -2
  57. package/dist/botlit/components/QuotaExhaustedDialog.js.map +1 -1
  58. package/dist/botlit/components/RetentionStatusPanel.d.ts +2 -0
  59. package/dist/botlit/components/RetentionStatusPanel.js +18 -19
  60. package/dist/botlit/components/RetentionStatusPanel.js.map +1 -1
  61. package/dist/botlit/components/RouteLoader.d.ts +23 -0
  62. package/dist/botlit/components/RouteLoader.js +1 -2
  63. package/dist/botlit/components/RouteLoader.js.map +1 -1
  64. package/dist/botlit/components/VersionHistoryPanel.d.ts +12 -0
  65. package/dist/botlit/components/VersionHistoryPanel.js +23 -24
  66. package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
  67. package/dist/botlit/components/WorkspaceRequired.d.ts +18 -0
  68. package/dist/botlit/components/WorkspaceRequired.js +1 -2
  69. package/dist/botlit/components/WorkspaceRequired.js.map +1 -1
  70. package/dist/botlit/components/index.d.ts +14 -0
  71. package/dist/botlit/hooks/index.d.ts +35 -0
  72. package/dist/botlit/hooks/index.js +16 -16
  73. package/dist/botlit/hooks/internal/mutationInput.d.ts +56 -0
  74. package/dist/botlit/hooks/internal/mutationInput.js +1 -2
  75. package/dist/botlit/hooks/internal/mutationInput.js.map +1 -1
  76. package/dist/botlit/hooks/internal/workspaceGateway.d.ts +54 -0
  77. package/dist/botlit/hooks/internal/workspaceGateway.js +17 -19
  78. package/dist/botlit/hooks/internal/workspaceGateway.js.map +1 -1
  79. package/dist/botlit/hooks/useA2A.d.ts +104 -0
  80. package/dist/botlit/hooks/useA2A.js +45 -45
  81. package/dist/botlit/hooks/useA2A.js.map +1 -1
  82. package/dist/botlit/hooks/useAgentApprovals.d.ts +62 -0
  83. package/dist/botlit/hooks/useAgentApprovals.js +38 -39
  84. package/dist/botlit/hooks/useAgentApprovals.js.map +1 -1
  85. package/dist/botlit/hooks/useAgents.d.ts +105 -0
  86. package/dist/botlit/hooks/useAgents.js +53 -54
  87. package/dist/botlit/hooks/useAgents.js.map +1 -1
  88. package/dist/botlit/hooks/useAiOperations.d.ts +95 -0
  89. package/dist/botlit/hooks/useAiOperations.js +20 -19
  90. package/dist/botlit/hooks/useAiOperations.js.map +1 -1
  91. package/dist/botlit/hooks/useAssistantChannels.d.ts +16 -0
  92. package/dist/botlit/hooks/useAssistantChannels.js +1 -2
  93. package/dist/botlit/hooks/useAssistantChannels.js.map +1 -1
  94. package/dist/botlit/hooks/useAssistantRuntimeSetup.d.ts +17 -0
  95. package/dist/botlit/hooks/useAssistantRuntimeSetup.js +1 -2
  96. package/dist/botlit/hooks/useAssistantRuntimeSetup.js.map +1 -1
  97. package/dist/botlit/hooks/useAssistantWebsites.d.ts +18 -0
  98. package/dist/botlit/hooks/useAssistantWebsites.js +1 -2
  99. package/dist/botlit/hooks/useAssistantWebsites.js.map +1 -1
  100. package/dist/botlit/hooks/useBotWorkflow.d.ts +22 -0
  101. package/dist/botlit/hooks/useBotWorkflow.js +1 -2
  102. package/dist/botlit/hooks/useBotWorkflow.js.map +1 -1
  103. package/dist/botlit/hooks/useBots.d.ts +68 -0
  104. package/dist/botlit/hooks/useBots.js +32 -33
  105. package/dist/botlit/hooks/useBots.js.map +1 -1
  106. package/dist/botlit/hooks/useBuckets.d.ts +62 -0
  107. package/dist/botlit/hooks/useBuckets.js +91 -58
  108. package/dist/botlit/hooks/useBuckets.js.map +1 -1
  109. package/dist/botlit/hooks/useChannels.d.ts +87 -0
  110. package/dist/botlit/hooks/useChannels.js +73 -73
  111. package/dist/botlit/hooks/useChannels.js.map +1 -1
  112. package/dist/botlit/hooks/useExecutions.d.ts +87 -0
  113. package/dist/botlit/hooks/useExecutions.js +37 -37
  114. package/dist/botlit/hooks/useExecutions.js.map +1 -1
  115. package/dist/botlit/hooks/useKnowledgeBases.d.ts +79 -0
  116. package/dist/botlit/hooks/useKnowledgeBases.js +40 -39
  117. package/dist/botlit/hooks/useKnowledgeBases.js.map +1 -1
  118. package/dist/botlit/hooks/useKnowledgeSourceImports.d.ts +21 -0
  119. package/dist/botlit/hooks/useKnowledgeSourceImports.js +1 -2
  120. package/dist/botlit/hooks/useKnowledgeSourceImports.js.map +1 -1
  121. package/dist/botlit/hooks/useLLMProviders.d.ts +66 -0
  122. package/dist/botlit/hooks/useLLMProviders.js +25 -26
  123. package/dist/botlit/hooks/useLLMProviders.js.map +1 -1
  124. package/dist/botlit/hooks/useMCPServers.d.ts +71 -0
  125. package/dist/botlit/hooks/useMCPServers.js +40 -38
  126. package/dist/botlit/hooks/useMCPServers.js.map +1 -1
  127. package/dist/botlit/hooks/usePolicies.d.ts +60 -0
  128. package/dist/botlit/hooks/usePolicies.js +49 -49
  129. package/dist/botlit/hooks/usePolicies.js.map +1 -1
  130. package/dist/botlit/hooks/usePromptTemplates.d.ts +88 -0
  131. package/dist/botlit/hooks/usePromptTemplates.js +57 -57
  132. package/dist/botlit/hooks/usePromptTemplates.js.map +1 -1
  133. package/dist/botlit/hooks/useRetention.d.ts +26 -0
  134. package/dist/botlit/hooks/useRetention.js +3 -3
  135. package/dist/botlit/hooks/useRetention.js.map +1 -1
  136. package/dist/botlit/hooks/useRetrievalProfiles.d.ts +75 -0
  137. package/dist/botlit/hooks/useRetrievalProfiles.js +47 -47
  138. package/dist/botlit/hooks/useRetrievalProfiles.js.map +1 -1
  139. package/dist/botlit/hooks/useSkills.d.ts +64 -0
  140. package/dist/botlit/hooks/useSkills.js +53 -53
  141. package/dist/botlit/hooks/useSkills.js.map +1 -1
  142. package/dist/botlit/hooks/useStore.d.ts +112 -0
  143. package/dist/botlit/hooks/useStore.js +55 -55
  144. package/dist/botlit/hooks/useStore.js.map +1 -1
  145. package/dist/botlit/hooks/useUserPlatformConnection.d.ts +80 -0
  146. package/dist/botlit/hooks/useUserPlatformConnection.js +19 -19
  147. package/dist/botlit/hooks/useUserPlatformConnection.js.map +1 -1
  148. package/dist/botlit/index.d.ts +15 -0
  149. package/dist/botlit/index.js +11 -11
  150. package/dist/botlit/pages/A2AAgentDetailPage.d.ts +6 -0
  151. package/dist/botlit/pages/A2AAgentDetailPage.js +171 -178
  152. package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
  153. package/dist/botlit/pages/A2ARegistryPage.d.ts +2 -0
  154. package/dist/botlit/pages/A2ARegistryPage.js +25 -26
  155. package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
  156. package/dist/botlit/pages/AgentApprovalsPage.d.ts +2 -0
  157. package/dist/botlit/pages/AgentApprovalsPage.js +32 -33
  158. package/dist/botlit/pages/AgentApprovalsPage.js.map +1 -1
  159. package/dist/botlit/pages/AgentBuilderPage.d.ts +2 -0
  160. package/dist/botlit/pages/AgentBuilderPage.js +59 -60
  161. package/dist/botlit/pages/AgentBuilderPage.js.map +1 -1
  162. package/dist/botlit/pages/AgentDetailPage.d.ts +2 -0
  163. package/dist/botlit/pages/AgentDetailPage.js +83 -84
  164. package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
  165. package/dist/botlit/pages/AgentsListPage.d.ts +2 -0
  166. package/dist/botlit/pages/AgentsListPage.js +71 -72
  167. package/dist/botlit/pages/AgentsListPage.js.map +1 -1
  168. package/dist/botlit/pages/AiOperationsPage.d.ts +2 -0
  169. package/dist/botlit/pages/AiOperationsPage.js +52 -53
  170. package/dist/botlit/pages/AiOperationsPage.js.map +1 -1
  171. package/dist/botlit/pages/BotChannelsTab.d.ts +7 -0
  172. package/dist/botlit/pages/BotChannelsTab.js +120 -122
  173. package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
  174. package/dist/botlit/pages/BotDetailPage.d.ts +7 -0
  175. package/dist/botlit/pages/BotDetailPage.js +353 -358
  176. package/dist/botlit/pages/BotDetailPage.js.map +1 -1
  177. package/dist/botlit/pages/BotWorkflowTab.d.ts +11 -0
  178. package/dist/botlit/pages/BotWorkflowTab.js +20 -21
  179. package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
  180. package/dist/botlit/pages/BotsListPage.d.ts +2 -0
  181. package/dist/botlit/pages/BotsListPage.js +52 -53
  182. package/dist/botlit/pages/BotsListPage.js.map +1 -1
  183. package/dist/botlit/pages/BucketDetailPage.d.ts +2 -0
  184. package/dist/botlit/pages/BucketDetailPage.js +251 -0
  185. package/dist/botlit/pages/BucketDetailPage.js.map +1 -0
  186. package/dist/botlit/pages/BucketsPage.d.ts +2 -0
  187. package/dist/botlit/pages/BucketsPage.js +260 -261
  188. package/dist/botlit/pages/BucketsPage.js.map +1 -1
  189. package/dist/botlit/pages/ChannelDetailPage.d.ts +6 -0
  190. package/dist/botlit/pages/ChannelDetailPage.js +97 -96
  191. package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
  192. package/dist/botlit/pages/ChannelRoutesPage.d.ts +2 -0
  193. package/dist/botlit/pages/ChannelRoutesPage.js +23 -24
  194. package/dist/botlit/pages/ChannelRoutesPage.js.map +1 -1
  195. package/dist/botlit/pages/ChannelsPage.d.ts +2 -0
  196. package/dist/botlit/pages/ChannelsPage.js +44 -45
  197. package/dist/botlit/pages/ChannelsPage.js.map +1 -1
  198. package/dist/botlit/pages/ChatPage.d.ts +1 -0
  199. package/dist/botlit/pages/ChatPage.js +10 -11
  200. package/dist/botlit/pages/ChatPage.js.map +1 -1
  201. package/dist/botlit/pages/DashboardPage.d.ts +2 -0
  202. package/dist/botlit/pages/DashboardPage.js +37 -38
  203. package/dist/botlit/pages/DashboardPage.js.map +1 -1
  204. package/dist/botlit/pages/ExecutionDetailPage.d.ts +2 -0
  205. package/dist/botlit/pages/ExecutionDetailPage.js +47 -48
  206. package/dist/botlit/pages/ExecutionDetailPage.js.map +1 -1
  207. package/dist/botlit/pages/ExecutionsPage.d.ts +2 -0
  208. package/dist/botlit/pages/ExecutionsPage.js +72 -70
  209. package/dist/botlit/pages/ExecutionsPage.js.map +1 -1
  210. package/dist/botlit/pages/InstalledPackagesPage.d.ts +2 -0
  211. package/dist/botlit/pages/InstalledPackagesPage.js +77 -78
  212. package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
  213. package/dist/botlit/pages/KnowledgeBaseDetailPage.d.ts +6 -0
  214. package/dist/botlit/pages/KnowledgeBaseDetailPage.js +171 -181
  215. package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
  216. package/dist/botlit/pages/KnowledgeBasesPage.d.ts +2 -0
  217. package/dist/botlit/pages/KnowledgeBasesPage.js +30 -31
  218. package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
  219. package/dist/botlit/pages/MCPServerDetailPage.d.ts +6 -0
  220. package/dist/botlit/pages/MCPServerDetailPage.js +82 -83
  221. package/dist/botlit/pages/MCPServerDetailPage.js.map +1 -1
  222. package/dist/botlit/pages/MCPServersPage.d.ts +2 -0
  223. package/dist/botlit/pages/MCPServersPage.js +54 -55
  224. package/dist/botlit/pages/MCPServersPage.js.map +1 -1
  225. package/dist/botlit/pages/PoliciesPage.d.ts +2 -0
  226. package/dist/botlit/pages/PoliciesPage.js +25 -26
  227. package/dist/botlit/pages/PoliciesPage.js.map +1 -1
  228. package/dist/botlit/pages/PolicyDetailPage.d.ts +6 -0
  229. package/dist/botlit/pages/PolicyDetailPage.js +257 -259
  230. package/dist/botlit/pages/PolicyDetailPage.js.map +1 -1
  231. package/dist/botlit/pages/PromptStudioPage.d.ts +2 -0
  232. package/dist/botlit/pages/PromptStudioPage.js +35 -35
  233. package/dist/botlit/pages/PromptStudioPage.js.map +1 -1
  234. package/dist/botlit/pages/PromptTemplateDetailPage.d.ts +6 -0
  235. package/dist/botlit/pages/PromptTemplateDetailPage.js +363 -362
  236. package/dist/botlit/pages/PromptTemplateDetailPage.js.map +1 -1
  237. package/dist/botlit/pages/PromptTemplatesPage.d.ts +2 -0
  238. package/dist/botlit/pages/PromptTemplatesPage.js +26 -27
  239. package/dist/botlit/pages/PromptTemplatesPage.js.map +1 -1
  240. package/dist/botlit/pages/RetrievalProfileDetailPage.d.ts +6 -0
  241. package/dist/botlit/pages/RetrievalProfileDetailPage.js +150 -158
  242. package/dist/botlit/pages/RetrievalProfileDetailPage.js.map +1 -1
  243. package/dist/botlit/pages/RetrievalProfilesPage.d.ts +2 -0
  244. package/dist/botlit/pages/RetrievalProfilesPage.js +24 -25
  245. package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
  246. package/dist/botlit/pages/SettingsPage.d.ts +2 -0
  247. package/dist/botlit/pages/SettingsPage.js +124 -125
  248. package/dist/botlit/pages/SettingsPage.js.map +1 -1
  249. package/dist/botlit/pages/SkillDetailPage.d.ts +6 -0
  250. package/dist/botlit/pages/SkillDetailPage.js +216 -217
  251. package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
  252. package/dist/botlit/pages/SkillsPage.d.ts +2 -0
  253. package/dist/botlit/pages/SkillsPage.js +24 -25
  254. package/dist/botlit/pages/SkillsPage.js.map +1 -1
  255. package/dist/botlit/pages/StorePackageDetailPage.d.ts +2 -0
  256. package/dist/botlit/pages/StorePackageDetailPage.js +38 -39
  257. package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
  258. package/dist/botlit/pages/StorePage.d.ts +2 -0
  259. package/dist/botlit/pages/StorePage.js +135 -136
  260. package/dist/botlit/pages/StorePage.js.map +1 -1
  261. package/dist/botlit/pages/index.d.ts +38 -0
  262. package/dist/botlit/permissions/PermissionRequired.d.ts +20 -0
  263. package/dist/botlit/permissions/PermissionRequired.js +10 -11
  264. package/dist/botlit/permissions/PermissionRequired.js.map +1 -1
  265. package/dist/botlit/permissions/botmanorPermissions.d.ts +82 -0
  266. package/dist/botlit/permissions/botmanorPermissions.js +1 -2
  267. package/dist/botlit/permissions/botmanorPermissions.js.map +1 -1
  268. package/dist/botlit/permissions/index.d.ts +7 -0
  269. package/dist/botlit/permissions/index.js +4 -3
  270. package/dist/botlit/permissions/useBotmanorPermissions.d.ts +41 -0
  271. package/dist/botlit/permissions/useBotmanorPermissions.js +1 -2
  272. package/dist/botlit/permissions/useBotmanorPermissions.js.map +1 -1
  273. package/dist/botlit/providers/BotlitProvider.d.ts +14 -0
  274. package/dist/botlit/providers/BotlitProvider.js +3 -3
  275. package/dist/botlit/providers/BotlitProvider.js.map +1 -1
  276. package/dist/botlit/store/botlitStore.d.ts +85 -0
  277. package/dist/botlit/store/botlitStore.js +1 -2
  278. package/dist/botlit/store/botlitStore.js.map +1 -1
  279. package/dist/botlit/store/renamedKeyStorage.d.ts +13 -0
  280. package/dist/botlit/store/renamedKeyStorage.js +1 -2
  281. package/dist/botlit/store/renamedKeyStorage.js.map +1 -1
  282. package/dist/botlit/types/index.d.ts +1008 -0
  283. package/dist/botlit/utils/cn.d.ts +2 -0
  284. package/dist/botlit/utils/cn.js +1 -2
  285. package/dist/botlit/utils/cn.js.map +1 -1
  286. package/dist/botlit/utils/embedding-models.d.ts +9 -0
  287. package/dist/botlit/utils/embedding-models.js +1 -2
  288. package/dist/botlit/utils/embedding-models.js.map +1 -1
  289. package/dist/botlit/utils/errors.d.ts +19 -0
  290. package/dist/botlit/utils/errors.js +1 -2
  291. package/dist/botlit/utils/errors.js.map +1 -1
  292. package/dist/botlit/utils/formatters.d.ts +38 -0
  293. package/dist/botlit/utils/formatters.js +0 -1
  294. package/dist/botlit/utils/formatters.js.map +1 -1
  295. package/dist/botlit/utils/navigation.d.ts +19 -0
  296. package/dist/botlit/utils/navigation.js +1 -2
  297. package/dist/botlit/utils/navigation.js.map +1 -1
  298. package/dist/botlit/utils/policyConfig.d.ts +68 -0
  299. package/dist/botlit/utils/policyConfig.js +2 -3
  300. package/dist/botlit/utils/policyConfig.js.map +1 -1
  301. package/dist/botlit/utils/unions.d.ts +25 -0
  302. package/dist/botlit/utils/unions.js +1 -2
  303. package/dist/botlit/utils/unions.js.map +1 -1
  304. package/dist/dev/App.d.ts +2 -0
  305. package/dist/dev/main.d.ts +0 -0
  306. package/dist/generated/global-operations.d.ts +197 -0
  307. package/dist/generated/global-operations.js +1 -2
  308. package/dist/generated/global-operations.js.map +1 -1
  309. package/dist/generated/global-types.d.ts +27678 -0
  310. package/dist/generated/global-types.js +1 -2
  311. package/dist/generated/global-types.js.map +1 -1
  312. package/dist/generated/wspace-operations.d.ts +5489 -0
  313. package/dist/generated/wspace-operations.js +88 -84
  314. package/dist/generated/wspace-operations.js.map +1 -1
  315. package/dist/generated/wspace-types.d.ts +152017 -0
  316. package/dist/generated/wspace-types.js +1 -2
  317. package/dist/generated/wspace-types.js.map +1 -1
  318. package/dist/index.d.ts +5 -0
  319. package/dist/index.js +5 -6
  320. package/dist/shared/hooks/useTr.d.ts +16 -0
  321. package/dist/shared/hooks/useTr.js +1 -2
  322. package/dist/shared/hooks/useTr.js.map +1 -1
  323. package/dist/stories/Badge.stories.d.ts +11 -0
  324. package/dist/stories/Button.stories.d.ts +13 -0
  325. package/dist/stories/EmptyState.stories.d.ts +8 -0
  326. package/dist/stories/StatusBadge.stories.d.ts +9 -0
  327. package/dist/test/fixtures.d.ts +39 -0
  328. package/dist/test/happydom.d.ts +1 -0
  329. package/dist/test/renderPage.d.ts +18 -0
  330. package/dist/test/setup.d.ts +9 -0
  331. package/dist/utils/nativeBridge.d.ts +2 -0
  332. package/dist/utils/nativeBridge.js +1 -2
  333. package/package.json +87 -60
  334. package/dist/botlit/hooks/useConversations.js +0 -64
  335. package/dist/botlit/hooks/useConversations.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PolicyDetailPage.js","names":[],"sources":["../../../src/botlit/pages/PolicyDetailPage.tsx"],"sourcesContent":["/**\n * Policy Detail Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { useParams } from 'react-router';\nimport { toast } from 'sonner';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { isNative, nativeImpact, nativeNotify } from '../../utils/nativeBridge';\nimport {\n ArrowLeft,\n Shield,\n Settings,\n Save,\n AlertTriangle,\n Wrench,\n Database,\n FileText,\n DollarSign,\n Clock,\n Trash2,\n Edit,\n Power,\n} from 'lucide-react';\nimport { PageLayout } from '../components/PageLayout';\nimport { PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { EmptyState } from '../components/EmptyState';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input, Textarea, FormField } from '../components/Input';\nimport { StatusBadge, Badge } from '../components/Badge';\nimport { usePolicy, useCreatePolicy, useUpdatePolicy, useDeletePolicy } from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { toUnion } from '../utils/unions';\nimport type { PolicyType, Visibility } from '../types';\nimport {\n A2A_TRUST_LEVELS,\n CREATABLE_POLICY_TYPES,\n EMPTY_POLICY_FORM,\n MAX_RETENTION_DAYS,\n TOOL_RISK_LEVELS,\n buildPolicyConfig,\n isCreatablePolicyType,\n unenforcedConfigKeys,\n type CreatablePolicyType,\n type PolicyFormState,\n} from '../utils/policyConfig';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\n/**\n * Policy types the UI can render; the column itself is a free-form String.\n * DATA has no runtime evaluator: existing rows still render, but the editor\n * only creates CREATABLE_POLICY_TYPES (BOFF-9683). RETENTION is enforced by\n * the scheduled retention job (BOFF-9661).\n */\nconst POLICY_TYPES: PolicyType[] = [\n 'CONTENT',\n 'TOOL',\n 'DATA',\n 'RESPONSE',\n 'BUDGET',\n 'RATE_LIMIT',\n 'RETENTION',\n];\n\nconst VISIBILITIES: Visibility[] = ['PRIVATE', 'WORKSPACE', 'PUBLIC'];\n\nconst SELECT_CLASS =\n 'flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm';\n\ninterface PolicyDetailPageProps {\n isNew?: boolean;\n}\n\nconst PolicyTypeIcon: FC<{ type: PolicyType }> = ({ type }) => {\n const icons: Record<PolicyType, React.ReactElement> = {\n CONTENT: <AlertTriangle size={18} />,\n TOOL: <Wrench size={18} />,\n DATA: <Database size={18} />,\n RESPONSE: <FileText size={18} />,\n BUDGET: <DollarSign size={18} />,\n RATE_LIMIT: <Clock size={18} />,\n RETENTION: <Trash2 size={18} />,\n };\n return icons[type] || <Shield size={18} />;\n};\n\nconst PolicyTypeLabel: Record<PolicyType, string> = {\n CONTENT: 'Content Policy',\n TOOL: 'Tool Policy',\n DATA: 'Data Policy',\n RESPONSE: 'Response & Model Policy',\n BUDGET: 'Budget Policy',\n RATE_LIMIT: 'Rate Limit Policy',\n RETENTION: 'Retention Policy',\n};\n\nexport const PolicyDetailPage: FC<PolicyDetailPageProps> = ({ isNew }) => {\n const { policyId } = useParams();\n const { navigateTo } = useBotlit();\n const { data: policy, loading, refetch: refetchPolicy } = usePolicy(isNew ? undefined : policyId);\n const { create: createPolicy, loading: createLoading } = useCreatePolicy();\n const { update: updatePolicy, loading: updateLoading } = useUpdatePolicy();\n const { remove: deletePolicy, loading: deleteLoading } = useDeletePolicy();\n\n const [isEditing, setIsEditing] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n\n const [formData, setFormData] = useState({\n name: '',\n description: '',\n type: 'CONTENT' as CreatablePolicyType,\n visibility: 'PRIVATE' as Visibility,\n });\n\n // Edit-form fields: name, description and visibility of an existing policy.\n const [editData, setEditData] = useState({\n name: '',\n description: '',\n visibility: 'PRIVATE' as Visibility,\n });\n\n // Type-specific config. Every field maps to a key the runtime enforces.\n const [policyForm, setPolicyForm] = useState<PolicyFormState>(EMPTY_POLICY_FORM);\n const [configError, setConfigError] = useState<string | null>(null);\n\n const updateForm = <K extends keyof PolicyFormState>(\n section: K,\n patch: Partial<PolicyFormState[K]>\n ) => {\n setConfigError(null);\n setPolicyForm((current) => ({ ...current, [section]: { ...current[section], ...patch } }));\n };\n\n // New policies start as drafts unless the author chooses to enforce them now.\n const [activateOnCreate, setActivateOnCreate] = useState(false);\n\n const handleCreate = async () => {\n if (!formData.name) return;\n\n const built = buildPolicyConfig(formData.type, policyForm);\n if (!built.ok) {\n setConfigError(built.error);\n toast.error(built.error);\n return;\n }\n\n try {\n await createPolicy({\n name: formData.name,\n description: formData.description,\n type: formData.type,\n visibility: formData.visibility,\n status: activateOnCreate ? 'ACTIVE' : 'DRAFT',\n config: built.config as Record<string, unknown>,\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to create policy');\n return;\n }\n toast.success(`Policy \"${formData.name}\" created`);\n navigateTo('policies');\n };\n\n const handleUpdate = async () => {\n if (!policyId || !editData.name) return;\n try {\n await updatePolicy({\n policyId,\n input: {\n name: editData.name,\n description: editData.description,\n visibility: editData.visibility,\n },\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to update policy');\n return;\n }\n // The policy query is network-only local state, so re-read it to show the change.\n await refetchPolicy();\n toast.success('Policy updated');\n setIsEditing(false);\n };\n\n const handleDelete = async () => {\n if (!policyId) return;\n try {\n await deletePolicy(policyId);\n if (isNative()) void nativeNotify('success');\n navigateTo('policies');\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n };\n\n const isActive = policy?.status === 'ACTIVE';\n\n const handleToggleActive = async () => {\n if (!policyId) return;\n const nextStatus = isActive ? 'DRAFT' : 'ACTIVE';\n try {\n await updatePolicy({ policyId, input: { status: nextStatus } });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to update policy');\n return;\n }\n await refetchPolicy();\n toast.success(\n nextStatus === 'ACTIVE' ? 'Policy is now enforced' : 'Policy is no longer enforced'\n );\n };\n\n const startEditing = () => {\n if (!policy) return;\n setEditData({\n name: policy.name,\n description: policy.description || '',\n visibility: toUnion(policy.visibility, VISIBILITIES, 'PRIVATE'),\n });\n setIsEditing(true);\n };\n\n if (isNew) {\n return (\n <PageLayout\n title=\"Create Policy\"\n description=\"Define guardrails and constraints for your AI agents\"\n actions={\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" onClick={() => navigateTo('policies')}>\n Cancel\n </Button>\n <Button\n leftIcon={<Save size={16} />}\n onClick={handleCreate}\n isLoading={createLoading}\n disabled={!formData.name}\n >\n Create\n </Button>\n </div>\n }\n >\n <div className=\"max-w-2xl space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Basic Information</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Policy Name\" required>\n <Input\n placeholder=\"e.g., Production Content Policy\"\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n\n <FormField label=\"Description\">\n <Textarea\n placeholder=\"What does this policy enforce?\"\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={3}\n />\n </FormField>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Policy Type\" required>\n <select\n className={SELECT_CLASS}\n value={formData.type}\n onChange={(e) => {\n const next = e.target.value as PolicyType;\n if (!isCreatablePolicyType(next)) return;\n setConfigError(null);\n setFormData({ ...formData, type: next });\n }}\n >\n {CREATABLE_POLICY_TYPES.map((type) => (\n <option key={type} value={type}>\n {PolicyTypeLabel[type]}\n </option>\n ))}\n </select>\n </FormField>\n\n <FormField label=\"Visibility\">\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n </div>\n </CardContent>\n </Card>\n\n {/* Policy-specific configuration: every field below is enforced at runtime. */}\n {formData.type === 'CONTENT' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <AlertTriangle size={18} />\n Content Policy Configuration\n </CardTitle>\n <CardDescription>\n Checked against every message sent to an agent and every response it gives. A\n blocked message is refused; a blocked response is replaced with a refusal.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"flex items-start gap-2\">\n <input\n type=\"checkbox\"\n id=\"pii\"\n checked={policyForm.content.piiDetection}\n onChange={(e) => updateForm('content', { piiDetection: e.target.checked })}\n className=\"mt-1 h-4 w-4\"\n />\n <label htmlFor=\"pii\" className=\"text-sm\">\n <span className=\"font-medium\">PII Detection</span>\n <span className=\"block text-text-secondary\">\n Blocks text containing an email address, a US SSN or a card-number shaped\n digit run.\n </span>\n </label>\n </div>\n\n <FormField\n label=\"Blocked Keywords\"\n description=\"Comma-separated. Case-insensitive; any occurrence blocks the text.\"\n >\n <Input\n placeholder=\"e.g., internal-only, project-x\"\n value={policyForm.content.blockedKeywords}\n onChange={(e) => updateForm('content', { blockedKeywords: e.target.value })}\n />\n </FormField>\n\n <FormField\n label=\"Blocked Patterns\"\n description=\"One regular expression per line, matched case-insensitively.\"\n >\n <Textarea\n placeholder=\"e.g., \\bACME-\\d{6}\\b\"\n value={policyForm.content.blockedPatterns}\n onChange={(e) => updateForm('content', { blockedPatterns: e.target.value })}\n rows={3}\n />\n </FormField>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'TOOL' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Wrench size={18} />\n Tool Policy Configuration\n </CardTitle>\n <CardDescription>\n Applies to MCP tool calls made by agents and through Call Tool, and to agent\n delegation. Leave a field empty to not restrict it.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField\n label=\"Allowed Tools\"\n description=\"Comma-separated MCP tool names. End an entry with * to allow a prefix. Empty allows every tool.\"\n >\n <Input\n placeholder=\"e.g., search, read_*\"\n value={policyForm.tool.allowedTools}\n onChange={(e) => updateForm('tool', { allowedTools: e.target.value })}\n />\n </FormField>\n\n <FormField\n label=\"Denied Tools\"\n description=\"Comma-separated MCP tool names that may never run. A deny always wins.\"\n >\n <Input\n placeholder=\"e.g., delete_*, execute_code\"\n value={policyForm.tool.deniedTools}\n onChange={(e) => updateForm('tool', { deniedTools: e.target.value })}\n />\n </FormField>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <FormField label=\"Max Tool Risk Level\">\n <select\n className={SELECT_CLASS}\n value={policyForm.tool.maxToolRiskLevel}\n onChange={(e) =>\n updateForm('tool', {\n maxToolRiskLevel: e.target\n .value as PolicyFormState['tool']['maxToolRiskLevel'],\n })\n }\n >\n <option value=\"\">Any risk level</option>\n {TOOL_RISK_LEVELS.map((level) => (\n <option key={level} value={level}>\n Up to {level.toLowerCase()}\n </option>\n ))}\n </select>\n </FormField>\n <FormField\n label=\"Minimum A2A Trust Level\"\n description=\"For delegation to external registry agents.\"\n >\n <select\n className={SELECT_CLASS}\n value={policyForm.tool.a2aMinTrustLevel}\n onChange={(e) =>\n updateForm('tool', {\n a2aMinTrustLevel: e.target\n .value as PolicyFormState['tool']['a2aMinTrustLevel'],\n })\n }\n >\n <option value=\"\">Default (verified publisher)</option>\n {A2A_TRUST_LEVELS.map((level) => (\n <option key={level} value={level}>\n {level === 'VERIFIED_PUBLISHER'\n ? 'Verified publisher'\n : level.charAt(0) + level.slice(1).toLowerCase()}\n </option>\n ))}\n </select>\n </FormField>\n </div>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <FormField\n label=\"Max Tool Calls Per Execution\"\n description=\"Tool calls allowed in one agent turn.\"\n >\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.tool.maxCallsPerExecution}\n onChange={(e) => updateForm('tool', { maxCallsPerExecution: e.target.value })}\n />\n </FormField>\n <FormField\n label=\"Tool Call Timeout (seconds)\"\n description=\"Can only shorten the platform's own timeout.\"\n >\n <Input\n type=\"number\"\n min={1}\n placeholder=\"Platform default\"\n value={policyForm.tool.timeoutSeconds}\n onChange={(e) => updateForm('tool', { timeoutSeconds: e.target.value })}\n />\n </FormField>\n </div>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'BUDGET' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <DollarSign size={18} />\n Budget Policy Configuration\n </CardTitle>\n <CardDescription>\n Token budgets apply per agent. Leave a field empty to not restrict it.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <FormField\n label=\"Max Tokens Per Day\"\n description=\"An agent that has used this many tokens today (UTC) is refused.\"\n >\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.budget.maxTokensPerDay}\n onChange={(e) => updateForm('budget', { maxTokensPerDay: e.target.value })}\n />\n </FormField>\n <FormField\n label=\"Max Output Tokens Per Model Call\"\n description=\"Lowers the agent's own max-tokens setting when it is higher.\"\n >\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.budget.maxTokensPerExecution}\n onChange={(e) =>\n updateForm('budget', { maxTokensPerExecution: e.target.value })\n }\n />\n </FormField>\n </div>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'RATE_LIMIT' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Clock size={18} />\n Rate Limit Configuration\n </CardTitle>\n <CardDescription>\n Every limit is counted per agent. Leave a field empty to not restrict it.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\n <FormField label=\"Requests / Minute\">\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.rateLimit.requestsPerMinute}\n onChange={(e) =>\n updateForm('rateLimit', { requestsPerMinute: e.target.value })\n }\n />\n </FormField>\n <FormField label=\"Requests / Hour\">\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.rateLimit.requestsPerHour}\n onChange={(e) => updateForm('rateLimit', { requestsPerHour: e.target.value })}\n />\n </FormField>\n <FormField label=\"Tokens / Minute\">\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.rateLimit.tokensPerMinute}\n onChange={(e) => updateForm('rateLimit', { tokensPerMinute: e.target.value })}\n />\n </FormField>\n </div>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'RESPONSE' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <FileText size={18} />\n Model Usage Allowlist\n </CardTitle>\n <CardDescription>\n Agents in this workspace may only answer with models that match every active model\n policy. Leave both fields empty to allow all models.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField\n label=\"Allowed Models\"\n description=\"Comma-separated model IDs. End an entry with * to allow a prefix.\"\n >\n <Input\n placeholder=\"e.g., gpt-4o-mini, anthropic.claude-*\"\n value={policyForm.response.allowedModels}\n onChange={(e) => updateForm('response', { allowedModels: e.target.value })}\n />\n </FormField>\n\n <FormField\n label=\"Allowed Providers\"\n description=\"Comma-separated provider types, e.g. OPENAI, ANTHROPIC, AWS_BEDROCK.\"\n >\n <Input\n placeholder=\"e.g., AWS_BEDROCK, ANTHROPIC\"\n value={policyForm.response.allowedProviders}\n onChange={(e) => updateForm('response', { allowedProviders: e.target.value })}\n />\n </FormField>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'RETENTION' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Trash2 size={18} />\n Retention Policy Configuration\n </CardTitle>\n <CardDescription>\n A scheduled job erases content older than these periods every hour. With several\n active retention policies the shortest period applies. Leave a field empty to keep\n that content for the life of the workspace.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <FormField\n label=\"Execution Data Retention (days)\"\n description=\"Inputs, outputs and errors of finished runs and agent-to-agent messages are erased this many days after the run ended; 0 keeps none. Run metrics stay.\"\n >\n <Input\n type=\"number\"\n min={0}\n max={MAX_RETENTION_DAYS}\n placeholder=\"Keep\"\n value={policyForm.retention.executionDataRetentionDays}\n onChange={(e) =>\n updateForm('retention', { executionDataRetentionDays: e.target.value })\n }\n />\n </FormField>\n <FormField\n label=\"Conversation Retention (days)\"\n description=\"Assistant conversations older than this are retired and erased.\"\n >\n <Input\n type=\"number\"\n min={1}\n max={MAX_RETENTION_DAYS}\n placeholder=\"Keep\"\n value={policyForm.retention.conversationRetentionDays}\n onChange={(e) =>\n updateForm('retention', { conversationRetentionDays: e.target.value })\n }\n />\n </FormField>\n </div>\n </CardContent>\n </Card>\n )}\n\n {configError && (\n <p className=\"text-sm text-status-error-text\" role=\"alert\">\n {configError}\n </p>\n )}\n\n <Card>\n <CardContent className=\"pt-6\">\n <div className=\"flex items-start gap-2\">\n <input\n type=\"checkbox\"\n id=\"activate-on-create\"\n checked={activateOnCreate}\n onChange={(e) => setActivateOnCreate(e.target.checked)}\n className=\"mt-1 h-4 w-4\"\n />\n <label htmlFor=\"activate-on-create\" className=\"text-sm\">\n <span className=\"font-medium\">Enforce immediately</span>\n <span className=\"block text-text-secondary\">\n Only active policies are enforced. Leave unchecked to save this policy as a\n draft and activate it later.\n </span>\n </label>\n </div>\n </CardContent>\n </Card>\n </div>\n </PageLayout>\n );\n }\n\n if (loading) {\n return (\n <PageLayout title=\"Loading...\">\n <div className=\"h-96 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\" />\n </PageLayout>\n );\n }\n\n if (!policy) {\n return (\n <PageLayout title=\"Policy Not Found\">\n <EmptyState\n illustration=\"empty-generic\"\n title=\"Policy Not Found\"\n description=\"This policy doesn't exist.\"\n action={<Button onClick={() => navigateTo('policies')}>Back to Policies</Button>}\n />\n </PageLayout>\n );\n }\n\n const policyType = toUnion(policy.type, POLICY_TYPES, 'CONTENT');\n const unenforced = unenforcedConfigKeys(policyType, policy.config);\n\n return (\n <PageLayout\n title={\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => navigateTo('policies')}>\n <ArrowLeft size={20} />\n </Button>\n <div className=\"p-2 rounded-lg bg-action-primary-bg/10\">\n <PolicyTypeIcon type={policyType} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <span>{policy.name}</span>\n <StatusBadge status={policy.status} />\n </div>\n <p className=\"text-sm font-normal text-text-secondary\">{policy.description}</p>\n </div>\n </div>\n }\n actions={\n <div className=\"flex gap-2\">\n {isEditing ? (\n <>\n <Button variant=\"outline\" onClick={() => setIsEditing(false)}>\n Cancel\n </Button>\n <Button\n leftIcon={<Save size={16} />}\n onClick={handleUpdate}\n isLoading={updateLoading}\n disabled={!editData.name}\n >\n Save Changes\n </Button>\n </>\n ) : (\n <>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.POLICY_UPDATE}>\n <Button\n variant={isActive ? 'outline' : 'default'}\n leftIcon={<Power size={16} />}\n onClick={() => void handleToggleActive()}\n isLoading={updateLoading}\n >\n {isActive ? 'Deactivate' : 'Activate'}\n </Button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.POLICY_UPDATE}>\n <Button variant=\"outline\" leftIcon={<Edit size={16} />} onClick={startEditing}>\n Edit\n </Button>\n </BotmanorPermissionGate>\n {showDeleteConfirm ? (\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => setShowDeleteConfirm(false)}>\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => {\n nativeImpact('medium');\n void handleDelete();\n }}\n isLoading={deleteLoading}\n >\n Confirm Delete\n </Button>\n </div>\n ) : (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.POLICY_DELETE}>\n <Button\n variant=\"destructive\"\n leftIcon={<Trash2 size={16} />}\n onClick={() => setShowDeleteConfirm(true)}\n >\n Delete\n </Button>\n </BotmanorPermissionGate>\n )}\n </>\n )}\n </div>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Shield size={18} />}>\n This is a single guardrail and its rules. Review and tune exactly what it enforces — what\n content to block, which tools are allowed, the spend or rate limits it applies — then\n attach it to the agents and bots that should obey it. Policies are how you keep agents\n safe, compliant and within budget.\n </PagePurpose>\n\n {/* Edit Form */}\n {isEditing && (\n <Card>\n <CardHeader>\n <CardTitle>Edit Policy</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Policy Name\" required>\n <Input\n value={editData.name}\n onChange={(e) => setEditData({ ...editData, name: e.target.value })}\n />\n </FormField>\n <FormField label=\"Description\">\n <Textarea\n value={editData.description}\n onChange={(e) => setEditData({ ...editData, description: e.target.value })}\n rows={3}\n />\n </FormField>\n <FormField label=\"Visibility\">\n <select\n className={SELECT_CLASS}\n value={editData.visibility}\n onChange={(e) =>\n setEditData({ ...editData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n <p className=\"text-sm text-text-secondary\">\n Note: Policy type and configuration cannot be changed after creation.\n </p>\n </CardContent>\n </Card>\n )}\n\n {/* Overview */}\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card treatment=\"glass\" glow>\n <CardContent className=\"pt-6 text-center\">\n <div className=\"p-3 rounded-full bg-action-primary-bg/10 w-fit mx-auto mb-2\">\n <PolicyTypeIcon type={policyType} />\n </div>\n <p className=\"text-lg font-bold\">{PolicyTypeLabel[policyType]}</p>\n <p className=\"text-sm text-text-secondary\">Policy Type</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-3xl font-bold text-text-primary capitalize\">\n {policy.visibility.toLowerCase()}\n </p>\n <p className=\"text-sm text-text-secondary\">Visibility</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-3xl font-bold text-text-primary\">{policy.revision}</p>\n <p className=\"text-sm text-text-secondary\">Revision</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-lg font-bold text-text-primary\">\n {formatRelativeTime(policy.updatedAt)}\n </p>\n <p className=\"text-sm text-text-secondary\">Last Updated</p>\n </CardContent>\n </Card>\n </div>\n\n {/* Configuration */}\n <Card>\n <CardHeader>\n <CardTitle>Configuration</CardTitle>\n <CardDescription>Current policy configuration</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {unenforced === null ? (\n <div\n className=\"flex items-start gap-2 p-3 bg-status-warning-bg-subtle rounded-lg text-sm\"\n data-testid=\"policy-not-enforced\"\n >\n <AlertTriangle size={16} className=\"mt-0.5 shrink-0 text-status-warning-text\" />\n <p>\n {PolicyTypeLabel[policyType]} settings are not enforced at runtime. This policy is\n kept for reference only and does not restrict any agent.\n </p>\n </div>\n ) : unenforced.length > 0 ? (\n <div\n className=\"flex items-start gap-2 p-3 bg-status-warning-bg-subtle rounded-lg text-sm\"\n data-testid=\"policy-ignored-keys\"\n >\n <AlertTriangle size={16} className=\"mt-0.5 shrink-0 text-status-warning-text\" />\n <p>\n These settings are not enforced at runtime and have no effect:{' '}\n <span className=\"font-mono\">{unenforced.join(', ')}</span>. Create a new policy to\n use the enforced settings.\n </p>\n </div>\n ) : null}\n <div className=\"p-4 bg-bg-sunken rounded-lg font-mono text-sm overflow-auto\">\n <pre>{JSON.stringify(policy.config, null, 2)}</pre>\n </div>\n </CardContent>\n </Card>\n\n {/* Metadata */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Settings size={18} />\n Metadata\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-6 text-sm\">\n <div>\n <p className=\"text-text-secondary\">Created</p>\n <p className=\"font-medium\">{formatRelativeTime(policy.createdAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Updated</p>\n <p className=\"font-medium\">{formatRelativeTime(policy.updatedAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Tags</p>\n <div className=\"flex gap-1\">\n {policy.tags.length > 0 ? (\n policy.tags.map((tag: string) => (\n <Badge key={tag} variant=\"secondary\" className=\"text-xs\">\n {tag}\n </Badge>\n ))\n ) : (\n <span className=\"text-text-secondary\">None</span>\n )}\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"PolicyDetailPage.js","names":["Textarea","_Fragment","Textarea$1","POLICY_TYPES","VISIBILITIES","SELECT_CLASS","PolicyTypeIcon","AlertTriangle","Wrench","Database","FileText","DollarSign","Clock","Trash2","type","Shield","PolicyTypeLabel","PolicyDetailPage","useParams","useBotlit","policy","refetchPolicy","usePolicy","isNew","policyId","createPolicy","createLoading","useCreatePolicy","updatePolicy","updateLoading","useUpdatePolicy","deletePolicy","deleteLoading","useDeletePolicy","isEditing","setIsEditing","useState","showDeleteConfirm","setShowDeleteConfirm","formData","setFormData","editData","setEditData","policyForm","setPolicyForm","EMPTY_POLICY_FORM","configError","setConfigError","updateForm","current","section","patch","activateOnCreate","setActivateOnCreate","handleCreate","built","buildPolicyConfig","toast","err","navigateTo","handleUpdate","handleDelete","isNative","nativeNotify","isActive","handleToggleActive","nextStatus","startEditing","toUnion","PageLayout","Button","Save","Card","CardHeader","CardTitle","CardContent","FormField","Input","next","isCreatablePolicyType","CREATABLE_POLICY_TYPES","CardDescription","TOOL_RISK_LEVELS","level","A2A_TRUST_LEVELS","loading","EmptyState","policyType","unenforced","unenforcedConfigKeys","ArrowLeft","StatusBadge","Fragment","BotmanorPermissionGate","BOTMANOR_PERMISSIONS","Power","Edit","nativeImpact","PagePurpose","formatRelativeTime","Settings","Badge","tag"],"sources":["../../../src/botlit/pages/PolicyDetailPage.tsx"],"sourcesContent":["/**\n * Policy Detail Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { useParams } from 'react-router';\nimport { toast } from 'sonner';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { isNative, nativeImpact, nativeNotify } from '../../utils/nativeBridge';\nimport {\n ArrowLeft,\n Shield,\n Settings,\n Save,\n AlertTriangle,\n Wrench,\n Database,\n FileText,\n DollarSign,\n Clock,\n Trash2,\n Edit,\n Power,\n} from 'lucide-react';\nimport { PageLayout } from '../components/PageLayout';\nimport { PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { EmptyState } from '../components/EmptyState';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input, Textarea, FormField } from '../components/Input';\nimport { StatusBadge, Badge } from '../components/Badge';\nimport { usePolicy, useCreatePolicy, useUpdatePolicy, useDeletePolicy } from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { toUnion } from '../utils/unions';\nimport type { PolicyType, Visibility } from '../types';\nimport {\n A2A_TRUST_LEVELS,\n CREATABLE_POLICY_TYPES,\n EMPTY_POLICY_FORM,\n MAX_RETENTION_DAYS,\n TOOL_RISK_LEVELS,\n buildPolicyConfig,\n isCreatablePolicyType,\n unenforcedConfigKeys,\n type CreatablePolicyType,\n type PolicyFormState,\n} from '../utils/policyConfig';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\n/**\n * Policy types the UI can render; the column itself is a free-form String.\n * DATA has no runtime evaluator: existing rows still render, but the editor\n * only creates CREATABLE_POLICY_TYPES (BOFF-9683). RETENTION is enforced by\n * the scheduled retention job (BOFF-9661).\n */\nconst POLICY_TYPES: PolicyType[] = [\n 'CONTENT',\n 'TOOL',\n 'DATA',\n 'RESPONSE',\n 'BUDGET',\n 'RATE_LIMIT',\n 'RETENTION',\n];\n\nconst VISIBILITIES: Visibility[] = ['PRIVATE', 'WORKSPACE', 'PUBLIC'];\n\nconst SELECT_CLASS =\n 'flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm';\n\ninterface PolicyDetailPageProps {\n isNew?: boolean;\n}\n\nconst PolicyTypeIcon: FC<{ type: PolicyType }> = ({ type }) => {\n const icons: Record<PolicyType, React.ReactElement> = {\n CONTENT: <AlertTriangle size={18} />,\n TOOL: <Wrench size={18} />,\n DATA: <Database size={18} />,\n RESPONSE: <FileText size={18} />,\n BUDGET: <DollarSign size={18} />,\n RATE_LIMIT: <Clock size={18} />,\n RETENTION: <Trash2 size={18} />,\n };\n return icons[type] || <Shield size={18} />;\n};\n\nconst PolicyTypeLabel: Record<PolicyType, string> = {\n CONTENT: 'Content Policy',\n TOOL: 'Tool Policy',\n DATA: 'Data Policy',\n RESPONSE: 'Response & Model Policy',\n BUDGET: 'Budget Policy',\n RATE_LIMIT: 'Rate Limit Policy',\n RETENTION: 'Retention Policy',\n};\n\nexport const PolicyDetailPage: FC<PolicyDetailPageProps> = ({ isNew }) => {\n const { policyId } = useParams();\n const { navigateTo } = useBotlit();\n const { data: policy, loading, refetch: refetchPolicy } = usePolicy(isNew ? undefined : policyId);\n const { create: createPolicy, loading: createLoading } = useCreatePolicy();\n const { update: updatePolicy, loading: updateLoading } = useUpdatePolicy();\n const { remove: deletePolicy, loading: deleteLoading } = useDeletePolicy();\n\n const [isEditing, setIsEditing] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n\n const [formData, setFormData] = useState({\n name: '',\n description: '',\n type: 'CONTENT' as CreatablePolicyType,\n visibility: 'PRIVATE' as Visibility,\n });\n\n // Edit-form fields: name, description and visibility of an existing policy.\n const [editData, setEditData] = useState({\n name: '',\n description: '',\n visibility: 'PRIVATE' as Visibility,\n });\n\n // Type-specific config. Every field maps to a key the runtime enforces.\n const [policyForm, setPolicyForm] = useState<PolicyFormState>(EMPTY_POLICY_FORM);\n const [configError, setConfigError] = useState<string | null>(null);\n\n const updateForm = <K extends keyof PolicyFormState>(\n section: K,\n patch: Partial<PolicyFormState[K]>\n ) => {\n setConfigError(null);\n setPolicyForm((current) => ({ ...current, [section]: { ...current[section], ...patch } }));\n };\n\n // New policies start as drafts unless the author chooses to enforce them now.\n const [activateOnCreate, setActivateOnCreate] = useState(false);\n\n const handleCreate = async () => {\n if (!formData.name) return;\n\n const built = buildPolicyConfig(formData.type, policyForm);\n if (!built.ok) {\n setConfigError(built.error);\n toast.error(built.error);\n return;\n }\n\n try {\n await createPolicy({\n name: formData.name,\n description: formData.description,\n type: formData.type,\n visibility: formData.visibility,\n status: activateOnCreate ? 'ACTIVE' : 'DRAFT',\n config: built.config as Record<string, unknown>,\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to create policy');\n return;\n }\n toast.success(`Policy \"${formData.name}\" created`);\n navigateTo('policies');\n };\n\n const handleUpdate = async () => {\n if (!policyId || !editData.name) return;\n try {\n await updatePolicy({\n policyId,\n input: {\n name: editData.name,\n description: editData.description,\n visibility: editData.visibility,\n },\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to update policy');\n return;\n }\n // The policy query is network-only local state, so re-read it to show the change.\n await refetchPolicy();\n toast.success('Policy updated');\n setIsEditing(false);\n };\n\n const handleDelete = async () => {\n if (!policyId) return;\n try {\n await deletePolicy(policyId);\n if (isNative()) void nativeNotify('success');\n navigateTo('policies');\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n };\n\n const isActive = policy?.status === 'ACTIVE';\n\n const handleToggleActive = async () => {\n if (!policyId) return;\n const nextStatus = isActive ? 'DRAFT' : 'ACTIVE';\n try {\n await updatePolicy({ policyId, input: { status: nextStatus } });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to update policy');\n return;\n }\n await refetchPolicy();\n toast.success(\n nextStatus === 'ACTIVE' ? 'Policy is now enforced' : 'Policy is no longer enforced'\n );\n };\n\n const startEditing = () => {\n if (!policy) return;\n setEditData({\n name: policy.name,\n description: policy.description || '',\n visibility: toUnion(policy.visibility, VISIBILITIES, 'PRIVATE'),\n });\n setIsEditing(true);\n };\n\n if (isNew) {\n return (\n <PageLayout\n title=\"Create Policy\"\n description=\"Define guardrails and constraints for your AI agents\"\n actions={\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" onClick={() => navigateTo('policies')}>\n Cancel\n </Button>\n <Button\n leftIcon={<Save size={16} />}\n onClick={handleCreate}\n isLoading={createLoading}\n disabled={!formData.name}\n >\n Create\n </Button>\n </div>\n }\n >\n <div className=\"max-w-2xl space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Basic Information</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Policy Name\" required>\n <Input\n placeholder=\"e.g., Production Content Policy\"\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n\n <FormField label=\"Description\">\n <Textarea\n placeholder=\"What does this policy enforce?\"\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={3}\n />\n </FormField>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Policy Type\" required>\n <select\n className={SELECT_CLASS}\n value={formData.type}\n onChange={(e) => {\n const next = e.target.value as PolicyType;\n if (!isCreatablePolicyType(next)) return;\n setConfigError(null);\n setFormData({ ...formData, type: next });\n }}\n >\n {CREATABLE_POLICY_TYPES.map((type) => (\n <option key={type} value={type}>\n {PolicyTypeLabel[type]}\n </option>\n ))}\n </select>\n </FormField>\n\n <FormField label=\"Visibility\">\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n </div>\n </CardContent>\n </Card>\n\n {/* Policy-specific configuration: every field below is enforced at runtime. */}\n {formData.type === 'CONTENT' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <AlertTriangle size={18} />\n Content Policy Configuration\n </CardTitle>\n <CardDescription>\n Checked against every message sent to an agent and every response it gives. A\n blocked message is refused; a blocked response is replaced with a refusal.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"flex items-start gap-2\">\n <input\n type=\"checkbox\"\n id=\"pii\"\n checked={policyForm.content.piiDetection}\n onChange={(e) => updateForm('content', { piiDetection: e.target.checked })}\n className=\"mt-1 h-4 w-4\"\n />\n <label htmlFor=\"pii\" className=\"text-sm\">\n <span className=\"font-medium\">PII Detection</span>\n <span className=\"block text-text-secondary\">\n Blocks text containing an email address, a US SSN or a card-number shaped\n digit run.\n </span>\n </label>\n </div>\n\n <FormField\n label=\"Blocked Keywords\"\n description=\"Comma-separated. Case-insensitive; any occurrence blocks the text.\"\n >\n <Input\n placeholder=\"e.g., internal-only, project-x\"\n value={policyForm.content.blockedKeywords}\n onChange={(e) => updateForm('content', { blockedKeywords: e.target.value })}\n />\n </FormField>\n\n <FormField\n label=\"Blocked Patterns\"\n description=\"One regular expression per line, matched case-insensitively.\"\n >\n <Textarea\n placeholder=\"e.g., \\bACME-\\d{6}\\b\"\n value={policyForm.content.blockedPatterns}\n onChange={(e) => updateForm('content', { blockedPatterns: e.target.value })}\n rows={3}\n />\n </FormField>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'TOOL' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Wrench size={18} />\n Tool Policy Configuration\n </CardTitle>\n <CardDescription>\n Applies to MCP tool calls made by agents and through Call Tool, and to agent\n delegation. Leave a field empty to not restrict it.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField\n label=\"Allowed Tools\"\n description=\"Comma-separated MCP tool names. End an entry with * to allow a prefix. Empty allows every tool.\"\n >\n <Input\n placeholder=\"e.g., search, read_*\"\n value={policyForm.tool.allowedTools}\n onChange={(e) => updateForm('tool', { allowedTools: e.target.value })}\n />\n </FormField>\n\n <FormField\n label=\"Denied Tools\"\n description=\"Comma-separated MCP tool names that may never run. A deny always wins.\"\n >\n <Input\n placeholder=\"e.g., delete_*, execute_code\"\n value={policyForm.tool.deniedTools}\n onChange={(e) => updateForm('tool', { deniedTools: e.target.value })}\n />\n </FormField>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <FormField label=\"Max Tool Risk Level\">\n <select\n className={SELECT_CLASS}\n value={policyForm.tool.maxToolRiskLevel}\n onChange={(e) =>\n updateForm('tool', {\n maxToolRiskLevel: e.target\n .value as PolicyFormState['tool']['maxToolRiskLevel'],\n })\n }\n >\n <option value=\"\">Any risk level</option>\n {TOOL_RISK_LEVELS.map((level) => (\n <option key={level} value={level}>\n Up to {level.toLowerCase()}\n </option>\n ))}\n </select>\n </FormField>\n <FormField\n label=\"Minimum A2A Trust Level\"\n description=\"For delegation to external registry agents.\"\n >\n <select\n className={SELECT_CLASS}\n value={policyForm.tool.a2aMinTrustLevel}\n onChange={(e) =>\n updateForm('tool', {\n a2aMinTrustLevel: e.target\n .value as PolicyFormState['tool']['a2aMinTrustLevel'],\n })\n }\n >\n <option value=\"\">Default (verified publisher)</option>\n {A2A_TRUST_LEVELS.map((level) => (\n <option key={level} value={level}>\n {level === 'VERIFIED_PUBLISHER'\n ? 'Verified publisher'\n : level.charAt(0) + level.slice(1).toLowerCase()}\n </option>\n ))}\n </select>\n </FormField>\n </div>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <FormField\n label=\"Max Tool Calls Per Execution\"\n description=\"Tool calls allowed in one agent turn.\"\n >\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.tool.maxCallsPerExecution}\n onChange={(e) => updateForm('tool', { maxCallsPerExecution: e.target.value })}\n />\n </FormField>\n <FormField\n label=\"Tool Call Timeout (seconds)\"\n description=\"Can only shorten the platform's own timeout.\"\n >\n <Input\n type=\"number\"\n min={1}\n placeholder=\"Platform default\"\n value={policyForm.tool.timeoutSeconds}\n onChange={(e) => updateForm('tool', { timeoutSeconds: e.target.value })}\n />\n </FormField>\n </div>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'BUDGET' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <DollarSign size={18} />\n Budget Policy Configuration\n </CardTitle>\n <CardDescription>\n Token budgets apply per agent. Leave a field empty to not restrict it.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <FormField\n label=\"Max Tokens Per Day\"\n description=\"An agent that has used this many tokens today (UTC) is refused.\"\n >\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.budget.maxTokensPerDay}\n onChange={(e) => updateForm('budget', { maxTokensPerDay: e.target.value })}\n />\n </FormField>\n <FormField\n label=\"Max Output Tokens Per Model Call\"\n description=\"Lowers the agent's own max-tokens setting when it is higher.\"\n >\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.budget.maxTokensPerExecution}\n onChange={(e) =>\n updateForm('budget', { maxTokensPerExecution: e.target.value })\n }\n />\n </FormField>\n </div>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'RATE_LIMIT' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Clock size={18} />\n Rate Limit Configuration\n </CardTitle>\n <CardDescription>\n Every limit is counted per agent. Leave a field empty to not restrict it.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\n <FormField label=\"Requests / Minute\">\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.rateLimit.requestsPerMinute}\n onChange={(e) =>\n updateForm('rateLimit', { requestsPerMinute: e.target.value })\n }\n />\n </FormField>\n <FormField label=\"Requests / Hour\">\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.rateLimit.requestsPerHour}\n onChange={(e) => updateForm('rateLimit', { requestsPerHour: e.target.value })}\n />\n </FormField>\n <FormField label=\"Tokens / Minute\">\n <Input\n type=\"number\"\n min={1}\n placeholder=\"No limit\"\n value={policyForm.rateLimit.tokensPerMinute}\n onChange={(e) => updateForm('rateLimit', { tokensPerMinute: e.target.value })}\n />\n </FormField>\n </div>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'RESPONSE' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <FileText size={18} />\n Model Usage Allowlist\n </CardTitle>\n <CardDescription>\n Agents in this workspace may only answer with models that match every active model\n policy. Leave both fields empty to allow all models.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField\n label=\"Allowed Models\"\n description=\"Comma-separated model IDs. End an entry with * to allow a prefix.\"\n >\n <Input\n placeholder=\"e.g., gpt-4o-mini, anthropic.claude-*\"\n value={policyForm.response.allowedModels}\n onChange={(e) => updateForm('response', { allowedModels: e.target.value })}\n />\n </FormField>\n\n <FormField\n label=\"Allowed Providers\"\n description=\"Comma-separated provider types, e.g. OPENAI, ANTHROPIC, AWS_BEDROCK.\"\n >\n <Input\n placeholder=\"e.g., AWS_BEDROCK, ANTHROPIC\"\n value={policyForm.response.allowedProviders}\n onChange={(e) => updateForm('response', { allowedProviders: e.target.value })}\n />\n </FormField>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'RETENTION' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Trash2 size={18} />\n Retention Policy Configuration\n </CardTitle>\n <CardDescription>\n A scheduled job erases content older than these periods every hour. With several\n active retention policies the shortest period applies. Leave a field empty to keep\n that content for the life of the workspace.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <FormField\n label=\"Execution Data Retention (days)\"\n description=\"Inputs, outputs and errors of finished runs and agent-to-agent messages are erased this many days after the run ended; 0 keeps none. Run metrics stay.\"\n >\n <Input\n type=\"number\"\n min={0}\n max={MAX_RETENTION_DAYS}\n placeholder=\"Keep\"\n value={policyForm.retention.executionDataRetentionDays}\n onChange={(e) =>\n updateForm('retention', { executionDataRetentionDays: e.target.value })\n }\n />\n </FormField>\n <FormField\n label=\"Conversation Retention (days)\"\n description=\"Assistant conversations older than this are retired and erased.\"\n >\n <Input\n type=\"number\"\n min={1}\n max={MAX_RETENTION_DAYS}\n placeholder=\"Keep\"\n value={policyForm.retention.conversationRetentionDays}\n onChange={(e) =>\n updateForm('retention', { conversationRetentionDays: e.target.value })\n }\n />\n </FormField>\n </div>\n </CardContent>\n </Card>\n )}\n\n {configError && (\n <p className=\"text-sm text-status-error-text\" role=\"alert\">\n {configError}\n </p>\n )}\n\n <Card>\n <CardContent className=\"pt-6\">\n <div className=\"flex items-start gap-2\">\n <input\n type=\"checkbox\"\n id=\"activate-on-create\"\n checked={activateOnCreate}\n onChange={(e) => setActivateOnCreate(e.target.checked)}\n className=\"mt-1 h-4 w-4\"\n />\n <label htmlFor=\"activate-on-create\" className=\"text-sm\">\n <span className=\"font-medium\">Enforce immediately</span>\n <span className=\"block text-text-secondary\">\n Only active policies are enforced. Leave unchecked to save this policy as a\n draft and activate it later.\n </span>\n </label>\n </div>\n </CardContent>\n </Card>\n </div>\n </PageLayout>\n );\n }\n\n if (loading) {\n return (\n <PageLayout title=\"Loading...\">\n <div className=\"h-96 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\" />\n </PageLayout>\n );\n }\n\n if (!policy) {\n return (\n <PageLayout title=\"Policy Not Found\">\n <EmptyState\n illustration=\"empty-generic\"\n title=\"Policy Not Found\"\n description=\"This policy doesn't exist.\"\n action={<Button onClick={() => navigateTo('policies')}>Back to Policies</Button>}\n />\n </PageLayout>\n );\n }\n\n const policyType = toUnion(policy.type, POLICY_TYPES, 'CONTENT');\n const unenforced = unenforcedConfigKeys(policyType, policy.config);\n\n return (\n <PageLayout\n title={\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => navigateTo('policies')}>\n <ArrowLeft size={20} />\n </Button>\n <div className=\"p-2 rounded-lg bg-action-primary-bg/10\">\n <PolicyTypeIcon type={policyType} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <span>{policy.name}</span>\n <StatusBadge status={policy.status} />\n </div>\n <p className=\"text-sm font-normal text-text-secondary\">{policy.description}</p>\n </div>\n </div>\n }\n actions={\n <div className=\"flex gap-2\">\n {isEditing ? (\n <>\n <Button variant=\"outline\" onClick={() => setIsEditing(false)}>\n Cancel\n </Button>\n <Button\n leftIcon={<Save size={16} />}\n onClick={handleUpdate}\n isLoading={updateLoading}\n disabled={!editData.name}\n >\n Save Changes\n </Button>\n </>\n ) : (\n <>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.POLICY_UPDATE}>\n <Button\n variant={isActive ? 'outline' : 'default'}\n leftIcon={<Power size={16} />}\n onClick={() => void handleToggleActive()}\n isLoading={updateLoading}\n >\n {isActive ? 'Deactivate' : 'Activate'}\n </Button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.POLICY_UPDATE}>\n <Button variant=\"outline\" leftIcon={<Edit size={16} />} onClick={startEditing}>\n Edit\n </Button>\n </BotmanorPermissionGate>\n {showDeleteConfirm ? (\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => setShowDeleteConfirm(false)}>\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => {\n nativeImpact('medium');\n void handleDelete();\n }}\n isLoading={deleteLoading}\n >\n Confirm Delete\n </Button>\n </div>\n ) : (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.POLICY_DELETE}>\n <Button\n variant=\"destructive\"\n leftIcon={<Trash2 size={16} />}\n onClick={() => setShowDeleteConfirm(true)}\n >\n Delete\n </Button>\n </BotmanorPermissionGate>\n )}\n </>\n )}\n </div>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Shield size={18} />}>\n This is a single guardrail and its rules. Review and tune exactly what it enforces — what\n content to block, which tools are allowed, the spend or rate limits it applies — then\n attach it to the agents and bots that should obey it. Policies are how you keep agents\n safe, compliant and within budget.\n </PagePurpose>\n\n {/* Edit Form */}\n {isEditing && (\n <Card>\n <CardHeader>\n <CardTitle>Edit Policy</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Policy Name\" required>\n <Input\n value={editData.name}\n onChange={(e) => setEditData({ ...editData, name: e.target.value })}\n />\n </FormField>\n <FormField label=\"Description\">\n <Textarea\n value={editData.description}\n onChange={(e) => setEditData({ ...editData, description: e.target.value })}\n rows={3}\n />\n </FormField>\n <FormField label=\"Visibility\">\n <select\n className={SELECT_CLASS}\n value={editData.visibility}\n onChange={(e) =>\n setEditData({ ...editData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n <p className=\"text-sm text-text-secondary\">\n Note: Policy type and configuration cannot be changed after creation.\n </p>\n </CardContent>\n </Card>\n )}\n\n {/* Overview */}\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card treatment=\"glass\" glow>\n <CardContent className=\"pt-6 text-center\">\n <div className=\"p-3 rounded-full bg-action-primary-bg/10 w-fit mx-auto mb-2\">\n <PolicyTypeIcon type={policyType} />\n </div>\n <p className=\"text-lg font-bold\">{PolicyTypeLabel[policyType]}</p>\n <p className=\"text-sm text-text-secondary\">Policy Type</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-3xl font-bold text-text-primary capitalize\">\n {policy.visibility.toLowerCase()}\n </p>\n <p className=\"text-sm text-text-secondary\">Visibility</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-3xl font-bold text-text-primary\">{policy.revision}</p>\n <p className=\"text-sm text-text-secondary\">Revision</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-lg font-bold text-text-primary\">\n {formatRelativeTime(policy.updatedAt)}\n </p>\n <p className=\"text-sm text-text-secondary\">Last Updated</p>\n </CardContent>\n </Card>\n </div>\n\n {/* Configuration */}\n <Card>\n <CardHeader>\n <CardTitle>Configuration</CardTitle>\n <CardDescription>Current policy configuration</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {unenforced === null ? (\n <div\n className=\"flex items-start gap-2 p-3 bg-status-warning-bg-subtle rounded-lg text-sm\"\n data-testid=\"policy-not-enforced\"\n >\n <AlertTriangle size={16} className=\"mt-0.5 shrink-0 text-status-warning-text\" />\n <p>\n {PolicyTypeLabel[policyType]} settings are not enforced at runtime. This policy is\n kept for reference only and does not restrict any agent.\n </p>\n </div>\n ) : unenforced.length > 0 ? (\n <div\n className=\"flex items-start gap-2 p-3 bg-status-warning-bg-subtle rounded-lg text-sm\"\n data-testid=\"policy-ignored-keys\"\n >\n <AlertTriangle size={16} className=\"mt-0.5 shrink-0 text-status-warning-text\" />\n <p>\n These settings are not enforced at runtime and have no effect:{' '}\n <span className=\"font-mono\">{unenforced.join(', ')}</span>. Create a new policy to\n use the enforced settings.\n </p>\n </div>\n ) : null}\n <div className=\"p-4 bg-bg-sunken rounded-lg font-mono text-sm overflow-auto\">\n <pre>{JSON.stringify(policy.config, null, 2)}</pre>\n </div>\n </CardContent>\n </Card>\n\n {/* Metadata */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Settings size={18} />\n Metadata\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-6 text-sm\">\n <div>\n <p className=\"text-text-secondary\">Created</p>\n <p className=\"font-medium\">{formatRelativeTime(policy.createdAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Updated</p>\n <p className=\"font-medium\">{formatRelativeTime(policy.updatedAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Tags</p>\n <div className=\"flex gap-1\">\n {policy.tags.length > 0 ? (\n policy.tags.map((tag: string) => (\n <Badge key={tag} variant=\"secondary\" className=\"text-xs\">\n {tag}\n </Badge>\n ))\n ) : (\n <span className=\"text-text-secondary\">None</span>\n )}\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { FC } from 'react';
2
+ export declare const PromptStudioPage: FC;
@@ -1,24 +1,24 @@
1
- import { useBotlit as e } from "../providers/BotlitProvider.js";
2
- import { graphqlErrorMessage as t } from "../utils/errors.js";
3
- import { formatRelativeTime as n } from "../utils/formatters.js";
4
- import { BOTMANOR_PERMISSIONS as r } from "../permissions/botmanorPermissions.js";
5
- import { BotmanorPermissionGate as i } from "../permissions/useBotmanorPermissions.js";
6
- import { PageLayout as a } from "../components/PageLayout.js";
1
+ import { PageLayout as e } from "../components/PageLayout.js";
2
+ import { Card as t, CardContent as n, CardDescription as r, CardHeader as i, CardTitle as a } from "../components/Card.js";
7
3
  import { Button as o } from "../components/Button.js";
8
- import "../permissions/index.js";
9
- import { Card as s, CardContent as c, CardDescription as l, CardHeader as u, CardTitle as d } from "../components/Card.js";
4
+ import { BOTMANOR_PERMISSIONS as s } from "../permissions/botmanorPermissions.js";
5
+ import { BotmanorPermissionGate as c } from "../permissions/useBotmanorPermissions.js";
6
+ import { FormField as l, Input as u, Textarea as d } from "../components/Input.js";
10
7
  import { Badge as f } from "../components/Badge.js";
11
8
  import { EmptyState as p } from "../components/EmptyState.js";
12
- import { FormField as m, Input as h, Textarea as g } from "../components/Input.js";
13
- import { ErrorState as _ } from "../components/ErrorState.js";
14
- import { promptTemplateVariables as v, usePromptTemplates as y, useRenderPromptTemplate as b } from "../hooks/usePromptTemplates.js";
9
+ import { ErrorState as m } from "../components/ErrorState.js";
10
+ import { useBotlit as h } from "../providers/BotlitProvider.js";
15
11
  import "../hooks/index.js";
12
+ import { graphqlErrorMessage as g } from "../utils/errors.js";
13
+ import { formatRelativeTime as _ } from "../utils/formatters.js";
14
+ import { promptTemplateVariables as v, usePromptTemplates as y, useRenderPromptTemplate as b } from "../hooks/usePromptTemplates.js";
15
+ import "../permissions/index.js";
16
16
  import { useEffect as x, useMemo as S, useState as C } from "react";
17
17
  import { GlassCard as w, PagePurpose as T } from "@burdenoff/fe-libs/ui";
18
18
  import { jsx as E, jsxs as D } from "react/jsx-runtime";
19
19
  import { Play as O, Plus as k, Tag as A } from "lucide-react";
20
20
  import { toast as j } from "sonner";
21
- //#region src/botlit/pages/PromptStudioPage.tsx
21
+ // src/botlit/pages/PromptStudioPage.tsx
22
22
  function M(e) {
23
23
  if (!e || typeof e != "object" || Array.isArray(e)) return null;
24
24
  let t = e, n = typeof t.name == "string" ? t.name : void 0;
@@ -34,25 +34,26 @@ function N(e) {
34
34
  return e ? v(e).map(M).filter((e) => e !== null) : [];
35
35
  }
36
36
  var P = () => {
37
- let { navigateTo: v } = e(), { data: M, loading: P, error: F, refetch: I } = y(), { render: L, loading: R } = b(), [z, B] = C(null), [V, H] = C({}), [U, W] = C("");
37
+ let { navigateTo: v } = h(), { data: M, loading: P, error: F, refetch: I } = y(), { render: L, loading: R } = b(), [z, B] = C(null), [V, H] = C({}), [U, W] = C("");
38
38
  x(() => {
39
39
  !z && M.length > 0 && B(M[0].id);
40
40
  }, [M, z]);
41
41
  let G = S(() => M.find((e) => e.id === z), [M, z]), K = S(() => N(G), [G]), q = async () => {
42
42
  if (G) try {
43
- W(await L({
43
+ let e = await L({
44
44
  templateId: G.id,
45
45
  variables: V
46
- }));
46
+ });
47
+ W(e);
47
48
  } catch (e) {
48
- j.error(t(e, "Failed to render prompt"));
49
+ j.error(g(e, "Failed to render prompt"));
49
50
  }
50
51
  };
51
- return /* @__PURE__ */ E(a, {
52
+ return /* @__PURE__ */ E(e, {
52
53
  title: "Prompt Studio",
53
54
  description: "Create, test, and manage prompts for your AI agents",
54
- actions: /* @__PURE__ */ E(i, {
55
- permission: r.PROMPT_TEMPLATE_CREATE,
55
+ actions: /* @__PURE__ */ E(c, {
56
+ permission: s.PROMPT_TEMPLATE_CREATE,
56
57
  children: /* @__PURE__ */ E(o, {
57
58
  leftIcon: /* @__PURE__ */ E(k, { size: 16 }),
58
59
  onClick: () => v("prompt-templates/new"),
@@ -69,10 +70,10 @@ var P = () => {
69
70
  children: [
70
71
  /* @__PURE__ */ E("div", {
71
72
  className: "col-span-3",
72
- children: /* @__PURE__ */ D(s, { children: [/* @__PURE__ */ E(u, { children: /* @__PURE__ */ E(d, {
73
+ children: /* @__PURE__ */ D(t, { children: [/* @__PURE__ */ E(i, { children: /* @__PURE__ */ E(a, {
73
74
  className: "text-base",
74
75
  children: "Prompts"
75
- }) }), /* @__PURE__ */ E(c, {
76
+ }) }), /* @__PURE__ */ E(n, {
76
77
  className: "p-0",
77
78
  children: P ? /* @__PURE__ */ E("div", {
78
79
  className: "space-y-2 p-4",
@@ -81,7 +82,7 @@ var P = () => {
81
82
  2,
82
83
  3
83
84
  ].map((e) => /* @__PURE__ */ E("div", { className: "h-14 bg-bg-sunken motion-safe:animate-vc-shimmer rounded" }, e))
84
- }) : F ? /* @__PURE__ */ E(_, {
85
+ }) : F ? /* @__PURE__ */ E(m, {
85
86
  resource: "prompt templates",
86
87
  error: F,
87
88
  onRetry: () => void I(),
@@ -128,15 +129,15 @@ var P = () => {
128
129
  treatment: "glass",
129
130
  glow: !0,
130
131
  className: "overflow-hidden",
131
- children: [/* @__PURE__ */ D(u, {
132
+ children: [/* @__PURE__ */ D(i, {
132
133
  className: "flex flex-row items-center justify-between",
133
- children: [/* @__PURE__ */ D("div", { children: [/* @__PURE__ */ E(d, { children: G.name }), /* @__PURE__ */ E(l, { children: G.description })] }), /* @__PURE__ */ E(o, {
134
+ children: [/* @__PURE__ */ D("div", { children: [/* @__PURE__ */ E(a, { children: G.name }), /* @__PURE__ */ E(r, { children: G.description })] }), /* @__PURE__ */ E(o, {
134
135
  size: "sm",
135
136
  variant: "outline",
136
137
  onClick: () => v(`prompt-templates/${G.id}`),
137
138
  children: "Open template"
138
139
  })]
139
- }), /* @__PURE__ */ D(c, {
140
+ }), /* @__PURE__ */ D(n, {
140
141
  className: "space-y-4",
141
142
  children: [
142
143
  /* @__PURE__ */ D("div", {
@@ -149,9 +150,9 @@ var P = () => {
149
150
  children: e
150
151
  }, e))]
151
152
  }),
152
- /* @__PURE__ */ E(m, {
153
+ /* @__PURE__ */ E(l, {
153
154
  label: "Prompt Content",
154
- children: /* @__PURE__ */ E(g, {
155
+ children: /* @__PURE__ */ E(d, {
155
156
  value: G.templateText,
156
157
  rows: 15,
157
158
  readOnly: !0,
@@ -186,7 +187,7 @@ var P = () => {
186
187
  })] }),
187
188
  /* @__PURE__ */ D("div", {
188
189
  className: "pt-4 text-xs text-text-secondary",
189
- children: ["Updated ", n(G.updatedAt)]
190
+ children: ["Updated ", _(G.updatedAt)]
190
191
  })
191
192
  ]
192
193
  })]
@@ -198,15 +199,15 @@ var P = () => {
198
199
  }),
199
200
  /* @__PURE__ */ E("div", {
200
201
  className: "col-span-3",
201
- children: /* @__PURE__ */ D(s, { children: [/* @__PURE__ */ E(u, { children: /* @__PURE__ */ D(d, {
202
+ children: /* @__PURE__ */ D(t, { children: [/* @__PURE__ */ E(i, { children: /* @__PURE__ */ D(a, {
202
203
  className: "text-base flex items-center gap-2",
203
204
  children: [/* @__PURE__ */ E(O, { size: 16 }), "Test Prompt"]
204
- }) }), /* @__PURE__ */ D(c, {
205
+ }) }), /* @__PURE__ */ D(n, {
205
206
  className: "space-y-4",
206
207
  children: [
207
- K.map((e) => /* @__PURE__ */ E(m, {
208
+ K.map((e) => /* @__PURE__ */ E(l, {
208
209
  label: e.name,
209
- children: /* @__PURE__ */ E(h, {
210
+ children: /* @__PURE__ */ E(u, {
210
211
  placeholder: e.description || `Enter ${e.name}`,
211
212
  value: V[e.name] || "",
212
213
  onChange: (t) => H({
@@ -215,8 +216,8 @@ var P = () => {
215
216
  })
216
217
  })
217
218
  }, e.name)),
218
- /* @__PURE__ */ E(i, {
219
- permission: r.PROMPT_TEMPLATE_EXECUTE,
219
+ /* @__PURE__ */ E(c, {
220
+ permission: s.PROMPT_TEMPLATE_EXECUTE,
220
221
  children: /* @__PURE__ */ E(o, {
221
222
  className: "w-full",
222
223
  onClick: () => void q(),
@@ -240,7 +241,6 @@ var P = () => {
240
241
  })
241
242
  });
242
243
  };
243
- //#endregion
244
244
  export { P as PromptStudioPage };
245
245
 
246
246
  //# sourceMappingURL=PromptStudioPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PromptStudioPage.js","names":[],"sources":["../../../src/botlit/pages/PromptStudioPage.tsx"],"sourcesContent":["/**\n * Prompt Studio Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Plus, Play, Tag } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input, Textarea, FormField } from '../components/Input';\nimport { Badge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n usePromptTemplates,\n useRenderPromptTemplate,\n promptTemplateVariables,\n type PromptTemplateRecord,\n} from '../hooks';\nimport { graphqlErrorMessage } from '../utils/errors';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { PromptVariable } from '../types';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\n/** Normalises one entry of a template's free-form `variables` JSON. */\nfunction toPromptVariable(value: unknown): PromptVariable | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return null;\n const record = value as Record<string, unknown>;\n const name = typeof record.name === 'string' ? record.name : undefined;\n if (!name) return null;\n const type = typeof record.type === 'string' ? record.type : 'string';\n return {\n name,\n type: type as PromptVariable['type'],\n description: typeof record.description === 'string' ? record.description : undefined,\n required: record.required === true,\n defaultValue: record.defaultValue,\n };\n}\n\nfunction templateVariables(template: PromptTemplateRecord | undefined): PromptVariable[] {\n if (!template) return [];\n return promptTemplateVariables(template)\n .map(toPromptVariable)\n .filter((variable): variable is PromptVariable => variable !== null);\n}\n\nexport const PromptStudioPage: FC = () => {\n const { navigateTo } = useBotlit();\n const { data: templates, loading, error, refetch } = usePromptTemplates();\n const { render, loading: isRunning } = useRenderPromptTemplate();\n\n const [selectedPromptId, setSelectedPromptId] = useState<string | null>(null);\n const [testVariables, setTestVariables] = useState<Record<string, string>>({});\n const [testOutput, setTestOutput] = useState('');\n\n // Select the first template once the list arrives.\n useEffect(() => {\n if (!selectedPromptId && templates.length > 0) {\n setSelectedPromptId(templates[0].id);\n }\n }, [templates, selectedPromptId]);\n\n const selectedPrompt = useMemo(\n () => templates.find((template) => template.id === selectedPromptId),\n [templates, selectedPromptId]\n );\n\n const selectedVariables = useMemo(() => templateVariables(selectedPrompt), [selectedPrompt]);\n\n const handleTest = async () => {\n if (!selectedPrompt) return;\n try {\n // Rendered by wspace-botlit-svc so the preview matches what the agent\n // actually receives — never a client-side string substitution.\n const output = await render({\n templateId: selectedPrompt.id,\n variables: testVariables,\n });\n setTestOutput(output);\n } catch (err) {\n toast.error(graphqlErrorMessage(err, 'Failed to render prompt'));\n }\n };\n\n return (\n <PageLayout\n title=\"Prompt Studio\"\n description=\"Create, test, and manage prompts for your AI agents\"\n actions={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.PROMPT_TEMPLATE_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => navigateTo('prompt-templates/new')}>\n New Prompt\n </Button>\n </BotmanorPermissionGate>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Play size={18} />}>\n Prompt Studio is your interactive workbench for writing and testing prompts before they go\n live. Pick a prompt, edit its text and variables on the left, then fill in sample values\n and hit Run Test to preview exactly what the agent will receive — so you can iterate on\n wording and catch mistakes here instead of in production.\n </PagePurpose>\n\n <div className=\"grid grid-cols-12 gap-6\">\n {/* Prompt List */}\n <div className=\"col-span-3\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Prompts</CardTitle>\n </CardHeader>\n <CardContent className=\"p-0\">\n {loading ? (\n <div className=\"space-y-2 p-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-14 bg-bg-sunken motion-safe:animate-vc-shimmer rounded\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState\n resource=\"prompt templates\"\n error={error}\n onRetry={() => void refetch()}\n className=\"m-4\"\n />\n ) : templates.length === 0 ? (\n <p className=\"p-4 text-sm text-text-secondary\">\n No prompt templates yet. Create one to start iterating.\n </p>\n ) : (\n <div className=\"divide-y divide-border-subtle\">\n {templates.map((prompt: PromptTemplateRecord) => (\n <button\n key={prompt.id}\n type=\"button\"\n className={`w-full text-left p-4 hover:bg-accent transition-colors ${\n selectedPrompt?.id === prompt.id ? 'bg-accent' : ''\n }`}\n onClick={() => {\n setSelectedPromptId(prompt.id);\n setTestVariables({});\n setTestOutput('');\n }}\n >\n <p className=\"font-medium truncate\">{prompt.name}</p>\n <p className=\"text-xs text-text-secondary mt-1 truncate\">\n v{prompt.version}\n </p>\n <div className=\"flex items-center gap-2 mt-2\">\n {prompt.visibility === 'PUBLIC' && (\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n Public\n </Badge>\n )}\n <span className=\"text-xs text-text-secondary\">\n {templateVariables(prompt).length} vars\n </span>\n </div>\n </button>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n\n {/* Editor */}\n <div className=\"col-span-6\">\n {selectedPrompt ? (\n <GlassCard treatment=\"glass\" glow className=\"overflow-hidden\">\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <div>\n <CardTitle>{selectedPrompt.name}</CardTitle>\n <CardDescription>{selectedPrompt.description}</CardDescription>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => navigateTo(`prompt-templates/${selectedPrompt.id}`)}\n >\n Open template\n </Button>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {/* Tags */}\n <div className=\"flex items-center gap-2\">\n <Tag size={14} className=\"text-text-secondary\" />\n {selectedPrompt.tags.map((tag) => (\n <Badge key={tag} variant=\"secondary\">\n {tag}\n </Badge>\n ))}\n </div>\n\n {/* Content */}\n <FormField label=\"Prompt Content\">\n <Textarea\n value={selectedPrompt.templateText}\n rows={15}\n readOnly\n className=\"font-mono text-sm\"\n />\n </FormField>\n\n {/* Variables */}\n {selectedVariables.length > 0 && (\n <div>\n <p className=\"text-sm font-medium mb-2\">Variables</p>\n <div className=\"space-y-2\">\n {selectedVariables.map((variable: PromptVariable) => (\n <div\n key={variable.name}\n className=\"flex items-center gap-4 p-3 bg-bg-sunken rounded-lg\"\n >\n <div className=\"flex-1\">\n <p className=\"font-medium text-sm\">\n {`{{${variable.name}}}`}\n {variable.required && (\n <span className=\"text-status-error-text ml-1\">*</span>\n )}\n </p>\n {variable.description && (\n <p className=\"text-xs text-text-secondary\">\n {variable.description}\n </p>\n )}\n </div>\n <Badge variant=\"outline\" className=\"capitalize\">\n {variable.type}\n </Badge>\n </div>\n ))}\n </div>\n </div>\n )}\n\n <div className=\"pt-4 text-xs text-text-secondary\">\n Updated {formatRelativeTime(selectedPrompt.updatedAt)}\n </div>\n </CardContent>\n </GlassCard>\n ) : (\n <EmptyState\n illustration=\"onboarding\"\n title=\"Select a prompt\"\n description=\"Choose a prompt from the list to view and edit\"\n />\n )}\n </div>\n\n {/* Test Panel */}\n <div className=\"col-span-3\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Play size={16} />\n Test Prompt\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {selectedVariables.map((variable: PromptVariable) => (\n <FormField key={variable.name} label={variable.name}>\n <Input\n placeholder={variable.description || `Enter ${variable.name}`}\n value={testVariables[variable.name] || ''}\n onChange={(e) =>\n setTestVariables({ ...testVariables, [variable.name]: e.target.value })\n }\n />\n </FormField>\n ))}\n\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.PROMPT_TEMPLATE_EXECUTE}>\n <Button\n className=\"w-full\"\n onClick={() => void handleTest()}\n isLoading={isRunning}\n disabled={!selectedPrompt}\n >\n Run Test\n </Button>\n </BotmanorPermissionGate>\n\n {testOutput && (\n <div>\n <p className=\"text-sm font-medium mb-2\">Output</p>\n <div className=\"p-3 bg-bg-sunken rounded-lg text-sm whitespace-pre-wrap font-mono max-h-64 overflow-auto\">\n {testOutput}\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"PromptStudioPage.js","names":["Textarea","Textarea$1","toPromptVariable","value","record","name","templateVariables","template","promptTemplateVariables","variable","PromptStudioPage","useBotlit","templates","usePromptTemplates","isRunning","useRenderPromptTemplate","selectedPromptId","setSelectedPromptId","useState","testVariables","setTestVariables","testOutput","setTestOutput","selectedPrompt","useMemo","selectedVariables","handleTest","output","render","err","graphqlErrorMessage","PageLayout","BotmanorPermissionGate","BOTMANOR_PERMISSIONS","Button","Plus","navigateTo","PagePurpose","Play","Card","CardHeader","CardTitle","CardContent","loading","i","error","ErrorState","refetch","prompt","Badge","GlassCard","CardDescription","Tag","tag","FormField","formatRelativeTime","EmptyState","Input","e"],"sources":["../../../src/botlit/pages/PromptStudioPage.tsx"],"sourcesContent":["/**\n * Prompt Studio Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Plus, Play, Tag } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input, Textarea, FormField } from '../components/Input';\nimport { Badge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n usePromptTemplates,\n useRenderPromptTemplate,\n promptTemplateVariables,\n type PromptTemplateRecord,\n} from '../hooks';\nimport { graphqlErrorMessage } from '../utils/errors';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { PromptVariable } from '../types';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\n/** Normalises one entry of a template's free-form `variables` JSON. */\nfunction toPromptVariable(value: unknown): PromptVariable | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return null;\n const record = value as Record<string, unknown>;\n const name = typeof record.name === 'string' ? record.name : undefined;\n if (!name) return null;\n const type = typeof record.type === 'string' ? record.type : 'string';\n return {\n name,\n type: type as PromptVariable['type'],\n description: typeof record.description === 'string' ? record.description : undefined,\n required: record.required === true,\n defaultValue: record.defaultValue,\n };\n}\n\nfunction templateVariables(template: PromptTemplateRecord | undefined): PromptVariable[] {\n if (!template) return [];\n return promptTemplateVariables(template)\n .map(toPromptVariable)\n .filter((variable): variable is PromptVariable => variable !== null);\n}\n\nexport const PromptStudioPage: FC = () => {\n const { navigateTo } = useBotlit();\n const { data: templates, loading, error, refetch } = usePromptTemplates();\n const { render, loading: isRunning } = useRenderPromptTemplate();\n\n const [selectedPromptId, setSelectedPromptId] = useState<string | null>(null);\n const [testVariables, setTestVariables] = useState<Record<string, string>>({});\n const [testOutput, setTestOutput] = useState('');\n\n // Select the first template once the list arrives.\n useEffect(() => {\n if (!selectedPromptId && templates.length > 0) {\n setSelectedPromptId(templates[0].id);\n }\n }, [templates, selectedPromptId]);\n\n const selectedPrompt = useMemo(\n () => templates.find((template) => template.id === selectedPromptId),\n [templates, selectedPromptId]\n );\n\n const selectedVariables = useMemo(() => templateVariables(selectedPrompt), [selectedPrompt]);\n\n const handleTest = async () => {\n if (!selectedPrompt) return;\n try {\n // Rendered by wspace-botlit-svc so the preview matches what the agent\n // actually receives — never a client-side string substitution.\n const output = await render({\n templateId: selectedPrompt.id,\n variables: testVariables,\n });\n setTestOutput(output);\n } catch (err) {\n toast.error(graphqlErrorMessage(err, 'Failed to render prompt'));\n }\n };\n\n return (\n <PageLayout\n title=\"Prompt Studio\"\n description=\"Create, test, and manage prompts for your AI agents\"\n actions={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.PROMPT_TEMPLATE_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => navigateTo('prompt-templates/new')}>\n New Prompt\n </Button>\n </BotmanorPermissionGate>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Play size={18} />}>\n Prompt Studio is your interactive workbench for writing and testing prompts before they go\n live. Pick a prompt, edit its text and variables on the left, then fill in sample values\n and hit Run Test to preview exactly what the agent will receive — so you can iterate on\n wording and catch mistakes here instead of in production.\n </PagePurpose>\n\n <div className=\"grid grid-cols-12 gap-6\">\n {/* Prompt List */}\n <div className=\"col-span-3\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Prompts</CardTitle>\n </CardHeader>\n <CardContent className=\"p-0\">\n {loading ? (\n <div className=\"space-y-2 p-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-14 bg-bg-sunken motion-safe:animate-vc-shimmer rounded\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState\n resource=\"prompt templates\"\n error={error}\n onRetry={() => void refetch()}\n className=\"m-4\"\n />\n ) : templates.length === 0 ? (\n <p className=\"p-4 text-sm text-text-secondary\">\n No prompt templates yet. Create one to start iterating.\n </p>\n ) : (\n <div className=\"divide-y divide-border-subtle\">\n {templates.map((prompt: PromptTemplateRecord) => (\n <button\n key={prompt.id}\n type=\"button\"\n className={`w-full text-left p-4 hover:bg-accent transition-colors ${\n selectedPrompt?.id === prompt.id ? 'bg-accent' : ''\n }`}\n onClick={() => {\n setSelectedPromptId(prompt.id);\n setTestVariables({});\n setTestOutput('');\n }}\n >\n <p className=\"font-medium truncate\">{prompt.name}</p>\n <p className=\"text-xs text-text-secondary mt-1 truncate\">\n v{prompt.version}\n </p>\n <div className=\"flex items-center gap-2 mt-2\">\n {prompt.visibility === 'PUBLIC' && (\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n Public\n </Badge>\n )}\n <span className=\"text-xs text-text-secondary\">\n {templateVariables(prompt).length} vars\n </span>\n </div>\n </button>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n\n {/* Editor */}\n <div className=\"col-span-6\">\n {selectedPrompt ? (\n <GlassCard treatment=\"glass\" glow className=\"overflow-hidden\">\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <div>\n <CardTitle>{selectedPrompt.name}</CardTitle>\n <CardDescription>{selectedPrompt.description}</CardDescription>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => navigateTo(`prompt-templates/${selectedPrompt.id}`)}\n >\n Open template\n </Button>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {/* Tags */}\n <div className=\"flex items-center gap-2\">\n <Tag size={14} className=\"text-text-secondary\" />\n {selectedPrompt.tags.map((tag) => (\n <Badge key={tag} variant=\"secondary\">\n {tag}\n </Badge>\n ))}\n </div>\n\n {/* Content */}\n <FormField label=\"Prompt Content\">\n <Textarea\n value={selectedPrompt.templateText}\n rows={15}\n readOnly\n className=\"font-mono text-sm\"\n />\n </FormField>\n\n {/* Variables */}\n {selectedVariables.length > 0 && (\n <div>\n <p className=\"text-sm font-medium mb-2\">Variables</p>\n <div className=\"space-y-2\">\n {selectedVariables.map((variable: PromptVariable) => (\n <div\n key={variable.name}\n className=\"flex items-center gap-4 p-3 bg-bg-sunken rounded-lg\"\n >\n <div className=\"flex-1\">\n <p className=\"font-medium text-sm\">\n {`{{${variable.name}}}`}\n {variable.required && (\n <span className=\"text-status-error-text ml-1\">*</span>\n )}\n </p>\n {variable.description && (\n <p className=\"text-xs text-text-secondary\">\n {variable.description}\n </p>\n )}\n </div>\n <Badge variant=\"outline\" className=\"capitalize\">\n {variable.type}\n </Badge>\n </div>\n ))}\n </div>\n </div>\n )}\n\n <div className=\"pt-4 text-xs text-text-secondary\">\n Updated {formatRelativeTime(selectedPrompt.updatedAt)}\n </div>\n </CardContent>\n </GlassCard>\n ) : (\n <EmptyState\n illustration=\"onboarding\"\n title=\"Select a prompt\"\n description=\"Choose a prompt from the list to view and edit\"\n />\n )}\n </div>\n\n {/* Test Panel */}\n <div className=\"col-span-3\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Play size={16} />\n Test Prompt\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {selectedVariables.map((variable: PromptVariable) => (\n <FormField key={variable.name} label={variable.name}>\n <Input\n placeholder={variable.description || `Enter ${variable.name}`}\n value={testVariables[variable.name] || ''}\n onChange={(e) =>\n setTestVariables({ ...testVariables, [variable.name]: e.target.value })\n }\n />\n </FormField>\n ))}\n\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.PROMPT_TEMPLATE_EXECUTE}>\n <Button\n className=\"w-full\"\n onClick={() => void handleTest()}\n isLoading={isRunning}\n disabled={!selectedPrompt}\n >\n Run Test\n </Button>\n </BotmanorPermissionGate>\n\n {testOutput && (\n <div>\n <p className=\"text-sm font-medium mb-2\">Output</p>\n <div className=\"p-3 bg-bg-sunken rounded-lg text-sm whitespace-pre-wrap font-mono max-h-64 overflow-auto\">\n {testOutput}\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { FC } from 'react';
2
+ interface PromptTemplateDetailPageProps {
3
+ isNew?: boolean;
4
+ }
5
+ export declare const PromptTemplateDetailPage: FC<PromptTemplateDetailPageProps>;
6
+ export {};