@stigmer/react 3.12.2 → 3.12.4

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 (429) hide show
  1. package/access/ManageAccessDialog.d.ts.map +1 -1
  2. package/access/ManageAccessDialog.js +3 -19
  3. package/access/ManageAccessDialog.js.map +1 -1
  4. package/agent/steps/IdentityStep.d.ts.map +1 -1
  5. package/agent/steps/IdentityStep.js +2 -1
  6. package/agent/steps/IdentityStep.js.map +1 -1
  7. package/agent-instance/AgentInstanceDetailPanel.d.ts.map +1 -1
  8. package/agent-instance/AgentInstanceDetailPanel.js +2 -1
  9. package/agent-instance/AgentInstanceDetailPanel.js.map +1 -1
  10. package/agent-instance/CreateAgentInstanceDialog.d.ts.map +1 -1
  11. package/agent-instance/CreateAgentInstanceDialog.js +7 -20
  12. package/agent-instance/CreateAgentInstanceDialog.js.map +1 -1
  13. package/api-key/CreateApiKeyForm.d.ts.map +1 -1
  14. package/api-key/CreateApiKeyForm.js +2 -1
  15. package/api-key/CreateApiKeyForm.js.map +1 -1
  16. package/attachment/AttachmentImageLightbox.d.ts.map +1 -1
  17. package/attachment/AttachmentImageLightbox.js +8 -23
  18. package/attachment/AttachmentImageLightbox.js.map +1 -1
  19. package/channel/ChannelConversationsDialog.d.ts.map +1 -1
  20. package/channel/ChannelConversationsDialog.js +5 -20
  21. package/channel/ChannelConversationsDialog.js.map +1 -1
  22. package/channel/ChannelCredentialsDialog.d.ts.map +1 -1
  23. package/channel/ChannelCredentialsDialog.js +3 -19
  24. package/channel/ChannelCredentialsDialog.js.map +1 -1
  25. package/channel/ChannelTemplatesDialog.d.ts.map +1 -1
  26. package/channel/ChannelTemplatesDialog.js +6 -21
  27. package/channel/ChannelTemplatesDialog.js.map +1 -1
  28. package/channel/ConnectSlackDialog.d.ts.map +1 -1
  29. package/channel/ConnectSlackDialog.js +5 -22
  30. package/channel/ConnectSlackDialog.js.map +1 -1
  31. package/channel/ConnectWhatsAppDialog.d.ts.map +1 -1
  32. package/channel/ConnectWhatsAppDialog.js +3 -21
  33. package/channel/ConnectWhatsAppDialog.js.map +1 -1
  34. package/channel/connect/ServingAppSection.d.ts.map +1 -1
  35. package/channel/connect/ServingAppSection.js +2 -1
  36. package/channel/connect/ServingAppSection.js.map +1 -1
  37. package/channel-app/CreateChannelAppForm.d.ts.map +1 -1
  38. package/channel-app/CreateChannelAppForm.js +2 -1
  39. package/channel-app/CreateChannelAppForm.js.map +1 -1
  40. package/conversation/ConversationAttentionBanner.d.ts +23 -6
  41. package/conversation/ConversationAttentionBanner.d.ts.map +1 -1
  42. package/conversation/ConversationAttentionBanner.js +25 -10
  43. package/conversation/ConversationAttentionBanner.js.map +1 -1
  44. package/conversation/ConversationListPane.d.ts.map +1 -1
  45. package/conversation/ConversationListPane.js +26 -6
  46. package/conversation/ConversationListPane.js.map +1 -1
  47. package/conversation/ConversationTimelineView.d.ts.map +1 -1
  48. package/conversation/ConversationTimelineView.js +2 -1
  49. package/conversation/ConversationTimelineView.js.map +1 -1
  50. package/conversation/ConversationsWorkbench.d.ts.map +1 -1
  51. package/conversation/ConversationsWorkbench.js +1 -1
  52. package/conversation/ConversationsWorkbench.js.map +1 -1
  53. package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -1
  54. package/cursor-accounts/CursorAccountsConsole.js +2 -1
  55. package/cursor-accounts/CursorAccountsConsole.js.map +1 -1
  56. package/cursor-accounts/MemberKeysPanel.d.ts.map +1 -1
  57. package/cursor-accounts/MemberKeysPanel.js +2 -1
  58. package/cursor-accounts/MemberKeysPanel.js.map +1 -1
  59. package/dashboard/DashboardFailedRuns.d.ts.map +1 -1
  60. package/dashboard/DashboardFailedRuns.js +2 -1
  61. package/dashboard/DashboardFailedRuns.js.map +1 -1
  62. package/dependency-graph/DependencyGraph.d.ts.map +1 -1
  63. package/dependency-graph/DependencyGraph.js +2 -1
  64. package/dependency-graph/DependencyGraph.js.map +1 -1
  65. package/dependency-graph/DependencyTreeNode.d.ts.map +1 -1
  66. package/dependency-graph/DependencyTreeNode.js +2 -1
  67. package/dependency-graph/DependencyTreeNode.js.map +1 -1
  68. package/environment/EnvironmentPicker.d.ts.map +1 -1
  69. package/environment/EnvironmentPicker.js +2 -1
  70. package/environment/EnvironmentPicker.js.map +1 -1
  71. package/error/SecretFlowErrorGuide.d.ts.map +1 -1
  72. package/error/SecretFlowErrorGuide.js +2 -1
  73. package/error/SecretFlowErrorGuide.js.map +1 -1
  74. package/execution/ApprovalCard.d.ts.map +1 -1
  75. package/execution/ApprovalCard.js +13 -3
  76. package/execution/ApprovalCard.js.map +1 -1
  77. package/execution/ArtifactContentBody.d.ts.map +1 -1
  78. package/execution/ArtifactContentBody.js +2 -1
  79. package/execution/ArtifactContentBody.js.map +1 -1
  80. package/execution/ArtifactPreviewModal.d.ts.map +1 -1
  81. package/execution/ArtifactPreviewModal.js +11 -17
  82. package/execution/ArtifactPreviewModal.js.map +1 -1
  83. package/execution/ArtifactsWidget.d.ts.map +1 -1
  84. package/execution/ArtifactsWidget.js +2 -1
  85. package/execution/ArtifactsWidget.js.map +1 -1
  86. package/execution/FileChangeProgressBar.d.ts.map +1 -1
  87. package/execution/FileChangeProgressBar.js +2 -1
  88. package/execution/FileChangeProgressBar.js.map +1 -1
  89. package/execution/TodoList.d.ts.map +1 -1
  90. package/execution/TodoList.js +2 -1
  91. package/execution/TodoList.js.map +1 -1
  92. package/execution/ToolCallItem.d.ts +3 -1
  93. package/execution/ToolCallItem.d.ts.map +1 -1
  94. package/execution/ToolCallItem.js +19 -7
  95. package/execution/ToolCallItem.js.map +1 -1
  96. package/execution/WriteBacksWidget.d.ts.map +1 -1
  97. package/execution/WriteBacksWidget.js +2 -1
  98. package/execution/WriteBacksWidget.js.map +1 -1
  99. package/execution/index.d.ts +1 -1
  100. package/execution/index.d.ts.map +1 -1
  101. package/execution/index.js +1 -1
  102. package/execution/index.js.map +1 -1
  103. package/execution/tool-categories.d.ts +37 -3
  104. package/execution/tool-categories.d.ts.map +1 -1
  105. package/execution/tool-categories.js +74 -2
  106. package/execution/tool-categories.js.map +1 -1
  107. package/execution/tool-presenter.d.ts +15 -0
  108. package/execution/tool-presenter.d.ts.map +1 -1
  109. package/execution/tool-presenter.js +7 -2
  110. package/execution/tool-presenter.js.map +1 -1
  111. package/iam-policy/PeopleWithAccess.d.ts.map +1 -1
  112. package/iam-policy/PeopleWithAccess.js +2 -1
  113. package/iam-policy/PeopleWithAccess.js.map +1 -1
  114. package/iam-policy/PrincipalPicker.d.ts.map +1 -1
  115. package/iam-policy/PrincipalPicker.js +2 -1
  116. package/iam-policy/PrincipalPicker.js.map +1 -1
  117. package/iam-policy/RoleSelector.d.ts.map +1 -1
  118. package/iam-policy/RoleSelector.js +2 -1
  119. package/iam-policy/RoleSelector.js.map +1 -1
  120. package/identity-provider/CreateIdentityProviderForm.d.ts.map +1 -1
  121. package/identity-provider/CreateIdentityProviderForm.js +2 -1
  122. package/identity-provider/CreateIdentityProviderForm.js.map +1 -1
  123. package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
  124. package/identity-provider/IdentityProviderDetailPanel.js +2 -1
  125. package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
  126. package/identity-provider/IdentityProviderWizard.d.ts.map +1 -1
  127. package/identity-provider/IdentityProviderWizard.js +2 -1
  128. package/identity-provider/IdentityProviderWizard.js.map +1 -1
  129. package/index.d.ts +4 -2
  130. package/index.d.ts.map +1 -1
  131. package/index.js +4 -1
  132. package/index.js.map +1 -1
  133. package/internal/DialogShell.d.ts +77 -0
  134. package/internal/DialogShell.d.ts.map +1 -0
  135. package/internal/DialogShell.js +77 -0
  136. package/internal/DialogShell.js.map +1 -0
  137. package/internal/element-resets.d.ts +17 -0
  138. package/internal/element-resets.d.ts.map +1 -0
  139. package/internal/element-resets.js +32 -0
  140. package/internal/element-resets.js.map +1 -0
  141. package/internal/file-tree/FileTreeNode.d.ts.map +1 -1
  142. package/internal/file-tree/FileTreeNode.js +2 -1
  143. package/internal/file-tree/FileTreeNode.js.map +1 -1
  144. package/internal/markdown-components.d.ts +7 -0
  145. package/internal/markdown-components.d.ts.map +1 -1
  146. package/internal/markdown-components.js +15 -5
  147. package/internal/markdown-components.js.map +1 -1
  148. package/invitation/InvitationManager.d.ts.map +1 -1
  149. package/invitation/InvitationManager.js +2 -1
  150. package/invitation/InvitationManager.js.map +1 -1
  151. package/manifest/ApplyManifestDialog.d.ts.map +1 -1
  152. package/manifest/ApplyManifestDialog.js +8 -17
  153. package/manifest/ApplyManifestDialog.js.map +1 -1
  154. package/manifest/EditResourceYamlDialog.d.ts.map +1 -1
  155. package/manifest/EditResourceYamlDialog.js +3 -19
  156. package/manifest/EditResourceYamlDialog.js.map +1 -1
  157. package/mcp-server/McpServerConnectDialog.d.ts.map +1 -1
  158. package/mcp-server/McpServerConnectDialog.js +8 -20
  159. package/mcp-server/McpServerConnectDialog.js.map +1 -1
  160. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  161. package/mcp-server/McpServerDetailView.js +4 -15
  162. package/mcp-server/McpServerDetailView.js.map +1 -1
  163. package/mcp-server/steps/IdentityTransportStep.d.ts.map +1 -1
  164. package/mcp-server/steps/IdentityTransportStep.js +2 -1
  165. package/mcp-server/steps/IdentityTransportStep.js.map +1 -1
  166. package/package.json +4 -4
  167. package/platform-client/CreatePlatformClientForm.d.ts.map +1 -1
  168. package/platform-client/CreatePlatformClientForm.js +2 -1
  169. package/platform-client/CreatePlatformClientForm.js.map +1 -1
  170. package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -1
  171. package/platform-client/PlatformClientDetailPanel.js +2 -1
  172. package/platform-client/PlatformClientDetailPanel.js.map +1 -1
  173. package/pricing-governance/BaselineEditor.d.ts.map +1 -1
  174. package/pricing-governance/BaselineEditor.js +2 -1
  175. package/pricing-governance/BaselineEditor.js.map +1 -1
  176. package/pricing-governance/PricingGovernanceConsole.d.ts.map +1 -1
  177. package/pricing-governance/PricingGovernanceConsole.js +2 -1
  178. package/pricing-governance/PricingGovernanceConsole.js.map +1 -1
  179. package/provider-standing/ProviderStandingAccessNotice.d.ts +11 -0
  180. package/provider-standing/ProviderStandingAccessNotice.d.ts.map +1 -0
  181. package/provider-standing/ProviderStandingAccessNotice.js +14 -0
  182. package/provider-standing/ProviderStandingAccessNotice.js.map +1 -0
  183. package/provider-standing/ProviderStandingConsole.d.ts +24 -0
  184. package/provider-standing/ProviderStandingConsole.d.ts.map +1 -0
  185. package/provider-standing/ProviderStandingConsole.js +98 -0
  186. package/provider-standing/ProviderStandingConsole.js.map +1 -0
  187. package/provider-standing/index.d.ts +6 -0
  188. package/provider-standing/index.d.ts.map +1 -0
  189. package/provider-standing/index.js +6 -0
  190. package/provider-standing/index.js.map +1 -0
  191. package/provider-standing/useProviderStanding.d.ts +34 -0
  192. package/provider-standing/useProviderStanding.d.ts.map +1 -0
  193. package/provider-standing/useProviderStanding.js +26 -0
  194. package/provider-standing/useProviderStanding.js.map +1 -0
  195. package/provider.d.ts +12 -0
  196. package/provider.d.ts.map +1 -1
  197. package/provider.js +12 -0
  198. package/provider.js.map +1 -1
  199. package/resource-creation/StepIndicator.d.ts.map +1 -1
  200. package/resource-creation/StepIndicator.js +2 -1
  201. package/resource-creation/StepIndicator.js.map +1 -1
  202. package/resource-detail/ConfirmDialog.d.ts +2 -3
  203. package/resource-detail/ConfirmDialog.d.ts.map +1 -1
  204. package/resource-detail/ConfirmDialog.js +8 -20
  205. package/resource-detail/ConfirmDialog.js.map +1 -1
  206. package/schedule/ScheduleDetailView.d.ts.map +1 -1
  207. package/schedule/ScheduleDetailView.js +3 -2
  208. package/schedule/ScheduleDetailView.js.map +1 -1
  209. package/schedule/ScheduleRunsTable.d.ts.map +1 -1
  210. package/schedule/ScheduleRunsTable.js +2 -1
  211. package/schedule/ScheduleRunsTable.js.map +1 -1
  212. package/session/facets/ArtifactsTab.d.ts.map +1 -1
  213. package/session/facets/ArtifactsTab.js +2 -1
  214. package/session/facets/ArtifactsTab.js.map +1 -1
  215. package/session/facets/ChangesTab.d.ts.map +1 -1
  216. package/session/facets/ChangesTab.js +2 -1
  217. package/session/facets/ChangesTab.js.map +1 -1
  218. package/session/facets/UsageTab.d.ts +10 -3
  219. package/session/facets/UsageTab.d.ts.map +1 -1
  220. package/session/facets/UsageTab.js +42 -6
  221. package/session/facets/UsageTab.js.map +1 -1
  222. package/session/index.d.ts +1 -1
  223. package/session/index.d.ts.map +1 -1
  224. package/session/index.js.map +1 -1
  225. package/session/useSessionUsage.d.ts +25 -0
  226. package/session/useSessionUsage.d.ts.map +1 -1
  227. package/session/useSessionUsage.js +11 -0
  228. package/session/useSessionUsage.js.map +1 -1
  229. package/settings/settings-nav.d.ts.map +1 -1
  230. package/settings/settings-nav.js +7 -1
  231. package/settings/settings-nav.js.map +1 -1
  232. package/settings/useSettingsNavGroups.d.ts.map +1 -1
  233. package/settings/useSettingsNavGroups.js +4 -1
  234. package/settings/useSettingsNavGroups.js.map +1 -1
  235. package/sharing/ShareAgentDialog.d.ts.map +1 -1
  236. package/sharing/ShareAgentDialog.js +4 -21
  237. package/sharing/ShareAgentDialog.js.map +1 -1
  238. package/sidebar/WorkspaceSidebar.d.ts.map +1 -1
  239. package/sidebar/WorkspaceSidebar.js +2 -1
  240. package/sidebar/WorkspaceSidebar.js.map +1 -1
  241. package/skill/SkillDiffDialog.d.ts.map +1 -1
  242. package/skill/SkillDiffDialog.js +5 -21
  243. package/skill/SkillDiffDialog.js.map +1 -1
  244. package/skill/SkillFileBrowser.d.ts.map +1 -1
  245. package/skill/SkillFileBrowser.js +2 -1
  246. package/skill/SkillFileBrowser.js.map +1 -1
  247. package/skill/internal/fetchAndUnpackArtifact.d.ts +1 -1
  248. package/skill/internal/fetchAndUnpackArtifact.d.ts.map +1 -1
  249. package/skill/internal/fetchAndUnpackArtifact.js +47 -3
  250. package/skill/internal/fetchAndUnpackArtifact.js.map +1 -1
  251. package/skill/useSkillDiff.d.ts.map +1 -1
  252. package/skill/useSkillDiff.js +7 -1
  253. package/skill/useSkillDiff.js.map +1 -1
  254. package/skill/useSkillUpload.d.ts.map +1 -1
  255. package/skill/useSkillUpload.js +22 -4
  256. package/skill/useSkillUpload.js.map +1 -1
  257. package/src/__tests__/bare-host-resets.layout.test.tsx +184 -0
  258. package/src/access/ManageAccessDialog.tsx +7 -27
  259. package/src/agent/steps/IdentityStep.tsx +2 -1
  260. package/src/agent-instance/AgentInstanceDetailPanel.tsx +2 -1
  261. package/src/agent-instance/CreateAgentInstanceDialog.tsx +14 -27
  262. package/src/api-key/CreateApiKeyForm.tsx +2 -1
  263. package/src/attachment/AttachmentImageLightbox.tsx +13 -36
  264. package/src/channel/ChannelConversationsDialog.tsx +10 -28
  265. package/src/channel/ChannelCredentialsDialog.tsx +8 -28
  266. package/src/channel/ChannelTemplatesDialog.tsx +12 -30
  267. package/src/channel/ConnectSlackDialog.tsx +10 -31
  268. package/src/channel/ConnectWhatsAppDialog.tsx +8 -30
  269. package/src/channel/connect/ServingAppSection.tsx +2 -1
  270. package/src/channel-app/CreateChannelAppForm.tsx +2 -1
  271. package/src/conversation/ConversationAttentionBanner.tsx +64 -19
  272. package/src/conversation/ConversationListPane.tsx +39 -17
  273. package/src/conversation/ConversationTimelineView.tsx +2 -1
  274. package/src/conversation/ConversationsWorkbench.tsx +1 -0
  275. package/src/conversation/__tests__/ConversationAttentionBanner.test.tsx +76 -2
  276. package/src/conversation/__tests__/ConversationListPane.test.tsx +15 -4
  277. package/src/cursor-accounts/CursorAccountsConsole.tsx +2 -1
  278. package/src/cursor-accounts/MemberKeysPanel.tsx +2 -1
  279. package/src/dashboard/DashboardFailedRuns.tsx +2 -1
  280. package/src/dependency-graph/DependencyGraph.tsx +2 -1
  281. package/src/dependency-graph/DependencyTreeNode.tsx +2 -1
  282. package/src/environment/EnvironmentPicker.tsx +2 -1
  283. package/src/error/SecretFlowErrorGuide.tsx +3 -2
  284. package/src/execution/ApprovalCard.tsx +23 -2
  285. package/src/execution/ArtifactContentBody.tsx +2 -1
  286. package/src/execution/ArtifactPreviewModal.tsx +15 -27
  287. package/src/execution/ArtifactsWidget.tsx +2 -1
  288. package/src/execution/FileChangeProgressBar.tsx +2 -1
  289. package/src/execution/TodoList.tsx +2 -1
  290. package/src/execution/ToolCallItem.tsx +19 -8
  291. package/src/execution/WriteBacksWidget.tsx +2 -1
  292. package/src/execution/__tests__/intent-title.test.tsx +221 -0
  293. package/src/execution/index.ts +3 -0
  294. package/src/execution/tool-categories.ts +103 -5
  295. package/src/execution/tool-presenter.ts +22 -1
  296. package/src/iam-policy/PeopleWithAccess.tsx +2 -1
  297. package/src/iam-policy/PrincipalPicker.tsx +2 -0
  298. package/src/iam-policy/RoleSelector.tsx +2 -1
  299. package/src/identity-provider/CreateIdentityProviderForm.tsx +2 -1
  300. package/src/identity-provider/IdentityProviderDetailPanel.tsx +2 -1
  301. package/src/identity-provider/IdentityProviderWizard.tsx +2 -1
  302. package/src/index.ts +16 -0
  303. package/src/internal/DialogShell.tsx +169 -0
  304. package/src/internal/__tests__/DialogShell.test.tsx +223 -0
  305. package/src/internal/element-resets.ts +33 -0
  306. package/src/internal/file-tree/FileTreeNode.tsx +2 -1
  307. package/src/internal/markdown-components.tsx +15 -5
  308. package/src/invitation/InvitationManager.tsx +3 -2
  309. package/src/manifest/ApplyManifestDialog.tsx +10 -27
  310. package/src/manifest/EditResourceYamlDialog.tsx +4 -31
  311. package/src/mcp-server/McpServerConnectDialog.tsx +15 -29
  312. package/src/mcp-server/McpServerDetailView.tsx +12 -24
  313. package/src/mcp-server/steps/IdentityTransportStep.tsx +3 -2
  314. package/src/platform-client/CreatePlatformClientForm.tsx +4 -3
  315. package/src/platform-client/PlatformClientDetailPanel.tsx +4 -3
  316. package/src/pricing-governance/BaselineEditor.tsx +3 -2
  317. package/src/pricing-governance/PricingGovernanceConsole.tsx +2 -1
  318. package/src/provider-standing/ProviderStandingAccessNotice.tsx +36 -0
  319. package/src/provider-standing/ProviderStandingConsole.tsx +216 -0
  320. package/src/provider-standing/__tests__/ProviderStandingConsole.test.tsx +143 -0
  321. package/src/provider-standing/index.ts +8 -0
  322. package/src/provider-standing/useProviderStanding.ts +50 -0
  323. package/src/provider.tsx +12 -0
  324. package/src/resource-creation/StepIndicator.tsx +2 -1
  325. package/src/resource-detail/ConfirmDialog.tsx +9 -30
  326. package/src/schedule/ScheduleDetailView.tsx +3 -2
  327. package/src/schedule/ScheduleRunsTable.tsx +2 -1
  328. package/src/session/__tests__/UsageTab.test.tsx +136 -0
  329. package/src/session/__tests__/useSessionUsage.test.ts +19 -0
  330. package/src/session/facets/ArtifactsTab.tsx +2 -1
  331. package/src/session/facets/ChangesTab.tsx +2 -1
  332. package/src/session/facets/UsageTab.tsx +98 -6
  333. package/src/session/index.ts +1 -0
  334. package/src/session/useSessionUsage.ts +37 -0
  335. package/src/settings/__tests__/useSettingsNavGroups.test.tsx +11 -1
  336. package/src/settings/settings-nav.ts +7 -0
  337. package/src/settings/useSettingsNavGroups.ts +8 -1
  338. package/src/sharing/ShareAgentDialog.tsx +9 -30
  339. package/src/sidebar/WorkspaceSidebar.tsx +2 -1
  340. package/src/skill/SkillDiffDialog.tsx +13 -36
  341. package/src/skill/SkillFileBrowser.tsx +2 -1
  342. package/src/skill/__tests__/SkillFileBrowser.test.tsx +10 -2
  343. package/src/skill/__tests__/fetchAndUnpackArtifact.test.ts +90 -0
  344. package/src/skill/__tests__/useSkillUpload.test.ts +69 -0
  345. package/src/skill/internal/fetchAndUnpackArtifact.ts +54 -4
  346. package/src/skill/useSkillDiff.ts +7 -1
  347. package/src/skill/useSkillUpload.ts +25 -6
  348. package/src/workflow/FailedRunsWidget.tsx +2 -1
  349. package/src/workflow/PendingApprovalsWidget.tsx +2 -1
  350. package/src/workflow/ViewYamlDialog.tsx +18 -37
  351. package/src/workflow/WorkflowArchitectDialog.tsx +11 -43
  352. package/src/workflow/WorkflowExplainDialog.tsx +11 -37
  353. package/src/workflow/WorkflowGraphFullscreenDialog.tsx +14 -26
  354. package/src/workflow/WorkflowRunDialog.tsx +21 -48
  355. package/src/workflow/execution-comparison/ExecutionComparisonPicker.tsx +14 -31
  356. package/src/workflow/facets/WorkflowArtifactsTab.tsx +2 -1
  357. package/src/workflow/facets/WorkflowUsageTab.tsx +2 -1
  358. package/src/workflow/inspector/WorkflowSummaryPanel.tsx +2 -1
  359. package/src/workflow/inspector/tabs/BranchesTab.tsx +2 -1
  360. package/src/workflow/inspector/tabs/IterationTab.tsx +2 -1
  361. package/src/workflow/instance/CreateWorkflowInstanceDialog.tsx +14 -27
  362. package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +2 -1
  363. package/src/workflow/templates/WorkflowTemplatePreview.tsx +18 -28
  364. package/src/workspace/ExplorerTree.tsx +2 -1
  365. package/src/workspace/WorkspaceContentSearch.tsx +2 -1
  366. package/src/workspace/WorkspaceFileSearch.tsx +2 -1
  367. package/src/workspace/WorkspaceSummary.tsx +2 -1
  368. package/styles.css +1 -1
  369. package/workflow/FailedRunsWidget.d.ts.map +1 -1
  370. package/workflow/FailedRunsWidget.js +2 -1
  371. package/workflow/FailedRunsWidget.js.map +1 -1
  372. package/workflow/PendingApprovalsWidget.d.ts.map +1 -1
  373. package/workflow/PendingApprovalsWidget.js +2 -1
  374. package/workflow/PendingApprovalsWidget.js.map +1 -1
  375. package/workflow/ViewYamlDialog.d.ts.map +1 -1
  376. package/workflow/ViewYamlDialog.js +10 -29
  377. package/workflow/ViewYamlDialog.js.map +1 -1
  378. package/workflow/WorkflowArchitectDialog.d.ts.map +1 -1
  379. package/workflow/WorkflowArchitectDialog.js +5 -24
  380. package/workflow/WorkflowArchitectDialog.js.map +1 -1
  381. package/workflow/WorkflowExplainDialog.d.ts.map +1 -1
  382. package/workflow/WorkflowExplainDialog.js +5 -21
  383. package/workflow/WorkflowExplainDialog.js.map +1 -1
  384. package/workflow/WorkflowGraphFullscreenDialog.d.ts.map +1 -1
  385. package/workflow/WorkflowGraphFullscreenDialog.js +11 -17
  386. package/workflow/WorkflowGraphFullscreenDialog.js.map +1 -1
  387. package/workflow/WorkflowRunDialog.d.ts.map +1 -1
  388. package/workflow/WorkflowRunDialog.js +13 -29
  389. package/workflow/WorkflowRunDialog.js.map +1 -1
  390. package/workflow/execution-comparison/ExecutionComparisonPicker.d.ts.map +1 -1
  391. package/workflow/execution-comparison/ExecutionComparisonPicker.js +8 -26
  392. package/workflow/execution-comparison/ExecutionComparisonPicker.js.map +1 -1
  393. package/workflow/facets/WorkflowArtifactsTab.d.ts.map +1 -1
  394. package/workflow/facets/WorkflowArtifactsTab.js +2 -1
  395. package/workflow/facets/WorkflowArtifactsTab.js.map +1 -1
  396. package/workflow/facets/WorkflowUsageTab.d.ts.map +1 -1
  397. package/workflow/facets/WorkflowUsageTab.js +2 -1
  398. package/workflow/facets/WorkflowUsageTab.js.map +1 -1
  399. package/workflow/inspector/WorkflowSummaryPanel.d.ts.map +1 -1
  400. package/workflow/inspector/WorkflowSummaryPanel.js +2 -1
  401. package/workflow/inspector/WorkflowSummaryPanel.js.map +1 -1
  402. package/workflow/inspector/tabs/BranchesTab.d.ts.map +1 -1
  403. package/workflow/inspector/tabs/BranchesTab.js +2 -1
  404. package/workflow/inspector/tabs/BranchesTab.js.map +1 -1
  405. package/workflow/inspector/tabs/IterationTab.d.ts.map +1 -1
  406. package/workflow/inspector/tabs/IterationTab.js +2 -1
  407. package/workflow/inspector/tabs/IterationTab.js.map +1 -1
  408. package/workflow/instance/CreateWorkflowInstanceDialog.d.ts.map +1 -1
  409. package/workflow/instance/CreateWorkflowInstanceDialog.js +7 -20
  410. package/workflow/instance/CreateWorkflowInstanceDialog.js.map +1 -1
  411. package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
  412. package/workflow/instance/WorkflowInstanceDetailPanel.js +2 -1
  413. package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
  414. package/workflow/templates/WorkflowTemplatePreview.d.ts +1 -1
  415. package/workflow/templates/WorkflowTemplatePreview.d.ts.map +1 -1
  416. package/workflow/templates/WorkflowTemplatePreview.js +10 -22
  417. package/workflow/templates/WorkflowTemplatePreview.js.map +1 -1
  418. package/workspace/ExplorerTree.d.ts.map +1 -1
  419. package/workspace/ExplorerTree.js +2 -1
  420. package/workspace/ExplorerTree.js.map +1 -1
  421. package/workspace/WorkspaceContentSearch.d.ts.map +1 -1
  422. package/workspace/WorkspaceContentSearch.js +2 -1
  423. package/workspace/WorkspaceContentSearch.js.map +1 -1
  424. package/workspace/WorkspaceFileSearch.d.ts.map +1 -1
  425. package/workspace/WorkspaceFileSearch.js +2 -1
  426. package/workspace/WorkspaceFileSearch.js.map +1 -1
  427. package/workspace/WorkspaceSummary.d.ts.map +1 -1
  428. package/workspace/WorkspaceSummary.js +2 -1
  429. package/workspace/WorkspaceSummary.js.map +1 -1
