@xenosystem/agent-interface-ui 0.1.24 → 0.1.26

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 (380) hide show
  1. package/dist/adapters/agentHostPlatformBridge.d.ts.map +1 -1
  2. package/dist/adapters/agentHostPlatformBridge.js +96 -16
  3. package/dist/adapters/agentHostPlatformBridge.js.map +1 -1
  4. package/dist/adapters/hubAgentPlatformBridge.d.ts.map +1 -1
  5. package/dist/adapters/hubAgentPlatformBridge.js +2 -0
  6. package/dist/adapters/hubAgentPlatformBridge.js.map +1 -1
  7. package/dist/adapters/scopedBackupBridge.d.ts +4 -0
  8. package/dist/adapters/scopedBackupBridge.d.ts.map +1 -0
  9. package/dist/adapters/scopedBackupBridge.js +49 -0
  10. package/dist/adapters/scopedBackupBridge.js.map +1 -0
  11. package/dist/adapters/xenoAgentCompatibilityBridge.d.ts.map +1 -1
  12. package/dist/adapters/xenoAgentCompatibilityBridge.js +9 -1
  13. package/dist/adapters/xenoAgentCompatibilityBridge.js.map +1 -1
  14. package/dist/agent.css +13227 -0
  15. package/dist/components/agent/AgentIdentityGenerator.d.ts +16 -0
  16. package/dist/components/agent/AgentIdentityGenerator.d.ts.map +1 -0
  17. package/dist/components/agent/AgentIdentityGenerator.js +80 -0
  18. package/dist/components/agent/AgentIdentityGenerator.js.map +1 -0
  19. package/dist/components/agent/AgentInterface.d.ts +1 -0
  20. package/dist/components/agent/AgentInterface.d.ts.map +1 -1
  21. package/dist/components/agent/AgentInterface.js +1816 -643
  22. package/dist/components/agent/AgentInterface.js.map +1 -1
  23. package/dist/components/agent/AgentNotificationBanner.d.ts +10 -0
  24. package/dist/components/agent/AgentNotificationBanner.d.ts.map +1 -0
  25. package/dist/components/agent/AgentNotificationBanner.js +28 -0
  26. package/dist/components/agent/AgentNotificationBanner.js.map +1 -0
  27. package/dist/components/agent/AgentOnboarding.d.ts +16 -2
  28. package/dist/components/agent/AgentOnboarding.d.ts.map +1 -1
  29. package/dist/components/agent/AgentOnboarding.js +93 -201
  30. package/dist/components/agent/AgentOnboarding.js.map +1 -1
  31. package/dist/components/agent/AgentView.d.ts.map +1 -1
  32. package/dist/components/agent/AgentView.js +533 -308
  33. package/dist/components/agent/AgentView.js.map +1 -1
  34. package/dist/components/agent/AgentWorkbenchPanel.d.ts +3 -1
  35. package/dist/components/agent/AgentWorkbenchPanel.d.ts.map +1 -1
  36. package/dist/components/agent/AgentWorkbenchPanel.js +3 -2
  37. package/dist/components/agent/AgentWorkbenchPanel.js.map +1 -1
  38. package/dist/components/agent/AgentWorkspaceBrowserPanel.d.ts +4 -1
  39. package/dist/components/agent/AgentWorkspaceBrowserPanel.d.ts.map +1 -1
  40. package/dist/components/agent/AgentWorkspaceBrowserPanel.js +23 -195
  41. package/dist/components/agent/AgentWorkspaceBrowserPanel.js.map +1 -1
  42. package/dist/components/agent/AgentsWorkspaceView.d.ts +12 -0
  43. package/dist/components/agent/AgentsWorkspaceView.d.ts.map +1 -0
  44. package/dist/components/agent/AgentsWorkspaceView.js +129 -0
  45. package/dist/components/agent/AgentsWorkspaceView.js.map +1 -0
  46. package/dist/components/agent/DevelopmentCoordinationPanel.d.ts +7 -0
  47. package/dist/components/agent/DevelopmentCoordinationPanel.d.ts.map +1 -1
  48. package/dist/components/agent/DevelopmentCoordinationPanel.js +57 -49
  49. package/dist/components/agent/DevelopmentCoordinationPanel.js.map +1 -1
  50. package/dist/components/agent/KnowledgePanel.d.ts.map +1 -1
  51. package/dist/components/agent/KnowledgePanel.js +17 -67
  52. package/dist/components/agent/KnowledgePanel.js.map +1 -1
  53. package/dist/components/agent/LiveConversationCollaboration.d.ts +27 -0
  54. package/dist/components/agent/LiveConversationCollaboration.d.ts.map +1 -0
  55. package/dist/components/agent/LiveConversationCollaboration.js +127 -0
  56. package/dist/components/agent/LiveConversationCollaboration.js.map +1 -0
  57. package/dist/components/agent/MonacoDiffWorkbenchEditor.d.ts.map +1 -1
  58. package/dist/components/agent/MonacoDiffWorkbenchEditor.js +1 -1
  59. package/dist/components/agent/MonacoDiffWorkbenchEditor.js.map +1 -1
  60. package/dist/components/agent/MonacoWorkbenchEditor.d.ts.map +1 -1
  61. package/dist/components/agent/MonacoWorkbenchEditor.js +3 -3
  62. package/dist/components/agent/MonacoWorkbenchEditor.js.map +1 -1
  63. package/dist/components/agent/OwnedBrowserController.d.ts +55 -0
  64. package/dist/components/agent/OwnedBrowserController.d.ts.map +1 -0
  65. package/dist/components/agent/OwnedBrowserController.js +166 -0
  66. package/dist/components/agent/OwnedBrowserController.js.map +1 -0
  67. package/dist/components/agent/OwnedWorkforceView.d.ts +10 -0
  68. package/dist/components/agent/OwnedWorkforceView.d.ts.map +1 -0
  69. package/dist/components/agent/OwnedWorkforceView.js +256 -0
  70. package/dist/components/agent/OwnedWorkforceView.js.map +1 -0
  71. package/dist/components/agent/PluginManager.d.ts +34 -0
  72. package/dist/components/agent/PluginManager.d.ts.map +1 -1
  73. package/dist/components/agent/PluginManager.js +187 -126
  74. package/dist/components/agent/PluginManager.js.map +1 -1
  75. package/dist/components/agent/ProjectsWorkspaceView.d.ts +14 -0
  76. package/dist/components/agent/ProjectsWorkspaceView.d.ts.map +1 -0
  77. package/dist/components/agent/ProjectsWorkspaceView.js +176 -0
  78. package/dist/components/agent/ProjectsWorkspaceView.js.map +1 -0
  79. package/dist/components/agent/RunReviewPanel.d.ts +8 -13
  80. package/dist/components/agent/RunReviewPanel.d.ts.map +1 -1
  81. package/dist/components/agent/RunReviewPanel.js +120 -106
  82. package/dist/components/agent/RunReviewPanel.js.map +1 -1
  83. package/dist/components/agent/ScheduledWorkspaceView.d.ts +19 -0
  84. package/dist/components/agent/ScheduledWorkspaceView.d.ts.map +1 -0
  85. package/dist/components/agent/ScheduledWorkspaceView.js +150 -0
  86. package/dist/components/agent/ScheduledWorkspaceView.js.map +1 -0
  87. package/dist/components/agent/SdkSessionPanel.d.ts +25 -0
  88. package/dist/components/agent/SdkSessionPanel.d.ts.map +1 -0
  89. package/dist/components/agent/SdkSessionPanel.js +15 -0
  90. package/dist/components/agent/SdkSessionPanel.js.map +1 -0
  91. package/dist/components/agent/SlashCommandAutocomplete.d.ts +12 -0
  92. package/dist/components/agent/SlashCommandAutocomplete.d.ts.map +1 -0
  93. package/dist/components/agent/SlashCommandAutocomplete.js +33 -0
  94. package/dist/components/agent/SlashCommandAutocomplete.js.map +1 -0
  95. package/dist/components/agent/TeamsWorkspaceView.d.ts +12 -0
  96. package/dist/components/agent/TeamsWorkspaceView.d.ts.map +1 -0
  97. package/dist/components/agent/TeamsWorkspaceView.js +127 -0
  98. package/dist/components/agent/TeamsWorkspaceView.js.map +1 -0
  99. package/dist/components/agent/WorkspacePersistenceNotice.d.ts +3 -0
  100. package/dist/components/agent/WorkspacePersistenceNotice.d.ts.map +1 -0
  101. package/dist/components/agent/WorkspacePersistenceNotice.js +23 -0
  102. package/dist/components/agent/WorkspacePersistenceNotice.js.map +1 -0
  103. package/dist/components/agent/acp/AcpAgentConfigForm.d.ts +1 -0
  104. package/dist/components/agent/acp/AcpAgentConfigForm.d.ts.map +1 -1
  105. package/dist/components/agent/acp/AcpAgentConfigForm.js +47 -14
  106. package/dist/components/agent/acp/AcpAgentConfigForm.js.map +1 -1
  107. package/dist/components/agent/acp/AcpAgentDiagnosticsPanel.js +1 -1
  108. package/dist/components/agent/acp/AcpAgentDiagnosticsPanel.js.map +1 -1
  109. package/dist/components/agent/acp/AcpAgentManager.d.ts.map +1 -1
  110. package/dist/components/agent/acp/AcpAgentManager.js +18 -18
  111. package/dist/components/agent/acp/AcpAgentManager.js.map +1 -1
  112. package/dist/components/agent/acp/AcpAgentTestResultPanel.js +1 -1
  113. package/dist/components/agent/acp/AcpAgentTestResultPanel.js.map +1 -1
  114. package/dist/components/agent/acp/AcpApprovalPanel.js +2 -2
  115. package/dist/components/agent/acp/AcpApprovalPanel.js.map +1 -1
  116. package/dist/components/agent/acp/AcpCertificationPanel.js +1 -1
  117. package/dist/components/agent/acp/AcpCertificationPanel.js.map +1 -1
  118. package/dist/components/agent/acp/AcpLiveProviderWorkflowPanel.js +1 -1
  119. package/dist/components/agent/acp/AcpLiveProviderWorkflowPanel.js.map +1 -1
  120. package/dist/components/agent/acp/AcpProviderManagerPanel.js +1 -1
  121. package/dist/components/agent/acp/AcpProviderManagerPanel.js.map +1 -1
  122. package/dist/components/agent/acp/AcpProviderModelsPanel.js +1 -1
  123. package/dist/components/agent/acp/AcpProviderModelsPanel.js.map +1 -1
  124. package/dist/components/agent/acp/AcpSupportBundlePanel.js +1 -1
  125. package/dist/components/agent/acp/AcpSupportBundlePanel.js.map +1 -1
  126. package/dist/components/agent/collaborationWindow.d.ts +11 -0
  127. package/dist/components/agent/collaborationWindow.d.ts.map +1 -0
  128. package/dist/components/agent/collaborationWindow.js +10 -0
  129. package/dist/components/agent/collaborationWindow.js.map +1 -0
  130. package/dist/components/agent/conversationCollaborationAppendJournal.d.ts +25 -0
  131. package/dist/components/agent/conversationCollaborationAppendJournal.d.ts.map +1 -0
  132. package/dist/components/agent/conversationCollaborationAppendJournal.js +118 -0
  133. package/dist/components/agent/conversationCollaborationAppendJournal.js.map +1 -0
  134. package/dist/components/agent/conversationCollaborationController.d.ts +96 -0
  135. package/dist/components/agent/conversationCollaborationController.d.ts.map +1 -0
  136. package/dist/components/agent/conversationCollaborationController.js +597 -0
  137. package/dist/components/agent/conversationCollaborationController.js.map +1 -0
  138. package/dist/components/agent/destructiveConfirmation.d.ts +76 -0
  139. package/dist/components/agent/destructiveConfirmation.d.ts.map +1 -0
  140. package/dist/components/agent/destructiveConfirmation.js +231 -0
  141. package/dist/components/agent/destructiveConfirmation.js.map +1 -0
  142. package/dist/components/agent/developmentCoordinationController.d.ts +43 -0
  143. package/dist/components/agent/developmentCoordinationController.d.ts.map +1 -0
  144. package/dist/components/agent/developmentCoordinationController.js +94 -0
  145. package/dist/components/agent/developmentCoordinationController.js.map +1 -0
  146. package/dist/components/agent/developmentCoordinationProjection.d.ts +24 -0
  147. package/dist/components/agent/developmentCoordinationProjection.d.ts.map +1 -1
  148. package/dist/components/agent/developmentCoordinationProjection.js +34 -5
  149. package/dist/components/agent/developmentCoordinationProjection.js.map +1 -1
  150. package/dist/components/agent/editorOperationAuthority.d.ts +29 -0
  151. package/dist/components/agent/editorOperationAuthority.d.ts.map +1 -0
  152. package/dist/components/agent/editorOperationAuthority.js +73 -0
  153. package/dist/components/agent/editorOperationAuthority.js.map +1 -0
  154. package/dist/components/agent/knowledgePagination.d.ts +7 -0
  155. package/dist/components/agent/knowledgePagination.d.ts.map +1 -0
  156. package/dist/components/agent/knowledgePagination.js +7 -0
  157. package/dist/components/agent/knowledgePagination.js.map +1 -0
  158. package/dist/components/agent/knowledgePanelController.d.ts +32 -0
  159. package/dist/components/agent/knowledgePanelController.d.ts.map +1 -0
  160. package/dist/components/agent/knowledgePanelController.js +119 -0
  161. package/dist/components/agent/knowledgePanelController.js.map +1 -0
  162. package/dist/components/agent/monacoWorkbenchShared.js +1 -1
  163. package/dist/components/agent/onboardingModels.d.ts +31 -0
  164. package/dist/components/agent/onboardingModels.d.ts.map +1 -0
  165. package/dist/components/agent/onboardingModels.js +107 -0
  166. package/dist/components/agent/onboardingModels.js.map +1 -0
  167. package/dist/components/agent/personalConversationScope.d.ts +26 -0
  168. package/dist/components/agent/personalConversationScope.d.ts.map +1 -0
  169. package/dist/components/agent/personalConversationScope.js +43 -0
  170. package/dist/components/agent/personalConversationScope.js.map +1 -0
  171. package/dist/components/agent/reviewRequestScope.d.ts +16 -0
  172. package/dist/components/agent/reviewRequestScope.d.ts.map +1 -0
  173. package/dist/components/agent/reviewRequestScope.js +101 -0
  174. package/dist/components/agent/reviewRequestScope.js.map +1 -0
  175. package/dist/components/agent/scheduleCreationAttempt.d.ts +12 -0
  176. package/dist/components/agent/scheduleCreationAttempt.d.ts.map +1 -0
  177. package/dist/components/agent/scheduleCreationAttempt.js +30 -0
  178. package/dist/components/agent/scheduleCreationAttempt.js.map +1 -0
  179. package/dist/components/agent/settings/EntitySettingsLayout.d.ts +1 -1
  180. package/dist/components/agent/settings/EntitySettingsLayout.d.ts.map +1 -1
  181. package/dist/components/agent/settings/EntitySettingsLayout.js +64 -44
  182. package/dist/components/agent/settings/EntitySettingsLayout.js.map +1 -1
  183. package/dist/components/agent/settings/SettingsNavigation.d.ts.map +1 -1
  184. package/dist/components/agent/settings/SettingsNavigation.js +17 -17
  185. package/dist/components/agent/settings/SettingsNavigation.js.map +1 -1
  186. package/dist/components/agent/settings/entityArchiveState.d.ts +24 -0
  187. package/dist/components/agent/settings/entityArchiveState.d.ts.map +1 -0
  188. package/dist/components/agent/settings/entityArchiveState.js +12 -0
  189. package/dist/components/agent/settings/entityArchiveState.js.map +1 -0
  190. package/dist/components/agent/settings/sections/AccessMembersSection.d.ts.map +1 -1
  191. package/dist/components/agent/settings/sections/AccessMembersSection.js +10 -25
  192. package/dist/components/agent/settings/sections/AccessMembersSection.js.map +1 -1
  193. package/dist/components/agent/settings/sections/AccountWorkspacePanel.d.ts +16 -0
  194. package/dist/components/agent/settings/sections/AccountWorkspacePanel.d.ts.map +1 -0
  195. package/dist/components/agent/settings/sections/AccountWorkspacePanel.js +265 -0
  196. package/dist/components/agent/settings/sections/AccountWorkspacePanel.js.map +1 -0
  197. package/dist/components/agent/settings/sections/AgentPermissionRulesPanel.d.ts.map +1 -1
  198. package/dist/components/agent/settings/sections/AgentPermissionRulesPanel.js +47 -32
  199. package/dist/components/agent/settings/sections/AgentPermissionRulesPanel.js.map +1 -1
  200. package/dist/components/agent/settings/sections/DangerZoneSection.d.ts.map +1 -1
  201. package/dist/components/agent/settings/sections/DangerZoneSection.js +30 -6
  202. package/dist/components/agent/settings/sections/DangerZoneSection.js.map +1 -1
  203. package/dist/components/agent/settings/sections/DefaultAgentConfigSection.d.ts.map +1 -1
  204. package/dist/components/agent/settings/sections/DefaultAgentConfigSection.js +47 -37
  205. package/dist/components/agent/settings/sections/DefaultAgentConfigSection.js.map +1 -1
  206. package/dist/components/agent/settings/sections/EnvironmentSecretsSection.d.ts.map +1 -1
  207. package/dist/components/agent/settings/sections/EnvironmentSecretsSection.js +30 -43
  208. package/dist/components/agent/settings/sections/EnvironmentSecretsSection.js.map +1 -1
  209. package/dist/components/agent/settings/sections/ExportBackupSection.d.ts +3 -1
  210. package/dist/components/agent/settings/sections/ExportBackupSection.d.ts.map +1 -1
  211. package/dist/components/agent/settings/sections/ExportBackupSection.js +14 -12
  212. package/dist/components/agent/settings/sections/ExportBackupSection.js.map +1 -1
  213. package/dist/components/agent/settings/sections/GeneralSection.d.ts.map +1 -1
  214. package/dist/components/agent/settings/sections/GeneralSection.js +47 -4
  215. package/dist/components/agent/settings/sections/GeneralSection.js.map +1 -1
  216. package/dist/components/agent/settings/sections/IntegrationsSection.d.ts.map +1 -1
  217. package/dist/components/agent/settings/sections/IntegrationsSection.js +14 -21
  218. package/dist/components/agent/settings/sections/IntegrationsSection.js.map +1 -1
  219. package/dist/components/agent/settings/sections/NotificationsSection.d.ts.map +1 -1
  220. package/dist/components/agent/settings/sections/NotificationsSection.js +125 -20
  221. package/dist/components/agent/settings/sections/NotificationsSection.js.map +1 -1
  222. package/dist/components/agent/settings/sections/ResourceLimitsSection.d.ts.map +1 -1
  223. package/dist/components/agent/settings/sections/ResourceLimitsSection.js +7 -7
  224. package/dist/components/agent/settings/sections/ResourceLimitsSection.js.map +1 -1
  225. package/dist/components/agent/settings/sections/SecurityComplianceSection.d.ts.map +1 -1
  226. package/dist/components/agent/settings/sections/SecurityComplianceSection.js +5 -4
  227. package/dist/components/agent/settings/sections/SecurityComplianceSection.js.map +1 -1
  228. package/dist/components/agent/settings/sections/UsageAnalyticsSection.d.ts.map +1 -1
  229. package/dist/components/agent/settings/sections/UsageAnalyticsSection.js +2 -3
  230. package/dist/components/agent/settings/sections/UsageAnalyticsSection.js.map +1 -1
  231. package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.d.ts.map +1 -1
  232. package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.js +39 -26
  233. package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.js.map +1 -1
  234. package/dist/components/agent/settings/sections/WorkspaceKeysPanel.d.ts +6 -0
  235. package/dist/components/agent/settings/sections/WorkspaceKeysPanel.d.ts.map +1 -0
  236. package/dist/components/agent/settings/sections/WorkspaceKeysPanel.js +205 -0
  237. package/dist/components/agent/settings/sections/WorkspaceKeysPanel.js.map +1 -0
  238. package/dist/components/agent/settings/sections/environmentDraftAction.d.ts +3 -0
  239. package/dist/components/agent/settings/sections/environmentDraftAction.d.ts.map +1 -0
  240. package/dist/components/agent/settings/sections/environmentDraftAction.js +6 -0
  241. package/dist/components/agent/settings/sections/environmentDraftAction.js.map +1 -0
  242. package/dist/components/agent/settings/sections/membershipOperationProjection.d.ts +3 -0
  243. package/dist/components/agent/settings/sections/membershipOperationProjection.d.ts.map +1 -0
  244. package/dist/components/agent/settings/sections/membershipOperationProjection.js +9 -0
  245. package/dist/components/agent/settings/sections/membershipOperationProjection.js.map +1 -0
  246. package/dist/components/agent/settings/sections/workspaceKeyOperationProjection.d.ts +6 -0
  247. package/dist/components/agent/settings/sections/workspaceKeyOperationProjection.d.ts.map +1 -0
  248. package/dist/components/agent/settings/sections/workspaceKeyOperationProjection.js +8 -0
  249. package/dist/components/agent/settings/sections/workspaceKeyOperationProjection.js.map +1 -0
  250. package/dist/components/agent/settings/shared/InAppConfirmationDialog.d.ts +25 -0
  251. package/dist/components/agent/settings/shared/InAppConfirmationDialog.d.ts.map +1 -0
  252. package/dist/components/agent/settings/shared/InAppConfirmationDialog.js +89 -0
  253. package/dist/components/agent/settings/shared/InAppConfirmationDialog.js.map +1 -0
  254. package/dist/components/agent/settings/shared/InputField.d.ts +1 -1
  255. package/dist/components/agent/settings/shared/InputField.d.ts.map +1 -1
  256. package/dist/components/agent/settings/shared/InputField.js +4 -3
  257. package/dist/components/agent/settings/shared/InputField.js.map +1 -1
  258. package/dist/components/agent/settings/shared/MembersTable.d.ts +3 -3
  259. package/dist/components/agent/settings/shared/MembersTable.d.ts.map +1 -1
  260. package/dist/components/agent/settings/shared/MembersTable.js +1 -1
  261. package/dist/components/agent/settings/shared/MembersTable.js.map +1 -1
  262. package/dist/components/agent/settings/shared/ScopedAuditPanel.d.ts +5 -0
  263. package/dist/components/agent/settings/shared/ScopedAuditPanel.d.ts.map +1 -0
  264. package/dist/components/agent/settings/shared/ScopedAuditPanel.js +70 -0
  265. package/dist/components/agent/settings/shared/ScopedAuditPanel.js.map +1 -0
  266. package/dist/components/agent/settings/shared/SettingsCard.d.ts +2 -1
  267. package/dist/components/agent/settings/shared/SettingsCard.d.ts.map +1 -1
  268. package/dist/components/agent/settings/shared/SettingsCard.js +2 -2
  269. package/dist/components/agent/settings/shared/SettingsCard.js.map +1 -1
  270. package/dist/components/agent/settings/shared/ToggleSwitch.d.ts.map +1 -1
  271. package/dist/components/agent/settings/shared/ToggleSwitch.js +1 -1
  272. package/dist/components/agent/settings/shared/ToggleSwitch.js.map +1 -1
  273. package/dist/components/agent/settings/shared/UsageChart.d.ts +10 -0
  274. package/dist/components/agent/settings/shared/UsageChart.d.ts.map +1 -1
  275. package/dist/components/agent/settings/shared/UsageChart.js +16 -10
  276. package/dist/components/agent/settings/shared/UsageChart.js.map +1 -1
  277. package/dist/components/agent/settings/shared/WorkspaceRulesControl.d.ts +8 -0
  278. package/dist/components/agent/settings/shared/WorkspaceRulesControl.d.ts.map +1 -0
  279. package/dist/components/agent/settings/shared/WorkspaceRulesControl.js +26 -0
  280. package/dist/components/agent/settings/shared/WorkspaceRulesControl.js.map +1 -0
  281. package/dist/components/agent/settings/shared/useScopedConfirmation.d.ts +8 -0
  282. package/dist/components/agent/settings/shared/useScopedConfirmation.d.ts.map +1 -0
  283. package/dist/components/agent/settings/shared/useScopedConfirmation.js +53 -0
  284. package/dist/components/agent/settings/shared/useScopedConfirmation.js.map +1 -0
  285. package/dist/components/agent/settings/shared/useSettingsConfirmation.d.ts +8 -0
  286. package/dist/components/agent/settings/shared/useSettingsConfirmation.d.ts.map +1 -0
  287. package/dist/components/agent/settings/shared/useSettingsConfirmation.js +51 -0
  288. package/dist/components/agent/settings/shared/useSettingsConfirmation.js.map +1 -0
  289. package/dist/components/agent/settings/shared/workspaceRulesController.d.ts +28 -0
  290. package/dist/components/agent/settings/shared/workspaceRulesController.d.ts.map +1 -0
  291. package/dist/components/agent/settings/shared/workspaceRulesController.js +82 -0
  292. package/dist/components/agent/settings/shared/workspaceRulesController.js.map +1 -0
  293. package/dist/components/agent/sidebarEntityPins.d.ts +11 -0
  294. package/dist/components/agent/sidebarEntityPins.d.ts.map +1 -0
  295. package/dist/components/agent/sidebarEntityPins.js +37 -0
  296. package/dist/components/agent/sidebarEntityPins.js.map +1 -0
  297. package/dist/components/agent/workspaceHierarchy.d.ts +24 -0
  298. package/dist/components/agent/workspaceHierarchy.d.ts.map +1 -0
  299. package/dist/components/agent/workspaceHierarchy.js +50 -0
  300. package/dist/components/agent/workspaceHierarchy.js.map +1 -0
  301. package/dist/components/product/XenoAgentProductHeader.d.ts +4 -2
  302. package/dist/components/product/XenoAgentProductHeader.d.ts.map +1 -1
  303. package/dist/components/product/XenoAgentProductHeader.js +22 -4
  304. package/dist/components/product/XenoAgentProductHeader.js.map +1 -1
  305. package/dist/components/product/XenoAgentSessionTabs.js +1 -1
  306. package/dist/components/product/XenoAgentSessionTabs.js.map +1 -1
  307. package/dist/components/product/XenoAgentWorkspaceSelector.d.ts +7 -0
  308. package/dist/components/product/XenoAgentWorkspaceSelector.d.ts.map +1 -0
  309. package/dist/components/product/XenoAgentWorkspaceSelector.js +237 -0
  310. package/dist/components/product/XenoAgentWorkspaceSelector.js.map +1 -0
  311. package/dist/components/workspace/WorkspaceCreationWizard.d.ts +6 -0
  312. package/dist/components/workspace/WorkspaceCreationWizard.d.ts.map +1 -0
  313. package/dist/components/workspace/WorkspaceCreationWizard.js +48 -0
  314. package/dist/components/workspace/WorkspaceCreationWizard.js.map +1 -0
  315. package/dist/hooks/useSidebarLayoutPreference.d.ts +29 -0
  316. package/dist/hooks/useSidebarLayoutPreference.d.ts.map +1 -0
  317. package/dist/hooks/useSidebarLayoutPreference.js +83 -0
  318. package/dist/hooks/useSidebarLayoutPreference.js.map +1 -0
  319. package/dist/hooks/useWorkspaceCreation.d.ts +8 -0
  320. package/dist/hooks/useWorkspaceCreation.d.ts.map +1 -0
  321. package/dist/hooks/useWorkspaceCreation.js +40 -0
  322. package/dist/hooks/useWorkspaceCreation.js.map +1 -0
  323. package/dist/index.d.ts +3 -0
  324. package/dist/index.d.ts.map +1 -1
  325. package/dist/index.js +3 -0
  326. package/dist/index.js.map +1 -1
  327. package/dist/platformApiTypes.d.ts +77 -36
  328. package/dist/platformApiTypes.d.ts.map +1 -1
  329. package/dist/platformBridge.d.ts +4 -0
  330. package/dist/platformBridge.d.ts.map +1 -1
  331. package/dist/platformBridge.js +10 -0
  332. package/dist/platformBridge.js.map +1 -1
  333. package/dist/stores/agentChatStore.d.ts +120 -2
  334. package/dist/stores/agentChatStore.d.ts.map +1 -1
  335. package/dist/stores/agentChatStore.js +344 -35
  336. package/dist/stores/agentChatStore.js.map +1 -1
  337. package/dist/stores/agentCreationDefaults.d.ts +25 -0
  338. package/dist/stores/agentCreationDefaults.d.ts.map +1 -0
  339. package/dist/stores/agentCreationDefaults.js +11 -0
  340. package/dist/stores/agentCreationDefaults.js.map +1 -0
  341. package/dist/stores/entitySettingsStore.d.ts +37 -12
  342. package/dist/stores/entitySettingsStore.d.ts.map +1 -1
  343. package/dist/stores/entitySettingsStore.js +558 -585
  344. package/dist/stores/entitySettingsStore.js.map +1 -1
  345. package/dist/stores/suggestionStore.d.ts +9 -2
  346. package/dist/stores/suggestionStore.d.ts.map +1 -1
  347. package/dist/stores/suggestionStore.js +51 -24
  348. package/dist/stores/suggestionStore.js.map +1 -1
  349. package/dist/stores/workspaceCreationAttempt.d.ts +14 -0
  350. package/dist/stores/workspaceCreationAttempt.d.ts.map +1 -0
  351. package/dist/stores/workspaceCreationAttempt.js +35 -0
  352. package/dist/stores/workspaceCreationAttempt.js.map +1 -0
  353. package/dist/stores/workspaceReconciliation.d.ts +6 -0
  354. package/dist/stores/workspaceReconciliation.d.ts.map +1 -0
  355. package/dist/stores/workspaceReconciliation.js +33 -0
  356. package/dist/stores/workspaceReconciliation.js.map +1 -0
  357. package/dist/stores/workspaceStore.d.ts +44 -9
  358. package/dist/stores/workspaceStore.d.ts.map +1 -1
  359. package/dist/stores/workspaceStore.js +238 -99
  360. package/dist/stores/workspaceStore.js.map +1 -1
  361. package/dist/types/agentEditor.d.ts +1 -0
  362. package/dist/types/agentEditor.d.ts.map +1 -1
  363. package/dist/utils/advertisedReasoning.d.ts +25 -0
  364. package/dist/utils/advertisedReasoning.d.ts.map +1 -0
  365. package/dist/utils/advertisedReasoning.js +62 -0
  366. package/dist/utils/advertisedReasoning.js.map +1 -0
  367. package/dist/utils/clipboardCopy.d.ts +4 -0
  368. package/dist/utils/clipboardCopy.d.ts.map +1 -0
  369. package/dist/utils/clipboardCopy.js +27 -0
  370. package/dist/utils/clipboardCopy.js.map +1 -0
  371. package/dist/utils/providerCommandArgs.d.ts +11 -0
  372. package/dist/utils/providerCommandArgs.d.ts.map +1 -0
  373. package/dist/utils/providerCommandArgs.js +18 -0
  374. package/dist/utils/providerCommandArgs.js.map +1 -0
  375. package/dist/utils/rendererTeardown.d.ts +6 -0
  376. package/dist/utils/rendererTeardown.d.ts.map +1 -0
  377. package/dist/utils/rendererTeardown.js +18 -0
  378. package/dist/utils/rendererTeardown.js.map +1 -0
  379. package/package.json +20 -8
  380. package/src/agent.css +39 -9
