@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":"VibeAgentEmptyState.js","names":[],"sources":["../../../src/components/vibe/VibeAgentEmptyState.tsx"],"sourcesContent":["/**\n * VibeAgentEmptyState — shown on the Vibe details page when the vibe has no\n * agent attached. Tabs that depend on an agent (sessions, gitops, GraphQL\n * playground, git) are hidden, and the user is invited to attach an agent.\n *\n * UX: opens an in-place modal listing the workspace's existing agents so the\n * user can attach one without leaving the vibe detail page. Falls back to\n * navigating to the agents page only if no agents exist in the workspace\n * (so the user can register their first one).\n */\nimport { useCallback, useMemo, useState } from 'react';\nimport type { FC } from 'react';\nimport { ArrowRight, Plus, Server } from 'lucide-react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { EmptyState } from '@/components/shared';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport {\n useListAgentsQuery,\n useAttachAgentToVibeMutation,\n GetVibeDocument,\n ListVibesDocument,\n type ListAgentsQuery,\n} from '@/generated/wspace-operations';\n\nexport interface VibeAgentEmptyStateProps {\n vibeId: string;\n tr: (key: string, fallback: string) => string;\n /** Optional: called after a successful attach so the parent can refetch. */\n onAttached?: () => void;\n}\n\nexport const VibeAgentEmptyState: FC<VibeAgentEmptyStateProps> = ({ vibeId, tr, onAttached }) => {\n const navigate = useVibeNavigate();\n const apolloClient = useApolloClient();\n const [open, setOpen] = useState(false);\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const [busyAgentId, setBusyAgentId] = useState<string | null>(null);\n\n const { data, loading } = useListAgentsQuery({\n skip: !open,\n fetchPolicy: 'cache-and-network',\n });\n const [attach] = useAttachAgentToVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n\n const agents = useMemo<ListAgentsQuery['vibecontrolsAgents']>(\n () => data?.vibecontrolsAgents ?? [],\n [data]\n );\n\n const handleAttach = useCallback(\n async (agentId: string) => {\n setErrorMessage(null);\n setBusyAgentId(agentId);\n try {\n await attach({ variables: { input: { vibeId, agentId } } });\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n setOpen(false);\n onAttached?.();\n } catch (err) {\n setErrorMessage(err instanceof Error ? err.message : String(err));\n } finally {\n setBusyAgentId(null);\n }\n },\n [attach, vibeId, onAttached, apolloClient]\n );\n\n const handleRegisterNew = useCallback(() => {\n // Deep-link to the agents page with vibeId so the agents UI can offer\n // a \"register and attach to this vibe\" affordance.\n const query = vibeId ? `?attachToVibe=${encodeURIComponent(vibeId)}` : '';\n navigate(`/agents${query}`);\n }, [navigate, vibeId]);\n\n return (\n <>\n <div className=\"rounded-lg border border-border-default bg-bg-surface\">\n <EmptyState\n icon={<Server className=\"w-8 h-8 text-text-secondary\" />}\n title={tr('vibeDetails.noAgentTitle', 'No agent attached')}\n description={tr(\n 'vibeDetails.noAgentDescription',\n 'This vibe is not attached to an agent yet. Sessions, GitOps, GraphQL playground, and git tooling all run through an agent — connect one to unlock those tabs.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('vibeDetails.connectAnAgent', 'Connect an agent to this vibe')}\n <ArrowRight className=\"w-4 h-4\" />\n </button>\n }\n />\n </div>\n\n {open && (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"vibe-attach-agent-title\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\n onClick={(e) => {\n if (e.target === e.currentTarget) setOpen(false);\n }}\n >\n <div className=\"w-full max-w-md rounded-lg bg-bg-elevated border border-border-default shadow-xl\">\n <div className=\"flex items-center justify-between px-5 py-4 border-b border-border-subtle\">\n <h2\n id=\"vibe-attach-agent-title\"\n className=\"text-base font-semibold text-text-primary\"\n >\n {tr('vibeDetails.attachAgentTitle', 'Attach an agent')}\n </h2>\n <button\n type=\"button\"\n onClick={() => setOpen(false)}\n className=\"text-text-secondary hover:text-text-primary transition-colors\"\n aria-label={tr('common.close', 'Close')}\n >\n ✕\n </button>\n </div>\n\n <div className=\"px-5 py-4 max-h-[60vh] overflow-y-auto\">\n {loading && agents.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">{tr('common.loading', 'Loading…')}</p>\n ) : agents.length === 0 ? (\n <div className=\"text-sm text-text-secondary space-y-3\">\n <p>\n {tr(\n 'vibeDetails.noWorkspaceAgents',\n 'No agents in this workspace yet. Register one first, then attach it to this vibe.'\n )}\n </p>\n <button\n type=\"button\"\n onClick={handleRegisterNew}\n className=\"inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('vibeDetails.registerAgent', 'Register an agent')}\n </button>\n </div>\n ) : (\n <ul className=\"space-y-2\">\n {agents.map((a) => (\n <li key={a.id}>\n <button\n type=\"button\"\n onClick={() => handleAttach(a.id)}\n disabled={busyAgentId !== null}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-subtle hover:border-border-default hover:bg-action-ghost-bg-hover transition-colors text-left disabled:opacity-60\"\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"w-4 h-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {a.name}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname || '—'}{' '}\n {a.isActive\n ? `· ${tr('agents.active', 'Active')}`\n : `· ${tr('agents.inactive', 'Inactive')}`}\n </span>\n </span>\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {busyAgentId === a.id\n ? tr('common.attaching', 'Attaching…')\n : tr('vibeDetails.attach', 'Attach')}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n\n {errorMessage && (\n <p className=\"mt-3 text-sm text-status-error-text\">{errorMessage}</p>\n )}\n </div>\n\n {agents.length > 0 && (\n <div className=\"flex items-center justify-between px-5 py-3 border-t border-border-subtle\">\n <button\n type=\"button\"\n onClick={handleRegisterNew}\n className=\"text-xs text-text-secondary hover:text-text-primary inline-flex items-center gap-1\"\n >\n <Plus className=\"w-3.5 h-3.5\" />\n {tr('vibeDetails.registerAgent', 'Register a new agent')}\n </button>\n <button\n type=\"button\"\n onClick={() => setOpen(false)}\n className=\"text-sm px-3 py-1.5 rounded-md border border-border-default text-text-primary hover:bg-action-ghost-bg-hover\"\n >\n {tr('common.cancel', 'Cancel')}\n </button>\n </div>\n )}\n </div>\n </div>\n )}\n </>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"VibeAgentEmptyState.js","names":[],"sources":["../../../src/components/vibe/VibeAgentEmptyState.tsx"],"sourcesContent":["/**\n * VibeAgentEmptyState — shown on the Vibe details page when the vibe has no\n * agent attached. Tabs that depend on an agent (sessions, gitops, GraphQL\n * playground, git) are hidden, and the user is invited to attach an agent.\n *\n * UX: opens an in-place modal listing the workspace's existing agents so the\n * user can attach one without leaving the vibe detail page. Falls back to\n * navigating to the agents page only if no agents exist in the workspace\n * (so the user can register their first one).\n */\nimport { useCallback, useMemo, useState } from 'react';\nimport type { FC } from 'react';\nimport { ArrowRight, Plus, Server } from 'lucide-react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { EmptyState } from '@/components/shared';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport {\n useListAgentsQuery,\n useAttachAgentToVibeMutation,\n GetVibeDocument,\n ListVibesDocument,\n type ListAgentsQuery,\n} from '@/generated/wspace-operations';\n\nexport interface VibeAgentEmptyStateProps {\n vibeId: string;\n tr: (key: string, fallback: string) => string;\n /** Optional: called after a successful attach so the parent can refetch. */\n onAttached?: () => void;\n}\n\nexport const VibeAgentEmptyState: FC<VibeAgentEmptyStateProps> = ({ vibeId, tr, onAttached }) => {\n const navigate = useVibeNavigate();\n const apolloClient = useApolloClient();\n const [open, setOpen] = useState(false);\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const [busyAgentId, setBusyAgentId] = useState<string | null>(null);\n\n const { data, loading } = useListAgentsQuery({\n skip: !open,\n fetchPolicy: 'cache-and-network',\n });\n const [attach] = useAttachAgentToVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n\n const agents = useMemo<ListAgentsQuery['vibecontrolsAgents']>(\n () => data?.vibecontrolsAgents ?? [],\n [data]\n );\n\n const handleAttach = useCallback(\n async (agentId: string) => {\n setErrorMessage(null);\n setBusyAgentId(agentId);\n try {\n await attach({ variables: { input: { vibeId, agentId } } });\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n setOpen(false);\n onAttached?.();\n } catch (err) {\n setErrorMessage(err instanceof Error ? err.message : String(err));\n } finally {\n setBusyAgentId(null);\n }\n },\n [attach, vibeId, onAttached, apolloClient]\n );\n\n const handleRegisterNew = useCallback(() => {\n // Deep-link to the agents page with vibeId so the agents UI can offer\n // a \"register and attach to this vibe\" affordance.\n const query = vibeId ? `?attachToVibe=${encodeURIComponent(vibeId)}` : '';\n navigate(`/agents${query}`);\n }, [navigate, vibeId]);\n\n return (\n <>\n <div className=\"rounded-lg border border-border-default bg-bg-surface\">\n <EmptyState\n icon={<Server className=\"size-8 text-text-secondary\" />}\n title={tr('vibeDetails.noAgentTitle', 'No agent attached')}\n description={tr(\n 'vibeDetails.noAgentDescription',\n 'This vibe is not attached to an agent yet. Sessions, GitOps, GraphQL playground, and git tooling all run through an agent — connect one to unlock those tabs.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('vibeDetails.connectAnAgent', 'Connect an agent to this vibe')}\n <ArrowRight className=\"size-4\" />\n </button>\n }\n />\n </div>\n\n {open && (\n <div tabIndex={0} onKeyDown={(e) => { if (e.key === 'Escape') { e.preventDefault(); setOpen(false); } }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"vibe-attach-agent-title\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\n onClick={(e) => {\n if (e.target === e.currentTarget) setOpen(false);\n }}\n >\n <div className=\"w-full max-w-md rounded-lg bg-bg-elevated border border-border-default shadow-xl\">\n <div className=\"flex items-center justify-between px-5 py-4 border-b border-border-subtle\">\n <h2\n id=\"vibe-attach-agent-title\"\n className=\"text-base font-semibold text-text-primary\"\n >\n {tr('vibeDetails.attachAgentTitle', 'Attach an agent')}\n </h2>\n <button\n type=\"button\"\n onClick={() => setOpen(false)}\n className=\"text-text-secondary hover:text-text-primary transition-colors\"\n aria-label={tr('common.close', 'Close')}\n >\n ✕\n </button>\n </div>\n\n <div className=\"px-5 py-4 max-h-[60vh] overflow-y-auto\">\n {loading && agents.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">{tr('common.loading', 'Loading…')}</p>\n ) : agents.length === 0 ? (\n <div className=\"text-sm text-text-secondary space-y-3\">\n <p>\n {tr(\n 'vibeDetails.noWorkspaceAgents',\n 'No agents in this workspace yet. Register one first, then attach it to this vibe.'\n )}\n </p>\n <button\n type=\"button\"\n onClick={handleRegisterNew}\n className=\"inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n {tr('vibeDetails.registerAgent', 'Register an agent')}\n </button>\n </div>\n ) : (\n <ul className=\"space-y-2\">\n {agents.map((a) => (\n <li key={a.id}>\n <button\n type=\"button\"\n onClick={() => handleAttach(a.id)}\n disabled={busyAgentId !== null}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-subtle hover:border-border-default hover:bg-action-ghost-bg-hover transition-colors text-left disabled:opacity-60\"\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"size-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {a.name}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname || '—'}{' '}\n {a.isActive\n ? `· ${tr('agents.active', 'Active')}`\n : `· ${tr('agents.inactive', 'Inactive')}`}\n </span>\n </span>\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {busyAgentId === a.id\n ? tr('common.attaching', 'Attaching…')\n : tr('vibeDetails.attach', 'Attach')}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n\n {errorMessage && (\n <p className=\"mt-3 text-sm text-status-error-text\">{errorMessage}</p>\n )}\n </div>\n\n {agents.length > 0 && (\n <div className=\"flex items-center justify-between px-5 py-3 border-t border-border-subtle\">\n <button\n type=\"button\"\n onClick={handleRegisterNew}\n className=\"text-xs text-text-secondary hover:text-text-primary inline-flex items-center gap-1\"\n >\n <Plus className=\"size-3.5\" />\n {tr('vibeDetails.registerAgent', 'Register a new agent')}\n </button>\n <button\n type=\"button\"\n onClick={() => setOpen(false)}\n className=\"text-sm px-3 py-1.5 rounded-md border border-border-default text-text-primary hover:bg-action-ghost-bg-hover\"\n >\n {tr('common.cancel', 'Cancel')}\n </button>\n </div>\n )}\n </div>\n </div>\n )}\n </>\n );\n};\n"],"mappings":"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"}
@@ -70,13 +70,13 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
70
70
  className: "p-4 border-b border-border-default flex items-center justify-between",
