@stigmer/react 3.11.0 → 3.12.0

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 (559) hide show
  1. package/activity/useRecentActivity.d.ts +3 -2
  2. package/activity/useRecentActivity.d.ts.map +1 -1
  3. package/activity/useRecentActivity.js +3 -2
  4. package/activity/useRecentActivity.js.map +1 -1
  5. package/agent/AgentDetailView.d.ts +2 -12
  6. package/agent/AgentDetailView.d.ts.map +1 -1
  7. package/agent/AgentDetailView.js +10 -42
  8. package/agent/AgentDetailView.js.map +1 -1
  9. package/agent/internal/agentToInput.d.ts.map +1 -1
  10. package/agent/internal/agentToInput.js +0 -8
  11. package/agent/internal/agentToInput.js.map +1 -1
  12. package/agent-instance/AgentInstanceList.d.ts.map +1 -1
  13. package/agent-instance/AgentInstanceList.js +2 -1
  14. package/agent-instance/AgentInstanceList.js.map +1 -1
  15. package/api-key/ApiKeyListPanel.d.ts.map +1 -1
  16. package/api-key/ApiKeyListPanel.js +2 -1
  17. package/api-key/ApiKeyListPanel.js.map +1 -1
  18. package/attachment/AttachmentChipList.d.ts.map +1 -1
  19. package/attachment/AttachmentChipList.js +9 -8
  20. package/attachment/AttachmentChipList.js.map +1 -1
  21. package/attachment/AttachmentImageLightbox.d.ts.map +1 -1
  22. package/attachment/AttachmentImageLightbox.js +1 -1
  23. package/attachment/AttachmentImageLightbox.js.map +1 -1
  24. package/channel/AgentChannelsPanel.d.ts.map +1 -1
  25. package/channel/AgentChannelsPanel.js +2 -1
  26. package/channel/AgentChannelsPanel.js.map +1 -1
  27. package/channel/ChannelConversationsDialog.d.ts.map +1 -1
  28. package/channel/ChannelConversationsDialog.js +2 -1
  29. package/channel/ChannelConversationsDialog.js.map +1 -1
  30. package/channel/ChannelTemplatesDialog.d.ts.map +1 -1
  31. package/channel/ChannelTemplatesDialog.js +2 -1
  32. package/channel/ChannelTemplatesDialog.js.map +1 -1
  33. package/channel-app/internal.d.ts.map +1 -1
  34. package/channel-app/internal.js +2 -1
  35. package/channel-app/internal.js.map +1 -1
  36. package/composer/ComposerToolbar.d.ts.map +1 -1
  37. package/composer/ComposerToolbar.js +10 -7
  38. package/composer/ComposerToolbar.js.map +1 -1
  39. package/composer/ConfigureMenu.d.ts.map +1 -1
  40. package/composer/ConfigureMenu.js +2 -1
  41. package/composer/ConfigureMenu.js.map +1 -1
  42. package/composer/ContextChip.d.ts.map +1 -1
  43. package/composer/ContextChip.js +2 -1
  44. package/composer/ContextChip.js.map +1 -1
  45. package/composer/ContextPopover.d.ts.map +1 -1
  46. package/composer/ContextPopover.js +2 -1
  47. package/composer/ContextPopover.js.map +1 -1
  48. package/composer/SessionComposer.d.ts +13 -0
  49. package/composer/SessionComposer.d.ts.map +1 -1
  50. package/composer/SessionComposer.js +12 -2
  51. package/composer/SessionComposer.js.map +1 -1
  52. package/conversation/ConversationMediaAttachment.d.ts.map +1 -1
  53. package/conversation/ConversationMediaAttachment.js +2 -1
  54. package/conversation/ConversationMediaAttachment.js.map +1 -1
  55. package/conversation/ConversationTimelineView.d.ts.map +1 -1
  56. package/conversation/ConversationTimelineView.js +14 -4
  57. package/conversation/ConversationTimelineView.js.map +1 -1
  58. package/conversation/conversationPresentation.d.ts +28 -0
  59. package/conversation/conversationPresentation.d.ts.map +1 -1
  60. package/conversation/conversationPresentation.js +38 -1
  61. package/conversation/conversationPresentation.js.map +1 -1
  62. package/cursor-accounts/MemberCoverageTable.d.ts.map +1 -1
  63. package/cursor-accounts/MemberCoverageTable.js +6 -5
  64. package/cursor-accounts/MemberCoverageTable.js.map +1 -1
  65. package/dashboard/DashboardKPICards.d.ts.map +1 -1
  66. package/dashboard/DashboardKPICards.js +3 -1
  67. package/dashboard/DashboardKPICards.js.map +1 -1
  68. package/dependency-graph/DependencyTreeNode.d.ts.map +1 -1
  69. package/dependency-graph/DependencyTreeNode.js +1 -7
  70. package/dependency-graph/DependencyTreeNode.js.map +1 -1
  71. package/dependency-graph/types.d.ts +8 -20
  72. package/dependency-graph/types.d.ts.map +1 -1
  73. package/dependency-graph/useDependencyGraph.d.ts.map +1 -1
  74. package/dependency-graph/useDependencyGraph.js +2 -20
  75. package/dependency-graph/useDependencyGraph.js.map +1 -1
  76. package/environment/EnvironmentVariableEditor.d.ts.map +1 -1
  77. package/environment/EnvironmentVariableEditor.js +2 -1
  78. package/environment/EnvironmentVariableEditor.js.map +1 -1
  79. package/execution/ApprovalCard.d.ts.map +1 -1
  80. package/execution/ApprovalCard.js +1 -1
  81. package/execution/ApprovalCard.js.map +1 -1
  82. package/execution/ArtifactRowView.d.ts.map +1 -1
  83. package/execution/ArtifactRowView.js +2 -1
  84. package/execution/ArtifactRowView.js.map +1 -1
  85. package/execution/FilePathLink.d.ts +4 -4
  86. package/execution/FilePathLink.d.ts.map +1 -1
  87. package/execution/FilePathLink.js +4 -4
  88. package/execution/FilePathLink.js.map +1 -1
  89. package/execution/McpToolDetail.d.ts.map +1 -1
  90. package/execution/McpToolDetail.js +2 -1
  91. package/execution/McpToolDetail.js.map +1 -1
  92. package/execution/MessageAttachments.d.ts.map +1 -1
  93. package/execution/MessageAttachments.js +10 -8
  94. package/execution/MessageAttachments.js.map +1 -1
  95. package/execution/MessageEntry.d.ts.map +1 -1
  96. package/execution/MessageEntry.js +2 -1
  97. package/execution/MessageEntry.js.map +1 -1
  98. package/execution/PlanArtifactCard.d.ts.map +1 -1
  99. package/execution/PlanArtifactCard.js +7 -4
  100. package/execution/PlanArtifactCard.js.map +1 -1
  101. package/execution/ToolCallDetail.d.ts.map +1 -1
  102. package/execution/ToolCallDetail.js +1 -1
  103. package/execution/ToolCallDetail.js.map +1 -1
  104. package/execution/ToolCallItem.d.ts.map +1 -1
  105. package/execution/ToolCallItem.js +5 -1
  106. package/execution/ToolCallItem.js.map +1 -1
  107. package/execution/WriteBackCard.d.ts.map +1 -1
  108. package/execution/WriteBackCard.js +6 -4
  109. package/execution/WriteBackCard.js.map +1 -1
  110. package/execution/artifact-row-item.d.ts +1 -1
  111. package/execution/artifact-row-item.d.ts.map +1 -1
  112. package/file-reference/FileReferenceChipList.d.ts.map +1 -1
  113. package/file-reference/FileReferenceChipList.js +6 -1
  114. package/file-reference/FileReferenceChipList.js.map +1 -1
  115. package/iam-policy/OrgMembersPanel.d.ts.map +1 -1
  116. package/iam-policy/OrgMembersPanel.js +6 -5
  117. package/iam-policy/OrgMembersPanel.js.map +1 -1
  118. package/iam-policy/ProviderBadge.d.ts.map +1 -1
  119. package/iam-policy/ProviderBadge.js +3 -2
  120. package/iam-policy/ProviderBadge.js.map +1 -1
  121. package/iam-policy/RoleSelector.d.ts.map +1 -1
  122. package/iam-policy/RoleSelector.js +1 -1
  123. package/iam-policy/RoleSelector.js.map +1 -1
  124. package/identity-provider/IdentityProviderListPanel.d.ts.map +1 -1
  125. package/identity-provider/IdentityProviderListPanel.js +2 -1
  126. package/identity-provider/IdentityProviderListPanel.js.map +1 -1
  127. package/index.d.ts +0 -2
  128. package/index.d.ts.map +1 -1
  129. package/index.js +0 -6
  130. package/index.js.map +1 -1
  131. package/internal/truncated-text.d.ts +17 -0
  132. package/internal/truncated-text.d.ts.map +1 -0
  133. package/internal/truncated-text.js +27 -0
  134. package/internal/truncated-text.js.map +1 -0
  135. package/invitation/InvitationManager.d.ts.map +1 -1
  136. package/invitation/InvitationManager.js +4 -3
  137. package/invitation/InvitationManager.js.map +1 -1
  138. package/library/ScopeToggle.d.ts.map +1 -1
  139. package/library/ScopeToggle.js +10 -2
  140. package/library/ScopeToggle.js.map +1 -1
  141. package/library/VisibilitySelector.d.ts.map +1 -1
  142. package/library/VisibilitySelector.js +2 -1
  143. package/library/VisibilitySelector.js.map +1 -1
  144. package/library/useExportResource.d.ts +3 -4
  145. package/library/useExportResource.d.ts.map +1 -1
  146. package/library/useExportResource.js +1 -1
  147. package/library/useExportResource.js.map +1 -1
  148. package/manifest/EditResourceYamlDialog.d.ts.map +1 -1
  149. package/manifest/EditResourceYamlDialog.js.map +1 -1
  150. package/mcp-server/McpServerConfigPanel.d.ts +30 -1
  151. package/mcp-server/McpServerConfigPanel.d.ts.map +1 -1
  152. package/mcp-server/McpServerConfigPanel.js +18 -8
  153. package/mcp-server/McpServerConfigPanel.js.map +1 -1
  154. package/mcp-server/McpServerConnectDialog.d.ts +12 -1
  155. package/mcp-server/McpServerConnectDialog.d.ts.map +1 -1
  156. package/mcp-server/McpServerConnectDialog.js +8 -7
  157. package/mcp-server/McpServerConnectDialog.js.map +1 -1
  158. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  159. package/mcp-server/McpServerDetailView.js +4 -4
  160. package/mcp-server/McpServerDetailView.js.map +1 -1
  161. package/mcp-server/McpServerPicker.d.ts.map +1 -1
  162. package/mcp-server/McpServerPicker.js +86 -5
  163. package/mcp-server/McpServerPicker.js.map +1 -1
  164. package/mcp-server/McpToolSelector.d.ts.map +1 -1
  165. package/mcp-server/McpToolSelector.js +2 -1
  166. package/mcp-server/McpToolSelector.js.map +1 -1
  167. package/mcp-server/VendorApprovalBlockedNotice.d.ts +77 -0
  168. package/mcp-server/VendorApprovalBlockedNotice.d.ts.map +1 -0
  169. package/mcp-server/VendorApprovalBlockedNotice.js +62 -0
  170. package/mcp-server/VendorApprovalBlockedNotice.js.map +1 -0
  171. package/mcp-server/mcpServerSetupReducer.d.ts +18 -0
  172. package/mcp-server/mcpServerSetupReducer.d.ts.map +1 -1
  173. package/mcp-server/mcpServerSetupReducer.js +6 -0
  174. package/mcp-server/mcpServerSetupReducer.js.map +1 -1
  175. package/mcp-server/useMcpServerSetup.d.ts.map +1 -1
  176. package/mcp-server/useMcpServerSetup.js +7 -0
  177. package/mcp-server/useMcpServerSetup.js.map +1 -1
  178. package/oauth-app/OAuthAppListPanel.d.ts.map +1 -1
  179. package/oauth-app/OAuthAppListPanel.js +2 -1
  180. package/oauth-app/OAuthAppListPanel.js.map +1 -1
  181. package/package.json +4 -4
  182. package/platform-client/PlatformClientListPanel.d.ts.map +1 -1
  183. package/platform-client/PlatformClientListPanel.js +3 -2
  184. package/platform-client/PlatformClientListPanel.js.map +1 -1
  185. package/pricing-governance/BaselineEditor.d.ts.map +1 -1
  186. package/pricing-governance/BaselineEditor.js +7 -1
  187. package/pricing-governance/BaselineEditor.js.map +1 -1
  188. package/pricing-governance/ModelCatalogPanel.d.ts.map +1 -1
  189. package/pricing-governance/ModelCatalogPanel.js +2 -1
  190. package/pricing-governance/ModelCatalogPanel.js.map +1 -1
  191. package/pricing-governance/PricingGovernanceConsole.d.ts.map +1 -1
  192. package/pricing-governance/PricingGovernanceConsole.js +2 -1
  193. package/pricing-governance/PricingGovernanceConsole.js.map +1 -1
  194. package/pricing-governance/PricingGovernancePanel.d.ts.map +1 -1
  195. package/pricing-governance/PricingGovernancePanel.js +2 -1
  196. package/pricing-governance/PricingGovernancePanel.js.map +1 -1
  197. package/resource-workbench/components/StatusBadge.d.ts.map +1 -1
  198. package/resource-workbench/components/StatusBadge.js +2 -1
  199. package/resource-workbench/components/StatusBadge.js.map +1 -1
  200. package/schedule/CadenceField.d.ts.map +1 -1
  201. package/schedule/CadenceField.js +15 -8
  202. package/schedule/CadenceField.js.map +1 -1
  203. package/schedule/ScheduleRunsTable.d.ts.map +1 -1
  204. package/schedule/ScheduleRunsTable.js +3 -2
  205. package/schedule/ScheduleRunsTable.js.map +1 -1
  206. package/session/PlanEditor.d.ts.map +1 -1
  207. package/session/PlanEditor.js +3 -5
  208. package/session/PlanEditor.js.map +1 -1
  209. package/sharing/AgentShareList.d.ts.map +1 -1
  210. package/sharing/AgentShareList.js +3 -1
  211. package/sharing/AgentShareList.js.map +1 -1
  212. package/sharing/ShareAgentDialog.d.ts.map +1 -1
  213. package/sharing/ShareAgentDialog.js +2 -1
  214. package/sharing/ShareAgentDialog.js.map +1 -1
  215. package/skill/SkillDetailView.d.ts.map +1 -1
  216. package/skill/SkillDetailView.js +3 -2
  217. package/skill/SkillDetailView.js.map +1 -1
  218. package/src/__tests__/helpers/open-menu.ts +88 -0
  219. package/src/__tests__/portal-container.test.tsx +3 -3
  220. package/src/activity/useRecentActivity.ts +3 -2
  221. package/src/agent/AgentDetailView.tsx +6 -130
  222. package/src/agent/internal/__tests__/agentToInput.test.ts +2 -11
  223. package/src/agent/internal/agentToInput.ts +0 -11
  224. package/src/agent-instance/AgentInstanceList.tsx +5 -6
  225. package/src/agent-instance/__tests__/AgentInstanceList.test.tsx +5 -4
  226. package/src/api-key/ApiKeyListPanel.tsx +11 -3
  227. package/src/attachment/AttachmentChipList.tsx +74 -65
  228. package/src/attachment/AttachmentImageLightbox.tsx +5 -4
  229. package/src/attachment/__tests__/AttachmentChipList.test.tsx +4 -3
  230. package/src/channel/AgentChannelsPanel.tsx +5 -6
  231. package/src/channel/ChannelConversationsDialog.tsx +5 -3
  232. package/src/channel/ChannelTemplatesDialog.tsx +5 -6
  233. package/src/channel/__tests__/AgentChannelsPanel.test.tsx +14 -9
  234. package/src/channel-app/internal.tsx +5 -6
  235. package/src/composer/ComposerToolbar.tsx +122 -90
  236. package/src/composer/ConfigureMenu.tsx +33 -24
  237. package/src/composer/ContextChip.tsx +2 -3
  238. package/src/composer/ContextPopover.tsx +27 -18
  239. package/src/composer/SessionComposer.tsx +41 -9
  240. package/src/composer/__tests__/SessionComposer-agentSetupError.test.tsx +124 -0
  241. package/src/composer/__tests__/SessionComposer-lockAgent.test.tsx +4 -9
  242. package/src/conversation/ConversationMediaAttachment.tsx +2 -2
  243. package/src/conversation/ConversationTimelineView.tsx +19 -2
  244. package/src/conversation/__tests__/ConversationTimelineView.test.tsx +106 -3
  245. package/src/conversation/conversationPresentation.ts +52 -1
  246. package/src/cursor-accounts/MemberCoverageTable.tsx +15 -13
  247. package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +4 -4
  248. package/src/dashboard/DashboardKPICards.tsx +2 -1
  249. package/src/dependency-graph/DependencyTreeNode.tsx +1 -7
  250. package/src/dependency-graph/__tests__/useDependencyGraph.test.ts +18 -34
  251. package/src/dependency-graph/types.ts +8 -20
  252. package/src/dependency-graph/useDependencyGraph.ts +2 -22
  253. package/src/environment/EnvironmentVariableEditor.tsx +17 -6
  254. package/src/execution/ApprovalCard.tsx +1 -3
  255. package/src/execution/ArtifactRowView.tsx +68 -48
  256. package/src/execution/FilePathLink.tsx +43 -27
  257. package/src/execution/McpToolDetail.tsx +6 -2
  258. package/src/execution/MessageAttachments.tsx +57 -41
  259. package/src/execution/MessageEntry.tsx +22 -15
  260. package/src/execution/PlanArtifactCard.tsx +25 -18
  261. package/src/execution/ToolCallDetail.tsx +1 -4
  262. package/src/execution/ToolCallItem.tsx +18 -7
  263. package/src/execution/WriteBackCard.tsx +38 -29
  264. package/src/execution/__tests__/ArtifactRow.test.tsx +6 -2
  265. package/src/execution/__tests__/ArtifactRowView.test.tsx +5 -2
  266. package/src/execution/__tests__/FilePathLink.test.tsx +10 -6
  267. package/src/execution/__tests__/FileReviewCard.test.tsx +2 -1
  268. package/src/execution/__tests__/MessageEntry-attachments.test.tsx +3 -2
  269. package/src/execution/__tests__/MessageThread.test.tsx +6 -1
  270. package/src/execution/__tests__/artifact-row-tooltips.layout.test.tsx +115 -0
  271. package/src/execution/artifact-row-item.ts +1 -1
  272. package/src/file-reference/FileReferenceChipList.tsx +29 -17
  273. package/src/file-reference/__tests__/FileReferenceChipList.test.tsx +5 -2
  274. package/src/iam-policy/OrgMembersPanel.tsx +26 -19
  275. package/src/iam-policy/ProviderBadge.tsx +17 -10
  276. package/src/iam-policy/RoleSelector.tsx +0 -1
  277. package/src/identity-provider/IdentityProviderListPanel.tsx +11 -3
  278. package/src/index.ts +0 -82
  279. package/src/internal/__tests__/truncated-text.layout.test.tsx +68 -0
  280. package/src/internal/__tests__/truncated-text.test.tsx +33 -0
  281. package/src/internal/truncated-text.tsx +81 -0
  282. package/src/invitation/InvitationManager.tsx +18 -5
  283. package/src/library/ScopeToggle.tsx +14 -2
  284. package/src/library/VisibilitySelector.tsx +21 -14
  285. package/src/library/useExportResource.ts +3 -4
  286. package/src/manifest/EditResourceYamlDialog.tsx +1 -2
  287. package/src/manifest/__tests__/ApplyManifestDialog.test.tsx +2 -2
  288. package/src/manifest/__tests__/EditResourceYamlDialog.test.tsx +9 -9
  289. package/src/mcp-server/McpServerConfigPanel.tsx +79 -37
  290. package/src/mcp-server/McpServerConnectDialog.tsx +41 -5
  291. package/src/mcp-server/McpServerDetailView.tsx +23 -39
  292. package/src/mcp-server/McpServerPicker.tsx +99 -7
  293. package/src/mcp-server/McpToolSelector.tsx +12 -7
  294. package/src/mcp-server/VendorApprovalBlockedNotice.tsx +221 -0
  295. package/src/mcp-server/__tests__/McpServerPicker.test.tsx +504 -0
  296. package/src/mcp-server/__tests__/VendorApprovalBlocked.surfaces.test.tsx +321 -0
  297. package/src/mcp-server/__tests__/VendorApprovalBlockedNotice.test.tsx +154 -0
  298. package/src/mcp-server/mcpServerSetupReducer.ts +24 -0
  299. package/src/mcp-server/useMcpServerSetup.ts +9 -0
  300. package/src/oauth-app/OAuthAppListPanel.tsx +11 -3
  301. package/src/platform-client/PlatformClientListPanel.tsx +35 -18
  302. package/src/pricing-governance/BaselineEditor.tsx +20 -0
  303. package/src/pricing-governance/ModelCatalogPanel.tsx +9 -5
  304. package/src/pricing-governance/PricingGovernanceConsole.tsx +9 -5
  305. package/src/pricing-governance/PricingGovernancePanel.tsx +13 -4
  306. package/src/pricing-governance/__tests__/ModelCatalogPanel.test.tsx +37 -0
  307. package/src/resource-workbench/components/StatusBadge.tsx +7 -3
  308. package/src/schedule/CadenceField.tsx +38 -27
  309. package/src/schedule/ScheduleRunsTable.tsx +23 -11
  310. package/src/schedule/__tests__/cadence-tooltips.layout.test.tsx +86 -0
  311. package/src/session/PlanEditor.tsx +9 -8
  312. package/src/sharing/AgentShareList.tsx +28 -22
  313. package/src/sharing/ShareAgentDialog.tsx +5 -6
  314. package/src/sharing/__tests__/AgentShareList.test.tsx +4 -4
  315. package/src/skill/SkillDetailView.tsx +23 -12
  316. package/src/version-history/VersionTimelineEntry.tsx +21 -12
  317. package/src/workflow/CanvasTransitionEdge.tsx +23 -16
  318. package/src/workflow/ExecutionActiveTaskIndicator.tsx +74 -59
  319. package/src/workflow/TaskPickerPopover.tsx +0 -1
  320. package/src/workflow/WorkflowCanvasEditor.tsx +95 -64
  321. package/src/workflow/WorkflowNode.tsx +13 -6
  322. package/src/workflow/WorkflowTaskApprovalSummary.tsx +18 -11
  323. package/src/workflow/WorkflowTaskList.tsx +2 -2
  324. package/src/workflow/WorkflowVersionBadge.tsx +33 -18
  325. package/src/workflow/WorkflowVersionTimeline.tsx +7 -6
  326. package/src/workflow/__tests__/WorkflowTaskApprovalSummary.test.tsx +3 -1
  327. package/src/workflow/__tests__/structured-data-viewer.test.tsx +5 -2
  328. package/src/workflow/execution-comparison/ExecutionComparisonView.tsx +5 -3
  329. package/src/workflow/execution-comparison/TaskComparisonTable.tsx +12 -5
  330. package/src/workflow/execution-history/ExecutionHistoryTable.tsx +24 -15
  331. package/src/workflow/inspector/InspectorHeader.tsx +20 -11
  332. package/src/workflow/inspector/NestedTaskList.tsx +18 -11
  333. package/src/workflow/inspector/WorkflowSummaryPanel.tsx +5 -3
  334. package/src/workflow/inspector/tabs/BranchesTab.tsx +61 -31
  335. package/src/workflow/instance/WorkflowInstanceList.tsx +5 -6
  336. package/src/workflow/instance/__tests__/WorkflowInstanceList.test.tsx +5 -4
  337. package/src/workflow/node-shell/DiffBadge.tsx +18 -11
  338. package/src/workflow/node-shell/ExecutionBadge.tsx +73 -46
  339. package/src/workflow/node-shell/NodeActions.tsx +128 -94
  340. package/src/workflow/task-detail/StructuredDataViewer.tsx +4 -2
  341. package/src/workspace/EditorTabs.tsx +102 -85
  342. package/src/workspace/ExplorerTree.tsx +47 -30
  343. package/src/workspace/FileViewer.tsx +11 -3
  344. package/src/workspace/PanelChip.tsx +32 -23
  345. package/src/workspace/WorkspaceEditor.tsx +21 -9
  346. package/src/workspace/WorkspaceSummary.tsx +21 -12
  347. package/src/workspace/WorkspaceSurface.tsx +86 -61
  348. package/src/workspace/__tests__/EditorTabs.test.tsx +5 -2
  349. package/src/workspace/__tests__/WorkspaceSurface.test.tsx +5 -2
  350. package/styles.css +1 -1
  351. package/version-history/VersionTimelineEntry.d.ts.map +1 -1
  352. package/version-history/VersionTimelineEntry.js +2 -1
  353. package/version-history/VersionTimelineEntry.js.map +1 -1
  354. package/workflow/CanvasTransitionEdge.d.ts +1 -1
  355. package/workflow/CanvasTransitionEdge.d.ts.map +1 -1
  356. package/workflow/CanvasTransitionEdge.js +3 -2
  357. package/workflow/CanvasTransitionEdge.js.map +1 -1
  358. package/workflow/ExecutionActiveTaskIndicator.d.ts.map +1 -1
  359. package/workflow/ExecutionActiveTaskIndicator.js +12 -11
  360. package/workflow/ExecutionActiveTaskIndicator.js.map +1 -1
  361. package/workflow/TaskPickerPopover.js +1 -1
  362. package/workflow/TaskPickerPopover.js.map +1 -1
  363. package/workflow/WorkflowCanvasEditor.d.ts.map +1 -1
  364. package/workflow/WorkflowCanvasEditor.js +9 -2
  365. package/workflow/WorkflowCanvasEditor.js.map +1 -1
  366. package/workflow/WorkflowNode.d.ts.map +1 -1
  367. package/workflow/WorkflowNode.js +2 -1
  368. package/workflow/WorkflowNode.js.map +1 -1
  369. package/workflow/WorkflowTaskApprovalSummary.d.ts.map +1 -1
  370. package/workflow/WorkflowTaskApprovalSummary.js +6 -4
  371. package/workflow/WorkflowTaskApprovalSummary.js.map +1 -1
  372. package/workflow/WorkflowTaskList.js +2 -2
  373. package/workflow/WorkflowTaskList.js.map +1 -1
  374. package/workflow/WorkflowVersionBadge.d.ts.map +1 -1
  375. package/workflow/WorkflowVersionBadge.js +2 -1
  376. package/workflow/WorkflowVersionBadge.js.map +1 -1
  377. package/workflow/WorkflowVersionTimeline.d.ts.map +1 -1
  378. package/workflow/WorkflowVersionTimeline.js +2 -1
  379. package/workflow/WorkflowVersionTimeline.js.map +1 -1
  380. package/workflow/execution-comparison/ExecutionComparisonView.d.ts.map +1 -1
  381. package/workflow/execution-comparison/ExecutionComparisonView.js +2 -1
  382. package/workflow/execution-comparison/ExecutionComparisonView.js.map +1 -1
  383. package/workflow/execution-comparison/TaskComparisonTable.d.ts.map +1 -1
  384. package/workflow/execution-comparison/TaskComparisonTable.js +2 -1
  385. package/workflow/execution-comparison/TaskComparisonTable.js.map +1 -1
  386. package/workflow/execution-history/ExecutionHistoryTable.d.ts.map +1 -1
  387. package/workflow/execution-history/ExecutionHistoryTable.js +6 -4
  388. package/workflow/execution-history/ExecutionHistoryTable.js.map +1 -1
  389. package/workflow/inspector/InspectorHeader.d.ts.map +1 -1
  390. package/workflow/inspector/InspectorHeader.js +4 -2
  391. package/workflow/inspector/InspectorHeader.js.map +1 -1
  392. package/workflow/inspector/NestedTaskList.d.ts.map +1 -1
  393. package/workflow/inspector/NestedTaskList.js +2 -1
  394. package/workflow/inspector/NestedTaskList.js.map +1 -1
  395. package/workflow/inspector/WorkflowSummaryPanel.d.ts.map +1 -1
  396. package/workflow/inspector/WorkflowSummaryPanel.js +2 -1
  397. package/workflow/inspector/WorkflowSummaryPanel.js.map +1 -1
  398. package/workflow/inspector/tabs/BranchesTab.d.ts.map +1 -1
  399. package/workflow/inspector/tabs/BranchesTab.js +5 -2
  400. package/workflow/inspector/tabs/BranchesTab.js.map +1 -1
  401. package/workflow/instance/WorkflowInstanceList.d.ts.map +1 -1
  402. package/workflow/instance/WorkflowInstanceList.js +2 -1
  403. package/workflow/instance/WorkflowInstanceList.js.map +1 -1
  404. package/workflow/node-shell/DiffBadge.d.ts.map +1 -1
  405. package/workflow/node-shell/DiffBadge.js +3 -2
  406. package/workflow/node-shell/DiffBadge.js.map +1 -1
  407. package/workflow/node-shell/ExecutionBadge.d.ts.map +1 -1
  408. package/workflow/node-shell/ExecutionBadge.js +5 -4
  409. package/workflow/node-shell/ExecutionBadge.js.map +1 -1
  410. package/workflow/node-shell/NodeActions.d.ts.map +1 -1
  411. package/workflow/node-shell/NodeActions.js +12 -11
  412. package/workflow/node-shell/NodeActions.js.map +1 -1
  413. package/workflow/task-detail/StructuredDataViewer.d.ts.map +1 -1
  414. package/workflow/task-detail/StructuredDataViewer.js +5 -1
  415. package/workflow/task-detail/StructuredDataViewer.js.map +1 -1
  416. package/workspace/EditorTabs.d.ts.map +1 -1
  417. package/workspace/EditorTabs.js +38 -37
  418. package/workspace/EditorTabs.js.map +1 -1
  419. package/workspace/ExplorerTree.d.ts.map +1 -1
  420. package/workspace/ExplorerTree.js +2 -1
  421. package/workspace/ExplorerTree.js.map +1 -1
  422. package/workspace/FileViewer.d.ts.map +1 -1
  423. package/workspace/FileViewer.js +2 -1
  424. package/workspace/FileViewer.js.map +1 -1
  425. package/workspace/PanelChip.d.ts.map +1 -1
  426. package/workspace/PanelChip.js +2 -1
  427. package/workspace/PanelChip.js.map +1 -1
  428. package/workspace/WorkspaceEditor.d.ts.map +1 -1
  429. package/workspace/WorkspaceEditor.js +2 -1
  430. package/workspace/WorkspaceEditor.js.map +1 -1
  431. package/workspace/WorkspaceSummary.d.ts.map +1 -1
  432. package/workspace/WorkspaceSummary.js +7 -2
  433. package/workspace/WorkspaceSummary.js.map +1 -1
  434. package/workspace/WorkspaceSurface.d.ts.map +1 -1
  435. package/workspace/WorkspaceSurface.js +12 -11
  436. package/workspace/WorkspaceSurface.js.map +1 -1
  437. package/datastore/CollectionRecordsBrowser.d.ts +0 -34
  438. package/datastore/CollectionRecordsBrowser.d.ts.map +0 -1
  439. package/datastore/CollectionRecordsBrowser.js +0 -223
  440. package/datastore/CollectionRecordsBrowser.js.map +0 -1
  441. package/datastore/CollectionSchemaView.d.ts +0 -29
  442. package/datastore/CollectionSchemaView.d.ts.map +0 -1
  443. package/datastore/CollectionSchemaView.js +0 -93
  444. package/datastore/CollectionSchemaView.js.map +0 -1
  445. package/datastore/DatastoreDetailView.d.ts +0 -44
  446. package/datastore/DatastoreDetailView.d.ts.map +0 -1
  447. package/datastore/DatastoreDetailView.js +0 -76
  448. package/datastore/DatastoreDetailView.js.map +0 -1
  449. package/datastore/DatastoreSyncReport.d.ts +0 -19
  450. package/datastore/DatastoreSyncReport.d.ts.map +0 -1
  451. package/datastore/DatastoreSyncReport.js +0 -45
  452. package/datastore/DatastoreSyncReport.js.map +0 -1
  453. package/datastore/DeleteDatastoreDialog.d.ts +0 -35
  454. package/datastore/DeleteDatastoreDialog.d.ts.map +0 -1
  455. package/datastore/DeleteDatastoreDialog.js +0 -90
  456. package/datastore/DeleteDatastoreDialog.js.map +0 -1
  457. package/datastore/FieldValueControl.d.ts +0 -55
  458. package/datastore/FieldValueControl.d.ts.map +0 -1
  459. package/datastore/FieldValueControl.js +0 -138
  460. package/datastore/FieldValueControl.js.map +0 -1
  461. package/datastore/RecordFilterBuilder.d.ts +0 -37
  462. package/datastore/RecordFilterBuilder.d.ts.map +0 -1
  463. package/datastore/RecordFilterBuilder.js +0 -122
  464. package/datastore/RecordFilterBuilder.js.map +0 -1
  465. package/datastore/RecordFormPanel.d.ts +0 -45
  466. package/datastore/RecordFormPanel.d.ts.map +0 -1
  467. package/datastore/RecordFormPanel.js +0 -215
  468. package/datastore/RecordFormPanel.js.map +0 -1
  469. package/datastore/index.d.ts +0 -43
  470. package/datastore/index.d.ts.map +0 -1
  471. package/datastore/index.js +0 -22
  472. package/datastore/index.js.map +0 -1
  473. package/datastore/recordFilter.d.ts +0 -62
  474. package/datastore/recordFilter.d.ts.map +0 -1
  475. package/datastore/recordFilter.js +0 -104
  476. package/datastore/recordFilter.js.map +0 -1
  477. package/datastore/recordValues.d.ts +0 -85
  478. package/datastore/recordValues.d.ts.map +0 -1
  479. package/datastore/recordValues.js +0 -282
  480. package/datastore/recordValues.js.map +0 -1
  481. package/datastore/useDatastore.d.ts +0 -39
  482. package/datastore/useDatastore.d.ts.map +0 -1
  483. package/datastore/useDatastore.js +0 -44
  484. package/datastore/useDatastore.js.map +0 -1
  485. package/datastore/useDatastoreCount.d.ts +0 -50
  486. package/datastore/useDatastoreCount.d.ts.map +0 -1
  487. package/datastore/useDatastoreCount.js +0 -27
  488. package/datastore/useDatastoreCount.js.map +0 -1
  489. package/datastore/useDatastoreDescription.d.ts +0 -54
  490. package/datastore/useDatastoreDescription.d.ts.map +0 -1
  491. package/datastore/useDatastoreDescription.js +0 -50
  492. package/datastore/useDatastoreDescription.js.map +0 -1
  493. package/datastore/useDatastoreList.d.ts +0 -57
  494. package/datastore/useDatastoreList.d.ts.map +0 -1
  495. package/datastore/useDatastoreList.js +0 -29
  496. package/datastore/useDatastoreList.js.map +0 -1
  497. package/datastore/useDatastoreSearch.d.ts +0 -19
  498. package/datastore/useDatastoreSearch.d.ts.map +0 -1
  499. package/datastore/useDatastoreSearch.js +0 -22
  500. package/datastore/useDatastoreSearch.js.map +0 -1
  501. package/datastore/useDeleteDatastore.d.ts +0 -53
  502. package/datastore/useDeleteDatastore.d.ts.map +0 -1
  503. package/datastore/useDeleteDatastore.js +0 -40
  504. package/datastore/useDeleteDatastore.js.map +0 -1
  505. package/datastore/useDeleteRecord.d.ts +0 -34
  506. package/datastore/useDeleteRecord.d.ts.map +0 -1
  507. package/datastore/useDeleteRecord.js +0 -43
  508. package/datastore/useDeleteRecord.js.map +0 -1
  509. package/datastore/useInsertRecord.d.ts +0 -50
  510. package/datastore/useInsertRecord.d.ts.map +0 -1
  511. package/datastore/useInsertRecord.js +0 -55
  512. package/datastore/useInsertRecord.js.map +0 -1
  513. package/datastore/useRecordCollection.d.ts +0 -104
  514. package/datastore/useRecordCollection.d.ts.map +0 -1
  515. package/datastore/useRecordCollection.js +0 -136
  516. package/datastore/useRecordCollection.js.map +0 -1
  517. package/datastore/useRecordList.d.ts +0 -66
  518. package/datastore/useRecordList.d.ts.map +0 -1
  519. package/datastore/useRecordList.js +0 -58
  520. package/datastore/useRecordList.js.map +0 -1
  521. package/datastore/useUpdateRecord.d.ts +0 -52
  522. package/datastore/useUpdateRecord.d.ts.map +0 -1
  523. package/datastore/useUpdateRecord.js +0 -55
  524. package/datastore/useUpdateRecord.js.map +0 -1
  525. package/src/agent/__tests__/AgentDetailView.datastores.test.tsx +0 -166
  526. package/src/datastore/CollectionRecordsBrowser.tsx +0 -570
  527. package/src/datastore/CollectionSchemaView.tsx +0 -247
  528. package/src/datastore/DatastoreDetailView.tsx +0 -201
  529. package/src/datastore/DatastoreSyncReport.tsx +0 -105
  530. package/src/datastore/DeleteDatastoreDialog.tsx +0 -202
  531. package/src/datastore/FieldValueControl.tsx +0 -289
  532. package/src/datastore/RecordFilterBuilder.tsx +0 -422
  533. package/src/datastore/RecordFormPanel.tsx +0 -432
  534. package/src/datastore/__tests__/CollectionRecordsBrowser.test.tsx +0 -245
  535. package/src/datastore/__tests__/DeleteDatastoreDialog.test.tsx +0 -133
  536. package/src/datastore/__tests__/FieldValueControl.test.tsx +0 -160
  537. package/src/datastore/__tests__/RecordFilterBuilder.test.tsx +0 -155
  538. package/src/datastore/__tests__/RecordFormPanel.test.tsx +0 -227
  539. package/src/datastore/__tests__/recordFilter.test.ts +0 -169
  540. package/src/datastore/__tests__/recordMutations.test.tsx +0 -195
  541. package/src/datastore/__tests__/recordValues.test.ts +0 -359
  542. package/src/datastore/__tests__/schemaAndSyncViews.test.tsx +0 -142
  543. package/src/datastore/__tests__/useDatastoreDescription.test.tsx +0 -143
  544. package/src/datastore/__tests__/useRecordCollection.test.tsx +0 -250
  545. package/src/datastore/__tests__/useRecordList.test.tsx +0 -85
  546. package/src/datastore/index.ts +0 -111
  547. package/src/datastore/recordFilter.ts +0 -154
  548. package/src/datastore/recordValues.ts +0 -327
  549. package/src/datastore/useDatastore.ts +0 -67
  550. package/src/datastore/useDatastoreCount.ts +0 -69
  551. package/src/datastore/useDatastoreDescription.ts +0 -90
  552. package/src/datastore/useDatastoreList.ts +0 -79
  553. package/src/datastore/useDatastoreSearch.ts +0 -39
  554. package/src/datastore/useDeleteDatastore.ts +0 -87
  555. package/src/datastore/useDeleteRecord.ts +0 -77
  556. package/src/datastore/useInsertRecord.ts +0 -92
  557. package/src/datastore/useRecordCollection.ts +0 -256
  558. package/src/datastore/useRecordList.ts +0 -131
  559. package/src/datastore/useUpdateRecord.ts +0 -95