@@ -1,8 +1,8 @@
1
1
  import { getAgentPlatformBridge } from '../platformBridge.js';
2
+ import { isAgentUsageResult } from '@xenosystem/agent-interface-contract';
2
3
  import { create } from 'zustand';
3
- import { useWorkspaceStore } from './workspaceStore.js';
4
- import { useAgentChatStore } from './agentChatStore.js';
5
- import { useAuthStore } from './authStore.js';
4
+ import { useWorkspaceStore, toolsForAgentCapabilities, requestWorkspaceLifecycle, requireWorkspacePersistence } from './workspaceStore.js';
5
+ import { useAgentChatStore, loadLocalAgentConversations } from './agentChatStore.js';
6
6
  export const SETTINGS_SECTIONS = [
7
7
  { id: 'general', label: 'General', icon: 'settings', availableFor: ['workspace', 'team', 'agent'] },
8
8
  { id: 'directoryAccess', label: 'Directory Access', icon: 'folder', availableFor: ['workspace', 'team', 'agent'] },
@@ -11,274 +11,263 @@ export const SETTINGS_SECTIONS = [
11
11
  { id: 'resourceLimits', label: 'Resource Limits', icon: 'gauge', availableFor: ['workspace', 'team', 'agent'] },
12
12
  { id: 'usage', label: 'Usage & Analytics', icon: 'barChart', availableFor: ['workspace', 'team', 'agent'] },
13
13
  { id: 'integrations', label: 'Integrations', icon: 'plug', availableFor: ['workspace', 'team'] },
14
- { id: 'environment', label: 'Environment & Secrets', icon: 'key', availableFor: ['workspace', 'team'] },
14
+ { id: 'environment', label: 'Environment & Secrets', icon: 'key', availableFor: ['workspace', 'team', 'agent'] },
15
15
  { id: 'notifications', label: 'Notifications', icon: 'bell', availableFor: ['workspace', 'team', 'agent'] },
16
16
  { id: 'security', label: 'Security & Compliance', icon: 'shield', availableFor: ['workspace', 'team'] },
17
- { id: 'exportBackup', label: 'Export & Backup', icon: 'download', availableFor: ['workspace', 'team'] },
17
+ { id: 'exportBackup', label: 'Export & Backup', icon: 'download', availableFor: ['workspace', 'team', 'agent'] },
18
18
  { id: 'dangerZone', label: 'Danger Zone', icon: 'alertTriangle', availableFor: ['workspace', 'team', 'agent'] },
19
19
  ];
20
20
  export function getSectionsForEntity(entityType) {
21
21
  return SETTINGS_SECTIONS.filter(s => s.availableFor.includes(entityType));
22
22
  }
23
23
  // =============================================================================
24
- // MOCK DATA GENERATOR
24
+ // INITIAL UNOBSERVED STATE
25
25
  // =============================================================================
26
26
  function generateId() {
27
27
  return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
28
28
  }
29
- function generateMockSettings(entityId, entityType, entityName, extra) {
30
- const now = new Date().toISOString();
31
- const thirtyDaysAgo = new Date(Date.now() - 30 * 86400000).toISOString();
32
- const owner = {
33
- id: 'user_owner_1',
34
- name: 'You',
35
- email: 'you@example.com',
36
- role: 'owner',
37
- joinedAt: thirtyDaysAgo,
38
- };
39
- const members = [
40
- owner,
41
- { id: 'user_2', name: 'Alice Chen', email: 'alice@example.com', role: 'admin', joinedAt: thirtyDaysAgo },
42
- { id: 'user_3', name: 'Bob Smith', email: 'bob@example.com', role: 'editor', joinedAt: now },
43
- ];
44
- const dailyUsage = Array.from({ length: 7 }, (_, i) => ({
45
- label: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][i],
46
- value: Math.floor(Math.random() * 50000) + 5000,
47
- }));
48
- const weeklyUsage = Array.from({ length: 4 }, (_, i) => ({
49
- label: `Week ${i + 1}`,
50
- value: Math.floor(Math.random() * 200000) + 50000,
51
- }));
52
- const monthlyUsage = Array.from({ length: 6 }, (_, i) => ({
53
- label: ['Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Jan'][i],
54
- value: Math.floor(Math.random() * 800000) + 100000,
55
- }));
56
- const workspaceQuotas = [
57
- { label: 'Teams', current: 3, limit: 10, unit: 'teams' },
58
- { label: 'Tokens / month', current: 425000, limit: 1000000, unit: 'tokens' },
59
- { label: 'Storage', current: 2.4, limit: 10, unit: 'GB' },
60
- ];
61
- const teamQuotas = [
62
- { label: 'Agents', current: 5, limit: 20, unit: 'agents' },
63
- { label: 'Tokens / month', current: 180000, limit: 500000, unit: 'tokens' },
64
- ];
65
- const agentQuotas = [
66
- { label: 'Tokens / month', current: 42000, limit: 100000, unit: 'tokens' },
67
- ];
68
- const quotas = entityType === 'workspace' ? workspaceQuotas : entityType === 'team' ? teamQuotas : agentQuotas;
29
+ function createInitialSettings(entityId, entityType, entityName, extra) {
30
+ // Empty means unobserved, not a synthetic successful response. Load statuses
31
+ // distinguish unavailable services from successfully observed empty collections.
32
+ const owner = null;
69
33
  return {
70
- entityId,
71
- entityType,
72
- entityName,
73
- workspaceId: extra?.workspaceId,
74
- workspaceName: extra?.workspaceName,
75
- teamId: extra?.teamId,
76
- teamName: extra?.teamName,
34
+ entityId, entityType, entityName,
35
+ workspaceId: extra?.workspaceId, workspaceName: extra?.workspaceName,
36
+ teamId: extra?.teamId, teamName: extra?.teamName,
77
37
  general: {
78
- name: entityName,
79
- description: `A ${entityType} for managing AI operations.`,
80
- icon: entityType === 'workspace' ? 'building' : entityType === 'team' ? 'users' : 'bot',
81
- slug: entityName.toLowerCase().replace(/\s+/g, '-'),
82
- createdAt: thirtyDaysAgo,
83
- updatedAt: now,
84
- },
85
- defaultAgentConfig: entityType !== 'agent' ? {
86
- defaultModel: 'claude-sonnet-4-6',
87
- systemInstructions: 'You are a helpful AI assistant.',
88
- enabledTools: ['web-search', 'code-execution', 'file-read'],
89
- availableTools: ['web-search', 'code-execution', 'file-read', 'file-write', 'image-generation', 'data-analysis'],
90
- } : undefined,
91
- access: {
92
- owner,
93
- members: entityType === 'agent' ? [owner] : members,
94
- pendingInvites: entityType === 'agent' ? [] : [
95
- { id: 'inv_1', email: 'carol@example.com', role: 'viewer', sentAt: now, expiresAt: new Date(Date.now() + 7 * 86400000).toISOString() },
96
- ],
97
- publicAccess: false,
98
- allowGuestViewing: false,
99
- },
100
- resourceLimits: {
101
- quotas,
102
- rateLimitRpm: entityType === 'workspace' ? 1000 : entityType === 'team' ? 500 : 100,
103
- rateLimitTpd: entityType === 'workspace' ? 1000000 : entityType === 'team' ? 500000 : 100000,
104
- },
105
- usage: {
106
- totalTokens: 425000,
107
- totalCost: 12.50,
108
- totalRequests: 1842,
109
- dailyUsage,
110
- weeklyUsage,
111
- monthlyUsage,
112
- costByModel: [
113
- { model: 'Opus 4.5', cost: 8.20, tokens: 280000 },
114
- { model: 'GPT 5.3 Codex', cost: 3.10, tokens: 105000 },
115
- { model: 'Flash 3.0', cost: 1.20, tokens: 40000 },
116
- ],
117
- topAgents: [
118
- { name: 'Code Reviewer', tokens: 120000, cost: 3.60 },
119
- { name: 'Research Bot', tokens: 95000, cost: 2.85 },
120
- { name: 'Doc Writer', tokens: 72000, cost: 2.16 },
121
- ],
38
+ name: entityName, description: '', icon: entityType === 'workspace' ? 'building' : entityType === 'team' ? 'users' : 'bot',
39
+ slug: entityName.toLowerCase().replace(/\s+/g, '-'), createdAt: '', updatedAt: '',
122
40
  },
41
+ defaultAgentConfig: entityType !== 'agent'
42
+ ? { defaultModel: '', systemInstructions: '', enabledTools: [], availableTools: [] }
43
+ : undefined,
44
+ access: { owner, members: [], pendingInvites: [], publicAccess: false, allowGuestViewing: false },
45
+ resourceLimits: { quotas: [], rateLimitRpm: 0, rateLimitTpd: 0 },
46
+ usage: { totalTokens: 0, totalCost: null, totalRequests: 0, dailyUsage: [], weeklyUsage: [], monthlyUsage: [], costByModel: [], topAgents: [] },
123
47
  integrations: {
124
48
  integrations: [
125
- { id: 'int_1', type: 'github', name: 'GitHub', enabled: true, connectedAt: thirtyDaysAgo, status: 'connected' },
126
- { id: 'int_2', type: 'slack', name: 'Slack', enabled: false, connectedAt: '', status: 'disconnected' },
127
- { id: 'int_3', type: 'discord', name: 'Discord', enabled: false, connectedAt: '', status: 'disconnected' },
128
- { id: 'int_4', type: 'webhook', name: 'Custom Webhook', enabled: true, connectedAt: thirtyDaysAgo, status: 'connected', config: { url: 'https://api.example.com/webhook' } },
129
- ],
130
- apiKeys: [
131
- { id: 'key_1', name: 'Production Key', prefix: 'xk_prod_...a3f2', createdAt: thirtyDaysAgo, lastUsed: now },
132
- { id: 'key_2', name: 'Development Key', prefix: 'xk_dev_...b1c4', createdAt: now, lastUsed: now },
133
- ],
134
- webhookEndpoints: [
135
- { id: 'wh_1', url: 'https://api.example.com/webhook', events: ['agent.started', 'agent.completed'], enabled: true, secret: 'whsec_...x9y2', createdAt: thirtyDaysAgo },
136
- ],
137
- },
138
- environment: {
139
- variables: [
140
- { id: 'env_1', key: 'API_BASE_URL', value: 'https://api.example.com', isSecret: false, updatedAt: now },
141
- { id: 'env_2', key: 'DATABASE_URL', value: '••••••••••••', isSecret: true, updatedAt: thirtyDaysAgo },
142
- { id: 'env_3', key: 'OPENAI_API_KEY', value: '••••••••••••', isSecret: true, updatedAt: thirtyDaysAgo },
143
- ],
144
- },
145
- notifications: {
146
- emailEnabled: true,
147
- slackEnabled: false,
148
- discordEnabled: false,
149
- webhookEnabled: true,
150
- rules: [
151
- { id: 'rule_1', event: 'Agent Error', channel: 'email', enabled: true, description: 'Notify when an agent encounters an error' },
152
- { id: 'rule_2', event: 'Task Completed', channel: 'webhook', enabled: true, description: 'Webhook on task completion' },
153
- { id: 'rule_3', event: 'Quota Warning', channel: 'email', enabled: true, description: 'Alert when approaching usage limits' },
154
- ],
155
- digestFrequency: 'daily',
156
- },
157
- security: {
158
- auditLog: [
159
- { id: 'log_1', action: 'member.added', actor: 'You', target: 'Alice Chen', timestamp: now, details: 'Added as admin' },
160
- { id: 'log_2', action: 'settings.updated', actor: 'You', target: 'General Settings', timestamp: thirtyDaysAgo, details: 'Updated workspace name' },
161
- { id: 'log_3', action: 'agent.created', actor: 'Alice Chen', target: 'Code Reviewer', timestamp: thirtyDaysAgo, details: 'Created new agent' },
162
- { id: 'log_4', action: 'apikey.created', actor: 'You', target: 'Production Key', timestamp: thirtyDaysAgo, details: 'Created API key' },
163
- { id: 'log_5', action: 'member.role_changed', actor: 'You', target: 'Bob Smith', timestamp: now, details: 'Changed role to editor' },
164
- ],
165
- ipAllowlist: [],
166
- require2FA: false,
167
- requireApiKeyAuth: true,
168
- sessionTimeout: 30,
169
- },
170
- exportBackup: {
171
- autoBackupEnabled: true,
172
- backupFrequency: 'weekly',
173
- retentionDays: 30,
174
- availableBackups: [
175
- { id: 'bk_1', name: 'Auto Backup', size: '2.4 MB', createdAt: now, type: 'auto' },
176
- { id: 'bk_2', name: 'Pre-migration Backup', size: '1.8 MB', createdAt: thirtyDaysAgo, type: 'manual' },
177
- ],
178
- availableExports: [
179
- { format: 'json', label: 'JSON Export' },
180
- { format: 'csv', label: 'CSV Export' },
181
- { format: 'yaml', label: 'YAML Export' },
49
+ { id: 'github', type: 'github', name: 'GitHub', enabled: false, connectedAt: '', status: 'disconnected' },
50
+ { id: 'slack', type: 'slack', name: 'Slack', enabled: false, connectedAt: '', status: 'disconnected' },
51
+ { id: 'discord', type: 'discord', name: 'Discord', enabled: false, connectedAt: '', status: 'disconnected' },
182
52
  ],
53
+ apiKeys: [], webhookEndpoints: [],
183
54
  },
184
- dangerZone: {
185
- canArchive: true,
186
- canTransferOwnership: true,
187
- canDelete: true,
55
+ environment: { variables: [] },
56
+ notifications: { emailEnabled: false, slackEnabled: false, discordEnabled: false, webhookEnabled: false, rules: [], digestFrequency: 'daily' },
57
+ security: { auditLog: [], ipAllowlist: [], require2FA: false, requireApiKeyAuth: false, sessionTimeout: 0 },
58
+ exportBackup: { autoBackupEnabled: false, backupFrequency: 'weekly', retentionDays: 30, availableBackups: [], availableExports: [{ format: 'json', label: 'JSON Export' }, { format: 'csv', label: 'CSV Export' }] },
59
+ dangerZone: { canArchive: true, canTransferOwnership: false, canDelete: true },
60
+ };
61
+ }
62
+ let selectedHierarchyBaseline;
63
+ const profileDrafts = new WeakMap();
64
+ function currentProfileDrafts() {
65
+ const storage = getAgentPlatformBridge()?.workspaceStorage;
66
+ if (!storage)
67
+ return new Map();
68
+ let drafts = profileDrafts.get(storage);
69
+ if (!drafts) {
70
+ drafts = new Map();
71
+ profileDrafts.set(storage, drafts);
72
+ }
73
+ return drafts;
74
+ }
75
+ function profileIdentityExists(identity, workspaces) {
76
+ const [workspaceId, createdAt, teamId, agentId] = JSON.parse(identity);
77
+ const matches = workspaces.filter(workspace => workspace.id === workspaceId && workspace.createdAt === createdAt);
78
+ if (matches.length !== 1)
79
+ return false;
80
+ if (teamId === null)
81
+ return true;
82
+ const teams = matches[0].teams.filter(team => team.id === teamId);
83
+ return teams.length === 1 && (agentId === null || teams[0].agents.filter(agent => agent.id === agentId).length === 1);
84
+ }
85
+ export function validateProfileDraft(profile) {
86
+ if (!profile.name.trim())
87
+ return 'Name is required. Enter a name or discard profile changes.';
88
+ if (profile.name.length > 200)
89
+ return 'Name must be at most 200 characters.';
90
+ if (/[\u0000-\u001f\u007f-\u009f]/.test(profile.name))
91
+ return 'Name cannot contain control characters.';
92
+ if (profile.description.length > 4000)
93
+ return 'Description must be at most 4000 characters.';
94
+ if (/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f]/.test(profile.description))
95
+ return 'Description contains unsupported control characters.';
96
+ return undefined;
97
+ }
98
+ if (typeof window !== 'undefined')
99
+ window.addEventListener('beforeunload', event => {
100
+ if (!currentProfileDrafts().size)
101
+ return;
102
+ event.preventDefault();
103
+ event.returnValue = '';
104
+ });
105
+ /** One projection shared by initial load and acknowledged remote reconciliation. */
106
+ function projectHierarchySettings(settings, workspaces) {
107
+ const matches = workspaces.filter(w => w.id === (settings.entityType === 'workspace' ? settings.entityId : settings.workspaceId));
108
+ if (matches.length !== 1)
109
+ return undefined;
110
+ const workspace = matches[0];
111
+ const teams = settings.entityType === 'workspace' ? [] : workspace.teams.filter(t => t.id === (settings.entityType === 'team' ? settings.entityId : settings.teamId));
112
+ if (settings.entityType !== 'workspace' && teams.length !== 1)
113
+ return undefined;
114
+ const team = teams[0];
115
+ const agents = settings.entityType === 'agent' ? team.agents.filter(a => a.id === settings.entityId) : [];
116
+ if (settings.entityType === 'agent' && agents.length !== 1)
117
+ return undefined;
118
+ const agent = agents[0];
119
+ const entity = agent ?? team ?? workspace;
120
+ const defaults = settings.entityType === 'workspace' ? workspace.agentDefaults
121
+ : settings.entityType === 'team' ? { ...workspace.agentDefaults, ...team?.agentDefaults }
122
+ : { model: agent?.model, systemPrompt: agent?.systemPrompt, tools: agent?.tools ?? toolsForAgentCapabilities(agent?.capabilities) };
123
+ const createdAt = Number.isFinite(workspace.createdAt) ? new Date(workspace.createdAt).toISOString() : '';
124
+ return {
125
+ // Team/Agent IDs have no generation field in the current canonical schema.
126
+ // Observed disappearance invalidates selection; workspace recreation is exact.
127
+ identity: JSON.stringify([workspace.id, workspace.createdAt, team?.id ?? null, agent?.id ?? null]),
128
+ entityName: entity.name, workspaceName: workspace.name, ...(team ? { teamName: team.name } : {}),
129
+ general: {
130
+ name: entity.name, description: entity.description ?? '',
131
+ slug: entity.name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''),
132
+ icon: settings.entityType === 'workspace' ? 'building' : settings.entityType === 'team' ? 'users' : 'bot',
133
+ createdAt: settings.entityType === 'workspace' ? createdAt : settings.general.createdAt,
134
+ updatedAt: settings.entityType === 'workspace' ? (workspace.updatedAt ? new Date(workspace.updatedAt).toISOString() : createdAt) : settings.general.updatedAt,
188
135
  },
136
+ ...(settings.defaultAgentConfig ? { defaultAgentConfig: {
137
+ defaultModel: defaults?.model ?? '', systemInstructions: defaults?.systemPrompt ?? '',
138
+ enabledTools: [...(defaults?.tools ?? toolsForAgentCapabilities())],
139
+ availableTools: settings.defaultAgentConfig.availableTools,
140
+ } } : {}),
189
141
  };
190
142
  }
