@stigmer/react 3.12.1 → 3.12.2

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 (658) hide show
  1. package/access/ManageAccessDialog.d.ts.map +1 -1
  2. package/access/ManageAccessDialog.js +7 -2
  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 +10 -2
  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/index.d.ts +2 -0
  30. package/attachment/index.d.ts.map +1 -1
  31. package/attachment/index.js +1 -0
  32. package/attachment/index.js.map +1 -1
  33. package/attachment/vision-preflight.d.ts +113 -0
  34. package/attachment/vision-preflight.d.ts.map +1 -0
  35. package/attachment/vision-preflight.js +143 -0
  36. package/attachment/vision-preflight.js.map +1 -0
  37. package/billing/AutoRechargeCard.d.ts.map +1 -1
  38. package/billing/AutoRechargeCard.js +3 -2
  39. package/billing/AutoRechargeCard.js.map +1 -1
  40. package/billing/BillingSection.d.ts.map +1 -1
  41. package/billing/BillingSection.js +3 -2
  42. package/billing/BillingSection.js.map +1 -1
  43. package/channel/ChannelConversationsDialog.d.ts.map +1 -1
  44. package/channel/ChannelConversationsDialog.js +5 -4
  45. package/channel/ChannelConversationsDialog.js.map +1 -1
  46. package/channel/ChannelCredentialsDialog.d.ts.map +1 -1
  47. package/channel/ChannelCredentialsDialog.js +9 -4
  48. package/channel/ChannelCredentialsDialog.js.map +1 -1
  49. package/channel/ChannelTemplatesDialog.d.ts.map +1 -1
  50. package/channel/ChannelTemplatesDialog.js +5 -4
  51. package/channel/ChannelTemplatesDialog.js.map +1 -1
  52. package/channel/ConnectSlackDialog.d.ts.map +1 -1
  53. package/channel/ConnectSlackDialog.js +9 -4
  54. package/channel/ConnectSlackDialog.js.map +1 -1
  55. package/channel/ConnectWhatsAppDialog.d.ts.map +1 -1
  56. package/channel/ConnectWhatsAppDialog.js +9 -4
  57. package/channel/ConnectWhatsAppDialog.js.map +1 -1
  58. package/channel/useChannelSessions.d.ts.map +1 -1
  59. package/channel/useChannelSessions.js.map +1 -1
  60. package/channel-app/ChannelAppDetailPanel.d.ts.map +1 -1
  61. package/channel-app/ChannelAppDetailPanel.js +8 -5
  62. package/channel-app/ChannelAppDetailPanel.js.map +1 -1
  63. package/channel-app/CreateChannelAppForm.d.ts.map +1 -1
  64. package/channel-app/CreateChannelAppForm.js +12 -7
  65. package/channel-app/CreateChannelAppForm.js.map +1 -1
  66. package/channel-app/internal.d.ts +0 -1
  67. package/channel-app/internal.d.ts.map +1 -1
  68. package/channel-app/internal.js +5 -10
  69. package/channel-app/internal.js.map +1 -1
  70. package/composer/ComposerToolbar.js +2 -1
  71. package/composer/ComposerToolbar.js.map +1 -1
  72. package/composer/SessionComposer.d.ts +1 -1
  73. package/composer/SessionComposer.d.ts.map +1 -1
  74. package/composer/SessionComposer.js +120 -13
  75. package/composer/SessionComposer.js.map +1 -1
  76. package/composer/icons.d.ts +0 -1
  77. package/composer/icons.d.ts.map +1 -1
  78. package/composer/icons.js +0 -3
  79. package/composer/icons.js.map +1 -1
  80. package/conversation/ConversationComposer.js +1 -1
  81. package/conversation/ConversationComposer.js.map +1 -1
  82. package/conversation/ConversationListPane.d.ts.map +1 -1
  83. package/conversation/ConversationListPane.js +3 -2
  84. package/conversation/ConversationListPane.js.map +1 -1
  85. package/cursor-accounts/MemberCoverageTable.js +3 -14
  86. package/cursor-accounts/MemberCoverageTable.js.map +1 -1
  87. package/dashboard/DashboardFailedRuns.d.ts.map +1 -1
  88. package/dashboard/DashboardFailedRuns.js +2 -14
  89. package/dashboard/DashboardFailedRuns.js.map +1 -1
  90. package/environment/CreateEnvironmentForm.d.ts.map +1 -1
  91. package/environment/CreateEnvironmentForm.js +4 -8
  92. package/environment/CreateEnvironmentForm.js.map +1 -1
  93. package/environment/EnvVarForm.d.ts.map +1 -1
  94. package/environment/EnvVarForm.js +2 -4
  95. package/environment/EnvVarForm.js.map +1 -1
  96. package/environment/EnvironmentVariableEditor.d.ts.map +1 -1
  97. package/environment/EnvironmentVariableEditor.js +5 -7
  98. package/environment/EnvironmentVariableEditor.js.map +1 -1
  99. package/execution/ArtifactApplyButton.d.ts.map +1 -1
  100. package/execution/ArtifactApplyButton.js +2 -4
  101. package/execution/ArtifactApplyButton.js.map +1 -1
  102. package/execution/ExecutionErrorNotice.d.ts +36 -0
  103. package/execution/ExecutionErrorNotice.d.ts.map +1 -0
  104. package/execution/ExecutionErrorNotice.js +39 -0
  105. package/execution/ExecutionErrorNotice.js.map +1 -0
  106. package/execution/FilePathLink.d.ts.map +1 -1
  107. package/execution/FilePathLink.js +5 -8
  108. package/execution/FilePathLink.js.map +1 -1
  109. package/execution/FileReviewCard.d.ts.map +1 -1
  110. package/execution/FileReviewCard.js +1 -6
  111. package/execution/FileReviewCard.js.map +1 -1
  112. package/execution/FollowUpInput.d.ts.map +1 -1
  113. package/execution/FollowUpInput.js +1 -3
  114. package/execution/FollowUpInput.js.map +1 -1
  115. package/execution/LivenessStatusLine.d.ts +40 -0
  116. package/execution/LivenessStatusLine.d.ts.map +1 -0
  117. package/execution/LivenessStatusLine.js +34 -0
  118. package/execution/LivenessStatusLine.js.map +1 -0
  119. package/execution/MessageEntry.d.ts.map +1 -1
  120. package/execution/MessageEntry.js +31 -3
  121. package/execution/MessageEntry.js.map +1 -1
  122. package/execution/MessageThread.d.ts +25 -0
  123. package/execution/MessageThread.d.ts.map +1 -1
  124. package/execution/MessageThread.js +51 -36
  125. package/execution/MessageThread.js.map +1 -1
  126. package/execution/SetupProgress.d.ts.map +1 -1
  127. package/execution/SetupProgress.js +1 -1
  128. package/execution/SetupProgress.js.map +1 -1
  129. package/execution/SubAgentSection.d.ts.map +1 -1
  130. package/execution/SubAgentSection.js +9 -7
  131. package/execution/SubAgentSection.js.map +1 -1
  132. package/execution/TerminalSession.d.ts +30 -0
  133. package/execution/TerminalSession.d.ts.map +1 -1
  134. package/execution/TerminalSession.js +37 -1
  135. package/execution/TerminalSession.js.map +1 -1
  136. package/execution/ToolCallDetail.d.ts +9 -0
  137. package/execution/ToolCallDetail.d.ts.map +1 -1
  138. package/execution/ToolCallDetail.js +16 -0
  139. package/execution/ToolCallDetail.js.map +1 -1
  140. package/execution/ToolCallItem.d.ts +20 -6
  141. package/execution/ToolCallItem.d.ts.map +1 -1
  142. package/execution/ToolCallItem.js +102 -29
  143. package/execution/ToolCallItem.js.map +1 -1
  144. package/execution/ToolRunGroup.d.ts.map +1 -1
  145. package/execution/ToolRunGroup.js +11 -11
  146. package/execution/ToolRunGroup.js.map +1 -1
  147. package/execution/WriteBackCard.d.ts.map +1 -1
  148. package/execution/WriteBackCard.js +5 -20
  149. package/execution/WriteBackCard.js.map +1 -1
  150. package/execution/index.d.ts +6 -2
  151. package/execution/index.d.ts.map +1 -1
  152. package/execution/index.js +3 -1
  153. package/execution/index.js.map +1 -1
  154. package/execution/tool-categories.d.ts +42 -7
  155. package/execution/tool-categories.d.ts.map +1 -1
  156. package/execution/tool-categories.js +38 -4
  157. package/execution/tool-categories.js.map +1 -1
  158. package/execution/tool-presenter.d.ts +17 -1
  159. package/execution/tool-presenter.d.ts.map +1 -1
  160. package/execution/tool-presenter.js +4 -1
  161. package/execution/tool-presenter.js.map +1 -1
  162. package/execution/useArtifactInspection.d.ts.map +1 -1
  163. package/execution/useArtifactInspection.js +4 -7
  164. package/execution/useArtifactInspection.js.map +1 -1
  165. package/iam-policy/GrantAccessForm.d.ts.map +1 -1
  166. package/iam-policy/GrantAccessForm.js +2 -4
  167. package/iam-policy/GrantAccessForm.js.map +1 -1
  168. package/iam-policy/OrgMembersPanel.d.ts.map +1 -1
  169. package/iam-policy/OrgMembersPanel.js +3 -5
  170. package/iam-policy/OrgMembersPanel.js.map +1 -1
  171. package/iam-policy/RoleSelector.d.ts.map +1 -1
  172. package/iam-policy/RoleSelector.js +7 -1
  173. package/iam-policy/RoleSelector.js.map +1 -1
  174. package/identity-provider/CreateIdentityProviderForm.d.ts.map +1 -1
  175. package/identity-provider/CreateIdentityProviderForm.js +6 -9
  176. package/identity-provider/CreateIdentityProviderForm.js.map +1 -1
  177. package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
  178. package/identity-provider/IdentityProviderDetailPanel.js +17 -26
  179. package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
  180. package/identity-provider/IdentityProviderListPanel.d.ts.map +1 -1
  181. package/identity-provider/IdentityProviderListPanel.js +2 -4
  182. package/identity-provider/IdentityProviderListPanel.js.map +1 -1
  183. package/identity-provider/IdentityProviderWizard.d.ts.map +1 -1
  184. package/identity-provider/IdentityProviderWizard.js +8 -7
  185. package/identity-provider/IdentityProviderWizard.js.map +1 -1
  186. package/identity-provider/SsoLoginPrompt.js +5 -6
  187. package/identity-provider/SsoLoginPrompt.js.map +1 -1
  188. package/index.d.ts +9 -8
  189. package/index.d.ts.map +1 -1
  190. package/index.js +4 -4
  191. package/index.js.map +1 -1
  192. package/internal/DecisionButton.d.ts.map +1 -1
  193. package/internal/DecisionButton.js +1 -6
  194. package/internal/DecisionButton.js.map +1 -1
  195. package/internal/SpinnerIcon.d.ts +22 -0
  196. package/internal/SpinnerIcon.d.ts.map +1 -0
  197. package/internal/SpinnerIcon.js +23 -0
  198. package/internal/SpinnerIcon.js.map +1 -0
  199. package/internal/select-element-text.d.ts +11 -0
  200. package/internal/select-element-text.d.ts.map +1 -0
  201. package/internal/select-element-text.js +19 -0
  202. package/internal/select-element-text.js.map +1 -0
  203. package/internal/thread-card/ThreadCardShell.d.ts +27 -10
  204. package/internal/thread-card/ThreadCardShell.d.ts.map +1 -1
  205. package/internal/thread-card/ThreadCardShell.js +11 -5
  206. package/internal/thread-card/ThreadCardShell.js.map +1 -1
  207. package/internal/thread-card/glyphs.d.ts +11 -2
  208. package/internal/thread-card/glyphs.d.ts.map +1 -1
  209. package/internal/thread-card/glyphs.js +9 -3
  210. package/internal/thread-card/glyphs.js.map +1 -1
  211. package/internal/thread-card/index.d.ts +1 -1
  212. package/internal/thread-card/index.d.ts.map +1 -1
  213. package/internal/thread-card/index.js.map +1 -1
  214. package/internal/useCopyFeedback.d.ts +28 -0
  215. package/internal/useCopyFeedback.d.ts.map +1 -0
  216. package/internal/useCopyFeedback.js +40 -0
  217. package/internal/useCopyFeedback.js.map +1 -0
  218. package/invitation/InvitationCreatedAlert.d.ts.map +1 -1
  219. package/invitation/InvitationCreatedAlert.js +12 -19
  220. package/invitation/InvitationCreatedAlert.js.map +1 -1
  221. package/invitation/InvitationManager.d.ts.map +1 -1
  222. package/invitation/InvitationManager.js +14 -21
  223. package/invitation/InvitationManager.js.map +1 -1
  224. package/invitation/InvitationRedemption.d.ts.map +1 -1
  225. package/invitation/InvitationRedemption.js +2 -4
  226. package/invitation/InvitationRedemption.js.map +1 -1
  227. package/library/useExportResource.d.ts.map +1 -1
  228. package/library/useExportResource.js +16 -27
  229. package/library/useExportResource.js.map +1 -1
  230. package/manifest/ApplyManifestDialog.js +1 -1
  231. package/manifest/EditResourceYamlDialog.js +1 -1
  232. package/mcp-server/DefinitionDriftNotice.d.ts +42 -0
  233. package/mcp-server/DefinitionDriftNotice.d.ts.map +1 -0
  234. package/mcp-server/DefinitionDriftNotice.js +52 -0
  235. package/mcp-server/DefinitionDriftNotice.js.map +1 -0
  236. package/mcp-server/McpServerConnectDialog.js +1 -1
  237. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  238. package/mcp-server/McpServerDetailView.js +47 -14
  239. package/mcp-server/McpServerDetailView.js.map +1 -1
  240. package/mcp-server/OAuthAppForm.d.ts.map +1 -1
  241. package/mcp-server/OAuthAppForm.js +2 -4
  242. package/mcp-server/OAuthAppForm.js.map +1 -1
  243. package/mcp-server/internal/definitionDrift.d.ts +39 -0
  244. package/mcp-server/internal/definitionDrift.d.ts.map +1 -0
  245. package/mcp-server/internal/definitionDrift.js +122 -0
  246. package/mcp-server/internal/definitionDrift.js.map +1 -0
  247. package/mcp-server/internal/mcpServerToInput.d.ts.map +1 -1
  248. package/mcp-server/internal/mcpServerToInput.js +3 -0
  249. package/mcp-server/internal/mcpServerToInput.js.map +1 -1
  250. package/mcp-server/steps/EnvironmentAuthStep.d.ts.map +1 -1
  251. package/mcp-server/steps/EnvironmentAuthStep.js +8 -4
  252. package/mcp-server/steps/EnvironmentAuthStep.js.map +1 -1
  253. package/mcp-server/steps/IdentityTransportStep.d.ts.map +1 -1
  254. package/mcp-server/steps/IdentityTransportStep.js +5 -4
  255. package/mcp-server/steps/IdentityTransportStep.js.map +1 -1
  256. package/mcp-server/useMcpServerConnect.d.ts +1 -1
  257. package/mcp-server/useMcpServerDefinitionDrift.d.ts +44 -0
  258. package/mcp-server/useMcpServerDefinitionDrift.d.ts.map +1 -0
  259. package/mcp-server/useMcpServerDefinitionDrift.js +61 -0
  260. package/mcp-server/useMcpServerDefinitionDrift.js.map +1 -0
  261. package/models/ModelRegistryContext.d.ts +7 -1
  262. package/models/ModelRegistryContext.d.ts.map +1 -1
  263. package/models/ModelRegistryContext.js.map +1 -1
  264. package/models/ModelSelector.js +9 -1
  265. package/models/ModelSelector.js.map +1 -1
  266. package/models/index.d.ts +2 -2
  267. package/models/index.d.ts.map +1 -1
  268. package/models/index.js +1 -1
  269. package/models/index.js.map +1 -1
  270. package/models/registry.d.ts +88 -6
  271. package/models/registry.d.ts.map +1 -1
  272. package/models/registry.js +133 -27
  273. package/models/registry.js.map +1 -1
  274. package/models/useModelRegistry.d.ts +7 -1
  275. package/models/useModelRegistry.d.ts.map +1 -1
  276. package/models/useModelRegistry.js +3 -2
  277. package/models/useModelRegistry.js.map +1 -1
  278. package/oauth-app/CreateOAuthAppForm.d.ts.map +1 -1
  279. package/oauth-app/CreateOAuthAppForm.js +4 -5
  280. package/oauth-app/CreateOAuthAppForm.js.map +1 -1
  281. package/oauth-app/OAuthAppDetailPanel.d.ts.map +1 -1
  282. package/oauth-app/OAuthAppDetailPanel.js +5 -6
  283. package/oauth-app/OAuthAppDetailPanel.js.map +1 -1
  284. package/organization/CreateOrganizationForm.d.ts.map +1 -1
  285. package/organization/CreateOrganizationForm.js +5 -9
  286. package/organization/CreateOrganizationForm.js.map +1 -1
  287. package/organization/OrgProfilePanel.d.ts.map +1 -1
  288. package/organization/OrgProfilePanel.js +7 -16
  289. package/organization/OrgProfilePanel.js.map +1 -1
  290. package/package.json +4 -4
  291. package/platform-client/CreatePlatformClientForm.d.ts.map +1 -1
  292. package/platform-client/CreatePlatformClientForm.js +5 -6
  293. package/platform-client/CreatePlatformClientForm.js.map +1 -1
  294. package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -1
  295. package/platform-client/PlatformClientDetailPanel.js +6 -7
  296. package/platform-client/PlatformClientDetailPanel.js.map +1 -1
  297. package/platform-client/PlatformClientListPanel.d.ts.map +1 -1
  298. package/platform-client/PlatformClientListPanel.js +2 -4
  299. package/platform-client/PlatformClientListPanel.js.map +1 -1
  300. package/platform-client/PlatformClientSecretAlert.d.ts.map +1 -1
  301. package/platform-client/PlatformClientSecretAlert.js +18 -25
  302. package/platform-client/PlatformClientSecretAlert.js.map +1 -1
  303. package/provider.d.ts +34 -1
  304. package/provider.d.ts.map +1 -1
  305. package/provider.js +14 -7
  306. package/provider.js.map +1 -1
  307. package/resource-creation/WizardNav.d.ts.map +1 -1
  308. package/resource-creation/WizardNav.js +2 -4
  309. package/resource-creation/WizardNav.js.map +1 -1
  310. package/resource-detail/ConfirmDialog.js +1 -1
  311. package/resource-detail/useCopyResource.d.ts +4 -3
  312. package/resource-detail/useCopyResource.d.ts.map +1 -1
  313. package/resource-detail/useCopyResource.js +10 -19
  314. package/resource-detail/useCopyResource.js.map +1 -1
  315. package/schedule/ScheduleDetailView.d.ts.map +1 -1
  316. package/schedule/ScheduleDetailView.js +2 -4
  317. package/schedule/ScheduleDetailView.js.map +1 -1
  318. package/schedule/ScheduleForm.d.ts.map +1 -1
  319. package/schedule/ScheduleForm.js +6 -7
  320. package/schedule/ScheduleForm.js.map +1 -1
  321. package/session/NewSessionViewer.d.ts +52 -2
  322. package/session/NewSessionViewer.d.ts.map +1 -1
  323. package/session/NewSessionViewer.js +21 -6
  324. package/session/NewSessionViewer.js.map +1 -1
  325. package/session/SessionViewer.d.ts +63 -2
  326. package/session/SessionViewer.d.ts.map +1 -1
  327. package/session/SessionViewer.js +43 -17
  328. package/session/SessionViewer.js.map +1 -1
  329. package/session/audience.d.ts +17 -0
  330. package/session/audience.d.ts.map +1 -1
  331. package/session/index.d.ts +2 -1
  332. package/session/index.d.ts.map +1 -1
  333. package/session/index.js.map +1 -1
  334. package/session/run-config.d.ts +50 -0
  335. package/session/run-config.d.ts.map +1 -0
  336. package/session/run-config.js +15 -0
  337. package/session/run-config.js.map +1 -0
  338. package/session/useNewSessionFlow.d.ts +11 -0
  339. package/session/useNewSessionFlow.d.ts.map +1 -1
  340. package/session/useNewSessionFlow.js +29 -2
  341. package/session/useNewSessionFlow.js.map +1 -1
  342. package/session/useSessionConversation.d.ts +7 -7
  343. package/session/useSessionConversation.d.ts.map +1 -1
  344. package/session/useSessionConversation.js +2 -0
  345. package/session/useSessionConversation.js.map +1 -1
  346. package/session/useSessionPageFlow.d.ts +18 -4
  347. package/session/useSessionPageFlow.d.ts.map +1 -1
  348. package/session/useSessionPageFlow.js +33 -6
  349. package/session/useSessionPageFlow.js.map +1 -1
  350. package/session/useSessionPanel.d.ts +37 -2
  351. package/session/useSessionPanel.d.ts.map +1 -1
  352. package/session/useSessionPanel.js +44 -10
  353. package/session/useSessionPanel.js.map +1 -1
  354. package/settings/ApiKeysSection.d.ts.map +1 -1
  355. package/settings/ApiKeysSection.js +3 -2
  356. package/settings/ApiKeysSection.js.map +1 -1
  357. package/settings/ChannelAppsSection.d.ts.map +1 -1
  358. package/settings/ChannelAppsSection.js +3 -2
  359. package/settings/ChannelAppsSection.js.map +1 -1
  360. package/settings/EnvironmentsSection.js +5 -3
  361. package/settings/EnvironmentsSection.js.map +1 -1
  362. package/settings/IdentityProvidersSection.d.ts.map +1 -1
  363. package/settings/IdentityProvidersSection.js +3 -2
  364. package/settings/IdentityProvidersSection.js.map +1 -1
  365. package/settings/InvitationsSection.d.ts.map +1 -1
  366. package/settings/InvitationsSection.js +3 -1
  367. package/settings/InvitationsSection.js.map +1 -1
  368. package/settings/MembersSection.d.ts.map +1 -1
  369. package/settings/MembersSection.js +3 -1
  370. package/settings/MembersSection.js.map +1 -1
  371. package/settings/OAuthAppsSection.d.ts.map +1 -1
  372. package/settings/OAuthAppsSection.js +3 -2
  373. package/settings/OAuthAppsSection.js.map +1 -1
  374. package/settings/OrgProfileSection.d.ts.map +1 -1
  375. package/settings/OrgProfileSection.js +3 -2
  376. package/settings/OrgProfileSection.js.map +1 -1
  377. package/settings/PlatformClientsSection.d.ts.map +1 -1
  378. package/settings/PlatformClientsSection.js +3 -2
  379. package/settings/PlatformClientsSection.js.map +1 -1
  380. package/settings/UsageSection.d.ts.map +1 -1
  381. package/settings/UsageSection.js +3 -1
  382. package/settings/UsageSection.js.map +1 -1
  383. package/sharing/ShareAgentDialog.d.ts.map +1 -1
  384. package/sharing/ShareAgentDialog.js +18 -7
  385. package/sharing/ShareAgentDialog.js.map +1 -1
  386. package/sidebar/chrome.d.ts +3 -4
  387. package/sidebar/chrome.d.ts.map +1 -1
  388. package/sidebar/chrome.js +5 -4
  389. package/sidebar/chrome.js.map +1 -1
  390. package/skill/SkillDiffDialog.js +1 -1
  391. package/src/access/ManageAccessDialog.tsx +10 -4
  392. package/src/activity/format-relative-time.ts +11 -9
  393. package/src/agent/steps/CapabilitiesStep.tsx +6 -3
  394. package/src/agent/steps/IdentityStep.tsx +19 -12
  395. package/src/agent-instance/CreateAgentInstanceDialog.tsx +17 -8
  396. package/src/api-key/ApiKeyCreatedAlert.tsx +10 -19
  397. package/src/api-key/ApiKeyListPanel.tsx +3 -39
  398. package/src/api-key/CreateApiKeyForm.tsx +12 -26
  399. package/src/approval-defaults-context.ts +56 -0
  400. package/src/attachment/__tests__/vision-preflight.test.ts +311 -0
  401. package/src/attachment/index.ts +12 -0
  402. package/src/attachment/vision-preflight.ts +236 -0
  403. package/src/billing/AutoRechargeCard.tsx +5 -4
  404. package/src/billing/BillingSection.tsx +4 -3
  405. package/src/channel/ChannelConversationsDialog.tsx +8 -4
  406. package/src/channel/ChannelCredentialsDialog.tsx +14 -4
  407. package/src/channel/ChannelTemplatesDialog.tsx +8 -4
  408. package/src/channel/ConnectSlackDialog.tsx +14 -4
  409. package/src/channel/ConnectWhatsAppDialog.tsx +14 -4
  410. package/src/channel/useChannelSessions.ts +3 -0
  411. package/src/channel-app/ChannelAppDetailPanel.tsx +15 -12
  412. package/src/channel-app/CreateChannelAppForm.tsx +17 -12
  413. package/src/channel-app/internal.tsx +5 -25
  414. package/src/composer/ComposerToolbar.tsx +1 -1
  415. package/src/composer/SessionComposer.tsx +160 -13
  416. package/src/composer/__tests__/SessionComposer-modelCoherence.test.tsx +220 -0
  417. package/src/composer/__tests__/SessionComposer-visionPreflight.test.tsx +222 -0
  418. package/src/composer/icons.tsx +0 -18
  419. package/src/conversation/ConversationComposer.tsx +1 -1
  420. package/src/conversation/ConversationListPane.tsx +4 -3
  421. package/src/cursor-accounts/MemberCoverageTable.tsx +3 -14
  422. package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +2 -10
  423. package/src/dashboard/DashboardFailedRuns.tsx +2 -12
  424. package/src/environment/CreateEnvironmentForm.tsx +8 -27
  425. package/src/environment/EnvVarForm.tsx +2 -18
  426. package/src/environment/EnvironmentVariableEditor.tsx +5 -21
  427. package/src/execution/ArtifactApplyButton.tsx +2 -17
  428. package/src/execution/ExecutionErrorNotice.tsx +99 -0
  429. package/src/execution/FilePathLink.tsx +5 -9
  430. package/src/execution/FileReviewCard.tsx +1 -20
  431. package/src/execution/FollowUpInput.tsx +1 -16
  432. package/src/execution/LivenessStatusLine.tsx +59 -0
  433. package/src/execution/MessageEntry.tsx +136 -25
  434. package/src/execution/MessageThread.tsx +84 -83
  435. package/src/execution/SetupProgress.tsx +5 -1
  436. package/src/execution/SubAgentSection.tsx +9 -20
  437. package/src/execution/TerminalSession.tsx +97 -10
  438. package/src/execution/ToolCallDetail.tsx +19 -0
  439. package/src/execution/ToolCallItem.tsx +157 -37
  440. package/src/execution/ToolRunGroup.tsx +30 -32
  441. package/src/execution/WriteBackCard.tsx +5 -24
  442. package/src/execution/__tests__/MessageEntry-copy.test.tsx +125 -0
  443. package/src/execution/__tests__/MessageThread.test.tsx +97 -0
  444. package/src/execution/__tests__/TerminalSession.test.tsx +71 -1
  445. package/src/execution/__tests__/ToolCallDetail.test.tsx +33 -1
  446. package/src/execution/__tests__/ToolCallItem.test.tsx +299 -11
  447. package/src/execution/__tests__/ToolRunGroup.test.tsx +41 -9
  448. package/src/execution/__tests__/message-thread-slots.test.tsx +92 -0
  449. package/src/execution/__tests__/tool-presenter.test.tsx +41 -4
  450. package/src/execution/index.ts +8 -2
  451. package/src/execution/tool-categories.ts +72 -8
  452. package/src/execution/tool-presenter.ts +22 -1
  453. package/src/execution/useArtifactInspection.ts +4 -8
  454. package/src/iam-policy/GrantAccessForm.tsx +2 -18
  455. package/src/iam-policy/OrgMembersPanel.tsx +3 -19
  456. package/src/iam-policy/RoleSelector.tsx +8 -1
  457. package/src/identity-provider/CreateIdentityProviderForm.tsx +13 -31
  458. package/src/identity-provider/IdentityProviderDetailPanel.tsx +24 -49
  459. package/src/identity-provider/IdentityProviderListPanel.tsx +2 -18
  460. package/src/identity-provider/IdentityProviderWizard.tsx +15 -32
  461. package/src/identity-provider/SsoLoginPrompt.tsx +6 -21
  462. package/src/index.ts +23 -1
  463. package/src/internal/DecisionButton.tsx +1 -20
  464. package/src/internal/SpinnerIcon.tsx +42 -0
  465. package/src/internal/__tests__/ThreadCardShell.test.tsx +43 -7
  466. package/src/internal/__tests__/useCopyFeedback.test.ts +92 -0
  467. package/src/internal/select-element-text.ts +17 -0
  468. package/src/internal/thread-card/ThreadCardShell.tsx +53 -21
  469. package/src/internal/thread-card/glyphs.tsx +24 -3
  470. package/src/internal/thread-card/index.ts +1 -0
  471. package/src/internal/useCopyFeedback.ts +61 -0
  472. package/src/invitation/InvitationCreatedAlert.tsx +10 -18
  473. package/src/invitation/InvitationManager.tsx +23 -34
  474. package/src/invitation/InvitationRedemption.tsx +2 -18
  475. package/src/library/useExportResource.ts +15 -29
  476. package/src/manifest/ApplyManifestDialog.tsx +1 -1
  477. package/src/manifest/EditResourceYamlDialog.tsx +1 -1
  478. package/src/mcp-server/DefinitionDriftNotice.tsx +120 -0
  479. package/src/mcp-server/McpServerConnectDialog.tsx +1 -1
  480. package/src/mcp-server/McpServerDetailView.tsx +58 -26
  481. package/src/mcp-server/OAuthAppForm.tsx +2 -18
  482. package/src/mcp-server/__tests__/DefinitionDriftNotice.test.tsx +57 -0
  483. package/src/mcp-server/__tests__/definitionDrift.test.ts +245 -0
  484. package/src/mcp-server/__tests__/mcpServerToInput.test.ts +201 -0
  485. package/src/mcp-server/__tests__/useMcpServerDefinitionDrift.test.tsx +173 -0
  486. package/src/mcp-server/internal/definitionDrift.ts +158 -0
  487. package/src/mcp-server/internal/mcpServerToInput.ts +3 -0
  488. package/src/mcp-server/steps/EnvironmentAuthStep.tsx +19 -19
  489. package/src/mcp-server/steps/IdentityTransportStep.tsx +24 -23
  490. package/src/mcp-server/useMcpServerConnect.ts +1 -1
  491. package/src/mcp-server/useMcpServerDefinitionDrift.ts +95 -0
  492. package/src/models/ModelRegistryContext.ts +7 -1
  493. package/src/models/ModelSelector.tsx +37 -0
  494. package/src/models/__tests__/ModelSelector-visionIndicator.test.tsx +129 -0
  495. package/src/models/__tests__/resolveDefaultModel.test.ts +115 -0
  496. package/src/models/__tests__/useModelRegistry.test.tsx +99 -4
  497. package/src/models/index.ts +2 -2
  498. package/src/models/registry.ts +196 -29
  499. package/src/models/useModelRegistry.ts +10 -2
  500. package/src/oauth-app/CreateOAuthAppForm.tsx +16 -31
  501. package/src/oauth-app/OAuthAppDetailPanel.tsx +16 -31
  502. package/src/organization/CreateOrganizationForm.tsx +10 -29
  503. package/src/organization/OrgProfilePanel.tsx +13 -44
  504. package/src/platform-client/CreatePlatformClientForm.tsx +9 -29
  505. package/src/platform-client/PlatformClientDetailPanel.tsx +10 -30
  506. package/src/platform-client/PlatformClientListPanel.tsx +2 -18
  507. package/src/platform-client/PlatformClientSecretAlert.tsx +26 -55
  508. package/src/provider.tsx +76 -33
  509. package/src/resource-creation/WizardNav.tsx +2 -18
  510. package/src/resource-detail/ConfirmDialog.tsx +1 -1
  511. package/src/resource-detail/useCopyResource.ts +17 -23
  512. package/src/schedule/ScheduleDetailView.tsx +2 -18
  513. package/src/schedule/ScheduleForm.tsx +19 -34
  514. package/src/session/NewSessionViewer.tsx +85 -7
  515. package/src/session/SessionViewer.tsx +120 -17
  516. package/src/session/__tests__/audienceWiring.test.tsx +76 -0
  517. package/src/session/__tests__/panelNegotiation.test.tsx +302 -0
  518. package/src/session/__tests__/useNewSessionFlow.test.tsx +134 -5
  519. package/src/session/__tests__/useSessionPageFlow.autoApprove.test.tsx +74 -0
  520. package/src/session/__tests__/useSessionPageFlow.runConfig.test.tsx +157 -0
  521. package/src/session/__tests__/useSessionPanel.test.ts +114 -0
  522. package/src/session/audience.ts +18 -0
  523. package/src/session/index.ts +2 -1
  524. package/src/session/run-config.ts +59 -0
  525. package/src/session/useNewSessionFlow.ts +39 -2
  526. package/src/session/useSessionConversation.ts +10 -8
  527. package/src/session/useSessionPageFlow.ts +51 -10
  528. package/src/session/useSessionPanel.ts +91 -10
  529. package/src/settings/ApiKeysSection.tsx +4 -3
  530. package/src/settings/ChannelAppsSection.tsx +4 -3
  531. package/src/settings/EnvironmentsSection.tsx +8 -5
  532. package/src/settings/IdentityProvidersSection.tsx +4 -3
  533. package/src/settings/InvitationsSection.tsx +4 -2
  534. package/src/settings/MembersSection.tsx +4 -2
  535. package/src/settings/OAuthAppsSection.tsx +4 -3
  536. package/src/settings/OrgProfileSection.tsx +4 -3
  537. package/src/settings/PlatformClientsSection.tsx +4 -3
  538. package/src/settings/UsageSection.tsx +4 -2
  539. package/src/sharing/ShareAgentDialog.tsx +28 -10
  540. package/src/sidebar/__tests__/WorkspaceSidebar.test.tsx +4 -1
  541. package/src/sidebar/chrome.tsx +6 -6
  542. package/src/skill/SkillDiffDialog.tsx +1 -1
  543. package/src/styles.css +43 -0
  544. package/src/version-history/VersionTimelineEntry.tsx +1 -21
  545. package/src/workflow/FailedRunsWidget.tsx +2 -9
  546. package/src/workflow/PendingApprovalsWidget.tsx +2 -9
  547. package/src/workflow/ViewYamlDialog.tsx +7 -22
  548. package/src/workflow/WorkflowArchitectDialog.tsx +8 -27
  549. package/src/workflow/WorkflowArtifactDocument.tsx +5 -9
  550. package/src/workflow/WorkflowCanvasEditor.tsx +2 -0
  551. package/src/workflow/WorkflowCanvasInner.tsx +14 -1
  552. package/src/workflow/WorkflowDiffGraph.tsx +7 -1
  553. package/src/workflow/WorkflowExecutionViewer.tsx +88 -11
  554. package/src/workflow/WorkflowExplainDialog.tsx +8 -24
  555. package/src/workflow/WorkflowOverviewGraph.tsx +9 -1
  556. package/src/workflow/WorkflowRefinePanel.tsx +2 -18
  557. package/src/workflow/WorkflowRepairCard.tsx +2 -18
  558. package/src/workflow/WorkflowRunDialog.tsx +3 -23
  559. package/src/workflow/WorkflowTaskApprovalSummary.tsx +2 -17
  560. package/src/workflow/WorkflowVersionBadge.tsx +4 -13
  561. package/src/workflow/WorkflowVersionTimeline.tsx +1 -25
  562. package/src/workflow/__tests__/panelNegotiation.test.tsx +230 -0
  563. package/src/workflow/__tests__/useWorkflowCanvas.dirty.test.tsx +178 -0
  564. package/src/workflow/__tests__/useWorkflowCanvas.drag.test.tsx +224 -0
  565. package/src/workflow/__tests__/useWorkflowExecutionPanel.test.ts +100 -0
  566. package/src/workflow/execution-comparison/ExecutionComparisonPicker.tsx +7 -11
  567. package/src/workflow/execution-history/ExecutionHistoryTable.tsx +1 -25
  568. package/src/workflow/index.ts +1 -0
  569. package/src/workflow/instance/CreateWorkflowInstanceDialog.tsx +1 -1
  570. package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +2 -1
  571. package/src/workflow/picker/BranchAddPopover.tsx +4 -3
  572. package/src/workflow/templates/WorkflowTemplatePreview.tsx +1 -1
  573. package/src/workflow/useApprovalBoundary.ts +1 -1
  574. package/src/workflow/useWorkflowCanvas.ts +114 -11
  575. package/src/workflow/useWorkflowExecutionPanel.ts +95 -13
  576. package/styles.css +1 -1
  577. package/version-history/VersionTimelineEntry.d.ts.map +1 -1
  578. package/version-history/VersionTimelineEntry.js +1 -23
  579. package/version-history/VersionTimelineEntry.js.map +1 -1
  580. package/workflow/CanvasTransitionEdge.d.ts +1 -1
  581. package/workflow/FailedRunsWidget.d.ts.map +1 -1
  582. package/workflow/FailedRunsWidget.js +2 -11
  583. package/workflow/FailedRunsWidget.js.map +1 -1
  584. package/workflow/PendingApprovalsWidget.d.ts.map +1 -1
  585. package/workflow/PendingApprovalsWidget.js +2 -11
  586. package/workflow/PendingApprovalsWidget.js.map +1 -1
  587. package/workflow/ViewYamlDialog.d.ts.map +1 -1
  588. package/workflow/ViewYamlDialog.js +7 -23
  589. package/workflow/ViewYamlDialog.js.map +1 -1
  590. package/workflow/WorkflowArchitectDialog.d.ts.map +1 -1
  591. package/workflow/WorkflowArchitectDialog.js +7 -11
  592. package/workflow/WorkflowArchitectDialog.js.map +1 -1
  593. package/workflow/WorkflowArtifactDocument.d.ts.map +1 -1
  594. package/workflow/WorkflowArtifactDocument.js +5 -8
  595. package/workflow/WorkflowArtifactDocument.js.map +1 -1
  596. package/workflow/WorkflowCanvasEditor.d.ts.map +1 -1
  597. package/workflow/WorkflowCanvasEditor.js +1 -1
  598. package/workflow/WorkflowCanvasEditor.js.map +1 -1
  599. package/workflow/WorkflowCanvasInner.d.ts +4 -2
  600. package/workflow/WorkflowCanvasInner.d.ts.map +1 -1
  601. package/workflow/WorkflowCanvasInner.js +7 -3
  602. package/workflow/WorkflowCanvasInner.js.map +1 -1
  603. package/workflow/WorkflowDiffGraph.js +6 -2
  604. package/workflow/WorkflowDiffGraph.js.map +1 -1
  605. package/workflow/WorkflowExecutionViewer.d.ts +51 -0
  606. package/workflow/WorkflowExecutionViewer.d.ts.map +1 -1
  607. package/workflow/WorkflowExecutionViewer.js +23 -6
  608. package/workflow/WorkflowExecutionViewer.js.map +1 -1
  609. package/workflow/WorkflowExplainDialog.d.ts.map +1 -1
  610. package/workflow/WorkflowExplainDialog.js +6 -8
  611. package/workflow/WorkflowExplainDialog.js.map +1 -1
  612. package/workflow/WorkflowOverviewGraph.js +8 -2
  613. package/workflow/WorkflowOverviewGraph.js.map +1 -1
  614. package/workflow/WorkflowRefinePanel.d.ts.map +1 -1
  615. package/workflow/WorkflowRefinePanel.js +2 -4
  616. package/workflow/WorkflowRefinePanel.js.map +1 -1
  617. package/workflow/WorkflowRepairCard.d.ts.map +1 -1
  618. package/workflow/WorkflowRepairCard.js +2 -4
  619. package/workflow/WorkflowRepairCard.js.map +1 -1
  620. package/workflow/WorkflowRunDialog.d.ts.map +1 -1
  621. package/workflow/WorkflowRunDialog.js +2 -7
  622. package/workflow/WorkflowRunDialog.js.map +1 -1
  623. package/workflow/WorkflowTaskApprovalSummary.d.ts.map +1 -1
  624. package/workflow/WorkflowTaskApprovalSummary.js +2 -4
  625. package/workflow/WorkflowTaskApprovalSummary.js.map +1 -1
  626. package/workflow/WorkflowVersionBadge.d.ts.map +1 -1
  627. package/workflow/WorkflowVersionBadge.js +4 -13
  628. package/workflow/WorkflowVersionBadge.js.map +1 -1
  629. package/workflow/WorkflowVersionTimeline.d.ts.map +1 -1
  630. package/workflow/WorkflowVersionTimeline.js +1 -26
  631. package/workflow/WorkflowVersionTimeline.js.map +1 -1
  632. package/workflow/execution-comparison/ExecutionComparisonPicker.d.ts.map +1 -1
  633. package/workflow/execution-comparison/ExecutionComparisonPicker.js +7 -15
  634. package/workflow/execution-comparison/ExecutionComparisonPicker.js.map +1 -1
  635. package/workflow/execution-history/ExecutionHistoryTable.d.ts.map +1 -1
  636. package/workflow/execution-history/ExecutionHistoryTable.js +1 -24
  637. package/workflow/execution-history/ExecutionHistoryTable.js.map +1 -1
  638. package/workflow/index.d.ts +1 -1
  639. package/workflow/index.d.ts.map +1 -1
  640. package/workflow/index.js.map +1 -1
  641. package/workflow/instance/CreateWorkflowInstanceDialog.js +1 -1
  642. package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
  643. package/workflow/instance/WorkflowInstanceDetailPanel.js +1 -1
  644. package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
  645. package/workflow/picker/BranchAddPopover.d.ts.map +1 -1
  646. package/workflow/picker/BranchAddPopover.js +3 -2
  647. package/workflow/picker/BranchAddPopover.js.map +1 -1
  648. package/workflow/templates/WorkflowTemplatePreview.js +1 -1
  649. package/workflow/useApprovalBoundary.d.ts +1 -1
  650. package/workflow/useApprovalBoundary.js +1 -1
  651. package/workflow/useWorkflowCanvas.d.ts +5 -1
  652. package/workflow/useWorkflowCanvas.d.ts.map +1 -1
  653. package/workflow/useWorkflowCanvas.js +99 -13
  654. package/workflow/useWorkflowCanvas.js.map +1 -1
  655. package/workflow/useWorkflowExecutionPanel.d.ts +38 -2
  656. package/workflow/useWorkflowExecutionPanel.d.ts.map +1 -1
  657. package/workflow/useWorkflowExecutionPanel.js +46 -13
  658. package/workflow/useWorkflowExecutionPanel.js.map +1 -1