@@ -36,7 +36,7 @@ function entry(
36
36
  ): ManifestPreviewEntry {
37
37
  return {
38
38
  document: {
39
- handler: { yamlKind: "datastore", displayName: "Datastore" },
39
+ handler: { yamlKind: "mcpserver", displayName: "McpServer" },
40
40
  name: slug,
41
41
  slug,
42
42
  org: "acme",
@@ -55,7 +55,7 @@ const applyAllMock = vi.fn(async () => applyAllResult);
55
55
  vi.mock("../useApplyManifest", () => ({
56
56
  useApplyManifest: (): UseApplyManifestReturn =>
57
57
  ({
58
- content: "kind: Datastore",
58
+ content: "kind: McpServer",
59
59
  setContent: vi.fn(),
60
60
  readFile: vi.fn(),
61
61
  entries: mockEntries,
@@ -1,13 +1,13 @@
1
1
  // Tests for the shared Edit-YAML dialog's apply-error affordance
2
2
  // (DD-008 SD-6): the server's refusal renders verbatim with
3
- // Try-again/Dismiss — shared by every kind (McpServer, Agent, Skill,
4
- // Datastore), so the datastore collection-removal rejection and any
5
- // other apply-time guard get the same acknowledge-and-retry treatment.
3
+ // Try-again/Dismiss — shared by every kind (McpServer, Agent, Skill),
4
+ // so any apply-time guard gets the same acknowledge-and-retry
5
+ // treatment.
6
6
 
7
7
  import { describe, it, expect, vi, beforeAll, afterEach } from "vitest";
8
8
  import { render, screen, cleanup, fireEvent } from "@testing-library/react";
9
9
  import { create } from "@bufbuild/protobuf";
10
- import { DatastoreSchema } from "@stigmer/protos/ai/stigmer/agentic/datastore/v1/api_pb";
10
+ import { McpServerSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
11
11
  import { EditResourceYamlDialog } from "../EditResourceYamlDialog";
12
12
  import type { useEditResourceYaml } from "../useEditResourceYaml";
13
13
 
@@ -34,7 +34,7 @@ let editState: Partial<EditState>;
34
34
 
35
35
  vi.mock("../useEditResourceYaml", () => ({
36
36
  useEditResourceYaml: () => ({
37
- yaml: "kind: Datastore",
37
+ yaml: "kind: McpServer",
38
38
  setYaml: vi.fn(),
39
39
  validation: { status: "valid" as const },
40
40
  target: { action: "update" as const, slug: "clinic" },
@@ -54,8 +54,8 @@ vi.mock("../YamlEditor", () => ({
54
54
  YamlEditor: () => <div data-testid="yaml-editor" />,
55
55
  }));
56
56
 
57
- const RESOURCE = create(DatastoreSchema, {
58
- metadata: { id: "dst_1", slug: "clinic", org: "acme", name: "Clinic" },
57
+ const RESOURCE = create(McpServerSchema, {
58
+ metadata: { id: "mcp_1", slug: "clinic", org: "acme", name: "Clinic" },
59
59
  });
60
60
 
61
61
  function renderDialog() {
@@ -73,14 +73,14 @@ describe("EditResourceYamlDialog — apply-error affordance", () => {
73
73
  it("renders the server's refusal verbatim with Try again and Dismiss", () => {
74
74
  editState = {
75
75
  error: new Error(
76
- 'collection "old_notes" was removed from the spec; re-apply with the removal acknowledged',
76
+ 'spec change refused by an apply-time guard; re-apply with the change acknowledged',
77
77
  ),
78
78
  };
79
79
  renderDialog();
80
80
 
81
81
  const alert = screen.getByRole("alert");
82
82
  expect(alert.textContent).toContain(
83
- 'collection "old_notes" was removed from the spec',
83
+ "spec change refused by an apply-time guard",
84
84
  );
85
85
  expect(screen.getByRole("button", { name: "Try again" })).toBeTruthy();
86
86
  expect(screen.getByRole("button", { name: "Dismiss error" })).toBeTruthy();
@@ -14,7 +14,11 @@ import {
14
14
  type EnvVarFormSubmitOptions,
15
15
  } from "../environment/EnvVarForm.js";
16
16
  import { McpToolSelector } from "./McpToolSelector.js";
17
- import type { OAuthConnectPhase } from "./useMcpServerOAuthConnect.js";
17
+ import { VendorApprovalBlockedNotice } from "./VendorApprovalBlockedNotice.js";
18
+ import {
19
+ getOAuthConnectErrorMessage,
20
+ type OAuthConnectPhase,
21
+ } from "./useMcpServerOAuthConnect.js";
18
22
 
19
23
  // ---------------------------------------------------------------------------
20
24
  // Credential sub-props
@@ -93,8 +97,27 @@ export interface McpServerOAuthSignInProps {
93
97
  readonly onClearDisconnectError?: () => void;
94
98
  /** Error from the most recent failed OAuth attempt, or `null`. */
95
99
  readonly error: Error | null;
100
+ /**
101
+ * The OAuth flow phase in which {@link error} was thrown, or `null`.
102
+ *
103
+ * Threading it lets the panel compose error copy through
104
+ * `getOAuthConnectErrorMessage`: a `"connecting"`-phase failure means
105
+ * sign-in SUCCEEDED and only the chained tool discovery failed —
106
+ * without this, the raw RPC error reads as a failed sign-in
107
+ * (stigmer/stigmer#418).
108
+ */
109
+ readonly failedPhase?: OAuthConnectPhase | null;
96
110
  /** Clear the OAuth error state. */
97
111
  readonly onClearError: () => void;
112
+ /**
113
+ * `true` when the user is signed in but the server has no discovered
114
+ * tools — the "signed in — tools not discovered yet" state
115
+ * (stigmer/stigmer#229/#418). The action button reads "Discover tools"
116
+ * and `onSignIn` is expected to run bare discovery instead of the
117
+ * OAuth popup. The caller owns that branch; this prop only drives
118
+ * presentation.
119
+ */
120
+ readonly isOAuthStranded?: boolean;
98
121
  /**
99
122
  * `true` when the platform's OAuth app is pending vendor approval.
100
123
  * Disables the sign-in button and shows an informational message.
@@ -120,6 +143,16 @@ export interface McpServerOAuthSignInProps {
120
143
  * `true` when an org-level BYOA override is active.
121
144
  */
122
145
  readonly isOrgOAuthApp?: boolean;
146
+ /**
147
+ * Whether a manually-entered static token can authenticate this server
148
+ * (`false` for `oauth_only` servers whose endpoint rejects static
149
+ * tokens). Consulted by the vendor-approval-blocked message so it never
150
+ * recommends manual entry on a server where it cannot work.
151
+ * When omitted, falls back to whether `onSwitchToManual` is wired on
152
+ * {@link McpServerConfigPanelProps} — callers gate that affordance on
153
+ * the same fact.
154
+ */
155
+ readonly manualEntrySupported?: boolean;
123
156
  /**
124
157
  * Open the BYOA form. The parent is responsible for rendering the
125
158
  * form/dialog and handling the mutation.
@@ -331,6 +364,8 @@ export function McpServerConfigPanel({
331
364
  disconnectError={oauthSignIn.disconnectError}
332
365
  onClearDisconnectError={oauthSignIn.onClearDisconnectError}
333
366
  error={oauthSignIn.error}
367
+ failedPhase={oauthSignIn.failedPhase}
368
+ isOAuthStranded={oauthSignIn.isOAuthStranded}
334
369
  onClearError={oauthSignIn.onClearError}
335
370
  isVendorApprovalPending={oauthSignIn.isVendorApprovalPending}
336
371
  isVendorApprovalBlocked={oauthSignIn.isVendorApprovalBlocked}
@@ -340,6 +375,7 @@ export function McpServerConfigPanel({
340
375
  onBringOwnApp={oauthSignIn.onBringOwnApp}
341
376
  onRemoveOrgApp={oauthSignIn.onRemoveOrgApp}
342
377
  isRemovingOrgApp={oauthSignIn.isRemovingOrgApp}
378
+ manualEntrySupported={oauthSignIn.manualEntrySupported}
343
379
  onSwitchToManual={onSwitchToManual}
344
380
  />
345
381
  )}
@@ -451,6 +487,8 @@ function InlineOAuthSignIn({
451
487
  disconnectError,
452
488
  onClearDisconnectError,
453
489
  error,
490
+ failedPhase,
491
+ isOAuthStranded,
454
492
  onClearError,
455
493
  isVendorApprovalPending,
456
494
  isVendorApprovalBlocked,
@@ -460,6 +498,7 @@ function InlineOAuthSignIn({
460
498
  onBringOwnApp,
461
499
  onRemoveOrgApp,
462
500
  isRemovingOrgApp,
501
+ manualEntrySupported,
463
502
  onSwitchToManual,
464
503
  }: {
465
504
  readonly serverName: string;
@@ -472,6 +511,8 @@ function InlineOAuthSignIn({
472
511
  readonly disconnectError?: Error | null;
473
512
  readonly onClearDisconnectError?: () => void;
474
513
  readonly error: Error | null;
514
+ readonly failedPhase?: OAuthConnectPhase | null;
515
+ readonly isOAuthStranded?: boolean;
475
516
  readonly onClearError: () => void;
476
517
  readonly isVendorApprovalPending?: boolean;
477
518
  readonly isVendorApprovalBlocked?: boolean;
@@ -481,6 +522,7 @@ function InlineOAuthSignIn({
481
522
  readonly onBringOwnApp?: () => void;
482
523
  readonly onRemoveOrgApp?: () => Promise<void>;
483
524
  readonly isRemovingOrgApp?: boolean;
525
+ readonly manualEntrySupported?: boolean;
484
526
  readonly onSwitchToManual?: () => void;
485
527
  }) {
486
528
  const [disconnectPhase, setDisconnectPhase] = useState<InlineDisconnectPhase>("idle");
@@ -494,17 +536,28 @@ function InlineOAuthSignIn({
494
536
  phase === "completing" ||
495
537
  phase === "connecting";
496
538
 
497
- const signInDisabled = isBusy || (!!blocked && !isOrgOAuthApp);
539
+ // Stranded ("signed in tools not discovered yet", stigmer/stigmer#418):
540
+ // the action is bare tool discovery, which needs no OAuth app — so the
541
+ // vendor-approval block must not gate it.
542
+ const stranded = !!isOAuthStranded;
543
+
544
+ const signInDisabled = isBusy || (!!blocked && !isOrgOAuthApp && !stranded);
498
545
  const anyBusy = isBusy || !!isDisconnecting || !!isRemovingOrgApp;
499
546
 
500
547
  const needsReAuth =
501
548
  connectionHealth === OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_TOKEN_EXPIRED;
502
549
 
503
- const status = inlineHealthProps(
504
- connectionHealth,
505
- isConnected,
506
- !!isVendorApprovalPending && !isOrgOAuthApp,
507
- );
550
+ const status = stranded
551
+ ? {
552
+ textClass: "stg:text-amber-600 stg:dark:text-amber-400",
553
+ dotClass: "stg:bg-amber-500",
554
+ label: "Signed in \u2014 tools not discovered yet",
555
+ }
556
+ : inlineHealthProps(
557
+ connectionHealth,
558
+ isConnected,
559
+ !!isVendorApprovalPending && !isOrgOAuthApp,
560
+ );
508
561
 
509
562
  const showDisconnectLink =
510
563
  isConnected && onDisconnect && !anyBusy && disconnectPhase === "idle";
@@ -668,7 +721,7 @@ function InlineOAuthSignIn({
668
721
  disabled={signInDisabled}
669
722
  className={cn(
670
723
  "stg:inline-flex stg:items-center stg:gap-1 stg:rounded stg:px-2 stg:py-0.5 stg:text-[0.65rem] stg:font-medium",
671
- isConnected && !needsReAuth
724
+ isConnected && !needsReAuth && !stranded
672
725
  ? "stg:text-muted-foreground stg:hover:text-foreground stg:hover:bg-accent-hover"
673
726
  : "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover",
674
727
  "stg:disabled:pointer-events-none stg:disabled:opacity-50",
@@ -676,6 +729,8 @@ function InlineOAuthSignIn({
676
729
  >
677
730
  {isBusy ? (
678
731
  <InlineSpinner />
732
+ ) : stranded ? (
733
+ "Discover tools"
679
734
  ) : isOrgOAuthApp && !isConnected ? (
680
735
  "Sign in with your app"
681
736
  ) : isConnected && !needsReAuth ? (
@@ -689,34 +744,16 @@ function InlineOAuthSignIn({
689
744
  </div>
690
745
 
691
746
  {/* Vendor approval blocked message with BYOA CTA */}
692
- {blocked && !isConnected && !isOrgOAuthApp && (
693
- <div className="stg:text-[0.65rem] stg:text-amber-700 stg:dark:text-amber-300">
694
- <p>
695
- OAuth sign-in is pending vendor approval.
696
- {canBringOwnApp && onBringOwnApp
697
- ? " You can use your own OAuth app or enter a token manually."
698
- : ""}
699
- </p>
700
- {canBringOwnApp && onBringOwnApp && (
701
- <button
702
- type="button"
703
- onClick={onBringOwnApp}
704
- className="stg:mt-1 stg:inline-flex stg:items-center stg:gap-1 stg:rounded stg:bg-amber-600 stg:px-2 stg:py-0.5 stg:text-[0.6rem] stg:font-medium stg:text-white stg:hover:bg-amber-700 stg:dark:bg-amber-500 stg:dark:text-amber-950 stg:dark:hover:bg-amber-400"
705
- >
706
- Use your own OAuth app
707
- </button>
708
- )}
709
- {vendorApprovalDocsUrl && !canBringOwnApp && (
710
- <a
711
- href={vendorApprovalDocsUrl}
712
- target="_blank"
713
- rel="noopener noreferrer"
714
- className="stg:underline stg:decoration-amber-600/40 stg:underline-offset-2 stg:hover:decoration-amber-600 stg:dark:decoration-amber-400/40 stg:dark:hover:decoration-amber-400"
715
- >
716
- Learn how to bring your own token
717
- </a>
718
- )}
719
- </div>
747
+ {!isConnected && !isOrgOAuthApp && (
748
+ <VendorApprovalBlockedNotice
749
+ blocked={!!blocked}
750
+ pending={!!isVendorApprovalPending}
751
+ manualEntrySupported={manualEntrySupported ?? Boolean(onSwitchToManual)}
752
+ canBringOwnApp={Boolean(canBringOwnApp && onBringOwnApp)}
753
+ docsUrl={vendorApprovalDocsUrl ?? null}
754
+ onBringOwnApp={onBringOwnApp}
755
+ compact
756
+ />
720
757
  )}
721
758
 
722
759
  {/* Org override indicator when not connected */}
@@ -728,7 +765,12 @@ function InlineOAuthSignIn({
728
765
 
729
766
  {error && (
730
767
  <div className="stg:flex stg:items-start stg:gap-1.5 stg:text-[0.65rem] stg:text-destructive" role="alert">
731
- <span className="stg:flex-1">{getUserMessage(error)}</span>
768
+ {/* Phase-aware copy: a "connecting"-phase failure means sign-in
769
+ succeeded and only tool discovery failed — the raw RPC message
770
+ alone reads as a failed sign-in (stigmer/stigmer#418). */}
771
+ <span className="stg:flex-1">
772
+ {getOAuthConnectErrorMessage(error, failedPhase ?? null)}
773
+ </span>
732
774
  <div className="stg:flex stg:shrink-0 stg:items-center stg:gap-1.5">
733
775
  {isRetryableError(error) && (
734
776
  <button
@@ -13,6 +13,7 @@ import { EnvVarForm } from "../environment/EnvVarForm.js";
13
13
  import { ErrorMessage } from "../error/ErrorMessage.js";
14
14
  import { StdioSandboxNotice } from "./StdioSandboxNotice.js";
15
15
  import { OAuthRequiredNotice } from "./OAuthRequiredNotice.js";
16
+ import { VendorApprovalBlockedNotice } from "./VendorApprovalBlockedNotice.js";
16
17
 
17
18
  /** Props for {@link McpServerConnectDialog}. */
18
19
  export interface McpServerConnectDialogProps {
@@ -33,6 +34,17 @@ export interface McpServerConnectDialogProps {
33
34
  readonly onClose: () => void;
34
35
  /** Called after a successful connect with the server name. */
35
36
  readonly onConnected?: (serverName: string) => void;
37
+ /**
38
+ * Called when the user needs the server's detail page — today the
39
+ * "Use your own OAuth app" escape hatch shown when the platform OAuth
40
+ * app is vendor-approval blocked on an `oauth_only` server, since the
41
+ * BYOA form lives on the detail page, not in this dialog.
42
+ *
43
+ * The host owns navigation (and should close the dialog itself if its
44
+ * route keeps this component mounted). When omitted, the blocked notice
45
+ * still explains the state; only the navigation affordance is dropped.
46
+ */
47
+ readonly onOpenDetails?: () => void;
36
48
  /** Additional CSS classes for the dialog element. */
37
49
  readonly className?: string;
38
50
  }
@@ -73,6 +85,7 @@ export function McpServerConnectDialog({
73
85
  open,
74
86
  onClose,
75
87
  onConnected,
88
+ onOpenDetails,
76
89
  className,
77
90
  }: McpServerConnectDialogProps) {
78
91
  const dialogRef = useRef<HTMLDialogElement>(null);
@@ -125,6 +138,7 @@ export function McpServerConnectDialog({
125
138
  activeOrg={resolvedOrg}
126
139
  onClose={onClose}
127
140
  onConnected={onConnected}
141
+ onOpenDetails={onOpenDetails}
128
142
  />
129
143
  </div>
130
144
  </dialog>
@@ -137,12 +151,14 @@ function ConnectDialogContent({
137
151
  activeOrg,
138
152
  onClose,
139
153
  onConnected,
154
+ onOpenDetails,
140
155
  }: {
141
156
  readonly org: string;
142
157
  readonly slug: string;
143
158
  readonly activeOrg: string;
144
159
  readonly onClose: () => void;
145
160
  readonly onConnected?: (serverName: string) => void;
161
+ readonly onOpenDetails?: () => void;
146
162
  }) {
147
163
  const { mcpServer, isLoading: isServerLoading, error: serverError } = useMcpServer(org, slug);
148
164
  const creds = useMcpServerCredentials(activeOrg, mcpServer);
@@ -327,11 +343,16 @@ function ConnectDialogContent({
327
343
  phase={oauth.phase}
328
344
  onSignIn={handleOAuthSignIn}
329
345
  isVendorApprovalBlocked={creds.isVendorApprovalBlocked}
346
+ isVendorApprovalPending={creds.isVendorApprovalPending}
347
+ manualEntrySupported={creds.manualEntrySupported}
348
+ canBringOwnApp={creds.canBringOwnApp}
349
+ vendorApprovalDocsUrl={creds.vendorApprovalDocsUrl}
330
350
  onSwitchToManual={
331
351
  creds.manualEntrySupported
332
352
  ? () => creds.setManualOverride(true)
333
353
  : undefined
334
354
  }
355
+ onOpenDetails={onOpenDetails}
335
356
  disabled={isConnectingPhase}
336
357
  />
337
358
  )}
@@ -437,15 +458,26 @@ function OAuthSection({
437
458
  phase,
438
459
  onSignIn,
439
460
  isVendorApprovalBlocked,
461
+ isVendorApprovalPending,
462
+ manualEntrySupported,
463
+ canBringOwnApp,
464
+ vendorApprovalDocsUrl,
440
465
  onSwitchToManual,
466
+ onOpenDetails,
441
467
  disabled,
442
468
  }: {
443
469
  readonly isConnected: boolean;
444
470
  readonly phase: OAuthConnectPhase;
445
471
  readonly onSignIn: () => void;
446
472
  readonly isVendorApprovalBlocked: boolean;
473
+ readonly isVendorApprovalPending: boolean;
474
+ readonly manualEntrySupported: boolean;
475
+ readonly canBringOwnApp: boolean;
476
+ readonly vendorApprovalDocsUrl: string | null;
447
477
  /** When omitted (e.g. `oauth_only` servers), no manual-entry link is shown. */
448
478
  readonly onSwitchToManual?: () => void;
479
+ /** Navigates to the detail page, where the BYOA form lives. */
480
+ readonly onOpenDetails?: () => void;
449
481
  readonly disabled?: boolean;
450
482
  }) {
451
483
  if (isConnected) {
@@ -482,11 +514,15 @@ function OAuthSection({
482
514
  {isInProgress && <LoadingSpinner size="sm" />}
483
515
  {isInProgress ? (phaseLabel[phase] ?? "Connecting...") : "Sign in with OAuth"}
484
516
  </button>
485
- {isVendorApprovalBlocked && onSwitchToManual && (
486
- <p className="stg:text-xs stg:text-muted-foreground">
487
- OAuth sign-in is pending vendor approval. You can enter your token manually instead.
488
- </p>
489
- )}
517
+ <VendorApprovalBlockedNotice
518
+ blocked={isVendorApprovalBlocked}
519
+ pending={isVendorApprovalPending}
520
+ manualEntrySupported={manualEntrySupported}
521
+ canBringOwnApp={canBringOwnApp}
522
+ docsUrl={vendorApprovalDocsUrl}
523
+ onBringOwnApp={onOpenDetails}
524
+ className="stg:rounded-md stg:border stg:border-amber-500/20"
525
+ />
490
526
  {onSwitchToManual && (
491
527
  <button
492
528
  type="button"
@@ -26,11 +26,13 @@ import {
26
26
  import type { OAuthConnectPhase } from "./useMcpServerOAuthConnect.js";
27
27
  import { StdioSandboxNotice } from "./StdioSandboxNotice.js";
28
28
  import { OAuthRequiredNotice } from "./OAuthRequiredNotice.js";
29
+ import { VendorApprovalBlockedNotice } from "./VendorApprovalBlockedNotice.js";
29
30
  import { useDisconnectOAuth } from "./useDisconnectOAuth.js";
30
31
  import { useOrgOAuthApp } from "./useOrgOAuthApp.js";
31
32
  import { OAuthAppForm } from "./OAuthAppForm.js";
32
33
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
33
34
  import { ErrorMessage } from "../error/ErrorMessage.js";
35
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../internal/tooltip.js";
34
36
  import { EnvVarForm } from "../environment/EnvVarForm.js";
35
37
  import type { EnvVarFormVariable } from "../environment/EnvVarForm.js";
36
38
  import { VisibilityBadge } from "../library/VisibilitySelector.js";
@@ -1135,38 +1137,15 @@ function ConnectBar({
1135
1137
 
1136
1138
  {/* Vendor approval blocked banner with BYOA CTA */}
1137
1139
  {oauthSignInDisabled && (
1138
- <div className="stg:flex stg:items-start stg:gap-2 stg:border-t stg:border-amber-500/20 stg:bg-amber-500/5 stg:px-3 stg:py-2">
1139
- <WarningIcon className="stg:mt-0.5 stg:size-3.5 stg:shrink-0 stg:text-amber-600 stg:dark:text-amber-400" />
1140
- <div className="stg:flex-1 stg:text-xs stg:text-amber-700 stg:dark:text-amber-300">
1141
- <p>
1142
- The platform&apos;s OAuth app is awaiting vendor approval.
1143
- {canBringOwnApp
1144
- ? " You can use your own OAuth app or enter a token manually."
1145
- : " You can still connect by entering your own token manually."}
1146
- </p>
1147
- {canBringOwnApp && (
1148
- <button
1149
- type="button"
1150
- onClick={onBringOwnApp}
1151
- data-cursor-target="byoa-cta-button"
1152
- className="stg:mt-1.5 stg:inline-flex stg:items-center stg:gap-1 stg:rounded-md stg:bg-amber-600 stg:px-2.5 stg:py-1 stg:text-[11px] stg:font-medium stg:text-white stg:hover:bg-amber-700 stg:dark:bg-amber-500 stg:dark:text-amber-950 stg:dark:hover:bg-amber-400"
1153
- >
1154
- Use your own OAuth app
1155
- </button>
1156
- )}
1157
- {vendorApprovalDocsUrl && !canBringOwnApp && (
1158
- <a
1159
- href={vendorApprovalDocsUrl}
1160
- target="_blank"
1161
- rel="noopener noreferrer"
1162
- className="stg:mt-1 stg:inline-flex stg:items-center stg:gap-1 stg:underline stg:decoration-amber-600/40 stg:underline-offset-2 stg:hover:decoration-amber-600 stg:dark:decoration-amber-400/40 stg:dark:hover:decoration-amber-400"
1163
- >
1164
- Learn how to bring your own token
1165
- <ExternalLinkIcon className="stg:size-3 stg:shrink-0" />
1166
- </a>
1167
- )}
1168
- </div>
1169
- </div>
1140
+ <VendorApprovalBlockedNotice
1141
+ blocked
1142
+ pending={isVendorApprovalPending}
1143
+ manualEntrySupported={manualEntrySupported}
1144
+ canBringOwnApp={canBringOwnApp}
1145
+ docsUrl={vendorApprovalDocsUrl}
1146
+ onBringOwnApp={onBringOwnApp}
1147
+ className="stg:border-t stg:border-amber-500/20"
1148
+ />
1170
1149
  )}
1171
1150
 
1172
1151
  {/* Secondary actions: manual entry, BYOA, back to OAuth. Suppressed
@@ -1660,13 +1639,18 @@ function renderHeaderValue(value: string): React.ReactNode {
1660
1639
  parts.push(value.slice(lastIndex, match.index));
1661
1640
  }
1662
1641
  parts.push(
1663
- <span
1664
- key={match.index}
1665
- className="stg:inline-flex stg:items-center stg:gap-0.5 stg:rounded stg:bg-primary-subtle stg:px-1 stg:py-px stg:text-[10px] stg:font-medium stg:text-primary"
1666
- title={`Resolved from environment variable: ${match[1]}`}
1667
- >
1668
- {match[0]}
1669
- </span>,
1642
+ <Tooltip key={match.index}>
1643
+ <TooltipTrigger
1644
+ render={
1645
+ <span className="stg:inline-flex stg:items-center stg:gap-0.5 stg:rounded stg:bg-primary-subtle stg:px-1 stg:py-px stg:text-[10px] stg:font-medium stg:text-primary" />
1646
+ }
1647
+ >
1648
+ {match[0]}
1649
+ </TooltipTrigger>
1650
+ <TooltipContent side="top">
1651
+ {`Resolved from environment variable: ${match[1]}`}
1652
+ </TooltipContent>
1653
+ </Tooltip>,
1670
1654
  );
1671
1655
  lastIndex = match.index + match[0].length;
1672
1656
  }
@@ -13,6 +13,7 @@ import { cn } from "@stigmer/theme";
13
13
  import type { EnvVarInput, McpServerUsageInput, ResourceRef } from "@stigmer/sdk";
14
14
  import type { SearchResult } from "@stigmer/protos/ai/stigmer/search/v1/io_pb";
15
15
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
16
+ import { OAuthConnectionHealth } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/io_pb";
16
17
  import { VendorApprovalStatus } from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/spec_pb";
17
18
  import type { EnvVarFormSubmitOptions } from "../environment/EnvVarForm.js";
18
19
  import { useMcpServerSearch } from "./useMcpServerSearch.js";
@@ -20,6 +21,7 @@ import { useScrollShadows } from "../internal/useScrollShadows.js";
20
21
  import { ScrollFade } from "../internal/ScrollFade.js";
21
22
  import { McpServerConfigPanel } from "./McpServerConfigPanel.js";
22
23
  import type { McpServerSetupEntry } from "./mcpServerSetupReducer.js";
24
+ import { useMcpServerConnect } from "./useMcpServerConnect.js";
23
25
  import { useMcpServerOAuthConnect } from "./useMcpServerOAuthConnect.js";
24
26
  import { ScopeToggle } from "../library/ScopeToggle.js";
25
27
  import type { ResourceListScope } from "../search/index.js";
@@ -269,6 +271,17 @@ export function McpServerPicker({
269
271
  const { results, isLoading, error, query, setQuery } =
270
272
  useMcpServerSearch(org, { scope: activeScope });
271
273
  const oauth = useMcpServerOAuthConnect();
274
+ // Bare tool-discovery `connect`, used when sign-in already succeeded and
275
+ // only the chained discovery leg failed — relaunching the OAuth popup
276
+ // would burn a consent round for nothing (stigmer/stigmer#418).
277
+ const discovery = useMcpServerConnect();
278
+ // The oauth/discovery hooks are single instances shared by every server
279
+ // in the picker, so their error/phase/failedPhase signals are only
280
+ // meaningful for the server an attempt was started for. Without this
281
+ // key, server A's discovery failure would render under server B's
282
+ // configure view — and worse, make B's sign-in click retry discovery
283
+ // for a grant B never had.
284
+ const [oauthAttemptKey, setOauthAttemptKey] = useState<string | null>(null);
272
285
 
273
286
  const [focusIndex, setFocusIndex] = useState(-1);
274
287
  const [view, setView] = useState<PickerView>(() =>
@@ -431,28 +444,105 @@ export function McpServerPicker({
431
444
  (oauthStatus?.vendorApprovalStatus === VendorApprovalStatus.PENDING ||
432
445
  oauthStatus?.vendorApprovalStatus === VendorApprovalStatus.REJECTED);
433
446
 
447
+ // System env vars are only injected when the server declares them —
448
+ // the dialog and detail view pass these on every OAuth chain and
449
+ // bare connect; the picker must too.
450
+ const declaredEnvKeys = Object.keys(entry.mcpServer.spec?.env ?? {});
451
+
452
+ // Scope the shared hooks' signals to the server they belong to.
453
+ const isOwnOAuthAttempt = oauthAttemptKey === view.serverKey;
454
+ const oauthError = isOwnOAuthAttempt ? oauth.error : null;
455
+ const oauthFailedPhase = isOwnOAuthAttempt ? oauth.failedPhase : null;
456
+ const discoveryError = isOwnOAuthAttempt ? discovery.error : null;
457
+
458
+ // "Signed in — tools not discovered yet" (the stigmer/stigmer#229
459
+ // two-act persistence gap, picker arm: stigmer/stigmer#418). Two
460
+ // signals, mirroring the detail view:
461
+ // - In-flow: the OAuth chain broke in its "connecting" phase, so
462
+ // sign-in succeeded and only discovery failed — the entry's own
463
+ // data is still stale at this point.
464
+ // - Server truth: the entry resolved ready off a usable grant with
465
+ // nothing discovered. Survives popover close/reopen, where the
466
+ // in-flow signal dies with the hook. Token-expired grants are
467
+ // excluded — re-auth, not discovery, is their next step.
468
+ const isDiscoveryRetry = oauthFailedPhase === "connecting";
469
+ const grantUsable =
470
+ entry.oauthConnectionHealth ===
471
+ OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_HEALTHY ||
472
+ entry.oauthConnectionHealth ===
473
+ OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_TOKEN_EXPIRED_REFRESHABLE;
474
+ const isOAuthStranded =
475
+ isDiscoveryRetry ||
476
+ (hasOAuth &&
477
+ entry.status === "ready" &&
478
+ grantUsable &&
479
+ entry.discoveredTools.length === 0);
480
+
434
481
  const oauthSignInProps =
435
482
  hasOAuth && !isManualOverride
436
483
  ? {
437
484
  onSignIn: async () => {
438
485
  if (!entry.mcpServer.metadata?.id) return;
486
+ const serverId = entry.mcpServer.metadata.id;
487
+ const connectOrg = activeOrg ?? org;
488
+ setOauthAttemptKey(view.serverKey);
489
+
490
+ if (isOAuthStranded) {
491
+ // Sign-in already succeeded — the grant is stored
492
+ // server-side. Retry bare discovery; never relaunch the
493
+ // popup (stigmer/stigmer#418).
494
+ try {
495
+ await discovery.connect(
496
+ serverId,
497
+ connectOrg,
498
+ undefined,
499
+ declaredEnvKeys,
500
+ );
501
+ // Discovery succeeded — retire the chain's stale
502
+ // failure and re-evaluate the entry so it resolves
503
+ // ready with the discovered tools.
504
+ oauth.clearError();
505
+ setup.onServerAdded(ref);
506
+ } catch {
507
+ // error state managed by the discovery hook
508
+ }
509
+ return;
510
+ }
511
+
439
512
  try {
440
- await oauth.startOAuth(
441
- entry.mcpServer.metadata.id,
442
- activeOrg ?? org,
443
- );
513
+ await oauth.startOAuth(serverId, connectOrg, declaredEnvKeys);
444
514
  setup.onServerAdded(ref);
445
515
  } catch {
446
516
  // error state managed by oauth hook
447
517
  }
448
518
  },
449
- phase: oauth.phase,
519
+ // oauth.phase stays unscoped on purpose: it disables every
520
+ // server's sign-in button while a popup flow is in flight,
521
+ // preventing two concurrent flows over the same hook.
522
+ phase:
523
+ discovery.isConnecting && isOwnOAuthAttempt
524
+ ? ("connecting" as const)
525
+ : oauth.phase,
450
526
  isConnected: !oauthTokenMissing,
451
- error: oauth.error,
452
- onClearError: oauth.clearError,
527
+ connectionHealth: entry.oauthConnectionHealth,
528
+ error: oauthError ?? discoveryError,
529
+ // A bare-discovery failure is by definition a discovery-leg
530
+ // failure — keep the honest "signed in, but discovery
531
+ // failed" copy for it.
532
+ failedPhase: oauthError
533
+ ? oauthFailedPhase
534
+ : discoveryError
535
+ ? ("connecting" as const)
536
+ : null,
537
+ isOAuthStranded,
538
+ onClearError: () => {
539
+ oauth.clearError();
540
+ discovery.clearError();
541
+ },
453
542
  isVendorApprovalPending,
454
543
  isVendorApprovalBlocked,
455
544
  vendorApprovalDocsUrl: oauthStatus?.vendorApprovalDocsUrl || null,
545
+ manualEntrySupported,
456
546
  }
457
547
  : undefined;
458
548
 
@@ -757,6 +847,7 @@ function SetupServerRow({
757
847
  "stg:text-warning stg:hover:bg-warning/10",
758
848
  "stg:disabled:pointer-events-none stg:disabled:opacity-50",
759
849
  )}
850
+ aria-label={`Configure ${slug}`}
760
851
  >
761
852
  Configure
762
853
  </button>
@@ -778,6 +869,7 @@ function SetupServerRow({
778
869
  "stg:text-muted-foreground stg:hover:text-foreground stg:hover:bg-accent-hover",
779
870
  "stg:disabled:pointer-events-none stg:disabled:opacity-50",
780
871
  )}
872
+ aria-label={`Configure ${slug}`}
781
873
  >
782
874
  {entry.discoveredTools.length > 0 && (
783
875
  <span>