@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
@@ -7,6 +7,7 @@ import { formatFileSize } from "./attachment-utils.js";
7
7
  import { useObjectUrl } from "./useObjectUrl.js";
8
8
  import { AttachmentImageLightbox } from "./AttachmentImageLightbox.js";
9
9
  import { UNSTYLED_BUTTON } from "../internal/form-primitives.js";
10
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../internal/tooltip.js";
10
11
 
11
12
  /** Props for {@link AttachmentChipList}. */
12
13
  export interface AttachmentChipListProps {
@@ -216,84 +217,92 @@ function ImageAttachmentChip({
216
217
  return (
217
218
  // The remove badge and retry pill are SIBLINGS of the preview button,
218
219
  // absolutely positioned over it — buttons cannot nest inside buttons.
219
- <span
220
- role="listitem"
221
- aria-label={chipAriaLabel(entry)}
222
- title={entry.file.name}
223
- className="stg:relative stg:inline-flex"
224
- >
225
- {/* The whole tile is the preview target. Preview stays enabled while
226
- `disabled` (that prop gates the mutating remove/retry actions) and
227
- in every phase: the object URL wraps in-memory bytes, no fetch.
228
- UNSTYLED_BUTTON adds the pointer cursor — the image tile carries
229
- no other clickability cue. */}
230
- <button
231
- type="button"
232
- onClick={onPreview}
233
- aria-label={`Preview ${entry.file.name}`}
234
- className={cn(
235
- UNSTYLED_BUTTON,
236
- "stg:relative stg:block stg:h-14 stg:w-14 stg:overflow-hidden stg:rounded-md stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring",
237
- isError && "stg:ring-1 stg:ring-destructive",
238
- )}
220
+ <Tooltip>
221
+ <TooltipTrigger
222
+ render={
223
+ <span
224
+ role="listitem"
225
+ aria-label={chipAriaLabel(entry)}
226
+ className="stg:relative stg:inline-flex"
227
+ />
228
+ }
239
229
  >
240
- {url ? (
241
- <img
242
- src={url}
243
- alt=""
244
- aria-hidden="true"
245
- onError={() => setLoadFailed(true)}
230
+ {/* The whole tile is the preview target. Preview stays enabled while
231
+ `disabled` (that prop gates the mutating remove/retry actions) and
232
+ in every phase: the object URL wraps in-memory bytes, no fetch.
233
+ UNSTYLED_BUTTON adds the pointer cursor — the image tile carries
234
+ no other clickability cue. */}
235
+ <button
236
+ type="button"
237
+ onClick={onPreview}
238
+ aria-label={`Preview ${entry.file.name}`}
239
+ className={cn(
240
+ UNSTYLED_BUTTON,
241
+ "stg:relative stg:block stg:h-14 stg:w-14 stg:overflow-hidden stg:rounded-md stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring",
242
+ isError && "stg:ring-1 stg:ring-destructive",
243
+ )}
244
+ >
245
+ {url ? (
246
+ <img
247
+ src={url}
248
+ alt=""
249
+ aria-hidden="true"
250
+ onError={() => setLoadFailed(true)}
251
+ className={cn(
252
+ "stg:h-full stg:w-full stg:object-cover",
253
+ (isUploading || isError) && "stg:opacity-50",
254
+ )}
255
+ />
256
+ ) : (
257
+ // One-frame placeholder until the object-URL effect runs; same
258
+ // footprint as the image, so no layout shift.
259
+ <span
260
+ className="stg:block stg:h-full stg:w-full stg:animate-pulse stg:bg-muted"
261
+ aria-hidden="true"
262
+ />
263
+ )}
264
+ {isUploading && (
265
+ <span className="stg:absolute stg:inset-0 stg:flex stg:items-center stg:justify-center">
266
+ <ChipSpinner size={16} />
267
+ </span>
268
+ )}
269
+ </button>
270
+
271
+ {isError && (
272
+ <button
273
+ type="button"
274
+ onClick={onRetry}
275
+ disabled={disabled}
276
+ aria-label={`Retry uploading ${entry.file.name}`}
246
277
  className={cn(
247
- "stg:h-full stg:w-full stg:object-cover",
248
- (isUploading || isError) && "stg:opacity-50",
278
+ UNSTYLED_BUTTON,
279
+ "stg:absolute stg:left-1/2 stg:top-1/2 stg:-translate-x-1/2 stg:-translate-y-1/2 stg:rounded-full stg:bg-destructive stg:px-1.5 stg:py-0.5 stg:text-[0.6rem] stg:font-medium stg:leading-none stg:text-destructive-foreground stg:shadow-sm stg:hover:bg-destructive-hover stg:disabled:pointer-events-none",
249
280
  )}
250
- />
251
- ) : (
252
- // One-frame placeholder until the object-URL effect runs; same
253
- // footprint as the image, so no layout shift.
254
- <span
255
- className="stg:block stg:h-full stg:w-full stg:animate-pulse stg:bg-muted"
256
- aria-hidden="true"
257
- />
281
+ >
282
+ Retry
283
+ </button>
258
284
  )}
259
- {isUploading && (
260
- <span className="stg:absolute stg:inset-0 stg:flex stg:items-center stg:justify-center">
261
- <ChipSpinner size={16} />
262
- </span>
263
- )}
264
- </button>
265
285
 
266
- {isError && (
267
286
  <button
268
287
  type="button"
269
- onClick={onRetry}
288
+ onClick={onRemove}
270
289
  disabled={disabled}
271
- aria-label={`Retry uploading ${entry.file.name}`}
290
+ aria-label={`Remove ${entry.file.name}`}
272
291
  className={cn(
273
292
  UNSTYLED_BUTTON,
274
- "stg:absolute stg:left-1/2 stg:top-1/2 stg:-translate-x-1/2 stg:-translate-y-1/2 stg:rounded-full stg:bg-destructive stg:px-1.5 stg:py-0.5 stg:text-[0.6rem] stg:font-medium stg:leading-none stg:text-destructive-foreground stg:shadow-sm stg:hover:bg-destructive-hover stg:disabled:pointer-events-none",
293
+ // The established corner-badge geometry (ContextPopover,
294
+ // ComposerToolbar). Solid bg + border keep it legible over any
295
+ // image without opacity-modified tokens (Dont-Do #4).
296
+ "stg:absolute stg:-right-1.5 stg:-top-1.5 stg:flex stg:h-4 stg:w-4 stg:items-center stg:justify-center stg:rounded-full stg:border stg:border-border stg:bg-background stg:text-muted-foreground stg:shadow-sm stg:hover:text-destructive stg:disabled:pointer-events-none",
275
297
  )}
276
298
  >
277
- Retry
299
+ <XIcon />
278
300
  </button>
279
- )}
280
-
281
- <button
282
- type="button"
283
- onClick={onRemove}
284
- disabled={disabled}
285
- aria-label={`Remove ${entry.file.name}`}
286
- className={cn(
287
- UNSTYLED_BUTTON,
288
- // The established corner-badge geometry (ContextPopover,
289
- // ComposerToolbar). Solid bg + border keep it legible over any
290
- // image without opacity-modified tokens (Dont-Do #4).
291
- "stg:absolute stg:-right-1.5 stg:-top-1.5 stg:flex stg:h-4 stg:w-4 stg:items-center stg:justify-center stg:rounded-full stg:border stg:border-border stg:bg-background stg:text-muted-foreground stg:shadow-sm stg:hover:text-destructive stg:disabled:pointer-events-none",
292
- )}
293
- >
294
- <XIcon />
295
- </button>
296
- </span>
301
+ </TooltipTrigger>
302
+ <TooltipContent side="top" className="stg:break-all">
303
+ {entry.file.name}
304
+ </TooltipContent>
305
+ </Tooltip>
297
306
  );
298
307
  }
299
308
 
@@ -95,10 +95,11 @@ export function AttachmentImageLightbox({
95
95
  {open && (
96
96
  <div className="stg:flex stg:flex-col">
97
97
  <div className="stg:flex stg:items-center stg:gap-2 stg:px-3 stg:py-2">
98
- <span
99
- className="stg:min-w-0 stg:flex-1 stg:truncate stg:text-xs stg:font-semibold stg:text-foreground"
100
- title={filename}
101
- >
98
+ {/* No tooltip here: the house tooltip portals OUTSIDE this native
99
+ showModal() dialog, where the top layer covers it and `inert`
100
+ disables it. The old title only restated the visible filename
101
+ (also the image's alt), so it is dropped rather than replaced. */}
102
+ <span className="stg:min-w-0 stg:flex-1 stg:truncate stg:text-xs stg:font-semibold stg:text-foreground">
102
103
  {filename}
103
104
  </span>
104
105
  <button
@@ -106,11 +106,12 @@ describe("AttachmentChipList — image miniature", () => {
106
106
 
107
107
  await waitFor(() => expect(chipImage(container)).toBeTruthy());
108
108
 
109
- // The tile is the chip — the name lives in the tooltip and accessible
110
- // label, never as a text node (file chips, by contrast, keep theirs).
109
+ // The tile is the chip — the name lives in the house tooltip and
110
+ // accessible label, never as a text node (file chips, by contrast,
111
+ // keep theirs) and never a native title (banned, stigmer-cloud#268).
111
112
  expect(screen.queryByText("shot.png")).toBeNull();
112
113
  const tile = screen.getByRole("listitem", { name: /^shot\.png/ });
113
- expect(tile.getAttribute("title")).toBe("shot.png");
114
+ expect(tile.getAttribute("title")).toBeNull();
114
115
  // Remove is an always-visible corner badge, not hover-revealed.
115
116
  expect(screen.getByRole("button", { name: "Remove shot.png" })).toBeTruthy();
116
117
  });
@@ -22,6 +22,7 @@ import { useConfirmAction } from "../resource-detail/useConfirmAction.js";
22
22
  import { EditResourceYamlDialog } from "../manifest/EditResourceYamlDialog.js";
23
23
  import { useDeploymentMode } from "../deployment-mode.js";
24
24
  import { CloudFeatureNotice } from "../internal/CloudFeatureNotice.js";
25
+ import { TruncatedText } from "../internal/truncated-text.js";
25
26
  import { ChannelConversationsDialog } from "./ChannelConversationsDialog.js";
26
27
  import { ChannelCredentialsDialog } from "./ChannelCredentialsDialog.js";
27
28
  import { ChannelTemplatesDialog } from "./ChannelTemplatesDialog.js";
@@ -510,12 +511,10 @@ function ChannelCard({
510
511
  <provider.Icon className="stg:size-5 stg:shrink-0 stg:text-foreground" />
511
512
  <div className="stg:min-w-0">
512
513
  <div className="stg:flex stg:items-center stg:gap-2">
513
- <span
514
- className="stg:truncate stg:text-sm stg:font-medium stg:text-foreground"
515
- title={meta?.name || meta?.slug || undefined}
516
- >
517
- {meta?.name || meta?.slug || "\u2014"}
518
- </span>
514
+ <TruncatedText
515
+ text={meta?.name || meta?.slug || "\u2014"}
516
+ className="stg:text-sm stg:font-medium stg:text-foreground"
517
+ />
519
518
  <InstallStatePill state={installState} />
520
519
  </div>
521
520
  <p className="stg:mt-0.5 stg:text-xs stg:text-muted-foreground">
@@ -10,6 +10,7 @@ import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_
10
10
  import { formatRelativeTime } from "../activity/format-relative-time.js";
11
11
  import { Button } from "../button/Button.js";
12
12
  import { EmptyState } from "../empty-state/EmptyState.js";
13
+ import { TruncatedText } from "../internal/truncated-text.js";
13
14
  import { channelSessionExternalUserKey } from "../session/channelOrigin.js";
14
15
  import { useChannelSessions } from "./useChannelSessions.js";
15
16
 
@@ -200,9 +201,10 @@ function ConversationRow({
200
201
  const content = (
201
202
  <>
202
203
  <div className="stg:min-w-0 stg:flex-1">
203
- <p className="stg:truncate stg:text-sm stg:text-foreground" title={subject}>
204
- {subject}
205
- </p>
204
+ <TruncatedText
205
+ text={subject}
206
+ className="stg:block stg:text-sm stg:text-foreground"
207
+ />
206
208
  {externalUser && (
207
209
  <p className="stg:mt-0.5 stg:flex stg:items-center stg:gap-1 stg:text-xs stg:text-muted-foreground">
208
210
  <User aria-hidden="true" className="stg:size-3" />
@@ -9,6 +9,7 @@ import type { ChannelTemplate } from "@stigmer/protos/ai/stigmer/agentic/agentch
9
9
  import { Button } from "../button/Button.js";
10
10
  import { EmptyState } from "../empty-state/EmptyState.js";
11
11
  import { CloudFeatureNotice } from "../internal/CloudFeatureNotice.js";
12
+ import { TruncatedText } from "../internal/truncated-text.js";
12
13
  import { StatusBadge } from "../resource-workbench/components/StatusBadge.js";
13
14
  import {
14
15
  channelPresentationOf,
@@ -332,12 +333,10 @@ function TemplateRow({ template }: { readonly template: ChannelTemplate }) {
332
333
  <li className="stg:rounded-lg stg:border stg:border-border stg:p-3">
333
334
  <div className="stg:flex stg:items-start stg:justify-between stg:gap-3">
334
335
  <div className="stg:flex stg:min-w-0 stg:flex-wrap stg:items-center stg:gap-x-2 stg:gap-y-1">
335
- <span
336
- className="stg:truncate stg:text-sm stg:font-medium stg:text-foreground"
337
- title={template.name}
338
- >
339
- {template.name}
340
- </span>
336
+ <TruncatedText
337
+ text={template.name}
338
+ className="stg:text-sm stg:font-medium stg:text-foreground"
339
+ />
341
340
  {/* (name, language) is the template's identity — each
342
341
  language is approved independently, so it always shows. */}
343
342
  <span className="stg:shrink-0 stg:text-xs stg:text-muted-foreground">
@@ -5,6 +5,7 @@ import type { AgentChannelInput } from "@stigmer/sdk";
5
5
  import { StigmerContext } from "../../context";
6
6
  import { FetchCacheContext } from "../../internal/FetchCacheProvider";
7
7
  import { DeploymentModeContext } from "../../deployment-mode";
8
+ import { openMenu } from "../../__tests__/helpers/open-menu";
8
9
  import { AgentChannelsPanel } from "../AgentChannelsPanel";
9
10
 
10
11
  // Toasts are visual feedback owned by the feedback module; keep them inert.
@@ -272,7 +273,7 @@ describe("AgentChannelsPanel", () => {
272
273
  );
273
274
 
274
275
  await waitFor(() => expect(screen.getByText("Support Slack")).toBeTruthy());
275
- fireEvent.click(screen.getByRole("button", { name: /actions for/i }));
276
+ await openMenu(screen.getByRole("button", { name: /actions for/i }));
276
277
  fireEvent.click(await screen.findByRole("menuitem", { name: "Disconnect" }));
277
278
 
278
279
  // The confirmation explains teardown vs pause before anything happens.
@@ -409,14 +410,18 @@ describe("AgentChannelsPanel", () => {
409
410
  await waitFor(() => expect(screen.getByText("Support Slack")).toBeTruthy());
410
411
  await waitFor(() => expect(checkMyPermission).toHaveBeenCalled());
411
412
 
412
- expect(screen.queryByRole("switch")).toBeNull();
413
+ // The panel renders mutation affordances optimistic-visible and hides
414
+ // them when the denial lands. "Mock was called" precedes "denial
415
+ // rendered", so wait for the state this test is actually about instead
416
+ // of racing the re-render (flaked under CPU contention, ~1/20).
417
+ await waitFor(() => expect(screen.queryByRole("switch")).toBeNull());
413
418
  expect(screen.queryByRole("button", { name: /connect to slack/i })).toBeNull();
414
419
 
415
420
  // The card menu still renders: Sessions is a viewer-level action
416
421
  // (everyone who sees the card holds can_view on the channel — the same
417
422
  // bar as viewing its sessions, DD-012). Mutation items stay
418
423
  // permission-gated and absent.
419
- fireEvent.click(screen.getByRole("button", { name: /actions for/i }));
424
+ await openMenu(screen.getByRole("button", { name: /actions for/i }));
420
425
  // The awaited query anchors on the portaled menu's mount (#323) — only
421
426
  // then are the absence assertions below meaningful rather than vacuous.
422
427
  expect(await screen.findByRole("menuitem", { name: /sessions/i })).toBeTruthy();
@@ -441,7 +446,7 @@ describe("AgentChannelsPanel", () => {
441
446
  );
442
447
  await waitFor(() => expect(screen.getByText("Support Slack")).toBeTruthy());
443
448
 
444
- fireEvent.click(screen.getByRole("button", { name: /actions for/i }));
449
+ await openMenu(screen.getByRole("button", { name: /actions for/i }));
445
450
  fireEvent.click(await screen.findByRole("menuitem", { name: /manage access/i }));
446
451
 
447
452
  // The one canonical dialog opens, and its subtitle names the channel
@@ -501,7 +506,7 @@ describe("AgentChannelsPanel", () => {
501
506
  );
502
507
 
503
508
  await waitFor(() => expect(screen.getByText("Support Slack")).toBeTruthy());
504
- fireEvent.click(screen.getByRole("button", { name: /actions for/i }));
509
+ await openMenu(screen.getByRole("button", { name: /actions for/i }));
505
510
  fireEvent.click(
506
511
  await screen.findByRole("menuitem", { name: "Tool credentials" }),
507
512
  );
@@ -629,7 +634,7 @@ describe("AgentChannelsPanel", () => {
629
634
  await waitFor(() =>
630
635
  expect(screen.getByText("Support WhatsApp")).toBeTruthy(),
631
636
  );
632
- fireEvent.click(screen.getByRole("button", { name: /actions for/i }));
637
+ await openMenu(screen.getByRole("button", { name: /actions for/i }));
633
638
  fireEvent.click(await screen.findByRole("menuitem", { name: "Disconnect" }));
634
639
 
635
640
  // WhatsApp credentials live on the shared ChannelApp and survive the
@@ -652,7 +657,7 @@ describe("AgentChannelsPanel", () => {
652
657
  await waitFor(() =>
653
658
  expect(screen.getByText("Support WhatsApp")).toBeTruthy(),
654
659
  );
655
- fireEvent.click(screen.getByRole("button", { name: /actions for/i }));
660
+ await openMenu(screen.getByRole("button", { name: /actions for/i }));
656
661
  fireEvent.click(await screen.findByRole("menuitem", { name: "Templates" }));
657
662
 
658
663
  expect(
@@ -676,7 +681,7 @@ describe("AgentChannelsPanel", () => {
676
681
  );
677
682
 
678
683
  await waitFor(() => expect(screen.getByText("Support Slack")).toBeTruthy());
679
- fireEvent.click(screen.getByRole("button", { name: /actions for/i }));
684
+ await openMenu(screen.getByRole("button", { name: /actions for/i }));
680
685
 
681
686
  // Slack has no template concept: hidden, not disabled — a disabled
682
687
  // item would imply the capability might one day exist there.
@@ -704,7 +709,7 @@ describe("AgentChannelsPanel", () => {
704
709
  expect(screen.getByText("Support WhatsApp")).toBeTruthy(),
705
710
  );
706
711
  await waitFor(() => expect(checkMyPermission).toHaveBeenCalled());
707
- fireEvent.click(screen.getByRole("button", { name: /actions for/i }));
712
+ await openMenu(screen.getByRole("button", { name: /actions for/i }));
708
713
 
709
714
  expect(
710
715
  await screen.findByRole("menuitem", { name: /sessions/i }),
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { useCallback, useState } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
+ import { TruncatedText } from "../internal/truncated-text.js";
5
6
 
6
7
  /**
7
8
  * Internal building blocks shared by the channel-app forms and panels.
@@ -74,15 +75,13 @@ export function CopyRow({
74
75
  <div className="stg:space-y-1">
75
76
  <p className="stg:text-xs stg:font-medium stg:text-foreground">{label}</p>
76
77
  <div className="stg:flex stg:items-center stg:gap-1.5">
77
- <code
78
+ <TruncatedText
79
+ text={value}
78
80
  className={cn(
79
- "stg:min-w-0 stg:flex-1 stg:truncate stg:rounded-md stg:border stg:border-border stg:bg-muted-subtle",
81
+ "stg:min-w-0 stg:flex-1 stg:rounded-md stg:border stg:border-border stg:bg-muted-subtle",
80
82
  "stg:px-2 stg:py-1.5 stg:font-mono stg:text-[0.65rem] stg:text-foreground",
81
83
  )}
82
- title={value}
83
- >
84
- {value}
85
- </code>
84
+ />
86
85
  <CopyButton copied={copied} onCopy={copy} copyTargetId={copyTargetId} />
87
86
  </div>
88
87
  </div>
@@ -1,6 +1,12 @@
1
1
  "use client";
2
2
 
3
3
  import { cn } from "@stigmer/theme";
4
+ import {
5
+ Tooltip,
6
+ TooltipContent,
7
+ TooltipProvider,
8
+ TooltipTrigger,
9
+ } from "../internal/tooltip.js";
4
10
  import { ContextPopover } from "./ContextPopover.js";
5
11
  import { ConfigureMenu, type ConfigureMenuItem } from "./ConfigureMenu.js";
6
12
  import { ModelSelector } from "../models/ModelSelector.js";
@@ -160,101 +166,127 @@ export function ComposerToolbar({
160
166
  )}
161
167
  </div>
162
168
 
163
- {/* ---- Right group: Secondary actions (icon-only) + Send ---- */}
169
+ {/* ---- Right group: Secondary actions (icon-only) + Send ----
164
170
 
165
- <div className="stg:flex stg:shrink-0 stg:items-center stg:gap-1">
166
- {showWorkspace && (
167
- onWorkspaceDirectAction
168
- ? <button
169
- type="button"
170
- disabled={disabled}
171
- onClick={onWorkspaceDirectAction}
172
- title="Workspace"
173
- className={cn(
174
- "stg:inline-flex stg:h-8 stg:w-8 stg:items-center stg:justify-center stg:rounded-md stg:text-xs stg:transition-colors",
175
- "stg:text-muted-foreground stg:hover:text-foreground stg:hover:bg-accent-hover",
176
- "stg:disabled:pointer-events-none stg:disabled:opacity-50",
177
- )}
178
- aria-label="Workspace"
179
- >
180
- <span className="stg:relative">
181
- <WorkspaceIcon />
182
- {workspaceCount > 0 && (
183
- <span className="stg:absolute stg:-right-1.5 stg:-top-1.5 stg:flex stg:h-3.5 stg:min-w-3.5 stg:items-center stg:justify-center stg:rounded-full stg:bg-primary stg:px-0.5 stg:text-[0.5rem] stg:font-medium stg:leading-none stg:text-primary-foreground">
184
- {workspaceCount}
185
- </span>
171
+ Icon-only actions carry house tooltips (never native `title` —
172
+ OS-delayed and unreachable from keyboard/touch, dead entirely on
173
+ disabled controls). Disabled-capable buttons put the trigger on a
174
+ plain wrapper span: `disabled` adds `pointer-events-none`, so the
175
+ span, not the button, must own the hover for the tooltip to keep
176
+ working while disabled. The provider is context-only (no DOM node)
177
+ and groups the buttons' hover delay. */}
178
+
179
+ <TooltipProvider>
180
+ <div className="stg:flex stg:shrink-0 stg:items-center stg:gap-1">
181
+ {showWorkspace && (
182
+ onWorkspaceDirectAction
183
+ ? <Tooltip>
184
+ <TooltipTrigger render={<span className="stg:inline-flex" />}>
185
+ <button
186
+ type="button"
187
+ disabled={disabled}
188
+ onClick={onWorkspaceDirectAction}
189
+ className={cn(
190
+ "stg:inline-flex stg:h-8 stg:w-8 stg:items-center stg:justify-center stg:rounded-md stg:text-xs stg:transition-colors",
191
+ "stg:text-muted-foreground stg:hover:text-foreground stg:hover:bg-accent-hover",
192
+ "stg:disabled:pointer-events-none stg:disabled:opacity-50",
193
+ )}
194
+ aria-label="Workspace"
195
+ >
196
+ <span className="stg:relative">
197
+ <WorkspaceIcon />
198
+ {workspaceCount > 0 && (
199
+ <span className="stg:absolute stg:-right-1.5 stg:-top-1.5 stg:flex stg:h-3.5 stg:min-w-3.5 stg:items-center stg:justify-center stg:rounded-full stg:bg-primary stg:px-0.5 stg:text-[0.5rem] stg:font-medium stg:leading-none stg:text-primary-foreground">
200
+ {workspaceCount}
201
+ </span>
202
+ )}
203
+ </span>
204
+ </button>
205
+ </TooltipTrigger>
206
+ <TooltipContent side="top">Workspace</TooltipContent>
207
+ </Tooltip>
208
+ : <ContextPopover
209
+ icon={<WorkspaceIcon />}
210
+ label="Workspace"
211
+ count={workspaceCount}
212
+ disabled={disabled}
213
+ >
214
+ {workspaceContent}
215
+ </ContextPopover>
216
+ )}
217
+
218
+ {showAttach && (
219
+ <Tooltip>
220
+ <TooltipTrigger render={<span className="stg:inline-flex" />}>
221
+ <button
222
+ type="button"
223
+ disabled={disabled}
224
+ onClick={onAttachClick}
225
+ className={cn(
226
+ "stg:inline-flex stg:h-8 stg:w-8 stg:items-center stg:justify-center stg:rounded-md stg:text-xs stg:transition-colors",
227
+ "stg:text-muted-foreground stg:hover:text-foreground stg:hover:bg-accent-hover",
228
+ "stg:disabled:pointer-events-none stg:disabled:opacity-50",
186
229
  )}
187
- </span>
188
- </button>
189
- : <ContextPopover
190
- icon={<WorkspaceIcon />}
191
- label="Workspace"
192
- count={workspaceCount}
193
- disabled={disabled}
194
- >
195
- {workspaceContent}
196
- </ContextPopover>
197
- )}
230
+ aria-label="Attach files"
231
+ >
232
+ <span className="stg:relative">
233
+ <PaperclipIcon />
234
+ {attachmentCount > 0 && (
235
+ <span className="stg:absolute stg:-right-1.5 stg:-top-1.5 stg:flex stg:h-3.5 stg:min-w-3.5 stg:items-center stg:justify-center stg:rounded-full stg:bg-primary stg:px-0.5 stg:text-[0.5rem] stg:font-medium stg:leading-none stg:text-primary-foreground">
236
+ {attachmentCount}
237
+ </span>
238
+ )}
239
+ </span>
240
+ </button>
241
+ </TooltipTrigger>
242
+ <TooltipContent side="top">Attach files</TooltipContent>
243
+ </Tooltip>
244
+ )}
198
245
 
199
- {showAttach && (
200
- <button
201
- type="button"
246
+ <ConfigureMenu
247
+ open={configOpen}
248
+ onOpenChange={onConfigOpenChange}
249
+ activePanel={configActivePanel}
250
+ onActivePanelChange={onConfigActivePanelChange}
251
+ items={configureItems}
252
+ renderPanel={renderConfigPanel}
202
253
  disabled={disabled}
203
- onClick={onAttachClick}
204
- title="Attach files"
205
- className={cn(
206
- "stg:inline-flex stg:h-8 stg:w-8 stg:items-center stg:justify-center stg:rounded-md stg:text-xs stg:transition-colors",
207
- "stg:text-muted-foreground stg:hover:text-foreground stg:hover:bg-accent-hover",
208
- "stg:disabled:pointer-events-none stg:disabled:opacity-50",
209
- )}
210
- aria-label="Attach files"
211
- >
212
- <span className="stg:relative">
213
- <PaperclipIcon />
214
- {attachmentCount > 0 && (
215
- <span className="stg:absolute stg:-right-1.5 stg:-top-1.5 stg:flex stg:h-3.5 stg:min-w-3.5 stg:items-center stg:justify-center stg:rounded-full stg:bg-primary stg:px-0.5 stg:text-[0.5rem] stg:font-medium stg:leading-none stg:text-primary-foreground">
216
- {attachmentCount}
217
- </span>
218
- )}
219
- </span>
220
- </button>
221
- )}
222
-
223
- <ConfigureMenu
224
- open={configOpen}
225
- onOpenChange={onConfigOpenChange}
226
- activePanel={configActivePanel}
227
- onActivePanelChange={onConfigActivePanelChange}
228
- items={configureItems}
229
- renderPanel={renderConfigPanel}
230
- disabled={disabled}
231
- />
254
+ />
232
255
 
233
- {onStop ? (
234
- // Circular container (vs. Send's rounded-square) gives the square glyph
235
- // a proper home — the canonical stop affordance — and the shape morph
236
- // from Send→Stop signals the running state at a glance.
237
- <button
238
- type="button"
239
- onClick={onStop}
240
- className="stg:flex stg:h-8 stg:w-8 stg:shrink-0 stg:items-center stg:justify-center stg:rounded-full stg:bg-primary stg:text-primary-foreground stg:transition-colors stg:hover:bg-primary-hover"
241
- aria-label="Stop generating"
242
- title="Stop"
243
- >
244
- {isStopping ? <SpinnerIcon /> : <StopIcon />}
245
- </button>
246
- ) : (
247
- <button
248
- type="button"
249
- disabled={!canSend}
250
- onClick={onSend}
251
- className="stg:flex stg:h-8 stg:w-8 stg:shrink-0 stg:items-center stg:justify-center stg:rounded-lg stg:bg-primary stg:text-primary-foreground stg:transition-colors stg:hover:bg-primary-hover stg:disabled:pointer-events-none stg:disabled:opacity-40"
252
- aria-label="Send message"
253
- >
254
- {isSubmitting ? <SpinnerIcon /> : <ArrowUpIcon />}
255
- </button>
256
- )}
257
- </div>
256
+ {onStop ? (
257
+ // Circular container (vs. Send's rounded-square) gives the square glyph
258
+ // a proper home — the canonical stop affordance — and the shape morph
259
+ // from Send→Stop signals the running state at a glance. Always
260
+ // enabled, so the button itself is the tooltip trigger (keyboard
261
+ // focus opens it too).
262
+ <Tooltip>
263
+ <TooltipTrigger
264
+ render={
265
+ <button
266
+ type="button"
267
+ onClick={onStop}
268
+ className="stg:flex stg:h-8 stg:w-8 stg:shrink-0 stg:items-center stg:justify-center stg:rounded-full stg:bg-primary stg:text-primary-foreground stg:transition-colors stg:hover:bg-primary-hover"
269
+ aria-label="Stop generating"
270
+ />
271
+ }
272
+ >
273
+ {isStopping ? <SpinnerIcon /> : <StopIcon />}
274
+ </TooltipTrigger>
275
+ <TooltipContent side="top">Stop</TooltipContent>
276
+ </Tooltip>
277
+ ) : (
278
+ <button
279
+ type="button"
280
+ disabled={!canSend}
281
+ onClick={onSend}
282
+ className="stg:flex stg:h-8 stg:w-8 stg:shrink-0 stg:items-center stg:justify-center stg:rounded-lg stg:bg-primary stg:text-primary-foreground stg:transition-colors stg:hover:bg-primary-hover stg:disabled:pointer-events-none stg:disabled:opacity-40"
283
+ aria-label="Send message"
284
+ >
285
+ {isSubmitting ? <SpinnerIcon /> : <ArrowUpIcon />}
286
+ </button>
287
+ )}
288
+ </div>
289
+ </TooltipProvider>
258
290
  </div>
259
291
  );
260
292
  }