@stigmer/react 3.12.1 → 3.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (708) hide show
  1. package/access/ManageAccessDialog.d.ts.map +1 -1
  2. package/access/ManageAccessDialog.js +8 -19
  3. package/access/ManageAccessDialog.js.map +1 -1
  4. package/activity/format-relative-time.d.ts +11 -9
  5. package/activity/format-relative-time.d.ts.map +1 -1
  6. package/activity/format-relative-time.js +11 -9
  7. package/activity/format-relative-time.js.map +1 -1
  8. package/agent/steps/CapabilitiesStep.js +5 -2
  9. package/agent/steps/CapabilitiesStep.js.map +1 -1
  10. package/agent/steps/IdentityStep.d.ts.map +1 -1
  11. package/agent/steps/IdentityStep.js +6 -5
  12. package/agent/steps/IdentityStep.js.map +1 -1
  13. package/agent-instance/CreateAgentInstanceDialog.d.ts.map +1 -1
  14. package/agent-instance/CreateAgentInstanceDialog.js +15 -20
  15. package/agent-instance/CreateAgentInstanceDialog.js.map +1 -1
  16. package/api-key/ApiKeyCreatedAlert.d.ts.map +1 -1
  17. package/api-key/ApiKeyCreatedAlert.js +12 -20
  18. package/api-key/ApiKeyCreatedAlert.js.map +1 -1
  19. package/api-key/ApiKeyListPanel.d.ts.map +1 -1
  20. package/api-key/ApiKeyListPanel.js +3 -23
  21. package/api-key/ApiKeyListPanel.js.map +1 -1
  22. package/api-key/CreateApiKeyForm.d.ts.map +1 -1
  23. package/api-key/CreateApiKeyForm.js +6 -10
  24. package/api-key/CreateApiKeyForm.js.map +1 -1
  25. package/approval-defaults-context.d.ts +47 -0
  26. package/approval-defaults-context.d.ts.map +1 -0
  27. package/approval-defaults-context.js +27 -0
  28. package/approval-defaults-context.js.map +1 -0
  29. package/attachment/AttachmentImageLightbox.d.ts.map +1 -1
  30. package/attachment/AttachmentImageLightbox.js +8 -23
  31. package/attachment/AttachmentImageLightbox.js.map +1 -1
  32. package/attachment/index.d.ts +2 -0
  33. package/attachment/index.d.ts.map +1 -1
  34. package/attachment/index.js +1 -0
  35. package/attachment/index.js.map +1 -1
  36. package/attachment/vision-preflight.d.ts +113 -0
  37. package/attachment/vision-preflight.d.ts.map +1 -0
  38. package/attachment/vision-preflight.js +143 -0
  39. package/attachment/vision-preflight.js.map +1 -0
  40. package/billing/AutoRechargeCard.d.ts.map +1 -1
  41. package/billing/AutoRechargeCard.js +3 -2
  42. package/billing/AutoRechargeCard.js.map +1 -1
  43. package/billing/BillingSection.d.ts.map +1 -1
  44. package/billing/BillingSection.js +3 -2
  45. package/billing/BillingSection.js.map +1 -1
  46. package/channel/ChannelConversationsDialog.d.ts.map +1 -1
  47. package/channel/ChannelConversationsDialog.js +6 -21
  48. package/channel/ChannelConversationsDialog.js.map +1 -1
  49. package/channel/ChannelCredentialsDialog.d.ts.map +1 -1
  50. package/channel/ChannelCredentialsDialog.js +10 -21
  51. package/channel/ChannelCredentialsDialog.js.map +1 -1
  52. package/channel/ChannelTemplatesDialog.d.ts.map +1 -1
  53. package/channel/ChannelTemplatesDialog.js +7 -22
  54. package/channel/ChannelTemplatesDialog.js.map +1 -1
  55. package/channel/ConnectSlackDialog.d.ts.map +1 -1
  56. package/channel/ConnectSlackDialog.js +10 -23
  57. package/channel/ConnectSlackDialog.js.map +1 -1
  58. package/channel/ConnectWhatsAppDialog.d.ts.map +1 -1
  59. package/channel/ConnectWhatsAppDialog.js +10 -23
  60. package/channel/ConnectWhatsAppDialog.js.map +1 -1
  61. package/channel/useChannelSessions.d.ts.map +1 -1
  62. package/channel/useChannelSessions.js.map +1 -1
  63. package/channel-app/ChannelAppDetailPanel.d.ts.map +1 -1
  64. package/channel-app/ChannelAppDetailPanel.js +8 -5
  65. package/channel-app/ChannelAppDetailPanel.js.map +1 -1
  66. package/channel-app/CreateChannelAppForm.d.ts.map +1 -1
  67. package/channel-app/CreateChannelAppForm.js +12 -7
  68. package/channel-app/CreateChannelAppForm.js.map +1 -1
  69. package/channel-app/internal.d.ts +0 -1
  70. package/channel-app/internal.d.ts.map +1 -1
  71. package/channel-app/internal.js +5 -10
  72. package/channel-app/internal.js.map +1 -1
  73. package/composer/ComposerToolbar.js +2 -1
  74. package/composer/ComposerToolbar.js.map +1 -1
  75. package/composer/SessionComposer.d.ts +1 -1
  76. package/composer/SessionComposer.d.ts.map +1 -1
  77. package/composer/SessionComposer.js +120 -13
  78. package/composer/SessionComposer.js.map +1 -1
  79. package/composer/icons.d.ts +0 -1
  80. package/composer/icons.d.ts.map +1 -1
  81. package/composer/icons.js +0 -3
  82. package/composer/icons.js.map +1 -1
  83. package/conversation/ConversationAttentionBanner.d.ts +23 -6
  84. package/conversation/ConversationAttentionBanner.d.ts.map +1 -1
  85. package/conversation/ConversationAttentionBanner.js +25 -10
  86. package/conversation/ConversationAttentionBanner.js.map +1 -1
  87. package/conversation/ConversationComposer.js +1 -1
  88. package/conversation/ConversationComposer.js.map +1 -1
  89. package/conversation/ConversationListPane.d.ts.map +1 -1
  90. package/conversation/ConversationListPane.js +28 -8
  91. package/conversation/ConversationListPane.js.map +1 -1
  92. package/conversation/ConversationsWorkbench.d.ts.map +1 -1
  93. package/conversation/ConversationsWorkbench.js +1 -1
  94. package/conversation/ConversationsWorkbench.js.map +1 -1
  95. package/cursor-accounts/MemberCoverageTable.js +3 -14
  96. package/cursor-accounts/MemberCoverageTable.js.map +1 -1
  97. package/dashboard/DashboardFailedRuns.d.ts.map +1 -1
  98. package/dashboard/DashboardFailedRuns.js +2 -14
  99. package/dashboard/DashboardFailedRuns.js.map +1 -1
  100. package/environment/CreateEnvironmentForm.d.ts.map +1 -1
  101. package/environment/CreateEnvironmentForm.js +4 -8
  102. package/environment/CreateEnvironmentForm.js.map +1 -1
  103. package/environment/EnvVarForm.d.ts.map +1 -1
  104. package/environment/EnvVarForm.js +2 -4
  105. package/environment/EnvVarForm.js.map +1 -1
  106. package/environment/EnvironmentVariableEditor.d.ts.map +1 -1
  107. package/environment/EnvironmentVariableEditor.js +5 -7
  108. package/environment/EnvironmentVariableEditor.js.map +1 -1
  109. package/execution/ApprovalCard.d.ts.map +1 -1
  110. package/execution/ApprovalCard.js +13 -3
  111. package/execution/ApprovalCard.js.map +1 -1
  112. package/execution/ArtifactApplyButton.d.ts.map +1 -1
  113. package/execution/ArtifactApplyButton.js +2 -4
  114. package/execution/ArtifactApplyButton.js.map +1 -1
  115. package/execution/ArtifactPreviewModal.d.ts.map +1 -1
  116. package/execution/ArtifactPreviewModal.js +11 -17
  117. package/execution/ArtifactPreviewModal.js.map +1 -1
  118. package/execution/ExecutionErrorNotice.d.ts +36 -0
  119. package/execution/ExecutionErrorNotice.d.ts.map +1 -0
  120. package/execution/ExecutionErrorNotice.js +39 -0
  121. package/execution/ExecutionErrorNotice.js.map +1 -0
  122. package/execution/FilePathLink.d.ts.map +1 -1
  123. package/execution/FilePathLink.js +5 -8
  124. package/execution/FilePathLink.js.map +1 -1
  125. package/execution/FileReviewCard.d.ts.map +1 -1
  126. package/execution/FileReviewCard.js +1 -6
  127. package/execution/FileReviewCard.js.map +1 -1
  128. package/execution/FollowUpInput.d.ts.map +1 -1
  129. package/execution/FollowUpInput.js +1 -3
  130. package/execution/FollowUpInput.js.map +1 -1
  131. package/execution/LivenessStatusLine.d.ts +40 -0
  132. package/execution/LivenessStatusLine.d.ts.map +1 -0
  133. package/execution/LivenessStatusLine.js +34 -0
  134. package/execution/LivenessStatusLine.js.map +1 -0
  135. package/execution/MessageEntry.d.ts.map +1 -1
  136. package/execution/MessageEntry.js +31 -3
  137. package/execution/MessageEntry.js.map +1 -1
  138. package/execution/MessageThread.d.ts +25 -0
  139. package/execution/MessageThread.d.ts.map +1 -1
  140. package/execution/MessageThread.js +51 -36
  141. package/execution/MessageThread.js.map +1 -1
  142. package/execution/SetupProgress.d.ts.map +1 -1
  143. package/execution/SetupProgress.js +1 -1
  144. package/execution/SetupProgress.js.map +1 -1
  145. package/execution/SubAgentSection.d.ts.map +1 -1
  146. package/execution/SubAgentSection.js +9 -7
  147. package/execution/SubAgentSection.js.map +1 -1
  148. package/execution/TerminalSession.d.ts +30 -0
  149. package/execution/TerminalSession.d.ts.map +1 -1
  150. package/execution/TerminalSession.js +37 -1
  151. package/execution/TerminalSession.js.map +1 -1
  152. package/execution/ToolCallDetail.d.ts +9 -0
  153. package/execution/ToolCallDetail.d.ts.map +1 -1
  154. package/execution/ToolCallDetail.js +16 -0
  155. package/execution/ToolCallDetail.js.map +1 -1
  156. package/execution/ToolCallItem.d.ts +23 -7
  157. package/execution/ToolCallItem.d.ts.map +1 -1
  158. package/execution/ToolCallItem.js +120 -35
  159. package/execution/ToolCallItem.js.map +1 -1
  160. package/execution/ToolRunGroup.d.ts.map +1 -1
  161. package/execution/ToolRunGroup.js +11 -11
  162. package/execution/ToolRunGroup.js.map +1 -1
  163. package/execution/WriteBackCard.d.ts.map +1 -1
  164. package/execution/WriteBackCard.js +5 -20
  165. package/execution/WriteBackCard.js.map +1 -1
  166. package/execution/index.d.ts +7 -3
  167. package/execution/index.d.ts.map +1 -1
  168. package/execution/index.js +4 -2
  169. package/execution/index.js.map +1 -1
  170. package/execution/tool-categories.d.ts +93 -7
  171. package/execution/tool-categories.d.ts.map +1 -1
  172. package/execution/tool-categories.js +141 -5
  173. package/execution/tool-categories.js.map +1 -1
  174. package/execution/tool-presenter.d.ts +32 -1
  175. package/execution/tool-presenter.d.ts.map +1 -1
  176. package/execution/tool-presenter.js +10 -2
  177. package/execution/tool-presenter.js.map +1 -1
  178. package/execution/useArtifactInspection.d.ts.map +1 -1
  179. package/execution/useArtifactInspection.js +4 -7
  180. package/execution/useArtifactInspection.js.map +1 -1
  181. package/iam-policy/GrantAccessForm.d.ts.map +1 -1
  182. package/iam-policy/GrantAccessForm.js +2 -4
  183. package/iam-policy/GrantAccessForm.js.map +1 -1
  184. package/iam-policy/OrgMembersPanel.d.ts.map +1 -1
  185. package/iam-policy/OrgMembersPanel.js +3 -5
  186. package/iam-policy/OrgMembersPanel.js.map +1 -1
  187. package/iam-policy/RoleSelector.d.ts.map +1 -1
  188. package/iam-policy/RoleSelector.js +7 -1
  189. package/iam-policy/RoleSelector.js.map +1 -1
  190. package/identity-provider/CreateIdentityProviderForm.d.ts.map +1 -1
  191. package/identity-provider/CreateIdentityProviderForm.js +6 -9
  192. package/identity-provider/CreateIdentityProviderForm.js.map +1 -1
  193. package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
  194. package/identity-provider/IdentityProviderDetailPanel.js +17 -26
  195. package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
  196. package/identity-provider/IdentityProviderListPanel.d.ts.map +1 -1
  197. package/identity-provider/IdentityProviderListPanel.js +2 -4
  198. package/identity-provider/IdentityProviderListPanel.js.map +1 -1
  199. package/identity-provider/IdentityProviderWizard.d.ts.map +1 -1
  200. package/identity-provider/IdentityProviderWizard.js +8 -7
  201. package/identity-provider/IdentityProviderWizard.js.map +1 -1
  202. package/identity-provider/SsoLoginPrompt.js +5 -6
  203. package/identity-provider/SsoLoginPrompt.js.map +1 -1
  204. package/index.d.ts +9 -8
  205. package/index.d.ts.map +1 -1
  206. package/index.js +4 -4
  207. package/index.js.map +1 -1
  208. package/internal/DecisionButton.d.ts.map +1 -1
  209. package/internal/DecisionButton.js +1 -6
  210. package/internal/DecisionButton.js.map +1 -1
  211. package/internal/DialogShell.d.ts +77 -0
  212. package/internal/DialogShell.d.ts.map +1 -0
  213. package/internal/DialogShell.js +77 -0
  214. package/internal/DialogShell.js.map +1 -0
  215. package/internal/SpinnerIcon.d.ts +22 -0
  216. package/internal/SpinnerIcon.d.ts.map +1 -0
  217. package/internal/SpinnerIcon.js +23 -0
  218. package/internal/SpinnerIcon.js.map +1 -0
  219. package/internal/select-element-text.d.ts +11 -0
  220. package/internal/select-element-text.d.ts.map +1 -0
  221. package/internal/select-element-text.js +19 -0
  222. package/internal/select-element-text.js.map +1 -0
  223. package/internal/thread-card/ThreadCardShell.d.ts +27 -10
  224. package/internal/thread-card/ThreadCardShell.d.ts.map +1 -1
  225. package/internal/thread-card/ThreadCardShell.js +11 -5
  226. package/internal/thread-card/ThreadCardShell.js.map +1 -1
  227. package/internal/thread-card/glyphs.d.ts +11 -2
  228. package/internal/thread-card/glyphs.d.ts.map +1 -1
  229. package/internal/thread-card/glyphs.js +9 -3
  230. package/internal/thread-card/glyphs.js.map +1 -1
  231. package/internal/thread-card/index.d.ts +1 -1
  232. package/internal/thread-card/index.d.ts.map +1 -1
  233. package/internal/thread-card/index.js.map +1 -1
  234. package/internal/useCopyFeedback.d.ts +28 -0
  235. package/internal/useCopyFeedback.d.ts.map +1 -0
  236. package/internal/useCopyFeedback.js +40 -0
  237. package/internal/useCopyFeedback.js.map +1 -0
  238. package/invitation/InvitationCreatedAlert.d.ts.map +1 -1
  239. package/invitation/InvitationCreatedAlert.js +12 -19
  240. package/invitation/InvitationCreatedAlert.js.map +1 -1
  241. package/invitation/InvitationManager.d.ts.map +1 -1
  242. package/invitation/InvitationManager.js +14 -21
  243. package/invitation/InvitationManager.js.map +1 -1
  244. package/invitation/InvitationRedemption.d.ts.map +1 -1
  245. package/invitation/InvitationRedemption.js +2 -4
  246. package/invitation/InvitationRedemption.js.map +1 -1
  247. package/library/useExportResource.d.ts.map +1 -1
  248. package/library/useExportResource.js +16 -27
  249. package/library/useExportResource.js.map +1 -1
  250. package/manifest/ApplyManifestDialog.d.ts.map +1 -1
  251. package/manifest/ApplyManifestDialog.js +7 -17
  252. package/manifest/ApplyManifestDialog.js.map +1 -1
  253. package/manifest/EditResourceYamlDialog.d.ts.map +1 -1
  254. package/manifest/EditResourceYamlDialog.js +3 -19
  255. package/manifest/EditResourceYamlDialog.js.map +1 -1
  256. package/mcp-server/DefinitionDriftNotice.d.ts +42 -0
  257. package/mcp-server/DefinitionDriftNotice.d.ts.map +1 -0
  258. package/mcp-server/DefinitionDriftNotice.js +52 -0
  259. package/mcp-server/DefinitionDriftNotice.js.map +1 -0
  260. package/mcp-server/McpServerConnectDialog.d.ts.map +1 -1
  261. package/mcp-server/McpServerConnectDialog.js +8 -20
  262. package/mcp-server/McpServerConnectDialog.js.map +1 -1
  263. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  264. package/mcp-server/McpServerDetailView.js +50 -28
  265. package/mcp-server/McpServerDetailView.js.map +1 -1
  266. package/mcp-server/OAuthAppForm.d.ts.map +1 -1
  267. package/mcp-server/OAuthAppForm.js +2 -4
  268. package/mcp-server/OAuthAppForm.js.map +1 -1
  269. package/mcp-server/internal/definitionDrift.d.ts +39 -0
  270. package/mcp-server/internal/definitionDrift.d.ts.map +1 -0
  271. package/mcp-server/internal/definitionDrift.js +122 -0
  272. package/mcp-server/internal/definitionDrift.js.map +1 -0
  273. package/mcp-server/internal/mcpServerToInput.d.ts.map +1 -1
  274. package/mcp-server/internal/mcpServerToInput.js +3 -0
  275. package/mcp-server/internal/mcpServerToInput.js.map +1 -1
  276. package/mcp-server/steps/EnvironmentAuthStep.d.ts.map +1 -1
  277. package/mcp-server/steps/EnvironmentAuthStep.js +8 -4
  278. package/mcp-server/steps/EnvironmentAuthStep.js.map +1 -1
  279. package/mcp-server/steps/IdentityTransportStep.d.ts.map +1 -1
  280. package/mcp-server/steps/IdentityTransportStep.js +5 -4
  281. package/mcp-server/steps/IdentityTransportStep.js.map +1 -1
  282. package/mcp-server/useMcpServerConnect.d.ts +1 -1
  283. package/mcp-server/useMcpServerDefinitionDrift.d.ts +44 -0
  284. package/mcp-server/useMcpServerDefinitionDrift.d.ts.map +1 -0
  285. package/mcp-server/useMcpServerDefinitionDrift.js +61 -0
  286. package/mcp-server/useMcpServerDefinitionDrift.js.map +1 -0
  287. package/models/ModelRegistryContext.d.ts +7 -1
  288. package/models/ModelRegistryContext.d.ts.map +1 -1
  289. package/models/ModelRegistryContext.js.map +1 -1
  290. package/models/ModelSelector.js +9 -1
  291. package/models/ModelSelector.js.map +1 -1
  292. package/models/index.d.ts +2 -2
  293. package/models/index.d.ts.map +1 -1
  294. package/models/index.js +1 -1
  295. package/models/index.js.map +1 -1
  296. package/models/registry.d.ts +88 -6
  297. package/models/registry.d.ts.map +1 -1
  298. package/models/registry.js +133 -27
  299. package/models/registry.js.map +1 -1
  300. package/models/useModelRegistry.d.ts +7 -1
  301. package/models/useModelRegistry.d.ts.map +1 -1
  302. package/models/useModelRegistry.js +3 -2
  303. package/models/useModelRegistry.js.map +1 -1
  304. package/oauth-app/CreateOAuthAppForm.d.ts.map +1 -1
  305. package/oauth-app/CreateOAuthAppForm.js +4 -5
  306. package/oauth-app/CreateOAuthAppForm.js.map +1 -1
  307. package/oauth-app/OAuthAppDetailPanel.d.ts.map +1 -1
  308. package/oauth-app/OAuthAppDetailPanel.js +5 -6
  309. package/oauth-app/OAuthAppDetailPanel.js.map +1 -1
  310. package/organization/CreateOrganizationForm.d.ts.map +1 -1
  311. package/organization/CreateOrganizationForm.js +5 -9
  312. package/organization/CreateOrganizationForm.js.map +1 -1
  313. package/organization/OrgProfilePanel.d.ts.map +1 -1
  314. package/organization/OrgProfilePanel.js +7 -16
  315. package/organization/OrgProfilePanel.js.map +1 -1
  316. package/package.json +4 -4
  317. package/platform-client/CreatePlatformClientForm.d.ts.map +1 -1
  318. package/platform-client/CreatePlatformClientForm.js +5 -6
  319. package/platform-client/CreatePlatformClientForm.js.map +1 -1
  320. package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -1
  321. package/platform-client/PlatformClientDetailPanel.js +6 -7
  322. package/platform-client/PlatformClientDetailPanel.js.map +1 -1
  323. package/platform-client/PlatformClientListPanel.d.ts.map +1 -1
  324. package/platform-client/PlatformClientListPanel.js +2 -4
  325. package/platform-client/PlatformClientListPanel.js.map +1 -1
  326. package/platform-client/PlatformClientSecretAlert.d.ts.map +1 -1
  327. package/platform-client/PlatformClientSecretAlert.js +18 -25
  328. package/platform-client/PlatformClientSecretAlert.js.map +1 -1
  329. package/provider.d.ts +34 -1
  330. package/provider.d.ts.map +1 -1
  331. package/provider.js +14 -7
  332. package/provider.js.map +1 -1
  333. package/resource-creation/WizardNav.d.ts.map +1 -1
  334. package/resource-creation/WizardNav.js +2 -4
  335. package/resource-creation/WizardNav.js.map +1 -1
  336. package/resource-detail/ConfirmDialog.d.ts +2 -3
  337. package/resource-detail/ConfirmDialog.d.ts.map +1 -1
  338. package/resource-detail/ConfirmDialog.js +8 -20
  339. package/resource-detail/ConfirmDialog.js.map +1 -1
  340. package/resource-detail/useCopyResource.d.ts +4 -3
  341. package/resource-detail/useCopyResource.d.ts.map +1 -1
  342. package/resource-detail/useCopyResource.js +10 -19
  343. package/resource-detail/useCopyResource.js.map +1 -1
  344. package/schedule/ScheduleDetailView.d.ts.map +1 -1
  345. package/schedule/ScheduleDetailView.js +2 -4
  346. package/schedule/ScheduleDetailView.js.map +1 -1
  347. package/schedule/ScheduleForm.d.ts.map +1 -1
  348. package/schedule/ScheduleForm.js +6 -7
  349. package/schedule/ScheduleForm.js.map +1 -1
  350. package/session/NewSessionViewer.d.ts +52 -2
  351. package/session/NewSessionViewer.d.ts.map +1 -1
  352. package/session/NewSessionViewer.js +21 -6
  353. package/session/NewSessionViewer.js.map +1 -1
  354. package/session/SessionViewer.d.ts +63 -2
  355. package/session/SessionViewer.d.ts.map +1 -1
  356. package/session/SessionViewer.js +43 -17
  357. package/session/SessionViewer.js.map +1 -1
  358. package/session/audience.d.ts +17 -0
  359. package/session/audience.d.ts.map +1 -1
  360. package/session/index.d.ts +2 -1
  361. package/session/index.d.ts.map +1 -1
  362. package/session/index.js.map +1 -1
  363. package/session/run-config.d.ts +50 -0
  364. package/session/run-config.d.ts.map +1 -0
  365. package/session/run-config.js +15 -0
  366. package/session/run-config.js.map +1 -0
  367. package/session/useNewSessionFlow.d.ts +11 -0
  368. package/session/useNewSessionFlow.d.ts.map +1 -1
  369. package/session/useNewSessionFlow.js +29 -2
  370. package/session/useNewSessionFlow.js.map +1 -1
  371. package/session/useSessionConversation.d.ts +7 -7
  372. package/session/useSessionConversation.d.ts.map +1 -1
  373. package/session/useSessionConversation.js +2 -0
  374. package/session/useSessionConversation.js.map +1 -1
  375. package/session/useSessionPageFlow.d.ts +18 -4
  376. package/session/useSessionPageFlow.d.ts.map +1 -1
  377. package/session/useSessionPageFlow.js +33 -6
  378. package/session/useSessionPageFlow.js.map +1 -1
  379. package/session/useSessionPanel.d.ts +37 -2
  380. package/session/useSessionPanel.d.ts.map +1 -1
  381. package/session/useSessionPanel.js +44 -10
  382. package/session/useSessionPanel.js.map +1 -1
  383. package/settings/ApiKeysSection.d.ts.map +1 -1
  384. package/settings/ApiKeysSection.js +3 -2
  385. package/settings/ApiKeysSection.js.map +1 -1
  386. package/settings/ChannelAppsSection.d.ts.map +1 -1
  387. package/settings/ChannelAppsSection.js +3 -2
  388. package/settings/ChannelAppsSection.js.map +1 -1
  389. package/settings/EnvironmentsSection.js +5 -3
  390. package/settings/EnvironmentsSection.js.map +1 -1
  391. package/settings/IdentityProvidersSection.d.ts.map +1 -1
  392. package/settings/IdentityProvidersSection.js +3 -2
  393. package/settings/IdentityProvidersSection.js.map +1 -1
  394. package/settings/InvitationsSection.d.ts.map +1 -1
  395. package/settings/InvitationsSection.js +3 -1
  396. package/settings/InvitationsSection.js.map +1 -1
  397. package/settings/MembersSection.d.ts.map +1 -1
  398. package/settings/MembersSection.js +3 -1
  399. package/settings/MembersSection.js.map +1 -1
  400. package/settings/OAuthAppsSection.d.ts.map +1 -1
  401. package/settings/OAuthAppsSection.js +3 -2
  402. package/settings/OAuthAppsSection.js.map +1 -1
  403. package/settings/OrgProfileSection.d.ts.map +1 -1
  404. package/settings/OrgProfileSection.js +3 -2
  405. package/settings/OrgProfileSection.js.map +1 -1
  406. package/settings/PlatformClientsSection.d.ts.map +1 -1
  407. package/settings/PlatformClientsSection.js +3 -2
  408. package/settings/PlatformClientsSection.js.map +1 -1
  409. package/settings/UsageSection.d.ts.map +1 -1
  410. package/settings/UsageSection.js +3 -1
  411. package/settings/UsageSection.js.map +1 -1
  412. package/sharing/ShareAgentDialog.d.ts.map +1 -1
  413. package/sharing/ShareAgentDialog.js +19 -26
  414. package/sharing/ShareAgentDialog.js.map +1 -1
  415. package/sidebar/chrome.d.ts +3 -4
  416. package/sidebar/chrome.d.ts.map +1 -1
  417. package/sidebar/chrome.js +5 -4
  418. package/sidebar/chrome.js.map +1 -1
  419. package/skill/SkillDiffDialog.d.ts.map +1 -1
  420. package/skill/SkillDiffDialog.js +5 -21
  421. package/skill/SkillDiffDialog.js.map +1 -1
  422. package/src/access/ManageAccessDialog.tsx +14 -28
  423. package/src/activity/format-relative-time.ts +11 -9
  424. package/src/agent/steps/CapabilitiesStep.tsx +6 -3
  425. package/src/agent/steps/IdentityStep.tsx +19 -12
  426. package/src/agent-instance/CreateAgentInstanceDialog.tsx +29 -33
  427. package/src/api-key/ApiKeyCreatedAlert.tsx +10 -19
  428. package/src/api-key/ApiKeyListPanel.tsx +3 -39
  429. package/src/api-key/CreateApiKeyForm.tsx +12 -26
  430. package/src/approval-defaults-context.ts +56 -0
  431. package/src/attachment/AttachmentImageLightbox.tsx +13 -36
  432. package/src/attachment/__tests__/vision-preflight.test.ts +311 -0
  433. package/src/attachment/index.ts +12 -0
  434. package/src/attachment/vision-preflight.ts +236 -0
  435. package/src/billing/AutoRechargeCard.tsx +5 -4
  436. package/src/billing/BillingSection.tsx +4 -3
  437. package/src/channel/ChannelConversationsDialog.tsx +14 -29
  438. package/src/channel/ChannelCredentialsDialog.tsx +19 -29
  439. package/src/channel/ChannelTemplatesDialog.tsx +16 -31
  440. package/src/channel/ConnectSlackDialog.tsx +19 -31
  441. package/src/channel/ConnectWhatsAppDialog.tsx +19 -31
  442. package/src/channel/useChannelSessions.ts +3 -0
  443. package/src/channel-app/ChannelAppDetailPanel.tsx +15 -12
  444. package/src/channel-app/CreateChannelAppForm.tsx +17 -12
  445. package/src/channel-app/internal.tsx +5 -25
  446. package/src/composer/ComposerToolbar.tsx +1 -1
  447. package/src/composer/SessionComposer.tsx +160 -13
  448. package/src/composer/__tests__/SessionComposer-modelCoherence.test.tsx +220 -0
  449. package/src/composer/__tests__/SessionComposer-visionPreflight.test.tsx +222 -0
  450. package/src/composer/icons.tsx +0 -18
  451. package/src/conversation/ConversationAttentionBanner.tsx +64 -19
  452. package/src/conversation/ConversationComposer.tsx +1 -1
  453. package/src/conversation/ConversationListPane.tsx +46 -20
  454. package/src/conversation/ConversationsWorkbench.tsx +1 -0
  455. package/src/conversation/__tests__/ConversationAttentionBanner.test.tsx +76 -2
  456. package/src/conversation/__tests__/ConversationListPane.test.tsx +15 -4
  457. package/src/cursor-accounts/MemberCoverageTable.tsx +3 -14
  458. package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +2 -10
  459. package/src/dashboard/DashboardFailedRuns.tsx +2 -12
  460. package/src/environment/CreateEnvironmentForm.tsx +8 -27
  461. package/src/environment/EnvVarForm.tsx +2 -18
  462. package/src/environment/EnvironmentVariableEditor.tsx +5 -21
  463. package/src/execution/ApprovalCard.tsx +23 -2
  464. package/src/execution/ArtifactApplyButton.tsx +2 -17
  465. package/src/execution/ArtifactPreviewModal.tsx +15 -27
  466. package/src/execution/ExecutionErrorNotice.tsx +99 -0
  467. package/src/execution/FilePathLink.tsx +5 -9
  468. package/src/execution/FileReviewCard.tsx +1 -20
  469. package/src/execution/FollowUpInput.tsx +1 -16
  470. package/src/execution/LivenessStatusLine.tsx +59 -0
  471. package/src/execution/MessageEntry.tsx +136 -25
  472. package/src/execution/MessageThread.tsx +84 -83
  473. package/src/execution/SetupProgress.tsx +5 -1
  474. package/src/execution/SubAgentSection.tsx +9 -20
  475. package/src/execution/TerminalSession.tsx +97 -10
  476. package/src/execution/ToolCallDetail.tsx +19 -0
  477. package/src/execution/ToolCallItem.tsx +175 -44
  478. package/src/execution/ToolRunGroup.tsx +30 -32
  479. package/src/execution/WriteBackCard.tsx +5 -24
  480. package/src/execution/__tests__/MessageEntry-copy.test.tsx +125 -0
  481. package/src/execution/__tests__/MessageThread.test.tsx +97 -0
  482. package/src/execution/__tests__/TerminalSession.test.tsx +71 -1
  483. package/src/execution/__tests__/ToolCallDetail.test.tsx +33 -1
  484. package/src/execution/__tests__/ToolCallItem.test.tsx +299 -11
  485. package/src/execution/__tests__/ToolRunGroup.test.tsx +41 -9
  486. package/src/execution/__tests__/intent-title.test.tsx +221 -0
  487. package/src/execution/__tests__/message-thread-slots.test.tsx +92 -0
  488. package/src/execution/__tests__/tool-presenter.test.tsx +41 -4
  489. package/src/execution/index.ts +11 -2
  490. package/src/execution/tool-categories.ts +195 -9
  491. package/src/execution/tool-presenter.ts +44 -2
  492. package/src/execution/useArtifactInspection.ts +4 -8
  493. package/src/iam-policy/GrantAccessForm.tsx +2 -18
  494. package/src/iam-policy/OrgMembersPanel.tsx +3 -19
  495. package/src/iam-policy/RoleSelector.tsx +8 -1
  496. package/src/identity-provider/CreateIdentityProviderForm.tsx +13 -31
  497. package/src/identity-provider/IdentityProviderDetailPanel.tsx +24 -49
  498. package/src/identity-provider/IdentityProviderListPanel.tsx +2 -18
  499. package/src/identity-provider/IdentityProviderWizard.tsx +15 -32
  500. package/src/identity-provider/SsoLoginPrompt.tsx +6 -21
  501. package/src/index.ts +26 -1
  502. package/src/internal/DecisionButton.tsx +1 -20
  503. package/src/internal/DialogShell.tsx +169 -0
  504. package/src/internal/SpinnerIcon.tsx +42 -0
  505. package/src/internal/__tests__/DialogShell.test.tsx +223 -0
  506. package/src/internal/__tests__/ThreadCardShell.test.tsx +43 -7
  507. package/src/internal/__tests__/useCopyFeedback.test.ts +92 -0
  508. package/src/internal/select-element-text.ts +17 -0
  509. package/src/internal/thread-card/ThreadCardShell.tsx +53 -21
  510. package/src/internal/thread-card/glyphs.tsx +24 -3
  511. package/src/internal/thread-card/index.ts +1 -0
  512. package/src/internal/useCopyFeedback.ts +61 -0
  513. package/src/invitation/InvitationCreatedAlert.tsx +10 -18
  514. package/src/invitation/InvitationManager.tsx +23 -34
  515. package/src/invitation/InvitationRedemption.tsx +2 -18
  516. package/src/library/useExportResource.ts +15 -29
  517. package/src/manifest/ApplyManifestDialog.tsx +8 -26
  518. package/src/manifest/EditResourceYamlDialog.tsx +4 -31
  519. package/src/mcp-server/DefinitionDriftNotice.tsx +120 -0
  520. package/src/mcp-server/McpServerConnectDialog.tsx +15 -29
  521. package/src/mcp-server/McpServerDetailView.tsx +69 -49
  522. package/src/mcp-server/OAuthAppForm.tsx +2 -18
  523. package/src/mcp-server/__tests__/DefinitionDriftNotice.test.tsx +57 -0
  524. package/src/mcp-server/__tests__/definitionDrift.test.ts +245 -0
  525. package/src/mcp-server/__tests__/mcpServerToInput.test.ts +201 -0
  526. package/src/mcp-server/__tests__/useMcpServerDefinitionDrift.test.tsx +173 -0
  527. package/src/mcp-server/internal/definitionDrift.ts +158 -0
  528. package/src/mcp-server/internal/mcpServerToInput.ts +3 -0
  529. package/src/mcp-server/steps/EnvironmentAuthStep.tsx +19 -19
  530. package/src/mcp-server/steps/IdentityTransportStep.tsx +24 -23
  531. package/src/mcp-server/useMcpServerConnect.ts +1 -1
  532. package/src/mcp-server/useMcpServerDefinitionDrift.ts +95 -0
  533. package/src/models/ModelRegistryContext.ts +7 -1
  534. package/src/models/ModelSelector.tsx +37 -0
  535. package/src/models/__tests__/ModelSelector-visionIndicator.test.tsx +129 -0
  536. package/src/models/__tests__/resolveDefaultModel.test.ts +115 -0
  537. package/src/models/__tests__/useModelRegistry.test.tsx +99 -4
  538. package/src/models/index.ts +2 -2
  539. package/src/models/registry.ts +196 -29
  540. package/src/models/useModelRegistry.ts +10 -2
  541. package/src/oauth-app/CreateOAuthAppForm.tsx +16 -31
  542. package/src/oauth-app/OAuthAppDetailPanel.tsx +16 -31
  543. package/src/organization/CreateOrganizationForm.tsx +10 -29
  544. package/src/organization/OrgProfilePanel.tsx +13 -44
  545. package/src/platform-client/CreatePlatformClientForm.tsx +9 -29
  546. package/src/platform-client/PlatformClientDetailPanel.tsx +10 -30
  547. package/src/platform-client/PlatformClientListPanel.tsx +2 -18
  548. package/src/platform-client/PlatformClientSecretAlert.tsx +26 -55
  549. package/src/provider.tsx +76 -33
  550. package/src/resource-creation/WizardNav.tsx +2 -18
  551. package/src/resource-detail/ConfirmDialog.tsx +9 -30
  552. package/src/resource-detail/useCopyResource.ts +17 -23
  553. package/src/schedule/ScheduleDetailView.tsx +2 -18
  554. package/src/schedule/ScheduleForm.tsx +19 -34
  555. package/src/session/NewSessionViewer.tsx +85 -7
  556. package/src/session/SessionViewer.tsx +120 -17
  557. package/src/session/__tests__/audienceWiring.test.tsx +76 -0
  558. package/src/session/__tests__/panelNegotiation.test.tsx +302 -0
  559. package/src/session/__tests__/useNewSessionFlow.test.tsx +134 -5
  560. package/src/session/__tests__/useSessionPageFlow.autoApprove.test.tsx +74 -0
  561. package/src/session/__tests__/useSessionPageFlow.runConfig.test.tsx +157 -0
  562. package/src/session/__tests__/useSessionPanel.test.ts +114 -0
  563. package/src/session/audience.ts +18 -0
  564. package/src/session/index.ts +2 -1
  565. package/src/session/run-config.ts +59 -0
  566. package/src/session/useNewSessionFlow.ts +39 -2
  567. package/src/session/useSessionConversation.ts +10 -8
  568. package/src/session/useSessionPageFlow.ts +51 -10
  569. package/src/session/useSessionPanel.ts +91 -10
  570. package/src/settings/ApiKeysSection.tsx +4 -3
  571. package/src/settings/ChannelAppsSection.tsx +4 -3
  572. package/src/settings/EnvironmentsSection.tsx +8 -5
  573. package/src/settings/IdentityProvidersSection.tsx +4 -3
  574. package/src/settings/InvitationsSection.tsx +4 -2
  575. package/src/settings/MembersSection.tsx +4 -2
  576. package/src/settings/OAuthAppsSection.tsx +4 -3
  577. package/src/settings/OrgProfileSection.tsx +4 -3
  578. package/src/settings/PlatformClientsSection.tsx +4 -3
  579. package/src/settings/UsageSection.tsx +4 -2
  580. package/src/sharing/ShareAgentDialog.tsx +33 -37
  581. package/src/sidebar/__tests__/WorkspaceSidebar.test.tsx +4 -1
  582. package/src/sidebar/chrome.tsx +6 -6
  583. package/src/skill/SkillDiffDialog.tsx +13 -36
  584. package/src/styles.css +43 -0
  585. package/src/version-history/VersionTimelineEntry.tsx +1 -21
  586. package/src/workflow/FailedRunsWidget.tsx +2 -9
  587. package/src/workflow/PendingApprovalsWidget.tsx +2 -9
  588. package/src/workflow/ViewYamlDialog.tsx +21 -55
  589. package/src/workflow/WorkflowArchitectDialog.tsx +17 -68
  590. package/src/workflow/WorkflowArtifactDocument.tsx +5 -9
  591. package/src/workflow/WorkflowCanvasEditor.tsx +2 -0
  592. package/src/workflow/WorkflowCanvasInner.tsx +14 -1
  593. package/src/workflow/WorkflowDiffGraph.tsx +7 -1
  594. package/src/workflow/WorkflowExecutionViewer.tsx +88 -11
  595. package/src/workflow/WorkflowExplainDialog.tsx +18 -60
  596. package/src/workflow/WorkflowGraphFullscreenDialog.tsx +14 -26
  597. package/src/workflow/WorkflowOverviewGraph.tsx +9 -1
  598. package/src/workflow/WorkflowRefinePanel.tsx +2 -18
  599. package/src/workflow/WorkflowRepairCard.tsx +2 -18
  600. package/src/workflow/WorkflowRunDialog.tsx +23 -70
  601. package/src/workflow/WorkflowTaskApprovalSummary.tsx +2 -17
  602. package/src/workflow/WorkflowVersionBadge.tsx +4 -13
  603. package/src/workflow/WorkflowVersionTimeline.tsx +1 -25
  604. package/src/workflow/__tests__/panelNegotiation.test.tsx +230 -0
  605. package/src/workflow/__tests__/useWorkflowCanvas.dirty.test.tsx +178 -0
  606. package/src/workflow/__tests__/useWorkflowCanvas.drag.test.tsx +224 -0
  607. package/src/workflow/__tests__/useWorkflowExecutionPanel.test.ts +100 -0
  608. package/src/workflow/execution-comparison/ExecutionComparisonPicker.tsx +20 -41
  609. package/src/workflow/execution-history/ExecutionHistoryTable.tsx +1 -25
  610. package/src/workflow/index.ts +1 -0
  611. package/src/workflow/instance/CreateWorkflowInstanceDialog.tsx +14 -27
  612. package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +2 -1
  613. package/src/workflow/picker/BranchAddPopover.tsx +4 -3
  614. package/src/workflow/templates/WorkflowTemplatePreview.tsx +18 -28
  615. package/src/workflow/useApprovalBoundary.ts +1 -1
  616. package/src/workflow/useWorkflowCanvas.ts +114 -11
  617. package/src/workflow/useWorkflowExecutionPanel.ts +95 -13
  618. package/styles.css +1 -1
  619. package/version-history/VersionTimelineEntry.d.ts.map +1 -1
  620. package/version-history/VersionTimelineEntry.js +1 -23
  621. package/version-history/VersionTimelineEntry.js.map +1 -1
  622. package/workflow/CanvasTransitionEdge.d.ts +1 -1
  623. package/workflow/FailedRunsWidget.d.ts.map +1 -1
  624. package/workflow/FailedRunsWidget.js +2 -11
  625. package/workflow/FailedRunsWidget.js.map +1 -1
  626. package/workflow/PendingApprovalsWidget.d.ts.map +1 -1
  627. package/workflow/PendingApprovalsWidget.js +2 -11
  628. package/workflow/PendingApprovalsWidget.js.map +1 -1
  629. package/workflow/ViewYamlDialog.d.ts.map +1 -1
  630. package/workflow/ViewYamlDialog.js +14 -49
  631. package/workflow/ViewYamlDialog.js.map +1 -1
  632. package/workflow/WorkflowArchitectDialog.d.ts.map +1 -1
  633. package/workflow/WorkflowArchitectDialog.js +10 -33
  634. package/workflow/WorkflowArchitectDialog.js.map +1 -1
  635. package/workflow/WorkflowArtifactDocument.d.ts.map +1 -1
  636. package/workflow/WorkflowArtifactDocument.js +5 -8
  637. package/workflow/WorkflowArtifactDocument.js.map +1 -1
  638. package/workflow/WorkflowCanvasEditor.d.ts.map +1 -1
  639. package/workflow/WorkflowCanvasEditor.js +1 -1
  640. package/workflow/WorkflowCanvasEditor.js.map +1 -1
  641. package/workflow/WorkflowCanvasInner.d.ts +4 -2
  642. package/workflow/WorkflowCanvasInner.d.ts.map +1 -1
  643. package/workflow/WorkflowCanvasInner.js +7 -3
  644. package/workflow/WorkflowCanvasInner.js.map +1 -1
  645. package/workflow/WorkflowDiffGraph.js +6 -2
  646. package/workflow/WorkflowDiffGraph.js.map +1 -1
  647. package/workflow/WorkflowExecutionViewer.d.ts +51 -0
  648. package/workflow/WorkflowExecutionViewer.d.ts.map +1 -1
  649. package/workflow/WorkflowExecutionViewer.js +23 -6
  650. package/workflow/WorkflowExecutionViewer.js.map +1 -1
  651. package/workflow/WorkflowExplainDialog.d.ts.map +1 -1
  652. package/workflow/WorkflowExplainDialog.js +10 -28
  653. package/workflow/WorkflowExplainDialog.js.map +1 -1
  654. package/workflow/WorkflowGraphFullscreenDialog.d.ts.map +1 -1
  655. package/workflow/WorkflowGraphFullscreenDialog.js +11 -17
  656. package/workflow/WorkflowGraphFullscreenDialog.js.map +1 -1
  657. package/workflow/WorkflowOverviewGraph.js +8 -2
  658. package/workflow/WorkflowOverviewGraph.js.map +1 -1
  659. package/workflow/WorkflowRefinePanel.d.ts.map +1 -1
  660. package/workflow/WorkflowRefinePanel.js +2 -4
  661. package/workflow/WorkflowRefinePanel.js.map +1 -1
  662. package/workflow/WorkflowRepairCard.d.ts.map +1 -1
  663. package/workflow/WorkflowRepairCard.js +2 -4
  664. package/workflow/WorkflowRepairCard.js.map +1 -1
  665. package/workflow/WorkflowRunDialog.d.ts.map +1 -1
  666. package/workflow/WorkflowRunDialog.js +14 -35
  667. package/workflow/WorkflowRunDialog.js.map +1 -1
  668. package/workflow/WorkflowTaskApprovalSummary.d.ts.map +1 -1
  669. package/workflow/WorkflowTaskApprovalSummary.js +2 -4
  670. package/workflow/WorkflowTaskApprovalSummary.js.map +1 -1
  671. package/workflow/WorkflowVersionBadge.d.ts.map +1 -1
  672. package/workflow/WorkflowVersionBadge.js +4 -13
  673. package/workflow/WorkflowVersionBadge.js.map +1 -1
  674. package/workflow/WorkflowVersionTimeline.d.ts.map +1 -1
  675. package/workflow/WorkflowVersionTimeline.js +1 -26
  676. package/workflow/WorkflowVersionTimeline.js.map +1 -1
  677. package/workflow/execution-comparison/ExecutionComparisonPicker.d.ts.map +1 -1
  678. package/workflow/execution-comparison/ExecutionComparisonPicker.js +14 -40
  679. package/workflow/execution-comparison/ExecutionComparisonPicker.js.map +1 -1
  680. package/workflow/execution-history/ExecutionHistoryTable.d.ts.map +1 -1
  681. package/workflow/execution-history/ExecutionHistoryTable.js +1 -24
  682. package/workflow/execution-history/ExecutionHistoryTable.js.map +1 -1
  683. package/workflow/index.d.ts +1 -1
  684. package/workflow/index.d.ts.map +1 -1
  685. package/workflow/index.js.map +1 -1
  686. package/workflow/instance/CreateWorkflowInstanceDialog.d.ts.map +1 -1
  687. package/workflow/instance/CreateWorkflowInstanceDialog.js +7 -20
  688. package/workflow/instance/CreateWorkflowInstanceDialog.js.map +1 -1
  689. package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
  690. package/workflow/instance/WorkflowInstanceDetailPanel.js +1 -1
  691. package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
  692. package/workflow/picker/BranchAddPopover.d.ts.map +1 -1
  693. package/workflow/picker/BranchAddPopover.js +3 -2
  694. package/workflow/picker/BranchAddPopover.js.map +1 -1
  695. package/workflow/templates/WorkflowTemplatePreview.d.ts +1 -1
  696. package/workflow/templates/WorkflowTemplatePreview.d.ts.map +1 -1
  697. package/workflow/templates/WorkflowTemplatePreview.js +10 -22
  698. package/workflow/templates/WorkflowTemplatePreview.js.map +1 -1
  699. package/workflow/useApprovalBoundary.d.ts +1 -1
  700. package/workflow/useApprovalBoundary.js +1 -1
  701. package/workflow/useWorkflowCanvas.d.ts +5 -1
  702. package/workflow/useWorkflowCanvas.d.ts.map +1 -1
  703. package/workflow/useWorkflowCanvas.js +99 -13
  704. package/workflow/useWorkflowCanvas.js.map +1 -1
  705. package/workflow/useWorkflowExecutionPanel.d.ts +38 -2
  706. package/workflow/useWorkflowExecutionPanel.d.ts.map +1 -1
  707. package/workflow/useWorkflowExecutionPanel.js +46 -13
  708. package/workflow/useWorkflowExecutionPanel.js.map +1 -1
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Client-side vision preflight — predicts, before a turn is spent, which
3
+ * attached images the runner will refuse to deliver inline and why
4
+ * (stigmer/stigmer#365, stigmer/stigmer#386).
5
+ *
6
+ * The runner is the enforcement authority (`VisionBudget` in its
7
+ * `shared/attachment-vision.ts`); this module is the warning authority.
8
+ * To never warn differently than the runner behaves, it replicates the
9
+ * runner's admission semantics against the SAME data the runner uses:
10
+ *
11
+ * - the byte budget arrives via the registry document's `limits.vision`
12
+ * block ({@link VisionLimits}) — advertised == enforced;
13
+ * - the model's vision capability arrives via the per-model
14
+ * `capabilities` block ({@link ModelInfo.visionCapability});
15
+ * - reasons reuse the runner's disclosure vocabulary
16
+ * (`VisionDegradedReason`), so a warning here and a disclosure in the
17
+ * agent's reply always tell one story.
18
+ *
19
+ * Tri-state discipline: absent limits or an unassessed model produce NO
20
+ * warnings. A client that cannot know the budget must stay silent, not
21
+ * guess — the runner's own disclosure remains the backstop.
22
+ *
23
+ * Deliberately assessed client-side reasons are a SUBSET of the runner's:
24
+ * `unsupported_format` and `type_mismatch` need magic-byte sniffing that a
25
+ * declared content type cannot honestly stand in for (and pasted images are
26
+ * already normalized by `prepareImageForVision`), so those two remain
27
+ * runner-disclosed only.
28
+ */
29
+
30
+ import type { ModelInfo, VisionLimits } from "../models/registry.js";
31
+ import { formatFileSize } from "./attachment-utils.js";
32
+
33
+ /**
34
+ * Content types the runner recognizes as vision candidates (its
35
+ * `VisionMimeType` set). Anything else — PDFs, SVGs, archives — rides the
36
+ * normal file story with no inline-vision expectation and no warning.
37
+ */
38
+ const VISION_CANDIDATE_TYPES: ReadonlySet<string> = new Set([
39
+ "image/png",
40
+ "image/jpeg",
41
+ "image/webp",
42
+ "image/gif",
43
+ ]);
44
+
45
+ /** Minimal attachment shape the preflight needs — pure data, no `File`. */
46
+ export interface VisionPreflightAttachment {
47
+ /** Display name used in warning copy (the chip's filename). */
48
+ readonly name: string;
49
+ /** Raw byte size — what the runner's budget counts. */
50
+ readonly sizeBytes: number;
51
+ /** Declared/detected MIME type (`AttachmentEntry.contentType`). */
52
+ readonly contentType: string;
53
+ }
54
+
55
+ /**
56
+ * Why an image will not be viewable inline — the client-assessable subset
57
+ * of the runner's `VisionDegradedReason` vocabulary, same spellings.
58
+ */
59
+ export type VisionPreflightReason =
60
+ /** Raw bytes exceed the per-image cap; a smaller re-export would fix it. */
61
+ | "too_large"
62
+ /** Image is fine but the turn's total/count budget is already spent. */
63
+ | "budget_exhausted"
64
+ /** The selected model is explicitly assessed as unable to see images. */
65
+ | "model_no_vision";
66
+
67
+ /** One image the runner is predicted to degrade, and why. */
68
+ export interface VisionPreflightWarning {
69
+ readonly name: string;
70
+ readonly sizeBytes: number;
71
+ readonly reason: VisionPreflightReason;
72
+ }
73
+
74
+ /** Result of {@link assessVisionPreflight}. */
75
+ export interface VisionPreflight {
76
+ /** Predicted-degraded images in attachment order. Empty = all clear. */
77
+ readonly warnings: readonly VisionPreflightWarning[];
78
+ /**
79
+ * True when the selected model is explicitly blind (`vision: false`)
80
+ * and at least one image is attached. When set, every image warning
81
+ * carries `model_no_vision` — resending smaller images cannot help, so
82
+ * warning UI should lead with the model, not the files.
83
+ */
84
+ readonly modelCannotSeeImages: boolean;
85
+ }
86
+
87
+ const NO_WARNINGS: VisionPreflight = { warnings: [], modelCannotSeeImages: false };
88
+
89
+ /** Options for {@link assessVisionPreflight}. */
90
+ export interface AssessVisionPreflightOptions {
91
+ /**
92
+ * The model the turn will run on. `undefined` (unknown/still loading)
93
+ * disables the capability verdict, never the byte assessment.
94
+ */
95
+ readonly model?: ModelInfo | undefined;
96
+ /**
97
+ * The advertised byte budget from `useModelRegistry().visionLimits`.
98
+ * `undefined` (older server, still loading) disables the byte
99
+ * assessment, never the capability verdict.
100
+ */
101
+ readonly limits?: VisionLimits | undefined;
102
+ }
103
+
104
+ /**
105
+ * Predict which attached images the runner will degrade this turn.
106
+ *
107
+ * Pure and deterministic — safe to call in render (memoized by callers).
108
+ * Non-image attachments never warn. The byte assessment replicates the
109
+ * runner's sequential admission: an image over the per-image cap is
110
+ * degraded WITHOUT consuming budget; remaining images are admitted in
111
+ * order until the count or total-byte budget is exhausted.
112
+ */
113
+ export function assessVisionPreflight(
114
+ attachments: readonly VisionPreflightAttachment[],
115
+ options?: AssessVisionPreflightOptions,
116
+ ): VisionPreflight {
117
+ const candidates = attachments.filter((a) =>
118
+ VISION_CANDIDATE_TYPES.has(a.contentType.toLowerCase()),
119
+ );
120
+ if (candidates.length === 0) return NO_WARNINGS;
121
+
122
+ // The capability gate short-circuits the byte math: on an explicitly
123
+ // blind model no image is deliverable at any size, and mixing byte
124
+ // warnings in would wrongly suggest a smaller resend could help.
125
+ if (options?.model?.visionCapability === false) {
126
+ return {
127
+ warnings: candidates.map((a) => ({
128
+ name: a.name,
129
+ sizeBytes: a.sizeBytes,
130
+ reason: "model_no_vision",
131
+ })),
132
+ modelCannotSeeImages: true,
133
+ };
134
+ }
135
+
136
+ const limits = options?.limits;
137
+ if (!limits) return NO_WARNINGS;
138
+
139
+ const warnings: VisionPreflightWarning[] = [];
140
+ let acceptedCount = 0;
141
+ let acceptedBytes = 0;
142
+
143
+ for (const image of candidates) {
144
+ if (image.sizeBytes > limits.maxImageBytes) {
145
+ warnings.push({ name: image.name, sizeBytes: image.sizeBytes, reason: "too_large" });
146
+ continue;
147
+ }
148
+ if (
149
+ acceptedCount >= limits.maxImages ||
150
+ acceptedBytes + image.sizeBytes > limits.maxTotalBytes
151
+ ) {
152
+ warnings.push({
153
+ name: image.name,
154
+ sizeBytes: image.sizeBytes,
155
+ reason: "budget_exhausted",
156
+ });
157
+ continue;
158
+ }
159
+ acceptedCount += 1;
160
+ acceptedBytes += image.sizeBytes;
161
+ }
162
+
163
+ return warnings.length === 0
164
+ ? NO_WARNINGS
165
+ : { warnings, modelCannotSeeImages: false };
166
+ }
167
+
168
+ /** Options for {@link visionPreflightMessage}. */
169
+ export interface VisionPreflightMessageOptions {
170
+ /** The advertised budget — names the caps in the copy when present. */
171
+ readonly limits?: VisionLimits | undefined;
172
+ /** Display name of the selected model, for the capability wording. */
173
+ readonly modelDisplayName?: string | undefined;
174
+ }
175
+
176
+ /**
177
+ * One-line human copy for a {@link VisionPreflight} — the client-side twin
178
+ * of the runner's `visionDisclosureLines`, worded for BEFORE the turn
179
+ * ("will arrive as a file") instead of after ("was not viewable").
180
+ *
181
+ * Returns `null` when there is nothing to warn about. Copy rules:
182
+ * - a blind model leads with the model, never the files — no smaller
183
+ * resend can help, so file-size advice would be dishonest;
184
+ * - `too_large` names the files (up to two, then a count) and the actual
185
+ * cap, so the fix — export smaller — is self-evident;
186
+ * - `budget_exhausted` explains the per-turn budget, the only fix being
187
+ * fewer images this turn.
188
+ */
189
+ export function visionPreflightMessage(
190
+ preflight: VisionPreflight,
191
+ options?: VisionPreflightMessageOptions,
192
+ ): string | null {
193
+ if (preflight.warnings.length === 0) return null;
194
+
195
+ if (preflight.modelCannotSeeImages) {
196
+ const model = options?.modelDisplayName ?? "The selected model";
197
+ return `${model} can't view images — attached images will reach the agent as files only.`;
198
+ }
199
+
200
+ const tooLarge = preflight.warnings.filter((w) => w.reason === "too_large");
201
+ const exhausted = preflight.warnings.filter((w) => w.reason === "budget_exhausted");
202
+ const parts: string[] = [];
203
+
204
+ if (tooLarge.length > 0) {
205
+ const capPhrase = options?.limits
206
+ ? `the ${formatFileSize(options.limits.maxImageBytes)} inline-image limit`
207
+ : "the inline-image size limit";
208
+ if (tooLarge.length === 1) {
209
+ const w = tooLarge[0];
210
+ parts.push(
211
+ `${w.name} (${formatFileSize(w.sizeBytes)}) exceeds ${capPhrase} and will reach the agent as a file, not an image`,
212
+ );
213
+ } else if (tooLarge.length === 2) {
214
+ parts.push(
215
+ `${tooLarge[0].name} and ${tooLarge[1].name} exceed ${capPhrase} and will reach the agent as files, not images`,
216
+ );
217
+ } else {
218
+ parts.push(
219
+ `${tooLarge.length} images exceed ${capPhrase} and will reach the agent as files, not images`,
220
+ );
221
+ }
222
+ }
223
+
224
+ if (exhausted.length > 0) {
225
+ const budget = options?.limits
226
+ ? `this turn's inline-image budget (${options.limits.maxImages} images, ${formatFileSize(options.limits.maxTotalBytes)} total)`
227
+ : "this turn's inline-image budget";
228
+ parts.push(
229
+ exhausted.length === 1
230
+ ? `${exhausted[0].name} is over ${budget} and will reach the agent as a file`
231
+ : `${exhausted.length} images are over ${budget} and will reach the agent as files`,
232
+ );
233
+ }
234
+
235
+ return parts.length === 0 ? null : `${parts.join("; ")}.`;
236
+ }
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { useState, useCallback, useEffect } from "react";
3
+ import { useState, useCallback, useEffect, useId } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
5
  import type { AutoRechargeConfig } from "@stigmer/protos/ai/stigmer/billing/v1/billing_account_pb";
6
6
  import { BillingAccountStatus } from "@stigmer/protos/ai/stigmer/billing/v1/enum_pb";
@@ -64,6 +64,7 @@ export function AutoRechargeCard({
64
64
  onSaved,
65
65
  className,
66
66
  }: AutoRechargeCardProps) {
67
+ const baseId = useId();
67
68
  const { setConfig, isSubmitting, error, clearError } =
68
69
  useSetAutoRechargeConfig();
69
70
 
@@ -168,7 +169,7 @@ export function AutoRechargeCard({
168
169
  {canConfigure && (
169
170
  <div className="stg:mt-4 stg:space-y-3">
170
171
  <DollarInput
171
- id="ar-threshold"
172
+ id={`${baseId}-threshold`}
172
173
  label="When balance drops below"
173
174
  value={threshold}
174
175
  onChange={setThreshold}
@@ -176,7 +177,7 @@ export function AutoRechargeCard({
176
177
  placeholder="e.g. 5"
177
178
  />
178
179
  <DollarInput
179
- id="ar-amount"
180
+ id={`${baseId}-amount`}
180
181
  label="Recharge amount"
181
182
  value={amount}
182
183
  onChange={setAmount}
@@ -184,7 +185,7 @@ export function AutoRechargeCard({
184
185
  placeholder="e.g. 50"
185
186
  />
186
187
  <DollarInput
187
- id="ar-cap"
188
+ id={`${baseId}-cap`}
188
189
  label="Monthly cap"
189
190
  value={cap}
190
191
  onChange={setCap}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { useState, useCallback } from "react";
3
+ import { useCallback, useId, useState } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
5
  import { getUserMessage } from "@stigmer/sdk";
6
6
  import { BillingAccountStatus } from "@stigmer/protos/ai/stigmer/billing/v1/enum_pb";
@@ -53,14 +53,15 @@ export function BillingSection({
53
53
  onDismissCheckoutSuccess,
54
54
  className,
55
55
  }: BillingSectionProps) {
56
+ const headingId = useId();
56
57
  const { activeOrg } = useOrg();
57
58
  const mode = useDeploymentMode();
58
59
  const orgId = activeOrg?.metadata?.id ?? "";
59
60
 
60
61
  return (
61
- <section aria-labelledby="billing-heading" className={className}>
62
+ <section aria-labelledby={headingId} className={className}>
62
63
  <h2
63
- id="billing-heading"
64
+ id={headingId}
64
65
  className="stg:text-foreground stg:mb-1 stg:text-sm stg:font-semibold"
65
66
  >
66
67
  Billing
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
 
3
- import { useCallback, useRef } from "react";
3
+ import { useCallback, useId } from "react";
4
4
  import { timestampDate } from "@bufbuild/protobuf/wkt";
5
5
  import { MessageSquare, User, X } from "lucide-react";
6
6
  import { cn } from "@stigmer/theme";
7
+ import { DialogShell } from "../internal/DialogShell.js";
7
8
  import { getUserMessage } from "@stigmer/sdk";
8
9
  import type { AgentChannel } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/api_pb";
9
10
  import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
@@ -68,56 +69,40 @@ export function ChannelConversationsDialog({
68
69
  sessionHref,
69
70
  modal = true,
70
71
  }: ChannelConversationsDialogProps) {
71
- const dialogRef = useRef<HTMLDialogElement>(null);
72
+ const titleId = useId();
72
73
 
73
74
  const handleClose = useCallback(() => {
74
- dialogRef.current?.close();
75
75
  onOpenChange(false);
76
76
  }, [onOpenChange]);
77
77
 
78
- // Sync native dialog open state (matches the SDK dialog convention).
79
- const prevOpenRef = useRef(false);
80
- if (modal && open !== prevOpenRef.current) {
81
- prevOpenRef.current = open;
82
- if (open) {
83
- requestAnimationFrame(() => {
84
- if (dialogRef.current && !dialogRef.current.open) {
85
- dialogRef.current.showModal();
86
- }
87
- });
88
- } else if (dialogRef.current?.open) {
89
- dialogRef.current.close();
90
- }
91
- }
92
-
93
78
  return (
94
- <dialog
95
- ref={dialogRef}
96
- open={modal ? undefined : open}
97
- onClose={handleClose}
98
- className={cn(
99
- "stg:w-full stg:max-w-lg stg:rounded-xl stg:border stg:border-border stg:bg-popover stg:p-0 stg:shadow-xl",
100
- modal ? "stg:fixed stg:inset-0 stg:m-auto stg:backdrop:bg-black/50" : "stg:relative",
101
- )}
102
- aria-labelledby="channel-conversations-title"
79
+ <DialogShell
80
+ open={open}
81
+ onOpenChange={onOpenChange}
82
+ modal={modal}
83
+ width="lg"
84
+ aria-labelledby={titleId}
103
85
  >
104
86
  {/* Body mounts only while open so each opening fetches fresh. */}
105
87
  {open && (
106
88
  <ChannelConversationsDialogBody
89
+ titleId={titleId}
107
90
  channel={channel}
108
91
  sessionHref={sessionHref}
109
92
  onClose={handleClose}
110
93
  />
111
94
  )}
112
- </dialog>
95
+ </DialogShell>
113
96
  );
114
97
  }
115
98
 
116
99
  function ChannelConversationsDialogBody({
100
+ titleId,
117
101
  channel,
118
102
  sessionHref,
119
103
  onClose,
120
104
  }: {
105
+ readonly titleId: string;
121
106
  readonly channel: AgentChannel;
122
107
  readonly sessionHref?: (sessionId: string) => string;
123
108
  readonly onClose: () => void;
@@ -133,7 +118,7 @@ function ChannelConversationsDialogBody({
133
118
  <div className="stg:flex stg:items-start stg:justify-between stg:gap-3 stg:border-b stg:border-border stg:px-5 stg:py-4">
134
119
  <div className="stg:min-w-0">
135
120
  <h2
136
- id="channel-conversations-title"
121
+ id={titleId}
137
122
  className="stg:text-sm stg:font-semibold stg:text-popover-foreground"
138
123
  >
139
124
  Sessions
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
 
3
- import { useCallback, useRef, useState } from "react";
3
+ import { useCallback, useId, useState } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
+ import { DialogShell } from "../internal/DialogShell.js";
5
6
  import { getUserMessage, type ResourceRef } from "@stigmer/sdk";
6
7
  import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
7
8
  import type { AgentChannel } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/api_pb";
@@ -51,38 +52,23 @@ export function ChannelCredentialsDialog({
51
52
  onSaved,
52
53
  modal = true,
53
54
  }: ChannelCredentialsDialogProps) {
54
- const dialogRef = useRef<HTMLDialogElement>(null);
55
+ // Instance-scoped title id (oss#593): a reusable component must not
56
+ // hardcode DOM ids — hosts legitimately mount this dialog more than once
57
+ // per page (e.g. zone-cached detail pages), and duplicate ids break the
58
+ // aria-labelledby association for every copy after the first.
59
+ const titleId = useId();
55
60
 
56
61
  const handleClose = useCallback(() => {
57
- dialogRef.current?.close();
58
62
  onOpenChange(false);
59
63
  }, [onOpenChange]);
60
64
 
61
- // Sync native dialog open state (matches the SDK dialog convention).
62
- const prevOpenRef = useRef(false);
63
- if (modal && open !== prevOpenRef.current) {
64
- prevOpenRef.current = open;
65
- if (open) {
66
- requestAnimationFrame(() => {
67
- if (dialogRef.current && !dialogRef.current.open) {
68
- dialogRef.current.showModal();
69
- }
70
- });
71
- } else if (dialogRef.current?.open) {
72
- dialogRef.current.close();
73
- }
74
- }
75
-
76
65
  return (
77
- <dialog
78
- ref={dialogRef}
79
- open={modal ? undefined : open}
80
- onClose={handleClose}
81
- className={cn(
82
- "stg:w-full stg:max-w-md stg:rounded-xl stg:border stg:border-border stg:bg-popover stg:p-0 stg:shadow-xl",
83
- modal ? "stg:fixed stg:inset-0 stg:m-auto stg:backdrop:bg-black/50" : "stg:relative",
84
- )}
85
- aria-labelledby="channel-credentials-title"
66
+ <DialogShell
67
+ open={open}
68
+ onOpenChange={onOpenChange}
69
+ modal={modal}
70
+ width="md"
71
+ aria-labelledby={titleId}
86
72
  >
87
73
  {/* Body mounts only while open so its draft resets per session —
88
74
  reopening never resumes stale, unsaved edits. */}
@@ -92,9 +78,10 @@ export function ChannelCredentialsDialog({
92
78
  channel={channel}
93
79
  onSaved={onSaved}
94
80
  onClose={handleClose}
81
+ titleId={titleId}
95
82
  />
96
83
  )}
97
- </dialog>
84
+ </DialogShell>
98
85
  );
99
86
  }
100
87
 
@@ -103,11 +90,14 @@ function ChannelCredentialsDialogBody({
103
90
  channel,
104
91
  onSaved,
105
92
  onClose,
93
+ titleId,
106
94
  }: {
107
95
  readonly agent: Agent;
108
96
  readonly channel: AgentChannel;
109
97
  readonly onSaved?: () => void;
110
98
  readonly onClose: () => void;
99
+ /** Heading id minted by the outer dialog for its aria-labelledby. */
100
+ readonly titleId: string;
111
101
  }) {
112
102
  const channelName =
113
103
  channel.metadata?.name || channel.metadata?.slug || "this channel";
@@ -142,7 +132,7 @@ function ChannelCredentialsDialogBody({
142
132
  <div className="stg:flex stg:items-start stg:justify-between stg:gap-3 stg:border-b stg:border-border stg:px-5 stg:py-4">
143
133
  <div className="stg:min-w-0">
144
134
  <h2
145
- id="channel-credentials-title"
135
+ id={titleId}
146
136
  className="stg:text-sm stg:font-semibold stg:text-foreground"
147
137
  >
148
138
  Tool credentials
@@ -1,8 +1,9 @@
1
1
  "use client";
2
2
 
3
- import { useCallback, useRef, type ReactNode } from "react";
3
+ import { useCallback, useId, type ReactNode } from "react";
4
4
  import { ExternalLink, LayoutTemplate, X } from "lucide-react";
5
5
  import { cn } from "@stigmer/theme";
6
+ import { DialogShell } from "../internal/DialogShell.js";
6
7
  import { getUserMessage } from "@stigmer/sdk";
7
8
  import type { AgentChannel } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/api_pb";
8
9
  import type { ChannelTemplate } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/message_io_pb";
@@ -89,59 +90,43 @@ export function ChannelTemplatesDialog({
89
90
  onEditYaml,
90
91
  modal = true,
91
92
  }: ChannelTemplatesDialogProps) {
92
- const dialogRef = useRef<HTMLDialogElement>(null);
93
+ const titleId = useId();
93
94
 
94
95
  const handleClose = useCallback(() => {
95
- dialogRef.current?.close();
96
96
  onOpenChange(false);
97
97
  }, [onOpenChange]);
98
98
 
99
- // Sync native dialog open state (matches the SDK dialog convention).
100
- const prevOpenRef = useRef(false);
101
- if (modal && open !== prevOpenRef.current) {
102
- prevOpenRef.current = open;
103
- if (open) {
104
- requestAnimationFrame(() => {
105
- if (dialogRef.current && !dialogRef.current.open) {
106
- dialogRef.current.showModal();
107
- }
108
- });
109
- } else if (dialogRef.current?.open) {
110
- dialogRef.current.close();
111
- }
112
- }
113
-
114
99
  return (
115
- <dialog
116
- ref={dialogRef}
117
- open={modal ? undefined : open}
118
- onClose={handleClose}
119
- className={cn(
120
- // Wider than the conversations dialog on purpose: template
121
- // bodies are the content, and a narrow column shreds them.
122
- "stg:w-full stg:max-w-2xl stg:rounded-xl stg:border stg:border-border stg:bg-popover stg:p-0 stg:shadow-xl",
123
- modal ? "stg:fixed stg:inset-0 stg:m-auto stg:backdrop:bg-black/50" : "stg:relative",
124
- )}
125
- aria-labelledby="channel-templates-title"
100
+ <DialogShell
101
+ open={open}
102
+ onOpenChange={onOpenChange}
103
+ modal={modal}
104
+ // Wider than the conversations dialog on purpose: template
105
+ // bodies are the content, and a narrow column shreds them.
106
+ width="2xl"
107
+ aria-labelledby={titleId}
126
108
  >
127
109
  {/* Body mounts only while open so each opening fetches fresh —
128
110
  approval statuses change on the provider's side at any time. */}
129
111
  {open && (
130
112
  <ChannelTemplatesDialogBody
113
+ titleId={titleId}
131
114
  channel={channel}
132
115
  onEditYaml={onEditYaml}
133
116
  onClose={handleClose}
134
117
  />
135
118
  )}
136
- </dialog>
119
+ </DialogShell>
137
120
  );
138
121
  }
139
122
 
140
123
  function ChannelTemplatesDialogBody({
124
+ titleId,
141
125
  channel,
142
126
  onEditYaml,
143
127
  onClose,
144
128
  }: {
129
+ readonly titleId: string;
145
130
  readonly channel: AgentChannel;
146
131
  readonly onEditYaml?: () => void;
147
132
  readonly onClose: () => void;
@@ -154,7 +139,7 @@ function ChannelTemplatesDialogBody({
154
139
  <div className="stg:flex stg:items-start stg:justify-between stg:gap-3 stg:border-b stg:border-border stg:px-5 stg:py-4">
155
140
  <div className="stg:min-w-0">
156
141
  <h2
157
- id="channel-templates-title"
142
+ id={titleId}
158
143
  className="stg:text-sm stg:font-semibold stg:text-popover-foreground"
159
144
  >
160
145
  Templates
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
 
3
- import { useCallback, useMemo, useRef, useState } from "react";
3
+ import { useCallback, useId, useMemo, useState } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
+ import { DialogShell } from "../internal/DialogShell.js";
5
6
  import { getErrorReason, type ResourceRef } from "@stigmer/sdk";
6
7
  import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
7
8
  import type { AgentChannel } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/api_pb";
@@ -89,40 +90,23 @@ export function ConnectSlackDialog({
89
90
  modal = true,
90
91
  channelAppsHref,
91
92
  }: ConnectSlackDialogProps) {
92
- const dialogRef = useRef<HTMLDialogElement>(null);
93
+ // Instance-scoped title id (oss#593): a reusable component must not
94
+ // hardcode DOM ids — hosts legitimately mount this dialog more than once
95
+ // per page (e.g. zone-cached detail pages), and duplicate ids break the
96
+ // aria-labelledby association for every copy after the first.
97
+ const titleId = useId();
93
98
 
94
99
  const handleClose = useCallback(() => {
95
- dialogRef.current?.close();
96
100
  onOpenChange(false);
97
101
  }, [onOpenChange]);
98
102
 
99
- // Sync native dialog open state (matches the SDK dialog convention).
100
- // Non-modal hosts pass `open` as a plain attribute instead — the dialog
101
- // renders in-flow with no top layer to manage.
102
- const prevOpenRef = useRef(false);
103
- if (modal && open !== prevOpenRef.current) {
104
- prevOpenRef.current = open;
105
- if (open) {
106
- requestAnimationFrame(() => {
107
- if (dialogRef.current && !dialogRef.current.open) {
108
- dialogRef.current.showModal();
109
- }
110
- });
111
- } else if (dialogRef.current?.open) {
112
- dialogRef.current.close();
113
- }
114
- }
115
-
116
103
  return (
117
- <dialog
118
- ref={dialogRef}
119
- open={modal ? undefined : open}
120
- onClose={handleClose}
121
- className={cn(
122
- "stg:w-full stg:max-w-md stg:rounded-xl stg:border stg:border-border stg:bg-popover stg:p-0 stg:shadow-xl",
123
- modal ? "stg:fixed stg:inset-0 stg:m-auto stg:backdrop:bg-black/50" : "stg:relative",
124
- )}
125
- aria-labelledby="connect-slack-title"
104
+ <DialogShell
105
+ open={open}
106
+ onOpenChange={onOpenChange}
107
+ modal={modal}
108
+ width="md"
109
+ aria-labelledby={titleId}
126
110
  >
127
111
  {/* Body mounts only while open so its flow state resets per
128
112
  session — reopening the dialog never resumes a stale flow. */}
@@ -132,10 +116,11 @@ export function ConnectSlackDialog({
132
116
  channel={channel ?? null}
133
117
  onChannelsChanged={onChannelsChanged}
134
118
  onClose={handleClose}
119
+ titleId={titleId}
135
120
  channelAppsHref={channelAppsHref}
136
121
  />
137
122
  )}
138
- </dialog>
123
+ </DialogShell>
139
124
  );
140
125
  }
141
126
 
@@ -149,6 +134,8 @@ interface ConnectSlackDialogBodyProps {
149
134
  readonly onChannelsChanged?: () => void;
150
135
  readonly onClose: () => void;
151
136
  readonly channelAppsHref?: string;
137
+ /** Heading id minted by the outer dialog for its aria-labelledby. */
138
+ readonly titleId: string;
152
139
  }
153
140
 
154
141
  function ConnectSlackDialogBody({
@@ -157,6 +144,7 @@ function ConnectSlackDialogBody({
157
144
  onChannelsChanged,
158
145
  onClose,
159
146
  channelAppsHref,
147
+ titleId,
160
148
  }: ConnectSlackDialogBodyProps) {
161
149
  const deploymentMode = useDeploymentMode();
162
150
  const agentName = agent.metadata?.name || agent.metadata?.slug || "this agent";
@@ -276,7 +264,7 @@ function ConnectSlackDialogBody({
276
264
  <div className="stg:flex stg:items-start stg:justify-between stg:gap-3 stg:border-b stg:border-border stg:px-5 stg:py-4">
277
265
  <div className="stg:flex stg:items-center stg:gap-2.5">
278
266
  <SlackMarkIcon className="stg:size-5 stg:text-foreground" />
279
- <h2 id="connect-slack-title" className="stg:text-sm stg:font-semibold stg:text-foreground">
267
+ <h2 id={titleId} className="stg:text-sm stg:font-semibold stg:text-foreground">
280
268
  {channel ? "Reconnect to Slack" : "Connect to Slack"}
281
269
  </h2>
282
270
  </div>