@burdenoff/microfe-vibecontrols 2026.623.1 → 2026.623.3

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 (295) hide show
  1. package/dist/components/actions/ActionCard.js +2 -2
  2. package/dist/components/actions/ActionCard.js.map +1 -1
  3. package/dist/components/actions/ActionTypeBadge.js +1 -1
  4. package/dist/components/actions/ActionTypeBadge.js.map +1 -1
  5. package/dist/components/actions/ExecutionHistory.js +1 -1
  6. package/dist/components/actions/ExecutionHistory.js.map +1 -1
  7. package/dist/components/agent-manager/AgentManagerAdminBar.js +1 -1
  8. package/dist/components/agent-manager/AgentManagerAdminBar.js.map +1 -1
  9. package/dist/components/agent-manager/AgentManagerChatPane.js +2 -2
  10. package/dist/components/agent-manager/AgentManagerChatPane.js.map +1 -1
  11. package/dist/components/agent-manager/AgentManagerInputArea.js +4 -4
  12. package/dist/components/agent-manager/AgentManagerInputArea.js.map +1 -1
  13. package/dist/components/agent-manager/AgentManagerLayout.js +1 -1
  14. package/dist/components/agent-manager/AgentManagerLayout.js.map +1 -1
  15. package/dist/components/agent-manager/AgentManagerMessageItem.js +1 -1
  16. package/dist/components/agent-manager/AgentManagerMessageItem.js.map +1 -1
  17. package/dist/components/agent-manager/AgentManagerSidebar.js +5 -5
  18. package/dist/components/agent-manager/AgentManagerSidebar.js.map +1 -1
  19. package/dist/components/agent-manager/AgentManagerTab.js +1 -1
  20. package/dist/components/agent-manager/AgentManagerTab.js.map +1 -1
  21. package/dist/components/agent-manager/AgentManagerTabBar.js +1 -1
  22. package/dist/components/agent-manager/AgentManagerTabBar.js.map +1 -1
  23. package/dist/components/agent-manager/BridleConfigPanel.js +24 -24
  24. package/dist/components/agent-manager/BridleConfigPanel.js.map +1 -1
  25. package/dist/components/agent-manager/PluginInstallModal.js +1 -1
  26. package/dist/components/agent-manager/PluginInstallModal.js.map +1 -1
  27. package/dist/components/agent-manager/ProfilesPanel.js +5 -5
  28. package/dist/components/agent-manager/ProfilesPanel.js.map +1 -1
  29. package/dist/components/agent-manager/controls/AutonomySelector.js +1 -1
  30. package/dist/components/agent-manager/controls/AutonomySelector.js.map +1 -1
  31. package/dist/components/agent-manager/controls/SdkSelector.js +1 -1
  32. package/dist/components/agent-manager/controls/SdkSelector.js.map +1 -1
  33. package/dist/components/agent-manager/controls/VoiceToggle.js +1 -1
  34. package/dist/components/agent-manager/controls/VoiceToggle.js.map +1 -1
  35. package/dist/components/agent-manager/detail/SessionConfigPanel.js +6 -6
  36. package/dist/components/agent-manager/detail/SessionConfigPanel.js.map +1 -1
  37. package/dist/components/agent-manager/detail/SessionLogsPanel.js +5 -5
  38. package/dist/components/agent-manager/detail/SessionLogsPanel.js.map +1 -1
  39. package/dist/components/agent-manager/detail/SessionToolsPanel.js +1 -1
  40. package/dist/components/agent-manager/detail/SessionToolsPanel.js.map +1 -1
  41. package/dist/components/agent-manager/dialogs/NewSessionDialog.js +2 -2
  42. package/dist/components/agent-manager/dialogs/NewSessionDialog.js.map +1 -1
  43. package/dist/components/agent-manager/dialogs/RenameSessionDialog.js +1 -1
  44. package/dist/components/agent-manager/dialogs/RenameSessionDialog.js.map +1 -1
  45. package/dist/components/agents/AgentCard.js +14 -11
  46. package/dist/components/agents/AgentCard.js.map +1 -1
  47. package/dist/components/ai/AIContextsTab.js +1 -1
  48. package/dist/components/ai/AIContextsTab.js.map +1 -1
  49. package/dist/components/ai/AIOverviewTab.js +4 -4
  50. package/dist/components/ai/AIOverviewTab.js.map +1 -1
  51. package/dist/components/ai/AIPlanPanel.js +4 -4
  52. package/dist/components/ai/AIPlanPanel.js.map +1 -1
  53. package/dist/components/ai/AIPlaygroundTab.js +1 -1
  54. package/dist/components/ai/AIPlaygroundTab.js.map +1 -1
  55. package/dist/components/ai/AIPromptsTab.js +2 -2
  56. package/dist/components/ai/AIPromptsTab.js.map +1 -1
  57. package/dist/components/ai/AIProviderCredentialsCard.js +4 -4
  58. package/dist/components/ai/AIProviderCredentialsCard.js.map +1 -1
  59. package/dist/components/ai/AIQueueTab.js +4 -4
  60. package/dist/components/ai/AIQueueTab.js.map +1 -1
  61. package/dist/components/ai/AISessionsTab.js +4 -4
  62. package/dist/components/ai/AISessionsTab.js.map +1 -1
  63. package/dist/components/ai/AITasksTab.js +1 -1
  64. package/dist/components/ai/AITasksTab.js.map +1 -1
  65. package/dist/components/ai/ClaudeCredentialsCard.js +3 -3
  66. package/dist/components/ai/ClaudeCredentialsCard.js.map +1 -1
  67. package/dist/components/ai/PluginHarnessPicker.js +3 -3
  68. package/dist/components/ai/PluginHarnessPicker.js.map +1 -1
  69. package/dist/components/analytics/AnalyticsBreakdownChart.js +8 -8
  70. package/dist/components/analytics/AnalyticsBreakdownChart.js.map +1 -1
  71. package/dist/components/analytics/AnalyticsTimeSeriesChart.js +5 -5
  72. package/dist/components/analytics/AnalyticsTimeSeriesChart.js.map +1 -1
  73. package/dist/components/audit/AuditDeleteDialog.js +2 -2
  74. package/dist/components/audit/AuditDeleteDialog.js.map +1 -1
  75. package/dist/components/audit/AuditExportButton.js +5 -5
  76. package/dist/components/audit/AuditExportButton.js.map +1 -1
  77. package/dist/components/audit/AuditLogDetail.js +9 -9
  78. package/dist/components/audit/AuditLogDetail.js.map +1 -1
  79. package/dist/components/audit/AuditLogFilters.js +1 -1
  80. package/dist/components/audit/AuditLogFilters.js.map +1 -1
  81. package/dist/components/audit/AuditLogStats.js +1 -1
  82. package/dist/components/audit/AuditLogStats.js.map +1 -1
  83. package/dist/components/audit/AuditLogTable.js +28 -28
  84. package/dist/components/audit/AuditLogTable.js.map +1 -1
  85. package/dist/components/catalog/CatalogCard.js +3 -3
  86. package/dist/components/catalog/CatalogCard.js.map +1 -1
  87. package/dist/components/catalog/CatalogForm.js +1 -1
  88. package/dist/components/catalog/CatalogForm.js.map +1 -1
  89. package/dist/components/common/ActionAgentTargetNotice.js +6 -6
  90. package/dist/components/common/ActionAgentTargetNotice.js.map +1 -1
  91. package/dist/components/common/CommandEditor.js +1 -1
  92. package/dist/components/common/CommandEditor.js.map +1 -1
  93. package/dist/components/docs/DocsPageTree.js +1 -1
  94. package/dist/components/docs/DocsPageTree.js.map +1 -1
  95. package/dist/components/docs/DocsPreviewPanel.js +1 -1
  96. package/dist/components/docs/DocsPreviewPanel.js.map +1 -1
  97. package/dist/components/docs/DocsRevisionHistory.js +4 -4
  98. package/dist/components/docs/DocsRevisionHistory.js.map +1 -1
  99. package/dist/components/docs/DocsSettingsPanel.js +7 -7
  100. package/dist/components/docs/DocsSettingsPanel.js.map +1 -1
  101. package/dist/components/docs/DocsTabPanel.js +1 -1
  102. package/dist/components/docs/DocsTabPanel.js.map +1 -1
  103. package/dist/components/graph/ConnectionPermissionsDialog.js +2 -2
  104. package/dist/components/graph/ConnectionPermissionsDialog.js.map +1 -1
  105. package/dist/components/graph/MeshDeployWizard.js +3 -3
  106. package/dist/components/graph/MeshDeployWizard.js.map +1 -1
  107. package/dist/components/graph/MeshRequestPanel.js +2 -2
  108. package/dist/components/graph/MeshRequestPanel.js.map +1 -1
  109. package/dist/components/idp-components/ComponentCard.js +5 -5
  110. package/dist/components/idp-components/ComponentCard.js.map +1 -1
  111. package/dist/components/idp-components/ComponentForm.js +1 -1
  112. package/dist/components/idp-components/ComponentForm.js.map +1 -1
  113. package/dist/components/idp-components/DependencyGraphTab.js +7 -7
  114. package/dist/components/idp-components/DependencyGraphTab.js.map +1 -1
  115. package/dist/components/logs/LogViewer.js +14 -14
  116. package/dist/components/logs/LogViewer.js.map +1 -1
  117. package/dist/components/notes/NoteCard.js +1 -1
  118. package/dist/components/notes/NoteCard.js.map +1 -1
  119. package/dist/components/notes/NoteEditor.js +2 -2
  120. package/dist/components/notes/NoteEditor.js.map +1 -1
  121. package/dist/components/notes/NoteList.js +1 -1
  122. package/dist/components/notes/NoteList.js.map +1 -1
  123. package/dist/components/notes/NotesTabPanel.js +1 -1
  124. package/dist/components/notes/NotesTabPanel.js.map +1 -1
  125. package/dist/components/scorecard/ScorecardEmptyState.js +1 -1
  126. package/dist/components/scorecard/ScorecardEmptyState.js.map +1 -1
  127. package/dist/components/scorecard/ScorecardPanel.js +3 -3
  128. package/dist/components/scorecard/ScorecardPanel.js.map +1 -1
  129. package/dist/components/security/SecurityScanList.js +11 -11
  130. package/dist/components/security/SecurityScanList.js.map +1 -1
  131. package/dist/components/sessions/SessionCard.js +26 -19
  132. package/dist/components/sessions/SessionCard.js.map +1 -1
  133. package/dist/components/sessions/SessionStatusBadge.js +7 -7
  134. package/dist/components/sessions/SessionStatusBadge.js.map +1 -1
  135. package/dist/components/shared/AgentSelector.js +4 -4
  136. package/dist/components/shared/AgentSelector.js.map +1 -1
  137. package/dist/components/shared/AgentSetupBanner.js +4 -4
  138. package/dist/components/shared/AgentSetupBanner.js.map +1 -1
  139. package/dist/components/shared/Card.js +4 -4
  140. package/dist/components/shared/Card.js.map +1 -1
  141. package/dist/components/shared/ErrorState.js +15 -9
  142. package/dist/components/shared/ErrorState.js.map +1 -1
  143. package/dist/components/shared/FilterDropdown.js +2 -2
  144. package/dist/components/shared/FilterDropdown.js.map +1 -1
  145. package/dist/components/shared/PageSkeleton.js +6 -6
  146. package/dist/components/shared/PageSkeleton.js.map +1 -1
  147. package/dist/components/shared/SearchInput.js +1 -1
  148. package/dist/components/shared/SearchInput.js.map +1 -1
  149. package/dist/components/shared/StatCard.js +7 -7
  150. package/dist/components/shared/StatCard.js.map +1 -1
  151. package/dist/components/templates/PublishTemplateForm.js +2 -2
  152. package/dist/components/templates/PublishTemplateForm.js.map +1 -1
  153. package/dist/components/templates/TemplateCard.js +5 -5
  154. package/dist/components/templates/TemplateCard.js.map +1 -1
  155. package/dist/components/templates/TemplateWizard.js +2 -2
  156. package/dist/components/templates/TemplateWizard.js.map +1 -1
  157. package/dist/components/tunnels/DomainVerificationBadge.js +4 -4
  158. package/dist/components/tunnels/DomainVerificationBadge.js.map +1 -1
  159. package/dist/components/tunnels/ProviderBadge.js +1 -1
  160. package/dist/components/tunnels/ProviderBadge.js.map +1 -1
  161. package/dist/components/tunnels/TunnelCard.js +16 -16
  162. package/dist/components/tunnels/TunnelCard.js.map +1 -1
  163. package/dist/components/tunnels/TunnelCreateWizard.js +1 -1
  164. package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
  165. package/dist/components/tunnels/TunnelPublicAccessPanel.js +1 -1
  166. package/dist/components/tunnels/TunnelPublicAccessPanel.js.map +1 -1
  167. package/dist/components/tunnels/TunnelStatusBadge.js +4 -4
  168. package/dist/components/tunnels/TunnelStatusBadge.js.map +1 -1
  169. package/dist/components/vibecalendar/LogsDrawer.js +2 -2
  170. package/dist/components/vibecalendar/LogsDrawer.js.map +1 -1
  171. package/dist/components/vibecalendar/ScheduleTaskModal.js +5 -5
  172. package/dist/components/vibecalendar/ScheduleTaskModal.js.map +1 -1
  173. package/dist/components/vibecalendar/VibeCalAgendaView.js +2 -2
  174. package/dist/components/vibecalendar/VibeCalAgendaView.js.map +1 -1
  175. package/dist/components/vibecalendar/VibeCalDayView.js +3 -3
  176. package/dist/components/vibecalendar/VibeCalDayView.js.map +1 -1
  177. package/dist/components/vibecalendar/VibeCalMonthView.js +1 -1
  178. package/dist/components/vibecalendar/VibeCalMonthView.js.map +1 -1
  179. package/dist/components/vibecalendar/VibeCalWeekView.js +4 -4
  180. package/dist/components/vibecalendar/VibeCalWeekView.js.map +1 -1
  181. package/dist/components/vibecalendar/VibeCalendarHeader.js +4 -4
  182. package/dist/components/vibecalendar/VibeCalendarHeader.js.map +1 -1
  183. package/dist/components/vibecalendar/VibeTaskBlock.js +2 -2
  184. package/dist/components/vibecalendar/VibeTaskBlock.js.map +1 -1
  185. package/dist/components/vibecalendar/types.js +7 -7
  186. package/dist/components/vibecalendar/types.js.map +1 -1
  187. package/dist/components/vibedeck/VibeDeckButtonForm.js +9 -9
  188. package/dist/components/vibedeck/VibeDeckButtonForm.js.map +1 -1
  189. package/dist/components/vibedeck/VibeDeckButtonTile.js +6 -6
  190. package/dist/components/vibedeck/VibeDeckButtonTile.js.map +1 -1
  191. package/dist/components/vibedeck/VibeDeckExecutionLog.js +10 -10
  192. package/dist/components/vibedeck/VibeDeckExecutionLog.js.map +1 -1
  193. package/dist/components/vibedeck/VibeDeckForm.js +8 -8
  194. package/dist/components/vibedeck/VibeDeckForm.js.map +1 -1
  195. package/dist/components/vibedeck/VibeDeckGrid.js +2 -2
  196. package/dist/components/vibedeck/VibeDeckGrid.js.map +1 -1
  197. package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js +2 -2
  198. package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js.map +1 -1
  199. package/dist/components/vibedeck/VibeDeckSwitcher.js +8 -8
  200. package/dist/components/vibedeck/VibeDeckSwitcher.js.map +1 -1
  201. package/dist/components/vibes/VibeCard.js +22 -18
  202. package/dist/components/vibes/VibeCard.js.map +1 -1
  203. package/dist/components/vibes/VibeList.js +16 -12
  204. package/dist/components/vibes/VibeList.js.map +1 -1
  205. package/dist/pages/ActionsPage.js +4 -3
  206. package/dist/pages/ActionsPage.js.map +1 -1
  207. package/dist/pages/AgentDetailsPage.js +9 -9
  208. package/dist/pages/AgentDetailsPage.js.map +1 -1
  209. package/dist/pages/AgentsLandingPage.js +4 -4
  210. package/dist/pages/AgentsLandingPage.js.map +1 -1
  211. package/dist/pages/AgentsPage.js +14 -14
  212. package/dist/pages/AgentsPage.js.map +1 -1
  213. package/dist/pages/AnalyticsPage.js +8 -8
  214. package/dist/pages/AnalyticsPage.js.map +1 -1
  215. package/dist/pages/CatalogDetailPage.js +11 -11
  216. package/dist/pages/CatalogDetailPage.js.map +1 -1
  217. package/dist/pages/CatalogPage.js +12 -9
  218. package/dist/pages/CatalogPage.js.map +1 -1
  219. package/dist/pages/ComponentDetailPage.js +7 -7
  220. package/dist/pages/ComponentDetailPage.js.map +1 -1
  221. package/dist/pages/ComponentsPage.js +12 -9
  222. package/dist/pages/ComponentsPage.js.map +1 -1
  223. package/dist/pages/EnvTopologyPage.js +2 -2
  224. package/dist/pages/EnvTopologyPage.js.map +1 -1
  225. package/dist/pages/GettingStartedPage.js +12 -12
  226. package/dist/pages/GettingStartedPage.js.map +1 -1
  227. package/dist/pages/HealthPage.js +12 -12
  228. package/dist/pages/HealthPage.js.map +1 -1
  229. package/dist/pages/LogsPage.js +4 -4
  230. package/dist/pages/LogsPage.js.map +1 -1
  231. package/dist/pages/NoteDetailsPage.js +5 -5
  232. package/dist/pages/NoteDetailsPage.js.map +1 -1
  233. package/dist/pages/OverviewPage.js +76 -43
  234. package/dist/pages/OverviewPage.js.map +1 -1
  235. package/dist/pages/PluginsCatalogPage.js +7 -4
  236. package/dist/pages/PluginsCatalogPage.js.map +1 -1
  237. package/dist/pages/ScheduledJobDetailPage.js +7 -7
  238. package/dist/pages/ScheduledJobDetailPage.js.map +1 -1
  239. package/dist/pages/SessionDetailsPage.js +21 -21
  240. package/dist/pages/SessionDetailsPage.js.map +1 -1
  241. package/dist/pages/SessionsPage.js +20 -20
  242. package/dist/pages/SessionsPage.js.map +1 -1
  243. package/dist/pages/SettingsPage.js +64 -52
  244. package/dist/pages/SettingsPage.js.map +1 -1
  245. package/dist/pages/SharedSessionPage.js +21 -21
  246. package/dist/pages/SharedSessionPage.js.map +1 -1
  247. package/dist/pages/SharedVibeDeckPage.js +5 -5
  248. package/dist/pages/SharedVibeDeckPage.js.map +1 -1
  249. package/dist/pages/TargetDetailsPage.js +56 -65
  250. package/dist/pages/TargetDetailsPage.js.map +1 -1
  251. package/dist/pages/TargetsPage.js +4 -4
  252. package/dist/pages/TargetsPage.js.map +1 -1
  253. package/dist/pages/TemplateDetailPage.js +10 -10
  254. package/dist/pages/TemplateDetailPage.js.map +1 -1
  255. package/dist/pages/TemplatesPage.js +6 -5
  256. package/dist/pages/TemplatesPage.js.map +1 -1
  257. package/dist/pages/VibeAuditPage.js +3 -3
  258. package/dist/pages/VibeAuditPage.js.map +1 -1
  259. package/dist/pages/VibeCalendarPage.js +3 -3
  260. package/dist/pages/VibeCalendarPage.js.map +1 -1
  261. package/dist/pages/VibeDeckPage.js +3 -3
  262. package/dist/pages/VibeDeckPage.js.map +1 -1
  263. package/dist/pages/VibeDetailsPage.js +15 -15
  264. package/dist/pages/VibeDetailsPage.js.map +1 -1
  265. package/dist/pages/VibeTaskDetailPage.js +5 -5
  266. package/dist/pages/VibeTaskDetailPage.js.map +1 -1
  267. package/dist/pages/VibesPage.js +18 -18
  268. package/dist/pages/VibesPage.js.map +1 -1
  269. package/dist/pages/WebhooksPage.js +11 -11
  270. package/dist/pages/WebhooksPage.js.map +1 -1
  271. package/dist/pages/ai/AIBookmarksPage.js +1 -1
  272. package/dist/pages/ai/AIBookmarksPage.js.map +1 -1
  273. package/dist/pages/ai/AISessionDetailPage.js +6 -6
  274. package/dist/pages/ai/AISessionDetailPage.js.map +1 -1
  275. package/dist/pages/tunnels/AuditTab.js +1 -1
  276. package/dist/pages/tunnels/AuditTab.js.map +1 -1
  277. package/dist/pages/tunnels/DomainsTab.js +1 -1
  278. package/dist/pages/tunnels/DomainsTab.js.map +1 -1
  279. package/dist/pages/tunnels/ProvidersTab.js +1 -1
  280. package/dist/pages/tunnels/ProvidersTab.js.map +1 -1
  281. package/dist/pages/tunnels/SessionsTab.js +1 -1
  282. package/dist/pages/tunnels/SessionsTab.js.map +1 -1
  283. package/dist/pages/tunnels/TunnelDetailsPage.js +3 -3
  284. package/dist/pages/tunnels/TunnelDetailsPage.js.map +1 -1
  285. package/dist/pages/tunnels/UsageTab.js +1 -1
  286. package/dist/pages/tunnels/UsageTab.js.map +1 -1
  287. package/dist/pages/tunnels/tabs/TunnelDomainsTab.js +16 -16
  288. package/dist/pages/tunnels/tabs/TunnelDomainsTab.js.map +1 -1
  289. package/dist/pages/tunnels/tabs/TunnelOverviewTab.js +1 -1
  290. package/dist/pages/tunnels/tabs/TunnelOverviewTab.js.map +1 -1
  291. package/dist/pages/tunnels/tabs/TunnelSessionsTab.js +52 -49
  292. package/dist/pages/tunnels/tabs/TunnelSessionsTab.js.map +1 -1
  293. package/dist/pages/tunnels/tabs/TunnelSettingsTab.js +9 -9
  294. package/dist/pages/tunnels/tabs/TunnelSettingsTab.js.map +1 -1
  295. package/package.json +1 -1