71
71
  children: [/* @__PURE__ */ y("h3", {
72
72
  className: "font-semibold text-text-primary flex items-center gap-2",
73
- children: [/* @__PURE__ */ v(h, { className: "w-5 h-5" }), C("vibeAgentSwitcher.title", "Active agent for this vibe")]
73
+ children: [/* @__PURE__ */ v(h, { className: "size-5" }), C("vibeAgentSwitcher.title", "Active agent for this vibe")]
74
74
  }), /* @__PURE__ */ y("button", {
75
75
  type: "button",
76
76
  onClick: () => j(!0),
77
77
  className: "inline-flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-md border border-border-default text-text-primary hover:bg-bg-sunken",
78
78
  disabled: I,
79
- children: [/* @__PURE__ */ v(p, { className: "w-3.5 h-3.5" }), C("vibeAgentSwitcher.attachAnother", "Attach another")]
79
+ children: [/* @__PURE__ */ v(p, { className: "size-3.5" }), C("vibeAgentSwitcher.attachAnother", "Attach another")]
80
80
  })]
81
81
  }),
82
82
  /* @__PURE__ */ y("div", {
@@ -89,7 +89,7 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
89
89
  "aria-expanded": E,
90
90
  children: [/* @__PURE__ */ y("span", {
91
91
  className: "flex items-center gap-3 min-w-0",
92
- children: [/* @__PURE__ */ v(h, { className: "w-4 h-4 text-text-secondary flex-shrink-0" }), /* @__PURE__ */ y("span", {
92
+ children: [/* @__PURE__ */ v(h, { className: "size-4 text-text-secondary flex-shrink-0" }), /* @__PURE__ */ y("span", {
93
93
  className: "min-w-0 text-left",
94
94
  children: [/* @__PURE__ */ v("span", {
95
95
  className: "block text-sm font-medium text-text-primary truncate",
@@ -99,18 +99,18 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
99
99
  children: [R?.hostname ?? "—", R && (R.isActive ? " · active" : " · offline")]
100
100
  })]
101
101
  })]
102
- }), /* @__PURE__ */ v(f, { className: `w-4 h-4 text-text-secondary transition-transform ${E ? "rotate-180" : ""}` })]
102
+ }), /* @__PURE__ */ v(f, { className: `size-4 text-text-secondary transition-transform ${E ? "rotate-180" : ""}` })]
103
103
  }), E && /* @__PURE__ */ y("div", {
104
104
  className: "absolute left-4 right-4 z-30 mt-1 rounded-md border border-border-default bg-bg-elevated shadow-lg",
105
105
  children: [/* @__PURE__ */ y("div", {
106
106
  className: "flex items-center gap-2 px-3 py-2 border-b border-border-subtle",
107
- children: [/* @__PURE__ */ v(m, { className: "w-4 h-4 text-text-secondary" }), /* @__PURE__ */ v("input", {
107
+ children: [/* @__PURE__ */ v(m, { className: "size-4 text-text-secondary" }), /* @__PURE__ */ v("input", {
108
+ "aria-label": "control",
108
109
  type: "text",
109
110
  value: O,
110
111
  onChange: (e) => k(e.target.value),
111
112
  placeholder: C("vibeAgentSwitcher.searchPlaceholder", "Search agents…"),
112
- className: "w-full bg-transparent text-sm text-text-primary outline-none",
113
- autoFocus: !0
113
+ className: "w-full bg-transparent text-sm text-text-primary outline-none"
114
114
  })]
115
115
  }), /* @__PURE__ */ v("ul", {
116
116
  role: "listbox",
@@ -130,7 +130,7 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
130
130
  className: `flex-1 flex items-center justify-between gap-3 px-3 py-2 text-left text-sm hover:bg-bg-sunken ${t ? "bg-bg-sunken" : ""}`,
131
131
  children: [/* @__PURE__ */ y("span", {
132
132
  className: "flex items-center gap-2 min-w-0",
133
- children: [/* @__PURE__ */ v(h, { className: "w-4 h-4 text-text-secondary flex-shrink-0" }), /* @__PURE__ */ y("span", {
133
+ children: [/* @__PURE__ */ v(h, { className: "size-4 text-text-secondary flex-shrink-0" }), /* @__PURE__ */ y("span", {
134
134
  className: "min-w-0",
135
135
  children: [/* @__PURE__ */ v("span", {
136
136
  className: "block text-text-primary truncate",
@@ -144,14 +144,14 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
144
144
  ]
145
145
  })]
146
146
  })]
147
- }), t && /* @__PURE__ */ v(d, { className: "w-4 h-4 text-action-primary-bg" })]
147
+ }), t && /* @__PURE__ */ v(d, { className: "size-4 text-action-primary-bg" })]
148
148
  }), /* @__PURE__ */ v("button", {
149
149
  type: "button",
150
150
  onClick: () => J(e.id),
151
151
  disabled: I,
152
152
  title: C("vibeAgentSwitcher.detach", "Detach from vibe"),
153
153
  className: "px-2 text-text-secondary hover:text-status-error-text",
154
- children: /* @__PURE__ */ v(g, { className: "w-4 h-4" })
154
+ children: /* @__PURE__ */ v(g, { className: "size-4" })
155
155
  })]
156
156
  }, e.id);
157
157
  })