@@ -20,6 +20,7 @@ import {
20
20
  import { PlanDocumentMessage } from "./PlanDocumentMessage.js";
21
21
  import { useRenderTracer } from "../internal/dev/index.js";
22
22
  import { Tooltip, TooltipContent, TooltipTrigger } from "../internal/tooltip.js";
23
+ import { useCopyFeedback } from "../internal/useCopyFeedback.js";
23
24
 
24
25
  /** Props for {@link MessageEntry}. */
25
26
  export interface MessageEntryProps {
@@ -192,29 +193,29 @@ function HumanMessage({
192
193
  />
193
194
  )}
194
195
  <p className="stg:text-sm stg:text-foreground stg:whitespace-pre-wrap">{content}</p>
195
- {onEdit && (
196
- <Tooltip>
197
- <TooltipTrigger
198
- render={
199
- <button
200
- type="button"
201
- onClick={onEdit}
202
- aria-label="Edit message"
203
- className={cn(
204
- "stg:absolute stg:-top-2.5 stg:-right-2.5 stg:inline-flex stg:h-7 stg:w-7 stg:items-center stg:justify-center stg:rounded-full",
205
- "stg:border stg:border-border stg:bg-card stg:text-muted-foreground stg:shadow-sm stg:transition",
206
- "stg:hover:text-foreground stg:hover:bg-accent-hover",
207
- "stg:opacity-0 stg:group-hover:opacity-100 stg:focus-visible:opacity-100",
208
- "stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring",
209
- )}
210
- />
211
- }
212
- >
213
- <EditIcon />
214
- </TooltipTrigger>
215
- <TooltipContent side="top">Edit</TooltipContent>
216
- </Tooltip>
217
- )}
196
+ {/* The hover-revealed action cluster on the bubble's shoulder: copy is
197
+ always offered (the message text is the content), edit only when the
198
+ host wired the callback. */}
199
+ <div className="stg:absolute stg:-top-2.5 stg:-right-2.5 stg:flex stg:gap-1">
200
+ <CopyMessageButton text={content} variant="bubble" />
201
+ {onEdit && (
202
+ <Tooltip>
203
+ <TooltipTrigger
204
+ render={
205
+ <button
206
+ type="button"
207
+ onClick={onEdit}
208
+ aria-label="Edit message"
209
+ className={BUBBLE_ACTION_CLASSES}
210
+ />
211
+ }
212
+ >
213
+ <EditIcon />
214
+ </TooltipTrigger>
215
+ <TooltipContent side="top">Edit</TooltipContent>
216
+ </Tooltip>
217
+ )}
218
+ </div>
218
219
  </div>
219
220
  );
220
221
  }