@@ -3,6 +3,7 @@
3
3
  import { useCallback, useMemo, useState } from "react";
4
4
  import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
5
5
  import { cn } from "@stigmer/theme";
6
+ import { UNSTYLED_LIST } from "../internal/element-resets.js";
6
7
  import {
7
8
  useSessionArtifacts,
8
9
  artifactKey,
@@ -116,7 +117,7 @@ export function ArtifactsWidget({
116
117
  </span>
117
118
  </div>
118
119
 
119
- <ul role="list" className="stg:flex stg:flex-col">
120
+ <ul role="list" className={cn(UNSTYLED_LIST, "stg:flex stg:flex-col")}>
120
121
  {artifacts.map((entry) => (
121
122
  <ArtifactRow
122
123
  key={artifactKey(entry.artifact)}
@@ -3,6 +3,7 @@
3
3
  import { memo, useState } from "react";
4
4
  import type { FileChangeProgress } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/filereview_pb";
5
5
  import { cn } from "@stigmer/theme";
6
+ import { UNSTYLED_LIST } from "../internal/element-resets.js";
6
7
  import { FileKindBadge, FileLineStats } from "./FileReviewAtoms.js";
7
8
  import { FilePathLink } from "./FilePathLink.js";
8
9
 
@@ -91,7 +92,7 @@ export const FileChangeProgressBar = memo(function FileChangeProgressBar({
91
92
  <FileLineStats linesAdded={linesAdded} linesRemoved={linesRemoved} />
92
93
  </div>
93
94
  {expanded && (
94
- <ul className="stg:mt-2 stg:max-h-[30vh] stg:space-y-1 stg:overflow-y-auto">
95
+ <ul className={cn(UNSTYLED_LIST, "stg:mt-2 stg:max-h-[30vh] stg:space-y-1 stg:overflow-y-auto")}>
95
96
  {entries.map((entry) => {
96
97
  const path = entry.pathAfter || entry.pathBefore;
97
98
  return (
@@ -4,6 +4,7 @@ import { useMemo, type ComponentType } from "react";
4
4
  import type { TodoItem } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/todo_pb";
5
5
  import { TodoStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
6
6
  import { cn } from "@stigmer/theme";
7
+ import { UNSTYLED_LIST } from "../internal/element-resets.js";
7
8
 
8
9
  /** Props for {@link TodoList}. */
9
10
  export interface TodoListProps {
@@ -69,7 +70,7 @@ export function TodoList({
69
70
  return (
70
71
  <ul
71
72
  role="list"
72
- className={cn("stg:flex stg:flex-col stg:gap-1", className)}
73
+ className={cn(UNSTYLED_LIST, "stg:flex stg:flex-col stg:gap-1", className)}
73
74
  aria-label="Tasks"
74
75
  >
75
76
  {sortedTodos.map((item) => (
@@ -105,7 +105,9 @@ export interface ToolCallItemProps {
105
105
  *
106
106
  * Shows category-aware labels (e.g., "Shell", "Read", "Edit") with
107
107
  * the primary argument as a subtitle, a category-specific icon, and
108
- * an inline approval decision badge when applicable.
108
+ * an inline approval decision badge when applicable. A shell row whose
109
+ * call carries a model-authored intent phrase is titled with that phrase
110
+ * instead — the command becomes the subtitle (stigmer#276).
109
111
  *
110
112
  * Wrapped in `React.memo` — structural sharing (DD-009/010) preserves
111
113
  * the `ToolCall` reference when unchanged, so a settled row skips
@@ -138,7 +140,7 @@ export const ToolCallItem = memo(function ToolCallItem({
138
140
  const duration = formatHeaderDuration(toolCall.startedAt, toolCall.completedAt);
139
141
  const isSubAgent = subAgentExecution != null;
140
142
 
141
- const { category, label, primaryArg, result, resultSummary, disclosure, chrome } =
143
+ const { category, label, intent, title, primaryArg, result, resultSummary, disclosure, chrome } =
142
144
  useToolPresentation(toolCall);
143
145
  const CategoryIcon = CATEGORY_ICON[category];
144
146
 
@@ -173,9 +175,12 @@ export const ToolCallItem = memo(function ToolCallItem({
173
175
  initialOpen: defaultExpanded || autoOpen,
174
176
  });
175
177
 
178
+ // Sub-agents title the row with their subject; every other row titles with
179
+ // the resolved presentation `title` (host label override > model-authored
180
+ // shell intent > category label, stigmer#276).
176
181
  const displayLabel = isSubAgent
177
182
  ? subAgentExecution.subject || subAgentExecution.name || label
178
- : label;
183
+ : title;
179
184
 
180
185
  const approvalBadge = getApprovalBadge(toolCall);
181
186
 
@@ -308,11 +313,17 @@ export const ToolCallItem = memo(function ToolCallItem({
308
313
  );
309
314
  }
310
315
 
311
- // Shell shows neither a command subtitle nor an exit summary in the header —
312
- // both live in the terminal session body below, so the header stays minimal
313
- // (icon + label + status + duration).
314
- const displaySubtitle =
315
- isSubAgent || category === "shell" ? null : primaryArg;
316
+ // Shell headers stay minimal (icon + label + status + duration) the
317
+ // command and exit summary live in the terminal session body EXCEPT when
318
+ // the model authored an intent title (stigmer#276): the title then says
319
+ // *why*, so the command surfaces as the secondary text and a fully
320
+ // collapsed row still reads like a narrated log. Intent-less shell rows
321
+ // render byte-identically to before.
322
+ const displaySubtitle = isSubAgent
323
+ ? null
324
+ : category === "shell"
325
+ ? (intent ? primaryArg : null)
326
+ : primaryArg;
316
327
 
317
328
  // For file tools the subtitle is a path: render it filename-first through
318
329
  // FilePathLink (full path on hover) rather than the raw, often-absolute string
@@ -2,6 +2,7 @@
2
2
 
3
3
  import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
4
4
  import { cn } from "@stigmer/theme";
5
+ import { UNSTYLED_LIST } from "../internal/element-resets.js";
5
6
  import { useSessionWriteBacks } from "../session/useSessionWriteBacks.js";
6
7
  import { WriteBackCard } from "./WriteBackCard.js";
7
8
 
@@ -71,7 +72,7 @@ export function WriteBacksWidget({
71
72
  </span>
72
73
  </div>
73
74
 
74
- <ul role="list" className="stg:flex stg:flex-col stg:gap-3">
75
+ <ul role="list" className={cn(UNSTYLED_LIST, "stg:flex stg:flex-col stg:gap-3")}>
75
76
  {writeBacks.map((entry) => (
76
77
  <li key={entry.writeBack.workspaceEntryName}>
77
78
  <WriteBackCard writeBack={entry.writeBack} />
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Model-authored intent titles for shell tool calls (stigmer#276).
3
+ *
4
+ * The extraction contract is pinned by the cross-surface fixture
5
+ * test/fixtures/tool-view/intent-title.json — the same file the runner's
6
+ * tool-intent middleware tests assert against, so the wire key and the
7
+ * kind-scoping can never drift between the writer and the readers.
8
+ */
9
+
10
+ import { readFileSync } from "node:fs";
11
+ import { dirname, resolve } from "node:path";
12
+ import { fileURLToPath } from "node:url";
13
+ import { describe, it, expect, afterEach } from "vitest";
14
+ import { render, screen, cleanup } from "@testing-library/react";
15
+ import { renderHook } from "@testing-library/react";
16
+ import { create, type JsonObject } from "@bufbuild/protobuf";
17
+ import {
18
+ ToolCallSchema,
19
+ type ToolCall,
20
+ } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
21
+ import { PendingApprovalSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/approval_pb";
22
+ import { ToolCallStatus, ToolKind } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
23
+ import {
24
+ extractShellIntent,
25
+ extractShellIntentFromPreview,
26
+ SHELL_INTENT_ARG_FIELD,
27
+ } from "../tool-categories";
28
+ import { useToolPresentation, registerToolPresenter } from "../tool-presenter";
29
+ import { ToolCallItem } from "../ToolCallItem";
30
+ import { ApprovalCardHeader } from "../ApprovalCard";
31
+
32
+ afterEach(cleanup);
33
+
34
+ const here = dirname(fileURLToPath(import.meta.url));
35
+ const fixturePath = resolve(here, "../../../../../test/fixtures/tool-view/intent-title.json");
36
+
37
+ interface IntentFixture {
38
+ argField: string;
39
+ cases: Array<{
40
+ name: string;
41
+ mcpServerSlug: string;
42
+ args: Record<string, unknown>;
43
+ intent: string | null;
44
+ }>;
45
+ }
46
+
47
+ const fixture = JSON.parse(readFileSync(fixturePath, "utf8")) as IntentFixture;
48
+
49
+ function makeToolCall(opts: {
50
+ name: string;
51
+ args?: Record<string, unknown>;
52
+ mcpServerSlug?: string;
53
+ status?: ToolCallStatus;
54
+ }): ToolCall {
55
+ return create(ToolCallSchema, {
56
+ id: opts.name,
57
+ name: opts.name,
58
+ args: (opts.args ?? {}) as JsonObject,
59
+ mcpServerSlug: opts.mcpServerSlug ?? "",
60
+ status: opts.status ?? ToolCallStatus.TOOL_CALL_COMPLETED,
61
+ });
62
+ }
63
+
64
+ describe("intent-title fixture contract", () => {
65
+ it("pins the wire key shared with the runner middleware", () => {
66
+ expect(SHELL_INTENT_ARG_FIELD).toBe(fixture.argField);
67
+ });
68
+
69
+ it.each(fixture.cases.map((c, i) => [i, c] as const))(
70
+ "case %#: %j",
71
+ (_i, c) => {
72
+ const tc = makeToolCall({
73
+ name: c.name,
74
+ args: c.args,
75
+ mcpServerSlug: c.mcpServerSlug,
76
+ });
77
+ expect(extractShellIntent(tc)).toBe(c.intent);
78
+ },
79
+ );
80
+ });
81
+
82
+ describe("extractShellIntentFromPreview", () => {
83
+ it("mirrors the ToolCall extraction on a JSON args preview", () => {
84
+ expect(
85
+ extractShellIntentFromPreview(
86
+ "execute",
87
+ JSON.stringify({ command: "make check", [SHELL_INTENT_ARG_FIELD]: "Verify the build" }),
88
+ ),
89
+ ).toBe("Verify the build");
90
+ });
91
+
92
+ it("prefers the denormalized wire kind over the name", () => {
93
+ // A shell tool whose NAME the classifier does not recognize still
94
+ // resolves via the wire kind — matching extractPrimaryArgFromPreview.
95
+ expect(
96
+ extractShellIntentFromPreview(
97
+ "custom_runner",
98
+ JSON.stringify({ command: "ls", [SHELL_INTENT_ARG_FIELD]: "List files" }),
99
+ "",
100
+ ToolKind.SHELL,
101
+ ),
102
+ ).toBe("List files");
103
+ });
104
+
105
+ it("returns null for malformed previews and non-shell kinds", () => {
106
+ expect(extractShellIntentFromPreview("execute", "not json{")).toBeNull();
107
+ expect(extractShellIntentFromPreview("execute", "")).toBeNull();
108
+ expect(
109
+ extractShellIntentFromPreview(
110
+ "read_file",
111
+ JSON.stringify({ file_path: "a", [SHELL_INTENT_ARG_FIELD]: "x" }),
112
+ ),
113
+ ).toBeNull();
114
+ });
115
+ });
116
+
117
+ describe("useToolPresentation title precedence", () => {
118
+ it("titles a shell row with the model-authored intent", () => {
119
+ const tc = makeToolCall({
120
+ name: "Shell",
121
+ args: { command: "npm test", [SHELL_INTENT_ARG_FIELD]: "Run the test suite" },
122
+ });
123
+ const { result } = renderHook(() => useToolPresentation(tc));
124
+
125
+ expect(result.current.intent).toBe("Run the test suite");
126
+ expect(result.current.title).toBe("Run the test suite");
127
+ // The short kind label is unchanged — chips and badges keep "Shell".
128
+ expect(result.current.label).toBe("Shell");
129
+ });
130
+
131
+ it("falls back to the category label when no intent is present", () => {
132
+ const tc = makeToolCall({ name: "Shell", args: { command: "ls" } });
133
+ const { result } = renderHook(() => useToolPresentation(tc));
134
+
135
+ expect(result.current.intent).toBeNull();
136
+ expect(result.current.title).toBe("Shell");
137
+ });
138
+
139
+ it("a registered presenter label override outranks the intent", () => {
140
+ const dispose = registerToolPresenter(ToolKind.SHELL, {
141
+ label: () => "Run command",
142
+ });
143
+ try {
144
+ const tc = makeToolCall({
145
+ name: "Shell",
146
+ args: { command: "ls", [SHELL_INTENT_ARG_FIELD]: "List files" },
147
+ });
148
+ const { result } = renderHook(() => useToolPresentation(tc));
149
+
150
+ expect(result.current.title).toBe("Run command");
151
+ expect(result.current.intent).toBe("List files");
152
+ } finally {
153
+ dispose();
154
+ }
155
+ });
156
+ });
157
+
158
+ describe("ToolCallItem shell header", () => {
159
+ function headerOf(container: HTMLElement): Element {
160
+ const row = container.querySelector('[data-cursor-target="tool-call-row"]')!;
161
+ return row.firstElementChild!;
162
+ }
163
+
164
+ it("renders the intent as the title and the command as the subtitle", () => {
165
+ const tc = makeToolCall({
166
+ name: "Shell",
167
+ args: {
168
+ command: "npx vitest run src/parser",
169
+ [SHELL_INTENT_ARG_FIELD]: "Run unit tests for the parser",
170
+ },
171
+ });
172
+ const { container } = render(<ToolCallItem toolCall={tc} />);
173
+
174
+ const header = headerOf(container);
175
+ expect(header.textContent).toContain("Run unit tests for the parser");
176
+ expect(header.textContent).toContain("npx vitest run src/parser");
177
+ expect(header.textContent).not.toContain("Shell");
178
+ });
179
+
180
+ it("renders an intent-less shell row exactly as before: bare label, no subtitle", () => {
181
+ const tc = makeToolCall({
182
+ name: "Shell",
183
+ args: { command: "ls -la" },
184
+ });
185
+ const { container } = render(<ToolCallItem toolCall={tc} />);
186
+
187
+ const header = headerOf(container);
188
+ expect(header.textContent).toContain("Shell");
189
+ // The command lives in the terminal body only — never in the header.
190
+ expect(header.textContent).not.toContain("ls -la");
191
+ });
192
+ });
193
+
194
+ describe("ApprovalCardHeader shell title", () => {
195
+ it("titles a gated shell call with the intent phrase", () => {
196
+ const pending = create(PendingApprovalSchema, {
197
+ toolCallId: "tc-1",
198
+ toolName: "execute",
199
+ toolKind: ToolKind.SHELL,
200
+ argsPreview: JSON.stringify({
201
+ command: "rm -rf build",
202
+ [SHELL_INTENT_ARG_FIELD]: "Clean the build directory",
203
+ }),
204
+ });
205
+ render(<ApprovalCardHeader pendingApproval={pending} />);
206
+
207
+ expect(screen.getByText("Clean the build directory")).toBeDefined();
208
+ });
209
+
210
+ it("keeps the bare category label when no intent is present", () => {
211
+ const pending = create(PendingApprovalSchema, {
212
+ toolCallId: "tc-2",
213
+ toolName: "execute",
214
+ toolKind: ToolKind.SHELL,
215
+ argsPreview: JSON.stringify({ command: "rm -rf build" }),
216
+ });
217
+ render(<ApprovalCardHeader pendingApproval={pending} />);
218
+
219
+ expect(screen.getByText("Shell")).toBeDefined();
220
+ });
221
+ });
@@ -340,6 +340,9 @@ export {
340
340
  toolKindToCategoryInfo,
341
341
  extractPrimaryArg,
342
342
  extractPrimaryArgFromPreview,
343
+ extractShellIntent,
344
+ extractShellIntentFromPreview,
345
+ SHELL_INTENT_ARG_FIELD,
343
346
  humanizeToolName,
344
347
  defaultDisclosureForCategory,
345
348
  isRunGroupableCategory,
@@ -1,16 +1,22 @@
1
1
  import type { ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
2
2
  import { ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
3
3
  import type { JsonObject } from "@bufbuild/protobuf";
4
- import { ToolKind, resolveToolKind, resolveToolKindByName } from "@stigmer/sdk";
4
+ import {
5
+ ToolKind,
6
+ resolveToolKind,
7
+ resolveToolKindByName,
8
+ shellIntentFromArgs,
9
+ } from "@stigmer/sdk";
5
10
 
6
11
  /**
7
12
  * Discriminated tool categories for type-aware rendering.
8
13
  *
9
14
  * This is the presentation taxonomy. Classification (name -> kind) lives in
10
15
  * `@stigmer/sdk`'s `resolveToolKind` (single source of truth, shared with the
11
- * runner and Go CLI); this file maps each {@link ToolKind} to its presentation
12
- * metadata (label, primary argument). `"mcp"` covers tools originating from an
13
- * MCP server, whose names are dynamic.
16
+ * runner, @stigmer/ink, and the CLI's headless renderers); this file maps each
17
+ * {@link ToolKind} to its presentation metadata (label, primary argument).
18
+ * `"mcp"` covers tools originating from an MCP server, whose names are
19
+ * dynamic.
14
20
  */
15
21
  export type ToolCategory =
16
22
  | "shell"
@@ -192,6 +198,14 @@ export interface ToolCategoryInfo {
192
198
  readonly primaryArgField: string;
193
199
  /** Fallback argument keys tried when the primary key is absent. */
194
200
  readonly fallbackArgFields: readonly string[];
201
+ /**
202
+ * JSON argument key carrying a model-authored intent phrase for this kind
203
+ * (stigmer#276), or `undefined` for kinds without one. Shell is the only
204
+ * carrier today: both harnesses converge on `description` — the Cursor
205
+ * harness's built-in Shell tool ships it natively, and the native harness's
206
+ * tool-intent middleware adds it to the `execute` schema at bind time.
207
+ */
208
+ readonly intentArgField?: string;
195
209
  }
196
210
 
197
211
  interface KindDisplayEntry {
@@ -199,6 +213,7 @@ interface KindDisplayEntry {
199
213
  readonly label: string;
200
214
  readonly primaryField: string;
201
215
  readonly fallbackFields?: readonly string[];
216
+ readonly intentField?: string;
202
217
  }
203
218
 
204
219
  // Presentation metadata per ToolKind. Classification (name -> kind) is owned by
@@ -209,7 +224,7 @@ const KIND_DISPLAY: Partial<Record<ToolKind, KindDisplayEntry>> = {
209
224
  [ToolKind.FILE_WRITE]: { category: "write", label: "Write", primaryField: "path", fallbackFields: ["file_path", "file", "filename"] },
210
225
  [ToolKind.FILE_EDIT]: { category: "edit", label: "Edit", primaryField: "path", fallbackFields: ["file_path", "file", "filename"] },
211
226
  [ToolKind.FILE_DELETE]: { category: "delete", label: "Delete", primaryField: "path", fallbackFields: ["file_path", "file", "filename"] },
212
- [ToolKind.SHELL]: { category: "shell", label: "Shell", primaryField: "command" },
227
+ [ToolKind.SHELL]: { category: "shell", label: "Shell", primaryField: "command", intentField: "description" },
213
228
  [ToolKind.SEARCH]: { category: "search", label: "Search", primaryField: "pattern", fallbackFields: ["query", "q"] },
214
229
  [ToolKind.LIST]: { category: "list", label: "List", primaryField: "path" },
215
230
  [ToolKind.FETCH]: { category: "fetch", label: "Fetch", primaryField: "url", fallbackFields: ["uri"] },
@@ -264,6 +279,7 @@ export function toolKindToCategoryInfo(
264
279
  label: entry.label,
265
280
  primaryArgField: entry.primaryField,
266
281
  fallbackArgFields: entry.fallbackFields ?? [],
282
+ ...(entry.intentField ? { intentArgField: entry.intentField } : {}),
267
283
  };
268
284
  }
269
285
 
@@ -440,6 +456,88 @@ export function extractPrimaryArgFromPreview(
440
456
  }
441
457
  }
442
458
 
459
+ /**
460
+ * Extracts the model-authored intent phrase from a tool call's args
461
+ * (stigmer#276), or `null` when the kind carries none / the model omitted it.
462
+ *
463
+ * The intent is presentation metadata authored by the model *for the user* —
464
+ * "Run unit tests for the parser" — rendered as the row title in place of the
465
+ * bare category label. Extraction is kind-scoped via
466
+ * {@link ToolCategoryInfo.intentArgField} (shell-only today) so a same-named
467
+ * REAL argument on another kind (e.g. the sub-agent task tool's
468
+ * `description`, which is its subject) is never misread as an intent.
469
+ */
470
+ export function extractIntent(toolCall: ToolCall): string | null {
471
+ const info = resolveToolCategoryFromCall(toolCall);
472
+ if (!info.intentArgField || !toolCall.args) return null;
473
+ const value = toolCall.args[info.intentArgField];
474
+ return typeof value === "string" && value.length > 0 ? value : null;
475
+ }
476
+
477
+ /**
478
+ * {@link extractIntent} for surfaces that carry a JSON `argsPreview` string
479
+ * instead of a full {@link ToolCall} — notably `PendingApproval`. Same
480
+ * kind-scoping; returns `null` on parse failure or when absent.
481
+ */
482
+ export function extractIntentFromPreview(
483
+ toolName: string,
484
+ argsPreview: string,
485
+ mcpServerSlug?: string,
486
+ toolKind?: ToolKind,
487
+ ): string | null {
488
+ if (!argsPreview) return null;
489
+
490
+ const info =
491
+ toolKind !== undefined
492
+ ? resolveToolCategoryFromKind(toolKind, toolName, mcpServerSlug)
493
+ : resolveToolCategory(toolName, mcpServerSlug);
494
+ if (!info.intentArgField) return null;
495
+
496
+ try {
497
+ const parsed = JSON.parse(argsPreview);
498
+ if (typeof parsed !== "object" || parsed === null) return null;
499
+ const value = (parsed as Record<string, unknown>)[info.intentArgField];
500
+ return typeof value === "string" && value.length > 0 ? value : null;
501
+ } catch {
502
+ return null;
503
+ }
504
+ }
505
+
506
+ // Intent-title extraction lives in @stigmer/sdk's tool-view module — the
507
+ // cross-surface single source of truth the intent-title.json fixture pins —
508
+ // so React, Ink, and the CLI's headless renderers share one implementation.
509
+ // Re-exported here because this module is where React's public tool-view API
510
+ // surfaced them first (#677).
511
+ export { SHELL_INTENT_ARG_FIELD, extractShellIntent } from "@stigmer/sdk";
512
+
513
+ /**
514
+ * Preview-string twin of {@link extractShellIntent} for surfaces that carry a
515
+ * `PendingApproval` (JSON `argsPreview`) instead of a full {@link ToolCall} —
516
+ * mirrors {@link extractPrimaryArgFromPreview}'s kind resolution.
517
+ */
518
+ export function extractShellIntentFromPreview(
519
+ toolName: string,
520
+ argsPreview: string,
521
+ mcpServerSlug?: string,
522
+ toolKind?: ToolKind,
523
+ ): string | null {
524
+ if (!argsPreview) return null;
525
+
526
+ const kind =
527
+ toolKind !== undefined && toolKind !== ToolKind.UNSPECIFIED
528
+ ? toolKind
529
+ : resolveToolKindByName(toolName, mcpServerSlug);
530
+ if (kind !== ToolKind.SHELL) return null;
531
+
532
+ try {
533
+ const parsed = JSON.parse(argsPreview);
534
+ if (typeof parsed !== "object" || parsed === null) return null;
535
+ return shellIntentFromArgs(kind, parsed as JsonObject);
536
+ } catch {
537
+ return null;
538
+ }
539
+ }
540
+
443
541
  const WRITE_CONTENT_FIELDS = [
444
542
  "contents",
445
543
  "content",
@@ -19,6 +19,7 @@ import type { ToolResultView } from "@stigmer/sdk";
19
19
  import {
20
20
  resolveToolCategoryFromCall,
21
21
  extractPrimaryArg,
22
+ extractShellIntent,
22
23
  defaultChromeForCategory,
23
24
  defaultDisclosureForCategory,
24
25
  isRunGroupableCategory,
@@ -124,6 +125,21 @@ export interface ToolPresentation {
124
125
  readonly category: ToolCategory;
125
126
  /** Display label, e.g. "Edit", "Shell". */
126
127
  readonly label: string;
128
+ /**
129
+ * The model-authored intent phrase for a SHELL call (stigmer#276), or null
130
+ * when absent (legacy executions, skipped optional arg, non-shell kinds).
131
+ * Raw extraction — precedence against overrides is resolved in
132
+ * {@link ToolPresentation.title}.
133
+ */
134
+ readonly intent: string | null;
135
+ /**
136
+ * The row title: a registered presenter's `label` override wins (a host's
137
+ * explicit wording is never displaced by model output), then the
138
+ * model-authored {@link intent}, then the category {@link label}. Renderers
139
+ * that title a row use this; {@link label} stays the short kind label for
140
+ * chips and badges.
141
+ */
142
+ readonly title: string;
127
143
  /** Primary argument (path, command, pattern...), or null. */
128
144
  readonly primaryArg: string | null;
129
145
  /** Normalized result view for rendering with {@link ResultView}. */
@@ -166,7 +182,10 @@ export function useToolPresentation(toolCall: ToolCall): ToolPresentation {
166
182
  const result = normalizeToolResult(toolCall);
167
183
  const override = registry.get(kind);
168
184
 
169
- const label = override?.label?.(toolCall) ?? categoryInfo.label;
185
+ const overrideLabel = override?.label?.(toolCall);
186
+ const label = overrideLabel ?? categoryInfo.label;
187
+ const intent = extractShellIntent(toolCall);
188
+ const title = overrideLabel ?? intent ?? categoryInfo.label;
170
189
  const resultSummary =
171
190
  override?.summary?.(toolCall, result) ?? summarizeResultView(result);
172
191
  const disclosure =
@@ -183,6 +202,8 @@ export function useToolPresentation(toolCall: ToolCall): ToolPresentation {
183
202
  kind,
184
203
  category: categoryInfo.category,
185
204
  label,
205
+ intent,
206
+ title,
186
207
  primaryArg: extractPrimaryArg(toolCall),
187
208
  result,
188
209
  resultSummary,
@@ -4,6 +4,7 @@ import { useCallback, useState } from "react";
4
4
  import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
5
5
  import type { PrincipalAccess } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/io_pb";
6
6
  import { cn } from "@stigmer/theme";
7
+ import { UNSTYLED_LIST } from "../internal/element-resets.js";
7
8
  import { getUserMessage } from "@stigmer/sdk";
8
9
  import { useShareFlow, type ShareFlowResource } from "./useShareFlow.js";
9
10
  import { GrantAccessForm } from "./GrantAccessForm.js";
@@ -83,7 +84,7 @@ export function PeopleWithAccess({
83
84
  )}
84
85
 
85
86
  {!isLoading && accessList.length > 0 && (
86
- <ul className="stg:space-y-1 stg:mt-2" aria-label="People with access">
87
+ <ul className={cn(UNSTYLED_LIST, "stg:space-y-1 stg:mt-2")} aria-label="People with access">
87
88
  {accessList.map((entry) => (
88
89
  <AccessEntry
89
90
  key={entry.principal?.id ?? "unknown"}
@@ -3,6 +3,7 @@
3
3
  import { useCallback, useId, useMemo, useRef, useState } from "react";
4
4
  import type { ApiResourceRefView } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/io_pb";
5
5
  import { cn } from "@stigmer/theme";
6
+ import { UNSTYLED_LIST } from "../internal/element-resets.js";
6
7
  import { getUserMessage } from "@stigmer/sdk";
7
8
  import { useResourceAccess } from "./useResourceAccess.js";
8
9
  import { ProviderBadge, providerLabel } from "./ProviderBadge.js";
@@ -238,6 +239,7 @@ export function PrincipalPicker({
238
239
  role="listbox"
239
240
  aria-label="Organization members"
240
241
  className={cn(
242
+ UNSTYLED_LIST,
241
243
  "stg:absolute stg:z-10 stg:mt-1 stg:max-h-56 stg:w-full stg:overflow-auto stg:rounded-md stg:border stg:border-border stg:bg-popover stg:py-1 stg:shadow-md",
242
244
  )}
243
245
  >
@@ -4,6 +4,7 @@ import { useId } from "react";
4
4
  import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
5
5
  import type { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
6
6
  import { cn } from "@stigmer/theme";
7
+ import { UNSTYLED_FIELDSET } from "../internal/element-resets.js";
7
8
  import { useRoleSelector } from "./useRoleSelector.js";
8
9
 
9
10
  /** Props for {@link RoleSelector}. */
@@ -73,7 +74,7 @@ export function RoleSelector({
73
74
  }
74
75
 
75
76
  return (
76
- <fieldset className={cn("stg:space-y-1.5", className)}>
77
+ <fieldset className={cn(UNSTYLED_FIELDSET, "stg:space-y-1.5", className)}>
77
78
  <legend className="stg:text-xs stg:font-medium stg:text-foreground">Role</legend>
78
79
  <div className="stg:flex stg:flex-wrap stg:gap-2">
79
80
  {options.map((opt) => {
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { type FormEvent, useCallback, useId, useState } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
+ import { UNSTYLED_FIELDSET } from "../internal/element-resets.js";
5
6
  import { getUserMessage } from "@stigmer/sdk";
6
7
  import type { IdentityProvider } from "@stigmer/protos/ai/stigmer/iam/identityprovider/v1/api_pb";
7
8
  import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
@@ -388,7 +389,7 @@ function JitSection({
388
389
  }
389
390
 
390
391
  return (
391
- <fieldset className="stg:space-y-2.5" disabled={disabled}>
392
+ <fieldset className={cn(UNSTYLED_FIELDSET, "stg:space-y-2.5")} disabled={disabled}>
392
393
  <hr className="stg:border-border-muted" />
393
394
  <legend className="stg:text-xs stg:font-medium stg:text-foreground">
394
395
  JIT provisioning
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { type FormEvent, useCallback, useId, useRef, useState } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
+ import { UNSTYLED_FIELDSET } from "../internal/element-resets.js";
5
6
  import { getUserMessage } from "@stigmer/sdk";
6
7
  import type { IdentityProvider } from "@stigmer/protos/ai/stigmer/iam/identityprovider/v1/api_pb";
7
8
  import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
@@ -674,7 +675,7 @@ function JitEditSection({
674
675
  }
675
676
 
676
677
  return (
677
- <fieldset className="stg:space-y-2.5" disabled={disabled}>
678
+ <fieldset className={cn(UNSTYLED_FIELDSET, "stg:space-y-2.5")} disabled={disabled}>
678
679
  <hr className="stg:border-border-muted" />
679
680
  <legend className="stg:text-xs stg:font-medium stg:text-foreground">
680
681
  JIT provisioning
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { type FormEvent, useCallback, useId, useState } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
+ import { UNSTYLED_FIELDSET } from "../internal/element-resets.js";
5
6
  import { getUserMessage } from "@stigmer/sdk";
6
7
  import type { IdentityProvider } from "@stigmer/protos/ai/stigmer/iam/identityprovider/v1/api_pb";
7
8
  import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
@@ -838,7 +839,7 @@ function JitProvisioningSection({
838
839
  }
839
840
 
840
841
  return (
841
- <fieldset className="stg:space-y-2.5" disabled={disabled}>
842
+ <fieldset className={cn(UNSTYLED_FIELDSET, "stg:space-y-2.5")} disabled={disabled}>
842
843
  <hr className="stg:border-border-muted" />
843
844
  <legend className="stg:text-xs stg:font-medium stg:text-foreground">
844
845
  JIT provisioning