@@ -159,6 +159,10 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
159
159
  })]
160
160
  }),
161
161
  A && /* @__PURE__ */ v("div", {
162
+ tabIndex: 0,
163
+ onKeyDown: (e) => {
164
+ e.key === "Escape" && (e.preventDefault(), j(!1));
165
+ },
162
166
  role: "dialog",
163
167
  "aria-modal": "true",
164
168
  className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4",
@@ -178,25 +182,25 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
178
182
  onClick: () => j(!1),
179
183
  className: "text-text-secondary hover:text-text-primary",
180
184
  "aria-label": C("common.close", "Close"),
181
- children: /* @__PURE__ */ v(g, { className: "w-4 h-4" })
185
+ children: /* @__PURE__ */ v(g, { className: "size-4" })
182
186
  })]
183
187
  }),
184
188
  /* @__PURE__ */ v("div", {
185
189
  className: "px-5 py-3 border-b border-border-subtle",
186
190
  children: /* @__PURE__ */ y("div", {
187
191
  className: "flex items-center gap-2",
188
- children: [/* @__PURE__ */ v(m, { className: "w-4 h-4 text-text-secondary" }), /* @__PURE__ */ v("input", {
192
+ children: [/* @__PURE__ */ v(m, { className: "size-4 text-text-secondary" }), /* @__PURE__ */ v("input", {
193
+ "aria-label": "control",
189
194
  type: "text",
190
195
  value: M,
191
196
  onChange: (e) => N(e.target.value),
192
197
  placeholder: C("vibeAgentSwitcher.searchPlaceholder", "Search agents…"),
193
- className: "w-full bg-transparent text-sm text-text-primary outline-none",
194
- autoFocus: !0
198
+ className: "w-full bg-transparent text-sm text-text-primary outline-none"
195
199
  })]
196
200
  })
197
201
  }),
198
202
  /* @__PURE__ */ y("div", {
199
- className: "px-2 py-2 max-h-[60vh] overflow-y-auto",
203
+ className: "p-2 max-h-[60vh] overflow-y-auto",
200
204
  children: [U.length === 0 ? /* @__PURE__ */ v("p", {
201
205
  className: "text-sm text-text-secondary px-3 py-2",
202
206
  children: C("vibeAgentSwitcher.noCandidates", "No unattached agents available. Register a new agent first.")
@@ -209,7 +213,7 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
209
213
  className: "w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-subtle hover:border-border-default hover:bg-action-ghost-bg-hover text-left disabled:opacity-60",
210
214
  children: [/* @__PURE__ */ y("span", {
211
215
  className: "flex items-center gap-3 min-w-0",
212
- children: [/* @__PURE__ */ v(h, { className: "w-4 h-4 text-text-secondary flex-shrink-0" }), /* @__PURE__ */ y("span", {
216
+ children: [/* @__PURE__ */ v(h, { className: "size-4 text-text-secondary flex-shrink-0" }), /* @__PURE__ */ y("span", {
213
217
  className: "min-w-0",
214
218
  children: [/* @__PURE__ */ v("span", {
215
219
  className: "block text-sm font-medium text-text-primary truncate",
@@ -1 +1 @@
1
- {"version":3,"file":"VibeAgentSwitcher.js","names":[],"sources":["../../../src/components/vibe/VibeAgentSwitcher.tsx"],"sourcesContent":["/**\n * VibeAgentSwitcher — inline switcher + attach-more affordance shown on the\n * Vibe detail Overview tab once at least one agent is attached.\n *\n * Why this exists: a vibe can carry many agents (every collaborator brings\n * their own host/dev VM alongside shared env agents). Without a top-level\n * switcher, the \"effective agent\" chosen by the auto-pick heuristic is\n * invisible and unswitchable from the detail page, and there's no way to\n * attach a *second* agent without leaving for the agents tab. This card:\n *\n * 1. Names the active agent for the current user on this vibe.\n * 2. Lists every attached agent in a searchable dropdown — choosing one\n * writes to the per-vibe default store slot, persisted across reloads.\n * 3. Surfaces \"Attach another agent\" so users discover the multi-attach\n * flow without bouncing tabs.\n * 4. Surfaces \"Detach\" per agent (owner-scoped, no peer detaches).\n */\nimport { useMemo, useState, useCallback } from 'react';\nimport { Check, ChevronDown, Plus, Search, Server, X } from 'lucide-react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { Card } from '@/components/shared';\nimport {\n useAttachAgentToVibeMutation,\n useDetachAgentFromVibeMutation,\n useListAgentsQuery,\n GetVibeDocument,\n ListVibesDocument,\n type ListAgentsQuery,\n} from '@/generated/wspace-operations';\n\ntype ListAgent = NonNullable<ListAgentsQuery['vibecontrolsAgents']>[number];\nimport { useVibeControlsStore } from '@/store/vibeControlsStore';\nimport { useTr } from '@/shared/hooks/useTr';\n\nexport interface AttachedAgent {\n id: string;\n name: string;\n hostname?: string | null;\n isActive: boolean;\n ownerUserId?: string | null;\n tunnelUrl?: string | null;\n}\n\ninterface Props {\n vibeId: string;\n attachedAgents: ReadonlyArray<AttachedAgent>;\n effectiveAgentId: string | null;\n}\n\nexport function VibeAgentSwitcher({ vibeId, attachedAgents, effectiveAgentId }: Props) {\n const tr = useTr();\n const apolloClient = useApolloClient();\n const setDefault = useVibeControlsStore((s) => s.setDefaultAgentForVibe);\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [attachOpen, setAttachOpen] = useState(false);\n const [attachQuery, setAttachQuery] = useState('');\n const [attachError, setAttachError] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n\n const active = attachedAgents.find((a) => a.id === effectiveAgentId) ?? attachedAgents[0] ?? null;\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return attachedAgents;\n return attachedAgents.filter(\n (a) =>\n a.name.toLowerCase().includes(q) ||\n (a.hostname ?? '').toLowerCase().includes(q) ||\n a.id.toLowerCase().includes(q)\n );\n }, [attachedAgents, query]);\n\n const { data: agentsData, refetch: refetchAgents } = useListAgentsQuery({\n skip: !attachOpen,\n fetchPolicy: 'cache-and-network',\n });\n const attachedIds = useMemo(() => new Set(attachedAgents.map((a) => a.id)), [attachedAgents]);\n const candidates = useMemo(() => {\n const all = agentsData?.vibecontrolsAgents ?? [];\n const q = attachQuery.trim().toLowerCase();\n return all\n .filter((a: ListAgent) => !attachedIds.has(a.id))\n .filter((a: ListAgent) =>\n q ? a.name.toLowerCase().includes(q) || (a.hostname ?? '').toLowerCase().includes(q) : true\n );\n }, [agentsData, attachedIds, attachQuery]);\n\n const [attach] = useAttachAgentToVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n const [detach] = useDetachAgentFromVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n\n const handlePick = useCallback(\n (agentId: string) => {\n setDefault(vibeId, agentId);\n setOpen(false);\n },\n [setDefault, vibeId]\n );\n\n const handleAttach = useCallback(\n async (agentId: string) => {\n setBusy(true);\n setAttachError(null);\n try {\n await attach({ variables: { input: { vibeId, agentId } } });\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n await refetchAgents();\n setAttachOpen(false);\n } catch (err) {\n setAttachError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n },\n [attach, refetchAgents, vibeId, apolloClient]\n );\n\n const handleDetach = useCallback(\n async (agentId: string) => {\n if (!confirm(tr('vibeAgentSwitcher.detachConfirm', 'Detach this agent from the vibe?'))) {\n return;\n }\n setBusy(true);\n try {\n await detach({ variables: { input: { vibeId, agentId } } });\n // Evict the vibe from cache so the parent GetVibe query re-renders immediately\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n setOpen(false);\n } finally {\n setBusy(false);\n }\n },\n [detach, tr, vibeId, apolloClient]\n );\n\n return (\n <Card>\n <div className=\"p-4 border-b border-border-default flex items-center justify-between\">\n <h3 className=\"font-semibold text-text-primary flex items-center gap-2\">\n <Server className=\"w-5 h-5\" />\n {tr('vibeAgentSwitcher.title', 'Active agent for this vibe')}\n </h3>\n <button\n type=\"button\"\n onClick={() => setAttachOpen(true)}\n className=\"inline-flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-md border border-border-default text-text-primary hover:bg-bg-sunken\"\n disabled={busy}\n >\n <Plus className=\"w-3.5 h-3.5\" />\n {tr('vibeAgentSwitcher.attachAnother', 'Attach another')}\n </button>\n </div>\n\n <div className=\"p-4 space-y-2 relative\">\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-default bg-bg-sunken hover:border-action-primary-bg\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"w-4 h-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0 text-left\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {active?.name ?? tr('vibeAgentSwitcher.none', 'No active agent')}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {active?.hostname ?? '—'}\n {active && (active.isActive ? ' · active' : ' · offline')}\n </span>\n </span>\n </span>\n <ChevronDown\n className={`w-4 h-4 text-text-secondary transition-transform ${open ? 'rotate-180' : ''}`}\n />\n </button>\n\n {open && (\n <div className=\"absolute left-4 right-4 z-30 mt-1 rounded-md border border-border-default bg-bg-elevated shadow-lg\">\n <div className=\"flex items-center gap-2 px-3 py-2 border-b border-border-subtle\">\n <Search className=\"w-4 h-4 text-text-secondary\" />\n <input\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={tr('vibeAgentSwitcher.searchPlaceholder', 'Search agents…')}\n className=\"w-full bg-transparent text-sm text-text-primary outline-none\"\n autoFocus\n />\n </div>\n <ul role=\"listbox\" className=\"max-h-64 overflow-y-auto py-1\">\n {filtered.length === 0 ? (\n <li className=\"px-3 py-2 text-xs text-text-secondary\">\n {tr('vibeAgentSwitcher.noMatch', 'No agents match your search.')}\n </li>\n ) : (\n filtered.map((a) => {\n const isActive = a.id === effectiveAgentId;\n return (\n <li key={a.id} className=\"flex items-center\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n onClick={() => handlePick(a.id)}\n className={`flex-1 flex items-center justify-between gap-3 px-3 py-2 text-left text-sm hover:bg-bg-sunken ${isActive ? 'bg-bg-sunken' : ''}`}\n >\n <span className=\"flex items-center gap-2 min-w-0\">\n <Server className=\"w-4 h-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-text-primary truncate\">{a.name}</span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname ?? '—'} {a.isActive ? '· active' : '· offline'}\n </span>\n </span>\n </span>\n {isActive && <Check className=\"w-4 h-4 text-action-primary-bg\" />}\n </button>\n <button\n type=\"button\"\n onClick={() => handleDetach(a.id)}\n disabled={busy}\n title={tr('vibeAgentSwitcher.detach', 'Detach from vibe')}\n className=\"px-2 text-text-secondary hover:text-status-error-text\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </li>\n );\n })\n )}\n </ul>\n </div>\n )}\n </div>\n\n {attachOpen && (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\n onClick={(e) => {\n if (e.target === e.currentTarget) setAttachOpen(false);\n }}\n >\n <div className=\"w-full max-w-md rounded-lg bg-bg-elevated border border-border-default shadow-xl\">\n <div className=\"flex items-center justify-between px-5 py-4 border-b border-border-subtle\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('vibeAgentSwitcher.attachTitle', 'Attach an additional agent')}\n </h2>\n <button\n type=\"button\"\n onClick={() => setAttachOpen(false)}\n className=\"text-text-secondary hover:text-text-primary\"\n aria-label={tr('common.close', 'Close')}\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n <div className=\"px-5 py-3 border-b border-border-subtle\">\n <div className=\"flex items-center gap-2\">\n <Search className=\"w-4 h-4 text-text-secondary\" />\n <input\n type=\"text\"\n value={attachQuery}\n onChange={(e) => setAttachQuery(e.target.value)}\n placeholder={tr('vibeAgentSwitcher.searchPlaceholder', 'Search agents…')}\n className=\"w-full bg-transparent text-sm text-text-primary outline-none\"\n autoFocus\n />\n </div>\n </div>\n <div className=\"px-2 py-2 max-h-[60vh] overflow-y-auto\">\n {candidates.length === 0 ? (\n <p className=\"text-sm text-text-secondary px-3 py-2\">\n {tr(\n 'vibeAgentSwitcher.noCandidates',\n 'No unattached agents available. Register a new agent first.'\n )}\n </p>\n ) : (\n <ul className=\"space-y-1\">\n {candidates.map((a: ListAgent) => (\n <li key={a.id}>\n <button\n type=\"button\"\n onClick={() => handleAttach(a.id)}\n disabled={busy}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-subtle hover:border-border-default hover:bg-action-ghost-bg-hover text-left disabled:opacity-60\"\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"w-4 h-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {a.name}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname || '—'}\n {a.isActive ? ' · active' : ' · inactive'}\n </span>\n </span>\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {tr('vibeAgentSwitcher.attach', 'Attach')}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n {attachError && (\n <p className=\"mt-2 px-3 text-sm text-status-error-text\">{attachError}</p>\n )}\n </div>\n </div>\n </div>\n )}\n </Card>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"VibeAgentSwitcher.js","names":[],"sources":["../../../src/components/vibe/VibeAgentSwitcher.tsx"],"sourcesContent":["/**\n * VibeAgentSwitcher — inline switcher + attach-more affordance shown on the\n * Vibe detail Overview tab once at least one agent is attached.\n *\n * Why this exists: a vibe can carry many agents (every collaborator brings\n * their own host/dev VM alongside shared env agents). Without a top-level\n * switcher, the \"effective agent\" chosen by the auto-pick heuristic is\n * invisible and unswitchable from the detail page, and there's no way to\n * attach a *second* agent without leaving for the agents tab. This card:\n *\n * 1. Names the active agent for the current user on this vibe.\n * 2. Lists every attached agent in a searchable dropdown — choosing one\n * writes to the per-vibe default store slot, persisted across reloads.\n * 3. Surfaces \"Attach another agent\" so users discover the multi-attach\n * flow without bouncing tabs.\n * 4. Surfaces \"Detach\" per agent (owner-scoped, no peer detaches).\n */\nimport { useMemo, useState, useCallback } from 'react';\nimport { Check, ChevronDown, Plus, Search, Server, X } from 'lucide-react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { Card } from '@/components/shared';\nimport {\n useAttachAgentToVibeMutation,\n useDetachAgentFromVibeMutation,\n useListAgentsQuery,\n GetVibeDocument,\n ListVibesDocument,\n type ListAgentsQuery,\n} from '@/generated/wspace-operations';\n\ntype ListAgent = NonNullable<ListAgentsQuery['vibecontrolsAgents']>[number];\nimport { useVibeControlsStore } from '@/store/vibeControlsStore';\nimport { useTr } from '@/shared/hooks/useTr';\n\nexport interface AttachedAgent {\n id: string;\n name: string;\n hostname?: string | null;\n isActive: boolean;\n ownerUserId?: string | null;\n tunnelUrl?: string | null;\n}\n\ninterface Props {\n vibeId: string;\n attachedAgents: ReadonlyArray<AttachedAgent>;\n effectiveAgentId: string | null;\n}\n\nexport function VibeAgentSwitcher({ vibeId, attachedAgents, effectiveAgentId }: Props) {\n const tr = useTr();\n const apolloClient = useApolloClient();\n const setDefault = useVibeControlsStore((s) => s.setDefaultAgentForVibe);\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [attachOpen, setAttachOpen] = useState(false);\n const [attachQuery, setAttachQuery] = useState('');\n const [attachError, setAttachError] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n\n const active = attachedAgents.find((a) => a.id === effectiveAgentId) ?? attachedAgents[0] ?? null;\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return attachedAgents;\n return attachedAgents.filter(\n (a) =>\n a.name.toLowerCase().includes(q) ||\n (a.hostname ?? '').toLowerCase().includes(q) ||\n a.id.toLowerCase().includes(q)\n );\n }, [attachedAgents, query]);\n\n const { data: agentsData, refetch: refetchAgents } = useListAgentsQuery({\n skip: !attachOpen,\n fetchPolicy: 'cache-and-network',\n });\n const attachedIds = useMemo(() => new Set(attachedAgents.map((a) => a.id)), [attachedAgents]);\n const candidates = useMemo(() => {\n const all = agentsData?.vibecontrolsAgents ?? [];\n const q = attachQuery.trim().toLowerCase();\n return all\n .filter((a: ListAgent) => !attachedIds.has(a.id))\n .filter((a: ListAgent) =>\n q ? a.name.toLowerCase().includes(q) || (a.hostname ?? '').toLowerCase().includes(q) : true\n );\n }, [agentsData, attachedIds, attachQuery]);\n\n const [attach] = useAttachAgentToVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n const [detach] = useDetachAgentFromVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n\n const handlePick = useCallback(\n (agentId: string) => {\n setDefault(vibeId, agentId);\n setOpen(false);\n },\n [setDefault, vibeId]\n );\n\n const handleAttach = useCallback(\n async (agentId: string) => {\n setBusy(true);\n setAttachError(null);\n try {\n await attach({ variables: { input: { vibeId, agentId } } });\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n await refetchAgents();\n setAttachOpen(false);\n } catch (err) {\n setAttachError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n },\n [attach, refetchAgents, vibeId, apolloClient]\n );\n\n const handleDetach = useCallback(\n async (agentId: string) => {\n if (!confirm(tr('vibeAgentSwitcher.detachConfirm', 'Detach this agent from the vibe?'))) {\n return;\n }\n setBusy(true);\n try {\n await detach({ variables: { input: { vibeId, agentId } } });\n // Evict the vibe from cache so the parent GetVibe query re-renders immediately\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n setOpen(false);\n } finally {\n setBusy(false);\n }\n },\n [detach, tr, vibeId, apolloClient]\n );\n\n return (\n <Card>\n <div className=\"p-4 border-b border-border-default flex items-center justify-between\">\n <h3 className=\"font-semibold text-text-primary flex items-center gap-2\">\n <Server className=\"size-5\" />\n {tr('vibeAgentSwitcher.title', 'Active agent for this vibe')}\n </h3>\n <button\n type=\"button\"\n onClick={() => setAttachOpen(true)}\n className=\"inline-flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-md border border-border-default text-text-primary hover:bg-bg-sunken\"\n disabled={busy}\n >\n <Plus className=\"size-3.5\" />\n {tr('vibeAgentSwitcher.attachAnother', 'Attach another')}\n </button>\n </div>\n\n <div className=\"p-4 space-y-2 relative\">\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-default bg-bg-sunken hover:border-action-primary-bg\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"size-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0 text-left\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {active?.name ?? tr('vibeAgentSwitcher.none', 'No active agent')}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {active?.hostname ?? '—'}\n {active && (active.isActive ? ' · active' : ' · offline')}\n </span>\n </span>\n </span>\n <ChevronDown\n className={`size-4 text-text-secondary transition-transform ${open ? 'rotate-180' : ''}`}\n />\n </button>\n\n {open && (\n <div className=\"absolute left-4 right-4 z-30 mt-1 rounded-md border border-border-default bg-bg-elevated shadow-lg\">\n <div className=\"flex items-center gap-2 px-3 py-2 border-b border-border-subtle\">\n <Search className=\"size-4 text-text-secondary\" />\n <input aria-label=\"control\"\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={tr('vibeAgentSwitcher.searchPlaceholder', 'Search agents…')}\n className=\"w-full bg-transparent text-sm text-text-primary outline-none\"\n\n />\n </div>\n <ul role=\"listbox\" className=\"max-h-64 overflow-y-auto py-1\">\n {filtered.length === 0 ? (\n <li className=\"px-3 py-2 text-xs text-text-secondary\">\n {tr('vibeAgentSwitcher.noMatch', 'No agents match your search.')}\n </li>\n ) : (\n filtered.map((a) => {\n const isActive = a.id === effectiveAgentId;\n return (\n <li key={a.id} className=\"flex items-center\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n onClick={() => handlePick(a.id)}\n className={`flex-1 flex items-center justify-between gap-3 px-3 py-2 text-left text-sm hover:bg-bg-sunken ${isActive ? 'bg-bg-sunken' : ''}`}\n >\n <span className=\"flex items-center gap-2 min-w-0\">\n <Server className=\"size-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-text-primary truncate\">{a.name}</span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname ?? '—'} {a.isActive ? '· active' : '· offline'}\n </span>\n </span>\n </span>\n {isActive && <Check className=\"size-4 text-action-primary-bg\" />}\n </button>\n <button\n type=\"button\"\n onClick={() => handleDetach(a.id)}\n disabled={busy}\n title={tr('vibeAgentSwitcher.detach', 'Detach from vibe')}\n className=\"px-2 text-text-secondary hover:text-status-error-text\"\n >\n <X className=\"size-4\" />\n </button>\n </li>\n );\n })\n )}\n </ul>\n </div>\n )}\n </div>\n\n {attachOpen && (\n <div tabIndex={0} onKeyDown={(e) => { if (e.key === 'Escape') { e.preventDefault(); setAttachOpen(false); } }}\n role=\"dialog\"\n aria-modal=\"true\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\n onClick={(e) => {\n if (e.target === e.currentTarget) setAttachOpen(false);\n }}\n >\n <div className=\"w-full max-w-md rounded-lg bg-bg-elevated border border-border-default shadow-xl\">\n <div className=\"flex items-center justify-between px-5 py-4 border-b border-border-subtle\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('vibeAgentSwitcher.attachTitle', 'Attach an additional agent')}\n </h2>\n <button\n type=\"button\"\n onClick={() => setAttachOpen(false)}\n className=\"text-text-secondary hover:text-text-primary\"\n aria-label={tr('common.close', 'Close')}\n >\n <X className=\"size-4\" />\n </button>\n </div>\n <div className=\"px-5 py-3 border-b border-border-subtle\">\n <div className=\"flex items-center gap-2\">\n <Search className=\"size-4 text-text-secondary\" />\n <input aria-label=\"control\"\n type=\"text\"\n value={attachQuery}\n onChange={(e) => setAttachQuery(e.target.value)}\n placeholder={tr('vibeAgentSwitcher.searchPlaceholder', 'Search agents…')}\n className=\"w-full bg-transparent text-sm text-text-primary outline-none\"\n\n />\n </div>\n </div>\n <div className=\"p-2 max-h-[60vh] overflow-y-auto\">\n {candidates.length === 0 ? (\n <p className=\"text-sm text-text-secondary px-3 py-2\">\n {tr(\n 'vibeAgentSwitcher.noCandidates',\n 'No unattached agents available. Register a new agent first.'\n )}\n </p>\n ) : (\n <ul className=\"space-y-1\">\n {candidates.map((a: ListAgent) => (\n <li key={a.id}>\n <button\n type=\"button\"\n onClick={() => handleAttach(a.id)}\n disabled={busy}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-subtle hover:border-border-default hover:bg-action-ghost-bg-hover text-left disabled:opacity-60\"\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"size-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {a.name}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname || '—'}\n {a.isActive ? ' · active' : ' · inactive'}\n </span>\n </span>\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {tr('vibeAgentSwitcher.attach', 'Attach')}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n {attachError && (\n <p className=\"mt-2 px-3 text-sm text-status-error-text\">{attachError}</p>\n )}\n </div>\n </div>\n </div>\n )}\n </Card>\n );\n}\n"],"mappings":"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"}
@@ -58,7 +58,7 @@ function p({ vibeId: a }) {
58
58
  children: [
59
59
  /* @__PURE__ */ l("header", {
60
60
  className: "flex items-start gap-3",
61
- children: [/* @__PURE__ */ c(r, { className: "w-5 h-5 text-status-warning-text mt-0.5" }), /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h3", {
61
+ children: [/* @__PURE__ */ c(r, { className: "size-5 text-status-warning-text mt-0.5" }), /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h3", {
62
62
  className: "text-base font-semibold text-text-primary",
63
63
  children: "Admin · all URLs for this vibe"
64
64
  }), /* @__PURE__ */ c("p", {
@@ -72,7 +72,7 @@ function p({ vibeId: a }) {
72
72
  }),
73
73
  y.length === 0 && !m && /* @__PURE__ */ l("div", {
74
74
  className: "text-sm text-text-secondary py-3 flex items-center gap-2",
75
- children: [/* @__PURE__ */ c(n, { className: "w-4 h-4" }), "No URLs minted for this vibe by any user."]
75
+ children: [/* @__PURE__ */ c(n, { className: "size-4" }), "No URLs minted for this vibe by any user."]
76
76
  }),
77
77
  y.length > 0 && /* @__PURE__ */ c("div", {
78
78
  className: "overflow-x-auto",
@@ -151,7 +151,7 @@ function p({ vibeId: a }) {
151
151
  className: "py-2 pr-3 text-xs text-text-secondary",
152
152
  children: /* @__PURE__ */ l("span", {
153
153
  className: "inline-flex items-center gap-1",
154
- children: [/* @__PURE__ */ c(t, { className: "w-3 h-3" }), f(e.expiresAt)]
154
+ children: [/* @__PURE__ */ c(t, { className: "size-3" }), f(e.expiresAt)]
155
155
  })
156
156
  }),
157
157
  /* @__PURE__ */ c("td", {
@@ -163,6 +163,7 @@ function p({ vibeId: a }) {
163
163
  children: e.status === "ACTIVE" ? /* @__PURE__ */ l("div", {
164
164
  className: "flex items-center gap-1",
165
165
  children: [/* @__PURE__ */ c("input", {
166
+ "aria-label": "reason",
166
167
  type: "text",
167
168
  value: _[e.id] ?? "",
168
169
  onChange: (t) => v((n) => ({
@@ -177,7 +178,7 @@ function p({ vibeId: a }) {
177
178
  title: "Admin revoke",
178
179
  "aria-label": "Admin revoke URL",
179
180
  className: "p-1.5 text-status-error-text hover:opacity-80",
180
- children: /* @__PURE__ */ c(i, { className: "w-4 h-4" })
181
+ children: /* @__PURE__ */ c(i, { className: "size-4" })
181
182
  })]
182
183
  }) : /* @__PURE__ */ c("span", {
183
184
  className: "text-xs text-text-secondary",
@@ -1 +1 @@
1
- {"version":3,"file":"VibeLlmContextAdminPanel.js","names":[],"sources":["../../../src/components/vibe/VibeLlmContextAdminPanel.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport { Clock, Info, Shield, Trash2 } from 'lucide-react';\n\ninterface AdminTokenRow {\n id: string;\n vibeId: string;\n userId: string;\n label: string | null;\n tokenFingerprint: string;\n includeCredentials: boolean;\n includes: string[];\n status: 'ACTIVE' | 'REVOKED';\n expiresAt: string;\n lastFetchedAt: string | null;\n fetchCount: number;\n createdAt: string;\n revokedAt: string | null;\n revokedReason: string | null;\n}\n\nconst ALL_TOKENS = gql`\n query AllVibeLlmContextTokens($vibeId: ID, $userId: ID) {\n allVibeLlmContextTokens(vibeId: $vibeId, userId: $userId) {\n id\n vibeId\n userId\n label\n tokenFingerprint\n includeCredentials\n includes\n status\n expiresAt\n lastFetchedAt\n fetchCount\n createdAt\n revokedAt\n revokedReason\n }\n }\n`;\n\nconst ADMIN_REVOKE = gql`\n mutation AdminRevokeVibeLlmContextToken($tokenId: ID!, $reason: String) {\n adminRevokeVibeLlmContextToken(tokenId: $tokenId, reason: $reason) {\n id\n status\n revokedAt\n revokedReason\n }\n }\n`;\n\nfunction formatExpiry(expiresAt: string): string {\n const diff = new Date(expiresAt).getTime() - Date.now();\n if (diff < 0) return 'expired';\n const hours = Math.floor(diff / (1000 * 60 * 60));\n const mins = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));\n if (hours > 24) return `${Math.floor(hours / 24)}d`;\n if (hours > 0) return `${hours}h ${mins}m`;\n return `${mins}m`;\n}\n\ninterface VibeLlmContextAdminPanelProps {\n vibeId: string;\n}\n\nexport function VibeLlmContextAdminPanel({ vibeId }: VibeLlmContextAdminPanelProps): ReactElement {\n const { data, loading, refetch } = useQuery<{ allVibeLlmContextTokens: AdminTokenRow[] }>(\n ALL_TOKENS,\n {\n variables: { vibeId },\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'ignore',\n }\n );\n const [adminRevoke] = useMutation<\n { adminRevokeVibeLlmContextToken: AdminTokenRow },\n { tokenId: string; reason?: string | null }\n >(ADMIN_REVOKE, { refetchQueries: ['AllVibeLlmContextTokens'] });\n\n const [reasonDraft, setReasonDraft] = useState<Record<string, string>>({});\n const tokens = data?.allVibeLlmContextTokens ?? [];\n\n const onRevoke = async (tokenId: string) => {\n await adminRevoke({\n variables: {\n tokenId,\n reason: (reasonDraft[tokenId] ?? '').trim() || null,\n },\n });\n setReasonDraft((prev) => {\n const next = { ...prev };\n delete next[tokenId];\n return next;\n });\n await refetch();\n };\n\n return (\n <section className=\"bg-bg-surface border border-status-warning-border rounded-lg p-5 space-y-3\">\n <header className=\"flex items-start gap-3\">\n <Shield className=\"w-5 h-5 text-status-warning-text mt-0.5\" />\n <div>\n <h3 className=\"text-base font-semibold text-text-primary\">\n Admin · all URLs for this vibe\n </h3>\n <p className=\"text-sm text-text-secondary\">\n Visible only to workspace admins. Lists every user's signed URLs for this vibe. Use\n revoke to immediately invalidate any URL — takes effect on the next fetch.\n </p>\n </div>\n </header>\n\n {loading && tokens.length === 0 && (\n <div className=\"text-sm text-text-secondary py-3\">Loading…</div>\n )}\n {tokens.length === 0 && !loading && (\n <div className=\"text-sm text-text-secondary py-3 flex items-center gap-2\">\n <Info className=\"w-4 h-4\" />\n No URLs minted for this vibe by any user.\n </div>\n )}\n {tokens.length > 0 && (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-default text-left text-xs text-text-secondary\">\n <th className=\"py-2 pr-3\">User</th>\n <th className=\"py-2 pr-3\">Label</th>\n <th className=\"py-2 pr-3\">Fingerprint</th>\n <th className=\"py-2 pr-3\">Creds</th>\n <th className=\"py-2 pr-3\">Status</th>\n <th className=\"py-2 pr-3\">Expires</th>\n <th className=\"py-2 pr-3\">Fetches</th>\n <th className=\"py-2 pr-3\">Revoke</th>\n </tr>\n </thead>\n <tbody>\n {tokens.map((t) => (\n <tr key={t.id} className=\"border-b border-border-subtle align-top\">\n <td\n className=\"py-2 pr-3 font-mono text-xs text-text-secondary truncate max-w-[120px]\"\n title={t.userId}\n >\n {t.userId}\n </td>\n <td className=\"py-2 pr-3 text-text-primary\">{t.label ?? '—'}</td>\n <td className=\"py-2 pr-3 font-mono text-xs text-text-secondary\">\n {t.tokenFingerprint}\n </td>\n <td className=\"py-2 pr-3\">\n {t.includeCredentials ? (\n <span className=\"text-xs text-status-warning-text\">on</span>\n ) : (\n <span className=\"text-xs text-text-secondary\">off</span>\n )}\n </td>\n <td className=\"py-2 pr-3\">\n <span\n className={`text-xs px-1.5 py-0.5 rounded ${\n t.status === 'ACTIVE'\n ? 'bg-status-success-bg/20 text-status-success-text'\n : 'bg-bg-sunken text-text-secondary'\n }`}\n >\n {t.status}\n </span>\n </td>\n <td className=\"py-2 pr-3 text-xs text-text-secondary\">\n <span className=\"inline-flex items-center gap-1\">\n <Clock className=\"w-3 h-3\" />\n {formatExpiry(t.expiresAt)}\n </span>\n </td>\n <td className=\"py-2 pr-3 text-xs text-text-secondary\">{t.fetchCount}</td>\n <td className=\"py-2 pr-3\">\n {t.status === 'ACTIVE' ? (\n <div className=\"flex items-center gap-1\">\n <input\n type=\"text\"\n value={reasonDraft[t.id] ?? ''}\n onChange={(e) =>\n setReasonDraft((prev) => ({ ...prev, [t.id]: e.target.value }))\n }\n placeholder=\"reason\"\n className=\"w-28 px-1.5 py-1 text-xs bg-bg-sunken border border-border-default rounded text-text-primary\"\n />\n <button\n type=\"button\"\n onClick={() => onRevoke(t.id)}\n title=\"Admin revoke\"\n aria-label=\"Admin revoke URL\"\n className=\"p-1.5 text-status-error-text hover:opacity-80\"\n >\n <Trash2 className=\"w-4 h-4\" />\n </button>\n </div>\n ) : (\n <span className=\"text-xs text-text-secondary\" title={t.revokedReason ?? ''}>\n {t.revokedReason ?? '—'}\n </span>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"VibeLlmContextAdminPanel.js","names":[],"sources":["../../../src/components/vibe/VibeLlmContextAdminPanel.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport { Clock, Info, Shield, Trash2 } from 'lucide-react';\n\ninterface AdminTokenRow {\n id: string;\n vibeId: string;\n userId: string;\n label: string | null;\n tokenFingerprint: string;\n includeCredentials: boolean;\n includes: string[];\n status: 'ACTIVE' | 'REVOKED';\n expiresAt: string;\n lastFetchedAt: string | null;\n fetchCount: number;\n createdAt: string;\n revokedAt: string | null;\n revokedReason: string | null;\n}\n\nconst ALL_TOKENS = gql`\n query AllVibeLlmContextTokens($vibeId: ID, $userId: ID) {\n allVibeLlmContextTokens(vibeId: $vibeId, userId: $userId) {\n id\n vibeId\n userId\n label\n tokenFingerprint\n includeCredentials\n includes\n status\n expiresAt\n lastFetchedAt\n fetchCount\n createdAt\n revokedAt\n revokedReason\n }\n }\n`;\n\nconst ADMIN_REVOKE = gql`\n mutation AdminRevokeVibeLlmContextToken($tokenId: ID!, $reason: String) {\n adminRevokeVibeLlmContextToken(tokenId: $tokenId, reason: $reason) {\n id\n status\n revokedAt\n revokedReason\n }\n }\n`;\n\nfunction formatExpiry(expiresAt: string): string {\n const diff = new Date(expiresAt).getTime() - Date.now();\n if (diff < 0) return 'expired';\n const hours = Math.floor(diff / (1000 * 60 * 60));\n const mins = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));\n if (hours > 24) return `${Math.floor(hours / 24)}d`;\n if (hours > 0) return `${hours}h ${mins}m`;\n return `${mins}m`;\n}\n\ninterface VibeLlmContextAdminPanelProps {\n vibeId: string;\n}\n\nexport function VibeLlmContextAdminPanel({ vibeId }: VibeLlmContextAdminPanelProps): ReactElement {\n const { data, loading, refetch } = useQuery<{ allVibeLlmContextTokens: AdminTokenRow[] }>(\n ALL_TOKENS,\n {\n variables: { vibeId },\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'ignore',\n }\n );\n const [adminRevoke] = useMutation<\n { adminRevokeVibeLlmContextToken: AdminTokenRow },\n { tokenId: string; reason?: string | null }\n >(ADMIN_REVOKE, { refetchQueries: ['AllVibeLlmContextTokens'] });\n\n const [reasonDraft, setReasonDraft] = useState<Record<string, string>>({});\n const tokens = data?.allVibeLlmContextTokens ?? [];\n\n const onRevoke = async (tokenId: string) => {\n await adminRevoke({\n variables: {\n tokenId,\n reason: (reasonDraft[tokenId] ?? '').trim() || null,\n },\n });\n setReasonDraft((prev) => {\n const next = { ...prev };\n delete next[tokenId];\n return next;\n });\n await refetch();\n };\n\n return (\n <section className=\"bg-bg-surface border border-status-warning-border rounded-lg p-5 space-y-3\">\n <header className=\"flex items-start gap-3\">\n <Shield className=\"size-5 text-status-warning-text mt-0.5\" />\n <div>\n <h3 className=\"text-base font-semibold text-text-primary\">\n Admin · all URLs for this vibe\n </h3>\n <p className=\"text-sm text-text-secondary\">\n Visible only to workspace admins. Lists every user's signed URLs for this vibe. Use\n revoke to immediately invalidate any URL — takes effect on the next fetch.\n </p>\n </div>\n </header>\n\n {loading && tokens.length === 0 && (\n <div className=\"text-sm text-text-secondary py-3\">Loading…</div>\n )}\n {tokens.length === 0 && !loading && (\n <div className=\"text-sm text-text-secondary py-3 flex items-center gap-2\">\n <Info className=\"size-4\" />\n No URLs minted for this vibe by any user.\n </div>\n )}\n {tokens.length > 0 && (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-default text-left text-xs text-text-secondary\">\n <th className=\"py-2 pr-3\">User</th>\n <th className=\"py-2 pr-3\">Label</th>\n <th className=\"py-2 pr-3\">Fingerprint</th>\n <th className=\"py-2 pr-3\">Creds</th>\n <th className=\"py-2 pr-3\">Status</th>\n <th className=\"py-2 pr-3\">Expires</th>\n <th className=\"py-2 pr-3\">Fetches</th>\n <th className=\"py-2 pr-3\">Revoke</th>\n </tr>\n </thead>\n <tbody>\n {tokens.map((t) => (\n <tr key={t.id} className=\"border-b border-border-subtle align-top\">\n <td\n className=\"py-2 pr-3 font-mono text-xs text-text-secondary truncate max-w-[120px]\"\n title={t.userId}\n >\n {t.userId}\n </td>\n <td className=\"py-2 pr-3 text-text-primary\">{t.label ?? '—'}</td>\n <td className=\"py-2 pr-3 font-mono text-xs text-text-secondary\">\n {t.tokenFingerprint}\n </td>\n <td className=\"py-2 pr-3\">\n {t.includeCredentials ? (\n <span className=\"text-xs text-status-warning-text\">on</span>\n ) : (\n <span className=\"text-xs text-text-secondary\">off</span>\n )}\n </td>\n <td className=\"py-2 pr-3\">\n <span\n className={`text-xs px-1.5 py-0.5 rounded ${\n t.status === 'ACTIVE'\n ? 'bg-status-success-bg/20 text-status-success-text'\n : 'bg-bg-sunken text-text-secondary'\n }`}\n >\n {t.status}\n </span>\n </td>\n <td className=\"py-2 pr-3 text-xs text-text-secondary\">\n <span className=\"inline-flex items-center gap-1\">\n <Clock className=\"size-3\" />\n {formatExpiry(t.expiresAt)}\n </span>\n </td>\n <td className=\"py-2 pr-3 text-xs text-text-secondary\">{t.fetchCount}</td>\n <td className=\"py-2 pr-3\">\n {t.status === 'ACTIVE' ? (\n <div className=\"flex items-center gap-1\">\n <input aria-label=\"reason\"\n type=\"text\"\n value={reasonDraft[t.id] ?? ''}\n onChange={(e) =>\n setReasonDraft((prev) => ({ ...prev, [t.id]: e.target.value }))\n }\n placeholder=\"reason\"\n className=\"w-28 px-1.5 py-1 text-xs bg-bg-sunken border border-border-default rounded text-text-primary\"\n />\n <button\n type=\"button\"\n onClick={() => onRevoke(t.id)}\n title=\"Admin revoke\"\n aria-label=\"Admin revoke URL\"\n className=\"p-1.5 text-status-error-text hover:opacity-80\"\n >\n <Trash2 className=\"size-4\" />\n </button>\n </div>\n ) : (\n <span className=\"text-xs text-text-secondary\" title={t.revokedReason ?? ''}>\n {t.revokedReason ?? '—'}\n </span>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n );\n}\n"],"mappings":"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"}
@@ -202,7 +202,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
202
202
  className: "rounded-lg border border-status-warning-border bg-status-warning-bg/30 p-4",
203
203
  children: /* @__PURE__ */ g("div", {
204
204
  className: "flex items-start gap-3",
205
- children: [/* @__PURE__ */ h(ie, { className: "w-5 h-5 text-status-warning-text mt-0.5" }), /* @__PURE__ */ g("div", {
205
+ children: [/* @__PURE__ */ h(ie, { className: "size-5 text-status-warning-text mt-0.5" }), /* @__PURE__ */ g("div", {
206
206
  className: "text-sm text-text-primary",
207
207
  children: [/* @__PURE__ */ h("p", {
208
208
  className: "font-medium mb-1",
@@ -241,10 +241,11 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
241
241
  },
242
242
  disabled: w.loading,
243
243
  className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover disabled:opacity-50",
244
- children: [K && !w.loading && /* @__PURE__ */ h(s, { className: "w-4 h-4" }), w.loading ? "Saving…" : K ? "Saved" : "Save settings"]
244
+ children: [K && !w.loading && /* @__PURE__ */ h(s, { className: "size-4" }), w.loading ? "Saving…" : K ? "Saved" : "Save settings"]
245
245
  })]
246
246
  }),
247
247
  /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
248
+ htmlFor: "vibellmcontexttabpanel-44",
248
249
  className: "block text-sm font-medium text-text-primary mb-2",
249
250
  children: "URL expiry"
250
251
  }), /* @__PURE__ */ g("div", {
@@ -261,6 +262,8 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
261
262
  children: "or custom hours:"
262
263
  }),
263
264
  /* @__PURE__ */ h("input", {
265
+ id: "vibellmcontexttabpanel-44",
266
+ "aria-label": "control",
264
267
  type: "number",
265
268
  min: 1,
266
269
  max: 168,
@@ -274,26 +277,28 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
274
277
  className: "flex items-center gap-2 text-sm text-text-primary",
275
278
  children: [
276
279
  /* @__PURE__ */ h("input", {
280
+ "aria-label": "control",
277
281
  type: "checkbox",
278
282
  checked: N,
279
283
  onChange: (e) => P(e.target.checked),
280
- className: "w-4 h-4"
284
+ className: "size-4"
281
285
  }),
282
286
  /* @__PURE__ */ h("span", { children: "Include credentials (tunnel URLs + agent API keys)" }),
283
287
  N ? /* @__PURE__ */ h(a, {
284
- className: "w-4 h-4 text-status-warning-text",
288
+ className: "size-4 text-status-warning-text",
285
289
  "aria-label": "Credentials will be exposed in the snapshot"
286
290
  }) : /* @__PURE__ */ h(re, {
287
- className: "w-4 h-4 text-text-secondary",
291
+ className: "size-4 text-text-secondary",
288
292
  "aria-label": "Credentials redacted"
289
293
  })
290
294
  ]
291
295
  }), N && /* @__PURE__ */ g("p", {
292
296
  className: "mt-1.5 text-xs text-status-warning-text flex items-start gap-1.5",
293
- children: [/* @__PURE__ */ h(a, { className: "w-3.5 h-3.5 mt-0.5 flex-shrink-0" }), /* @__PURE__ */ h("span", { children: "Anyone with a URL minted while this is on can read live agent tunnel URLs and API keys. Only enable for trusted recipients." })]
297
+ children: [/* @__PURE__ */ h(a, { className: "size-3.5 mt-0.5 flex-shrink-0" }), /* @__PURE__ */ h("span", { children: "Anyone with a URL minted while this is on can read live agent tunnel URLs and API keys. Only enable for trusted recipients." })]
294
298
  })] }),
295
299
  /* @__PURE__ */ g("div", { children: [
296
300
  /* @__PURE__ */ h("label", {
301
+ htmlFor: "vibellmcontexttabpanel-43",
297
302
  className: "block text-sm font-medium text-text-primary mb-2",
298
303
  children: "Sections to include"
299
304
  }),
@@ -317,9 +322,11 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
317
322
  })
318
323
  ] }),
319
324
  y.length > 0 && /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
325
+ htmlFor: "vibellmcontexttabpanel-43",
320
326
  className: "block text-sm font-medium text-text-primary mb-2",
321
327
  children: "Default agent for context fetch"
322
328
  }), /* @__PURE__ */ g("select", {
329
+ id: "vibellmcontexttabpanel-43",
323
330
  value: z,
324
331
  onChange: (e) => B(e.target.value),
325
332
  className: "w-full px-3 py-2 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary",
@@ -333,10 +340,13 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
333
340
  })] }),
334
341
  /* @__PURE__ */ g("div", { children: [
335
342
  /* @__PURE__ */ h("label", {
343
+ htmlFor: "vibellmcontexttabpanel-42",
336
344
  className: "block text-sm font-medium text-text-primary mb-2",
337
345
  children: "Custom context text"
338
346
  }),
339
347
  /* @__PURE__ */ h("textarea", {
348
+ id: "vibellmcontexttabpanel-42",
349
+ "aria-label": "Free-form notes embedded in every snapshot you mint AFTER saving (existing tokens keep their original copy).",
340
350
  value: L,
341
351
  onChange: (e) => R(e.target.value.slice(0, 8192)),
342
352
  rows: 5,
@@ -366,9 +376,12 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
366
376
  /* @__PURE__ */ g("div", {
367
377
  className: "flex-1 min-w-[200px]",
368
378
  children: [/* @__PURE__ */ h("label", {
379
+ htmlFor: "vibellmcontexttabpanel-41",
369
380
  className: "block text-sm font-medium text-text-primary mb-1",
370
381
  children: "Label (optional)"
371
382
  }), /* @__PURE__ */ h("input", {
383
+ id: "vibellmcontexttabpanel-41",
384
+ "aria-label": "e.g. Claude desktop",
372
385
  type: "text",
373
386
  value: V,
374
387
  onChange: (e) => H(e.target.value.slice(0, 120)),
@@ -381,7 +394,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
381
394
  onClick: Te,
382
395
  disabled: $.loading,
383
396
  className: "px-4 py-2 text-sm bg-bg-sunken text-text-primary border border-border-default rounded-md hover:bg-action-primary-bg-hover disabled:opacity-50 inline-flex items-center gap-1.5",
384
- children: [/* @__PURE__ */ h(ne, { className: "w-4 h-4" }), $.loading ? "Loading…" : "Preview"]
397
+ children: [/* @__PURE__ */ h(ne, { className: "size-4" }), $.loading ? "Loading…" : "Preview"]
385
398
  }),
386
399
  /* @__PURE__ */ h("button", {
387
400
  type: "button",
@@ -409,7 +422,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
409
422
  children: [/* @__PURE__ */ g("div", {
410
423
  className: "flex items-center gap-2 text-sm mb-2",
411
424
  children: [
412
- /* @__PURE__ */ h(s, { className: "w-4 h-4 text-status-success-text" }),
425
+ /* @__PURE__ */ h(s, { className: "size-4 text-status-success-text" }),
413
426
  /* @__PURE__ */ h("span", {
414
427
  className: "font-medium text-text-primary",
415
428
  children: "URL generated"
@@ -433,7 +446,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
433
446
  },
434
447
  className: "px-2 py-1.5 text-xs bg-bg-sunken border border-border-default rounded text-text-primary",
435
448
  "aria-label": "Copy URL",
436
- children: Se ? /* @__PURE__ */ h(s, { className: "w-4 h-4 text-status-success-text" }) : /* @__PURE__ */ h(te, { className: "w-4 h-4" })
449
+ children: Se ? /* @__PURE__ */ h(s, { className: "size-4 text-status-success-text" }) : /* @__PURE__ */ h(te, { className: "size-4" })
437
450
  })]
438
451
  })]
439
452
  })
@@ -457,16 +470,16 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
457
470
  },
458
471
  disabled: A.every((e) => e.status !== "ACTIVE"),
459
472
  className: "flex items-center gap-1 px-3 py-1.5 text-sm bg-status-error-bg/10 text-status-error-text border border-status-error-border rounded-md hover:bg-status-error-bg/20 disabled:opacity-40 disabled:cursor-not-allowed",
460
- children: [/* @__PURE__ */ h(u, { className: "w-4 h-4" }), "Revoke all"]
473
+ children: [/* @__PURE__ */ h(u, { className: "size-4" }), "Revoke all"]
461
474
  })]
462
475
  }),
463
476
  C.loading && A.length === 0 && /* @__PURE__ */ g("div", {
464
477
  className: "text-sm text-text-secondary py-4 flex items-center gap-2",
465
- children: [/* @__PURE__ */ h(ae, { className: "w-4 h-4 animate-spin" }), "Loading tokens…"]
478
+ children: [/* @__PURE__ */ h(ae, { className: "size-4 animate-spin" }), "Loading tokens…"]
466
479
  }),
467
480
  A.length === 0 && !C.loading && /* @__PURE__ */ g("div", {
468
481
  className: "text-sm text-text-secondary py-4 flex items-center gap-2",
469
- children: [/* @__PURE__ */ h(c, { className: "w-4 h-4" }), "No URLs minted yet for this vibe."]
482
+ children: [/* @__PURE__ */ h(c, { className: "size-4" }), "No URLs minted yet for this vibe."]
470
483
  }),
471
484
  A.length > 0 && /* @__PURE__ */ h("div", {
472
485
  className: "overflow-x-auto",
@@ -547,7 +560,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
547
560
  className: "py-2 pr-3 text-xs text-text-secondary",
548
561
  children: /* @__PURE__ */ g("span", {
549
562
  className: "inline-flex items-center gap-1",
550
- children: [/* @__PURE__ */ h(ee, { className: "w-3 h-3" }), x(e.expiresAt)]
563
+ children: [/* @__PURE__ */ h(ee, { className: "size-3" }), x(e.expiresAt)]
551
564
  })
552
565
  }),
553
566
  /* @__PURE__ */ h("td", {
@@ -564,7 +577,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
564
577
  title: "Show fetch history",
565
578
  "aria-label": "Show fetch history",
566
579
  className: "p-1.5 text-text-secondary hover:text-text-primary",
567
- children: /* @__PURE__ */ h(c, { className: "w-4 h-4" })
580
+ children: /* @__PURE__ */ h(c, { className: "size-4" })
568
581
  }), e.status === "ACTIVE" && /* @__PURE__ */ g(ce, { children: [/* @__PURE__ */ h("button", {
569
582
  type: "button",
570
583
  onClick: async () => {
@@ -574,14 +587,14 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
574
587
  title: "Rotate (revoke + mint a new one with same settings)",
575
588
  "aria-label": "Rotate URL",
576
589
  className: "p-1.5 text-text-secondary hover:text-text-primary",
577
- children: /* @__PURE__ */ h(l, { className: "w-4 h-4" })
590
+ children: /* @__PURE__ */ h(l, { className: "size-4" })
578
591
  }), /* @__PURE__ */ h("button", {
579
592
  type: "button",
580
593
  onClick: () => E({ variables: { tokenId: e.id } }),
581
594
  title: "Revoke",
582
595
  "aria-label": "Revoke URL",
583
596
  className: "p-1.5 text-status-error-text hover:opacity-80",
584
- children: /* @__PURE__ */ h(u, { className: "w-4 h-4" })
597
+ children: /* @__PURE__ */ h(u, { className: "size-4" })
585
598
  })] })]
586
599
  })
587
600
  })
@@ -599,7 +612,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
599
612
  /* @__PURE__ */ g("p", {
600
613
  className: "text-xs text-text-secondary flex items-center gap-1",
601
614
  children: [
602
- /* @__PURE__ */ h(o, { className: "w-3 h-3" }),
615
+ /* @__PURE__ */ h(o, { className: "size-3" }),
603
616
  "Tip: pipe the URL to any LLM with",
604
617
  " ",
605
618
  /* @__PURE__ */ h("code", {
@@ -617,6 +630,10 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
617
630
  ]
618
631
  }),
619
632
  Y && /* @__PURE__ */ h("div", {
633
+ tabIndex: 0,
634
+ onKeyDown: (e) => {
635
+ e.key === "Escape" && (e.preventDefault(), X(!1));
636
+ },
620
637
  className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay p-4",
621
638
  role: "dialog",
622
639
  "aria-modal": "true",
@@ -655,7 +672,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
655
672
  onClick: () => X(!1),
656
673
  "aria-label": "Close preview",
657
674
  className: "text-text-secondary hover:text-text-primary",
658
- children: /* @__PURE__ */ h(d, { className: "w-4 h-4" })
675
+ children: /* @__PURE__ */ h(d, { className: "size-4" })
659
676
  })
660
677
  ]
661
678
  }), /* @__PURE__ */ h("div", {