@@ -8,25 +8,25 @@ var h = [
8
8
  name: "Claude Code",
9
9
  id: "claude",
10
10
  config: "~/.claude/",
11
- color: "bg-accent-purple-subtle text-accent-purple"
11
+ color: "bg-accent-purple-subtle text-text-primary"
12
12
  },
13
13
  {
14
14
  name: "OpenCode",
15
15
  id: "opencode",
16
16
  config: "~/.config/opencode/",
17
- color: "bg-status-info-bg text-status-info-text"
17
+ color: "bg-status-info-bg-subtle text-status-info-text"
18
18
  },
19
19
  {
20
20
  name: "Goose",
21
21
  id: "goose",
22
22
  config: "~/.config/goose/",
23
- color: "bg-status-success-bg text-status-success-text"
23
+ color: "bg-status-success-bg-subtle text-status-success-text"
24
24
  },
25
25
  {
26
26
  name: "Amp",
27
27
  id: "amp",
28
28
  config: "~/.amp/",
29
- color: "bg-status-warning-bg text-status-warning-text"
29
+ color: "bg-status-warning-bg-subtle text-status-warning-text"
30
30
  },
31
31
  {
32
32
  name: "Copilot",
@@ -38,7 +38,7 @@ var h = [
38
38
  name: "Crush",
39
39
  id: "crush",
40
40
  config: "~/.config/crush/",
41
- color: "bg-status-error-bg text-status-error-text"
41
+ color: "bg-status-error-bg-subtle text-status-error-text"
42
42
  }
43
43
  ];
44
44
  function g({ agent: g }) {
@@ -86,7 +86,7 @@ function g({ agent: g }) {
86
86
  children: I.map(({ key: e, label: t, icon: n }) => /* @__PURE__ */ m("button", {
87
87
  type: "button",
88
88
  onClick: () => y(e),
89
- className: `flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded transition-colors ${v === e ? "bg-action-primary-bg/10 text-action-primary-text" : "text-text-secondary hover:text-text-primary hover:bg-bg-elevated"}`,
89
+ className: `flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded transition-colors ${v === e ? "bg-[var(--color-accent-soft)] text-text-primary" : "text-text-secondary hover:text-text-primary hover:bg-bg-elevated"}`,
90
90
  children: [/* @__PURE__ */ p(n, { className: "size-3.5" }), t]
91
91
  }, e))
92
92
  }),