143
+ function mergeAcknowledgedFields(local, previous, incoming) {
144
+ const merged = { ...local };
145
+ for (const key of Object.keys(incoming)) {
146
+ if (JSON.stringify(local[key]) === JSON.stringify(previous[key]))
147
+ merged[key] = incoming[key];
148
+ }
149
+ return merged;
150
+ }
191
151
  function normalizeBackupFrequency(value, fallback) {
192
152
  return value === 'daily' || value === 'weekly' || value === 'monthly' ? value : fallback;
193
153
  }
194
- // Async load real data for IPC-backed sections (export, usage, security)
195
- async function loadAsyncSectionData(entityId, entityType) {
154
+ function backupScope(settings) {
155
+ const scope = {
156
+ workspaceId: settings.entityType === 'workspace' ? settings.entityId : settings.workspaceId,
157
+ teamId: settings.entityType === 'team' ? settings.entityId : settings.teamId,
158
+ agentId: settings.entityType === 'agent' ? settings.entityId : undefined,
159
+ };
160
+ return { ...scope, caller: { ...scope } };
161
+ }
162
+ function requireSuccess(value, operation) {
163
+ if (!value || typeof value !== 'object' || value.success !== true) {
164
+ const error = value?.error;
165
+ throw new Error(typeof error === 'string' ? error : `${operation} was not confirmed by the host.`);
166
+ }
167
+ }
168
+ function settingsError(error) {
169
+ return error instanceof Error ? error.message : 'The host operation failed.';
170
+ }
171
+ // Each load has a generation, not just an entity id: A -> B -> A must not accept
172
+ // a response from the first A. Independent services load concurrently.
173
+ async function loadAsyncSectionData(settings, generation) {
196
174
  const store = useEntitySettingsStore;
197
- // Load real backup data
198
- try {
199
- const [backupList, backupSettings] = await Promise.all([
200
- getAgentPlatformBridge()?.exportBackup?.listBackups?.(),
201
- getAgentPlatformBridge()?.exportBackup?.getSettings?.(),
202
- ]);
203
- const current = store.getState().settings;
204
- if (current?.entityId === entityId) {
205
- const normalizedBackupFrequency = normalizeBackupFrequency(backupSettings?.settings?.frequency, current.exportBackup.backupFrequency);
206
- store.setState({
207
- settings: {
208
- ...current,
209
- exportBackup: {
210
- ...current.exportBackup,
211
- autoBackupEnabled: backupSettings?.settings?.autoBackupEnabled ?? current.exportBackup.autoBackupEnabled,
212
- backupFrequency: normalizedBackupFrequency,
213
- retentionDays: backupSettings?.settings?.retentionDays ?? current.exportBackup.retentionDays,
214
- availableBackups: (backupList?.backups || []).map((b) => ({
215
- id: b.id,
216
- name: b.name,
217
- size: formatBytes(b.size),
218
- createdAt: b.createdAt,
219
- type: 'manual',
220
- })),
221
- },
222
- },
223
- });
175
+ const load = async (section, read) => {
176
+ try {
177
+ const patch = await read();
178
+ const state = store.getState();
179
+ if (state.loadGeneration !== generation || !state.settings)
180
+ return;
181
+ store.setState({ settings: { ...state.settings, ...patch } });
224
182
  }
225
- }
226
- catch { /* silent */ }
227
- // Load real usage data
183
+ catch (error) {
184
+ if (store.getState().loadGeneration === generation) {
185
+ store.setState(state => ({ sectionErrors: { ...state.sectionErrors, [section]: settingsError(error) } }));
186
+ }
187
+ }
188
+ finally {
189
+ if (store.getState().loadGeneration === generation) {
190
+ store.setState(state => ({ sectionLoading: { ...state.sectionLoading, [section]: false } }));
191
+ }
192
+ }
193
+ };
194
+ await Promise.all([
195
+ load('environment', async () => {
196
+ const api = getAgentPlatformBridge().workspace.environment;
197
+ if (!api)
198
+ throw new Error('Protected environment service is unavailable on this host.');
199
+ const result = await api({ scope: environmentScope(settings), action: 'list' });
200
+ requireSuccess(result, 'Environment load');
201
+ return { environment: environmentMetadata(result) };
202
+ }),
203
+ load('exportBackup', async () => {
204
+ const api = getAgentPlatformBridge().exportBackup;
205
+ if (!api?.listBackups || !api.getSettings)
206
+ throw new Error('Backup service is not available on this host.');
207
+ const [list, policy] = await Promise.all([api.listBackups(backupScope(settings)), api.getSettings(backupScope(settings))]);
208
+ requireSuccess(list, 'Backup listing');
209
+ requireSuccess(policy, 'Backup policy');
210
+ if (!Array.isArray(list.backups) || !policy.settings)
211
+ throw new Error('The host returned an invalid backup response.');
212
+ return { exportBackup: {
213
+ ...settings.exportBackup,
214
+ autoBackupEnabled: policy.settings.autoBackupEnabled,
215
+ backupFrequency: normalizeBackupFrequency(policy.settings.frequency, settings.exportBackup.backupFrequency),
216
+ retentionDays: policy.settings.retentionDays,
217
+ lastError: policy.settings.lastError,
218
+ availableBackups: list.backups.map(b => ({
219
+ id: b.id, name: b.name, size: formatBytes(b.size), createdAt: b.createdAt, type: 'manual',
220
+ })),
221
+ } };
222
+ }),
223
+ load('usage', async () => {
224
+ const api = getAgentPlatformBridge().usage;
225
+ if (!api?.snapshot)
226
+ throw new Error('Scoped usage service is not available on this host.');
227
+ const result = await api.snapshot({ entityType: settings.entityType, entityId: settings.entityId });
228
+ if (!isAgentUsageResult(result))
229
+ throw new Error('The host returned an invalid usage response.');
230
+ if (!result.success)
231
+ throw new Error(result.error);
232
+ const summary = result.snapshot;
233
+ if (!Number.isSafeInteger(summary.totalTokens) || summary.totalTokens < 0 || !Array.isArray(summary.costByModel) || !Array.isArray(summary.topAgents)) {
234
+ throw new Error('The host returned an invalid usage response.');
235
+ }
236
+ return { usage: {
237
+ totalTokens: summary.totalTokens, totalCost: summary.totalCost, totalRequests: summary.totalRequests,
238
+ unmeasuredRequests: summary.unmeasuredRequests, observedAt: summary.observedAt,
239
+ dailyUsage: summary.dailyUsage, weeklyUsage: summary.weeklyUsage, monthlyUsage: summary.monthlyUsage,
240
+ costByModel: summary.costByModel, topAgents: summary.topAgents,
241
+ } };
242
+ }),
243
+ ]);
244
+ }
245
+ async function runBackupOperation(operation) {
246
+ const store = useEntitySettingsStore;
247
+ const state = store.getState();
248
+ if (!state.settings || state.backupBusy || state.sectionLoading.exportBackup)
249
+ return;
250
+ const { settings, loadGeneration } = state;
251
+ store.setState({ backupBusy: true, sectionErrors: { ...state.sectionErrors, exportBackup: undefined } });
228
252
  try {
229
- const [summary, byModel, topAgents] = await Promise.all([
230
- getAgentPlatformBridge()?.usage?.summary?.(entityType, entityId, 'daily'),
231
- getAgentPlatformBridge()?.usage?.byModel?.(),
232
- getAgentPlatformBridge()?.usage?.topAgents?.(),
233
- ]);
234
- const current = store.getState().settings;
235
- if (current?.entityId === entityId) {
236
- const usageSummary = (summary || {});
237
- const usageByModel = (byModel || {});
238
- const usageTopAgents = (topAgents || {});
239
- store.setState({
240
- settings: {
241
- ...current,
242
- usage: {
243
- totalTokens: usageSummary.totalTokens ?? 0,
244
- totalCost: usageSummary.totalCost ?? 0,
245
- totalRequests: usageSummary.totalRequests ?? 0,
246
- dailyUsage: usageSummary.dataPoints || [],
247
- weeklyUsage: [],
248
- monthlyUsage: [],
249
- costByModel: usageByModel.costByModel || [],
250
- topAgents: usageTopAgents.topAgents || [],
251
- },
252
- },
253
- });
253
+ const api = getAgentPlatformBridge().exportBackup;
254
+ if (!api)
255
+ throw new Error('Backup service is not available on this host.');
256
+ const patch = await operation(api, settings);
257
+ const current = store.getState();
258
+ if (current.loadGeneration === loadGeneration && current.settings && patch) {
259
+ store.setState({ settings: { ...current.settings, exportBackup: { ...current.settings.exportBackup, ...patch } } });
254
260
  }
255
261
  }
256
- catch { /* silent */ }
257
- // Load real audit log
258
- try {
259
- const result = await getAgentPlatformBridge()?.audit?.list?.(20);
260
- const current = store.getState().settings;
261
- if (current?.entityId === entityId) {
262
- const auditEntries = (result || {}).entries || [];
263
- store.setState({
264
- settings: {
265
- ...current,
266
- security: {
267
- ...current.security,
268
- auditLog: auditEntries.map((e, i) => ({
269
- id: `audit_${i}`,
270
- action: e.action,
271
- actor: e.user || 'You',
272
- target: e.entity || '',
273
- timestamp: e.timestamp,
274
- details: e.details || '',
275
- })),
276
- },
277
- },
278
- });
262
+ catch (error) {
263
+ if (store.getState().loadGeneration === loadGeneration) {
264
+ store.setState(current => ({ sectionErrors: { ...current.sectionErrors, exportBackup: settingsError(error) } }));
279
265
  }
280
266
  }
281
- catch { /* silent */ }
267
+ finally {
268
+ if (store.getState().loadGeneration === loadGeneration)
269
+ store.setState({ backupBusy: false });
270
+ }
282
271
  }
283
272
  function formatBytes(bytes) {
284
273
  if (bytes < 1024)
@@ -303,39 +292,69 @@ function syncNotificationsToWorkspaceStore(settings, notif) {
303
292
  });
304
293
  }
305
294
  // Sync env vars from settings back to workspace store
306
- function syncEnvVarsToWorkspaceStore(settings, vars) {
307
- const envVars = vars.map(v => ({ key: v.key, value: v.value, isSecret: v.isSecret }));
308
- const ws = useWorkspaceStore.getState();
309
- if (settings.entityType === 'workspace') {
310
- ws.updateWorkspace(settings.entityId, { envVars });
295
+ function environmentScope(settings) {
296
+ const value = backupScope(settings);
297
+ return { workspaceId: String(value.workspaceId || ''), ...(value.teamId ? { teamId: String(value.teamId) } : {}), ...(value.agentId ? { agentId: String(value.agentId) } : {}) };
298
+ }
299
+ function environmentMetadata(result) {
300
+ if (!Array.isArray(result.variables))
301
+ throw new Error('Invalid environment metadata from host');
302
+ return { environmentRevision: result.environmentRevision, protectedStorageAvailable: result.protectedStorageAvailable, variables: result.variables.map(variable => ({ ...variable, id: variable.key, value: '' })) };
303
+ }
304
+ async function changeEnvironment(input) {
305
+ const store = useEntitySettingsStore;
306
+ const initial = store.getState();
307
+ if (!initial.settings || initial.environmentBusy || initial.sectionLoading.environment)
308
+ return false;
309
+ const generation = initial.loadGeneration;
310
+ store.setState({ environmentBusy: true, sectionErrors: { ...initial.sectionErrors, environment: undefined } });
311
+ try {
312
+ const bridge = getAgentPlatformBridge();
313
+ const api = bridge.workspace.environment;
314
+ if (!api)
315
+ throw new Error('Protected environment service is unavailable on this host.');
316
+ const state = await bridge.workspaceStorage.load();
317
+ if (!state.success || !state.revision)
318
+ throw new Error('Reload workspace state before changing environment values.');
319
+ const result = await api({ ...input, scope: environmentScope(initial.settings), expectedRevision: state.revision, expectedEnvironmentRevision: initial.settings.environment.environmentRevision });
320
+ requireSuccess(result, 'Environment update');
321
+ if (store.getState().loadGeneration === generation)
322
+ store.setState(current => ({ settings: current.settings ? { ...current.settings, environment: environmentMetadata(result) } : null }));
323
+ return true;
311
324
  }
312
- else if (settings.entityType === 'team' && settings.workspaceId) {
313
- ws.updateTeam(settings.workspaceId, settings.entityId, { envVars });
325
+ catch (error) {
326
+ if (store.getState().loadGeneration === generation)
327
+ store.setState(current => ({ sectionErrors: { ...current.sectionErrors, environment: settingsError(error) } }));
328
+ return false;
329
+ }
330
+ finally {
331
+ if (store.getState().loadGeneration === generation)
332
+ store.setState({ environmentBusy: false });
314
333
  }
315
334
  }
316
335
  export const useEntitySettingsStore = create((set, get) => ({
336
+ environmentBusy: false,
317
337
  settings: null,
318
338
  activeSection: 'general',
319
339
  isLoading: false,
320
340
  isDirty: false,
341
+ profileDraftPending: false,
342
+ profileDraftError: undefined,
343
+ loadGeneration: 0,
344
+ sectionErrors: {},
345
+ sectionLoading: {},
346
+ backupBusy: false,
321
347
  loadSettings: (entityId, entityType, entityName, extra) => {
322
- set({ isLoading: true });
323
- // Start with mock structure, then overlay real data from workspace store
324
- const settings = generateMockSettings(entityId, entityType, entityName, extra);
348
+ const generation = get().loadGeneration + 1;
349
+ set({ isLoading: true, loadGeneration: generation, sectionErrors: {}, backupBusy: false,
350
+ environmentBusy: false, backupRestoreResult: undefined,
351
+ sectionLoading: { exportBackup: true, usage: true, environment: true } });
352
+ const settings = createInitialSettings(entityId, entityType, entityName, extra);
325
353
  const wsStore = useWorkspaceStore.getState();
326
354
  // Get current user from auth store for real owner info
327
- const authUser = useAuthStore.getState().user;
328
355
  if (entityType === 'workspace') {
329
356
  const ws = wsStore.workspaces.find(w => w.id === entityId);
330
357
  if (ws) {
331
- // General — all real
332
- const slug = ws.name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
333
- settings.general.name = ws.name;
334
- settings.general.description = ws.description || '';
335
- settings.general.slug = slug;
336
- settings.general.icon = 'building';
337
- settings.general.createdAt = ws.createdAt ? new Date(ws.createdAt).toISOString() : settings.general.createdAt;
338
- settings.general.updatedAt = ws.updatedAt ? new Date(ws.updatedAt).toISOString() : settings.general.createdAt;
339
358
  // Resource limits — real quotas from hierarchy
340
359
  const teamCount = ws.teams.length;
341
360
  const agentCount = ws.teams.reduce((sum, t) => sum + t.agents.length, 0);
@@ -351,6 +370,8 @@ export const useEntitySettingsStore = create((set, get) => ({
351
370
  variables: (ws.envVars || []).map((v, i) => ({
352
371
  id: `env_${i}`,
353
372
  ...v,
373
+ value: '',
374
+ legacy: true,
354
375
  updatedAt: new Date().toISOString(),
355
376
  })),
356
377
  };
@@ -369,11 +390,9 @@ export const useEntitySettingsStore = create((set, get) => ({
369
390
  };
370
391
  }
371
392
  // Access — real current user as owner, no fake members
372
- const ownerName = authUser?.display_name || authUser?.username || 'You';
373
- const ownerEmail = authUser?.email || '';
374
393
  settings.access = {
375
- owner: { id: 'self', name: ownerName, email: ownerEmail, role: 'owner', joinedAt: settings.general.createdAt },
376
- members: [{ id: 'self', name: ownerName, email: ownerEmail, role: 'owner', joinedAt: settings.general.createdAt }],
394
+ owner: null,
395
+ members: [],
377
396
  pendingInvites: [],
378
397
  publicAccess: ws.access?.publicAccess ?? false,
379
398
  allowGuestViewing: ws.access?.allowGuestViewing ?? false,
@@ -397,10 +416,6 @@ export const useEntitySettingsStore = create((set, get) => ({
397
416
  const ws = wsStore.workspaces.find(w => w.id === extra.workspaceId);
398
417
  const team = ws?.teams.find(t => t.id === entityId);
399
418
  if (team) {
400
- settings.general.name = team.name;
401
- settings.general.description = team.description || '';
402
- settings.general.slug = team.name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
403
- settings.general.icon = 'users';
404
419
  settings.resourceLimits.quotas = [
405
420
  { label: 'Agents', current: team.agents.length, limit: 50, unit: 'agents' },
406
421
  ];
@@ -410,15 +425,15 @@ export const useEntitySettingsStore = create((set, get) => ({
410
425
  variables: (team.envVars || []).map((v, i) => ({
411
426
  id: `env_${i}`,
412
427
  ...v,
428
+ value: '',
429
+ legacy: true,
413
430
  updatedAt: new Date().toISOString(),
414
431
  })),
415
432
  };
416
433
  // Real owner
417
- const ownerName = authUser?.display_name || authUser?.username || 'You';
418
- const ownerEmail = authUser?.email || '';
419
434
  settings.access = {
420
- owner: { id: 'self', name: ownerName, email: ownerEmail, role: 'owner', joinedAt: settings.general.createdAt },
421
- members: [{ id: 'self', name: ownerName, email: ownerEmail, role: 'owner', joinedAt: settings.general.createdAt }],
435
+ owner: null,
436
+ members: [],
422
437
  pendingInvites: [],
423
438
  publicAccess: false,
424
439
  allowGuestViewing: false,
@@ -430,65 +445,102 @@ export const useEntitySettingsStore = create((set, get) => ({
430
445
  const team = ws?.teams.find(t => t.id === extra.teamId);
431
446
  const agent = team?.agents.find(a => a.id === entityId);
432
447
  if (agent) {
433
- settings.general.name = agent.name;
434
- settings.general.description = agent.description || '';
435
- settings.general.slug = agent.name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
436
- settings.general.icon = 'bot';
437
448
  settings.resourceLimits.quotas = [
438
449
  { label: 'Conversations', current: Object.values(useAgentChatStore.getState().conversations).filter(c => c.agentId === entityId).length, limit: 1000, unit: 'convs' },
439
450
  ];
440
451
  // Real owner
441
- const ownerName = authUser?.display_name || authUser?.username || 'You';
442
- const ownerEmail = authUser?.email || '';
443
452
  settings.access = {
444
- owner: { id: 'self', name: ownerName, email: ownerEmail, role: 'owner', joinedAt: settings.general.createdAt },
445
- members: [{ id: 'self', name: ownerName, email: ownerEmail, role: 'owner', joinedAt: settings.general.createdAt }],
453
+ owner: null,
454
+ members: [],
446
455
  pendingInvites: [],
447
456
  publicAccess: false,
448
457
  allowGuestViewing: false,
449
458
  };
450
- if (settings.defaultAgentConfig) {
451
- settings.defaultAgentConfig.defaultModel = agent.model || 'claude-sonnet-4-6';
452
- settings.defaultAgentConfig.systemInstructions = agent.systemPrompt || '';
453
- settings.defaultAgentConfig.enabledTools = agent.tools || ['web-search', 'code-execution', 'file-read'];
454
- }
455
459
  settings.resourceLimits.rateLimitRpm = agent.rateLimits?.requestsPerMinute ?? settings.resourceLimits.rateLimitRpm;
456
460
  settings.resourceLimits.rateLimitTpd = agent.rateLimits?.tokensPerDay ?? settings.resourceLimits.rateLimitTpd;
457
461
  }
458
462
  }
459
- set({ settings, isLoading: false, activeSection: 'general', isDirty: false });
463
+ selectedHierarchyBaseline = projectHierarchySettings(settings, wsStore.workspaces);
464
+ if (selectedHierarchyBaseline) {
465
+ const { identity: _identity, ...projection } = selectedHierarchyBaseline;
466
+ Object.assign(settings, projection);
467
+ }
468
+ const draft = selectedHierarchyBaseline && currentProfileDrafts().get(selectedHierarchyBaseline.identity);
469
+ if (draft)
470
+ settings.general = { ...settings.general, ...draft.fields };
471
+ set({ settings, isLoading: false, activeSection: 'general', isDirty: Boolean(draft),
472
+ profileDraftPending: Boolean(draft), profileDraftError: draft ? validateProfileDraft(settings.general) : undefined });
460
473
  // Async: load real data for IPC-backed sections
461
- loadAsyncSectionData(entityId, entityType);
474
+ void loadAsyncSectionData(settings, generation);
462
475
  },
463
476
  setActiveSection: (section) => set({ activeSection: section }),
464
- clearSettings: () => set({ settings: null, activeSection: 'general', isDirty: false }),
477
+ clearSettings: () => {
478
+ selectedHierarchyBaseline = undefined;
479
+ set(state => ({ settings: null, activeSection: 'general', isDirty: false,
480
+ profileDraftPending: false, profileDraftError: undefined,
481
+ loadGeneration: state.loadGeneration + 1, sectionErrors: {}, sectionLoading: {}, backupBusy: false }));
482
+ },
465
483
  updateGeneral: (updates) => {
466
484
  const { settings } = get();
467
- if (!settings)
485
+ const identity = selectedHierarchyBaseline?.identity;
486
+ if (!settings || !identity)
487
+ return;
488
+ const fields = {
489
+ ...(updates.name !== undefined ? { name: updates.name } : {}),
490
+ ...(updates.description !== undefined ? { description: updates.description } : {}),
491
+ };
492
+ if (!Object.keys(fields).length)
468
493
  return;
494
+ const drafts = currentProfileDrafts();
495
+ const previous = drafts.get(identity);
496
+ const draft = { fields: { ...previous?.fields, ...fields }, submitted: { ...previous?.submitted } };
497
+ drafts.set(identity, draft);
498
+ const general = { ...settings.general, ...draft.fields };
499
+ const error = validateProfileDraft(general);
469
500
  set({
470
- settings: { ...settings, general: { ...settings.general, ...updates, updatedAt: new Date().toISOString() } },
471
- isDirty: true,
501
+ settings: { ...settings, general }, isDirty: true, profileDraftPending: true, profileDraftError: error,
472
502
  });
473
- // Persist to workspace store
474
- const ws = useWorkspaceStore.getState();
475
- if (settings.entityType === 'workspace') {
476
- ws.updateWorkspace(settings.entityId, {
477
- name: updates.name || settings.general.name,
478
- description: updates.description ?? settings.general.description,
479
- });
480
- }
481
- else if (settings.entityType === 'team' && settings.workspaceId) {
482
- ws.updateTeam(settings.workspaceId, settings.entityId, {
483
- name: updates.name || settings.general.name,
484
- description: updates.description ?? settings.general.description,
485
- });
503
+ if (!error)
504
+ void persistProfileFields(settings, identity, drafts, draft.fields);
505
+ },
506
+ discardProfileChanges: async () => {
507
+ const state = get(), identity = selectedHierarchyBaseline?.identity;
508
+ if (!state.settings || !identity)
509
+ return false;
510
+ const drafts = currentProfileDrafts(), draft = drafts.get(identity);
511
+ if (!draft)
512
+ return true;
513
+ try {
514
+ const loaded = await getAgentPlatformBridge().workspaceStorage.load();
515
+ if (!loaded.success || !Array.isArray(loaded.workspaces))
516
+ throw new Error('Acknowledged profile is unavailable; draft retained.');
517
+ const incoming = projectHierarchySettings(state.settings, loaded.workspaces);
518
+ if (!incoming || incoming.identity !== identity)
519
+ throw new Error('The original profile no longer exists; draft retained.');
520
+ if (selectedHierarchyBaseline?.identity !== identity || drafts.get(identity) !== draft)
521
+ return false;
522
+ // Submitted edits may still exist in the optimistic hierarchy. Revert only
523
+ // those profile fields through its existing CAS path, never reset the tree.
524
+ if (Object.keys(draft.submitted).length) {
525
+ const revert = Object.fromEntries(Object.keys(draft.submitted).map(key => [key, incoming.general[key]]));
526
+ draft.fields = revert;
527
+ if (!await persistProfileFields(state.settings, identity, drafts, revert))
528
+ return false;
529
+ }
530
+ if (selectedHierarchyBaseline?.identity !== identity || (drafts.has(identity) && drafts.get(identity) !== draft))
531
+ return false;
532
+ drafts.delete(identity);
533
+ selectedHierarchyBaseline = incoming;
534
+ const current = get();
535
+ if (current.settings && projectHierarchySettings(current.settings, loaded.workspaces)?.identity === identity) {
536
+ set({ settings: { ...current.settings, general: { ...current.settings.general, name: incoming.general.name, description: incoming.general.description, slug: incoming.general.slug } }, profileDraftPending: false, profileDraftError: undefined });
537
+ }
538
+ return true;
486
539
  }
487
- else if (settings.entityType === 'agent' && settings.workspaceId && settings.teamId) {
488
- ws.updateAgent(settings.workspaceId, settings.teamId, settings.entityId, {
489
- name: updates.name || settings.general.name,
490
- description: updates.description ?? settings.general.description,
491
- });
540
+ catch (error) {
541
+ if (selectedHierarchyBaseline?.identity === identity)
542
+ set({ profileDraftError: error instanceof Error ? error.message : 'Profile discard failed; draft retained.' });
543
+ return false;
492
544
  }
493
545
  },
494
546
  updateDefaultAgentConfig: (updates) => {
@@ -499,6 +551,21 @@ export const useEntitySettingsStore = create((set, get) => ({
499
551
  settings: { ...settings, defaultAgentConfig: { ...settings.defaultAgentConfig, ...updates } },
500
552
  isDirty: true,
501
553
  });
554
+ const workspace = useWorkspaceStore.getState().workspaces.find(w => w.id === (settings.workspaceId || settings.entityId));
555
+ const existing = settings.entityType === 'workspace' ? workspace?.agentDefaults
556
+ : workspace?.teams.find(t => t.id === settings.entityId)?.agentDefaults;
557
+ const defaults = {
558
+ ...existing,
559
+ ...(updates.defaultModel !== undefined ? { model: updates.defaultModel } : {}),
560
+ ...(updates.systemInstructions !== undefined ? { systemPrompt: updates.systemInstructions } : {}),
561
+ ...(updates.enabledTools !== undefined ? { tools: [...updates.enabledTools] } : {}),
562
+ };
563
+ if (settings.entityType === 'workspace') {
564
+ useWorkspaceStore.getState().updateWorkspace(settings.entityId, { agentDefaults: defaults });
565
+ }
566
+ else if (settings.entityType === 'team' && settings.workspaceId) {
567
+ useWorkspaceStore.getState().updateTeam(settings.workspaceId, settings.entityId, { agentDefaults: defaults });
568
+ }
502
569
  // Persist to workspace store — for agents, update model/prompt/tools
503
570
  if (settings.entityType === 'agent' && settings.workspaceId && settings.teamId) {
504
571
  const agentUpdates = {};
@@ -512,22 +579,7 @@ export const useEntitySettingsStore = create((set, get) => ({
512
579
  }
513
580
  },
514
581
  updateAccess: (updates) => {
515
- const { settings } = get();
516
- if (!settings)
517
- return;
518
- set({
519
- settings: { ...settings, access: { ...settings.access, ...updates } },
520
- isDirty: true,
521
- });
522
- // Persist access settings to workspace store
523
- if (settings.entityType === 'workspace') {
524
- useWorkspaceStore.getState().updateWorkspace(settings.entityId, {
525
- access: {
526
- publicAccess: updates.publicAccess ?? settings.access.publicAccess,
527
- allowGuestViewing: updates.allowGuestViewing ?? settings.access.allowGuestViewing,
528
- },
529
- });
530
- }
582
+ set(state => ({ sectionErrors: { ...state.sectionErrors, access: 'Workspace sharing is not connected to an access-control authority. Access was not changed.' } }));
531
583
  },
532
584
  updateResourceLimits: (updates) => {
533
585
  const { settings } = get();
@@ -577,155 +629,55 @@ export const useEntitySettingsStore = create((set, get) => ({
577
629
  }
578
630
  },
579
631
  updateSecurity: (updates) => {
580
- const { settings } = get();
581
- if (!settings)
582
- return;
583
- const merged = { ...settings.security, ...updates };
584
- set({
585
- settings: { ...settings, security: merged },
586
- isDirty: true,
587
- });
588
- // Persist security settings to workspace store
589
- if (settings.entityType === 'workspace') {
590
- useWorkspaceStore.getState().updateWorkspace(settings.entityId, {
591
- security: {
592
- require2FA: merged.require2FA,
593
- requireApiKeyAuth: merged.requireApiKeyAuth,
594
- sessionTimeout: merged.sessionTimeout,
595
- ipAllowlist: [...merged.ipAllowlist],
596
- },
597
- });
598
- }
632
+ set(state => ({ sectionErrors: { ...state.sectionErrors, security: 'Workspace authentication policy is not connected to an enforcement authority. Security settings were not changed.' } }));
599
633
  },
600
- updateExportBackup: (updates) => {
601
- const { settings } = get();
602
- if (!settings)
603
- return;
604
- set({
605
- settings: { ...settings, exportBackup: { ...settings.exportBackup, ...updates } },
606
- isDirty: true,
607
- });
608
- // Persist backup settings
609
- getAgentPlatformBridge()?.exportBackup?.updateSettings?.({
634
+ updateExportBackup: (updates) => runBackupOperation(async (api, settings) => {
635
+ const policy = {
610
636
  autoBackupEnabled: updates.autoBackupEnabled ?? settings.exportBackup.autoBackupEnabled,
611
637
  frequency: updates.backupFrequency ?? settings.exportBackup.backupFrequency,
612
638
  retentionDays: updates.retentionDays ?? settings.exportBackup.retentionDays,
613
- }).catch(() => { });
614
- },
639
+ };
640
+ if (!Number.isInteger(policy.retentionDays) || policy.retentionDays < 7 || policy.retentionDays > 90) {
641
+ throw new Error('Backup retention must be an integer between 7 and 90 days.');
642
+ }
643
+ const result = await api.updateSettings({ ...backupScope(settings), ...policy });
644
+ requireSuccess(result, 'Backup policy update');
645
+ return { autoBackupEnabled: policy.autoBackupEnabled, backupFrequency: policy.frequency, retentionDays: policy.retentionDays };
646
+ }),
615
647
  addMember: (member) => {
616
- const { settings } = get();
617
- if (!settings)
618
- return;
619
- const newMember = { ...member, id: `user_${generateId()}`, joinedAt: new Date().toISOString() };
620
- set({
621
- settings: { ...settings, access: { ...settings.access, members: [...settings.access.members, newMember] } },
622
- isDirty: true,
623
- });
648
+ set(state => ({ sectionErrors: { ...state.sectionErrors, access: 'Member invitations require a connected workspace membership authority. No invitation was sent.' } }));
624
649
  },
625
650
  removeMember: (memberId) => {
626
- const { settings } = get();
627
- if (!settings)
628
- return;
629
- set({
630
- settings: {
631
- ...settings,
632
- access: { ...settings.access, members: settings.access.members.filter(m => m.id !== memberId) },
633
- },
634
- isDirty: true,
635
- });
651
+ set(state => ({ sectionErrors: { ...state.sectionErrors, access: 'Member removal requires a connected workspace membership authority. Membership was not changed.' } }));
636
652
  },
637
653
  updateMemberRole: (memberId, role) => {
638
- const { settings } = get();
639
- if (!settings)
640
- return;
641
- set({
642
- settings: {
643
- ...settings,
644
- access: {
645
- ...settings.access,
646
- members: settings.access.members.map(m => m.id === memberId ? { ...m, role } : m),
647
- },
648
- },
649
- isDirty: true,
650
- });
654
+ set(state => ({ sectionErrors: { ...state.sectionErrors, access: 'Role changes require a connected workspace membership authority. Permissions were not changed.' } }));
651
655
  },
652
656
  addIntegration: (integration) => {
653
- const { settings } = get();
654
- if (!settings)
655
- return;
656
- const newInt = { ...integration, id: `int_${generateId()}` };
657
- set({
658
- settings: {
659
- ...settings,
660
- integrations: { ...settings.integrations, integrations: [...settings.integrations.integrations, newInt] },
661
- },
662
- isDirty: true,
663
- });
657
+ set(state => ({ sectionErrors: { ...state.sectionErrors, integrations: 'Integration authorization is not connected on this surface. No service was connected.' } }));
664
658
  },
665
659
  removeIntegration: (integrationId) => {
666
- const { settings } = get();
667
- if (!settings)
668
- return;
669
- set({
670
- settings: {
671
- ...settings,
672
- integrations: {
673
- ...settings.integrations,
674
- integrations: settings.integrations.integrations.filter(i => i.id !== integrationId),
675
- },
676
- },
677
- isDirty: true,
678
- });
660
+ set(state => ({ sectionErrors: { ...state.sectionErrors, integrations: 'Integration revocation is not connected on this surface. No service was disconnected.' } }));
679
661
  },
680
662
  toggleIntegration: (integrationId) => {
681
- const { settings } = get();
682
- if (!settings)
683
- return;
684
- set({
685
- settings: {
686
- ...settings,
687
- integrations: {
688
- ...settings.integrations,
689
- integrations: settings.integrations.integrations.map(i => i.id === integrationId ? { ...i, enabled: !i.enabled, status: !i.enabled ? 'connected' : 'disconnected' } : i),
690
- },
691
- },
692
- isDirty: true,
693
- });
663
+ set(state => ({ sectionErrors: { ...state.sectionErrors, integrations: 'Integration authorization is not connected on this surface. Connection status was not changed.' } }));
694
664
  },
695
665
  addEnvironmentVariable: (variable) => {
696
- const { settings } = get();
697
- if (!settings)
698
- return;
699
- const newVar = { ...variable, id: `env_${generateId()}`, updatedAt: new Date().toISOString() };
700
- const nextVars = [...settings.environment.variables, newVar];
701
- set({
702
- settings: { ...settings, environment: { variables: nextVars } },
703
- isDirty: true,
704
- });
705
- syncEnvVarsToWorkspaceStore(settings, nextVars);
666
+ return changeEnvironment({ action: 'set', key: variable.key, value: variable.value, isSecret: variable.isSecret });
706
667
  },
707
668
  updateEnvironmentVariable: (variableId, updates) => {
708
669
  const { settings } = get();
709
670
  if (!settings)
710
- return;
711
- const nextVars = settings.environment.variables.map(v => v.id === variableId ? { ...v, ...updates, updatedAt: new Date().toISOString() } : v);
712
- set({
713
- settings: { ...settings, environment: { variables: nextVars } },
714
- isDirty: true,
715
- });
716
- syncEnvVarsToWorkspaceStore(settings, nextVars);
671
+ return Promise.resolve(false);
672
+ const current = settings.environment.variables.find(variable => variable.id === variableId);
673
+ if (!current || updates.value === undefined)
674
+ return Promise.resolve(false);
675
+ return changeEnvironment({ action: 'set', key: current.key, value: updates.value, isSecret: updates.isSecret ?? current.isSecret });
717
676
  },
718
677
  deleteEnvironmentVariable: (variableId) => {
719
- const { settings } = get();
720
- if (!settings)
721
- return;
722
- const nextVars = settings.environment.variables.filter(v => v.id !== variableId);
723
- set({
724
- settings: { ...settings, environment: { variables: nextVars } },
725
- isDirty: true,
726
- });
727
- syncEnvVarsToWorkspaceStore(settings, nextVars);
678
+ return changeEnvironment({ action: 'delete', key: variableId });
728
679
  },
680
+ migrateEnvironmentVariables: () => changeEnvironment({ action: 'migrate' }),
729
681
  addNotificationRule: (rule) => {
730
682
  const { settings } = get();
731
683
  if (!settings)
@@ -761,156 +713,177 @@ export const useEntitySettingsStore = create((set, get) => ({
761
713
  syncNotificationsToWorkspaceStore(settings, { ...settings.notifications, rules: nextRules });
762
714
  },
763
715
  addApiKey: (key) => {
764
- const { settings } = get();
765
- if (!settings)
766
- return;
767
- const now = new Date().toISOString();
768
- const newKey = { ...key, id: `key_${generateId()}`, createdAt: now, lastUsed: now };
769
- set({
770
- settings: {
771
- ...settings,
772
- integrations: { ...settings.integrations, apiKeys: [...settings.integrations.apiKeys, newKey] },
773
- },
774
- isDirty: true,
775
- });
716
+ set(state => ({ sectionErrors: { ...state.sectionErrors, integrations: 'Workspace API-key issuance is not connected on this surface. No API key was created.' } }));
776
717
  },
777
718
  removeApiKey: (keyId) => {
778
- const { settings } = get();
779
- if (!settings)
780
- return;
781
- set({
782
- settings: {
783
- ...settings,
784
- integrations: { ...settings.integrations, apiKeys: settings.integrations.apiKeys.filter(k => k.id !== keyId) },
785
- },
786
- isDirty: true,
787
- });
719
+ set(state => ({ sectionErrors: { ...state.sectionErrors, integrations: 'Workspace API-key revocation is not connected on this surface. No API key was revoked.' } }));
788
720
  },
789
721
  addWebhook: (webhook) => {
790
- const { settings } = get();
791
- if (!settings)
792
- return;
793
- const newWh = { ...webhook, id: `wh_${generateId()}`, createdAt: new Date().toISOString() };
794
- set({
795
- settings: {
796
- ...settings,
797
- integrations: { ...settings.integrations, webhookEndpoints: [...settings.integrations.webhookEndpoints, newWh] },
798
- },
799
- isDirty: true,
800
- });
722
+ set(state => ({ sectionErrors: { ...state.sectionErrors, integrations: 'Webhook delivery is not connected on this surface. No webhook was registered.' } }));
801
723
  },
802
724
  removeWebhook: (webhookId) => {
803
- const { settings } = get();
804
- if (!settings)
805
- return;
806
- set({
807
- settings: {
808
- ...settings,
809
- integrations: {
810
- ...settings.integrations,
811
- webhookEndpoints: settings.integrations.webhookEndpoints.filter(w => w.id !== webhookId),
812
- },
813
- },
814
- isDirty: true,
815
- });
725
+ set(state => ({ sectionErrors: { ...state.sectionErrors, integrations: 'Webhook delivery is not connected on this surface. No webhook was removed.' } }));
816
726
  },
817
727
  toggleWebhook: (webhookId) => {
818
- const { settings } = get();
819
- if (!settings)
820
- return;
821
- set({
822
- settings: {
823
- ...settings,
824
- integrations: {
825
- ...settings.integrations,
826
- webhookEndpoints: settings.integrations.webhookEndpoints.map(w => w.id === webhookId ? { ...w, enabled: !w.enabled } : w),
827
- },
828
- },
829
- isDirty: true,
830
- });
831
- },
832
- createBackup: async (name) => {
833
- const { settings } = get();
834
- if (!settings)
835
- return;
836
- const result = await getAgentPlatformBridge()?.exportBackup?.createBackup?.(name);
837
- if (result?.success && result.backup) {
838
- const backup = result.backup;
839
- const newBackup = {
840
- id: backup.id || `backup_${Date.now()}`,
841
- name: backup.name || name || 'Backup',
842
- size: formatBytes(backup.size || 0),
843
- createdAt: backup.createdAt || new Date().toISOString(),
844
- type: 'manual',
845
- };
846
- set({
847
- settings: {
848
- ...settings,
849
- exportBackup: {
850
- ...settings.exportBackup,
851
- availableBackups: [newBackup, ...settings.exportBackup.availableBackups],
852
- },
853
- },
854
- });
855
- }
856
- },
857
- deleteBackup: async (backupId) => {
858
- const { settings } = get();
859
- if (!settings)
860
- return;
861
- await getAgentPlatformBridge()?.exportBackup?.deleteBackup?.(backupId);
862
- set({
863
- settings: {
864
- ...settings,
865
- exportBackup: {
866
- ...settings.exportBackup,
867
- availableBackups: settings.exportBackup.availableBackups.filter(b => b.id !== backupId),
868
- },
869
- },
870
- });
728
+ set(state => ({ sectionErrors: { ...state.sectionErrors, integrations: 'Webhook delivery is not connected on this surface. Delivery status was not changed.' } }));
871
729
  },
872
- archiveEntity: () => {
873
- const { settings } = get();
874
- if (!settings)
875
- return;
876
- const ws = useWorkspaceStore.getState();
877
- if (settings.entityType === 'workspace') {
878
- ws.archiveWorkspace(settings.entityId);
730
+ createBackup: (name) => runBackupOperation(async (api, settings) => {
731
+ const result = await api.createBackup({ ...backupScope(settings), name });
732
+ requireSuccess(result, 'Backup creation');
733
+ const backup = result.backup;
734
+ if (!backup?.id || !backup.createdAt || typeof backup.size !== 'number') {
735
+ throw new Error('The host did not return a valid created backup.');
879
736
  }
880
- },
737
+ return { availableBackups: [{
738
+ id: backup.id, name: backup.name || name, size: formatBytes(backup.size),
739
+ createdAt: backup.createdAt, type: 'manual',
740
+ }, ...settings.exportBackup.availableBackups] };
741
+ }),
742
+ deleteBackup: (id) => runBackupOperation(async (api, settings) => {
743
+ const result = await api.deleteBackup({ ...backupScope(settings), id });
744
+ requireSuccess(result, 'Backup deletion');
745
+ return { availableBackups: settings.exportBackup.availableBackups.filter(backup => backup.id !== id) };
746
+ }),
747
+ downloadBackup: (id) => runBackupOperation(async (api, settings) => {
748
+ requireSuccess(await api.downloadBackup({ ...backupScope(settings), id }), 'Backup download');
749
+ }),
750
+ restoreBackup: (id) => runBackupOperation(async (api, settings) => {
751
+ const result = await api.importBackup({ ...backupScope(settings), id });
752
+ requireSuccess(result, 'Backup restore');
753
+ set({ backupRestoreResult: result.restoredConversations ?? [] });
754
+ await useWorkspaceStore.getState().loadWorkspaces();
755
+ await loadLocalAgentConversations();
756
+ }),
757
+ exportData: (format) => runBackupOperation(async (api, settings) => {
758
+ requireSuccess(await (format === 'json' ? api.exportJson(backupScope(settings)) : api.exportCsv(backupScope(settings))), 'Workspace export');
759
+ }),
760
+ archiveEntity: () => applyEntityLifecycle('archive'),
881
761
  transferOwnership: (newOwnerId) => {
882
- const { settings } = get();
883
- if (!settings)
884
- return;
885
- const newOwner = settings.access.members.find(m => m.id === newOwnerId);
886
- if (!newOwner)
887
- return;
888
- set({
889
- settings: {
890
- ...settings,
891
- access: {
892
- ...settings.access,
893
- owner: { ...newOwner, role: 'owner' },
894
- members: settings.access.members.map(m => m.id === newOwnerId ? { ...m, role: 'owner' } : m.id === settings.access.owner.id ? { ...m, role: 'admin' } : m),
895
- },
896
- },
897
- isDirty: true,
898
- });
762
+ set(state => ({ sectionErrors: { ...state.sectionErrors, access: 'Ownership transfer requires a connected workspace membership authority. Ownership was not changed.' } }));
899
763
  },
900
- deleteEntity: () => {
901
- const { settings } = get();
902
- if (!settings)
903
- return;
904
- const ws = useWorkspaceStore.getState();
905
- if (settings.entityType === 'workspace') {
906
- ws.deleteWorkspace(settings.entityId);
764
+ deleteEntity: () => applyEntityLifecycle('delete'),
765
+ }));
766
+ async function persistProfileFields(settings, identity, drafts, fields) {
767
+ const sent = { ...fields };
768
+ const draft = drafts.get(identity);
769
+ if (!draft)
770
+ return false;
771
+ draft.submitted = { ...draft.submitted, ...sent };
772
+ const workspace = useWorkspaceStore.getState();
773
+ if (settings.entityType === 'workspace')
774
+ workspace.updateWorkspace(settings.entityId, sent);
775
+ else if (settings.entityType === 'team' && settings.workspaceId)
776
+ workspace.updateTeam(settings.workspaceId, settings.entityId, sent);
777
+ else if (settings.entityType === 'agent' && settings.workspaceId && settings.teamId)
778
+ workspace.updateAgent(settings.workspaceId, settings.teamId, settings.entityId, sent);
779
+ else
780
+ return false;
781
+ try {
782
+ await requireWorkspacePersistence(workspaces => {
783
+ const current = projectHierarchySettings(settings, workspaces);
784
+ return current?.identity === identity && Object.entries(sent).every(([key, value]) => current.general[key] === value);
785
+ });
786
+ const currentDraft = drafts.get(identity);
787
+ if (currentDraft) {
788
+ for (const key of Object.keys(sent)) {
789
+ if (currentDraft.fields[key] === sent[key])
790
+ delete currentDraft.fields[key];
791
+ if (currentDraft.submitted[key] === sent[key])
792
+ delete currentDraft.submitted[key];
793
+ }
794
+ if (!Object.keys(currentDraft.fields).length)
795
+ drafts.delete(identity);
907
796
  }
908
- else if (settings.entityType === 'team' && settings.workspaceId) {
909
- ws.deleteTeam(settings.workspaceId, settings.entityId);
797
+ if (selectedHierarchyBaseline?.identity === identity) {
798
+ const remaining = drafts.get(identity);
799
+ useEntitySettingsStore.setState({ profileDraftPending: Boolean(remaining), profileDraftError: remaining && useEntitySettingsStore.getState().settings ? validateProfileDraft(useEntitySettingsStore.getState().settings.general) : undefined });
910
800
  }
911
- else if (settings.entityType === 'agent' && settings.workspaceId && settings.teamId) {
912
- ws.deleteAgent(settings.workspaceId, settings.teamId, settings.entityId);
801
+ return true;
802
+ }
803
+ catch (error) {
804
+ if (selectedHierarchyBaseline?.identity === identity && drafts.has(identity))
805
+ useEntitySettingsStore.setState({ profileDraftError: error instanceof Error ? error.message : 'Profile save was not acknowledged.' });
806
+ return false;
807
+ }
808
+ }
809
+ let hierarchyRefreshGeneration = 0;
810
+ useWorkspaceStore.subscribe((next, previous) => {
811
+ if (next.workspaces === previous.workspaces && next.persistenceStatus === previous.persistenceStatus)
812
+ return;
813
+ const refresh = ++hierarchyRefreshGeneration;
814
+ const loadGeneration = useEntitySettingsStore.getState().loadGeneration;
815
+ if (!selectedHierarchyBaseline && !currentProfileDrafts().size)
816
+ return;
817
+ // Workspace mutations enqueue persistence inside Zustand updates. Start after
818
+ // that enqueue, then inspect the host ACK rather than accepting optimistic data.
819
+ queueMicrotask(() => { void reconcileAcknowledgedHierarchy(refresh, loadGeneration); });
820
+ });
821
+ async function reconcileAcknowledgedHierarchy(refresh, loadGeneration) {
822
+ let acknowledged;
823
+ try {
824
+ await requireWorkspacePersistence(workspaces => {
825
+ // The persistence guard checks acknowledged state first, then optimistic
826
+ // state. Capture only the former; a pending/conflicted edit is not authority.
827
+ acknowledged ??= workspaces;
828
+ return true;
829
+ });
830
+ }
831
+ catch {
832
+ return;
833
+ } // WorkspaceStore retains the actionable persistence error.
834
+ if (refresh === hierarchyRefreshGeneration && acknowledged) {
835
+ for (const identity of currentProfileDrafts().keys()) {
836
+ if (!profileIdentityExists(identity, acknowledged))
837
+ currentProfileDrafts().delete(identity);
913
838
  }
914
- },
915
- }));
839
+ }
840
+ const state = useEntitySettingsStore.getState();
841
+ const baseline = selectedHierarchyBaseline;
842
+ if (refresh !== hierarchyRefreshGeneration || loadGeneration !== state.loadGeneration || !state.settings || !baseline || !acknowledged)
843
+ return;
844
+ const incoming = projectHierarchySettings(state.settings, acknowledged);
845
+ if (!incoming || incoming.identity !== baseline.identity) {
846
+ currentProfileDrafts().delete(baseline.identity);
847
+ state.clearSettings();
848
+ return;
849
+ }
850
+ if (JSON.stringify(incoming) === JSON.stringify(baseline))
851
+ return;
852
+ selectedHierarchyBaseline = incoming;
853
+ useEntitySettingsStore.setState({ settings: {
854
+ ...state.settings,
855
+ entityName: incoming.entityName, workspaceName: incoming.workspaceName,
856
+ ...(incoming.teamName !== undefined ? { teamName: incoming.teamName } : {}),
857
+ general: mergeAcknowledgedFields(state.settings.general, baseline.general, incoming.general),
858
+ ...(state.settings.defaultAgentConfig && baseline.defaultAgentConfig && incoming.defaultAgentConfig ? {
859
+ defaultAgentConfig: mergeAcknowledgedFields(state.settings.defaultAgentConfig, baseline.defaultAgentConfig, incoming.defaultAgentConfig),
860
+ } : {}),
861
+ } });
862
+ }
863
+ async function applyEntityLifecycle(action) {
864
+ const initial = useEntitySettingsStore.getState();
865
+ const settings = initial.settings;
866
+ if (!settings || initial.sectionLoading.dangerZone)
867
+ return false;
868
+ const generation = initial.loadGeneration;
869
+ const current = () => useEntitySettingsStore.getState().loadGeneration === generation;
870
+ useEntitySettingsStore.setState(state => ({ sectionLoading: { ...state.sectionLoading, dangerZone: true }, sectionErrors: { ...state.sectionErrors, dangerZone: undefined } }));
871
+ try {
872
+ const scope = { workspaceId: settings.entityType === 'workspace' ? settings.entityId : settings.workspaceId,
873
+ ...(settings.entityType === 'team' ? { teamId: settings.entityId } : settings.teamId ? { teamId: settings.teamId } : {}),
874
+ ...(settings.entityType === 'agent' ? { agentId: settings.entityId } : {}) };
875
+ if (!await requestWorkspaceLifecycle(scope, action))
876
+ throw new Error(useWorkspaceStore.getState().lifecycleError || 'Lifecycle was not confirmed');
877
+ return current();
878
+ }
879
+ catch (error) {
880
+ if (current())
881
+ useEntitySettingsStore.setState(state => ({ sectionErrors: { ...state.sectionErrors, dangerZone: settingsError(error) } }));
882
+ return false;
883
+ }
884
+ finally {
885
+ if (current())
886
+ useEntitySettingsStore.setState(state => ({ sectionLoading: { ...state.sectionLoading, dangerZone: false } }));
887
+ }
888
+ }
916
889
  //# sourceMappingURL=entitySettingsStore.js.map