@burdenoff/microfe-vibecontrols 2026.527.11 → 2026.527.13

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 (434) hide show
  1. package/dist/components/actions/ActionCard.js +6 -0
  2. package/dist/components/actions/ActionCard.js.map +1 -1
  3. package/dist/components/actions/ActionForm.js +17 -1
  4. package/dist/components/actions/ActionForm.js.map +1 -1
  5. package/dist/components/actions/ActionSchedulesList.js +4 -1
  6. package/dist/components/actions/ActionSchedulesList.js.map +1 -1
  7. package/dist/components/actions/ExecutionHistory.js +2 -1
  8. package/dist/components/actions/ExecutionHistory.js.map +1 -1
  9. package/dist/components/agent-manager/AgentManagerAdminBar.js +8 -3
  10. package/dist/components/agent-manager/AgentManagerAdminBar.js.map +1 -1
  11. package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js +9 -9
  12. package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js.map +1 -1
  13. package/dist/components/agent-manager/AgentManagerBulkActions.js +6 -3
  14. package/dist/components/agent-manager/AgentManagerBulkActions.js.map +1 -1
  15. package/dist/components/agent-manager/AgentManagerCenter.js +8 -2
  16. package/dist/components/agent-manager/AgentManagerCenter.js.map +1 -1
  17. package/dist/components/agent-manager/AgentManagerChatPane.js +6 -6
  18. package/dist/components/agent-manager/AgentManagerChatPane.js.map +1 -1
  19. package/dist/components/agent-manager/AgentManagerDetailPanel.js +1 -1
  20. package/dist/components/agent-manager/AgentManagerDetailPanel.js.map +1 -1
  21. package/dist/components/agent-manager/AgentManagerInputArea.js +7 -5
  22. package/dist/components/agent-manager/AgentManagerInputArea.js.map +1 -1
  23. package/dist/components/agent-manager/AgentManagerLayout.js +8 -4
  24. package/dist/components/agent-manager/AgentManagerLayout.js.map +1 -1
  25. package/dist/components/agent-manager/AgentManagerMessageItem.js +6 -4
  26. package/dist/components/agent-manager/AgentManagerMessageItem.js.map +1 -1
  27. package/dist/components/agent-manager/AgentManagerMessageList.js +3 -3
  28. package/dist/components/agent-manager/AgentManagerMessageList.js.map +1 -1
  29. package/dist/components/agent-manager/AgentManagerSessionItem.js +29 -21
  30. package/dist/components/agent-manager/AgentManagerSessionItem.js.map +1 -1
  31. package/dist/components/agent-manager/AgentManagerSessionList.js +4 -2
  32. package/dist/components/agent-manager/AgentManagerSessionList.js.map +1 -1
  33. package/dist/components/agent-manager/AgentManagerSidebar.js +15 -5
  34. package/dist/components/agent-manager/AgentManagerSidebar.js.map +1 -1
  35. package/dist/components/agent-manager/AgentManagerStreamingIndicator.js +5 -4
  36. package/dist/components/agent-manager/AgentManagerStreamingIndicator.js.map +1 -1
  37. package/dist/components/agent-manager/AgentManagerTab.js +11 -7
  38. package/dist/components/agent-manager/AgentManagerTab.js.map +1 -1
  39. package/dist/components/agent-manager/AgentManagerTabBar.js +14 -9
  40. package/dist/components/agent-manager/AgentManagerTabBar.js.map +1 -1
  41. package/dist/components/agent-manager/BridleConfigPanel.js +34 -10
  42. package/dist/components/agent-manager/BridleConfigPanel.js.map +1 -1
  43. package/dist/components/agent-manager/PluginInstallModal.js +3 -3
  44. package/dist/components/agent-manager/PluginInstallModal.js.map +1 -1
  45. package/dist/components/agent-manager/ProfilesPanel.js +15 -10
  46. package/dist/components/agent-manager/ProfilesPanel.js.map +1 -1
  47. package/dist/components/agent-manager/controls/AutonomySelector.js +4 -4
  48. package/dist/components/agent-manager/controls/AutonomySelector.js.map +1 -1
  49. package/dist/components/agent-manager/controls/ContextLevelToggle.js +3 -3
  50. package/dist/components/agent-manager/controls/ContextLevelToggle.js.map +1 -1
  51. package/dist/components/agent-manager/controls/FileAttachButton.js +2 -1
  52. package/dist/components/agent-manager/controls/FileAttachButton.js.map +1 -1
  53. package/dist/components/agent-manager/controls/McpServerSelector.js +7 -7
  54. package/dist/components/agent-manager/controls/McpServerSelector.js.map +1 -1
  55. package/dist/components/agent-manager/controls/ModelSelector.js +3 -3
  56. package/dist/components/agent-manager/controls/ModelSelector.js.map +1 -1
  57. package/dist/components/agent-manager/controls/SdkSelector.js +5 -5
  58. package/dist/components/agent-manager/controls/SdkSelector.js.map +1 -1
  59. package/dist/components/agent-manager/controls/VoiceToggle.js +1 -1
  60. package/dist/components/agent-manager/controls/VoiceToggle.js.map +1 -1
  61. package/dist/components/agent-manager/detail/SessionConfigPanel.js +7 -2
  62. package/dist/components/agent-manager/detail/SessionConfigPanel.js.map +1 -1
  63. package/dist/components/agent-manager/detail/SessionLogsPanel.js +1 -1
  64. package/dist/components/agent-manager/detail/SessionLogsPanel.js.map +1 -1
  65. package/dist/components/agent-manager/detail/SessionToolsPanel.js +3 -3
  66. package/dist/components/agent-manager/detail/SessionToolsPanel.js.map +1 -1
  67. package/dist/components/agent-manager/dialogs/ExportSessionDialog.js +4 -2
  68. package/dist/components/agent-manager/dialogs/ExportSessionDialog.js.map +1 -1
  69. package/dist/components/agent-manager/dialogs/NewSessionDialog.js +4 -3
  70. package/dist/components/agent-manager/dialogs/NewSessionDialog.js.map +1 -1
  71. package/dist/components/agent-manager/dialogs/RenameSessionDialog.js +3 -3
  72. package/dist/components/agent-manager/dialogs/RenameSessionDialog.js.map +1 -1
  73. package/dist/components/agent-manager/dialogs/SessionSearchDialog.js +4 -3
  74. package/dist/components/agent-manager/dialogs/SessionSearchDialog.js.map +1 -1
  75. package/dist/components/agents/AgentCard.js +16 -14
  76. package/dist/components/agents/AgentCard.js.map +1 -1
  77. package/dist/components/agents/AgentForm.js +29 -24
  78. package/dist/components/agents/AgentForm.js.map +1 -1
  79. package/dist/components/agents/AgentList.js +38 -20
  80. package/dist/components/agents/AgentList.js.map +1 -1
  81. package/dist/components/agents/AgentStatusBadge.js +1 -1
  82. package/dist/components/agents/AgentStatusBadge.js.map +1 -1
  83. package/dist/components/agents/OpenInBrowserEditorButton.js +3 -2
  84. package/dist/components/agents/OpenInBrowserEditorButton.js.map +1 -1
  85. package/dist/components/agents/OpenInEditorMenu.js +7 -7
  86. package/dist/components/agents/OpenInEditorMenu.js.map +1 -1
  87. package/dist/components/agents/PluginUIPanel.js +28 -14
  88. package/dist/components/agents/PluginUIPanel.js.map +1 -1
  89. package/dist/components/agents/backup/AgentBackupTab.js +30 -20
  90. package/dist/components/agents/backup/AgentBackupTab.js.map +1 -1
  91. package/dist/components/ai/AIContextsTab.js +26 -7
  92. package/dist/components/ai/AIContextsTab.js.map +1 -1
  93. package/dist/components/ai/AIModeToggle.js +2 -1
  94. package/dist/components/ai/AIModeToggle.js.map +1 -1
  95. package/dist/components/ai/AIOverviewTab.js +5 -4
  96. package/dist/components/ai/AIOverviewTab.js.map +1 -1
  97. package/dist/components/ai/AIPlanPanel.js +21 -15
  98. package/dist/components/ai/AIPlanPanel.js.map +1 -1
  99. package/dist/components/ai/AIPlaygroundTab.js +6 -3
  100. package/dist/components/ai/AIPlaygroundTab.js.map +1 -1
  101. package/dist/components/ai/AIPromptsTab.js +10 -4
  102. package/dist/components/ai/AIPromptsTab.js.map +1 -1
  103. package/dist/components/ai/AIProviderCredentialsCard.js +9 -8
  104. package/dist/components/ai/AIProviderCredentialsCard.js.map +1 -1
  105. package/dist/components/ai/AISessionsTab.js +16 -6
  106. package/dist/components/ai/AISessionsTab.js.map +1 -1
  107. package/dist/components/ai/AIStatsTab.js +7 -6
  108. package/dist/components/ai/AIStatsTab.js.map +1 -1
  109. package/dist/components/ai/AITasksTab.js +30 -9
  110. package/dist/components/ai/AITasksTab.js.map +1 -1
  111. package/dist/components/ai/AITemplatesTab.js +51 -9
  112. package/dist/components/ai/AITemplatesTab.js.map +1 -1
  113. package/dist/components/ai/ClaudeCredentialsCard.js +6 -5
  114. package/dist/components/ai/ClaudeCredentialsCard.js.map +1 -1
  115. package/dist/components/ai/PluginHarnessPicker.js +6 -6
  116. package/dist/components/ai/PluginHarnessPicker.js.map +1 -1
  117. package/dist/components/aliases/AliasManager.js +32 -13
  118. package/dist/components/aliases/AliasManager.js.map +1 -1
  119. package/dist/components/analytics/AnalyticsBreakdownTable.js +9 -9
  120. package/dist/components/analytics/AnalyticsBreakdownTable.js.map +1 -1
  121. package/dist/components/analytics/AnalyticsFilterBar.js +4 -3
  122. package/dist/components/analytics/AnalyticsFilterBar.js.map +1 -1
  123. package/dist/components/analytics/AnalyticsKpiGrid.js +12 -12
  124. package/dist/components/analytics/AnalyticsKpiGrid.js.map +1 -1
  125. package/dist/components/assistant/AIAssistantPanel.js +6 -3
  126. package/dist/components/assistant/AIAssistantPanel.js.map +1 -1
  127. package/dist/components/assistant/AssistantChatInput.js +2 -1
  128. package/dist/components/assistant/AssistantChatInput.js.map +1 -1
  129. package/dist/components/assistant/AssistantConversationList.js +18 -7
  130. package/dist/components/assistant/AssistantConversationList.js.map +1 -1
  131. package/dist/components/assistant/AssistantExportMenu.js +6 -3
  132. package/dist/components/assistant/AssistantExportMenu.js.map +1 -1
  133. package/dist/components/assistant/AssistantMarkdownRenderer.js +2 -1
  134. package/dist/components/assistant/AssistantMarkdownRenderer.js.map +1 -1
  135. package/dist/components/assistant/AssistantMessageItem.js +2 -2
  136. package/dist/components/assistant/AssistantMessageItem.js.map +1 -1
  137. package/dist/components/assistant/AssistantMessageList.js +1 -1
  138. package/dist/components/assistant/AssistantMessageList.js.map +1 -1
  139. package/dist/components/assistant/AssistantModeSelector.js +5 -3
  140. package/dist/components/assistant/AssistantModeSelector.js.map +1 -1
  141. package/dist/components/assistant/AssistantWelcome.js +4 -3
  142. package/dist/components/assistant/AssistantWelcome.js.map +1 -1
  143. package/dist/components/audit/AuditDeleteDialog.js +4 -2
  144. package/dist/components/audit/AuditDeleteDialog.js.map +1 -1
  145. package/dist/components/audit/AuditLogDetail.js +4 -1
  146. package/dist/components/audit/AuditLogDetail.js.map +1 -1
  147. package/dist/components/audit/AuditLogFilters.js +1 -0
  148. package/dist/components/audit/AuditLogFilters.js.map +1 -1
  149. package/dist/components/catalog/CatalogCard.js +10 -9
  150. package/dist/components/catalog/CatalogCard.js.map +1 -1
  151. package/dist/components/catalog/CatalogForm.js +8 -1
  152. package/dist/components/catalog/CatalogForm.js.map +1 -1
  153. package/dist/components/docs/DocsCompileStatus.js +6 -5
  154. package/dist/components/docs/DocsCompileStatus.js.map +1 -1
  155. package/dist/components/docs/DocsEditPanel.js +10 -5
  156. package/dist/components/docs/DocsEditPanel.js.map +1 -1
  157. package/dist/components/docs/DocsEmptyState.js +4 -2
  158. package/dist/components/docs/DocsEmptyState.js.map +1 -1
  159. package/dist/components/docs/DocsFullScreenViewer.js +15 -8
  160. package/dist/components/docs/DocsFullScreenViewer.js.map +1 -1
  161. package/dist/components/docs/DocsPageEditor.js +7 -4
  162. package/dist/components/docs/DocsPageEditor.js.map +1 -1
  163. package/dist/components/docs/DocsPageTree.js +13 -4
  164. package/dist/components/docs/DocsPageTree.js.map +1 -1
  165. package/dist/components/docs/DocsPreviewPanel.js +18 -8
  166. package/dist/components/docs/DocsPreviewPanel.js.map +1 -1
  167. package/dist/components/docs/DocsRevisionHistory.js +8 -7
  168. package/dist/components/docs/DocsRevisionHistory.js.map +1 -1
  169. package/dist/components/docs/DocsSettingsPanel.js +43 -10
  170. package/dist/components/docs/DocsSettingsPanel.js.map +1 -1
  171. package/dist/components/docs/DocsTabPanel.js +3 -2
  172. package/dist/components/docs/DocsTabPanel.js.map +1 -1
  173. package/dist/components/gitops/CIDurationChart.js +1 -1
  174. package/dist/components/gitops/CIDurationChart.js.map +1 -1
  175. package/dist/components/gitops/CIFailedRuns.js +3 -3
  176. package/dist/components/gitops/CIFailedRuns.js.map +1 -1
  177. package/dist/components/gitops/CIPipelineRunsTable.js +2 -2
  178. package/dist/components/gitops/CIPipelineRunsTable.js.map +1 -1
  179. package/dist/components/gitops/CISuccessRateChart.js +1 -1
  180. package/dist/components/gitops/CISuccessRateChart.js.map +1 -1
  181. package/dist/components/gitops/CITab.js +1 -1
  182. package/dist/components/gitops/CITab.js.map +1 -1
  183. package/dist/components/gitops/CIWorkflowList.js +1 -1
  184. package/dist/components/gitops/CIWorkflowList.js.map +1 -1
  185. package/dist/components/gitops/GitOpsSetup.js +5 -3
  186. package/dist/components/gitops/GitOpsSetup.js.map +1 -1
  187. package/dist/components/gitops/GitOpsStatusBadge.js +1 -1
  188. package/dist/components/gitops/GitOpsStatusBadge.js.map +1 -1
  189. package/dist/components/gitops/RepoActivityCard.js +3 -3
  190. package/dist/components/gitops/RepoActivityCard.js.map +1 -1
  191. package/dist/components/gitops/RepoIssuesCard.js +1 -1
  192. package/dist/components/gitops/RepoIssuesCard.js.map +1 -1
  193. package/dist/components/gitops/RepoLanguagesCard.js +3 -3
  194. package/dist/components/gitops/RepoLanguagesCard.js.map +1 -1
  195. package/dist/components/gitops/RepoOverviewCard.js +8 -8
  196. package/dist/components/gitops/RepoOverviewCard.js.map +1 -1
  197. package/dist/components/gitops/RepoPullRequestsCard.js +1 -1
  198. package/dist/components/gitops/RepoPullRequestsCard.js.map +1 -1
  199. package/dist/components/gitops/RepoSecurityCard.js +1 -1
  200. package/dist/components/gitops/RepoSecurityCard.js.map +1 -1
  201. package/dist/components/gitops/RepoStatsTab.js +1 -1
  202. package/dist/components/gitops/RepoStatsTab.js.map +1 -1
  203. package/dist/components/gitops/VibeGitOpsTab.js +11 -6
  204. package/dist/components/gitops/VibeGitOpsTab.js.map +1 -1
  205. package/dist/components/graph/AgentNode.js +1 -1
  206. package/dist/components/graph/AgentNode.js.map +1 -1
  207. package/dist/components/graph/ConnectionPermissionsDialog.js +10 -0
  208. package/dist/components/graph/ConnectionPermissionsDialog.js.map +1 -1
  209. package/dist/components/graph/TargetNode.js +1 -1
  210. package/dist/components/graph/TargetNode.js.map +1 -1
  211. package/dist/components/idp-components/ComponentCard.js +7 -6
  212. package/dist/components/idp-components/ComponentCard.js.map +1 -1
  213. package/dist/components/idp-components/ComponentForm.js +17 -3
  214. package/dist/components/idp-components/ComponentForm.js.map +1 -1
  215. package/dist/components/idp-components/DependencyGraphTab.js +1 -1
  216. package/dist/components/idp-components/DependencyGraphTab.js.map +1 -1
  217. package/dist/components/logs/LogViewer.js +2 -1
  218. package/dist/components/logs/LogViewer.js.map +1 -1
  219. package/dist/components/notes/NoteCard.js +15 -14
  220. package/dist/components/notes/NoteCard.js.map +1 -1
  221. package/dist/components/notes/NoteEditor.js +19 -14
  222. package/dist/components/notes/NoteEditor.js.map +1 -1
  223. package/dist/components/notes/NoteList.js +23 -15
  224. package/dist/components/notes/NoteList.js.map +1 -1
  225. package/dist/components/notes/NotesTabPanel.js +19 -10
  226. package/dist/components/notes/NotesTabPanel.js.map +1 -1
  227. package/dist/components/plugins/AddTabDialog.js +6 -6
  228. package/dist/components/plugins/AddTabDialog.js.map +1 -1
  229. package/dist/components/scorecard/ScorecardPanel.js +19 -9
  230. package/dist/components/scorecard/ScorecardPanel.js.map +1 -1
  231. package/dist/components/security/SecurityEmptyState.js +1 -1
  232. package/dist/components/security/SecurityEmptyState.js.map +1 -1
  233. package/dist/components/security/SecurityFindingsTable.js +1 -1
  234. package/dist/components/security/SecurityFindingsTable.js.map +1 -1
  235. package/dist/components/security/SecurityHeaderStrip.js +1 -1
  236. package/dist/components/security/SecurityHeaderStrip.js.map +1 -1
  237. package/dist/components/security/SecurityProviderDrawer.js +1 -1
  238. package/dist/components/security/SecurityProviderDrawer.js.map +1 -1
  239. package/dist/components/sessions/CollaboratorsList.js +15 -12
  240. package/dist/components/sessions/CollaboratorsList.js.map +1 -1
  241. package/dist/components/sessions/ControlStatusBar.js +11 -9
  242. package/dist/components/sessions/ControlStatusBar.js.map +1 -1
  243. package/dist/components/sessions/SessionCard.js +13 -11
  244. package/dist/components/sessions/SessionCard.js.map +1 -1
  245. package/dist/components/sessions/SessionList.js +23 -13
  246. package/dist/components/sessions/SessionList.js.map +1 -1
  247. package/dist/components/sessions/SessionShareDialog.js +31 -19
  248. package/dist/components/sessions/SessionShareDialog.js.map +1 -1
  249. package/dist/components/sessions/SharedTerminalPanel.js +4 -2
  250. package/dist/components/sessions/SharedTerminalPanel.js.map +1 -1
  251. package/dist/components/sessions/TerminalPanel.js +287 -235
  252. package/dist/components/sessions/TerminalPanel.js.map +1 -1
  253. package/dist/components/settings/AdvancedSection.js +12 -4
  254. package/dist/components/settings/AdvancedSection.js.map +1 -1
  255. package/dist/components/settings/IdePreferencesSection.js +1 -1
  256. package/dist/components/settings/IdePreferencesSection.js.map +1 -1
  257. package/dist/components/settings/SettingsForm.js +3 -1
  258. package/dist/components/settings/SettingsForm.js.map +1 -1
  259. package/dist/components/shared/AgentSelector.js +6 -6
  260. package/dist/components/shared/AgentSelector.js.map +1 -1
  261. package/dist/components/shared/AgentSetupBanner.js +14 -10
  262. package/dist/components/shared/AgentSetupBanner.js.map +1 -1
  263. package/dist/components/shared/Card.js.map +1 -1
  264. package/dist/components/shared/ConfirmDialog.js +4 -3
  265. package/dist/components/shared/ConfirmDialog.js.map +1 -1
  266. package/dist/components/shared/EmptyState.js +4 -4
  267. package/dist/components/shared/EmptyState.js.map +1 -1
  268. package/dist/components/shared/EntityTagPicker.js +9 -10
  269. package/dist/components/shared/EntityTagPicker.js.map +1 -1
  270. package/dist/components/shared/ErrorState.js +7 -6
  271. package/dist/components/shared/ErrorState.js.map +1 -1
  272. package/dist/components/shared/FilterDropdown.js +6 -3
  273. package/dist/components/shared/FilterDropdown.js.map +1 -1
  274. package/dist/components/shared/GetHelpButton.js +1 -1
  275. package/dist/components/shared/GetHelpButton.js.map +1 -1
  276. package/dist/components/shared/InstallTabs.js +2 -2
  277. package/dist/components/shared/InstallTabs.js.map +1 -1
  278. package/dist/components/shared/LoadingState.js +3 -3
  279. package/dist/components/shared/LoadingState.js.map +1 -1
  280. package/dist/components/shared/NotificationToast.js +3 -3
  281. package/dist/components/shared/NotificationToast.js.map +1 -1
  282. package/dist/components/shared/PageSkeleton.js +1 -1
  283. package/dist/components/shared/PageSkeleton.js.map +1 -1
  284. package/dist/components/shared/PluginGate.js +12 -8
  285. package/dist/components/shared/PluginGate.js.map +1 -1
  286. package/dist/components/shared/RequireAgentReachable.js +4 -4
  287. package/dist/components/shared/RequireAgentReachable.js.map +1 -1
  288. package/dist/components/shared/SearchInput.js +3 -2
  289. package/dist/components/shared/SearchInput.js.map +1 -1
  290. package/dist/components/shared/SearchableSelect.js +10 -5
  291. package/dist/components/shared/SearchableSelect.js.map +1 -1
  292. package/dist/components/shared/SelectionCheckbox.js +2 -2
  293. package/dist/components/shared/SelectionCheckbox.js.map +1 -1
  294. package/dist/components/shared/SessionNotificationBanner.js +8 -6
  295. package/dist/components/shared/SessionNotificationBanner.js.map +1 -1
  296. package/dist/components/shared/StatCard.js +2 -2
  297. package/dist/components/shared/StatCard.js.map +1 -1
  298. package/dist/components/shared/StatusBadge.js +1 -1
  299. package/dist/components/shared/StatusBadge.js.map +1 -1
  300. package/dist/components/targets/TargetCard.js +24 -11
  301. package/dist/components/targets/TargetCard.js.map +1 -1
  302. package/dist/components/templates/PublishTemplateForm.js +27 -7
  303. package/dist/components/templates/PublishTemplateForm.js.map +1 -1
  304. package/dist/components/templates/TemplateCard.js +6 -6
  305. package/dist/components/templates/TemplateCard.js.map +1 -1
  306. package/dist/components/templates/TemplateVariableEditor.js +21 -3
  307. package/dist/components/templates/TemplateVariableEditor.js.map +1 -1
  308. package/dist/components/templates/TemplateWizard.js +38 -15
  309. package/dist/components/templates/TemplateWizard.js.map +1 -1
  310. package/dist/components/tunnels/TunnelCard.js +5 -5
  311. package/dist/components/tunnels/TunnelCard.js.map +1 -1
  312. package/dist/components/tunnels/TunnelCreateWizard.js +8 -0
  313. package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
  314. package/dist/components/vibe/VibeAgentEmptyState.js +9 -5
  315. package/dist/components/vibe/VibeAgentEmptyState.js.map +1 -1
  316. package/dist/components/vibe/VibeAgentSwitcher.js +20 -16
  317. package/dist/components/vibe/VibeAgentSwitcher.js.map +1 -1
  318. package/dist/components/vibe/VibeLlmContextAdminPanel.js +5 -4
  319. package/dist/components/vibe/VibeLlmContextAdminPanel.js.map +1 -1
  320. package/dist/components/vibe/VibeLlmContextTabPanel.js +35 -18
  321. package/dist/components/vibe/VibeLlmContextTabPanel.js.map +1 -1
  322. package/dist/components/vibecalendar/LogsDrawer.js +6 -0
  323. package/dist/components/vibecalendar/LogsDrawer.js.map +1 -1
  324. package/dist/components/vibecalendar/ScheduleTaskModal.js +19 -0
  325. package/dist/components/vibecalendar/ScheduleTaskModal.js.map +1 -1
  326. package/dist/components/vibecalendar/VibeCalAgendaView.js +7 -0
  327. package/dist/components/vibecalendar/VibeCalAgendaView.js.map +1 -1
  328. package/dist/components/vibecalendar/VibeCalDayView.js +7 -0
  329. package/dist/components/vibecalendar/VibeCalDayView.js.map +1 -1
  330. package/dist/components/vibecalendar/VibeCalMonthView.js +2 -2
  331. package/dist/components/vibecalendar/VibeCalMonthView.js.map +1 -1
  332. package/dist/components/vibecalendar/VibeCalWeekView.js +8 -1
  333. package/dist/components/vibecalendar/VibeCalWeekView.js.map +1 -1
  334. package/dist/components/vibecalendar/VibeCalendarHeader.js +5 -0
  335. package/dist/components/vibecalendar/VibeCalendarHeader.js.map +1 -1
  336. package/dist/components/vibecalendar/VibeTaskBlock.js +8 -0
  337. package/dist/components/vibecalendar/VibeTaskBlock.js.map +1 -1
  338. package/dist/components/vibedeck/VibeDeckButtonForm.js +20 -0
  339. package/dist/components/vibedeck/VibeDeckButtonForm.js.map +1 -1
  340. package/dist/components/vibedeck/VibeDeckButtonTile.js +12 -4
  341. package/dist/components/vibedeck/VibeDeckButtonTile.js.map +1 -1
  342. package/dist/components/vibedeck/VibeDeckExecutionLog.js +6 -0
  343. package/dist/components/vibedeck/VibeDeckExecutionLog.js.map +1 -1
  344. package/dist/components/vibedeck/VibeDeckForm.js +5 -0
  345. package/dist/components/vibedeck/VibeDeckForm.js.map +1 -1
  346. package/dist/components/vibedeck/VibeDeckGrid.js +1 -0
  347. package/dist/components/vibedeck/VibeDeckGrid.js.map +1 -1
  348. package/dist/components/vibedeck/VibeDeckShareDialog.js +18 -1
  349. package/dist/components/vibedeck/VibeDeckShareDialog.js.map +1 -1
  350. package/dist/components/vibedeck/VibeDeckSwitcher.js +8 -0
  351. package/dist/components/vibedeck/VibeDeckSwitcher.js.map +1 -1
  352. package/dist/components/vibes/VibeCard.js +10 -9
  353. package/dist/components/vibes/VibeCard.js.map +1 -1
  354. package/dist/components/vibes/VibeList.js +30 -16
  355. package/dist/components/vibes/VibeList.js.map +1 -1
  356. package/dist/pages/ActionsPage.js +12 -0
  357. package/dist/pages/ActionsPage.js.map +1 -1
  358. package/dist/pages/AgentDetailsPage.js +125 -68
  359. package/dist/pages/AgentDetailsPage.js.map +1 -1
  360. package/dist/pages/AgentGraphPage.js +5 -5
  361. package/dist/pages/AgentGraphPage.js.map +1 -1
  362. package/dist/pages/AgentsPage.js +37 -12
  363. package/dist/pages/AgentsPage.js.map +1 -1
  364. package/dist/pages/AnalyticsPage.js +1 -1
  365. package/dist/pages/AnalyticsPage.js.map +1 -1
  366. package/dist/pages/CatalogDetailPage.js +34 -20
  367. package/dist/pages/CatalogDetailPage.js.map +1 -1
  368. package/dist/pages/CatalogPage.js +9 -5
  369. package/dist/pages/CatalogPage.js.map +1 -1
  370. package/dist/pages/ComponentDetailPage.js +40 -23
  371. package/dist/pages/ComponentDetailPage.js.map +1 -1
  372. package/dist/pages/ComponentsPage.js +9 -5
  373. package/dist/pages/ComponentsPage.js.map +1 -1
  374. package/dist/pages/GettingStartedPage.js +6 -5
  375. package/dist/pages/GettingStartedPage.js.map +1 -1
  376. package/dist/pages/HealthPage.js +16 -15
  377. package/dist/pages/HealthPage.js.map +1 -1
  378. package/dist/pages/LogsPage.js +2 -2
  379. package/dist/pages/LogsPage.js.map +1 -1
  380. package/dist/pages/NoteDetailsPage.js +12 -7
  381. package/dist/pages/NoteDetailsPage.js.map +1 -1
  382. package/dist/pages/OverviewPage.js +26 -15
  383. package/dist/pages/OverviewPage.js.map +1 -1
  384. package/dist/pages/SessionDetailsPage.js +73 -50
  385. package/dist/pages/SessionDetailsPage.js.map +1 -1
  386. package/dist/pages/SessionsPage.js +49 -22
  387. package/dist/pages/SessionsPage.js.map +1 -1
  388. package/dist/pages/SettingsPage.js +4 -4
  389. package/dist/pages/SettingsPage.js.map +1 -1
  390. package/dist/pages/SharedSessionPage.js +36 -29
  391. package/dist/pages/SharedSessionPage.js.map +1 -1
  392. package/dist/pages/SharedVibeDeckPage.js +8 -6
  393. package/dist/pages/SharedVibeDeckPage.js.map +1 -1
  394. package/dist/pages/TargetDetailsPage.js +7 -6
  395. package/dist/pages/TargetDetailsPage.js.map +1 -1
  396. package/dist/pages/TargetsPage.js +84 -11
  397. package/dist/pages/TargetsPage.js.map +1 -1
  398. package/dist/pages/TemplateDetailPage.js +33 -23
  399. package/dist/pages/TemplateDetailPage.js.map +1 -1
  400. package/dist/pages/TemplatesPage.js +5 -3
  401. package/dist/pages/TemplatesPage.js.map +1 -1
  402. package/dist/pages/VibeCalendarPage.js +1 -0
  403. package/dist/pages/VibeCalendarPage.js.map +1 -1
  404. package/dist/pages/VibeDeckPage.js +256 -239
  405. package/dist/pages/VibeDeckPage.js.map +1 -1
  406. package/dist/pages/VibeDetailsPage.js +657 -619
  407. package/dist/pages/VibeDetailsPage.js.map +1 -1
  408. package/dist/pages/VibeTaskDetailPage.js +3 -0
  409. package/dist/pages/VibeTaskDetailPage.js.map +1 -1
  410. package/dist/pages/VibesPage.js +21 -8
  411. package/dist/pages/VibesPage.js.map +1 -1
  412. package/dist/pages/ai/AIBookmarksPage.js +8 -8
  413. package/dist/pages/ai/AIBookmarksPage.js.map +1 -1
  414. package/dist/pages/ai/AIPage.js +4 -2
  415. package/dist/pages/ai/AIPage.js.map +1 -1
  416. package/dist/pages/ai/AISessionDetailPage.js +19 -10
  417. package/dist/pages/ai/AISessionDetailPage.js.map +1 -1
  418. package/dist/pages/ai/AgentManagerPage.js +2 -1
  419. package/dist/pages/ai/AgentManagerPage.js.map +1 -1
  420. package/dist/pages/tunnels/ProvidersTab.js +1 -1
  421. package/dist/pages/tunnels/ProvidersTab.js.map +1 -1
  422. package/dist/pages/tunnels/TunnelDetailsPage.js +2 -1
  423. package/dist/pages/tunnels/TunnelDetailsPage.js.map +1 -1
  424. package/dist/pages/tunnels/tabs/TunnelCliTab.js +1 -1
  425. package/dist/pages/tunnels/tabs/TunnelCliTab.js.map +1 -1
  426. package/dist/pages/tunnels/tabs/TunnelDomainsTab.js +1 -0
  427. package/dist/pages/tunnels/tabs/TunnelDomainsTab.js.map +1 -1
  428. package/dist/pages/tunnels/tabs/TunnelEndpointsTab.js +1 -1
  429. package/dist/pages/tunnels/tabs/TunnelEndpointsTab.js.map +1 -1
  430. package/dist/providers/AgentEventsProvider.js +5 -5
  431. package/dist/providers/AgentEventsProvider.js.map +1 -1
  432. package/dist/providers/VibeControlsProvider.js +3 -3
  433. package/dist/providers/VibeControlsProvider.js.map +1 -1
  434. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AgentManagerAdminBar.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerAdminBar.tsx"],"sourcesContent":["/**\n * Admin bar for the Agent Manager.\n *\n * Horizontal tab strip rendered at the bottom of the layout. Each tab\n * opens an overlay panel with the corresponding AI management component\n * (Templates, Contexts, Prompts, Tasks, Stats, Playground).\n */\n\nimport { useState } from 'react';\nimport {\n X,\n FileText,\n BookOpen,\n MessageSquare,\n ListChecks,\n BarChart3,\n Play,\n Settings,\n ExternalLink,\n} from 'lucide-react';\nimport { motion, AnimatePresence, useReducedMotion } from 'framer-motion';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport type { AdminTab } from '@/types/agentManager';\nimport { AITemplatesTab } from '@/components/ai/AITemplatesTab';\nimport { AIContextsTab } from '@/components/ai/AIContextsTab';\nimport { AIPromptsTab } from '@/components/ai/AIPromptsTab';\nimport { AITasksTab } from '@/components/ai/AITasksTab';\nimport { AIStatsTab } from '@/components/ai/AIStatsTab';\nimport { AIPlaygroundTab } from '@/components/ai/AIPlaygroundTab';\nimport { BridleConfigPanel } from './BridleConfigPanel';\nimport { AIProviderCredentialsCard } from '@/components/ai/AIProviderCredentialsCard';\nimport { useTr } from '../../shared/hooks/useTr';\nimport type { AgentRef } from '@/services/aiApi';\n\ninterface AgentManagerAdminBarProps {\n agent: AgentRef;\n}\n\nconst ADMIN_TABS: Array<{ key: AdminTab; label: string; icon: typeof FileText }> = [\n { key: 'templates', label: 'Templates', icon: FileText },\n { key: 'contexts', label: 'Contexts', icon: BookOpen },\n { key: 'prompts', label: 'Prompts', icon: MessageSquare },\n { key: 'tasks', label: 'Tasks', icon: ListChecks },\n { key: 'stats', label: 'Stats', icon: BarChart3 },\n { key: 'playground', label: 'Playground', icon: Play },\n // Split: AI provider API keys (Anthropic, OpenAI, Gemini, …) live here;\n // Bridle owns the harness-config files (~/.claude/, ~/.config/opencode/).\n { key: 'aiKeys', label: 'AI Keys', icon: Settings },\n { key: 'bridle', label: 'Bridle', icon: Settings },\n];\n\nexport function AgentManagerAdminBar({ agent }: AgentManagerAdminBarProps) {\n const adminTab = useAgentManagerStore((s) => s.adminTab);\n const setAdminTab = useAgentManagerStore((s) => s.setAdminTab);\n const [overlayOpen, setOverlayOpen] = useState(false);\n const shouldReduceMotion = useReducedMotion();\n const handleNavigate = useVibeNavigate();\n const tr = useTr();\n\n function handleTabClick(tab: AdminTab) {\n if (overlayOpen && adminTab === tab) {\n setOverlayOpen(false);\n } else {\n setAdminTab(tab);\n setOverlayOpen(true);\n }\n }\n\n function renderTabContent() {\n switch (adminTab) {\n case 'templates':\n return <AITemplatesTab agentId={agent.id} />;\n case 'contexts':\n return <AIContextsTab agent={agent} />;\n case 'prompts':\n return <AIPromptsTab agent={agent} />;\n case 'tasks':\n return <AITasksTab />;\n case 'stats':\n return <AIStatsTab agent={agent} />;\n case 'playground':\n return <AIPlaygroundTab agent={agent} />;\n // 'aiKeys' is the SDK-credentials surface: every AI provider plugin\n // that reads from the agent's config bag (POST /api/config) gets a\n // row here. Distinct from Bridle below, which writes harness config\n // files on disk under ~/.claude/, ~/.config/opencode/, etc.\n case 'aiKeys':\n case 'config': // back-compat alias for old saved adminTab='config'\n return <AIProviderCredentialsCard agent={agent} />;\n case 'bridle':\n return <BridleConfigPanel agent={agent} />;\n default:\n return null;\n }\n }\n\n return (\n <>\n {/* Admin overlay */}\n <AnimatePresence>\n {overlayOpen && (\n <motion.div\n className=\"fixed inset-0 z-40 flex items-center justify-center\"\n initial={shouldReduceMotion ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n >\n {/* Backdrop */}\n <div className=\"absolute inset-0 bg-bg-overlay\" onClick={() => setOverlayOpen(false)} />\n\n {/* Content card */}\n <motion.div\n className=\"relative w-full max-w-4xl max-h-[80vh] mx-4 rounded-lg border border-border-default bg-bg-surface shadow-xl overflow-hidden flex flex-col\"\n initial={shouldReduceMotion ? undefined : { opacity: 0, scale: 0.96, y: 16 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.96, y: 16 }}\n transition={{ duration: 0.2, ease: [0.2, 0, 0, 1] }}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default\">\n <h2 className=\"text-sm font-semibold text-text-primary capitalize\">{adminTab}</h2>\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => handleNavigate('/ai-tools/' + adminTab)}\n className=\"p-1 rounded hover:bg-bg-elevated transition-colors text-text-tertiary hover:text-text-secondary\"\n title={tr('vibecontrols.agentManager.adminBar.openFullPage', 'Open full page')}\n >\n <ExternalLink className=\"w-4 h-4\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setOverlayOpen(false)}\n className=\"p-1 rounded hover:bg-bg-elevated transition-colors text-text-tertiary hover:text-text-secondary\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n\n {/* Tab content */}\n <div className=\"flex-1 overflow-y-auto p-4\">{renderTabContent()}</div>\n </motion.div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Bottom bar */}\n <div className=\"flex items-center gap-0.5 px-2 py-1 border-t border-border-default bg-bg-surface overflow-x-auto\">\n {ADMIN_TABS.map((tab) => {\n const Icon = tab.icon;\n const isActive = overlayOpen && adminTab === tab.key;\n return (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => handleTabClick(tab.key)}\n className={`flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded transition-colors whitespace-nowrap ${\n isActive\n ? 'bg-action-primary-bg/10 text-action-primary-text'\n : 'text-text-tertiary hover:text-text-secondary hover:bg-bg-elevated'\n }`}\n >\n <Icon className=\"w-3.5 h-3.5\" />\n <span>{tab.label}</span>\n </button>\n );\n })}\n </div>\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AgentManagerAdminBar.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerAdminBar.tsx"],"sourcesContent":["/**\n * Admin bar for the Agent Manager.\n *\n * Horizontal tab strip rendered at the bottom of the layout. Each tab\n * opens an overlay panel with the corresponding AI management component\n * (Templates, Contexts, Prompts, Tasks, Stats, Playground).\n */\n\nimport { useState } from 'react';\nimport {\n X,\n FileText,\n BookOpen,\n MessageSquare,\n ListChecks,\n BarChart3,\n Play,\n Settings,\n ExternalLink,\n} from 'lucide-react';\nimport { motion, AnimatePresence, useReducedMotion } from 'framer-motion';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport type { AdminTab } from '@/types/agentManager';\nimport { AITemplatesTab } from '@/components/ai/AITemplatesTab';\nimport { AIContextsTab } from '@/components/ai/AIContextsTab';\nimport { AIPromptsTab } from '@/components/ai/AIPromptsTab';\nimport { AITasksTab } from '@/components/ai/AITasksTab';\nimport { AIStatsTab } from '@/components/ai/AIStatsTab';\nimport { AIPlaygroundTab } from '@/components/ai/AIPlaygroundTab';\nimport { BridleConfigPanel } from './BridleConfigPanel';\nimport { AIProviderCredentialsCard } from '@/components/ai/AIProviderCredentialsCard';\nimport { useTr } from '../../shared/hooks/useTr';\nimport type { AgentRef } from '@/services/aiApi';\n\ninterface AgentManagerAdminBarProps {\n agent: AgentRef;\n}\n\nconst ADMIN_TABS: Array<{ key: AdminTab; label: string; icon: typeof FileText }> = [\n { key: 'templates', label: 'Templates', icon: FileText },\n { key: 'contexts', label: 'Contexts', icon: BookOpen },\n { key: 'prompts', label: 'Prompts', icon: MessageSquare },\n { key: 'tasks', label: 'Tasks', icon: ListChecks },\n { key: 'stats', label: 'Stats', icon: BarChart3 },\n { key: 'playground', label: 'Playground', icon: Play },\n // Split: AI provider API keys (Anthropic, OpenAI, Gemini, …) live here;\n // Bridle owns the harness-config files (~/.claude/, ~/.config/opencode/).\n { key: 'aiKeys', label: 'AI Keys', icon: Settings },\n { key: 'bridle', label: 'Bridle', icon: Settings },\n];\n\nexport function AgentManagerAdminBar({ agent }: AgentManagerAdminBarProps) {\n const adminTab = useAgentManagerStore((s) => s.adminTab);\n const setAdminTab = useAgentManagerStore((s) => s.setAdminTab);\n const [overlayOpen, setOverlayOpen] = useState(false);\n const shouldReduceMotion = useReducedMotion();\n const handleNavigate = useVibeNavigate();\n const tr = useTr();\n\n function handleTabClick(tab: AdminTab) {\n if (overlayOpen && adminTab === tab) {\n setOverlayOpen(false);\n } else {\n setAdminTab(tab);\n setOverlayOpen(true);\n }\n }\n\n function renderTabContent() {\n switch (adminTab) {\n case 'templates':\n return <AITemplatesTab agentId={agent.id} />;\n case 'contexts':\n return <AIContextsTab agent={agent} />;\n case 'prompts':\n return <AIPromptsTab agent={agent} />;\n case 'tasks':\n return <AITasksTab />;\n case 'stats':\n return <AIStatsTab agent={agent} />;\n case 'playground':\n return <AIPlaygroundTab agent={agent} />;\n // 'aiKeys' is the SDK-credentials surface: every AI provider plugin\n // that reads from the agent's config bag (POST /api/config) gets a\n // row here. Distinct from Bridle below, which writes harness config\n // files on disk under ~/.claude/, ~/.config/opencode/, etc.\n case 'aiKeys':\n case 'config': // back-compat alias for old saved adminTab='config'\n return <AIProviderCredentialsCard agent={agent} />;\n case 'bridle':\n return <BridleConfigPanel agent={agent} />;\n default:\n return null;\n }\n }\n\n return (\n <>\n {/* Admin overlay */}\n <AnimatePresence>\n {overlayOpen && (\n <motion.div\n className=\"fixed inset-0 z-40 flex items-center justify-center\"\n initial={shouldReduceMotion ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n >\n {/* Backdrop */}\n <div role=\"button\" tabIndex={0} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); (() => setOverlayOpen(false))(); } }} className=\"absolute inset-0 bg-bg-overlay\" onClick={() => setOverlayOpen(false)} />\n\n {/* Content card */}\n <motion.div\n className=\"relative w-full max-w-4xl max-h-[80vh] mx-4 rounded-lg border border-border-default bg-bg-surface shadow-xl overflow-hidden flex flex-col\"\n initial={shouldReduceMotion ? undefined : { opacity: 0, scale: 0.96, y: 16 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.96, y: 16 }}\n transition={{ duration: 0.2, ease: [0.2, 0, 0, 1] }}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default\">\n <h2 className=\"text-sm font-semibold text-text-primary capitalize\">{adminTab}</h2>\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => handleNavigate('/ai-tools/' + adminTab)}\n className=\"p-1 rounded hover:bg-bg-elevated transition-colors text-text-tertiary hover:text-text-secondary\"\n title={tr('vibecontrols.agentManager.adminBar.openFullPage', 'Open full page')}\n >\n <ExternalLink className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setOverlayOpen(false)}\n className=\"p-1 rounded hover:bg-bg-elevated transition-colors text-text-tertiary hover:text-text-secondary\"\n >\n <X className=\"size-4\" />\n </button>\n </div>\n </div>\n\n {/* Tab content */}\n <div className=\"flex-1 overflow-y-auto p-4\">{renderTabContent()}</div>\n </motion.div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Bottom bar */}\n <div className=\"flex items-center gap-0.5 px-2 py-1 border-t border-border-default bg-bg-surface overflow-x-auto\">\n {ADMIN_TABS.map((tab) => {\n const Icon = tab.icon;\n const isActive = overlayOpen && adminTab === tab.key;\n return (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => handleTabClick(tab.key)}\n className={`flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded transition-colors whitespace-nowrap ${\n isActive\n ? 'bg-action-primary-bg/10 text-action-primary-text'\n : 'text-text-tertiary hover:text-text-secondary hover:bg-bg-elevated'\n }`}\n >\n <Icon className=\"size-3.5\" />\n <span>{tab.label}</span>\n </button>\n );\n })}\n </div>\n </>\n );\n}\n"],"mappings":"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"}
@@ -43,7 +43,7 @@ var v = ({ open: g, onClose: v, sessionId: y, messages: b, onJump: x }) => {
43
43
  className: "flex items-center justify-between px-4 py-3 border-b border-border-default flex-shrink-0",
44
44
  children: [/* @__PURE__ */ h("div", {
45
45
  className: "flex items-center gap-2",
46
- children: [/* @__PURE__ */ m(o, { className: "w-4 h-4 text-text-secondary" }), /* @__PURE__ */ m("h3", {
46
+ children: [/* @__PURE__ */ m(o, { className: "size-4 text-text-secondary" }), /* @__PURE__ */ m("h3", {
47
47
  className: "text-sm font-semibold text-text-primary",
48
48
  children: C("vibecontrols.agentManager.bookmarksDrawer.title", "Bookmarks in this session")
49
49
  })]
@@ -52,7 +52,7 @@ var v = ({ open: g, onClose: v, sessionId: y, messages: b, onJump: x }) => {
52
52
  onClick: v,
53
53
  className: "p-1 rounded hover:bg-bg-sunken transition-colors",
54
54
  "aria-label": C("vibecontrols.common.close", "Close"),
55
- children: /* @__PURE__ */ m(f, { className: "w-4 h-4 text-text-secondary" })
55
+ children: /* @__PURE__ */ m(f, { className: "size-4 text-text-secondary" })
56
56
  })]
57
57
  }),
58
58
  /* @__PURE__ */ h("div", {
@@ -65,7 +65,7 @@ var v = ({ open: g, onClose: v, sessionId: y, messages: b, onJump: x }) => {
65
65
  !k && M.length === 0 && /* @__PURE__ */ h("div", {
66
66
  className: "px-4 py-10 flex flex-col items-center text-center gap-2",
67
67
  children: [
68
- /* @__PURE__ */ m(o, { className: "w-8 h-8 text-text-muted" }),
68
+ /* @__PURE__ */ m(o, { className: "size-8 text-text-muted" }),
69
69
  /* @__PURE__ */ m("p", {
70
70
  className: "text-sm font-medium text-text-primary",
71
71
  children: C("vibecontrols.agentManager.bookmarksDrawer.empty", "No bookmarks in this session yet")
@@ -88,7 +88,7 @@ var v = ({ open: g, onClose: v, sessionId: y, messages: b, onJump: x }) => {
88
88
  className: "flex-1 min-w-0",
89
89
  children: [
90
90
  r ? /* @__PURE__ */ m("input", {
91
- autoFocus: !0,
91
+ "aria-label": "control",
92
92
  value: E,
93
93
  onChange: (e) => D(e.target.value),
94
94
  onKeyDown: (t) => {
@@ -123,27 +123,27 @@ var v = ({ open: g, onClose: v, sessionId: y, messages: b, onJump: x }) => {
123
123
  className: "p-1 rounded hover:bg-bg-sunken transition-colors",
124
124
  title: C("vibecontrols.agentManager.bookmarksDrawer.jump", "Jump to message"),
125
125
  "aria-label": C("vibecontrols.agentManager.bookmarksDrawer.jump", "Jump to message"),
126
- children: /* @__PURE__ */ m(c, { className: "w-3.5 h-3.5 text-text-secondary" })
126
+ children: /* @__PURE__ */ m(c, { className: "size-3.5 text-text-secondary" })
127
127
  }),
128
128
  r ? /* @__PURE__ */ m("button", {
129
129
  type: "button",
130
130
  onClick: () => void F(e.id),
131
131
  className: "p-1 rounded hover:bg-bg-sunken transition-colors",
132
132
  "aria-label": C("vibecontrols.common.save", "Save"),
133
- children: /* @__PURE__ */ m(s, { className: "w-3.5 h-3.5 text-status-success-text" })
133
+ children: /* @__PURE__ */ m(s, { className: "size-3.5 text-status-success-text" })
134
134
  }) : /* @__PURE__ */ m("button", {
135
135
  type: "button",
136
136
  onClick: () => P(e.id, e.label),
137
137
  className: "p-1 rounded hover:bg-bg-sunken transition-colors",
138
138
  "aria-label": C("vibecontrols.agentManager.bookmarksDrawer.editLabel", "Edit label"),
139
- children: /* @__PURE__ */ m(u, { className: "w-3.5 h-3.5 text-text-secondary" })
139
+ children: /* @__PURE__ */ m(u, { className: "size-3.5 text-text-secondary" })
140
140
  }),
141
141
  /* @__PURE__ */ m("button", {
142
142
  type: "button",
143
143
  onClick: () => void I(e.id),
144
144
  className: "p-1 rounded hover:bg-bg-sunken transition-colors",
145
145
  "aria-label": C("vibecontrols.agentManager.messageItem.removeBookmark", "Remove bookmark"),
146
- children: /* @__PURE__ */ m(d, { className: "w-3.5 h-3.5 text-status-danger-text" })
146
+ children: /* @__PURE__ */ m(d, { className: "size-3.5 text-status-danger-text" })
147
147
  })
148
148
  ]
149
149
  })]
@@ -161,7 +161,7 @@ var v = ({ open: g, onClose: v, sessionId: y, messages: b, onJump: x }) => {
161
161
  v(), S("/vibecontrols/ai/bookmarks");
162
162
  },
163
163
  className: "inline-flex items-center gap-1.5 text-xs font-medium text-action-primary-text hover:underline",
164
- children: [/* @__PURE__ */ m(l, { className: "w-3 h-3" }), C("vibecontrols.agentManager.bookmarksDrawer.seeAll", "See all bookmarks across sessions")]
164
+ children: [/* @__PURE__ */ m(l, { className: "size-3" }), C("vibecontrols.agentManager.bookmarksDrawer.seeAll", "See all bookmarks across sessions")]
165
165
  })
166
166
  })
167
167
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"AgentManagerBookmarksDrawer.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerBookmarksDrawer.tsx"],"sourcesContent":["/**\n * Side drawer listing the current user's bookmarks for ONE chat session.\n *\n * Each row resolves its message body from the currently-loaded session\n * messages. When the bookmarked message is no longer in the session\n * (agent log pruning / rotation), the row degrades to a \"Message no\n * longer available\" affordance with a remove-only action.\n */\n\nimport { useState, type FC } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Bookmark, X, ChevronRight, Pencil, Trash2, Check, ExternalLink } from 'lucide-react';\nimport { relativeTime } from '@/utils/relativeTime';\nimport {\n useDeleteAgentMessageBookmarkMutation,\n useMyAgentMessageBookmarksQuery,\n useUpdateAgentMessageBookmarkMutation,\n type AgentMessageBookmarkFieldsFragment,\n} from '../../generated/wspace-operations';\nimport type { AgentManagerMessage } from '@/types/agentManager';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerBookmarksDrawerProps {\n open: boolean;\n onClose: () => void;\n sessionId: string;\n messages: AgentManagerMessage[];\n onJump: (messageId: string) => void;\n}\n\nconst PREVIEW_LEN = 80;\n\nfunction snippet(content: string): string {\n if (!content) return '';\n const trimmed = content.trim().replace(/\\s+/g, ' ');\n return trimmed.length > PREVIEW_LEN ? `${trimmed.slice(0, PREVIEW_LEN)}…` : trimmed;\n}\n\nexport const AgentManagerBookmarksDrawer: FC<AgentManagerBookmarksDrawerProps> = ({\n open,\n onClose,\n sessionId,\n messages,\n onJump,\n}) => {\n const navigate = useNavigate();\n const tr = useTr();\n const [editingId, setEditingId] = useState<string | null>(null);\n const [labelDraft, setLabelDraft] = useState('');\n\n const { data, loading } = useMyAgentMessageBookmarksQuery({\n variables: { filter: { sessionId } },\n skip: !open,\n fetchPolicy: 'cache-and-network',\n });\n\n const [updateMutation] = useUpdateAgentMessageBookmarkMutation({\n refetchQueries: ['MyAgentMessageBookmarks'],\n });\n const [deleteMutation] = useDeleteAgentMessageBookmarkMutation({\n refetchQueries: ['MyAgentMessageBookmarks'],\n });\n\n const bookmarks = data?.myAgentMessageBookmarks.items ?? [];\n const messageById = new Map(messages.map((m) => [m.id, m]));\n\n const startEdit = (id: string, current: string | null | undefined) => {\n setEditingId(id);\n setLabelDraft(current ?? '');\n };\n\n const saveEdit = async (id: string) => {\n await updateMutation({ variables: { id, input: { label: labelDraft || null } } });\n setEditingId(null);\n setLabelDraft('');\n };\n\n const removeBookmark = async (id: string) => {\n await deleteMutation({ variables: { id } });\n };\n\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-40 flex\">\n <div className=\"flex-1 bg-bg-overlay/40\" onClick={onClose} aria-hidden />\n <aside\n className=\"w-full max-w-md h-full bg-bg-surface border-l border-border-default shadow-xl flex flex-col\"\n role=\"dialog\"\n aria-label={tr(\n 'vibecontrols.agentManager.bookmarksDrawer.title',\n 'Bookmarks in this session'\n )}\n data-testid=\"agent-manager-bookmarks-drawer\"\n >\n <header className=\"flex items-center justify-between px-4 py-3 border-b border-border-default flex-shrink-0\">\n <div className=\"flex items-center gap-2\">\n <Bookmark className=\"w-4 h-4 text-text-secondary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {tr('vibecontrols.agentManager.bookmarksDrawer.title', 'Bookmarks in this session')}\n </h3>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n aria-label={tr('vibecontrols.common.close', 'Close')}\n >\n <X className=\"w-4 h-4 text-text-secondary\" />\n </button>\n </header>\n\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n {loading && bookmarks.length === 0 && (\n <div className=\"px-4 py-6 text-xs text-text-tertiary\">\n {tr('vibecontrols.common.loading', 'Loading...')}\n </div>\n )}\n\n {!loading && bookmarks.length === 0 && (\n <div className=\"px-4 py-10 flex flex-col items-center text-center gap-2\">\n <Bookmark className=\"w-8 h-8 text-text-muted\" />\n <p className=\"text-sm font-medium text-text-primary\">\n {tr(\n 'vibecontrols.agentManager.bookmarksDrawer.empty',\n 'No bookmarks in this session yet'\n )}\n </p>\n <p className=\"text-xs text-text-secondary max-w-xs\">\n {tr(\n 'vibecontrols.agentManager.bookmarksDrawer.emptyHint',\n 'Click the bookmark icon on any message to save it for later.'\n )}\n </p>\n </div>\n )}\n\n <ul className=\"divide-y divide-border-subtle\">\n {bookmarks.map((bm: AgentMessageBookmarkFieldsFragment) => {\n const msg = messageById.get(bm.messageId);\n const isStale = !msg;\n const isEditing = editingId === bm.id;\n\n return (\n <li key={bm.id} className=\"px-4 py-3 hover:bg-bg-elevated/40 transition-colors\">\n <div className=\"flex items-start gap-2\">\n <div className=\"flex-1 min-w-0\">\n {isEditing ? (\n <input\n autoFocus\n value={labelDraft}\n onChange={(e) => setLabelDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') void saveEdit(bm.id);\n if (e.key === 'Escape') {\n setEditingId(null);\n setLabelDraft('');\n }\n }}\n placeholder={tr(\n 'vibecontrols.agentManager.bookmarksDrawer.labelPlaceholder',\n 'Add a label (optional)'\n )}\n className=\"w-full bg-bg-sunken border border-border-subtle rounded px-2 py-1 text-xs text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-action-primary-bg\"\n />\n ) : (\n <p className=\"text-sm font-medium text-text-primary truncate\">\n {bm.label ||\n (msg?.role === 'user'\n ? tr('vibecontrols.agentManager.bookmarksDrawer.fromUser', 'From you')\n : tr(\n 'vibecontrols.agentManager.bookmarksDrawer.fromAssistant',\n 'Assistant reply'\n ))}\n </p>\n )}\n\n {isStale ? (\n <p className=\"text-xs text-text-tertiary italic mt-1\">\n {tr(\n 'vibecontrols.agentManager.bookmarksDrawer.stale',\n 'Message no longer available'\n )}\n </p>\n ) : (\n <p className=\"text-xs text-text-secondary mt-1 line-clamp-2\">\n {snippet(msg.content)}\n </p>\n )}\n\n <p className=\"text-[10px] text-text-tertiary mt-1\">\n {relativeTime(bm.createdAt)}\n </p>\n </div>\n\n <div className=\"flex items-center gap-0.5 shrink-0\">\n {!isStale && !isEditing && (\n <button\n type=\"button\"\n onClick={() => {\n onJump(bm.messageId);\n onClose();\n }}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n title={tr(\n 'vibecontrols.agentManager.bookmarksDrawer.jump',\n 'Jump to message'\n )}\n aria-label={tr(\n 'vibecontrols.agentManager.bookmarksDrawer.jump',\n 'Jump to message'\n )}\n >\n <ChevronRight className=\"w-3.5 h-3.5 text-text-secondary\" />\n </button>\n )}\n\n {isEditing ? (\n <button\n type=\"button\"\n onClick={() => void saveEdit(bm.id)}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n aria-label={tr('vibecontrols.common.save', 'Save')}\n >\n <Check className=\"w-3.5 h-3.5 text-status-success-text\" />\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={() => startEdit(bm.id, bm.label)}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n aria-label={tr(\n 'vibecontrols.agentManager.bookmarksDrawer.editLabel',\n 'Edit label'\n )}\n >\n <Pencil className=\"w-3.5 h-3.5 text-text-secondary\" />\n </button>\n )}\n\n <button\n type=\"button\"\n onClick={() => void removeBookmark(bm.id)}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n aria-label={tr(\n 'vibecontrols.agentManager.messageItem.removeBookmark',\n 'Remove bookmark'\n )}\n >\n <Trash2 className=\"w-3.5 h-3.5 text-status-danger-text\" />\n </button>\n </div>\n </div>\n </li>\n );\n })}\n </ul>\n </div>\n\n <footer className=\"px-4 py-3 border-t border-border-default flex-shrink-0\">\n <button\n type=\"button\"\n onClick={() => {\n onClose();\n navigate('/vibecontrols/ai/bookmarks');\n }}\n className=\"inline-flex items-center gap-1.5 text-xs font-medium text-action-primary-text hover:underline\"\n >\n <ExternalLink className=\"w-3 h-3\" />\n {tr(\n 'vibecontrols.agentManager.bookmarksDrawer.seeAll',\n 'See all bookmarks across sessions'\n )}\n </button>\n </footer>\n </aside>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AgentManagerBookmarksDrawer.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerBookmarksDrawer.tsx"],"sourcesContent":["/**\n * Side drawer listing the current user's bookmarks for ONE chat session.\n *\n * Each row resolves its message body from the currently-loaded session\n * messages. When the bookmarked message is no longer in the session\n * (agent log pruning / rotation), the row degrades to a \"Message no\n * longer available\" affordance with a remove-only action.\n */\n\nimport { useState, type FC } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Bookmark, X, ChevronRight, Pencil, Trash2, Check, ExternalLink } from 'lucide-react';\nimport { relativeTime } from '@/utils/relativeTime';\nimport {\n useDeleteAgentMessageBookmarkMutation,\n useMyAgentMessageBookmarksQuery,\n useUpdateAgentMessageBookmarkMutation,\n type AgentMessageBookmarkFieldsFragment,\n} from '../../generated/wspace-operations';\nimport type { AgentManagerMessage } from '@/types/agentManager';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerBookmarksDrawerProps {\n open: boolean;\n onClose: () => void;\n sessionId: string;\n messages: AgentManagerMessage[];\n onJump: (messageId: string) => void;\n}\n\nconst PREVIEW_LEN = 80;\n\nfunction snippet(content: string): string {\n if (!content) return '';\n const trimmed = content.trim().replace(/\\s+/g, ' ');\n return trimmed.length > PREVIEW_LEN ? `${trimmed.slice(0, PREVIEW_LEN)}…` : trimmed;\n}\n\nexport const AgentManagerBookmarksDrawer: FC<AgentManagerBookmarksDrawerProps> = ({\n open,\n onClose,\n sessionId,\n messages,\n onJump,\n}) => {\n const navigate = useNavigate();\n const tr = useTr();\n const [editingId, setEditingId] = useState<string | null>(null);\n const [labelDraft, setLabelDraft] = useState('');\n\n const { data, loading } = useMyAgentMessageBookmarksQuery({\n variables: { filter: { sessionId } },\n skip: !open,\n fetchPolicy: 'cache-and-network',\n });\n\n const [updateMutation] = useUpdateAgentMessageBookmarkMutation({\n refetchQueries: ['MyAgentMessageBookmarks'],\n });\n const [deleteMutation] = useDeleteAgentMessageBookmarkMutation({\n refetchQueries: ['MyAgentMessageBookmarks'],\n });\n\n const bookmarks = data?.myAgentMessageBookmarks.items ?? [];\n const messageById = new Map(messages.map((m) => [m.id, m]));\n\n const startEdit = (id: string, current: string | null | undefined) => {\n setEditingId(id);\n setLabelDraft(current ?? '');\n };\n\n const saveEdit = async (id: string) => {\n await updateMutation({ variables: { id, input: { label: labelDraft || null } } });\n setEditingId(null);\n setLabelDraft('');\n };\n\n const removeBookmark = async (id: string) => {\n await deleteMutation({ variables: { id } });\n };\n\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-40 flex\">\n <div className=\"flex-1 bg-bg-overlay/40\" onClick={onClose} aria-hidden />\n <aside\n className=\"w-full max-w-md h-full bg-bg-surface border-l border-border-default shadow-xl flex flex-col\"\n role=\"dialog\"\n aria-label={tr(\n 'vibecontrols.agentManager.bookmarksDrawer.title',\n 'Bookmarks in this session'\n )}\n data-testid=\"agent-manager-bookmarks-drawer\"\n >\n <header className=\"flex items-center justify-between px-4 py-3 border-b border-border-default flex-shrink-0\">\n <div className=\"flex items-center gap-2\">\n <Bookmark className=\"size-4 text-text-secondary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {tr('vibecontrols.agentManager.bookmarksDrawer.title', 'Bookmarks in this session')}\n </h3>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n aria-label={tr('vibecontrols.common.close', 'Close')}\n >\n <X className=\"size-4 text-text-secondary\" />\n </button>\n </header>\n\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n {loading && bookmarks.length === 0 && (\n <div className=\"px-4 py-6 text-xs text-text-tertiary\">\n {tr('vibecontrols.common.loading', 'Loading...')}\n </div>\n )}\n\n {!loading && bookmarks.length === 0 && (\n <div className=\"px-4 py-10 flex flex-col items-center text-center gap-2\">\n <Bookmark className=\"size-8 text-text-muted\" />\n <p className=\"text-sm font-medium text-text-primary\">\n {tr(\n 'vibecontrols.agentManager.bookmarksDrawer.empty',\n 'No bookmarks in this session yet'\n )}\n </p>\n <p className=\"text-xs text-text-secondary max-w-xs\">\n {tr(\n 'vibecontrols.agentManager.bookmarksDrawer.emptyHint',\n 'Click the bookmark icon on any message to save it for later.'\n )}\n </p>\n </div>\n )}\n\n <ul className=\"divide-y divide-border-subtle\">\n {bookmarks.map((bm: AgentMessageBookmarkFieldsFragment) => {\n const msg = messageById.get(bm.messageId);\n const isStale = !msg;\n const isEditing = editingId === bm.id;\n\n return (\n <li key={bm.id} className=\"px-4 py-3 hover:bg-bg-elevated/40 transition-colors\">\n <div className=\"flex items-start gap-2\">\n <div className=\"flex-1 min-w-0\">\n {isEditing ? (\n <input aria-label=\"control\"\n\n value={labelDraft}\n onChange={(e) => setLabelDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') void saveEdit(bm.id);\n if (e.key === 'Escape') {\n setEditingId(null);\n setLabelDraft('');\n }\n }}\n placeholder={tr(\n 'vibecontrols.agentManager.bookmarksDrawer.labelPlaceholder',\n 'Add a label (optional)'\n )}\n className=\"w-full bg-bg-sunken border border-border-subtle rounded px-2 py-1 text-xs text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-action-primary-bg\"\n />\n ) : (\n <p className=\"text-sm font-medium text-text-primary truncate\">\n {bm.label ||\n (msg?.role === 'user'\n ? tr('vibecontrols.agentManager.bookmarksDrawer.fromUser', 'From you')\n : tr(\n 'vibecontrols.agentManager.bookmarksDrawer.fromAssistant',\n 'Assistant reply'\n ))}\n </p>\n )}\n\n {isStale ? (\n <p className=\"text-xs text-text-tertiary italic mt-1\">\n {tr(\n 'vibecontrols.agentManager.bookmarksDrawer.stale',\n 'Message no longer available'\n )}\n </p>\n ) : (\n <p className=\"text-xs text-text-secondary mt-1 line-clamp-2\">\n {snippet(msg.content)}\n </p>\n )}\n\n <p className=\"text-[10px] text-text-tertiary mt-1\">\n {relativeTime(bm.createdAt)}\n </p>\n </div>\n\n <div className=\"flex items-center gap-0.5 shrink-0\">\n {!isStale && !isEditing && (\n <button\n type=\"button\"\n onClick={() => {\n onJump(bm.messageId);\n onClose();\n }}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n title={tr(\n 'vibecontrols.agentManager.bookmarksDrawer.jump',\n 'Jump to message'\n )}\n aria-label={tr(\n 'vibecontrols.agentManager.bookmarksDrawer.jump',\n 'Jump to message'\n )}\n >\n <ChevronRight className=\"size-3.5 text-text-secondary\" />\n </button>\n )}\n\n {isEditing ? (\n <button\n type=\"button\"\n onClick={() => void saveEdit(bm.id)}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n aria-label={tr('vibecontrols.common.save', 'Save')}\n >\n <Check className=\"size-3.5 text-status-success-text\" />\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={() => startEdit(bm.id, bm.label)}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n aria-label={tr(\n 'vibecontrols.agentManager.bookmarksDrawer.editLabel',\n 'Edit label'\n )}\n >\n <Pencil className=\"size-3.5 text-text-secondary\" />\n </button>\n )}\n\n <button\n type=\"button\"\n onClick={() => void removeBookmark(bm.id)}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n aria-label={tr(\n 'vibecontrols.agentManager.messageItem.removeBookmark',\n 'Remove bookmark'\n )}\n >\n <Trash2 className=\"size-3.5 text-status-danger-text\" />\n </button>\n </div>\n </div>\n </li>\n );\n })}\n </ul>\n </div>\n\n <footer className=\"px-4 py-3 border-t border-border-default flex-shrink-0\">\n <button\n type=\"button\"\n onClick={() => {\n onClose();\n navigate('/vibecontrols/ai/bookmarks');\n }}\n className=\"inline-flex items-center gap-1.5 text-xs font-medium text-action-primary-text hover:underline\"\n >\n <ExternalLink className=\"size-3\" />\n {tr(\n 'vibecontrols.agentManager.bookmarksDrawer.seeAll',\n 'See all bookmarks across sessions'\n )}\n </button>\n </footer>\n </aside>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -35,24 +35,27 @@ function d({ onDeleteSelected: d, onExportSelected: f }) {
35
35
  }),
36
36
  /* @__PURE__ */ l("div", { className: "flex-1" }),
37
37
  f && /* @__PURE__ */ u("button", {
38
+ type: "button",
38
39
  onClick: () => {
39
40
  f?.(p), m();
40
41
  },
41
42
  className: "inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-text-primary bg-bg-surface border border-border-default rounded-md hover:bg-bg-sunken transition-colors",
42
43
  title: _("vibecontrols.agentManager.bulkActions.exportSelected", "Export selected"),
43
- children: [/* @__PURE__ */ l(i, { className: "w-3.5 h-3.5" }), _("vibecontrols.agentManager.bulkActions.export", "Export")]
44
+ children: [/* @__PURE__ */ l(i, { className: "size-3.5" }), _("vibecontrols.agentManager.bulkActions.export", "Export")]
44
45
  }),
45
46
  /* @__PURE__ */ u("button", {
47
+ type: "button",
46
48
  onClick: () => g(!0),
47
49
  className: "inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-status-error-text bg-bg-surface border border-border-default rounded-md hover:bg-status-error-bg-subtle transition-colors",
48
50
  title: _("vibecontrols.agentManager.bulkActions.deleteSelected", "Delete selected"),
49
- children: [/* @__PURE__ */ l(a, { className: "w-3.5 h-3.5" }), _("vibecontrols.agentManager.bulkActions.delete", "Delete")]
51
+ children: [/* @__PURE__ */ l(a, { className: "size-3.5" }), _("vibecontrols.agentManager.bulkActions.delete", "Delete")]
50
52
  }),
51
53
  /* @__PURE__ */ l("button", {
54
+ type: "button",
52
55
  onClick: m,
53
56
  className: "p-1 rounded text-text-secondary hover:text-text-primary hover:bg-bg-sunken transition-colors",
54
57
  title: _("vibecontrols.agentManager.bulkActions.clearSelection", "Clear selection"),
55
- children: /* @__PURE__ */ l(o, { className: "w-3.5 h-3.5" })
58
+ children: /* @__PURE__ */ l(o, { className: "size-3.5" })
56
59
  })
57
60
  ]
58
61
  }), /* @__PURE__ */ l(t, {
@@ -1 +1 @@
1
- {"version":3,"file":"AgentManagerBulkActions.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerBulkActions.tsx"],"sourcesContent":["/**\n * Bulk actions bar displayed when one or more sessions are selected.\n *\n * Provides delete-selected and export-selected actions with\n * a ConfirmDialog for destructive operations.\n */\n\nimport { useState } from 'react';\nimport { Trash2, Download, X } from 'lucide-react';\nimport { motion } from 'framer-motion';\nimport { ConfirmDialog } from '@/components/shared';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerBulkActionsProps {\n onDeleteSelected: (sessionIds: string[]) => void;\n onExportSelected?: (sessionIds: string[]) => void;\n}\n\nexport function AgentManagerBulkActions({\n onDeleteSelected,\n onExportSelected,\n}: AgentManagerBulkActionsProps) {\n const selectedSessionIds = useAgentManagerStore((s) => s.selectedSessionIds);\n const clearSelection = useAgentManagerStore((s) => s.clearSelection);\n const [confirmOpen, setConfirmOpen] = useState(false);\n const tr = useTr();\n\n const count = selectedSessionIds.length;\n if (count === 0) return null;\n\n const handleDelete = () => {\n onDeleteSelected(selectedSessionIds);\n clearSelection();\n setConfirmOpen(false);\n };\n\n const handleExport = () => {\n onExportSelected?.(selectedSessionIds);\n clearSelection();\n };\n\n return (\n <>\n <motion.div\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 8 }}\n transition={{ duration: 0.15 }}\n className=\"flex items-center gap-2 px-3 py-2 border-t border-border-default bg-bg-elevated\"\n >\n <span className=\"text-xs font-medium text-text-secondary\">\n {count} {tr('vibecontrols.agentManager.bulkActions.selected', 'selected')}\n </span>\n\n <div className=\"flex-1\" />\n\n {onExportSelected && (\n <button\n onClick={handleExport}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-text-primary bg-bg-surface border border-border-default rounded-md hover:bg-bg-sunken transition-colors\"\n title={tr('vibecontrols.agentManager.bulkActions.exportSelected', 'Export selected')}\n >\n <Download className=\"w-3.5 h-3.5\" />\n {tr('vibecontrols.agentManager.bulkActions.export', 'Export')}\n </button>\n )}\n\n <button\n onClick={() => setConfirmOpen(true)}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-status-error-text bg-bg-surface border border-border-default rounded-md hover:bg-status-error-bg-subtle transition-colors\"\n title={tr('vibecontrols.agentManager.bulkActions.deleteSelected', 'Delete selected')}\n >\n <Trash2 className=\"w-3.5 h-3.5\" />\n {tr('vibecontrols.agentManager.bulkActions.delete', 'Delete')}\n </button>\n\n <button\n onClick={clearSelection}\n className=\"p-1 rounded text-text-secondary hover:text-text-primary hover:bg-bg-sunken transition-colors\"\n title={tr('vibecontrols.agentManager.bulkActions.clearSelection', 'Clear selection')}\n >\n <X className=\"w-3.5 h-3.5\" />\n </button>\n </motion.div>\n\n <ConfirmDialog\n isOpen={confirmOpen}\n onClose={() => setConfirmOpen(false)}\n onConfirm={handleDelete}\n title={tr('vibecontrols.agentManager.bulkActions.deleteSessionsTitle', 'Delete Sessions')}\n message={tr(\n 'vibecontrols.agentManager.bulkActions.confirmDelete',\n 'Are you sure you want to delete {{count}} session(s)? This cannot be undone.',\n { count }\n )}\n confirmLabel={tr('vibecontrols.agentManager.bulkActions.delete', 'Delete')}\n cancelLabel={tr('vibecontrols.agentManager.bulkActions.cancel', 'Cancel')}\n variant=\"danger\"\n />\n </>\n );\n}\n"],"mappings":";;;;;;;;;AAmBA,SAAgB,EAAwB,EACtC,qBACA,uBAC+B;CAC/B,IAAM,IAAqB,GAAsB,MAAM,EAAE,mBAAmB,EACtE,IAAiB,GAAsB,MAAM,EAAE,eAAe,EAC9D,CAAC,GAAa,KAAkB,EAAS,GAAM,EAC/C,IAAK,GAAO,EAEZ,IAAQ,EAAmB;AAcjC,QAbI,MAAU,IAAU,OActB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,EAAO,KAAR;EACE,SAAS;GAAE,SAAS;GAAG,GAAG;GAAG;EAC7B,SAAS;GAAE,SAAS;GAAG,GAAG;GAAG;EAC7B,MAAM;GAAE,SAAS;GAAG,GAAG;GAAG;EAC1B,YAAY,EAAE,UAAU,KAAM;EAC9B,WAAU;YALZ;GAOE,kBAAC,QAAD;IAAM,WAAU;cAAhB;KACG;KAAM;KAAE,EAAG,kDAAkD,WAAW;KACpE;;GAEP,kBAAC,OAAD,EAAK,WAAU,UAAW,CAAA;GAEzB,KACC,kBAAC,UAAD;IACE,eAtBiB;AAEzB,KADA,IAAmB,EAAmB,EACtC,GAAgB;;IAqBR,WAAU;IACV,OAAO,EAAG,wDAAwD,kBAAkB;cAHtF,CAKE,kBAAC,GAAD,EAAU,WAAU,eAAgB,CAAA,EACnC,EAAG,gDAAgD,SAAS,CACtD;;GAGX,kBAAC,UAAD;IACE,eAAe,EAAe,GAAK;IACnC,WAAU;IACV,OAAO,EAAG,wDAAwD,kBAAkB;cAHtF,CAKE,kBAAC,GAAD,EAAQ,WAAU,eAAgB,CAAA,EACjC,EAAG,gDAAgD,SAAS,CACtD;;GAET,kBAAC,UAAD;IACE,SAAS;IACT,WAAU;IACV,OAAO,EAAG,wDAAwD,kBAAkB;cAEpF,kBAAC,GAAD,EAAG,WAAU,eAAgB,CAAA;IACtB,CAAA;GACE;KAEb,kBAAC,GAAD;EACE,QAAQ;EACR,eAAe,EAAe,GAAM;EACpC,iBA1DqB;AAGzB,GAFA,EAAiB,EAAmB,EACpC,GAAgB,EAChB,EAAe,GAAM;;EAwDjB,OAAO,EAAG,6DAA6D,kBAAkB;EACzF,SAAS,EACP,uDACA,gFACA,EAAE,UAAO,CACV;EACD,cAAc,EAAG,gDAAgD,SAAS;EAC1E,aAAa,EAAG,gDAAgD,SAAS;EACzE,SAAQ;EACR,CAAA,CACD,EAAA,CAAA"}
1
+ {"version":3,"file":"AgentManagerBulkActions.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerBulkActions.tsx"],"sourcesContent":["/**\n * Bulk actions bar displayed when one or more sessions are selected.\n *\n * Provides delete-selected and export-selected actions with\n * a ConfirmDialog for destructive operations.\n */\n\nimport { useState } from 'react';\nimport { Trash2, Download, X } from 'lucide-react';\nimport { motion } from 'framer-motion';\nimport { ConfirmDialog } from '@/components/shared';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerBulkActionsProps {\n onDeleteSelected: (sessionIds: string[]) => void;\n onExportSelected?: (sessionIds: string[]) => void;\n}\n\nexport function AgentManagerBulkActions({\n onDeleteSelected,\n onExportSelected,\n}: AgentManagerBulkActionsProps) {\n const selectedSessionIds = useAgentManagerStore((s) => s.selectedSessionIds);\n const clearSelection = useAgentManagerStore((s) => s.clearSelection);\n const [confirmOpen, setConfirmOpen] = useState(false);\n const tr = useTr();\n\n const count = selectedSessionIds.length;\n if (count === 0) return null;\n\n const handleDelete = () => {\n onDeleteSelected(selectedSessionIds);\n clearSelection();\n setConfirmOpen(false);\n };\n\n const handleExport = () => {\n onExportSelected?.(selectedSessionIds);\n clearSelection();\n };\n\n return (\n <>\n <motion.div\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 8 }}\n transition={{ duration: 0.15 }}\n className=\"flex items-center gap-2 px-3 py-2 border-t border-border-default bg-bg-elevated\"\n >\n <span className=\"text-xs font-medium text-text-secondary\">\n {count} {tr('vibecontrols.agentManager.bulkActions.selected', 'selected')}\n </span>\n\n <div className=\"flex-1\" />\n\n {onExportSelected && (\n <button type=\"button\"\n onClick={handleExport}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-text-primary bg-bg-surface border border-border-default rounded-md hover:bg-bg-sunken transition-colors\"\n title={tr('vibecontrols.agentManager.bulkActions.exportSelected', 'Export selected')}\n >\n <Download className=\"size-3.5\" />\n {tr('vibecontrols.agentManager.bulkActions.export', 'Export')}\n </button>\n )}\n\n <button type=\"button\"\n onClick={() => setConfirmOpen(true)}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-status-error-text bg-bg-surface border border-border-default rounded-md hover:bg-status-error-bg-subtle transition-colors\"\n title={tr('vibecontrols.agentManager.bulkActions.deleteSelected', 'Delete selected')}\n >\n <Trash2 className=\"size-3.5\" />\n {tr('vibecontrols.agentManager.bulkActions.delete', 'Delete')}\n </button>\n\n <button type=\"button\"\n onClick={clearSelection}\n className=\"p-1 rounded text-text-secondary hover:text-text-primary hover:bg-bg-sunken transition-colors\"\n title={tr('vibecontrols.agentManager.bulkActions.clearSelection', 'Clear selection')}\n >\n <X className=\"size-3.5\" />\n </button>\n </motion.div>\n\n <ConfirmDialog\n isOpen={confirmOpen}\n onClose={() => setConfirmOpen(false)}\n onConfirm={handleDelete}\n title={tr('vibecontrols.agentManager.bulkActions.deleteSessionsTitle', 'Delete Sessions')}\n message={tr(\n 'vibecontrols.agentManager.bulkActions.confirmDelete',\n 'Are you sure you want to delete {{count}} session(s)? This cannot be undone.',\n { count }\n )}\n confirmLabel={tr('vibecontrols.agentManager.bulkActions.delete', 'Delete')}\n cancelLabel={tr('vibecontrols.agentManager.bulkActions.cancel', 'Cancel')}\n variant=\"danger\"\n />\n </>\n );\n}\n"],"mappings":";;;;;;;;;AAmBA,SAAgB,EAAwB,EACtC,qBACA,uBAC+B;CAC/B,IAAM,IAAqB,GAAsB,MAAM,EAAE,mBAAmB,EACtE,IAAiB,GAAsB,MAAM,EAAE,eAAe,EAC9D,CAAC,GAAa,KAAkB,EAAS,GAAM,EAC/C,IAAK,GAAO,EAEZ,IAAQ,EAAmB;AAcjC,QAbI,MAAU,IAAU,OActB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,EAAO,KAAR;EACE,SAAS;GAAE,SAAS;GAAG,GAAG;GAAG;EAC7B,SAAS;GAAE,SAAS;GAAG,GAAG;GAAG;EAC7B,MAAM;GAAE,SAAS;GAAG,GAAG;GAAG;EAC1B,YAAY,EAAE,UAAU,KAAM;EAC9B,WAAU;YALZ;GAOE,kBAAC,QAAD;IAAM,WAAU;cAAhB;KACG;KAAM;KAAE,EAAG,kDAAkD,WAAW;KACpE;;GAEP,kBAAC,OAAD,EAAK,WAAU,UAAW,CAAA;GAEzB,KACC,kBAAC,UAAD;IAAQ,MAAK;IACX,eAtBiB;AAEzB,KADA,IAAmB,EAAmB,EACtC,GAAgB;;IAqBR,WAAU;IACV,OAAO,EAAG,wDAAwD,kBAAkB;cAHtF,CAKE,kBAAC,GAAD,EAAU,WAAU,YAAa,CAAA,EAChC,EAAG,gDAAgD,SAAS,CACtD;;GAGX,kBAAC,UAAD;IAAQ,MAAK;IACX,eAAe,EAAe,GAAK;IACnC,WAAU;IACV,OAAO,EAAG,wDAAwD,kBAAkB;cAHtF,CAKE,kBAAC,GAAD,EAAQ,WAAU,YAAa,CAAA,EAC9B,EAAG,gDAAgD,SAAS,CACtD;;GAET,kBAAC,UAAD;IAAQ,MAAK;IACX,SAAS;IACT,WAAU;IACV,OAAO,EAAG,wDAAwD,kBAAkB;cAEpF,kBAAC,GAAD,EAAG,WAAU,YAAa,CAAA;IACnB,CAAA;GACE;KAEb,kBAAC,GAAD;EACE,QAAQ;EACR,eAAe,EAAe,GAAM;EACpC,iBA1DqB;AAGzB,GAFA,EAAiB,EAAmB,EACpC,GAAgB,EAChB,EAAe,GAAM;;EAwDjB,OAAO,EAAG,6DAA6D,kBAAkB;EACzF,SAAS,EACP,uDACA,gFACA,EAAE,UAAO,CACV;EACD,cAAc,EAAG,gDAAgD,SAAS;EAC1E,aAAa,EAAG,gDAAgD,SAAS;EACzE,SAAQ;EACR,CAAA,CACD,EAAA,CAAA"}
@@ -99,10 +99,11 @@ var g = [
99
99
  }, y) : /* @__PURE__ */ m("div", {
100
100
  className: "flex-1 flex items-center justify-center h-full",
101
101
  children: /* @__PURE__ */ m(t, {
102
- icon: /* @__PURE__ */ m(f, { className: "w-8 h-8 text-text-secondary" }),
102
+ icon: /* @__PURE__ */ m(f, { className: "size-8 text-text-secondary" }),
103
103
  title: S("vibecontrols.agentManager.center.noActiveSession", "No active session"),
104
104
  description: S("vibecontrols.agentManager.center.createSessionDesc", "Create a new session to start interacting with the AI agent."),
105
105
  action: /* @__PURE__ */ m("button", {
106
+ type: "button",
106
107
  onClick: k,
107
108
  className: "px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors",
108
109
  children: S("vibecontrols.agentManager.center.createNewSession", "Create a new session")
@@ -122,6 +123,11 @@ var g = [
122
123
  T && /* @__PURE__ */ h("div", {
123
124
  className: "fixed inset-0 z-50 flex items-center justify-center",
124
125
  children: [/* @__PURE__ */ m("div", {
126
+ role: "button",
127
+ tabIndex: 0,
128
+ onKeyDown: (e) => {
129
+ (e.key === "Enter" || e.key === " ") && (e.preventDefault(), E(!1));
130
+ },
125
131
  className: "absolute inset-0 bg-bg-overlay",
126
132
  onClick: () => E(!1)
127
133
  }), /* @__PURE__ */ h("div", {
@@ -136,7 +142,7 @@ var g = [
136
142
  type: "button",
137
143
  onClick: () => E(!1),
138
144
  className: "p-1 rounded hover:bg-bg-sunken transition-colors",
139
- children: /* @__PURE__ */ m(p, { className: "w-5 h-5 text-text-secondary" })
145
+ children: /* @__PURE__ */ m(p, { className: "size-5 text-text-secondary" })
140
146
  })]
141
147
  }),
142
148
  /* @__PURE__ */ m("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"AgentManagerCenter.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerCenter.tsx"],"sourcesContent":["/**\n * Center container for the Agent Manager.\n *\n * Renders the tab bar at top and the active session's chat pane below.\n * Shows a welcome/empty state when no tabs are open.\n */\n\nimport { useState, useCallback, useEffect, useRef, type FC } from 'react';\nimport { MessageSquarePlus, X } from 'lucide-react';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { EmptyState } from '@/components/shared';\nimport { AgentManagerTabBar } from './AgentManagerTabBar';\nimport { AgentManagerChatPane } from './AgentManagerChatPane';\nimport { AgentManagerAdminBar } from './AgentManagerAdminBar';\nimport { SessionSearchDialog } from './dialogs/SessionSearchDialog';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { createSession, type AgentRef } from '@/services/aiApi';\n\n/* ────────────────────────────────────────────────────────────────────── */\n/* Keyboard shortcuts reference */\n/* ────────────────────────────────────────────────────────────────────── */\n\nconst SHORTCUTS: Array<{ keys: string; description: string }> = [\n { keys: 'Ctrl/Cmd+Shift+N', description: 'New session' },\n { keys: 'Ctrl/Cmd+Shift+K', description: 'Search sessions' },\n { keys: 'Ctrl/Cmd+Shift+F', description: 'In-session search' },\n { keys: 'Escape', description: 'Cancel / close modal' },\n { keys: 'Enter', description: 'Send message' },\n { keys: 'Shift+Enter', description: 'New line' },\n];\n\ninterface AgentManagerCenterProps {\n agent: AgentRef;\n}\n\nexport const AgentManagerCenter: FC<AgentManagerCenterProps> = ({ agent }) => {\n const tabs = useAgentManagerStore((s) => s.tabs);\n const activeTabSessionId = useAgentManagerStore((s) => s.activeTabSessionId);\n const openSession = useAgentManagerStore((s) => s.openSession);\n const setActiveTab = useAgentManagerStore((s) => s.setActiveTab);\n const tr = useTr();\n\n const [searchOpen, setSearchOpen] = useState(false);\n const [shortcutsOpen, setShortcutsOpen] = useState(false);\n const rootRef = useRef<HTMLDivElement>(null);\n\n const bumpSessionsRefresh = useAgentManagerStore((s) => s.bumpSessionsRefresh);\n const handleCreateSession = useCallback(async () => {\n try {\n const session = await createSession(agent, {\n name: `Session ${tabs.length + 1}`,\n agentType: 'claude',\n config: { model: 'default', mode: 'cli', tags: [] },\n });\n openSession(session.id, session.name);\n bumpSessionsRefresh();\n } catch (err) {\n console.error('[AgentManagerCenter] createSession failed:', err);\n }\n }, [agent, tabs.length, openSession, bumpSessionsRefresh]);\n\n const handleOpenSearch = useCallback(() => setSearchOpen(true), []);\n\n useEffect(() => {\n if (activeTabSessionId && tabs.some((tab) => tab.sessionId === activeTabSessionId)) {\n setActiveTab(activeTabSessionId);\n }\n }, [activeTabSessionId, setActiveTab, tabs]);\n\n // Wire the shortcuts advertised in the SHORTCUTS modal. Scoped to the\n // Agent Manager container so they don't clash with shortcuts on other\n // pages. Each shortcut uses Shift to avoid colliding with built-in\n // browser shortcuts (Ctrl+N opens a window, Ctrl+F opens find).\n useEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n const handler = (e: KeyboardEvent) => {\n if (!root.contains(document.activeElement) && document.activeElement !== root) return;\n const mod = e.ctrlKey || e.metaKey;\n if (mod && e.shiftKey && (e.key === 'N' || e.key === 'n')) {\n e.preventDefault();\n void handleCreateSession();\n return;\n }\n if (mod && e.shiftKey && (e.key === 'K' || e.key === 'k')) {\n e.preventDefault();\n handleOpenSearch();\n return;\n }\n if (mod && e.shiftKey && (e.key === 'F' || e.key === 'f')) {\n e.preventDefault();\n const inSession = root.querySelector(\n '[data-testid=\"agent-manager-in-session-search\"]'\n ) as HTMLButtonElement | null;\n inSession?.click();\n }\n };\n document.addEventListener('keydown', handler);\n return () => document.removeEventListener('keydown', handler);\n }, [handleCreateSession, handleOpenSearch]);\n\n return (\n <div ref={rootRef} className=\"flex flex-col h-full min-h-0\" tabIndex={-1}>\n {/* Tab bar — occupies full row width, search/help live inside the tabBar area */}\n <AgentManagerTabBar\n agent={agent}\n onSearch={handleOpenSearch}\n onShowShortcuts={() => setShortcutsOpen(true)}\n />\n\n {/* Active session or empty state */}\n <div className=\"flex-1 min-h-0 overflow-hidden\">\n {activeTabSessionId && tabs.some((t) => t.sessionId === activeTabSessionId) ? (\n <AgentManagerChatPane\n key={activeTabSessionId}\n sessionId={activeTabSessionId}\n agentId={agent.id}\n />\n ) : (\n <div className=\"flex-1 flex items-center justify-center h-full\">\n <EmptyState\n icon={<MessageSquarePlus className=\"w-8 h-8 text-text-secondary\" />}\n title={tr('vibecontrols.agentManager.center.noActiveSession', 'No active session')}\n description={tr(\n 'vibecontrols.agentManager.center.createSessionDesc',\n 'Create a new session to start interacting with the AI agent.'\n )}\n action={\n <button\n onClick={handleCreateSession}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('vibecontrols.agentManager.center.createNewSession', 'Create a new session')}\n </button>\n }\n />\n </div>\n )}\n </div>\n\n {/* Admin bar at bottom */}\n <div className=\"flex-shrink-0\">\n <AgentManagerAdminBar agent={agent} />\n </div>\n\n {/* Session search dialog */}\n <SessionSearchDialog isOpen={searchOpen} agent={agent} onClose={() => setSearchOpen(false)} />\n\n {/* Keyboard shortcuts modal */}\n {shortcutsOpen && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div className=\"absolute inset-0 bg-bg-overlay\" onClick={() => setShortcutsOpen(false)} />\n <div className=\"relative w-full max-w-sm mx-4 rounded-lg border border-border-default bg-bg-surface shadow-xl\">\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border-default\">\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {tr('vibecontrols.agentManager.center.keyboardShortcuts', 'Keyboard Shortcuts')}\n </h3>\n <button\n type=\"button\"\n onClick={() => setShortcutsOpen(false)}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n >\n <X className=\"w-5 h-5 text-text-secondary\" />\n </button>\n </div>\n <div className=\"px-6 py-4 space-y-2\">\n {SHORTCUTS.map((s) => (\n <div key={s.keys} className=\"flex items-center justify-between py-1\">\n <span className=\"text-sm text-text-secondary\">{s.description}</span>\n <kbd className=\"px-2 py-0.5 text-xs font-mono rounded bg-bg-elevated border border-border-default text-text-primary\">\n {s.keys}\n </kbd>\n </div>\n ))}\n </div>\n <div className=\"px-6 py-3 border-t border-border-default bg-bg-sunken rounded-b-lg\">\n <button\n type=\"button\"\n onClick={() => setShortcutsOpen(false)}\n className=\"w-full px-4 py-2 text-sm font-medium text-text-primary bg-bg-surface border border-border-default rounded-md hover:bg-bg-elevated transition-colors\"\n >\n {tr('vibecontrols.agentManager.center.close', 'Close')}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AgentManagerCenter.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerCenter.tsx"],"sourcesContent":["/**\n * Center container for the Agent Manager.\n *\n * Renders the tab bar at top and the active session's chat pane below.\n * Shows a welcome/empty state when no tabs are open.\n */\n\nimport { useState, useCallback, useEffect, useRef, type FC } from 'react';\nimport { MessageSquarePlus, X } from 'lucide-react';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { EmptyState } from '@/components/shared';\nimport { AgentManagerTabBar } from './AgentManagerTabBar';\nimport { AgentManagerChatPane } from './AgentManagerChatPane';\nimport { AgentManagerAdminBar } from './AgentManagerAdminBar';\nimport { SessionSearchDialog } from './dialogs/SessionSearchDialog';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { createSession, type AgentRef } from '@/services/aiApi';\n\n/* ────────────────────────────────────────────────────────────────────── */\n/* Keyboard shortcuts reference */\n/* ────────────────────────────────────────────────────────────────────── */\n\nconst SHORTCUTS: Array<{ keys: string; description: string }> = [\n { keys: 'Ctrl/Cmd+Shift+N', description: 'New session' },\n { keys: 'Ctrl/Cmd+Shift+K', description: 'Search sessions' },\n { keys: 'Ctrl/Cmd+Shift+F', description: 'In-session search' },\n { keys: 'Escape', description: 'Cancel / close modal' },\n { keys: 'Enter', description: 'Send message' },\n { keys: 'Shift+Enter', description: 'New line' },\n];\n\ninterface AgentManagerCenterProps {\n agent: AgentRef;\n}\n\nexport const AgentManagerCenter: FC<AgentManagerCenterProps> = ({ agent }) => {\n const tabs = useAgentManagerStore((s) => s.tabs);\n const activeTabSessionId = useAgentManagerStore((s) => s.activeTabSessionId);\n const openSession = useAgentManagerStore((s) => s.openSession);\n const setActiveTab = useAgentManagerStore((s) => s.setActiveTab);\n const tr = useTr();\n\n const [searchOpen, setSearchOpen] = useState(false);\n const [shortcutsOpen, setShortcutsOpen] = useState(false);\n const rootRef = useRef<HTMLDivElement>(null);\n\n const bumpSessionsRefresh = useAgentManagerStore((s) => s.bumpSessionsRefresh);\n const handleCreateSession = useCallback(async () => {\n try {\n const session = await createSession(agent, {\n name: `Session ${tabs.length + 1}`,\n agentType: 'claude',\n config: { model: 'default', mode: 'cli', tags: [] },\n });\n openSession(session.id, session.name);\n bumpSessionsRefresh();\n } catch (err) {\n console.error('[AgentManagerCenter] createSession failed:', err);\n }\n }, [agent, tabs.length, openSession, bumpSessionsRefresh]);\n\n const handleOpenSearch = useCallback(() => setSearchOpen(true), []);\n\n useEffect(() => {\n if (activeTabSessionId && tabs.some((tab) => tab.sessionId === activeTabSessionId)) {\n setActiveTab(activeTabSessionId);\n }\n }, [activeTabSessionId, setActiveTab, tabs]);\n\n // Wire the shortcuts advertised in the SHORTCUTS modal. Scoped to the\n // Agent Manager container so they don't clash with shortcuts on other\n // pages. Each shortcut uses Shift to avoid colliding with built-in\n // browser shortcuts (Ctrl+N opens a window, Ctrl+F opens find).\n useEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n const handler = (e: KeyboardEvent) => {\n if (!root.contains(document.activeElement) && document.activeElement !== root) return;\n const mod = e.ctrlKey || e.metaKey;\n if (mod && e.shiftKey && (e.key === 'N' || e.key === 'n')) {\n e.preventDefault();\n void handleCreateSession();\n return;\n }\n if (mod && e.shiftKey && (e.key === 'K' || e.key === 'k')) {\n e.preventDefault();\n handleOpenSearch();\n return;\n }\n if (mod && e.shiftKey && (e.key === 'F' || e.key === 'f')) {\n e.preventDefault();\n const inSession = root.querySelector(\n '[data-testid=\"agent-manager-in-session-search\"]'\n ) as HTMLButtonElement | null;\n inSession?.click();\n }\n };\n document.addEventListener('keydown', handler);\n return () => document.removeEventListener('keydown', handler);\n }, [handleCreateSession, handleOpenSearch]);\n\n return (\n <div ref={rootRef} className=\"flex flex-col h-full min-h-0\" tabIndex={-1}>\n {/* Tab bar — occupies full row width, search/help live inside the tabBar area */}\n <AgentManagerTabBar\n agent={agent}\n onSearch={handleOpenSearch}\n onShowShortcuts={() => setShortcutsOpen(true)}\n />\n\n {/* Active session or empty state */}\n <div className=\"flex-1 min-h-0 overflow-hidden\">\n {activeTabSessionId && tabs.some((t) => t.sessionId === activeTabSessionId) ? (\n <AgentManagerChatPane\n key={activeTabSessionId}\n sessionId={activeTabSessionId}\n agentId={agent.id}\n />\n ) : (\n <div className=\"flex-1 flex items-center justify-center h-full\">\n <EmptyState\n icon={<MessageSquarePlus className=\"size-8 text-text-secondary\" />}\n title={tr('vibecontrols.agentManager.center.noActiveSession', 'No active session')}\n description={tr(\n 'vibecontrols.agentManager.center.createSessionDesc',\n 'Create a new session to start interacting with the AI agent.'\n )}\n action={\n <button type=\"button\"\n onClick={handleCreateSession}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('vibecontrols.agentManager.center.createNewSession', 'Create a new session')}\n </button>\n }\n />\n </div>\n )}\n </div>\n\n {/* Admin bar at bottom */}\n <div className=\"flex-shrink-0\">\n <AgentManagerAdminBar agent={agent} />\n </div>\n\n {/* Session search dialog */}\n <SessionSearchDialog isOpen={searchOpen} agent={agent} onClose={() => setSearchOpen(false)} />\n\n {/* Keyboard shortcuts modal */}\n {shortcutsOpen && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div role=\"button\" tabIndex={0} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); (() => setShortcutsOpen(false))(); } }} className=\"absolute inset-0 bg-bg-overlay\" onClick={() => setShortcutsOpen(false)} />\n <div className=\"relative w-full max-w-sm mx-4 rounded-lg border border-border-default bg-bg-surface shadow-xl\">\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border-default\">\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {tr('vibecontrols.agentManager.center.keyboardShortcuts', 'Keyboard Shortcuts')}\n </h3>\n <button\n type=\"button\"\n onClick={() => setShortcutsOpen(false)}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n >\n <X className=\"size-5 text-text-secondary\" />\n </button>\n </div>\n <div className=\"px-6 py-4 space-y-2\">\n {SHORTCUTS.map((s) => (\n <div key={s.keys} className=\"flex items-center justify-between py-1\">\n <span className=\"text-sm text-text-secondary\">{s.description}</span>\n <kbd className=\"px-2 py-0.5 text-xs font-mono rounded bg-bg-elevated border border-border-default text-text-primary\">\n {s.keys}\n </kbd>\n </div>\n ))}\n </div>\n <div className=\"px-6 py-3 border-t border-border-default bg-bg-sunken rounded-b-lg\">\n <button\n type=\"button\"\n onClick={() => setShortcutsOpen(false)}\n className=\"w-full px-4 py-2 text-sm font-medium text-text-primary bg-bg-surface border border-border-default rounded-md hover:bg-bg-elevated transition-colors\"\n >\n {tr('vibecontrols.agentManager.center.close', 'Close')}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAsBA,IAAM,IAA0D;CAC9D;EAAE,MAAM;EAAoB,aAAa;EAAe;CACxD;EAAE,MAAM;EAAoB,aAAa;EAAmB;CAC5D;EAAE,MAAM;EAAoB,aAAa;EAAqB;CAC9D;EAAE,MAAM;EAAU,aAAa;EAAwB;CACvD;EAAE,MAAM;EAAS,aAAa;EAAgB;CAC9C;EAAE,MAAM;EAAe,aAAa;EAAY;CACjD,EAMY,KAAmD,EAAE,eAAY;CAC5E,IAAM,IAAO,GAAsB,MAAM,EAAE,KAAK,EAC1C,IAAqB,GAAsB,MAAM,EAAE,mBAAmB,EACtE,IAAc,GAAsB,MAAM,EAAE,YAAY,EACxD,IAAe,GAAsB,MAAM,EAAE,aAAa,EAC1D,IAAK,GAAO,EAEZ,CAAC,GAAY,KAAiB,EAAS,GAAM,EAC7C,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,IAAU,EAAuB,KAAK,EAEtC,IAAsB,GAAsB,MAAM,EAAE,oBAAoB,EACxE,IAAsB,EAAY,YAAY;AAClD,MAAI;GACF,IAAM,IAAU,MAAM,EAAc,GAAO;IACzC,MAAM,WAAW,EAAK,SAAS;IAC/B,WAAW;IACX,QAAQ;KAAE,OAAO;KAAW,MAAM;KAAO,MAAM,EAAE;KAAE;IACpD,CAAC;AAEF,GADA,EAAY,EAAQ,IAAI,EAAQ,KAAK,EACrC,GAAqB;WACd,GAAK;AACZ,WAAQ,MAAM,8CAA8C,EAAI;;IAEjE;EAAC;EAAO,EAAK;EAAQ;EAAa;EAAoB,CAAC,EAEpD,IAAmB,QAAkB,EAAc,GAAK,EAAE,EAAE,CAAC;AAwCnE,QAtCA,QAAgB;AACd,EAAI,KAAsB,EAAK,MAAM,MAAQ,EAAI,cAAc,EAAmB,IAChF,EAAa,EAAmB;IAEjC;EAAC;EAAoB;EAAc;EAAK,CAAC,EAM5C,QAAgB;EACd,IAAM,IAAO,EAAQ;AACrB,MAAI,CAAC,EAAM;EACX,IAAM,KAAW,MAAqB;AACpC,OAAI,CAAC,EAAK,SAAS,SAAS,cAAc,IAAI,SAAS,kBAAkB,EAAM;GAC/E,IAAM,IAAM,EAAE,WAAW,EAAE;AAC3B,OAAI,KAAO,EAAE,aAAa,EAAE,QAAQ,OAAO,EAAE,QAAQ,MAAM;AAEpD,IADL,EAAE,gBAAgB,EACb,GAAqB;AAC1B;;AAEF,OAAI,KAAO,EAAE,aAAa,EAAE,QAAQ,OAAO,EAAE,QAAQ,MAAM;AAEzD,IADA,EAAE,gBAAgB,EAClB,GAAkB;AAClB;;AAEF,GAAI,KAAO,EAAE,aAAa,EAAE,QAAQ,OAAO,EAAE,QAAQ,SACnD,EAAE,gBAAgB,EACA,EAAK,cACrB,oDACD,EACU,OAAO;;AAItB,SADA,SAAS,iBAAiB,WAAW,EAAQ,QAChC,SAAS,oBAAoB,WAAW,EAAQ;IAC5D,CAAC,GAAqB,EAAiB,CAAC,EAGzC,kBAAC,OAAD;EAAK,KAAK;EAAS,WAAU;EAA+B,UAAU;YAAtE;GAEE,kBAAC,GAAD;IACS;IACP,UAAU;IACV,uBAAuB,EAAiB,GAAK;IAC7C,CAAA;GAGF,kBAAC,OAAD;IAAK,WAAU;cACZ,KAAsB,EAAK,MAAM,MAAM,EAAE,cAAc,EAAmB,GACzE,kBAAC,GAAD;KAEE,WAAW;KACX,SAAS,EAAM;KACf,EAHK,EAGL,GAEF,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAmB,WAAU,8BAA+B,CAAA;MAClE,OAAO,EAAG,oDAAoD,oBAAoB;MAClF,aAAa,EACX,sDACA,+DACD;MACD,QACE,kBAAC,UAAD;OAAQ,MAAK;OACX,SAAS;OACT,WAAU;iBAET,EAAG,qDAAqD,uBAAuB;OACzE,CAAA;MAEX,CAAA;KACE,CAAA;IAEJ,CAAA;GAGN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD,EAA6B,UAAS,CAAA;IAClC,CAAA;GAGN,kBAAC,GAAD;IAAqB,QAAQ;IAAmB;IAAO,eAAe,EAAc,GAAM;IAAI,CAAA;GAG7F,KACC,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,MAAK;KAAS,UAAU;KAAG,YAAY,MAAM;AAAE,OAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SAAO,EAAE,gBAAgB,EAAS,EAAiB,GAAM;;KAAU,WAAU;KAAiC,eAAe,EAAiB,GAAM;KAAI,CAAA,EAC/O,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAG,sDAAsD,qBAAqB;QAC5E,CAAA,EACL,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAiB,GAAM;QACtC,WAAU;kBAEV,kBAAC,GAAD,EAAG,WAAU,8BAA+B,CAAA;QACrC,CAAA,CACL;;MACN,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAU,KAAK,MACd,kBAAC,OAAD;QAAkB,WAAU;kBAA5B,CACE,kBAAC,QAAD;SAAM,WAAU;mBAA+B,EAAE;SAAmB,CAAA,EACpE,kBAAC,OAAD;SAAK,WAAU;mBACZ,EAAE;SACC,CAAA,CACF;UALI,EAAE,KAKN,CACN;OACE,CAAA;MACN,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAiB,GAAM;QACtC,WAAU;kBAET,EAAG,0CAA0C,QAAQ;QAC/C,CAAA;OACL,CAAA;MACF;OACF;;GAEJ"}
@@ -105,21 +105,21 @@ var C = ({ sessionId: d, agentId: C }) => {
105
105
  className: `p-1 rounded transition-colors shrink-0 ${D ? "bg-action-primary-bg/10 text-action-primary-text" : "text-text-tertiary hover:text-text-secondary hover:bg-bg-elevated"}`,
106
106
  title: B("vibecontrols.agentManager.chatPane.searchInSession", "Search in session (Ctrl+F)"),
107
107
  "aria-label": B("vibecontrols.agentManager.chatPane.searchInSession", "Search in session"),
108
- children: /* @__PURE__ */ x(ee, { className: "w-3.5 h-3.5" })
108
+ children: /* @__PURE__ */ x(ee, { className: "size-3.5" })
109
109
  }), D && /* @__PURE__ */ S("div", {
110
110
  className: "flex items-center gap-1.5 flex-1 min-w-0",
111
111
  children: [/* @__PURE__ */ x("input", {
112
+ "aria-label": "control",
112
113
  type: "text",
113
114
  value: k,
114
115
  onChange: (e) => A(e.target.value),
115
116
  placeholder: B("vibecontrols.agentManager.chatPane.searchPlaceholder", "Search in conversation..."),
116
- autoFocus: !0,
117
117
  className: "flex-1 min-w-0 bg-transparent text-xs text-text-primary placeholder:text-text-tertiary focus:outline-none"
118
118
  }), k && /* @__PURE__ */ x("button", {
119
119
  type: "button",
120
120
  onClick: () => A(""),
121
121
  className: "p-0.5 rounded hover:bg-bg-elevated transition-colors",
122
- children: /* @__PURE__ */ x(y, { className: "w-3 h-3 text-text-tertiary" })
122
+ children: /* @__PURE__ */ x(y, { className: "size-3 text-text-tertiary" })
123
123
  })]
124
124
  })]
125
125
  }),
@@ -130,7 +130,7 @@ var C = ({ sessionId: d, agentId: C }) => {
130
130
  title: B("vibecontrols.agentManager.chatPane.bookmarksTooltip", "View bookmarked messages"),
131
131
  "aria-label": B("vibecontrols.agentManager.chatPane.bookmarksLabel", "Bookmarks"),
132
132
  "data-testid": "agent-manager-bookmarks-trigger",
133
- children: /* @__PURE__ */ x(_, { className: "w-3.5 h-3.5" })
133
+ children: /* @__PURE__ */ x(_, { className: "size-3.5" })
134
134
  }),
135
135
  /* @__PURE__ */ S("button", {
136
136
  type: "button",
@@ -139,7 +139,7 @@ var C = ({ sessionId: d, agentId: C }) => {
139
139
  title: B("vibecontrols.agentManager.chatPane.manageProvidersTooltip", "Install or remove AI providers (Claude, Codex, Gemini, OpenCode)"),
140
140
  "aria-label": B("vibecontrols.agentManager.chatPane.manageProviders", "Manage AI providers"),
141
141
  "data-testid": "agent-manager-manage-providers",
142
- children: [/* @__PURE__ */ x(v, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ x("span", {
142
+ children: [/* @__PURE__ */ x(v, { className: "size-3.5" }), /* @__PURE__ */ x("span", {
143
143
  className: "hidden sm:inline",
144
144
  children: B("vibecontrols.agentManager.chatPane.manageProviders", "Manage AI providers")
145
145
  })]
@@ -211,7 +211,7 @@ var C = ({ sessionId: d, agentId: C }) => {
211
211
  onClick: () => o(null),
212
212
  className: "p-1 rounded hover:bg-bg-sunken transition-colors flex-shrink-0",
213
213
  "aria-label": l("vibecontrols.common.close", "Close"),
214
- children: /* @__PURE__ */ x(y, { className: "w-5 h-5 text-text-secondary" })
214
+ children: /* @__PURE__ */ x(y, { className: "size-5 text-text-secondary" })
215
215
  })]
216
216
  }),
217
217
  /* @__PURE__ */ S("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"AgentManagerChatPane.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerChatPane.tsx"],"sourcesContent":["/**\n * Main chat interface for a single Agent Manager session.\n *\n * Renders message list + input area, manages the send/receive flow,\n * fetches existing conversation logs on mount, and provides\n * auto-scroll, cancel, and in-session search support.\n */\n\nimport { useEffect, useRef, useState, useCallback, useMemo, type FC } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { Bookmark, PackagePlus, Search, X } from 'lucide-react';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { useAgentManagerStreaming } from '@/hooks/useAgentManagerStreaming';\nimport { useCachedInitialData } from '@/hooks/useCachedInitialData';\nimport { fetchSessionLogs } from '@/services/aiApi';\nimport { useActiveAgentProfile } from '@/hooks/useActiveAgentProfile';\nimport { useToggleAgentBookmark } from '@/hooks/useToggleAgentBookmark';\nimport { AgentManagerMessageList } from './AgentManagerMessageList';\nimport { AgentManagerInputArea } from './AgentManagerInputArea';\nimport { AgentManagerBookmarksDrawer } from './AgentManagerBookmarksDrawer';\nimport { PluginInstallModal } from './PluginInstallModal';\nimport { AIProviderCredentialsCard } from '@/components/ai/AIProviderCredentialsCard';\nimport type { AgentManagerMessage } from '@/types/agentManager';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerChatPaneProps {\n sessionId: string;\n agentId: string;\n}\n\nexport const AgentManagerChatPane: FC<AgentManagerChatPaneProps> = ({ sessionId, agentId }) => {\n const [loadingLogs, setLoadingLogs] = useState(false);\n const [searchOpen, setSearchOpen] = useState(false);\n const [searchQuery, setSearchQuery] = useState('');\n // Provider-install modal triggered from the header. Lets users add a\n // claude/codex/gemini/opencode plugin without leaving the conversation.\n const [installModalOpen, setInstallModalOpen] = useState(false);\n const [bookmarksDrawerOpen, setBookmarksDrawerOpen] = useState(false);\n const [flashMessageId, setFlashMessageId] = useState<string | null>(null);\n const [searchParams, setSearchParams] = useSearchParams();\n const pendingScrollMessageId = searchParams.get('messageId');\n const consumedScrollTargetRef = useRef<string | null>(null);\n const tr = useTr();\n\n const { agents } = useCachedInitialData();\n const activeAgent = useMemo(\n () => agents.find((a) => a.id === agentId) ?? null,\n [agents, agentId]\n );\n\n const sessionState = useAgentManagerStore((s) => s.sessionStates[sessionId]);\n const addMessage = useAgentManagerStore((s) => s.addMessage);\n\n const messages = useMemo(() => sessionState?.messages ?? [], [sessionState?.messages]);\n\n const { active: activeProfile } = useActiveAgentProfile(activeAgent?.id ?? null);\n const agentRef = useMemo(\n () => ({ id: agentId, profile: activeProfile }),\n [agentId, activeProfile]\n );\n\n const { sendMessage, cancelStream, isStreaming } = useAgentManagerStreaming({\n agent: agentRef,\n sessionId,\n });\n\n const { bookmarkedIds, toggle: toggleBookmark } = useToggleAgentBookmark(sessionId);\n\n const jumpToMessage = useCallback((messageId: string) => {\n const el = document.querySelector(`[data-message-id=\"${messageId}\"]`);\n if (!el) return;\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n setFlashMessageId(messageId);\n window.setTimeout(() => {\n setFlashMessageId((current) => (current === messageId ? null : current));\n }, 1500);\n }, []);\n\n const handleToggleBookmark = useCallback(\n (messageId: string) => {\n void toggleBookmark({ agentId, sessionId, messageId });\n },\n [toggleBookmark, agentId, sessionId]\n );\n\n const toggleSearch = useCallback(() => {\n setSearchOpen((prev) => {\n if (prev) setSearchQuery('');\n return !prev;\n });\n }, []);\n\n // Fetch existing conversation logs on mount\n useEffect(() => {\n let cancelled = false;\n\n const loadExistingLogs = async () => {\n // Only load if session has no messages yet\n if (messages.length > 0) return;\n\n setLoadingLogs(true);\n try {\n const logs = await fetchSessionLogs(agentRef, sessionId, {\n types: ['input', 'output'],\n });\n\n if (cancelled || logs.length === 0) return;\n\n const seenLogKeys = new Set<string>();\n\n // Convert session logs to AgentManagerMessage format. The core AI\n // route owns logging, but older provider builds also wrote the same\n // input/output records; collapse same-second duplicates on restore.\n for (const log of logs) {\n const content = log.message || log.content || '';\n const timestamp = log.timestamp || log.createdAt;\n const timestampSecond = timestamp ? Math.floor(new Date(timestamp).getTime() / 1000) : 0;\n const logKey = [log.type, content, log.model ?? '', timestampSecond].join('\\u0000');\n if (seenLogKeys.has(logKey)) continue;\n seenLogKeys.add(logKey);\n\n const msg: AgentManagerMessage = {\n id: log.id,\n role: log.type === 'input' ? 'user' : 'assistant',\n content,\n timestamp,\n tokens: log.tokenCount ? { input: 0, output: log.tokenCount } : undefined,\n model: log.model,\n };\n addMessage(sessionId, msg);\n }\n } catch {\n // Silent fail -- session may not have logs yet\n } finally {\n if (!cancelled) setLoadingLogs(false);\n }\n };\n\n void loadExistingLogs();\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- only run on mount\n }, [agentId, sessionId]);\n\n // Auto-scroll to a message linked via ?messageId=... (from drawer / cross-session page).\n // Waits for logs to finish loading and the target to be in the DOM before scrolling.\n useEffect(() => {\n if (!pendingScrollMessageId || loadingLogs) return;\n if (consumedScrollTargetRef.current === pendingScrollMessageId) return;\n\n const exists = messages.some((m) => m.id === pendingScrollMessageId);\n if (!exists) return;\n\n consumedScrollTargetRef.current = pendingScrollMessageId;\n jumpToMessage(pendingScrollMessageId);\n\n // Strip the query param so a manual refresh doesn't re-trigger the flash.\n const next = new URLSearchParams(searchParams);\n next.delete('messageId');\n setSearchParams(next, { replace: true });\n }, [pendingScrollMessageId, loadingLogs, messages, jumpToMessage, searchParams, setSearchParams]);\n\n return (\n <div className=\"flex flex-col h-full min-h-0\" data-testid=\"agent-manager-chat-pane\">\n {/* In-session search bar.\n Layout: [search controls (flex-1)] ... [Manage AI providers].\n The search input expands inside the LEFT cluster only, so the\n Manage button stays anchored on the right and never shifts. */}\n <div className=\"flex items-center gap-1 px-3 py-1 border-b border-border-default bg-bg-surface flex-shrink-0\">\n <div className=\"flex items-center gap-1.5 min-w-0 flex-1\">\n <button\n type=\"button\"\n onClick={toggleSearch}\n className={`p-1 rounded transition-colors shrink-0 ${\n searchOpen\n ? 'bg-action-primary-bg/10 text-action-primary-text'\n : 'text-text-tertiary hover:text-text-secondary hover:bg-bg-elevated'\n }`}\n title={tr(\n 'vibecontrols.agentManager.chatPane.searchInSession',\n 'Search in session (Ctrl+F)'\n )}\n aria-label={tr(\n 'vibecontrols.agentManager.chatPane.searchInSession',\n 'Search in session'\n )}\n >\n <Search className=\"w-3.5 h-3.5\" />\n </button>\n {searchOpen && (\n <div className=\"flex items-center gap-1.5 flex-1 min-w-0\">\n <input\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder={tr(\n 'vibecontrols.agentManager.chatPane.searchPlaceholder',\n 'Search in conversation...'\n )}\n autoFocus\n className=\"flex-1 min-w-0 bg-transparent text-xs text-text-primary placeholder:text-text-tertiary focus:outline-none\"\n />\n {searchQuery && (\n <button\n type=\"button\"\n onClick={() => setSearchQuery('')}\n className=\"p-0.5 rounded hover:bg-bg-elevated transition-colors\"\n >\n <X className=\"w-3 h-3 text-text-tertiary\" />\n </button>\n )}\n </div>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => setBookmarksDrawerOpen(true)}\n className=\"shrink-0 p-1 rounded transition-colors text-text-tertiary hover:text-text-secondary hover:bg-bg-elevated\"\n title={tr(\n 'vibecontrols.agentManager.chatPane.bookmarksTooltip',\n 'View bookmarked messages'\n )}\n aria-label={tr('vibecontrols.agentManager.chatPane.bookmarksLabel', 'Bookmarks')}\n data-testid=\"agent-manager-bookmarks-trigger\"\n >\n <Bookmark className=\"w-3.5 h-3.5\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setInstallModalOpen(true)}\n className=\"shrink-0 inline-flex items-center gap-1.5 rounded-md border border-border-default bg-bg-elevated px-2 py-1 text-xs font-medium text-text-primary transition-colors hover:bg-bg-sunken hover:border-action-primary-bg/40\"\n title={tr(\n 'vibecontrols.agentManager.chatPane.manageProvidersTooltip',\n 'Install or remove AI providers (Claude, Codex, Gemini, OpenCode)'\n )}\n aria-label={tr(\n 'vibecontrols.agentManager.chatPane.manageProviders',\n 'Manage AI providers'\n )}\n data-testid=\"agent-manager-manage-providers\"\n >\n <PackagePlus className=\"w-3.5 h-3.5\" />\n <span className=\"hidden sm:inline\">\n {tr('vibecontrols.agentManager.chatPane.manageProviders', 'Manage AI providers')}\n </span>\n </button>\n </div>\n\n {/* Message list */}\n {loadingLogs ? (\n <div className=\"flex-1 flex items-center justify-center\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\n 'vibecontrols.agentManager.chatPane.loadingConversation',\n 'Loading conversation...'\n )}\n </p>\n </div>\n ) : (\n <AgentManagerMessageList\n messages={messages}\n isStreaming={isStreaming}\n onCancelStream={cancelStream}\n searchQuery={searchQuery}\n bookmarkedIds={bookmarkedIds}\n onToggleBookmark={handleToggleBookmark}\n flashMessageId={flashMessageId}\n />\n )}\n\n {/* Rich input area with controls */}\n <AgentManagerInputArea\n agentId={agentId}\n sessionId={sessionId}\n onSend={(text) => void sendMessage(text)}\n onCancel={cancelStream}\n agentTunnelUrl={activeAgent?.tunnelUrl ?? undefined}\n agentApiKey={activeAgent?.agentApiKey ?? undefined}\n />\n\n {/* Per-session bookmarks drawer */}\n <AgentManagerBookmarksDrawer\n open={bookmarksDrawerOpen}\n onClose={() => setBookmarksDrawerOpen(false)}\n sessionId={sessionId}\n messages={messages}\n onJump={jumpToMessage}\n />\n\n {/* Header-triggered provider install/remove. Sits below the chat\n tree so it can render full-screen without disturbing layout. */}\n <PluginInstallModal\n open={installModalOpen}\n agentId={agentId}\n onClose={() => setInstallModalOpen(false)}\n />\n\n {/* SDK auth prompt: opens when the streaming hook detects a missing\n ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN, so the user can save the\n credential inline instead of being told to go look elsewhere.\n The session's currently-selected SDK is forwarded so the picker\n can preselect the right provider. */}\n <SdkAuthPromptModal\n agentId={agentId}\n agentRef={agentRef}\n initialProviderId={sessionState?.sdk ?? undefined}\n />\n </div>\n );\n};\n\ninterface SdkAuthPromptModalProps {\n agentId: string;\n agentRef: { id: string; profile: string };\n initialProviderId?: string;\n}\n\nconst SdkAuthPromptModal: FC<SdkAuthPromptModalProps> = ({\n agentId,\n agentRef,\n initialProviderId,\n}) => {\n const sdkAuthPrompt = useAgentManagerStore((s) => s.sdkAuthPrompt);\n const setSdkAuthPrompt = useAgentManagerStore((s) => s.setSdkAuthPrompt);\n // Track whether the inner card has at least one primary credential\n // saved on the agent. The Continue button is gated on this so the user\n // can't dismiss the modal without actually persisting a key — but the\n // moment they save *any* of the either-or options it lights up.\n const [authSatisfied, setAuthSatisfied] = useState(false);\n const tr = useTr();\n\n // Reset the satisfied flag whenever the modal re-opens for a fresh\n // prompt (different agent / different session). Without this, dismissing\n // and re-opening would leave the flag stuck at its previous value.\n useEffect(() => {\n if (sdkAuthPrompt && sdkAuthPrompt.agentId === agentId) {\n setAuthSatisfied(false);\n }\n }, [sdkAuthPrompt, agentId]);\n\n if (!sdkAuthPrompt || sdkAuthPrompt.agentId !== agentId) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <div\n className=\"absolute inset-0 bg-bg-overlay\"\n onClick={() => setSdkAuthPrompt(null)}\n aria-hidden\n />\n {/* Constrain height to the viewport and let the inner body scroll so the\n modal never escapes the screen no matter how many providers/fields\n render inside AIProviderCredentialsCard. The header + footer stay\n sticky so the close + Continue buttons are always reachable. */}\n <div className=\"relative w-full max-w-xl max-h-[85vh] flex flex-col rounded-lg border border-border-default bg-bg-surface shadow-xl overflow-hidden\">\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default bg-bg-surface flex-shrink-0\">\n <h3 className=\"text-base font-semibold text-text-primary truncate pr-2\">\n {tr('vibecontrols.ai.sdkAuth.title', 'Configure AI provider credentials')}\n </h3>\n <button\n type=\"button\"\n onClick={() => setSdkAuthPrompt(null)}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors flex-shrink-0\"\n aria-label={tr('vibecontrols.common.close', 'Close')}\n >\n <X className=\"w-5 h-5 text-text-secondary\" />\n </button>\n </div>\n <div className=\"flex-1 min-h-0 overflow-y-auto px-4 py-3 space-y-3\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\n 'vibecontrols.ai.sdkAuth.body',\n \"The agent doesn't have a credential configured for this provider. Save any one of the listed keys (you don't need all of them) and click Continue to retry.\"\n )}\n </p>\n <AIProviderCredentialsCard\n agent={agentRef}\n initialProviderId={initialProviderId}\n onProviderAuthSatisfiedChange={setAuthSatisfied}\n />\n </div>\n <div className=\"flex items-center justify-end gap-2 px-4 py-3 border-t border-border-default bg-bg-surface flex-shrink-0\">\n <button\n type=\"button\"\n onClick={() => setSdkAuthPrompt(null)}\n className=\"px-3 py-1.5 rounded-md text-sm text-text-secondary hover:text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n {tr('vibecontrols.common.close', 'Close')}\n </button>\n <button\n type=\"button\"\n onClick={() => setSdkAuthPrompt(null)}\n disabled={!authSatisfied}\n title={\n authSatisfied\n ? undefined\n : tr(\n 'vibecontrols.ai.sdkAuth.saveOneFirst',\n 'Save at least one of the listed credentials to continue'\n )\n }\n className=\"px-3 py-1.5 rounded-md text-sm font-medium bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {tr('vibecontrols.ai.sdkAuth.continue', 'Continue')}\n </button>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AA8BA,IAAa,KAAuD,EAAE,cAAW,iBAAc;CAC7F,IAAM,CAAC,GAAa,KAAkB,EAAS,GAAM,EAC/C,CAAC,GAAY,KAAiB,EAAS,GAAM,EAC7C,CAAC,GAAa,KAAkB,EAAS,GAAG,EAG5C,CAAC,GAAkB,KAAuB,EAAS,GAAM,EACzD,CAAC,IAAqB,KAA0B,EAAS,GAAM,EAC/D,CAAC,GAAgB,KAAqB,EAAwB,KAAK,EACnE,CAAC,GAAc,KAAmB,GAAiB,EACnD,IAAyB,EAAa,IAAI,YAAY,EACtD,IAA0B,EAAsB,KAAK,EACrD,IAAK,GAAO,EAEZ,EAAE,cAAW,GAAsB,EACnC,IAAc,QACZ,EAAO,MAAM,MAAM,EAAE,OAAO,EAAQ,IAAI,MAC9C,CAAC,GAAQ,EAAQ,CAClB,EAEK,IAAe,GAAsB,MAAM,EAAE,cAAc,GAAW,EACtE,IAAa,GAAsB,MAAM,EAAE,WAAW,EAEtD,IAAW,QAAc,GAAc,YAAY,EAAE,EAAE,CAAC,GAAc,SAAS,CAAC,EAEhF,EAAE,QAAQ,MAAkB,EAAsB,GAAa,MAAM,KAAK,EAC1E,IAAW,SACR;EAAE,IAAI;EAAS,SAAS;EAAe,GAC9C,CAAC,GAAS,EAAc,CACzB,EAEK,EAAE,gBAAa,iBAAc,mBAAgB,EAAyB;EAC1E,OAAO;EACP;EACD,CAAC,EAEI,EAAE,kBAAe,QAAQ,MAAmB,EAAuB,EAAU,EAE7E,IAAgB,GAAa,MAAsB;EACvD,IAAM,IAAK,SAAS,cAAc,qBAAqB,EAAU,IAAI;AAChE,QACL,EAAG,eAAe;GAAE,UAAU;GAAU,OAAO;GAAU,CAAC,EAC1D,EAAkB,EAAU,EAC5B,OAAO,iBAAiB;AACtB,MAAmB,MAAa,MAAY,IAAY,OAAO,EAAS;KACvE,KAAK;IACP,EAAE,CAAC,EAEA,KAAuB,GAC1B,MAAsB;AAChB,IAAe;GAAE;GAAS;GAAW;GAAW,CAAC;IAExD;EAAC;EAAgB;EAAS;EAAU,CACrC,EAEK,KAAe,QAAkB;AACrC,KAAe,OACT,KAAM,EAAe,GAAG,EACrB,CAAC,GACR;IACD,EAAE,CAAC;AA0EN,QAvEA,QAAgB;EACd,IAAI,IAAY;AA8ChB,UA5CyB,YAAY;AAE/B,WAAS,SAAS,IAEtB;MAAe,GAAK;AACpB,QAAI;KACF,IAAM,IAAO,MAAM,EAAiB,GAAU,GAAW,EACvD,OAAO,CAAC,SAAS,SAAS,EAC3B,CAAC;AAEF,SAAI,KAAa,EAAK,WAAW,EAAG;KAEpC,IAAM,oBAAc,IAAI,KAAa;AAKrC,UAAK,IAAM,KAAO,GAAM;MACtB,IAAM,IAAU,EAAI,WAAW,EAAI,WAAW,IACxC,IAAY,EAAI,aAAa,EAAI,WACjC,IAAkB,IAAY,KAAK,MAAM,IAAI,KAAK,EAAU,CAAC,SAAS,GAAG,IAAK,GAAG,GACjF,IAAS;OAAC,EAAI;OAAM;OAAS,EAAI,SAAS;OAAI;OAAgB,CAAC,KAAK,KAAS;AAC/E,QAAY,IAAI,EAAO,KAC3B,EAAY,IAAI,EAAO,EAUvB,EAAW,GARsB;OAC/B,IAAI,EAAI;OACR,MAAM,EAAI,SAAS,UAAU,SAAS;OACtC;OACA;OACA,QAAQ,EAAI,aAAa;QAAE,OAAO;QAAG,QAAQ,EAAI;QAAY,GAAG,KAAA;OAChE,OAAO,EAAI;OACZ,CACyB;;YAEtB,WAEE;AACR,KAAK,KAAW,EAAe,GAAM;;;MAIlB,QAEV;AACX,OAAY;;IAGb,CAAC,GAAS,EAAU,CAAC,EAIxB,QAAgB;AAKd,MAJI,CAAC,KAA0B,KAC3B,EAAwB,YAAY,KAGpC,CADW,EAAS,MAAM,MAAM,EAAE,OAAO,EAAuB,CACvD;AAGb,EADA,EAAwB,UAAU,GAClC,EAAc,EAAuB;EAGrC,IAAM,IAAO,IAAI,gBAAgB,EAAa;AAE9C,EADA,EAAK,OAAO,YAAY,EACxB,EAAgB,GAAM,EAAE,SAAS,IAAM,CAAC;IACvC;EAAC;EAAwB;EAAa;EAAU;EAAe;EAAc;EAAgB,CAAC,EAG/F,kBAAC,OAAD;EAAK,WAAU;EAA+B,eAAY;YAA1D;GAKE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,WAAW,0CACT,IACI,qDACA;OAEN,OAAO,EACL,sDACA,6BACD;OACD,cAAY,EACV,sDACA,oBACD;iBAED,kBAAC,IAAD,EAAQ,WAAU,eAAgB,CAAA;OAC3B,CAAA,EACR,KACC,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,SAAD;QACE,MAAK;QACL,OAAO;QACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;QAC/C,aAAa,EACX,wDACA,4BACD;QACD,WAAA;QACA,WAAU;QACV,CAAA,EACD,KACC,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAe,GAAG;QACjC,WAAU;kBAEV,kBAAC,GAAD,EAAG,WAAU,8BAA+B,CAAA;QACrC,CAAA,CAEP;SAEJ;;KACN,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAuB,GAAK;MAC3C,WAAU;MACV,OAAO,EACL,uDACA,2BACD;MACD,cAAY,EAAG,qDAAqD,YAAY;MAChF,eAAY;gBAEZ,kBAAC,GAAD,EAAU,WAAU,eAAgB,CAAA;MAC7B,CAAA;KACT,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAoB,GAAK;MACxC,WAAU;MACV,OAAO,EACL,6DACA,mEACD;MACD,cAAY,EACV,sDACA,sBACD;MACD,eAAY;gBAZd,CAcE,kBAAC,GAAD,EAAa,WAAU,eAAgB,CAAA,EACvC,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAG,sDAAsD,sBAAsB;OAC3E,CAAA,CACA;;KACL;;GAGL,IACC,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,KAAD;KAAG,WAAU;eACV,EACC,0DACA,0BACD;KACC,CAAA;IACA,CAAA,GAEN,kBAAC,GAAD;IACY;IACG;IACb,gBAAgB;IACH;IACE;IACf,kBAAkB;IACF;IAChB,CAAA;GAIJ,kBAAC,GAAD;IACW;IACE;IACX,SAAS,MAAS,KAAK,EAAY,EAAK;IACxC,UAAU;IACV,gBAAgB,GAAa,aAAa,KAAA;IAC1C,aAAa,GAAa,eAAe,KAAA;IACzC,CAAA;GAGF,kBAAC,GAAD;IACE,MAAM;IACN,eAAe,EAAuB,GAAM;IACjC;IACD;IACV,QAAQ;IACR,CAAA;GAIF,kBAAC,GAAD;IACE,MAAM;IACG;IACT,eAAe,EAAoB,GAAM;IACzC,CAAA;GAOF,kBAAC,GAAD;IACW;IACC;IACV,mBAAmB,GAAc,OAAO,KAAA;IACxC,CAAA;GACE;;GAUJ,KAAmD,EACvD,YACA,aACA,2BACI;CACJ,IAAM,IAAgB,GAAsB,MAAM,EAAE,cAAc,EAC5D,IAAmB,GAAsB,MAAM,EAAE,iBAAiB,EAKlE,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,IAAK,GAAO;AAalB,QARA,QAAgB;AACd,EAAI,KAAiB,EAAc,YAAY,KAC7C,EAAiB,GAAM;IAExB,CAAC,GAAe,EAAQ,CAAC,EAExB,CAAC,KAAiB,EAAc,YAAY,IAAgB,OAG9D,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GACE,WAAU;GACV,eAAe,EAAiB,KAAK;GACrC,eAAA;GACA,CAAA,EAKF,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAG,iCAAiC,oCAAoC;MACtE,CAAA,EACL,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAiB,KAAK;MACrC,WAAU;MACV,cAAY,EAAG,6BAA6B,QAAQ;gBAEpD,kBAAC,GAAD,EAAG,WAAU,+BAAgC,CAAA;MACtC,CAAA,CACL;;IACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EACC,gCACA,8JACD;MACC,CAAA,EACJ,kBAAC,GAAD;MACE,OAAO;MACY;MACnB,+BAA+B;MAC/B,CAAA,CACE;;IACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAiB,KAAK;MACrC,WAAU;gBAET,EAAG,6BAA6B,QAAQ;MAClC,CAAA,EACT,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAiB,KAAK;MACrC,UAAU,CAAC;MACX,OACE,IACI,KAAA,IACA,EACE,wCACA,0DACD;MAEP,WAAU;gBAET,EAAG,oCAAoC,WAAW;MAC5C,CAAA,CACL;;IACF;KACF"}
1
+ {"version":3,"file":"AgentManagerChatPane.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerChatPane.tsx"],"sourcesContent":["/**\n * Main chat interface for a single Agent Manager session.\n *\n * Renders message list + input area, manages the send/receive flow,\n * fetches existing conversation logs on mount, and provides\n * auto-scroll, cancel, and in-session search support.\n */\n\nimport { useEffect, useRef, useState, useCallback, useMemo, type FC } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { Bookmark, PackagePlus, Search, X } from 'lucide-react';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { useAgentManagerStreaming } from '@/hooks/useAgentManagerStreaming';\nimport { useCachedInitialData } from '@/hooks/useCachedInitialData';\nimport { fetchSessionLogs } from '@/services/aiApi';\nimport { useActiveAgentProfile } from '@/hooks/useActiveAgentProfile';\nimport { useToggleAgentBookmark } from '@/hooks/useToggleAgentBookmark';\nimport { AgentManagerMessageList } from './AgentManagerMessageList';\nimport { AgentManagerInputArea } from './AgentManagerInputArea';\nimport { AgentManagerBookmarksDrawer } from './AgentManagerBookmarksDrawer';\nimport { PluginInstallModal } from './PluginInstallModal';\nimport { AIProviderCredentialsCard } from '@/components/ai/AIProviderCredentialsCard';\nimport type { AgentManagerMessage } from '@/types/agentManager';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerChatPaneProps {\n sessionId: string;\n agentId: string;\n}\n\nexport const AgentManagerChatPane: FC<AgentManagerChatPaneProps> = ({ sessionId, agentId }) => {\n const [loadingLogs, setLoadingLogs] = useState(false);\n const [searchOpen, setSearchOpen] = useState(false);\n const [searchQuery, setSearchQuery] = useState('');\n // Provider-install modal triggered from the header. Lets users add a\n // claude/codex/gemini/opencode plugin without leaving the conversation.\n const [installModalOpen, setInstallModalOpen] = useState(false);\n const [bookmarksDrawerOpen, setBookmarksDrawerOpen] = useState(false);\n const [flashMessageId, setFlashMessageId] = useState<string | null>(null);\n const [searchParams, setSearchParams] = useSearchParams();\n const pendingScrollMessageId = searchParams.get('messageId');\n const consumedScrollTargetRef = useRef<string | null>(null);\n const tr = useTr();\n\n const { agents } = useCachedInitialData();\n const activeAgent = useMemo(\n () => agents.find((a) => a.id === agentId) ?? null,\n [agents, agentId]\n );\n\n const sessionState = useAgentManagerStore((s) => s.sessionStates[sessionId]);\n const addMessage = useAgentManagerStore((s) => s.addMessage);\n\n const messages = useMemo(() => sessionState?.messages ?? [], [sessionState?.messages]);\n\n const { active: activeProfile } = useActiveAgentProfile(activeAgent?.id ?? null);\n const agentRef = useMemo(\n () => ({ id: agentId, profile: activeProfile }),\n [agentId, activeProfile]\n );\n\n const { sendMessage, cancelStream, isStreaming } = useAgentManagerStreaming({\n agent: agentRef,\n sessionId,\n });\n\n const { bookmarkedIds, toggle: toggleBookmark } = useToggleAgentBookmark(sessionId);\n\n const jumpToMessage = useCallback((messageId: string) => {\n const el = document.querySelector(`[data-message-id=\"${messageId}\"]`);\n if (!el) return;\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n setFlashMessageId(messageId);\n window.setTimeout(() => {\n setFlashMessageId((current) => (current === messageId ? null : current));\n }, 1500);\n }, []);\n\n const handleToggleBookmark = useCallback(\n (messageId: string) => {\n void toggleBookmark({ agentId, sessionId, messageId });\n },\n [toggleBookmark, agentId, sessionId]\n );\n\n const toggleSearch = useCallback(() => {\n setSearchOpen((prev) => {\n if (prev) setSearchQuery('');\n return !prev;\n });\n }, []);\n\n // Fetch existing conversation logs on mount\n useEffect(() => {\n let cancelled = false;\n\n const loadExistingLogs = async () => {\n // Only load if session has no messages yet\n if (messages.length > 0) return;\n\n setLoadingLogs(true);\n try {\n const logs = await fetchSessionLogs(agentRef, sessionId, {\n types: ['input', 'output'],\n });\n\n if (cancelled || logs.length === 0) return;\n\n const seenLogKeys = new Set<string>();\n\n // Convert session logs to AgentManagerMessage format. The core AI\n // route owns logging, but older provider builds also wrote the same\n // input/output records; collapse same-second duplicates on restore.\n for (const log of logs) {\n const content = log.message || log.content || '';\n const timestamp = log.timestamp || log.createdAt;\n const timestampSecond = timestamp ? Math.floor(new Date(timestamp).getTime() / 1000) : 0;\n const logKey = [log.type, content, log.model ?? '', timestampSecond].join('\\u0000');\n if (seenLogKeys.has(logKey)) continue;\n seenLogKeys.add(logKey);\n\n const msg: AgentManagerMessage = {\n id: log.id,\n role: log.type === 'input' ? 'user' : 'assistant',\n content,\n timestamp,\n tokens: log.tokenCount ? { input: 0, output: log.tokenCount } : undefined,\n model: log.model,\n };\n addMessage(sessionId, msg);\n }\n } catch {\n // Silent fail -- session may not have logs yet\n } finally {\n if (!cancelled) setLoadingLogs(false);\n }\n };\n\n void loadExistingLogs();\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- only run on mount\n }, [agentId, sessionId]);\n\n // Auto-scroll to a message linked via ?messageId=... (from drawer / cross-session page).\n // Waits for logs to finish loading and the target to be in the DOM before scrolling.\n useEffect(() => {\n if (!pendingScrollMessageId || loadingLogs) return;\n if (consumedScrollTargetRef.current === pendingScrollMessageId) return;\n\n const exists = messages.some((m) => m.id === pendingScrollMessageId);\n if (!exists) return;\n\n consumedScrollTargetRef.current = pendingScrollMessageId;\n jumpToMessage(pendingScrollMessageId);\n\n // Strip the query param so a manual refresh doesn't re-trigger the flash.\n const next = new URLSearchParams(searchParams);\n next.delete('messageId');\n setSearchParams(next, { replace: true });\n }, [pendingScrollMessageId, loadingLogs, messages, jumpToMessage, searchParams, setSearchParams]);\n\n return (\n <div className=\"flex flex-col h-full min-h-0\" data-testid=\"agent-manager-chat-pane\">\n {/* In-session search bar.\n Layout: [search controls (flex-1)] ... [Manage AI providers].\n The search input expands inside the LEFT cluster only, so the\n Manage button stays anchored on the right and never shifts. */}\n <div className=\"flex items-center gap-1 px-3 py-1 border-b border-border-default bg-bg-surface flex-shrink-0\">\n <div className=\"flex items-center gap-1.5 min-w-0 flex-1\">\n <button\n type=\"button\"\n onClick={toggleSearch}\n className={`p-1 rounded transition-colors shrink-0 ${\n searchOpen\n ? 'bg-action-primary-bg/10 text-action-primary-text'\n : 'text-text-tertiary hover:text-text-secondary hover:bg-bg-elevated'\n }`}\n title={tr(\n 'vibecontrols.agentManager.chatPane.searchInSession',\n 'Search in session (Ctrl+F)'\n )}\n aria-label={tr(\n 'vibecontrols.agentManager.chatPane.searchInSession',\n 'Search in session'\n )}\n >\n <Search className=\"size-3.5\" />\n </button>\n {searchOpen && (\n <div className=\"flex items-center gap-1.5 flex-1 min-w-0\">\n <input aria-label=\"control\"\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder={tr(\n 'vibecontrols.agentManager.chatPane.searchPlaceholder',\n 'Search in conversation...'\n )}\n\n className=\"flex-1 min-w-0 bg-transparent text-xs text-text-primary placeholder:text-text-tertiary focus:outline-none\"\n />\n {searchQuery && (\n <button\n type=\"button\"\n onClick={() => setSearchQuery('')}\n className=\"p-0.5 rounded hover:bg-bg-elevated transition-colors\"\n >\n <X className=\"size-3 text-text-tertiary\" />\n </button>\n )}\n </div>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => setBookmarksDrawerOpen(true)}\n className=\"shrink-0 p-1 rounded transition-colors text-text-tertiary hover:text-text-secondary hover:bg-bg-elevated\"\n title={tr(\n 'vibecontrols.agentManager.chatPane.bookmarksTooltip',\n 'View bookmarked messages'\n )}\n aria-label={tr('vibecontrols.agentManager.chatPane.bookmarksLabel', 'Bookmarks')}\n data-testid=\"agent-manager-bookmarks-trigger\"\n >\n <Bookmark className=\"size-3.5\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setInstallModalOpen(true)}\n className=\"shrink-0 inline-flex items-center gap-1.5 rounded-md border border-border-default bg-bg-elevated px-2 py-1 text-xs font-medium text-text-primary transition-colors hover:bg-bg-sunken hover:border-action-primary-bg/40\"\n title={tr(\n 'vibecontrols.agentManager.chatPane.manageProvidersTooltip',\n 'Install or remove AI providers (Claude, Codex, Gemini, OpenCode)'\n )}\n aria-label={tr(\n 'vibecontrols.agentManager.chatPane.manageProviders',\n 'Manage AI providers'\n )}\n data-testid=\"agent-manager-manage-providers\"\n >\n <PackagePlus className=\"size-3.5\" />\n <span className=\"hidden sm:inline\">\n {tr('vibecontrols.agentManager.chatPane.manageProviders', 'Manage AI providers')}\n </span>\n </button>\n </div>\n\n {/* Message list */}\n {loadingLogs ? (\n <div className=\"flex-1 flex items-center justify-center\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\n 'vibecontrols.agentManager.chatPane.loadingConversation',\n 'Loading conversation...'\n )}\n </p>\n </div>\n ) : (\n <AgentManagerMessageList\n messages={messages}\n isStreaming={isStreaming}\n onCancelStream={cancelStream}\n searchQuery={searchQuery}\n bookmarkedIds={bookmarkedIds}\n onToggleBookmark={handleToggleBookmark}\n flashMessageId={flashMessageId}\n />\n )}\n\n {/* Rich input area with controls */}\n <AgentManagerInputArea\n agentId={agentId}\n sessionId={sessionId}\n onSend={(text) => void sendMessage(text)}\n onCancel={cancelStream}\n agentTunnelUrl={activeAgent?.tunnelUrl ?? undefined}\n agentApiKey={activeAgent?.agentApiKey ?? undefined}\n />\n\n {/* Per-session bookmarks drawer */}\n <AgentManagerBookmarksDrawer\n open={bookmarksDrawerOpen}\n onClose={() => setBookmarksDrawerOpen(false)}\n sessionId={sessionId}\n messages={messages}\n onJump={jumpToMessage}\n />\n\n {/* Header-triggered provider install/remove. Sits below the chat\n tree so it can render full-screen without disturbing layout. */}\n <PluginInstallModal\n open={installModalOpen}\n agentId={agentId}\n onClose={() => setInstallModalOpen(false)}\n />\n\n {/* SDK auth prompt: opens when the streaming hook detects a missing\n ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN, so the user can save the\n credential inline instead of being told to go look elsewhere.\n The session's currently-selected SDK is forwarded so the picker\n can preselect the right provider. */}\n <SdkAuthPromptModal\n agentId={agentId}\n agentRef={agentRef}\n initialProviderId={sessionState?.sdk ?? undefined}\n />\n </div>\n );\n};\n\ninterface SdkAuthPromptModalProps {\n agentId: string;\n agentRef: { id: string; profile: string };\n initialProviderId?: string;\n}\n\nconst SdkAuthPromptModal: FC<SdkAuthPromptModalProps> = ({\n agentId,\n agentRef,\n initialProviderId,\n}) => {\n const sdkAuthPrompt = useAgentManagerStore((s) => s.sdkAuthPrompt);\n const setSdkAuthPrompt = useAgentManagerStore((s) => s.setSdkAuthPrompt);\n // Track whether the inner card has at least one primary credential\n // saved on the agent. The Continue button is gated on this so the user\n // can't dismiss the modal without actually persisting a key — but the\n // moment they save *any* of the either-or options it lights up.\n const [authSatisfied, setAuthSatisfied] = useState(false);\n const tr = useTr();\n\n // Reset the satisfied flag whenever the modal re-opens for a fresh\n // prompt (different agent / different session). Without this, dismissing\n // and re-opening would leave the flag stuck at its previous value.\n useEffect(() => {\n if (sdkAuthPrompt && sdkAuthPrompt.agentId === agentId) {\n setAuthSatisfied(false);\n }\n }, [sdkAuthPrompt, agentId]);\n\n if (!sdkAuthPrompt || sdkAuthPrompt.agentId !== agentId) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <div\n className=\"absolute inset-0 bg-bg-overlay\"\n onClick={() => setSdkAuthPrompt(null)}\n aria-hidden\n />\n {/* Constrain height to the viewport and let the inner body scroll so the\n modal never escapes the screen no matter how many providers/fields\n render inside AIProviderCredentialsCard. The header + footer stay\n sticky so the close + Continue buttons are always reachable. */}\n <div className=\"relative w-full max-w-xl max-h-[85vh] flex flex-col rounded-lg border border-border-default bg-bg-surface shadow-xl overflow-hidden\">\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default bg-bg-surface flex-shrink-0\">\n <h3 className=\"text-base font-semibold text-text-primary truncate pr-2\">\n {tr('vibecontrols.ai.sdkAuth.title', 'Configure AI provider credentials')}\n </h3>\n <button\n type=\"button\"\n onClick={() => setSdkAuthPrompt(null)}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors flex-shrink-0\"\n aria-label={tr('vibecontrols.common.close', 'Close')}\n >\n <X className=\"size-5 text-text-secondary\" />\n </button>\n </div>\n <div className=\"flex-1 min-h-0 overflow-y-auto px-4 py-3 space-y-3\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\n 'vibecontrols.ai.sdkAuth.body',\n \"The agent doesn't have a credential configured for this provider. Save any one of the listed keys (you don't need all of them) and click Continue to retry.\"\n )}\n </p>\n <AIProviderCredentialsCard\n agent={agentRef}\n initialProviderId={initialProviderId}\n onProviderAuthSatisfiedChange={setAuthSatisfied}\n />\n </div>\n <div className=\"flex items-center justify-end gap-2 px-4 py-3 border-t border-border-default bg-bg-surface flex-shrink-0\">\n <button\n type=\"button\"\n onClick={() => setSdkAuthPrompt(null)}\n className=\"px-3 py-1.5 rounded-md text-sm text-text-secondary hover:text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n {tr('vibecontrols.common.close', 'Close')}\n </button>\n <button\n type=\"button\"\n onClick={() => setSdkAuthPrompt(null)}\n disabled={!authSatisfied}\n title={\n authSatisfied\n ? undefined\n : tr(\n 'vibecontrols.ai.sdkAuth.saveOneFirst',\n 'Save at least one of the listed credentials to continue'\n )\n }\n className=\"px-3 py-1.5 rounded-md text-sm font-medium bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {tr('vibecontrols.ai.sdkAuth.continue', 'Continue')}\n </button>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -45,7 +45,7 @@ function d({ sessionId: d, agent: f }) {
45
45
  onClick: () => h(!1),
46
46
  className: "p-1 rounded hover:bg-bg-elevated transition-colors text-text-tertiary hover:text-text-secondary",
47
47
  title: g("vibecontrols.agentManager.detailPanel.closePanel", "Close detail panel"),
48
- children: /* @__PURE__ */ c(s, { className: "w-4 h-4" })
48
+ children: /* @__PURE__ */ c(s, { className: "size-4" })
49
49
  })]
50
50
  }), /* @__PURE__ */ l("div", {
51
51
  className: "flex-1 overflow-y-auto",
@@ -1 +1 @@
1
- {"version":3,"file":"AgentManagerDetailPanel.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerDetailPanel.tsx"],"sourcesContent":["/**\n * Collapsible detail panel for the Agent Manager.\n *\n * Renders in the right pane of the three-column layout. Provides tabbed\n * sub-panels: Logs, Stats, Config, Tools.\n */\n\nimport { useState } from 'react';\nimport { X } from 'lucide-react';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { SessionLogsPanel } from './detail/SessionLogsPanel';\nimport { SessionStatsPanel } from './detail/SessionStatsPanel';\nimport { SessionConfigPanel } from './detail/SessionConfigPanel';\nimport { SessionToolsPanel } from './detail/SessionToolsPanel';\nimport { useTr } from '../../shared/hooks/useTr';\nimport type { AgentRef } from '@/services/aiApi';\n\ninterface AgentManagerDetailPanelProps {\n sessionId: string;\n agent: AgentRef;\n}\n\ntype PanelTab = 'logs' | 'stats' | 'config' | 'tools';\n\nconst TABS: Array<{ key: PanelTab; label: string }> = [\n { key: 'logs', label: 'Logs' },\n { key: 'stats', label: 'Stats' },\n { key: 'config', label: 'Config' },\n { key: 'tools', label: 'Tools' },\n];\n\nexport function AgentManagerDetailPanel({ sessionId, agent }: AgentManagerDetailPanelProps) {\n const [activeTab, setActiveTab] = useState<PanelTab>('logs');\n const setDetailPanelOpen = useAgentManagerStore((s) => s.setDetailPanelOpen);\n const tr = useTr();\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Tab bar */}\n <div className=\"flex items-center border-b border-border-default px-2\">\n <div className=\"flex items-center gap-0.5 flex-1 overflow-x-auto\">\n {TABS.map((tab) => (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => setActiveTab(tab.key)}\n className={`px-3 py-2 text-xs font-medium whitespace-nowrap border-b-2 transition-colors ${\n activeTab === tab.key\n ? 'border-action-primary-bg text-action-primary-text'\n : 'border-transparent text-text-tertiary hover:text-text-secondary'\n }`}\n >\n {tab.label}\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n onClick={() => setDetailPanelOpen(false)}\n className=\"p-1 rounded hover:bg-bg-elevated transition-colors text-text-tertiary hover:text-text-secondary\"\n title={tr('vibecontrols.agentManager.detailPanel.closePanel', 'Close detail panel')}\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n {/* Panel content */}\n <div className=\"flex-1 overflow-y-auto\">\n {activeTab === 'logs' && <SessionLogsPanel sessionId={sessionId} agent={agent} />}\n {activeTab === 'stats' && <SessionStatsPanel sessionId={sessionId} agent={agent} />}\n {activeTab === 'config' && <SessionConfigPanel sessionId={sessionId} agent={agent} />}\n {activeTab === 'tools' && <SessionToolsPanel agent={agent} />}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAwBA,IAAM,IAAgD;CACpD;EAAE,KAAK;EAAQ,OAAO;EAAQ;CAC9B;EAAE,KAAK;EAAS,OAAO;EAAS;CAChC;EAAE,KAAK;EAAU,OAAO;EAAU;CAClC;EAAE,KAAK;EAAS,OAAO;EAAS;CACjC;AAED,SAAgB,EAAwB,EAAE,cAAW,YAAuC;CAC1F,IAAM,CAAC,GAAW,KAAgB,EAAmB,OAAO,EACtD,IAAqB,GAAsB,MAAM,EAAE,mBAAmB,EACtE,IAAK,GAAO;AAElB,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CAEE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAK,KAAK,MACT,kBAAC,UAAD;KAEE,MAAK;KACL,eAAe,EAAa,EAAI,IAAI;KACpC,WAAW,gFACT,MAAc,EAAI,MACd,sDACA;eAGL,EAAI;KACE,EAVF,EAAI,IAUF,CACT;IACE,CAAA,EACN,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAmB,GAAM;IACxC,WAAU;IACV,OAAO,EAAG,oDAAoD,qBAAqB;cAEnF,kBAAC,GAAD,EAAG,WAAU,WAAY,CAAA;IAClB,CAAA,CACL;MAGN,kBAAC,OAAD;GAAK,WAAU;aAAf;IACG,MAAc,UAAU,kBAAC,GAAD;KAA6B;KAAkB;KAAS,CAAA;IAChF,MAAc,WAAW,kBAAC,GAAD;KAA8B;KAAkB;KAAS,CAAA;IAClF,MAAc,YAAY,kBAAC,GAAD;KAA+B;KAAkB;KAAS,CAAA;IACpF,MAAc,WAAW,kBAAC,GAAD,EAA0B,UAAS,CAAA;IACzD;KACF"}
1
+ {"version":3,"file":"AgentManagerDetailPanel.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerDetailPanel.tsx"],"sourcesContent":["/**\n * Collapsible detail panel for the Agent Manager.\n *\n * Renders in the right pane of the three-column layout. Provides tabbed\n * sub-panels: Logs, Stats, Config, Tools.\n */\n\nimport { useState } from 'react';\nimport { X } from 'lucide-react';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { SessionLogsPanel } from './detail/SessionLogsPanel';\nimport { SessionStatsPanel } from './detail/SessionStatsPanel';\nimport { SessionConfigPanel } from './detail/SessionConfigPanel';\nimport { SessionToolsPanel } from './detail/SessionToolsPanel';\nimport { useTr } from '../../shared/hooks/useTr';\nimport type { AgentRef } from '@/services/aiApi';\n\ninterface AgentManagerDetailPanelProps {\n sessionId: string;\n agent: AgentRef;\n}\n\ntype PanelTab = 'logs' | 'stats' | 'config' | 'tools';\n\nconst TABS: Array<{ key: PanelTab; label: string }> = [\n { key: 'logs', label: 'Logs' },\n { key: 'stats', label: 'Stats' },\n { key: 'config', label: 'Config' },\n { key: 'tools', label: 'Tools' },\n];\n\nexport function AgentManagerDetailPanel({ sessionId, agent }: AgentManagerDetailPanelProps) {\n const [activeTab, setActiveTab] = useState<PanelTab>('logs');\n const setDetailPanelOpen = useAgentManagerStore((s) => s.setDetailPanelOpen);\n const tr = useTr();\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Tab bar */}\n <div className=\"flex items-center border-b border-border-default px-2\">\n <div className=\"flex items-center gap-0.5 flex-1 overflow-x-auto\">\n {TABS.map((tab) => (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => setActiveTab(tab.key)}\n className={`px-3 py-2 text-xs font-medium whitespace-nowrap border-b-2 transition-colors ${\n activeTab === tab.key\n ? 'border-action-primary-bg text-action-primary-text'\n : 'border-transparent text-text-tertiary hover:text-text-secondary'\n }`}\n >\n {tab.label}\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n onClick={() => setDetailPanelOpen(false)}\n className=\"p-1 rounded hover:bg-bg-elevated transition-colors text-text-tertiary hover:text-text-secondary\"\n title={tr('vibecontrols.agentManager.detailPanel.closePanel', 'Close detail panel')}\n >\n <X className=\"size-4\" />\n </button>\n </div>\n\n {/* Panel content */}\n <div className=\"flex-1 overflow-y-auto\">\n {activeTab === 'logs' && <SessionLogsPanel sessionId={sessionId} agent={agent} />}\n {activeTab === 'stats' && <SessionStatsPanel sessionId={sessionId} agent={agent} />}\n {activeTab === 'config' && <SessionConfigPanel sessionId={sessionId} agent={agent} />}\n {activeTab === 'tools' && <SessionToolsPanel agent={agent} />}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAwBA,IAAM,IAAgD;CACpD;EAAE,KAAK;EAAQ,OAAO;EAAQ;CAC9B;EAAE,KAAK;EAAS,OAAO;EAAS;CAChC;EAAE,KAAK;EAAU,OAAO;EAAU;CAClC;EAAE,KAAK;EAAS,OAAO;EAAS;CACjC;AAED,SAAgB,EAAwB,EAAE,cAAW,YAAuC;CAC1F,IAAM,CAAC,GAAW,KAAgB,EAAmB,OAAO,EACtD,IAAqB,GAAsB,MAAM,EAAE,mBAAmB,EACtE,IAAK,GAAO;AAElB,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CAEE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAK,KAAK,MACT,kBAAC,UAAD;KAEE,MAAK;KACL,eAAe,EAAa,EAAI,IAAI;KACpC,WAAW,gFACT,MAAc,EAAI,MACd,sDACA;eAGL,EAAI;KACE,EAVF,EAAI,IAUF,CACT;IACE,CAAA,EACN,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAmB,GAAM;IACxC,WAAU;IACV,OAAO,EAAG,oDAAoD,qBAAqB;cAEnF,kBAAC,GAAD,EAAG,WAAU,UAAW,CAAA;IACjB,CAAA,CACL;MAGN,kBAAC,OAAD;GAAK,WAAU;aAAf;IACG,MAAc,UAAU,kBAAC,GAAD;KAA6B;KAAkB;KAAS,CAAA;IAChF,MAAc,WAAW,kBAAC,GAAD;KAA8B;KAAkB;KAAS,CAAA;IAClF,MAAc,YAAY,kBAAC,GAAD;KAA+B;KAAkB;KAAS,CAAA;IACpF,MAAc,WAAW,kBAAC,GAAD,EAA0B,UAAS,CAAA;IACzD;KACF"}