@@ -105,7 +105,7 @@ function g({ agent: g }) {
105
105
  onClick: () => {
106
106
  x(e.id), y("profiles");
107
107
  },
108
- className: "px-3 py-2.5 rounded-md border border-border-default bg-bg-primary hover:bg-bg-elevated transition-colors text-left",
108
+ className: "px-3 py-2.5 rounded-md border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors text-left",
109
109
  children: [/* @__PURE__ */ p("span", {
110
110
  className: "text-xs font-medium text-text-primary",
111
111
  children: e.name
@@ -122,7 +122,7 @@ function g({ agent: g }) {
122
122
  children: [/* @__PURE__ */ m("button", {
123
123
  type: "button",
124
124
  onClick: () => F("bridle status"),
125
- className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated transition-colors flex items-center gap-1.5",
125
+ className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors flex items-center gap-1.5",
126
126
  children: [
127
127
  /* @__PURE__ */ p(c, { className: "size-3" }),
128
128
  " ",
@@ -131,7 +131,7 @@ function g({ agent: g }) {
131
131
  }), /* @__PURE__ */ m("button", {
132
132
  type: "button",
133
133
  onClick: () => F("bridle init"),
134
- className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated transition-colors flex items-center gap-1.5",
134
+ className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors flex items-center gap-1.5",
135
135
  children: [
136
136
  /* @__PURE__ */ p(s, { className: "size-3" }),
137
137
  " ",
@@ -151,7 +151,7 @@ function g({ agent: g }) {
151
151
  id: "bridleconfigpanel-5",
152
152
  value: b,
153
153
  onChange: (e) => x(e.target.value),
154
- className: "w-full px-3 py-2 text-sm rounded border border-border-default bg-bg-primary text-text-primary",
154
+ className: "w-full px-3 py-2 text-sm rounded border border-border-default bg-bg-surface text-text-primary",
155
155
  children: h.map((e) => /* @__PURE__ */ p("option", {
156
156
  value: e.id,
157
157
  children: e.name
@@ -162,12 +162,12 @@ function g({ agent: g }) {
162
162
  children: [/* @__PURE__ */ p("button", {
163
163
  type: "button",
164
164
  onClick: () => F(`bridle profile list ${b}`),
165
- className: "px-3 py-2 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated transition-colors text-left",
165
+ className: "px-3 py-2 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors text-left",
166
166
  children: _("vibecontrols.agentManager.bridle.listProfiles", "List Profiles")
167
167
  }), /* @__PURE__ */ p("button", {
168
168
  type: "button",
169
169
  onClick: () => F(`bridle profile show ${b} ${S || "<name>"}`),
170
- className: "px-3 py-2 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated transition-colors text-left",
170
+ className: "px-3 py-2 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors text-left",
171
171
  children: _("vibecontrols.agentManager.bridle.showProfile", "Show Profile")
172
172
  })]
173
173
  }),
@@ -184,7 +184,7 @@ function g({ agent: g }) {
184
184
  value: S,
185
185
  onChange: (e) => C(e.target.value),
186
186
  placeholder: "e.g., work, personal, minimal",
187
- className: "flex-1 px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
187
+ className: "flex-1 px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
188
188
  })
189
189
  }),
190
190
  /* @__PURE__ */ m("div", {
@@ -201,21 +201,21 @@ function g({ agent: g }) {
201
201
  type: "button",
202
202
  onClick: () => F(`bridle profile create ${b} ${S} --from-current`),
203
203
  disabled: !S,
204
- className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated disabled:opacity-50 flex items-center gap-1",
204
+ className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated disabled:opacity-50 flex items-center gap-1",
205
205
  children: [/* @__PURE__ */ p(a, { className: "size-3" }), " From Current"]
206
206
  }),
207
207
  /* @__PURE__ */ m("button", {
208
208
  type: "button",
209
209
  onClick: () => F(`bridle profile switch ${b} ${S}`),
210
210
  disabled: !S,
211
- className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated disabled:opacity-50 flex items-center gap-1",
211
+ className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated disabled:opacity-50 flex items-center gap-1",
212
212
  children: [/* @__PURE__ */ p(r, { className: "size-3" }), " Switch"]
213
213
  }),
214
214
  /* @__PURE__ */ m("button", {
215
215
  type: "button",
216
216
  onClick: () => F(`bridle profile delete ${b} ${S}`),
217
217
  disabled: !S,
218
- className: "px-3 py-1.5 text-xs rounded border border-status-error-bg text-status-error-text hover:bg-status-error-bg/10 disabled:opacity-50 flex items-center gap-1",
218
+ className: "px-3 py-1.5 text-xs rounded-button border border-status-error-border text-status-error-text hover:bg-status-error-bg-subtle disabled:opacity-50 flex items-center gap-1",
219
219
  children: [/* @__PURE__ */ p(d, { className: "size-3" }), " Delete"]
220
220
  })
221
221
  ]
@@ -242,7 +242,7 @@ function g({ agent: g }) {
242
242
  value: w,
243
243
  onChange: (e) => T(e.target.value),
244
244
  placeholder: "owner/repo or full GitHub URL",
245
- className: "flex-1 px-3 py-2 text-sm rounded border border-border-default bg-bg-primary text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
245
+ className: "flex-1 px-3 py-2 text-sm rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
246
246
  }), /* @__PURE__ */ m("button", {
247
247
  type: "button",
248
248
  onClick: () => F(`bridle install ${w}`),
@@ -283,7 +283,7 @@ function g({ agent: g }) {
283
283
  value: E,
284
284
  onChange: (e) => D(e.target.value),
285
285
  placeholder: "e.g., editor, default_harness, profile_marker",
286
- className: "w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
286
+ className: "w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
287
287
  })] }),
288
288
  /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
289
289
  htmlFor: "bridleconfigpanel-3",
@@ -296,7 +296,7 @@ function g({ agent: g }) {
296
296
  value: O,
297
297
  onChange: (e) => k(e.target.value),
298
298
  placeholder: "value",
299
- className: "w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
299
+ className: "w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
300
300
  })] }),
301
301
  /* @__PURE__ */ m("div", {
302
302
  className: "flex gap-2",
@@ -304,7 +304,7 @@ function g({ agent: g }) {
304
304
  type: "button",
305
305
  onClick: () => F(`bridle config get ${E}`),
306
306
  disabled: !E,
307
- className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated disabled:opacity-50",
307
+ className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated disabled:opacity-50",
308
308
  children: "Get"
309
309
  }), /* @__PURE__ */ p("button", {
310
310
  type: "button",
@@ -322,19 +322,19 @@ function g({ agent: g }) {
322
322
  className: "space-y-1 text-xs text-text-secondary",
323
323
  children: [
324
324
  /* @__PURE__ */ m("div", {
325
- className: "flex justify-between px-2 py-1 rounded bg-bg-primary",
325
+ className: "flex justify-between px-2 py-1 rounded bg-bg-surface",
326
326
  children: [/* @__PURE__ */ p("code", { children: "profile_marker" }), /* @__PURE__ */ p("span", { children: "Enable debug marker files" })]
327
327
  }),
328
328
  /* @__PURE__ */ m("div", {
329
- className: "flex justify-between px-2 py-1 rounded bg-bg-primary",
329
+ className: "flex justify-between px-2 py-1 rounded bg-bg-surface",
330
330
  children: [/* @__PURE__ */ p("code", { children: "editor" }), /* @__PURE__ */ p("span", { children: "Default text editor" })]
331
331
  }),
332
332
  /* @__PURE__ */ m("div", {
333
- className: "flex justify-between px-2 py-1 rounded bg-bg-primary",
333
+ className: "flex justify-between px-2 py-1 rounded bg-bg-surface",
334
334
  children: [/* @__PURE__ */ p("code", { children: "tui.view" }), /* @__PURE__ */ p("span", { children: "Initial TUI view" })]
335
335
  }),
336
336
  /* @__PURE__ */ m("div", {
337
- className: "flex justify-between px-2 py-1 rounded bg-bg-primary",
337
+ className: "flex justify-between px-2 py-1 rounded bg-bg-surface",
338
338
  children: [/* @__PURE__ */ p("code", { children: "default_harness" }), /* @__PURE__ */ p("span", { children: "Startup harness tab" })]
339
339
  })
340
340
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"BridleConfigPanel.js","names":[],"sources":["../../../src/components/agent-manager/BridleConfigPanel.tsx"],"sourcesContent":["/**\n * Bridle Configuration Manager Panel.\n *\n * Provides a full UI for managing cross-harness AI assistant configurations\n * via the Bridle CLI tool. Supports profile management, skill installation,\n * and config editing across Claude Code, OpenCode, Goose, Amp, Copilot, and Crush.\n */\n\nimport { useState, useCallback } from 'react';\nimport {\n Terminal,\n Copy,\n Check,\n Plus,\n ArrowLeftRight,\n Trash2,\n Download,\n Settings,\n RefreshCw,\n} from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface BridleConfigPanelProps {\n agent: { id: string; profile: string };\n}\n\nconst HARNESSES = [\n {\n name: 'Claude Code',\n id: 'claude',\n config: '~/.claude/',\n color: 'bg-accent-purple-subtle text-accent-purple',\n },\n {\n name: 'OpenCode',\n id: 'opencode',\n config: '~/.config/opencode/',\n color: 'bg-status-info-bg text-status-info-text',\n },\n {\n name: 'Goose',\n id: 'goose',\n config: '~/.config/goose/',\n color: 'bg-status-success-bg text-status-success-text',\n },\n {\n name: 'Amp',\n id: 'amp',\n config: '~/.amp/',\n color: 'bg-status-warning-bg text-status-warning-text',\n },\n {\n name: 'Copilot',\n id: 'copilot',\n config: '~/.copilot/',\n color: 'bg-bg-sunken text-text-secondary',\n },\n {\n name: 'Crush',\n id: 'crush',\n config: '~/.config/crush/',\n color: 'bg-status-error-bg text-status-error-text',\n },\n];\n\ntype PanelView = 'overview' | 'profiles' | 'install' | 'settings';\n\nexport function BridleConfigPanel({ agent: _agent }: BridleConfigPanelProps) {\n const tr = useTr();\n const [view, setView] = useState<PanelView>('overview');\n const [selectedHarness, setSelectedHarness] = useState('claude');\n const [profileName, setProfileName] = useState('');\n const [installSource, setInstallSource] = useState('');\n const [configKey, setConfigKey] = useState('');\n const [configValue, setConfigValue] = useState('');\n const [output, setOutput] = useState('');\n const [copiedCmd, setCopiedCmd] = useState<string | null>(null);\n\n const copyToClipboard = useCallback((text: string) => {\n void navigator.clipboard.writeText(text);\n setCopiedCmd(text);\n setTimeout(() => setCopiedCmd(null), 2000);\n }, []);\n\n const showCommand = (cmd: string) => {\n setOutput(`$ ${cmd}\\n\\nRun this command in your terminal to execute.`);\n copyToClipboard(cmd);\n };\n\n const navItems: Array<{ key: PanelView; label: string; icon: typeof Settings }> = [\n { key: 'overview', label: 'Overview', icon: RefreshCw },\n { key: 'profiles', label: 'Profiles', icon: ArrowLeftRight },\n { key: 'install', label: 'Install', icon: Download },\n { key: 'settings', label: 'Settings', icon: Settings },\n ];\n\n return (\n <div className=\"flex flex-col h-full max-h-[65vh] overflow-hidden\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default flex-shrink-0\">\n <div>\n <h3 className=\"text-sm font-semibold text-text-primary flex items-center gap-2\">\n <Terminal className=\"size-4\" />\n {tr('vibecontrols.agentManager.bridle.title', 'Bridle — Cross-Harness Config Manager')}\n </h3>\n <p className=\"text-[11px] text-text-secondary mt-0.5\">\n {tr(\n 'vibecontrols.agentManager.bridle.description',\n 'Manage profiles, skills, and configurations across all AI coding assistants'\n )}\n </p>\n </div>\n </div>\n\n {/* Sub-navigation */}\n <div className=\"flex gap-1 px-4 py-2 border-b border-border-default flex-shrink-0\">\n {navItems.map(({ key, label, icon: Icon }) => (\n <button\n type=\"button\"\n key={key}\n onClick={() => setView(key)}\n className={`flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded transition-colors ${\n view === key\n ? 'bg-action-primary-bg/10 text-action-primary-text'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-elevated'\n }`}\n >\n <Icon className=\"size-3.5\" />\n {label}\n </button>\n ))}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto p-4\">\n {view === 'overview' && (\n <div className=\"space-y-4\">\n {/* Harness Grid */}\n <div>\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider mb-2\">\n {tr('vibecontrols.agentManager.bridle.supportedHarnesses', 'Supported Harnesses')}\n </h4>\n <div className=\"grid grid-cols-2 sm:grid-cols-3 gap-2\">\n {HARNESSES.map((h) => (\n <button\n type=\"button\"\n key={h.id}\n onClick={() => {\n setSelectedHarness(h.id);\n setView('profiles');\n }}\n className=\"px-3 py-2.5 rounded-md border border-border-default bg-bg-primary hover:bg-bg-elevated transition-colors text-left\"\n >\n <span className=\"text-xs font-medium text-text-primary\">{h.name}</span>\n <span className=\"block text-[10px] text-text-tertiary font-mono mt-0.5\">\n {h.config}\n </span>\n </button>\n ))}\n </div>\n </div>\n\n {/* Quick Status */}\n <div>\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider mb-2\">\n {tr('vibecontrols.agentManager.bridle.quickActions', 'Quick Actions')}\n </h4>\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => showCommand('bridle status')}\n className=\"px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated transition-colors flex items-center gap-1.5\"\n >\n <RefreshCw className=\"size-3\" />{' '}\n {tr('vibecontrols.agentManager.bridle.showStatus', 'Show Status')}\n </button>\n <button\n type=\"button\"\n onClick={() => showCommand('bridle init')}\n className=\"px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated transition-colors flex items-center gap-1.5\"\n >\n <Plus className=\"size-3\" />{' '}\n {tr('vibecontrols.agentManager.bridle.initialize', 'Initialize')}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {view === 'profiles' && (\n <div className=\"space-y-4\">\n {/* Harness Selector */}\n <div>\n <label\n htmlFor=\"bridleconfigpanel-5\"\n className=\"block text-xs font-medium text-text-secondary mb-1\"\n >\n Harness\n </label>\n <select\n id=\"bridleconfigpanel-5\"\n value={selectedHarness}\n onChange={(e) => setSelectedHarness(e.target.value)}\n className=\"w-full px-3 py-2 text-sm rounded border border-border-default bg-bg-primary text-text-primary\"\n >\n {HARNESSES.map((h) => (\n <option key={h.id} value={h.id}>\n {h.name}\n </option>\n ))}\n </select>\n </div>\n\n {/* Profile Actions */}\n <div className=\"grid grid-cols-2 gap-2\">\n <button\n type=\"button\"\n onClick={() => showCommand(`bridle profile list ${selectedHarness}`)}\n className=\"px-3 py-2 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated transition-colors text-left\"\n >\n {tr('vibecontrols.agentManager.bridle.listProfiles', 'List Profiles')}\n </button>\n <button\n type=\"button\"\n onClick={() =>\n showCommand(`bridle profile show ${selectedHarness} ${profileName || '<name>'}`)\n }\n className=\"px-3 py-2 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated transition-colors text-left\"\n >\n {tr('vibecontrols.agentManager.bridle.showProfile', 'Show Profile')}\n </button>\n </div>\n\n {/* Create Profile */}\n <div>\n <label className=\"block text-xs font-medium text-text-secondary mb-1\">\n {tr('vibecontrols.agentManager.bridle.profileName', 'Profile Name')}\n </label>\n <div className=\"flex gap-2\">\n <input\n aria-label=\"e.g., work, personal, minimal\"\n type=\"text\"\n value={profileName}\n onChange={(e) => setProfileName(e.target.value)}\n placeholder=\"e.g., work, personal, minimal\"\n className=\"flex-1 px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong\"\n />\n </div>\n <div className=\"flex gap-2 mt-2\">\n <button\n type=\"button\"\n onClick={() =>\n showCommand(`bridle profile create ${selectedHarness} ${profileName}`)\n }\n disabled={!profileName}\n className=\"px-3 py-1.5 text-xs rounded bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50 flex items-center gap-1\"\n >\n <Plus className=\"size-3\" /> Create\n </button>\n <button\n type=\"button\"\n onClick={() =>\n showCommand(\n `bridle profile create ${selectedHarness} ${profileName} --from-current`\n )\n }\n disabled={!profileName}\n className=\"px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated disabled:opacity-50 flex items-center gap-1\"\n >\n <Copy className=\"size-3\" /> From Current\n </button>\n <button\n type=\"button\"\n onClick={() =>\n showCommand(`bridle profile switch ${selectedHarness} ${profileName}`)\n }\n disabled={!profileName}\n className=\"px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated disabled:opacity-50 flex items-center gap-1\"\n >\n <ArrowLeftRight className=\"size-3\" /> Switch\n </button>\n <button\n type=\"button\"\n onClick={() =>\n showCommand(`bridle profile delete ${selectedHarness} ${profileName}`)\n }\n disabled={!profileName}\n className=\"px-3 py-1.5 text-xs rounded border border-status-error-bg text-status-error-text hover:bg-status-error-bg/10 disabled:opacity-50 flex items-center gap-1\"\n >\n <Trash2 className=\"size-3\" /> Delete\n </button>\n </div>\n </div>\n </div>\n )}\n\n {view === 'install' && (\n <div className=\"space-y-4\">\n <div>\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider mb-2\">\n {tr('vibecontrols.agentManager.bridle.installFromGithub', 'Install from GitHub')}\n </h4>\n <p className=\"text-xs text-text-secondary mb-3\">\n {tr(\n 'vibecontrols.agentManager.bridle.installDescription',\n 'Install skills, agents, commands, or MCPs from GitHub repositories.'\n )}\n </p>\n <div className=\"flex gap-2\">\n <input\n aria-label=\"owner/repo or full GitHub URL\"\n type=\"text\"\n value={installSource}\n onChange={(e) => setInstallSource(e.target.value)}\n placeholder=\"owner/repo or full GitHub URL\"\n className=\"flex-1 px-3 py-2 text-sm rounded border border-border-default bg-bg-primary text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong\"\n />\n <button\n type=\"button\"\n onClick={() => showCommand(`bridle install ${installSource}`)}\n disabled={!installSource}\n className=\"px-4 py-2 text-sm rounded bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50 flex items-center gap-1.5\"\n >\n <Download className=\"size-4\" /> Install\n </button>\n </div>\n <p className=\"text-[10px] text-text-tertiary mt-1.5\">\n Use <code className=\"px-1 py-0.5 rounded bg-bg-elevated\">--force</code> to overwrite\n existing installations\n </p>\n </div>\n </div>\n )}\n\n {view === 'settings' && (\n <div className=\"space-y-4\">\n <div>\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider mb-2\">\n {tr('vibecontrols.agentManager.bridle.configuration', 'Configuration')}\n </h4>\n <div className=\"space-y-3\">\n <div>\n <label\n htmlFor=\"bridleconfigpanel-4\"\n className=\"block text-xs font-medium text-text-secondary mb-1\"\n >\n Key\n </label>\n <input\n id=\"bridleconfigpanel-4\"\n aria-label=\"e.g., editor, default_harness, profile_marker\"\n type=\"text\"\n value={configKey}\n onChange={(e) => setConfigKey(e.target.value)}\n placeholder=\"e.g., editor, default_harness, profile_marker\"\n className=\"w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong\"\n />\n </div>\n <div>\n <label\n htmlFor=\"bridleconfigpanel-3\"\n className=\"block text-xs font-medium text-text-secondary mb-1\"\n >\n Value\n </label>\n <input\n id=\"bridleconfigpanel-3\"\n aria-label=\"value\"\n type=\"text\"\n value={configValue}\n onChange={(e) => setConfigValue(e.target.value)}\n placeholder=\"value\"\n className=\"w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong\"\n />\n </div>\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => showCommand(`bridle config get ${configKey}`)}\n disabled={!configKey}\n className=\"px-3 py-1.5 text-xs rounded border border-border-default bg-bg-primary hover:bg-bg-elevated disabled:opacity-50\"\n >\n Get\n </button>\n <button\n type=\"button\"\n onClick={() => showCommand(`bridle config set ${configKey} ${configValue}`)}\n disabled={!configKey || !configValue}\n className=\"px-3 py-1.5 text-xs rounded bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50\"\n >\n Set\n </button>\n </div>\n </div>\n </div>\n\n <div>\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider mb-2\">\n {tr(\n 'vibecontrols.agentManager.bridle.availableConfigKeys',\n 'Available Config Keys'\n )}\n </h4>\n <div className=\"space-y-1 text-xs text-text-secondary\">\n <div className=\"flex justify-between px-2 py-1 rounded bg-bg-primary\">\n <code>profile_marker</code>\n <span>Enable debug marker files</span>\n </div>\n <div className=\"flex justify-between px-2 py-1 rounded bg-bg-primary\">\n <code>editor</code>\n <span>Default text editor</span>\n </div>\n <div className=\"flex justify-between px-2 py-1 rounded bg-bg-primary\">\n <code>tui.view</code>\n <span>Initial TUI view</span>\n </div>\n <div className=\"flex justify-between px-2 py-1 rounded bg-bg-primary\">\n <code>default_harness</code>\n <span>Startup harness tab</span>\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* Output */}\n {output && (\n <div className=\"mt-4 border-t border-border-default pt-3\">\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider\">\n {tr('vibecontrols.agentManager.bridle.command', 'Command')}\n </h4>\n <button\n type=\"button\"\n onClick={() => setOutput('')}\n className=\"text-[10px] text-text-tertiary hover:text-text-secondary\"\n >\n {tr('vibecontrols.agentManager.bridle.clear', 'Clear')}\n </button>\n </div>\n <pre className=\"p-3 rounded-md bg-bg-sunken text-text-primary text-xs font-mono whitespace-pre-wrap border border-border-default\">\n {output}\n </pre>\n <p className=\"text-[10px] text-text-tertiary mt-1 flex items-center gap-1\">\n {copiedCmd ? (\n <>\n <Check className=\"size-3 text-status-success-text\" />{' '}\n {tr('vibecontrols.agentManager.bridle.copiedToClipboard', 'Copied to clipboard')}\n </>\n ) : (\n tr('vibecontrols.agentManager.bridle.commandCopied', 'Command copied to clipboard')\n )}\n </p>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"BridleConfigPanel.js","names":[],"sources":["../../../src/components/agent-manager/BridleConfigPanel.tsx"],"sourcesContent":["/**\n * Bridle Configuration Manager Panel.\n *\n * Provides a full UI for managing cross-harness AI assistant configurations\n * via the Bridle CLI tool. Supports profile management, skill installation,\n * and config editing across Claude Code, OpenCode, Goose, Amp, Copilot, and Crush.\n */\n\nimport { useState, useCallback } from 'react';\nimport {\n Terminal,\n Copy,\n Check,\n Plus,\n ArrowLeftRight,\n Trash2,\n Download,\n Settings,\n RefreshCw,\n} from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface BridleConfigPanelProps {\n agent: { id: string; profile: string };\n}\n\nconst HARNESSES = [\n {\n name: 'Claude Code',\n id: 'claude',\n config: '~/.claude/',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n name: 'OpenCode',\n id: 'opencode',\n config: '~/.config/opencode/',\n color: 'bg-status-info-bg-subtle text-status-info-text',\n },\n {\n name: 'Goose',\n id: 'goose',\n config: '~/.config/goose/',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n name: 'Amp',\n id: 'amp',\n config: '~/.amp/',\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n {\n name: 'Copilot',\n id: 'copilot',\n config: '~/.copilot/',\n color: 'bg-bg-sunken text-text-secondary',\n },\n {\n name: 'Crush',\n id: 'crush',\n config: '~/.config/crush/',\n color: 'bg-status-error-bg-subtle text-status-error-text',\n },\n];\n\ntype PanelView = 'overview' | 'profiles' | 'install' | 'settings';\n\nexport function BridleConfigPanel({ agent: _agent }: BridleConfigPanelProps) {\n const tr = useTr();\n const [view, setView] = useState<PanelView>('overview');\n const [selectedHarness, setSelectedHarness] = useState('claude');\n const [profileName, setProfileName] = useState('');\n const [installSource, setInstallSource] = useState('');\n const [configKey, setConfigKey] = useState('');\n const [configValue, setConfigValue] = useState('');\n const [output, setOutput] = useState('');\n const [copiedCmd, setCopiedCmd] = useState<string | null>(null);\n\n const copyToClipboard = useCallback((text: string) => {\n void navigator.clipboard.writeText(text);\n setCopiedCmd(text);\n setTimeout(() => setCopiedCmd(null), 2000);\n }, []);\n\n const showCommand = (cmd: string) => {\n setOutput(`$ ${cmd}\\n\\nRun this command in your terminal to execute.`);\n copyToClipboard(cmd);\n };\n\n const navItems: Array<{ key: PanelView; label: string; icon: typeof Settings }> = [\n { key: 'overview', label: 'Overview', icon: RefreshCw },\n { key: 'profiles', label: 'Profiles', icon: ArrowLeftRight },\n { key: 'install', label: 'Install', icon: Download },\n { key: 'settings', label: 'Settings', icon: Settings },\n ];\n\n return (\n <div className=\"flex flex-col h-full max-h-[65vh] overflow-hidden\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default flex-shrink-0\">\n <div>\n <h3 className=\"text-sm font-semibold text-text-primary flex items-center gap-2\">\n <Terminal className=\"size-4\" />\n {tr('vibecontrols.agentManager.bridle.title', 'Bridle — Cross-Harness Config Manager')}\n </h3>\n <p className=\"text-[11px] text-text-secondary mt-0.5\">\n {tr(\n 'vibecontrols.agentManager.bridle.description',\n 'Manage profiles, skills, and configurations across all AI coding assistants'\n )}\n </p>\n </div>\n </div>\n\n {/* Sub-navigation */}\n <div className=\"flex gap-1 px-4 py-2 border-b border-border-default flex-shrink-0\">\n {navItems.map(({ key, label, icon: Icon }) => (\n <button\n type=\"button\"\n key={key}\n onClick={() => setView(key)}\n className={`flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded transition-colors ${\n view === key\n ? 'bg-[var(--color-accent-soft)] text-text-primary'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-elevated'\n }`}\n >\n <Icon className=\"size-3.5\" />\n {label}\n </button>\n ))}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto p-4\">\n {view === 'overview' && (\n <div className=\"space-y-4\">\n {/* Harness Grid */}\n <div>\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider mb-2\">\n {tr('vibecontrols.agentManager.bridle.supportedHarnesses', 'Supported Harnesses')}\n </h4>\n <div className=\"grid grid-cols-2 sm:grid-cols-3 gap-2\">\n {HARNESSES.map((h) => (\n <button\n type=\"button\"\n key={h.id}\n onClick={() => {\n setSelectedHarness(h.id);\n setView('profiles');\n }}\n className=\"px-3 py-2.5 rounded-md border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors text-left\"\n >\n <span className=\"text-xs font-medium text-text-primary\">{h.name}</span>\n <span className=\"block text-[10px] text-text-tertiary font-mono mt-0.5\">\n {h.config}\n </span>\n </button>\n ))}\n </div>\n </div>\n\n {/* Quick Status */}\n <div>\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider mb-2\">\n {tr('vibecontrols.agentManager.bridle.quickActions', 'Quick Actions')}\n </h4>\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => showCommand('bridle status')}\n className=\"px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors flex items-center gap-1.5\"\n >\n <RefreshCw className=\"size-3\" />{' '}\n {tr('vibecontrols.agentManager.bridle.showStatus', 'Show Status')}\n </button>\n <button\n type=\"button\"\n onClick={() => showCommand('bridle init')}\n className=\"px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors flex items-center gap-1.5\"\n >\n <Plus className=\"size-3\" />{' '}\n {tr('vibecontrols.agentManager.bridle.initialize', 'Initialize')}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {view === 'profiles' && (\n <div className=\"space-y-4\">\n {/* Harness Selector */}\n <div>\n <label\n htmlFor=\"bridleconfigpanel-5\"\n className=\"block text-xs font-medium text-text-secondary mb-1\"\n >\n Harness\n </label>\n <select\n id=\"bridleconfigpanel-5\"\n value={selectedHarness}\n onChange={(e) => setSelectedHarness(e.target.value)}\n className=\"w-full px-3 py-2 text-sm rounded border border-border-default bg-bg-surface text-text-primary\"\n >\n {HARNESSES.map((h) => (\n <option key={h.id} value={h.id}>\n {h.name}\n </option>\n ))}\n </select>\n </div>\n\n {/* Profile Actions */}\n <div className=\"grid grid-cols-2 gap-2\">\n <button\n type=\"button\"\n onClick={() => showCommand(`bridle profile list ${selectedHarness}`)}\n className=\"px-3 py-2 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors text-left\"\n >\n {tr('vibecontrols.agentManager.bridle.listProfiles', 'List Profiles')}\n </button>\n <button\n type=\"button\"\n onClick={() =>\n showCommand(`bridle profile show ${selectedHarness} ${profileName || '<name>'}`)\n }\n className=\"px-3 py-2 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors text-left\"\n >\n {tr('vibecontrols.agentManager.bridle.showProfile', 'Show Profile')}\n </button>\n </div>\n\n {/* Create Profile */}\n <div>\n <label className=\"block text-xs font-medium text-text-secondary mb-1\">\n {tr('vibecontrols.agentManager.bridle.profileName', 'Profile Name')}\n </label>\n <div className=\"flex gap-2\">\n <input\n aria-label=\"e.g., work, personal, minimal\"\n type=\"text\"\n value={profileName}\n onChange={(e) => setProfileName(e.target.value)}\n placeholder=\"e.g., work, personal, minimal\"\n className=\"flex-1 px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong\"\n />\n </div>\n <div className=\"flex gap-2 mt-2\">\n <button\n type=\"button\"\n onClick={() =>\n showCommand(`bridle profile create ${selectedHarness} ${profileName}`)\n }\n disabled={!profileName}\n className=\"px-3 py-1.5 text-xs rounded bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50 flex items-center gap-1\"\n >\n <Plus className=\"size-3\" /> Create\n </button>\n <button\n type=\"button\"\n onClick={() =>\n showCommand(\n `bridle profile create ${selectedHarness} ${profileName} --from-current`\n )\n }\n disabled={!profileName}\n className=\"px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated disabled:opacity-50 flex items-center gap-1\"\n >\n <Copy className=\"size-3\" /> From Current\n </button>\n <button\n type=\"button\"\n onClick={() =>\n showCommand(`bridle profile switch ${selectedHarness} ${profileName}`)\n }\n disabled={!profileName}\n className=\"px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated disabled:opacity-50 flex items-center gap-1\"\n >\n <ArrowLeftRight className=\"size-3\" /> Switch\n </button>\n <button\n type=\"button\"\n onClick={() =>\n showCommand(`bridle profile delete ${selectedHarness} ${profileName}`)\n }\n disabled={!profileName}\n className=\"px-3 py-1.5 text-xs rounded-button border border-status-error-border text-status-error-text hover:bg-status-error-bg-subtle disabled:opacity-50 flex items-center gap-1\"\n >\n <Trash2 className=\"size-3\" /> Delete\n </button>\n </div>\n </div>\n </div>\n )}\n\n {view === 'install' && (\n <div className=\"space-y-4\">\n <div>\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider mb-2\">\n {tr('vibecontrols.agentManager.bridle.installFromGithub', 'Install from GitHub')}\n </h4>\n <p className=\"text-xs text-text-secondary mb-3\">\n {tr(\n 'vibecontrols.agentManager.bridle.installDescription',\n 'Install skills, agents, commands, or MCPs from GitHub repositories.'\n )}\n </p>\n <div className=\"flex gap-2\">\n <input\n aria-label=\"owner/repo or full GitHub URL\"\n type=\"text\"\n value={installSource}\n onChange={(e) => setInstallSource(e.target.value)}\n placeholder=\"owner/repo or full GitHub URL\"\n className=\"flex-1 px-3 py-2 text-sm rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong\"\n />\n <button\n type=\"button\"\n onClick={() => showCommand(`bridle install ${installSource}`)}\n disabled={!installSource}\n className=\"px-4 py-2 text-sm rounded bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50 flex items-center gap-1.5\"\n >\n <Download className=\"size-4\" /> Install\n </button>\n </div>\n <p className=\"text-[10px] text-text-tertiary mt-1.5\">\n Use <code className=\"px-1 py-0.5 rounded bg-bg-elevated\">--force</code> to overwrite\n existing installations\n </p>\n </div>\n </div>\n )}\n\n {view === 'settings' && (\n <div className=\"space-y-4\">\n <div>\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider mb-2\">\n {tr('vibecontrols.agentManager.bridle.configuration', 'Configuration')}\n </h4>\n <div className=\"space-y-3\">\n <div>\n <label\n htmlFor=\"bridleconfigpanel-4\"\n className=\"block text-xs font-medium text-text-secondary mb-1\"\n >\n Key\n </label>\n <input\n id=\"bridleconfigpanel-4\"\n aria-label=\"e.g., editor, default_harness, profile_marker\"\n type=\"text\"\n value={configKey}\n onChange={(e) => setConfigKey(e.target.value)}\n placeholder=\"e.g., editor, default_harness, profile_marker\"\n className=\"w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong\"\n />\n </div>\n <div>\n <label\n htmlFor=\"bridleconfigpanel-3\"\n className=\"block text-xs font-medium text-text-secondary mb-1\"\n >\n Value\n </label>\n <input\n id=\"bridleconfigpanel-3\"\n aria-label=\"value\"\n type=\"text\"\n value={configValue}\n onChange={(e) => setConfigValue(e.target.value)}\n placeholder=\"value\"\n className=\"w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong\"\n />\n </div>\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => showCommand(`bridle config get ${configKey}`)}\n disabled={!configKey}\n className=\"px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated disabled:opacity-50\"\n >\n Get\n </button>\n <button\n type=\"button\"\n onClick={() => showCommand(`bridle config set ${configKey} ${configValue}`)}\n disabled={!configKey || !configValue}\n className=\"px-3 py-1.5 text-xs rounded bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover disabled:opacity-50\"\n >\n Set\n </button>\n </div>\n </div>\n </div>\n\n <div>\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider mb-2\">\n {tr(\n 'vibecontrols.agentManager.bridle.availableConfigKeys',\n 'Available Config Keys'\n )}\n </h4>\n <div className=\"space-y-1 text-xs text-text-secondary\">\n <div className=\"flex justify-between px-2 py-1 rounded bg-bg-surface\">\n <code>profile_marker</code>\n <span>Enable debug marker files</span>\n </div>\n <div className=\"flex justify-between px-2 py-1 rounded bg-bg-surface\">\n <code>editor</code>\n <span>Default text editor</span>\n </div>\n <div className=\"flex justify-between px-2 py-1 rounded bg-bg-surface\">\n <code>tui.view</code>\n <span>Initial TUI view</span>\n </div>\n <div className=\"flex justify-between px-2 py-1 rounded bg-bg-surface\">\n <code>default_harness</code>\n <span>Startup harness tab</span>\n </div>\n </div>\n </div>\n </div>\n )}\n\n {/* Output */}\n {output && (\n <div className=\"mt-4 border-t border-border-default pt-3\">\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"text-xs font-semibold text-text-secondary uppercase tracking-wider\">\n {tr('vibecontrols.agentManager.bridle.command', 'Command')}\n </h4>\n <button\n type=\"button\"\n onClick={() => setOutput('')}\n className=\"text-[10px] text-text-tertiary hover:text-text-secondary\"\n >\n {tr('vibecontrols.agentManager.bridle.clear', 'Clear')}\n </button>\n </div>\n <pre className=\"p-3 rounded-md bg-bg-sunken text-text-primary text-xs font-mono whitespace-pre-wrap border border-border-default\">\n {output}\n </pre>\n <p className=\"text-[10px] text-text-tertiary mt-1 flex items-center gap-1\">\n {copiedCmd ? (\n <>\n <Check className=\"size-3 text-status-success-text\" />{' '}\n {tr('vibecontrols.agentManager.bridle.copiedToClipboard', 'Copied to clipboard')}\n </>\n ) : (\n tr('vibecontrols.agentManager.bridle.commandCopied', 'Command copied to clipboard')\n )}\n </p>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -57,7 +57,7 @@ var p = [t, ...n], m = ({ open: t, agentId: n, onClose: m }) => {
57
57
  children: /* @__PURE__ */ d(l, { className: "size-4 text-text-secondary" })
58
58
  })]
59
59
  }), n ? /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ f("div", {
60
- className: "mb-4 flex items-center gap-2 rounded-md border border-border-default bg-bg-sunken px-3 py-1.5 focus-within:border-action-primary-bg/40",
60
+ className: "mb-4 flex items-center gap-2 rounded-md border border-border-default bg-bg-sunken px-3 py-1.5 focus-within:border-[var(--color-accent-soft)]",
61
61
  children: [
62
62
  /* @__PURE__ */ d(c, { className: "size-3.5 text-text-tertiary shrink-0" }),
63
63
  /* @__PURE__ */ d("input", {
@@ -1 +1 @@
1
- {"version":3,"file":"PluginInstallModal.js","names":[],"sources":["../../../src/components/agent-manager/PluginInstallModal.tsx"],"sourcesContent":["/**\n * PluginInstallModal — install / remove agent plugins from the Agent\n * Manager chat-pane header on /vibecontrols/ai.\n *\n * Lets operators add or remove a provider plugin (claude / codex /\n * gemini / opencode) at any time without leaving the conversation.\n * Wraps the same `PluginHarnessPicker` the AI page uses; the modal is\n * gated on agent connectivity inside the picker itself.\n */\n\nimport { useEffect, useMemo, useState, type FC } from 'react';\nimport { Search, X } from 'lucide-react';\nimport { PluginHarnessPicker } from '@/components/ai/PluginHarnessPicker';\nimport { AI_CORE_PACKAGE, AI_PROVIDER_PACKAGES, getPluginMeta } from '@/constants/pluginCatalog';\nimport { useTr } from '../../shared/hooks/useTr';\n\n// Orchestrator + every supported provider so users can install/remove\n// any of them from the chat window — claude/codex/gemini/opencode plus\n// the AI core itself in case the operator needs to reinstall it.\nconst INSTALLABLE_PACKAGES: readonly string[] = [AI_CORE_PACKAGE, ...AI_PROVIDER_PACKAGES];\n\nexport interface PluginInstallModalProps {\n open: boolean;\n agentId: string | null;\n onClose: () => void;\n}\n\nexport const PluginInstallModal: FC<PluginInstallModalProps> = ({ open, agentId, onClose }) => {\n const tr = useTr();\n const [search, setSearch] = useState('');\n\n // Esc-to-close so the modal feels native.\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [open, onClose]);\n\n // Reset search whenever the modal closes so a fresh open starts clean.\n useEffect(() => {\n if (!open) setSearch('');\n }, [open]);\n\n // Substring filter — case-insensitive, matches displayName,\n // description, OR raw package name. Empty query → full list.\n const filteredPackages = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return INSTALLABLE_PACKAGES;\n return INSTALLABLE_PACKAGES.filter((pkg) => {\n const meta = getPluginMeta(pkg);\n const haystack = [pkg, meta.displayName, meta.description].join(' ').toLowerCase();\n return haystack.includes(q);\n });\n }, [search]);\n\n if (!open) return null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"agent-manager-plugin-install-title\"\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n data-testid=\"agent-manager-plugin-install-modal\"\n >\n <button\n type=\"button\"\n aria-label={tr('vibecontrols.agentManager.installModal.dismiss', 'Dismiss')}\n className=\"absolute inset-0 bg-bg-overlay/60 backdrop-blur-sm\"\n onClick={onClose}\n />\n <div className=\"relative z-10 w-full max-w-3xl max-h-[85vh] overflow-y-auto rounded-lg border border-border-default bg-bg-surface p-6 shadow-xl\">\n <div className=\"flex items-start justify-between gap-4 mb-4\">\n <div>\n <h2\n id=\"agent-manager-plugin-install-title\"\n className=\"text-lg font-semibold text-text-primary\"\n >\n {tr('vibecontrols.agentManager.installModal.title', 'Manage AI providers')}\n </h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {tr(\n 'vibecontrols.agentManager.installModal.description',\n 'Install or remove provider plugins (Claude, Codex, Gemini, OpenCode) on the connected agent. Changes take effect immediately for new messages.'\n )}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md p-1 hover:bg-bg-sunken transition-colors\"\n aria-label={tr('vibecontrols.agentManager.installModal.close', 'Close')}\n >\n <X className=\"size-4 text-text-secondary\" />\n </button>\n </div>\n\n {agentId ? (\n <>\n {/* Inline search filter — keeps the modal scannable as the\n supported-provider list grows. Searches displayName,\n description, and the raw package name. */}\n <div className=\"mb-4 flex items-center gap-2 rounded-md border border-border-default bg-bg-sunken px-3 py-1.5 focus-within:border-action-primary-bg/40\">\n <Search className=\"size-3.5 text-text-tertiary shrink-0\" />\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder={tr(\n 'vibecontrols.agentManager.installModal.searchPlaceholder',\n 'Search providers (Claude, Codex, Gemini, OpenCode…)'\n )}\n aria-label={tr(\n 'vibecontrols.agentManager.installModal.searchAria',\n 'Filter AI providers'\n )}\n data-testid=\"agent-manager-plugin-install-search\"\n className=\"flex-1 bg-transparent text-sm text-text-primary placeholder:text-text-tertiary focus:outline-none\"\n />\n {search && (\n <button\n type=\"button\"\n onClick={() => setSearch('')}\n className=\"rounded p-0.5 text-text-tertiary hover:bg-bg-elevated\"\n aria-label={tr(\n 'vibecontrols.agentManager.installModal.clearSearch',\n 'Clear search'\n )}\n >\n <X className=\"size-3\" />\n </button>\n )}\n </div>\n\n {filteredPackages.length === 0 ? (\n <div className=\"rounded-md border border-border-default bg-bg-sunken px-3 py-6 text-center text-sm text-text-secondary\">\n {tr(\n 'vibecontrols.agentManager.installModal.noMatches',\n 'No providers match your search.'\n )}\n </div>\n ) : (\n <PluginHarnessPicker\n agentId={agentId}\n packages={filteredPackages}\n title={tr(\n 'vibecontrols.agentManager.installModal.providersHeading',\n 'Available providers'\n )}\n description={tr(\n 'vibecontrols.agentManager.installModal.providersHint',\n 'Click Install to add a provider, or Remove to uninstall one.'\n )}\n />\n )}\n </>\n ) : (\n <div className=\"rounded-md border border-border-default bg-bg-sunken px-3 py-4 text-sm text-text-secondary\">\n {tr(\n 'vibecontrols.agentManager.installModal.noAgent',\n 'Connect an agent in Targets & Agents before installing AI providers.'\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;AAmBA,IAAM,IAA0C,CAAC,GAAiB,GAAG,EAAqB,EAQ7E,KAAmD,EAAE,SAAM,YAAS,iBAAc;CAC7F,IAAM,IAAK,GAAO,EACZ,CAAC,GAAQ,KAAa,EAAS,GAAG;AAaxC,CAVA,QAAgB;AACd,MAAI,CAAC,EAAM;EACX,IAAM,KAAS,MAAqB;AAClC,GAAI,EAAE,QAAQ,YAAU,GAAS;;AAGnC,SADA,OAAO,iBAAiB,WAAW,EAAM,QAC5B,OAAO,oBAAoB,WAAW,EAAM;IACxD,CAAC,GAAM,EAAQ,CAAC,EAGnB,QAAgB;AACd,EAAK,KAAM,EAAU,GAAG;IACvB,CAAC,EAAK,CAAC;CAIV,IAAM,IAAmB,QAAc;EACrC,IAAM,IAAI,EAAO,MAAM,CAAC,aAAa;AAErC,SADK,IACE,EAAqB,QAAQ,MAAQ;GAC1C,IAAM,IAAO,EAAc,EAAI;AAE/B,UADiB;IAAC;IAAK,EAAK;IAAa,EAAK;IAAY,CAAC,KAAK,IAAI,CAAC,aAAa,CAClE,SAAS,EAAE;IAC3B,GALa;IAMd,CAAC,EAAO,CAAC;AAIZ,QAFK,IAGH,kBAAC,OAAD;EACE,MAAK;EACL,cAAW;EACX,mBAAgB;EAChB,WAAU;EACV,eAAY;YALd,CAOE,kBAAC,UAAD;GACE,MAAK;GACL,cAAY,EAAG,kDAAkD,UAAU;GAC3E,WAAU;GACV,SAAS;GACT,CAAA,EACF,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KACE,IAAG;KACH,WAAU;eAET,EAAG,gDAAgD,sBAAsB;KACvE,CAAA,EACL,kBAAC,KAAD;KAAG,WAAU;eACV,EACC,sDACA,iJACD;KACC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,WAAU;KACV,cAAY,EAAG,gDAAgD,QAAQ;eAEvE,kBAAC,GAAD,EAAG,WAAU,8BAA+B,CAAA;KACrC,CAAA,CACL;OAEL,IACC,kBAAA,GAAA,EAAA,UAAA,CAIE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAQ,WAAU,wCAAyC,CAAA;KAC3D,kBAAC,SAAD;MACE,MAAK;MACL,OAAO;MACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAM;MAC1C,aAAa,EACX,4DACA,sDACD;MACD,cAAY,EACV,qDACA,sBACD;MACD,eAAY;MACZ,WAAU;MACV,CAAA;KACD,KACC,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAU,GAAG;MAC5B,WAAU;MACV,cAAY,EACV,sDACA,eACD;gBAED,kBAAC,GAAD,EAAG,WAAU,UAAW,CAAA;MACjB,CAAA;KAEP;OAEL,EAAiB,WAAW,IAC3B,kBAAC,OAAD;IAAK,WAAU;cACZ,EACC,oDACA,kCACD;IACG,CAAA,GAEN,kBAAC,GAAD;IACW;IACT,UAAU;IACV,OAAO,EACL,2DACA,sBACD;IACD,aAAa,EACX,wDACA,+DACD;IACD,CAAA,CAEH,EAAA,CAAA,GAEH,kBAAC,OAAD;IAAK,WAAU;cACZ,EACC,kDACA,uEACD;IACG,CAAA,CAEJ;KACF;MA9GU"}
1
+ {"version":3,"file":"PluginInstallModal.js","names":[],"sources":["../../../src/components/agent-manager/PluginInstallModal.tsx"],"sourcesContent":["/**\n * PluginInstallModal — install / remove agent plugins from the Agent\n * Manager chat-pane header on /vibecontrols/ai.\n *\n * Lets operators add or remove a provider plugin (claude / codex /\n * gemini / opencode) at any time without leaving the conversation.\n * Wraps the same `PluginHarnessPicker` the AI page uses; the modal is\n * gated on agent connectivity inside the picker itself.\n */\n\nimport { useEffect, useMemo, useState, type FC } from 'react';\nimport { Search, X } from 'lucide-react';\nimport { PluginHarnessPicker } from '@/components/ai/PluginHarnessPicker';\nimport { AI_CORE_PACKAGE, AI_PROVIDER_PACKAGES, getPluginMeta } from '@/constants/pluginCatalog';\nimport { useTr } from '../../shared/hooks/useTr';\n\n// Orchestrator + every supported provider so users can install/remove\n// any of them from the chat window — claude/codex/gemini/opencode plus\n// the AI core itself in case the operator needs to reinstall it.\nconst INSTALLABLE_PACKAGES: readonly string[] = [AI_CORE_PACKAGE, ...AI_PROVIDER_PACKAGES];\n\nexport interface PluginInstallModalProps {\n open: boolean;\n agentId: string | null;\n onClose: () => void;\n}\n\nexport const PluginInstallModal: FC<PluginInstallModalProps> = ({ open, agentId, onClose }) => {\n const tr = useTr();\n const [search, setSearch] = useState('');\n\n // Esc-to-close so the modal feels native.\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [open, onClose]);\n\n // Reset search whenever the modal closes so a fresh open starts clean.\n useEffect(() => {\n if (!open) setSearch('');\n }, [open]);\n\n // Substring filter — case-insensitive, matches displayName,\n // description, OR raw package name. Empty query → full list.\n const filteredPackages = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return INSTALLABLE_PACKAGES;\n return INSTALLABLE_PACKAGES.filter((pkg) => {\n const meta = getPluginMeta(pkg);\n const haystack = [pkg, meta.displayName, meta.description].join(' ').toLowerCase();\n return haystack.includes(q);\n });\n }, [search]);\n\n if (!open) return null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"agent-manager-plugin-install-title\"\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n data-testid=\"agent-manager-plugin-install-modal\"\n >\n <button\n type=\"button\"\n aria-label={tr('vibecontrols.agentManager.installModal.dismiss', 'Dismiss')}\n className=\"absolute inset-0 bg-bg-overlay/60 backdrop-blur-sm\"\n onClick={onClose}\n />\n <div className=\"relative z-10 w-full max-w-3xl max-h-[85vh] overflow-y-auto rounded-lg border border-border-default bg-bg-surface p-6 shadow-xl\">\n <div className=\"flex items-start justify-between gap-4 mb-4\">\n <div>\n <h2\n id=\"agent-manager-plugin-install-title\"\n className=\"text-lg font-semibold text-text-primary\"\n >\n {tr('vibecontrols.agentManager.installModal.title', 'Manage AI providers')}\n </h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {tr(\n 'vibecontrols.agentManager.installModal.description',\n 'Install or remove provider plugins (Claude, Codex, Gemini, OpenCode) on the connected agent. Changes take effect immediately for new messages.'\n )}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md p-1 hover:bg-bg-sunken transition-colors\"\n aria-label={tr('vibecontrols.agentManager.installModal.close', 'Close')}\n >\n <X className=\"size-4 text-text-secondary\" />\n </button>\n </div>\n\n {agentId ? (\n <>\n {/* Inline search filter — keeps the modal scannable as the\n supported-provider list grows. Searches displayName,\n description, and the raw package name. */}\n <div className=\"mb-4 flex items-center gap-2 rounded-md border border-border-default bg-bg-sunken px-3 py-1.5 focus-within:border-[var(--color-accent-soft)]\">\n <Search className=\"size-3.5 text-text-tertiary shrink-0\" />\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder={tr(\n 'vibecontrols.agentManager.installModal.searchPlaceholder',\n 'Search providers (Claude, Codex, Gemini, OpenCode…)'\n )}\n aria-label={tr(\n 'vibecontrols.agentManager.installModal.searchAria',\n 'Filter AI providers'\n )}\n data-testid=\"agent-manager-plugin-install-search\"\n className=\"flex-1 bg-transparent text-sm text-text-primary placeholder:text-text-tertiary focus:outline-none\"\n />\n {search && (\n <button\n type=\"button\"\n onClick={() => setSearch('')}\n className=\"rounded p-0.5 text-text-tertiary hover:bg-bg-elevated\"\n aria-label={tr(\n 'vibecontrols.agentManager.installModal.clearSearch',\n 'Clear search'\n )}\n >\n <X className=\"size-3\" />\n </button>\n )}\n </div>\n\n {filteredPackages.length === 0 ? (\n <div className=\"rounded-md border border-border-default bg-bg-sunken px-3 py-6 text-center text-sm text-text-secondary\">\n {tr(\n 'vibecontrols.agentManager.installModal.noMatches',\n 'No providers match your search.'\n )}\n </div>\n ) : (\n <PluginHarnessPicker\n agentId={agentId}\n packages={filteredPackages}\n title={tr(\n 'vibecontrols.agentManager.installModal.providersHeading',\n 'Available providers'\n )}\n description={tr(\n 'vibecontrols.agentManager.installModal.providersHint',\n 'Click Install to add a provider, or Remove to uninstall one.'\n )}\n />\n )}\n </>\n ) : (\n <div className=\"rounded-md border border-border-default bg-bg-sunken px-3 py-4 text-sm text-text-secondary\">\n {tr(\n 'vibecontrols.agentManager.installModal.noAgent',\n 'Connect an agent in Targets & Agents before installing AI providers.'\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;AAmBA,IAAM,IAA0C,CAAC,GAAiB,GAAG,EAAqB,EAQ7E,KAAmD,EAAE,SAAM,YAAS,iBAAc;CAC7F,IAAM,IAAK,GAAO,EACZ,CAAC,GAAQ,KAAa,EAAS,GAAG;AAaxC,CAVA,QAAgB;AACd,MAAI,CAAC,EAAM;EACX,IAAM,KAAS,MAAqB;AAClC,GAAI,EAAE,QAAQ,YAAU,GAAS;;AAGnC,SADA,OAAO,iBAAiB,WAAW,EAAM,QAC5B,OAAO,oBAAoB,WAAW,EAAM;IACxD,CAAC,GAAM,EAAQ,CAAC,EAGnB,QAAgB;AACd,EAAK,KAAM,EAAU,GAAG;IACvB,CAAC,EAAK,CAAC;CAIV,IAAM,IAAmB,QAAc;EACrC,IAAM,IAAI,EAAO,MAAM,CAAC,aAAa;AAErC,SADK,IACE,EAAqB,QAAQ,MAAQ;GAC1C,IAAM,IAAO,EAAc,EAAI;AAE/B,UADiB;IAAC;IAAK,EAAK;IAAa,EAAK;IAAY,CAAC,KAAK,IAAI,CAAC,aAAa,CAClE,SAAS,EAAE;IAC3B,GALa;IAMd,CAAC,EAAO,CAAC;AAIZ,QAFK,IAGH,kBAAC,OAAD;EACE,MAAK;EACL,cAAW;EACX,mBAAgB;EAChB,WAAU;EACV,eAAY;YALd,CAOE,kBAAC,UAAD;GACE,MAAK;GACL,cAAY,EAAG,kDAAkD,UAAU;GAC3E,WAAU;GACV,SAAS;GACT,CAAA,EACF,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KACE,IAAG;KACH,WAAU;eAET,EAAG,gDAAgD,sBAAsB;KACvE,CAAA,EACL,kBAAC,KAAD;KAAG,WAAU;eACV,EACC,sDACA,iJACD;KACC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,WAAU;KACV,cAAY,EAAG,gDAAgD,QAAQ;eAEvE,kBAAC,GAAD,EAAG,WAAU,8BAA+B,CAAA;KACrC,CAAA,CACL;OAEL,IACC,kBAAA,GAAA,EAAA,UAAA,CAIE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAQ,WAAU,wCAAyC,CAAA;KAC3D,kBAAC,SAAD;MACE,MAAK;MACL,OAAO;MACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAM;MAC1C,aAAa,EACX,4DACA,sDACD;MACD,cAAY,EACV,qDACA,sBACD;MACD,eAAY;MACZ,WAAU;MACV,CAAA;KACD,KACC,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAU,GAAG;MAC5B,WAAU;MACV,cAAY,EACV,sDACA,eACD;gBAED,kBAAC,GAAD,EAAG,WAAU,UAAW,CAAA;MACjB,CAAA;KAEP;OAEL,EAAiB,WAAW,IAC3B,kBAAC,OAAD;IAAK,WAAU;cACZ,EACC,oDACA,kCACD;IACG,CAAA,GAEN,kBAAC,GAAD;IACW;IACT,UAAU;IACV,OAAO,EACL,2DACA,sBACD;IACD,aAAa,EACX,wDACA,+DACD;IACD,CAAA,CAEH,EAAA,CAAA,GAEH,kBAAC,OAAD;IAAK,WAAU;cACZ,EACC,kDACA,uEACD;IACG,CAAA,CAEJ;KACF;MA9GU"}
@@ -114,7 +114,7 @@ function y({ agentId: d }) {
114
114
  })]
115
115
  }),
116
116
  A && /* @__PURE__ */ p("div", {
117
- className: "px-4 py-2 bg-status-error-bg/30 border-b border-status-error-text/20 text-sm text-status-error-text",
117
+ className: "px-4 py-2 bg-status-error-bg-subtle border-b border-status-error-border text-sm text-status-error-text",
118
118
  children: A
119
119
  }),
120
120
  w && /* @__PURE__ */ m("div", {
@@ -186,7 +186,7 @@ function y({ agentId: d }) {
186
186
  children: y.map((e) => {
187
187
  let n = e.name === b, r = t(e);
188
188
  return /* @__PURE__ */ m("div", {
189
- className: `p-4 flex items-center justify-between gap-4 ${n ? "bg-action-primary-bg/5" : ""}`,
189
+ className: `p-4 flex items-center justify-between gap-4 ${n ? "bg-[var(--color-accent-soft)]" : ""}`,
190
190
  children: [/* @__PURE__ */ m("div", {
191
191
  className: "flex items-center gap-3 min-w-0",
192
192
  children: [/* @__PURE__ */ p("span", {
@@ -202,11 +202,11 @@ function y({ agentId: d }) {
202
202
  children: e.name
203
203
  }),
204
204
  e.isDefault && /* @__PURE__ */ m("span", {
205
- className: "inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[10px] uppercase tracking-wide bg-action-primary-bg/10 text-action-primary-bg rounded",
205
+ className: "inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[10px] uppercase tracking-wide bg-[var(--color-accent-soft)] text-text-primary rounded",
206
206
  children: [/* @__PURE__ */ p(c, { className: "size-3" }), "Default"]
207
207
  }),
208
208
  n && /* @__PURE__ */ p("span", {
209
- className: "px-1.5 py-0.5 text-[10px] uppercase tracking-wide bg-status-success-bg/40 text-status-success-text rounded",
209
+ className: "px-1.5 py-0.5 text-[10px] uppercase tracking-wide bg-status-success-bg-subtle text-status-success-text rounded",
210
210
  children: "Active"
211
211
  })
212
212
  ]
@@ -242,7 +242,7 @@ function y({ agentId: d }) {
242
242
  disabled: V || e.isDefault,
243
243
  title: e.isDefault ? "Cannot delete the default profile" : "Delete",
244
244
  onClick: () => void z(e),
245
- className: "inline-flex items-center gap-1 px-2 py-1 text-xs text-status-error-text hover:bg-status-error-bg/30 border border-status-error-text/20 rounded disabled:opacity-50",
245
+ className: "inline-flex items-center gap-1 px-2 py-1 text-xs text-status-error-text hover:bg-status-error-bg-subtle border border-status-error-border rounded disabled:opacity-50",
246
246
  children: [/* @__PURE__ */ p(l, { className: "size-3" }), "Delete"]
247
247
  })
248
248
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"ProfilesPanel.js","names":[],"sources":["../../../src/components/agent-manager/ProfilesPanel.tsx"],"sourcesContent":["/**\n * ProfilesPanel — Phase 5B (multi-profile-per-daemon).\n *\n * Mounted on AgentDetailsPage as the \"Profiles\" tab. Lists every\n * `AgentProfile` row for the current agent and exposes full CRUDL:\n * - List with status indicators\n * - Create (autofilled name \"default\" but editable)\n * - Delete\n * - Set-default\n *\n * Apollo `gql` documents are inlined so the component compiles cleanly\n * before Phase 5A (svc) publishes the AgentProfile schema to Hive.\n */\n\nimport { useCallback, useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { CheckCircle2, Loader2, Plus, Star, Trash2, X } from 'lucide-react';\nimport { Card } from '@/components/shared';\nimport {\n useActiveAgentProfile,\n isUsableProfile,\n type AgentProfile,\n} from '@/hooks/useActiveAgentProfile';\n\ninterface ProfilesPanelProps {\n agentId: string;\n}\n\ninterface CreateAgentProfileInput {\n agentId: string;\n name: string;\n port?: number | null;\n}\n\ninterface CreateProfileData {\n createVibecontrolsAgentProfile: Pick<AgentProfile, 'id' | 'name' | 'isDefault' | 'status'>;\n}\n\ninterface CreateProfileVars {\n input: CreateAgentProfileInput;\n}\n\ninterface DeleteProfileData {\n deleteVibecontrolsAgentProfile: boolean;\n}\n\ninterface DeleteProfileVars {\n id: string;\n}\n\ninterface SetDefaultProfileData {\n setDefaultVibecontrolsAgentProfile: Pick<AgentProfile, 'id' | 'isDefault'>;\n}\n\ninterface SetDefaultProfileVars {\n id: string;\n}\n\nconst CREATE_PROFILE_MUTATION = gql`\n mutation CreateVibecontrolsAgentProfile($input: CreateVibecontrolsAgentProfileInput!) {\n createVibecontrolsAgentProfile(input: $input) {\n id\n name\n isDefault\n status\n }\n }\n`;\n\nconst DELETE_PROFILE_MUTATION = gql`\n mutation DeleteVibecontrolsAgentProfile($id: ID!) {\n deleteVibecontrolsAgentProfile(id: $id)\n }\n`;\n\nconst SET_DEFAULT_PROFILE_MUTATION = gql`\n mutation SetDefaultVibecontrolsAgentProfile($id: ID!) {\n setDefaultVibecontrolsAgentProfile(id: $id) {\n id\n isDefault\n }\n }\n`;\n\nfunction statusDot(status: string | null): string {\n const s = (status ?? '').toLowerCase();\n if (s === 'running' || s === 'active' || s === 'healthy') return 'bg-status-success-text';\n if (s === 'stopped' || s === 'inactive') return 'bg-text-placeholder';\n if (s === 'error' || s === 'failed') return 'bg-status-error-text';\n return 'bg-status-warning-text';\n}\n\nexport function ProfilesPanel({ agentId }: ProfilesPanelProps) {\n const { profiles, active, setActive, loading, refetch } = useActiveAgentProfile(agentId);\n\n const [showCreate, setShowCreate] = useState(false);\n const [newName, setNewName] = useState('default');\n const [newPort, setNewPort] = useState<string>('');\n const [actionError, setActionError] = useState<string | null>(null);\n\n const [createProfile, { loading: creating }] = useMutation<CreateProfileData, CreateProfileVars>(\n CREATE_PROFILE_MUTATION\n );\n\n const [deleteProfile, { loading: deleting }] = useMutation<DeleteProfileData, DeleteProfileVars>(\n DELETE_PROFILE_MUTATION\n );\n\n const [setDefaultProfile, { loading: settingDefault }] = useMutation<\n SetDefaultProfileData,\n SetDefaultProfileVars\n >(SET_DEFAULT_PROFILE_MUTATION);\n\n const handleCreate = useCallback(async () => {\n setActionError(null);\n const trimmedName = newName.trim();\n if (!trimmedName) {\n setActionError('Profile name is required');\n return;\n }\n const portNum = newPort.trim() ? Number(newPort.trim()) : null;\n if (newPort.trim() && (Number.isNaN(portNum) || portNum === null || portNum <= 0)) {\n setActionError('Port must be a positive number');\n return;\n }\n try {\n await createProfile({\n variables: {\n input: { agentId, name: trimmedName, port: portNum },\n },\n });\n } catch (err) {\n setActionError(err instanceof Error ? err.message : 'Failed to create profile');\n return;\n }\n setShowCreate(false);\n setNewName('default');\n setNewPort('');\n // The mutation already succeeded — refresh the list off the same observable\n // the panel renders from so the new profile shows without a manual\n // \"Refresh\". refetch() is non-throwing, so a refresh hiccup can never\n // surface as a \"Failed to create\" error; the list re-syncs on the next action.\n await refetch();\n }, [agentId, createProfile, newName, newPort, refetch]);\n\n const handleDelete = useCallback(\n async (profile: AgentProfile) => {\n setActionError(null);\n if (!window.confirm(`Delete profile \"${profile.name}\"? This cannot be undone.`)) {\n return;\n }\n try {\n await deleteProfile({ variables: { id: profile.id } });\n } catch (err) {\n setActionError(err instanceof Error ? err.message : 'Failed to delete profile');\n return;\n }\n // Refresh after a confirmed delete; refetch() is non-throwing so a\n // network hiccup can't masquerade as a failed delete (see handleCreate).\n await refetch();\n },\n [deleteProfile, refetch]\n );\n\n const handleSetDefault = useCallback(\n async (profile: AgentProfile) => {\n setActionError(null);\n try {\n await setDefaultProfile({ variables: { id: profile.id } });\n } catch (err) {\n setActionError(err instanceof Error ? err.message : 'Failed to set default profile');\n return;\n }\n // Refresh after a confirmed change; refetch() is non-throwing so a\n // network hiccup can't masquerade as a failed update (see handleCreate).\n await refetch();\n },\n [setDefaultProfile, refetch]\n );\n\n const busy = creating || deleting || settingDefault;\n\n return (\n <Card>\n <div className=\"p-4 border-b border-border-default flex items-center justify-between\">\n <div>\n <h3 className=\"font-semibold text-text-primary\">Profiles</h3>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n Each profile runs an isolated CLI on this agent. Active:{' '}\n <code className=\"font-mono text-text-primary\">{active}</code>\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n // Fire-and-forget from a click handler: refetch() is non-throwing,\n // so ignoring the returned promise can't leak an unhandled rejection.\n onClick={() => void refetch()}\n className=\"px-2 py-1 text-xs text-text-secondary hover:text-text-primary\"\n >\n Refresh\n </button>\n <button\n type=\"button\"\n onClick={() => setShowCreate((v) => !v)}\n 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:opacity-90\"\n >\n <Plus className=\"size-4\" />\n New profile\n </button>\n </div>\n </div>\n\n {actionError && (\n <div className=\"px-4 py-2 bg-status-error-bg/30 border-b border-status-error-text/20 text-sm text-status-error-text\">\n {actionError}\n </div>\n )}\n\n {showCreate && (\n <div className=\"p-4 border-b border-border-default bg-bg-sunken/40 space-y-3\">\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label\n htmlFor=\"profilespanel-2\"\n className=\"block text-xs font-medium text-text-secondary mb-1\"\n >\n Profile name\n </label>\n <input\n id=\"profilespanel-2\"\n aria-label=\"default\"\n type=\"text\"\n value={newName}\n onChange={(e) => setNewName(e.target.value)}\n placeholder=\"default\"\n className=\"w-full px-3 py-1.5 text-sm bg-bg-surface border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono\"\n />\n </div>\n <div>\n <label\n htmlFor=\"profilespanel-1\"\n className=\"block text-xs font-medium text-text-secondary mb-1\"\n >\n Port (optional)\n </label>\n <input\n id=\"profilespanel-1\"\n aria-label=\"auto\"\n type=\"number\"\n value={newPort}\n onChange={(e) => setNewPort(e.target.value)}\n placeholder=\"auto\"\n className=\"w-full px-3 py-1.5 text-sm bg-bg-surface border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono\"\n />\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n disabled={creating}\n onClick={() => void handleCreate()}\n 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:opacity-90 disabled:opacity-50\"\n >\n {creating ? (\n <Loader2 className=\"size-3.5 animate-spin\" />\n ) : (\n <CheckCircle2 className=\"size-3.5\" />\n )}\n Create\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setShowCreate(false);\n setActionError(null);\n }}\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-sm text-text-secondary hover:text-text-primary\"\n >\n <X className=\"size-3.5\" />\n Cancel\n </button>\n </div>\n </div>\n )}\n\n {loading && profiles.length === 0 ? (\n <div className=\"p-6 text-center text-text-secondary\">\n <Loader2 className=\"size-5 mx-auto mb-2 animate-spin\" />\n Loading profiles…\n </div>\n ) : profiles.length === 0 ? (\n <div className=\"p-6 text-center text-text-secondary\">\n <p>No profiles configured yet.</p>\n <p className=\"text-xs mt-1\">\n The agent will fall back to the implicit <code className=\"font-mono\">default</code>{' '}\n profile until you create one.\n </p>\n </div>\n ) : (\n <div className=\"divide-y divide-border-default\">\n {profiles.map((profile) => {\n const isActive = profile.name === active;\n // A never-started (awaiting-config) profile can't be the active\n // one — selecting it would just bounce back to a usable profile.\n // Disable \"Use\" and explain why instead of silently reverting.\n const usable = isUsableProfile(profile);\n return (\n <div\n key={profile.id}\n className={`p-4 flex items-center justify-between gap-4 ${\n isActive ? 'bg-action-primary-bg/5' : ''\n }`}\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <span\n className={`size-2 rounded-full flex-shrink-0 ${statusDot(profile.status)}`}\n aria-hidden\n />\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <code className=\"font-mono font-medium text-text-primary truncate\">\n {profile.name}\n </code>\n {profile.isDefault && (\n <span className=\"inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[10px] uppercase tracking-wide bg-action-primary-bg/10 text-action-primary-bg rounded\">\n <Star className=\"size-3\" />\n Default\n </span>\n )}\n {isActive && (\n <span className=\"px-1.5 py-0.5 text-[10px] uppercase tracking-wide bg-status-success-bg/40 text-status-success-text rounded\">\n Active\n </span>\n )}\n </div>\n <p className=\"text-xs text-text-secondary mt-0.5 truncate\">\n {profile.status ?? 'unknown'}\n {profile.port ? ` · port ${profile.port}` : ''}\n {profile.tunnelUrl ? ` · ${profile.tunnelUrl}` : ''}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n {!isActive && (\n <button\n type=\"button\"\n disabled={!usable}\n title={\n usable\n ? 'Make this the active profile'\n : \"This profile hasn't been started yet (awaiting config), so it can't be the active profile.\"\n }\n onClick={() => setActive(profile.name)}\n className=\"px-2 py-1 text-xs text-text-secondary hover:text-text-primary border border-border-default rounded disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Use\n </button>\n )}\n {!profile.isDefault && (\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void handleSetDefault(profile)}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs text-text-secondary hover:text-text-primary border border-border-default rounded disabled:opacity-50\"\n >\n <Star className=\"size-3\" />\n Set default\n </button>\n )}\n <button\n type=\"button\"\n disabled={busy || profile.isDefault}\n title={profile.isDefault ? 'Cannot delete the default profile' : 'Delete'}\n onClick={() => void handleDelete(profile)}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs text-status-error-text hover:bg-status-error-bg/30 border border-status-error-text/20 rounded disabled:opacity-50\"\n >\n <Trash2 className=\"size-3\" />\n Delete\n </button>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </Card>\n );\n}\n"],"mappings":";;;;;;;;;AA2DA,IAAM,IAA0B,CAAG;;;;;;;;;GAW7B,IAA0B,CAAG;;;;GAM7B,IAA+B,CAAG;;;;;;;;AASxC,SAAS,EAAU,GAA+B;CAChD,IAAM,KAAK,KAAU,IAAI,aAAa;AAItC,QAHI,MAAM,aAAa,MAAM,YAAY,MAAM,YAAkB,2BAC7D,MAAM,aAAa,MAAM,aAAmB,wBAC5C,MAAM,WAAW,MAAM,WAAiB,yBACrC;;AAGT,SAAgB,EAAc,EAAE,cAA+B;CAC7D,IAAM,EAAE,aAAU,WAAQ,cAAW,YAAS,eAAY,EAAsB,EAAQ,EAElF,CAAC,GAAY,KAAiB,EAAS,GAAM,EAC7C,CAAC,GAAS,KAAc,EAAS,UAAU,EAC3C,CAAC,GAAS,KAAc,EAAiB,GAAG,EAC5C,CAAC,GAAa,KAAkB,EAAwB,KAAK,EAE7D,CAAC,GAAe,EAAE,SAAS,OAAc,EAC7C,EACD,EAEK,CAAC,GAAe,EAAE,SAAS,OAAc,EAC7C,EACD,EAEK,CAAC,GAAmB,EAAE,SAAS,OAAoB,EAGvD,EAA6B,EAEzB,IAAe,EAAY,YAAY;AAC3C,IAAe,KAAK;EACpB,IAAM,IAAc,EAAQ,MAAM;AAClC,MAAI,CAAC,GAAa;AAChB,KAAe,2BAA2B;AAC1C;;EAEF,IAAM,IAAU,EAAQ,MAAM,GAAG,OAAO,EAAQ,MAAM,CAAC,GAAG;AAC1D,MAAI,EAAQ,MAAM,KAAK,OAAO,MAAM,EAAQ,IAAI,MAAY,QAAQ,KAAW,IAAI;AACjF,KAAe,iCAAiC;AAChD;;AAEF,MAAI;AACF,SAAM,EAAc,EAClB,WAAW,EACT,OAAO;IAAE;IAAS,MAAM;IAAa,MAAM;IAAS,EACrD,EACF,CAAC;WACK,GAAK;AACZ,KAAe,aAAe,QAAQ,EAAI,UAAU,2BAA2B;AAC/E;;AASF,EAPA,EAAc,GAAM,EACpB,EAAW,UAAU,EACrB,EAAW,GAAG,EAKd,MAAM,GAAS;IACd;EAAC;EAAS;EAAe;EAAS;EAAS;EAAQ,CAAC,EAEjD,IAAe,EACnB,OAAO,MAA0B;AAC/B,QAAe,KAAK,EACf,OAAO,QAAQ,mBAAmB,EAAQ,KAAK,2BAA2B,EAG/E;OAAI;AACF,UAAM,EAAc,EAAE,WAAW,EAAE,IAAI,EAAQ,IAAI,EAAE,CAAC;YAC/C,GAAK;AACZ,MAAe,aAAe,QAAQ,EAAI,UAAU,2BAA2B;AAC/E;;AAIF,SAAM,GAAS;;IAEjB,CAAC,GAAe,EAAQ,CACzB,EAEK,IAAmB,EACvB,OAAO,MAA0B;AAC/B,IAAe,KAAK;AACpB,MAAI;AACF,SAAM,EAAkB,EAAE,WAAW,EAAE,IAAI,EAAQ,IAAI,EAAE,CAAC;WACnD,GAAK;AACZ,KAAe,aAAe,QAAQ,EAAI,UAAU,gCAAgC;AACpF;;AAIF,QAAM,GAAS;IAEjB,CAAC,GAAmB,EAAQ,CAC7B,EAEK,IAAO,KAAY,KAAY;AAErC,QACE,kBAAC,GAAD,EAAA,UAAA;EACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;cAAkC;IAAa,CAAA,EAC7D,kBAAC,KAAD;IAAG,WAAU;cAAb;KAAkD;KACS;KACzD,kBAAC,QAAD;MAAM,WAAU;gBAA+B;MAAc,CAAA;KAC3D;MACA,EAAA,CAAA,EACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,UAAD;KACE,MAAK;KAGL,eAAe,KAAK,GAAS;KAC7B,WAAU;eACX;KAEQ,CAAA,EACT,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,GAAe,MAAM,CAAC,EAAE;KACvC,WAAU;eAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,EAAA,cAEpB;OACL;MACF;;EAEL,KACC,kBAAC,OAAD;GAAK,WAAU;aACZ;GACG,CAAA;EAGP,KACC,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;KACE,SAAQ;KACR,WAAU;eACX;KAEO,CAAA,EACR,kBAAC,SAAD;KACE,IAAG;KACH,cAAW;KACX,MAAK;KACL,OAAO;KACP,WAAW,MAAM,EAAW,EAAE,OAAO,MAAM;KAC3C,aAAY;KACZ,WAAU;KACV,CAAA,CACE,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;KACE,SAAQ;KACR,WAAU;eACX;KAEO,CAAA,EACR,kBAAC,SAAD;KACE,IAAG;KACH,cAAW;KACX,MAAK;KACL,OAAO;KACP,WAAW,MAAM,EAAW,EAAE,OAAO,MAAM;KAC3C,aAAY;KACZ,WAAU;KACV,CAAA,CACE,EAAA,CAAA,CACF;OACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,eAAe,KAAK,GAAc;KAClC,WAAU;eAJZ,CAMG,IACC,kBAAC,GAAD,EAAS,WAAU,yBAA0B,CAAA,GAE7C,kBAAC,GAAD,EAAc,WAAU,YAAa,CAAA,EACrC,SAEK;QACT,kBAAC,UAAD;KACE,MAAK;KACL,eAAe;AAEb,MADA,EAAc,GAAM,EACpB,EAAe,KAAK;;KAEtB,WAAU;eANZ,CAQE,kBAAC,GAAD,EAAG,WAAU,YAAa,CAAA,EAAA,SAEnB;OACL;MACF;;EAGP,KAAW,EAAS,WAAW,IAC9B,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD,EAAS,WAAU,oCAAqC,CAAA,EAAA,oBAEpD;OACJ,EAAS,WAAW,IACtB,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD,EAAA,UAAG,+BAA+B,CAAA,EAClC,kBAAC,KAAD;IAAG,WAAU;cAAb;KAA4B;KACe,kBAAC,QAAD;MAAM,WAAU;gBAAY;MAAc,CAAA;KAAC;KAAI;KAEtF;MACA;OAEN,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAS,KAAK,MAAY;IACzB,IAAM,IAAW,EAAQ,SAAS,GAI5B,IAAS,EAAgB,EAAQ;AACvC,WACE,kBAAC,OAAD;KAEE,WAAW,+CACT,IAAW,2BAA2B;eAH1C,CAME,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OACE,WAAW,qCAAqC,EAAU,EAAQ,OAAO;OACzE,eAAA;OACA,CAAA,EACF,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAQ;UACJ,CAAA;SACN,EAAQ,aACP,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CACE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,EAAA,UAEtB;;SAER,KACC,kBAAC,QAAD;UAAM,WAAU;oBAA6G;UAEtH,CAAA;SAEL;WACN,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG,EAAQ,UAAU;SAClB,EAAQ,OAAO,WAAW,EAAQ,SAAS;SAC3C,EAAQ,YAAY,MAAM,EAAQ,cAAc;SAC/C;UACA;SACF;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACG,CAAC,KACA,kBAAC,UAAD;QACE,MAAK;QACL,UAAU,CAAC;QACX,OACE,IACI,iCACA;QAEN,eAAe,EAAU,EAAQ,KAAK;QACtC,WAAU;kBACX;QAEQ,CAAA;OAEV,CAAC,EAAQ,aACR,kBAAC,UAAD;QACE,MAAK;QACL,UAAU;QACV,eAAe,KAAK,EAAiB,EAAQ;QAC7C,WAAU;kBAJZ,CAME,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,EAAA,cAEpB;;OAEX,kBAAC,UAAD;QACE,MAAK;QACL,UAAU,KAAQ,EAAQ;QAC1B,OAAO,EAAQ,YAAY,sCAAsC;QACjE,eAAe,KAAK,EAAa,EAAQ;QACzC,WAAU;kBALZ,CAOE,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA,EAAA,SAEtB;;OACL;QACF;OAxEC,EAAQ,GAwET;KAER;GACE,CAAA;EAEH,EAAA,CAAA"}
1
+ {"version":3,"file":"ProfilesPanel.js","names":[],"sources":["../../../src/components/agent-manager/ProfilesPanel.tsx"],"sourcesContent":["/**\n * ProfilesPanel — Phase 5B (multi-profile-per-daemon).\n *\n * Mounted on AgentDetailsPage as the \"Profiles\" tab. Lists every\n * `AgentProfile` row for the current agent and exposes full CRUDL:\n * - List with status indicators\n * - Create (autofilled name \"default\" but editable)\n * - Delete\n * - Set-default\n *\n * Apollo `gql` documents are inlined so the component compiles cleanly\n * before Phase 5A (svc) publishes the AgentProfile schema to Hive.\n */\n\nimport { useCallback, useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { CheckCircle2, Loader2, Plus, Star, Trash2, X } from 'lucide-react';\nimport { Card } from '@/components/shared';\nimport {\n useActiveAgentProfile,\n isUsableProfile,\n type AgentProfile,\n} from '@/hooks/useActiveAgentProfile';\n\ninterface ProfilesPanelProps {\n agentId: string;\n}\n\ninterface CreateAgentProfileInput {\n agentId: string;\n name: string;\n port?: number | null;\n}\n\ninterface CreateProfileData {\n createVibecontrolsAgentProfile: Pick<AgentProfile, 'id' | 'name' | 'isDefault' | 'status'>;\n}\n\ninterface CreateProfileVars {\n input: CreateAgentProfileInput;\n}\n\ninterface DeleteProfileData {\n deleteVibecontrolsAgentProfile: boolean;\n}\n\ninterface DeleteProfileVars {\n id: string;\n}\n\ninterface SetDefaultProfileData {\n setDefaultVibecontrolsAgentProfile: Pick<AgentProfile, 'id' | 'isDefault'>;\n}\n\ninterface SetDefaultProfileVars {\n id: string;\n}\n\nconst CREATE_PROFILE_MUTATION = gql`\n mutation CreateVibecontrolsAgentProfile($input: CreateVibecontrolsAgentProfileInput!) {\n createVibecontrolsAgentProfile(input: $input) {\n id\n name\n isDefault\n status\n }\n }\n`;\n\nconst DELETE_PROFILE_MUTATION = gql`\n mutation DeleteVibecontrolsAgentProfile($id: ID!) {\n deleteVibecontrolsAgentProfile(id: $id)\n }\n`;\n\nconst SET_DEFAULT_PROFILE_MUTATION = gql`\n mutation SetDefaultVibecontrolsAgentProfile($id: ID!) {\n setDefaultVibecontrolsAgentProfile(id: $id) {\n id\n isDefault\n }\n }\n`;\n\nfunction statusDot(status: string | null): string {\n const s = (status ?? '').toLowerCase();\n if (s === 'running' || s === 'active' || s === 'healthy') return 'bg-status-success-text';\n if (s === 'stopped' || s === 'inactive') return 'bg-text-placeholder';\n if (s === 'error' || s === 'failed') return 'bg-status-error-text';\n return 'bg-status-warning-text';\n}\n\nexport function ProfilesPanel({ agentId }: ProfilesPanelProps) {\n const { profiles, active, setActive, loading, refetch } = useActiveAgentProfile(agentId);\n\n const [showCreate, setShowCreate] = useState(false);\n const [newName, setNewName] = useState('default');\n const [newPort, setNewPort] = useState<string>('');\n const [actionError, setActionError] = useState<string | null>(null);\n\n const [createProfile, { loading: creating }] = useMutation<CreateProfileData, CreateProfileVars>(\n CREATE_PROFILE_MUTATION\n );\n\n const [deleteProfile, { loading: deleting }] = useMutation<DeleteProfileData, DeleteProfileVars>(\n DELETE_PROFILE_MUTATION\n );\n\n const [setDefaultProfile, { loading: settingDefault }] = useMutation<\n SetDefaultProfileData,\n SetDefaultProfileVars\n >(SET_DEFAULT_PROFILE_MUTATION);\n\n const handleCreate = useCallback(async () => {\n setActionError(null);\n const trimmedName = newName.trim();\n if (!trimmedName) {\n setActionError('Profile name is required');\n return;\n }\n const portNum = newPort.trim() ? Number(newPort.trim()) : null;\n if (newPort.trim() && (Number.isNaN(portNum) || portNum === null || portNum <= 0)) {\n setActionError('Port must be a positive number');\n return;\n }\n try {\n await createProfile({\n variables: {\n input: { agentId, name: trimmedName, port: portNum },\n },\n });\n } catch (err) {\n setActionError(err instanceof Error ? err.message : 'Failed to create profile');\n return;\n }\n setShowCreate(false);\n setNewName('default');\n setNewPort('');\n // The mutation already succeeded — refresh the list off the same observable\n // the panel renders from so the new profile shows without a manual\n // \"Refresh\". refetch() is non-throwing, so a refresh hiccup can never\n // surface as a \"Failed to create\" error; the list re-syncs on the next action.\n await refetch();\n }, [agentId, createProfile, newName, newPort, refetch]);\n\n const handleDelete = useCallback(\n async (profile: AgentProfile) => {\n setActionError(null);\n if (!window.confirm(`Delete profile \"${profile.name}\"? This cannot be undone.`)) {\n return;\n }\n try {\n await deleteProfile({ variables: { id: profile.id } });\n } catch (err) {\n setActionError(err instanceof Error ? err.message : 'Failed to delete profile');\n return;\n }\n // Refresh after a confirmed delete; refetch() is non-throwing so a\n // network hiccup can't masquerade as a failed delete (see handleCreate).\n await refetch();\n },\n [deleteProfile, refetch]\n );\n\n const handleSetDefault = useCallback(\n async (profile: AgentProfile) => {\n setActionError(null);\n try {\n await setDefaultProfile({ variables: { id: profile.id } });\n } catch (err) {\n setActionError(err instanceof Error ? err.message : 'Failed to set default profile');\n return;\n }\n // Refresh after a confirmed change; refetch() is non-throwing so a\n // network hiccup can't masquerade as a failed update (see handleCreate).\n await refetch();\n },\n [setDefaultProfile, refetch]\n );\n\n const busy = creating || deleting || settingDefault;\n\n return (\n <Card>\n <div className=\"p-4 border-b border-border-default flex items-center justify-between\">\n <div>\n <h3 className=\"font-semibold text-text-primary\">Profiles</h3>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n Each profile runs an isolated CLI on this agent. Active:{' '}\n <code className=\"font-mono text-text-primary\">{active}</code>\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n // Fire-and-forget from a click handler: refetch() is non-throwing,\n // so ignoring the returned promise can't leak an unhandled rejection.\n onClick={() => void refetch()}\n className=\"px-2 py-1 text-xs text-text-secondary hover:text-text-primary\"\n >\n Refresh\n </button>\n <button\n type=\"button\"\n onClick={() => setShowCreate((v) => !v)}\n 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:opacity-90\"\n >\n <Plus className=\"size-4\" />\n New profile\n </button>\n </div>\n </div>\n\n {actionError && (\n <div className=\"px-4 py-2 bg-status-error-bg-subtle border-b border-status-error-border text-sm text-status-error-text\">\n {actionError}\n </div>\n )}\n\n {showCreate && (\n <div className=\"p-4 border-b border-border-default bg-bg-sunken/40 space-y-3\">\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label\n htmlFor=\"profilespanel-2\"\n className=\"block text-xs font-medium text-text-secondary mb-1\"\n >\n Profile name\n </label>\n <input\n id=\"profilespanel-2\"\n aria-label=\"default\"\n type=\"text\"\n value={newName}\n onChange={(e) => setNewName(e.target.value)}\n placeholder=\"default\"\n className=\"w-full px-3 py-1.5 text-sm bg-bg-surface border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono\"\n />\n </div>\n <div>\n <label\n htmlFor=\"profilespanel-1\"\n className=\"block text-xs font-medium text-text-secondary mb-1\"\n >\n Port (optional)\n </label>\n <input\n id=\"profilespanel-1\"\n aria-label=\"auto\"\n type=\"number\"\n value={newPort}\n onChange={(e) => setNewPort(e.target.value)}\n placeholder=\"auto\"\n className=\"w-full px-3 py-1.5 text-sm bg-bg-surface border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono\"\n />\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n disabled={creating}\n onClick={() => void handleCreate()}\n 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:opacity-90 disabled:opacity-50\"\n >\n {creating ? (\n <Loader2 className=\"size-3.5 animate-spin\" />\n ) : (\n <CheckCircle2 className=\"size-3.5\" />\n )}\n Create\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setShowCreate(false);\n setActionError(null);\n }}\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-sm text-text-secondary hover:text-text-primary\"\n >\n <X className=\"size-3.5\" />\n Cancel\n </button>\n </div>\n </div>\n )}\n\n {loading && profiles.length === 0 ? (\n <div className=\"p-6 text-center text-text-secondary\">\n <Loader2 className=\"size-5 mx-auto mb-2 animate-spin\" />\n Loading profiles…\n </div>\n ) : profiles.length === 0 ? (\n <div className=\"p-6 text-center text-text-secondary\">\n <p>No profiles configured yet.</p>\n <p className=\"text-xs mt-1\">\n The agent will fall back to the implicit <code className=\"font-mono\">default</code>{' '}\n profile until you create one.\n </p>\n </div>\n ) : (\n <div className=\"divide-y divide-border-default\">\n {profiles.map((profile) => {\n const isActive = profile.name === active;\n // A never-started (awaiting-config) profile can't be the active\n // one — selecting it would just bounce back to a usable profile.\n // Disable \"Use\" and explain why instead of silently reverting.\n const usable = isUsableProfile(profile);\n return (\n <div\n key={profile.id}\n className={`p-4 flex items-center justify-between gap-4 ${\n isActive ? 'bg-[var(--color-accent-soft)]' : ''\n }`}\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <span\n className={`size-2 rounded-full flex-shrink-0 ${statusDot(profile.status)}`}\n aria-hidden\n />\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <code className=\"font-mono font-medium text-text-primary truncate\">\n {profile.name}\n </code>\n {profile.isDefault && (\n <span className=\"inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[10px] uppercase tracking-wide bg-[var(--color-accent-soft)] text-text-primary rounded\">\n <Star className=\"size-3\" />\n Default\n </span>\n )}\n {isActive && (\n <span className=\"px-1.5 py-0.5 text-[10px] uppercase tracking-wide bg-status-success-bg-subtle text-status-success-text rounded\">\n Active\n </span>\n )}\n </div>\n <p className=\"text-xs text-text-secondary mt-0.5 truncate\">\n {profile.status ?? 'unknown'}\n {profile.port ? ` · port ${profile.port}` : ''}\n {profile.tunnelUrl ? ` · ${profile.tunnelUrl}` : ''}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n {!isActive && (\n <button\n type=\"button\"\n disabled={!usable}\n title={\n usable\n ? 'Make this the active profile'\n : \"This profile hasn't been started yet (awaiting config), so it can't be the active profile.\"\n }\n onClick={() => setActive(profile.name)}\n className=\"px-2 py-1 text-xs text-text-secondary hover:text-text-primary border border-border-default rounded disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Use\n </button>\n )}\n {!profile.isDefault && (\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void handleSetDefault(profile)}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs text-text-secondary hover:text-text-primary border border-border-default rounded disabled:opacity-50\"\n >\n <Star className=\"size-3\" />\n Set default\n </button>\n )}\n <button\n type=\"button\"\n disabled={busy || profile.isDefault}\n title={profile.isDefault ? 'Cannot delete the default profile' : 'Delete'}\n onClick={() => void handleDelete(profile)}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-xs text-status-error-text hover:bg-status-error-bg-subtle border border-status-error-border rounded disabled:opacity-50\"\n >\n <Trash2 className=\"size-3\" />\n Delete\n </button>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </Card>\n );\n}\n"],"mappings":"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"}
@@ -125,7 +125,7 @@ function p({ value: s, mode: c, onChange: l }) {
125
125
  return /* @__PURE__ */ d("button", {
126
126
  type: "button",
127
127
  onClick: () => D(e.value),
128
- className: `w-full flex items-start gap-2 px-3 py-2 text-left hover:bg-bg-elevated transition-colors ${e.value === s ? "text-action-primary-text bg-action-primary-bg/10" : "text-text-primary"}`,
128
+ className: `w-full flex items-start gap-2 px-3 py-2 text-left hover:bg-bg-elevated transition-colors ${e.value === s ? "text-text-primary bg-[var(--color-accent-soft)]" : "text-text-primary"}`,
129
129
  children: [/* @__PURE__ */ u(t, { className: "size-4 mt-0.5 shrink-0" }), /* @__PURE__ */ d("span", {
130
130
  className: "flex flex-col",
131
131
  children: [/* @__PURE__ */ u("span", {
@@ -1 +1 @@
1
- {"version":3,"file":"AutonomySelector.js","names":[],"sources":["../../../../src/components/agent-manager/controls/AutonomySelector.tsx"],"sourcesContent":["/**\n * Autonomy (permission mode) selector.\n *\n * Provider-agnostic control for CLI-mode sessions: plan / acceptEdits /\n * fullAuto. Disabled in SDK mode (chat-only). Selecting fullAuto requires an\n * explicit confirmation, since it lets the agent run commands and edit files\n * without asking for approval.\n */\n\nimport { useState, useRef, useEffect, useCallback } from 'react';\nimport { Eye, Pencil, Zap, ChevronDown, AlertTriangle } from 'lucide-react';\nimport type { PermissionMode, ProviderMode } from '@/types/agentManager';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ninterface AutonomySelectorProps {\n value: PermissionMode;\n mode: ProviderMode;\n onChange: (mode: PermissionMode) => void;\n}\n\nconst OPTIONS: Array<{\n value: PermissionMode;\n labelKey: string;\n labelFallback: string;\n descKey: string;\n descFallback: string;\n icon: typeof Eye;\n}> = [\n {\n value: 'plan',\n labelKey: 'vibecontrols.agentManager.controls.autonomy.plan',\n labelFallback: 'Plan',\n descKey: 'vibecontrols.agentManager.controls.autonomy.planDesc',\n descFallback: 'Read-only — plan first, no edits or commands.',\n icon: Eye,\n },\n {\n value: 'acceptEdits',\n labelKey: 'vibecontrols.agentManager.controls.autonomy.acceptEdits',\n labelFallback: 'Accept edits',\n descKey: 'vibecontrols.agentManager.controls.autonomy.acceptEditsDesc',\n descFallback: 'Auto-apply file edits; ask before risky commands.',\n icon: Pencil,\n },\n {\n value: 'fullAuto',\n labelKey: 'vibecontrols.agentManager.controls.autonomy.fullAuto',\n labelFallback: 'Full Auto',\n descKey: 'vibecontrols.agentManager.controls.autonomy.fullAutoDesc',\n descFallback: 'Run commands and edit files without asking.',\n icon: Zap,\n },\n];\n\nexport function AutonomySelector({ value, mode, onChange }: AutonomySelectorProps) {\n const tr = useTr();\n const [open, setOpen] = useState(false);\n const [confirmFullAuto, setConfirmFullAuto] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const [pos, setPos] = useState({ bottom: 0, left: 0, width: 0 });\n\n const disabled = mode === 'sdk';\n const current = OPTIONS.find((o) => o.value === value) ?? OPTIONS[1];\n const CurrentIcon = current.icon;\n\n const handleClickOutside = useCallback((e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n }, []);\n\n useEffect(() => {\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }\n }, [open, handleClickOutside]);\n\n // Escape closes the dropdown — important for a security-sensitive control\n // where a user may reflexively bail out of the fullAuto confirm.\n useEffect(() => {\n if (!open) return;\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false);\n };\n document.addEventListener('keydown', handleKey);\n return () => document.removeEventListener('keydown', handleKey);\n }, [open]);\n\n useEffect(() => {\n if (!open) setConfirmFullAuto(false);\n }, [open]);\n\n const handleToggle = () => {\n if (disabled) return;\n if (!open && buttonRef.current) {\n const rect = buttonRef.current.getBoundingClientRect();\n setPos({\n bottom: window.innerHeight - rect.top + 4,\n left: rect.left,\n width: Math.max(rect.width, 240),\n });\n }\n setOpen((prev) => !prev);\n };\n\n const select = (next: PermissionMode) => {\n // fullAuto requires explicit confirmation (it runs commands/edits unattended).\n if (next === 'fullAuto') {\n setConfirmFullAuto(true);\n return;\n }\n onChange(next);\n setOpen(false);\n };\n\n return (\n <div ref={containerRef} className=\"relative\">\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={handleToggle}\n disabled={disabled}\n className=\"flex items-center gap-1.5 px-2 py-1 text-xs font-medium rounded border border-border-default bg-bg-surface text-text-secondary hover:text-text-primary hover:border-border-strong transition-colors disabled:cursor-not-allowed disabled:opacity-40\"\n title={\n disabled\n ? tr(\n 'vibecontrols.agentManager.controls.autonomy.sdkDisabled',\n 'Autonomy applies in CLI mode (SDK is chat-only)'\n )\n : tr(current.labelKey, current.labelFallback)\n }\n >\n <CurrentIcon className=\"size-3.5\" />\n <span>{tr(current.labelKey, current.labelFallback)}</span>\n <ChevronDown className=\"size-3\" />\n </button>\n\n {open && !disabled && (\n <div\n className=\"fixed rounded-lg border border-border-default bg-bg-surface shadow-lg z-[100]\"\n style={{ bottom: pos.bottom, left: pos.left, minWidth: pos.width }}\n >\n {confirmFullAuto ? (\n <div className=\"p-3 space-y-2\" style={{ maxWidth: 280 }}>\n <div className=\"flex items-center gap-1.5 text-status-warning-text text-xs font-semibold\">\n <AlertTriangle className=\"size-3.5\" />\n {tr(\n 'vibecontrols.agentManager.controls.autonomy.confirmTitle',\n 'Enable Full Auto?'\n )}\n </div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'vibecontrols.agentManager.controls.autonomy.confirmBody',\n 'Full Auto lets the agent run commands and edit files without asking for approval.'\n )}\n </p>\n <div className=\"flex items-center justify-end gap-2 pt-1\">\n <button\n type=\"button\"\n onClick={() => setConfirmFullAuto(false)}\n className=\"px-2 py-1 text-xs font-medium rounded border border-border-default text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('vibecontrols.agentManager.controls.autonomy.cancel', 'Cancel')}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n onChange('fullAuto');\n setConfirmFullAuto(false);\n setOpen(false);\n }}\n className=\"px-2 py-1 text-xs font-medium rounded bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('vibecontrols.agentManager.controls.autonomy.enable', 'Enable')}\n </button>\n </div>\n </div>\n ) : (\n <div className=\"py-1\">\n {OPTIONS.map((option) => {\n const Icon = option.icon;\n return (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => select(option.value)}\n className={`w-full flex items-start gap-2 px-3 py-2 text-left hover:bg-bg-elevated transition-colors ${\n option.value === value\n ? 'text-action-primary-text bg-action-primary-bg/10'\n : 'text-text-primary'\n }`}\n >\n <Icon className=\"size-4 mt-0.5 shrink-0\" />\n <span className=\"flex flex-col\">\n <span className=\"text-sm\">{tr(option.labelKey, option.labelFallback)}</span>\n <span className=\"text-[11px] text-text-tertiary\">\n {tr(option.descKey, option.descFallback)}\n </span>\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AutonomySelector.js","names":[],"sources":["../../../../src/components/agent-manager/controls/AutonomySelector.tsx"],"sourcesContent":["/**\n * Autonomy (permission mode) selector.\n *\n * Provider-agnostic control for CLI-mode sessions: plan / acceptEdits /\n * fullAuto. Disabled in SDK mode (chat-only). Selecting fullAuto requires an\n * explicit confirmation, since it lets the agent run commands and edit files\n * without asking for approval.\n */\n\nimport { useState, useRef, useEffect, useCallback } from 'react';\nimport { Eye, Pencil, Zap, ChevronDown, AlertTriangle } from 'lucide-react';\nimport type { PermissionMode, ProviderMode } from '@/types/agentManager';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ninterface AutonomySelectorProps {\n value: PermissionMode;\n mode: ProviderMode;\n onChange: (mode: PermissionMode) => void;\n}\n\nconst OPTIONS: Array<{\n value: PermissionMode;\n labelKey: string;\n labelFallback: string;\n descKey: string;\n descFallback: string;\n icon: typeof Eye;\n}> = [\n {\n value: 'plan',\n labelKey: 'vibecontrols.agentManager.controls.autonomy.plan',\n labelFallback: 'Plan',\n descKey: 'vibecontrols.agentManager.controls.autonomy.planDesc',\n descFallback: 'Read-only — plan first, no edits or commands.',\n icon: Eye,\n },\n {\n value: 'acceptEdits',\n labelKey: 'vibecontrols.agentManager.controls.autonomy.acceptEdits',\n labelFallback: 'Accept edits',\n descKey: 'vibecontrols.agentManager.controls.autonomy.acceptEditsDesc',\n descFallback: 'Auto-apply file edits; ask before risky commands.',\n icon: Pencil,\n },\n {\n value: 'fullAuto',\n labelKey: 'vibecontrols.agentManager.controls.autonomy.fullAuto',\n labelFallback: 'Full Auto',\n descKey: 'vibecontrols.agentManager.controls.autonomy.fullAutoDesc',\n descFallback: 'Run commands and edit files without asking.',\n icon: Zap,\n },\n];\n\nexport function AutonomySelector({ value, mode, onChange }: AutonomySelectorProps) {\n const tr = useTr();\n const [open, setOpen] = useState(false);\n const [confirmFullAuto, setConfirmFullAuto] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const [pos, setPos] = useState({ bottom: 0, left: 0, width: 0 });\n\n const disabled = mode === 'sdk';\n const current = OPTIONS.find((o) => o.value === value) ?? OPTIONS[1];\n const CurrentIcon = current.icon;\n\n const handleClickOutside = useCallback((e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n }, []);\n\n useEffect(() => {\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }\n }, [open, handleClickOutside]);\n\n // Escape closes the dropdown — important for a security-sensitive control\n // where a user may reflexively bail out of the fullAuto confirm.\n useEffect(() => {\n if (!open) return;\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false);\n };\n document.addEventListener('keydown', handleKey);\n return () => document.removeEventListener('keydown', handleKey);\n }, [open]);\n\n useEffect(() => {\n if (!open) setConfirmFullAuto(false);\n }, [open]);\n\n const handleToggle = () => {\n if (disabled) return;\n if (!open && buttonRef.current) {\n const rect = buttonRef.current.getBoundingClientRect();\n setPos({\n bottom: window.innerHeight - rect.top + 4,\n left: rect.left,\n width: Math.max(rect.width, 240),\n });\n }\n setOpen((prev) => !prev);\n };\n\n const select = (next: PermissionMode) => {\n // fullAuto requires explicit confirmation (it runs commands/edits unattended).\n if (next === 'fullAuto') {\n setConfirmFullAuto(true);\n return;\n }\n onChange(next);\n setOpen(false);\n };\n\n return (\n <div ref={containerRef} className=\"relative\">\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={handleToggle}\n disabled={disabled}\n className=\"flex items-center gap-1.5 px-2 py-1 text-xs font-medium rounded border border-border-default bg-bg-surface text-text-secondary hover:text-text-primary hover:border-border-strong transition-colors disabled:cursor-not-allowed disabled:opacity-40\"\n title={\n disabled\n ? tr(\n 'vibecontrols.agentManager.controls.autonomy.sdkDisabled',\n 'Autonomy applies in CLI mode (SDK is chat-only)'\n )\n : tr(current.labelKey, current.labelFallback)\n }\n >\n <CurrentIcon className=\"size-3.5\" />\n <span>{tr(current.labelKey, current.labelFallback)}</span>\n <ChevronDown className=\"size-3\" />\n </button>\n\n {open && !disabled && (\n <div\n className=\"fixed rounded-lg border border-border-default bg-bg-surface shadow-lg z-[100]\"\n style={{ bottom: pos.bottom, left: pos.left, minWidth: pos.width }}\n >\n {confirmFullAuto ? (\n <div className=\"p-3 space-y-2\" style={{ maxWidth: 280 }}>\n <div className=\"flex items-center gap-1.5 text-status-warning-text text-xs font-semibold\">\n <AlertTriangle className=\"size-3.5\" />\n {tr(\n 'vibecontrols.agentManager.controls.autonomy.confirmTitle',\n 'Enable Full Auto?'\n )}\n </div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'vibecontrols.agentManager.controls.autonomy.confirmBody',\n 'Full Auto lets the agent run commands and edit files without asking for approval.'\n )}\n </p>\n <div className=\"flex items-center justify-end gap-2 pt-1\">\n <button\n type=\"button\"\n onClick={() => setConfirmFullAuto(false)}\n className=\"px-2 py-1 text-xs font-medium rounded border border-border-default text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('vibecontrols.agentManager.controls.autonomy.cancel', 'Cancel')}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n onChange('fullAuto');\n setConfirmFullAuto(false);\n setOpen(false);\n }}\n className=\"px-2 py-1 text-xs font-medium rounded bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('vibecontrols.agentManager.controls.autonomy.enable', 'Enable')}\n </button>\n </div>\n </div>\n ) : (\n <div className=\"py-1\">\n {OPTIONS.map((option) => {\n const Icon = option.icon;\n return (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => select(option.value)}\n className={`w-full flex items-start gap-2 px-3 py-2 text-left hover:bg-bg-elevated transition-colors ${\n option.value === value\n ? 'text-text-primary bg-[var(--color-accent-soft)]'\n : 'text-text-primary'\n }`}\n >\n <Icon className=\"size-4 mt-0.5 shrink-0\" />\n <span className=\"flex flex-col\">\n <span className=\"text-sm\">{tr(option.labelKey, option.labelFallback)}</span>\n <span className=\"text-[11px] text-text-tertiary\">\n {tr(option.descKey, option.descFallback)}\n </span>\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}