@@ -269,7 +270,7 @@ function AiMessage({
269
270
  role="article"
270
271
  aria-label="AI response"
271
272
  aria-busy={isStreaming}
272
- className={cn("stg:px-4 stg:py-3", className)}
273
+ className={cn("stg:group stg:px-4 stg:py-3", className)}
273
274
  >
274
275
  <div className="stgm-prose">
275
276
  <Streamdown
@@ -280,10 +281,118 @@ function AiMessage({
280
281
  {markdown}
281
282
  </Streamdown>
282
283
  </div>
284
+ {/* The quiet per-message actions row (issue #278). Height is reserved
285
+ whenever it renders, so the hover reveal never shifts the prose; it
286
+ appears only once the message settles — a streaming message's text
287
+ is still changing, so a copy would race the content. Copies the
288
+ display markdown (fence-unwrapped), i.e. what the reader sees. */}
289
+ {!isStreaming && markdown.trim().length > 0 && (
290
+ <div className="stg:mt-1 stg:flex stg:h-6 stg:items-center">
291
+ <CopyMessageButton text={markdown} variant="quiet" />
292
+ </div>
293
+ )}
283
294
  </div>
284
295
  );
285
296
  }
286
297
 
298
+ // ---------------------------------------------------------------------------
299
+ // Per-message copy affordance (issue #278)
300
+ // ---------------------------------------------------------------------------
301
+
302
+ // The floating circular action on a human bubble's shoulder — shared by the
303
+ // copy and edit buttons so the cluster reads as one control family.
304
+ const BUBBLE_ACTION_CLASSES = cn(
305
+ "stg:inline-flex stg:h-7 stg:w-7 stg:items-center stg:justify-center stg:rounded-full",
306
+ "stg:border stg:border-border stg:bg-card stg:text-muted-foreground stg:shadow-sm stg:transition",
307
+ "stg:hover:text-foreground stg:hover:bg-accent-hover",
308
+ "stg:opacity-0 stg:group-hover:opacity-100 stg:focus-visible:opacity-100",
309
+ "stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring",
310
+ );
311
+
312
+ // The quiet in-flow variant for AI prose: no border or fill, one contrast
313
+ // step below the reading text (`muted-foreground-subtle`, rising to
314
+ // `muted-foreground` on hover) — findable when wanted, invisible while
315
+ // reading. The same hover/focus reveal keeps both variants keyboard-reachable.
316
+ const QUIET_ACTION_CLASSES = cn(
317
+ "stg:inline-flex stg:h-6 stg:w-6 stg:items-center stg:justify-center stg:rounded-md",
318
+ "stg:text-muted-foreground-subtle stg:transition",
319
+ "stg:hover:text-muted-foreground stg:hover:bg-accent-hover",
320
+ "stg:opacity-0 stg:group-hover:opacity-100 stg:focus-visible:opacity-100",
321
+ "stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring",
322
+ );
323
+
324
+ /**
325
+ * The per-message copy control: writes the message's text to the clipboard
326
+ * and flips to a check for the feedback window. `variant` selects the visual
327
+ * home — `"bubble"` joins the human bubble's floating action cluster,
328
+ * `"quiet"` sits in the AI message's reserved actions row.
329
+ */
330
+ function CopyMessageButton({
331
+ text,
332
+ variant,
333
+ }: {
334
+ text: string;
335
+ variant: "bubble" | "quiet";
336
+ }) {
337
+ const { copy, copied } = useCopyFeedback();
338
+ return (
339
+ <Tooltip>
340
+ <TooltipTrigger
341
+ render={
342
+ <button
343
+ type="button"
344
+ onClick={() => void copy(text)}
345
+ aria-label={copied ? "Copied" : "Copy message"}
346
+ className={
347
+ variant === "bubble" ? BUBBLE_ACTION_CLASSES : QUIET_ACTION_CLASSES
348
+ }
349
+ />
350
+ }
351
+ >
352
+ {copied ? <CheckIcon /> : <CopyMessageIcon />}
353
+ </TooltipTrigger>
354
+ <TooltipContent side="top">{copied ? "Copied" : "Copy"}</TooltipContent>
355
+ </Tooltip>
356
+ );
357
+ }
358
+
359
+ function CopyMessageIcon() {
360
+ return (
361
+ <svg
362
+ width="13"
363
+ height="13"
364
+ viewBox="0 0 24 24"
365
+ fill="none"
366
+ stroke="currentColor"
367
+ strokeWidth="2"
368
+ strokeLinecap="round"
369
+ strokeLinejoin="round"
370
+ aria-hidden="true"
371
+ >
372
+ <rect x="9" y="9" width="13" height="13" rx="2" />
373
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
374
+ </svg>
375
+ );
376
+ }
377
+
378
+ function CheckIcon() {
379
+ return (
380
+ <svg
381
+ width="13"
382
+ height="13"
383
+ viewBox="0 0 24 24"
384
+ fill="none"
385
+ stroke="currentColor"
386
+ strokeWidth="2"
387
+ strokeLinecap="round"
388
+ strokeLinejoin="round"
389
+ aria-hidden="true"
390
+ >
391
+ <path d="M20 6 9 17l-5-5" />
392
+ </svg>
393
+ );
394
+ }
395
+
287
396
  const THINKING_PREVIEW_LENGTH = 80;
288
397
 
289
398
  function ThinkingMessage({
@@ -320,7 +429,9 @@ function ThinkingMessage({
320
429
  )}
321
430
  >
322
431
  <ThinkingIcon isStreaming={isStreaming} />
323
- <span className="stg:min-w-0 stg:truncate">
432
+ {/* Live reasoning carries the ambient-liveness sweep (stigmer#277) —
433
+ the words themselves signal activity, not just the icon. */}
434
+ <span className={cn("stg:min-w-0 stg:truncate", isStreaming && "stgm-shimmer-label")}>
324
435
  {isStreaming && !hasContent
325
436
  ? "Thinking..."
326
437
  : expanded
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { lazy, memo, Suspense, useCallback, useMemo, useState, type ComponentType } from "react";
3
+ import { lazy, memo, Suspense, useCallback, useMemo, type ComponentType } from "react";
4
4
  import { create } from "@bufbuild/protobuf";
5
5
  import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
6
6
  import type { AgentMessage, ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
@@ -16,6 +16,8 @@ import {
16
16
  FileChangeSetStatus,
17
17
  InteractionMode,
18
18
  MessageType,
19
+ SubAgentStatus,
20
+ ToolCallStatus,
19
21
  } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
20
22
  import type { WorkspaceEntry } from "@stigmer/protos/ai/stigmer/agentic/session/v1/workspace_pb";
21
23
  import { displayFileChangeSets } from "@stigmer/sdk";
@@ -27,7 +29,12 @@ import { ToolCallGroup } from "./ToolCallGroup.js";
27
29
  import { SubAgentSection } from "./SubAgentSection.js";
28
30
  import { ExecutionPhaseBadge } from "./ExecutionPhaseBadge.js";
29
31
  import { SetupProgress, type SetupProgressProps } from "./SetupProgress.js";
32
+ import {
33
+ LivenessStatusLine,
34
+ type LivenessStatusLineProps,
35
+ } from "./LivenessStatusLine.js";
30
36
  import { ApprovalCard, type ApprovalCardProps } from "./ApprovalCard.js";
37
+ import { ExecutionErrorNotice, type ExecutionErrorNoticeProps } from "./ExecutionErrorNotice.js";
31
38
  import { FileReviewCard } from "./FileReviewCard.js";
32
39
  import { SummarizationCard } from "./SummarizationCard.js";
33
40
  import { PlanCompletionCard, type PlanCompletionCardProps } from "./PlanCompletionCard.js";
@@ -106,6 +113,20 @@ export interface MessageThreadSlots {
106
113
  readonly PlanStreamingCard?: ComponentType<PlanStreamingCardProps>;
107
114
  /** Pre-first-token setup / "Thinking…" indicator. */
108
115
  readonly SetupProgress?: ComponentType<SetupProgressProps>;
116
+ /**
117
+ * The terminal execution-failure notice. Receives the raw server-reported
118
+ * reason and the retry wiring, so a host can turn the failure into its own
119
+ * recovery moment (classify the reason, offer an alternate engine, link
120
+ * support) instead of the built-in Show more / Retry treatment.
121
+ */
122
+ readonly ExecutionErrorNotice?: ComponentType<ExecutionErrorNoticeProps>;
123
+ /**
124
+ * The ambient-liveness status line at the thread's tail while the active
125
+ * execution is live between visible events (stigmer#277). Override to
126
+ * supply a host-voiced label or richer treatment; the emission policy
127
+ * (when the line appears at all) stays with the thread.
128
+ */
129
+ readonly LivenessStatusLine?: ComponentType<LivenessStatusLineProps>;
109
130
  }
110
131
 
111
132
  /** Props for {@link MessageThread}. */
@@ -400,6 +421,16 @@ export type ThreadItem =
400
421
  readonly planTitle?: string;
401
422
  /** Length of the plan text streamed so far (drives the live size). */
402
423
  readonly planSize: number;
424
+ }
425
+ | {
426
+ /**
427
+ * The ambient-liveness status line at the thread's tail (stigmer#277):
428
+ * emitted while the active execution is IN_PROGRESS with no running
429
+ * tool call, no live sub-agent, and no pending approval — the quiet
430
+ * stretches where the screen would otherwise be completely still.
431
+ */
432
+ readonly kind: "liveness";
433
+ readonly key: string;
403
434
  };
404
435
 
405
436
  /**
@@ -426,6 +457,30 @@ function hasStartedResponding(execution: AgentExecution): boolean {
426
457
  });
427
458
  }
428
459
 
460
+ /**
461
+ * True while the active execution already shows a live signal of its own
462
+ * somewhere in the thread — a RUNNING tool call (its row's label carries the
463
+ * shimmer) or an in-flight sub-agent (its section carries a live indicator).
464
+ * Suppresses the bottom liveness line: one ambient signal at a time, riding
465
+ * the words closest to the actual activity.
466
+ */
467
+ function hasVisiblyRunningActivity(execution: AgentExecution): boolean {
468
+ for (const sub of execution.status?.subAgentExecutions ?? []) {
469
+ if (
470
+ sub.status === SubAgentStatus.SUB_AGENT_IN_PROGRESS ||
471
+ sub.status === SubAgentStatus.SUB_AGENT_PENDING
472
+ ) {
473
+ return true;
474
+ }
475
+ }
476
+ for (const msg of execution.status?.messages ?? []) {
477
+ for (const tc of msg.toolCalls) {
478
+ if (tc.status === ToolCallStatus.TOOL_CALL_RUNNING) return true;
479
+ }
480
+ }
481
+ return false;
482
+ }
483
+
429
484
  /**
430
485
  * True for an execution that ran in Plan mode and completed — the only kind of
431
486
  * execution that has a reviewable plan (streaming/failed/terminated Plan turns
@@ -1026,6 +1081,26 @@ export function buildThreadItems(
1026
1081
  // edit row, never appended at the thread tail. Pending decision bars are
1027
1082
  // not thread items at all: they live in the composer-docked FileReviewDock.
1028
1083
 
1084
+ // The ambient-liveness line (stigmer#277): the thread's tail is never a
1085
+ // dead frame while the agent is alive. Emitted only when
1086
+ // - the execution is IN_PROGRESS (phase-driven, DD-009 — WAITING/PAUSED
1087
+ // mean the agent is NOT working, and shimmering there would lie),
1088
+ // - it is past the pre-first-content window (setup-progress owns that),
1089
+ // - nothing else on screen carries its own live signal (a running tool
1090
+ // row or live sub-agent — one ambient signal at a time), and
1091
+ // - no approval is pending (the gate card is the louder, truthful state).
1092
+ // Model-generation gaps between tool calls — the exact moments users doubt
1093
+ // the agent — are precisely what remains.
1094
+ if (
1095
+ activeStreamExecution &&
1096
+ hasStartedResponding(activeStreamExecution) &&
1097
+ activeStreamExecution.status?.phase === ExecutionPhase.EXECUTION_IN_PROGRESS &&
1098
+ (activeStreamExecution.status.pendingApprovals?.length ?? 0) === 0 &&
1099
+ !hasVisiblyRunningActivity(activeStreamExecution)
1100
+ ) {
1101
+ items.push({ kind: "liveness", key: "liveness-status" });
1102
+ }
1103
+
1029
1104
  if (pendingUserMessage) {
1030
1105
  // A FAILED send never created an execution, so an existing execution with
1031
1106
  // identical text (e.g. two build attempts of the same plan — both
@@ -1489,14 +1564,16 @@ export function ThreadItemRenderer({
1489
1564
  <ExecutionPhaseBadge phase={item.phase} />
1490
1565
  </div>
1491
1566
  );
1492
- case "execution-error":
1567
+ case "execution-error": {
1568
+ const ErrorNotice = slots?.ExecutionErrorNotice ?? ExecutionErrorNotice;
1493
1569
  return (
1494
- <ExecutionErrorNotice
1570
+ <ErrorNotice
1495
1571
  error={item.error}
1496
1572
  retryMessage={item.retryMessage}
1497
1573
  onRetry={onRetryExecution}
1498
1574
  />
1499
1575
  );
1576
+ }
1500
1577
  case "approval-request":
1501
1578
  return (
1502
1579
  <ApprovalCardRow
@@ -1521,6 +1598,10 @@ export function ThreadItemRenderer({
1521
1598
  }
1522
1599
  case "context-compacted":
1523
1600
  return <SummarizationCard event={item.event} />;
1601
+ case "liveness": {
1602
+ const Liveness = slots?.LivenessStatusLine ?? LivenessStatusLine;
1603
+ return <Liveness />;
1604
+ }
1524
1605
  case "todos": {
1525
1606
  const Todos = slots?.TodoCard ?? TodoCard;
1526
1607
  return <Todos todos={item.todos} className="stg:mx-4" TodoRow={slots?.TodoRow} />;
@@ -1624,86 +1705,6 @@ function FailedUserMessage({
1624
1705
  );
1625
1706
  }
1626
1707
 
1627
- // ---------------------------------------------------------------------------
1628
- // ExecutionErrorNotice — server failure reason for a terminal-failed execution
1629
- // ---------------------------------------------------------------------------
1630
-
1631
- /**
1632
- * Recognizes a recoverable *interruption* (worker reaped / heartbeat timeout /
1633
- * stall) as opposed to a genuine application failure. The runner stamps these
1634
- * with a stable signature ("[StallTimeoutError]", "Execution interrupted",
1635
- * "Retry or resume."), and the workflow auto-resumes them while recovery cycles
1636
- * remain; by the time one reaches the UI as terminal it is resumable from the
1637
- * session's persisted harness_state_id rather than a dead end.
1638
- */
1639
- function isInterruptedError(error: string): boolean {
1640
- return /\[StallTimeoutError\]|execution interrupted|retry or resume/i.test(error);
1641
- }
1642
-
1643
- /**
1644
- * Renders the server-reported failure reason (`AgentExecutionStatus.error`)
1645
- * for an execution that died — typically before producing any messages. The
1646
- * reason can be a long Temporal error, so it is clamped by default with a
1647
- * Show more / Show less toggle.
1648
- *
1649
- * A genuine failure renders as a destructive alert with a Retry. A *recoverable
1650
- * interruption* renders as a neutral notice with a Resume — both resend the
1651
- * originating message, which the server continues from the session's persisted
1652
- * harness_state_id (the same data path; the framing differs so an interruption
1653
- * never looks like a dead-end crash).
1654
- */
1655
- function ExecutionErrorNotice({
1656
- error,
1657
- retryMessage,
1658
- onRetry,
1659
- }: {
1660
- error: string;
1661
- retryMessage?: string;
1662
- onRetry?: (message: string) => void;
1663
- }) {
1664
- const [expanded, setExpanded] = useState(false);
1665
- const canRetry = !!onRetry && !!retryMessage;
1666
- const interrupted = isInterruptedError(error);
1667
-
1668
- return (
1669
- <div
1670
- role={interrupted ? "status" : "alert"}
1671
- className={cn(
1672
- "stg:mx-4 stg:flex stg:flex-col stg:gap-1.5 stg:rounded-md stg:px-3 stg:py-2",
1673
- interrupted ? "stg:bg-muted" : "stg:bg-destructive-subtle",
1674
- )}
1675
- >
1676
- <p
1677
- className={cn(
1678
- "stg:text-xs stg:whitespace-pre-wrap stg:break-words",
1679
- interrupted ? "stg:text-foreground" : "stg:text-destructive",
1680
- !expanded && "stg:line-clamp-3",
1681
- )}
1682
- >
1683
- {error}
1684
- </p>
1685
- <div className="stg:flex stg:items-center stg:gap-3 stg:text-xs">
1686
- <button
1687
- type="button"
1688
- onClick={() => setExpanded((v) => !v)}
1689
- className="stg:font-medium stg:text-muted-foreground stg:underline-offset-2 stg:hover:underline stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring"
1690
- >
1691
- {expanded ? "Show less" : "Show more"}
1692
- </button>
1693
- {canRetry && (
1694
- <button
1695
- type="button"
1696
- onClick={() => onRetry!(retryMessage!)}
1697
- className="stg:font-medium stg:text-foreground stg:underline-offset-2 stg:hover:underline stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring"
1698
- >
1699
- {interrupted ? "Resume" : "Retry"}
1700
- </button>
1701
- )}
1702
- </div>
1703
- </div>
1704
- );
1705
- }
1706
-
1707
1708
  // ---------------------------------------------------------------------------
1708
1709
  // ApprovalCardRow — stabilizes the onSubmit callback for React.memo
1709
1710
  // ---------------------------------------------------------------------------
@@ -145,7 +145,11 @@ export const SetupProgress = memo(function SetupProgress({
145
145
  className={cn("stg:flex stg:items-center stg:gap-2.5 stg:px-4 stg:py-2", className)}
146
146
  >
147
147
  <PulseIndicator />
148
- <span className="stg:text-sm stg:text-muted-foreground stg:animate-in stg:fade-in stg:duration-300">
148
+ {/* The setup/thinking label carries the ambient-liveness sweep
149
+ (stigmer#277): this indicator only exists while the execution is
150
+ live, so it always shimmers. The shimmer class owns `color`,
151
+ replacing the static muted utility. */}
152
+ <span className="stg:text-sm stg:animate-in stg:fade-in stg:duration-300 stgm-shimmer-label">
149
153
  {currentMessage}
150
154
  </span>
151
155
  </div>
@@ -12,7 +12,7 @@ import { useRenderTracer } from "../internal/dev/index.js";
12
12
  import { useAutoDisclosure } from "../internal/useAutoDisclosure.js";
13
13
  import { useElapsedSince, formatElapsed } from "../internal/useElapsedSince.js";
14
14
  import { cn } from "@stigmer/theme";
15
- import { formatDuration } from "./ToolCallDetail.js";
15
+ import { formatHeaderDuration } from "./ToolCallDetail.js";
16
16
  import { MessageEntry } from "./MessageEntry.js";
17
17
  import { ToolCallGroup } from "./ToolCallGroup.js";
18
18
  import { ApprovalContext } from "./ApprovalContext.js";
@@ -23,6 +23,7 @@ import {
23
23
  findActiveTodo,
24
24
  todoCompletionSummary,
25
25
  } from "./TodoList.js";
26
+ import { SpinnerIcon } from "../internal/thread-card/glyphs.js";
26
27
 
27
28
  /** Props for {@link SubAgentSection}. */
28
29
  export interface SubAgentSectionProps {
@@ -80,7 +81,10 @@ export const SubAgentSection = memo(function SubAgentSection({
80
81
  }: SubAgentSectionProps) {
81
82
  useRenderTracer("SubAgentSection", { status: sub.status, name: sub.name });
82
83
 
83
- const duration = formatDuration(sub.startedAt, sub.completedAt);
84
+ // Header chip threshold (>= 1s) shared with ToolCallItem — a sub-second
85
+ // sub-agent is noise by the same rule, and the two row kinds must speak
86
+ // one duration vocabulary.
87
+ const duration = formatHeaderDuration(sub.startedAt, sub.completedAt);
84
88
  const statusInfo = SUB_AGENT_STATUS_MAP[sub.status];
85
89
  const StatusIcon = statusInfo.icon;
86
90
  const isFailed = sub.status === SubAgentStatus.SUB_AGENT_FAILED;
@@ -206,7 +210,7 @@ function CollapsibleCard({
206
210
  <span className="stg:min-w-0 stg:flex-1 stg:truncate">{displayLabel}</span>
207
211
  {isRunning && (
208
212
  <span className="stg:shrink-0 stg:text-muted-foreground" aria-hidden="true">
209
- <SpinnerIcon />
213
+ <SpinnerIcon size={12} />
210
214
  </span>
211
215
  )}
212
216
  <span
@@ -482,7 +486,8 @@ const SUB_AGENT_STATUS_MAP: Record<SubAgentStatus, SubAgentStatusInfo> = {
482
486
  label: "Running",
483
487
  colorClass: "stg:text-foreground",
484
488
  badgeClass: "stg:bg-muted stg:text-foreground",
485
- icon: SpinnerIcon,
489
+ // Sized up to match this map's 12px siblings (the glyph defaults to 10).
490
+ icon: () => <SpinnerIcon size={12} />,
486
491
  },
487
492
  [SubAgentStatus.SUB_AGENT_COMPLETED]: {
488
493
  label: "Completed",
@@ -508,22 +513,6 @@ const SUB_AGENT_STATUS_MAP: Record<SubAgentStatus, SubAgentStatusInfo> = {
508
513
  // Inline SVG icons
509
514
  // ---------------------------------------------------------------------------
510
515
 
511
- function SpinnerIcon() {
512
- return (
513
- <svg
514
- width="12"
515
- height="12"
516
- viewBox="0 0 12 12"
517
- fill="none"
518
- stroke="currentColor"
519
- strokeWidth="1.5"
520
- className="stg:animate-spin"
521
- >
522
- <path d="M6 1.5A4.5 4.5 0 1 1 1.5 6" strokeLinecap="round" />
523
- </svg>
524
- );
525
- }
526
-
527
516
  function CheckCircleIcon() {
528
517
  return (
529
518
  <svg
@@ -75,17 +75,104 @@ export function TerminalSession({
75
75
  {stderr && (
76
76
  <CollapsiblePre content={normalize(stderr)} className="stg:text-destructive" />
77
77
  )}
78
- {failed && (
79
- <div>
80
- <span className="stg:sr-only">Command exited with code {exitCode}</span>
81
- <span
82
- aria-hidden="true"
83
- className="stg:inline-block stg:rounded stg:bg-destructive-subtle stg:px-1 stg:py-0.5 stg:text-[10px] stg:font-medium stg:leading-none stg:tabular-nums stg:text-destructive"
84
- >
85
- exit {exitCode}
86
- </span>
87
- </div>
78
+ {failed && <ExitBadge exitCode={exitCode} />}
79
+ </div>
80
+ );
81
+ }
82
+
83
+ /** How many trailing output lines a collapsed terminal tail keeps visible. */
84
+ const TAIL_LINE_LIMIT = 3;
85
+
86
+ /** Props for {@link TerminalTail}. */
87
+ export interface TerminalTailProps {
88
+ /** The command that was run, shown as the `$ <command>` prompt line. */
89
+ readonly command?: string;
90
+ /** Standard output. */
91
+ readonly stdout?: string;
92
+ /** Standard error. */
93
+ readonly stderr?: string;
94
+ /** Process exit code. A non-zero code renders a trailing `exit N` badge. */
95
+ readonly exitCode?: number;
96
+ /** Additional CSS class names for the root container. */
97
+ readonly className?: string;
98
+ }
99
+
100
+ /**
101
+ * The collapsed teaser of a settled terminal session: the `$ command` prompt
102
+ * line plus a dimmed tail of the last few output lines — enough to see at a
103
+ * glance that the command ran and what it printed last, without the full
104
+ * output competing with the conversation.
105
+ *
106
+ * The reduced contrast is deliberate and load-bearing: the tail is *context*,
107
+ * not content, so it renders one contrast step below the reading text
108
+ * (`muted-foreground`), while the command — the user-relevant intent — keeps
109
+ * full contrast. stderr is not colored here for the same reason; the full
110
+ * session (one disclosure away) restores the destructive treatment.
111
+ *
112
+ * Rendered by the tool-call row's `"tail"` disclosure state (see
113
+ * {@link ToolCallItem}); the row's header chevron is the expand control, so
114
+ * this component is presentation-only.
115
+ */
116
+ export function TerminalTail({
117
+ command,
118
+ stdout,
119
+ stderr,
120
+ exitCode,
121
+ className,
122
+ }: TerminalTailProps) {
123
+ const normalize = useSandboxNormalize();
124
+ const failed = exitCode !== undefined && exitCode !== 0;
125
+
126
+ // One combined stream, in the order the full session renders it. Trailing
127
+ // whitespace is trimmed so an ending newline doesn't blank the last slot.
128
+ const combined = [stdout, stderr]
129
+ .filter((s): s is string => Boolean(s))
130
+ .join("\n")
131
+ .replace(/\s+$/, "");
132
+ const lines = combined ? normalize(combined).split("\n") : [];
133
+ const tail = lines.slice(-TAIL_LINE_LIMIT);
134
+ const hiddenCount = lines.length - tail.length;
135
+
136
+ return (
137
+ <div
138
+ data-cursor-target="terminal-tail"
139
+ className={cn(
140
+ "stg:space-y-1 stg:rounded-md stg:border stg:border-border stg:bg-muted-subtle stg:p-2.5 stg:font-mono stg:text-xs",
141
+ className,
88
142
  )}
143
+ >
144
+ {command && (
145
+ <pre className="stg:whitespace-pre-wrap stg:break-words stg:text-foreground">
146
+ <span className="stg:select-none stg:text-muted-foreground">$ </span>
147
+ {normalize(command)}
148
+ </pre>
149
+ )}
150
+ {tail.length > 0 && (
151
+ <pre className="stg:whitespace-pre-wrap stg:break-words stg:text-muted-foreground">
152
+ {hiddenCount > 0 && (
153
+ <span className="stg:block stg:select-none stg:text-muted-foreground-subtle">
154
+ … +{hiddenCount} {hiddenCount === 1 ? "line" : "lines"}
155
+ </span>
156
+ )}
157
+ {tail.join("\n")}
158
+ </pre>
159
+ )}
160
+ {failed && <ExitBadge exitCode={exitCode} />}
161
+ </div>
162
+ );
163
+ }
164
+
165
+ /** The `exit N` failure badge, shared by the full session and the tail. */
166
+ function ExitBadge({ exitCode }: { exitCode?: number }) {
167
+ return (
168
+ <div>
169
+ <span className="stg:sr-only">Command exited with code {exitCode}</span>
170
+ <span
171
+ aria-hidden="true"
172
+ className="stg:inline-block stg:rounded stg:bg-destructive-subtle stg:px-1 stg:py-0.5 stg:text-[10px] stg:font-medium stg:leading-none stg:tabular-nums stg:text-destructive"
173
+ >
174
+ exit {exitCode}
175
+ </span>
89
176
  </div>
90
177
  );
91
178
  }
@@ -347,3 +347,22 @@ export function formatDuration(
347
347
  const seconds = Math.round((ms % 60_000) / 1000);
348
348
  return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
349
349
  }
350
+
351
+ /**
352
+ * {@link formatDuration} for header duration chips: returns `null` below one
353
+ * second. A duration chip earns its place only when it carries information —
354
+ * a `4ms` chip on a directory listing draws the eye to the least interesting
355
+ * row in the thread (stigmer#274), so sub-second work renders no chip at all.
356
+ * `formatDuration` itself stays exact — it is public API with consumers that
357
+ * want the precise value.
358
+ */
359
+ export function formatHeaderDuration(
360
+ startedAt: string,
361
+ completedAt: string,
362
+ ): string | null {
363
+ const formatted = formatDuration(startedAt, completedAt);
364
+ // Exactly the sub-second arm of formatDuration ("123ms"); every other arm
365
+ // is >= 1s by construction.
366
+ if (formatted === null || formatted.endsWith("ms")) return null;
367
+ return formatted;
368
+ }