@stigmer/react 3.0.9-dev.20260615153829 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/execution/ApprovalCard.d.ts +47 -3
  2. package/execution/ApprovalCard.d.ts.map +1 -1
  3. package/execution/ApprovalCard.js +138 -70
  4. package/execution/ApprovalCard.js.map +1 -1
  5. package/execution/ApprovalContext.d.ts +72 -0
  6. package/execution/ApprovalContext.d.ts.map +1 -0
  7. package/execution/ApprovalContext.js +41 -0
  8. package/execution/ApprovalContext.js.map +1 -0
  9. package/execution/ArtifactCard.d.ts.map +1 -1
  10. package/execution/ArtifactCard.js +3 -1
  11. package/execution/ArtifactCard.js.map +1 -1
  12. package/execution/ArtifactPreviewModal.d.ts.map +1 -1
  13. package/execution/ArtifactPreviewModal.js +5 -3
  14. package/execution/ArtifactPreviewModal.js.map +1 -1
  15. package/execution/EmptyChangeNotice.d.ts +38 -0
  16. package/execution/EmptyChangeNotice.d.ts.map +1 -0
  17. package/execution/EmptyChangeNotice.js +27 -0
  18. package/execution/EmptyChangeNotice.js.map +1 -0
  19. package/execution/FileChangesView.d.ts +81 -0
  20. package/execution/FileChangesView.d.ts.map +1 -0
  21. package/execution/FileChangesView.js +164 -0
  22. package/execution/FileChangesView.js.map +1 -0
  23. package/execution/FilePathLink.d.ts +24 -4
  24. package/execution/FilePathLink.d.ts.map +1 -1
  25. package/execution/FilePathLink.js +31 -9
  26. package/execution/FilePathLink.js.map +1 -1
  27. package/execution/FileReviewCard.d.ts +111 -0
  28. package/execution/FileReviewCard.d.ts.map +1 -0
  29. package/execution/FileReviewCard.js +558 -0
  30. package/execution/FileReviewCard.js.map +1 -0
  31. package/execution/FileReviewContext.d.ts +35 -0
  32. package/execution/FileReviewContext.d.ts.map +1 -0
  33. package/execution/FileReviewContext.js +23 -0
  34. package/execution/FileReviewContext.js.map +1 -0
  35. package/execution/FileReviewDock.d.ts +73 -0
  36. package/execution/FileReviewDock.d.ts.map +1 -0
  37. package/execution/FileReviewDock.js +65 -0
  38. package/execution/FileReviewDock.js.map +1 -0
  39. package/execution/McpToolDetail.d.ts.map +1 -1
  40. package/execution/McpToolDetail.js +38 -5
  41. package/execution/McpToolDetail.js.map +1 -1
  42. package/execution/MessageThread.d.ts +42 -3
  43. package/execution/MessageThread.d.ts.map +1 -1
  44. package/execution/MessageThread.js +263 -18
  45. package/execution/MessageThread.js.map +1 -1
  46. package/execution/PlanArtifactCard.d.ts.map +1 -1
  47. package/execution/PlanArtifactCard.js +3 -1
  48. package/execution/PlanArtifactCard.js.map +1 -1
  49. package/execution/PlanCompletionCard.d.ts +1 -1
  50. package/execution/PlanCompletionCard.js +1 -1
  51. package/execution/ResultView.d.ts +19 -1
  52. package/execution/ResultView.d.ts.map +1 -1
  53. package/execution/ResultView.js +141 -40
  54. package/execution/ResultView.js.map +1 -1
  55. package/execution/SubAgentSection.d.ts.map +1 -1
  56. package/execution/SubAgentSection.js +45 -6
  57. package/execution/SubAgentSection.js.map +1 -1
  58. package/execution/TerminalSession.d.ts +34 -0
  59. package/execution/TerminalSession.d.ts.map +1 -0
  60. package/execution/TerminalSession.js +34 -0
  61. package/execution/TerminalSession.js.map +1 -0
  62. package/execution/TodoCard.d.ts +53 -0
  63. package/execution/TodoCard.d.ts.map +1 -0
  64. package/execution/TodoCard.js +77 -0
  65. package/execution/TodoCard.js.map +1 -0
  66. package/execution/ToolArgsView.d.ts +7 -1
  67. package/execution/ToolArgsView.d.ts.map +1 -1
  68. package/execution/ToolArgsView.js +10 -9
  69. package/execution/ToolArgsView.js.map +1 -1
  70. package/execution/ToolCallDetail.d.ts +10 -1
  71. package/execution/ToolCallDetail.d.ts.map +1 -1
  72. package/execution/ToolCallDetail.js +66 -19
  73. package/execution/ToolCallDetail.js.map +1 -1
  74. package/execution/ToolCallGroup.d.ts +28 -18
  75. package/execution/ToolCallGroup.d.ts.map +1 -1
  76. package/execution/ToolCallGroup.js +39 -148
  77. package/execution/ToolCallGroup.js.map +1 -1
  78. package/execution/ToolCallItem.d.ts +36 -8
  79. package/execution/ToolCallItem.d.ts.map +1 -1
  80. package/execution/ToolCallItem.js +140 -21
  81. package/execution/ToolCallItem.js.map +1 -1
  82. package/execution/ToolRunGroup.d.ts +48 -0
  83. package/execution/ToolRunGroup.d.ts.map +1 -0
  84. package/execution/ToolRunGroup.js +168 -0
  85. package/execution/ToolRunGroup.js.map +1 -0
  86. package/execution/approval-provenance.d.ts +2 -0
  87. package/execution/approval-provenance.d.ts.map +1 -0
  88. package/execution/approval-provenance.js +6 -0
  89. package/execution/approval-provenance.js.map +1 -0
  90. package/execution/artifact-utils.d.ts +0 -10
  91. package/execution/artifact-utils.d.ts.map +1 -1
  92. package/execution/artifact-utils.js +0 -17
  93. package/execution/artifact-utils.js.map +1 -1
  94. package/execution/execution-phases.d.ts +1 -6
  95. package/execution/execution-phases.d.ts.map +1 -1
  96. package/execution/execution-phases.js +4 -14
  97. package/execution/execution-phases.js.map +1 -1
  98. package/execution/file-path-resolver.d.ts +28 -0
  99. package/execution/file-path-resolver.d.ts.map +1 -1
  100. package/execution/file-path-resolver.js +24 -0
  101. package/execution/file-path-resolver.js.map +1 -1
  102. package/execution/file-review-status.d.ts +127 -0
  103. package/execution/file-review-status.d.ts.map +1 -0
  104. package/execution/file-review-status.js +135 -0
  105. package/execution/file-review-status.js.map +1 -0
  106. package/execution/index.d.ts +39 -5
  107. package/execution/index.d.ts.map +1 -1
  108. package/execution/index.js +23 -3
  109. package/execution/index.js.map +1 -1
  110. package/execution/segment-tool-calls.d.ts +46 -0
  111. package/execution/segment-tool-calls.d.ts.map +1 -0
  112. package/execution/segment-tool-calls.js +71 -0
  113. package/execution/segment-tool-calls.js.map +1 -0
  114. package/execution/tool-categories.d.ts +62 -1
  115. package/execution/tool-categories.d.ts.map +1 -1
  116. package/execution/tool-categories.js +96 -2
  117. package/execution/tool-categories.js.map +1 -1
  118. package/execution/tool-presenter.d.ts +38 -2
  119. package/execution/tool-presenter.d.ts.map +1 -1
  120. package/execution/tool-presenter.js +23 -1
  121. package/execution/tool-presenter.js.map +1 -1
  122. package/execution/tool-rendering-primitives.d.ts.map +1 -1
  123. package/execution/tool-rendering-primitives.js +3 -2
  124. package/execution/tool-rendering-primitives.js.map +1 -1
  125. package/execution/useArtifactDownload.d.ts +44 -0
  126. package/execution/useArtifactDownload.d.ts.map +1 -0
  127. package/execution/useArtifactDownload.js +80 -0
  128. package/execution/useArtifactDownload.js.map +1 -0
  129. package/execution/useArtifactDownloadUrl.d.ts +67 -0
  130. package/execution/useArtifactDownloadUrl.d.ts.map +1 -0
  131. package/execution/useArtifactDownloadUrl.js +59 -0
  132. package/execution/useArtifactDownloadUrl.js.map +1 -0
  133. package/execution/useFileChangeContent.d.ts +61 -0
  134. package/execution/useFileChangeContent.d.ts.map +1 -0
  135. package/execution/useFileChangeContent.js +89 -0
  136. package/execution/useFileChangeContent.js.map +1 -0
  137. package/execution/useFileReview.d.ts +89 -0
  138. package/execution/useFileReview.d.ts.map +1 -0
  139. package/execution/useFileReview.js +106 -0
  140. package/execution/useFileReview.js.map +1 -0
  141. package/execution/useSubmitApproval.d.ts +17 -2
  142. package/execution/useSubmitApproval.d.ts.map +1 -1
  143. package/execution/useSubmitApproval.js +27 -23
  144. package/execution/useSubmitApproval.js.map +1 -1
  145. package/execution/useToolOutputContent.d.ts +44 -0
  146. package/execution/useToolOutputContent.d.ts.map +1 -0
  147. package/execution/useToolOutputContent.js +31 -0
  148. package/execution/useToolOutputContent.js.map +1 -0
  149. package/index.d.ts +6 -6
  150. package/index.d.ts.map +1 -1
  151. package/index.js +3 -3
  152. package/index.js.map +1 -1
  153. package/internal/ApprovalPeekBar.d.ts +23 -0
  154. package/internal/ApprovalPeekBar.d.ts.map +1 -0
  155. package/internal/ApprovalPeekBar.js +25 -0
  156. package/internal/ApprovalPeekBar.js.map +1 -0
  157. package/internal/BoundedContent.d.ts +49 -0
  158. package/internal/BoundedContent.d.ts.map +1 -0
  159. package/internal/BoundedContent.js +50 -0
  160. package/internal/BoundedContent.js.map +1 -0
  161. package/internal/DecisionButton.d.ts +47 -0
  162. package/internal/DecisionButton.d.ts.map +1 -0
  163. package/internal/DecisionButton.js +42 -0
  164. package/internal/DecisionButton.js.map +1 -0
  165. package/internal/InCardDecisionError.d.ts +31 -0
  166. package/internal/InCardDecisionError.d.ts.map +1 -0
  167. package/internal/InCardDecisionError.js +23 -0
  168. package/internal/InCardDecisionError.js.map +1 -0
  169. package/internal/RevealToggle.d.ts +36 -0
  170. package/internal/RevealToggle.d.ts.map +1 -0
  171. package/internal/RevealToggle.js +32 -0
  172. package/internal/RevealToggle.js.map +1 -0
  173. package/internal/VirtualizedThread.d.ts +7 -1
  174. package/internal/VirtualizedThread.d.ts.map +1 -1
  175. package/internal/VirtualizedThread.js +7 -3
  176. package/internal/VirtualizedThread.js.map +1 -1
  177. package/internal/code-highlight.d.ts +24 -0
  178. package/internal/code-highlight.d.ts.map +1 -0
  179. package/internal/code-highlight.js +115 -0
  180. package/internal/code-highlight.js.map +1 -0
  181. package/internal/markdown-components.d.ts.map +1 -1
  182. package/internal/markdown-components.js +13 -2
  183. package/internal/markdown-components.js.map +1 -1
  184. package/internal/useAutoDisclosure.d.ts +34 -0
  185. package/internal/useAutoDisclosure.d.ts.map +1 -0
  186. package/internal/useAutoDisclosure.js +53 -0
  187. package/internal/useAutoDisclosure.js.map +1 -0
  188. package/internal/useElapsedSince.d.ts +30 -0
  189. package/internal/useElapsedSince.d.ts.map +1 -0
  190. package/internal/useElapsedSince.js +70 -0
  191. package/internal/useElapsedSince.js.map +1 -0
  192. package/internal/useIsOverflowing.d.ts +30 -0
  193. package/internal/useIsOverflowing.d.ts.map +1 -0
  194. package/internal/useIsOverflowing.js +47 -0
  195. package/internal/useIsOverflowing.js.map +1 -0
  196. package/internal/useIsTextTruncated.d.ts +24 -0
  197. package/internal/useIsTextTruncated.d.ts.map +1 -0
  198. package/internal/useIsTextTruncated.js +41 -0
  199. package/internal/useIsTextTruncated.js.map +1 -0
  200. package/internal/useKeyedSubmission.d.ts +49 -0
  201. package/internal/useKeyedSubmission.d.ts.map +1 -0
  202. package/internal/useKeyedSubmission.js +67 -0
  203. package/internal/useKeyedSubmission.js.map +1 -0
  204. package/package.json +7 -4
  205. package/session/SessionViewer.d.ts +2 -2
  206. package/session/SessionViewer.d.ts.map +1 -1
  207. package/session/SessionViewer.js +10 -4
  208. package/session/SessionViewer.js.map +1 -1
  209. package/session/index.d.ts +2 -0
  210. package/session/index.d.ts.map +1 -1
  211. package/session/index.js +1 -0
  212. package/session/index.js.map +1 -1
  213. package/session/inspector/ChangesTab.d.ts +8 -5
  214. package/session/inspector/ChangesTab.d.ts.map +1 -1
  215. package/session/inspector/ChangesTab.js +11 -8
  216. package/session/inspector/ChangesTab.js.map +1 -1
  217. package/session/inspector/SessionInspector.d.ts +4 -4
  218. package/session/inspector/SessionInspector.d.ts.map +1 -1
  219. package/session/inspector/SessionInspector.js +4 -4
  220. package/session/inspector/SessionInspector.js.map +1 -1
  221. package/session/inspector/index.d.ts +0 -2
  222. package/session/inspector/index.d.ts.map +1 -1
  223. package/session/inspector/index.js +0 -1
  224. package/session/inspector/index.js.map +1 -1
  225. package/session/inspector/useSessionInspector.d.ts +8 -4
  226. package/session/inspector/useSessionInspector.d.ts.map +1 -1
  227. package/session/inspector/useSessionInspector.js +27 -20
  228. package/session/inspector/useSessionInspector.js.map +1 -1
  229. package/session/useSessionConversation.d.ts +37 -3
  230. package/session/useSessionConversation.d.ts.map +1 -1
  231. package/session/useSessionConversation.js +18 -2
  232. package/session/useSessionConversation.js.map +1 -1
  233. package/session/useSessionFileChanges.d.ts +74 -0
  234. package/session/useSessionFileChanges.d.ts.map +1 -0
  235. package/session/useSessionFileChanges.js +178 -0
  236. package/session/useSessionFileChanges.js.map +1 -0
  237. package/src/__tests__/styles-border-layer-invariant.test.ts +105 -0
  238. package/src/execution/ApprovalCard.tsx +368 -230
  239. package/src/execution/ApprovalContext.ts +109 -0
  240. package/src/execution/ArtifactCard.tsx +10 -6
  241. package/src/execution/ArtifactPreviewModal.tsx +12 -6
  242. package/src/execution/EmptyChangeNotice.tsx +62 -0
  243. package/src/execution/FileChangesView.tsx +383 -0
  244. package/src/execution/FilePathLink.tsx +65 -12
  245. package/src/execution/FileReviewCard.tsx +1118 -0
  246. package/src/execution/FileReviewContext.ts +53 -0
  247. package/src/execution/FileReviewDock.tsx +157 -0
  248. package/src/execution/McpToolDetail.tsx +98 -32
  249. package/src/execution/MessageThread.tsx +374 -9
  250. package/src/execution/PlanArtifactCard.tsx +9 -6
  251. package/src/execution/PlanCompletionCard.tsx +1 -1
  252. package/src/execution/ResultView.tsx +333 -162
  253. package/src/execution/SubAgentSection.tsx +58 -11
  254. package/src/execution/TerminalSession.tsx +91 -0
  255. package/src/execution/TodoCard.tsx +186 -0
  256. package/src/execution/ToolArgsView.tsx +28 -17
  257. package/src/execution/ToolCallDetail.tsx +137 -26
  258. package/src/execution/ToolCallGroup.tsx +68 -296
  259. package/src/execution/ToolCallItem.tsx +265 -67
  260. package/src/execution/ToolRunGroup.tsx +302 -0
  261. package/src/execution/__tests__/ApprovalCard.test.tsx +395 -5
  262. package/src/execution/__tests__/ArtifactContentRenderer.test.tsx +15 -0
  263. package/src/execution/__tests__/ArtifactPreviewModal.test.tsx +0 -1
  264. package/src/execution/__tests__/EmptyChangeNotice.test.tsx +24 -0
  265. package/src/execution/__tests__/FileChangesView.test.tsx +296 -0
  266. package/src/execution/__tests__/FilePathLink.test.tsx +92 -0
  267. package/src/execution/__tests__/FileReviewCard.test.tsx +1044 -0
  268. package/src/execution/__tests__/FileReviewDock.test.tsx +134 -0
  269. package/src/execution/__tests__/McpToolDetail.test.tsx +79 -0
  270. package/src/execution/__tests__/MessageThread.test.tsx +324 -0
  271. package/src/execution/__tests__/PlanArtifactCard.test.tsx +37 -16
  272. package/src/execution/__tests__/ResultView.test.tsx +280 -2
  273. package/src/execution/__tests__/SubAgentSection.test.tsx +180 -0
  274. package/src/execution/__tests__/TerminalSession.test.tsx +72 -0
  275. package/src/execution/__tests__/TodoCard.test.tsx +102 -0
  276. package/src/execution/__tests__/ToolArgsView.test.tsx +48 -0
  277. package/src/execution/__tests__/ToolCallDetail.test.tsx +195 -0
  278. package/src/execution/__tests__/ToolCallGroup.test.tsx +132 -0
  279. package/src/execution/__tests__/ToolCallItem.test.tsx +521 -0
  280. package/src/execution/__tests__/ToolRunGroup.test.tsx +137 -0
  281. package/src/execution/__tests__/blanked-narration.test.tsx +149 -0
  282. package/src/execution/__tests__/buildThreadItems-approvals.test.ts +304 -0
  283. package/src/execution/__tests__/buildThreadItems-file-review.test.ts +331 -0
  284. package/src/execution/__tests__/file-path-resolver.test.ts +44 -0
  285. package/src/execution/__tests__/file-review-status.test.ts +343 -0
  286. package/src/execution/__tests__/message-entry.test.tsx +16 -0
  287. package/src/execution/__tests__/segment-tool-calls.test.ts +124 -0
  288. package/src/execution/__tests__/subagent-file-review-badge.test.tsx +273 -0
  289. package/src/execution/__tests__/thread-keys.test.ts +195 -0
  290. package/src/execution/__tests__/tool-presenter.test.tsx +95 -0
  291. package/src/execution/__tests__/useArtifactDownload.test.tsx +67 -0
  292. package/src/execution/__tests__/useArtifactDownloadUrl.test.tsx +51 -0
  293. package/src/execution/__tests__/useFileChangeContent.test.tsx +240 -0
  294. package/src/execution/__tests__/useFileReview.test.tsx +236 -0
  295. package/src/execution/__tests__/useSubmitApproval.test.tsx +165 -0
  296. package/src/execution/__tests__/useToolOutputContent.test.tsx +82 -0
  297. package/src/execution/approval-provenance.ts +8 -0
  298. package/src/execution/artifact-utils.ts +0 -18
  299. package/src/execution/execution-phases.ts +4 -16
  300. package/src/execution/file-path-resolver.ts +38 -0
  301. package/src/execution/file-review-status.ts +219 -0
  302. package/src/execution/index.ts +84 -4
  303. package/src/execution/segment-tool-calls.ts +101 -0
  304. package/src/execution/tool-categories.ts +128 -1
  305. package/src/execution/tool-presenter.ts +58 -3
  306. package/src/execution/tool-rendering-primitives.tsx +11 -14
  307. package/src/execution/useArtifactDownload.ts +109 -0
  308. package/src/execution/useArtifactDownloadUrl.ts +116 -0
  309. package/src/execution/useFileChangeContent.ts +149 -0
  310. package/src/execution/useFileReview.ts +197 -0
  311. package/src/execution/useSubmitApproval.ts +49 -27
  312. package/src/execution/useToolOutputContent.ts +70 -0
  313. package/src/index.ts +60 -1
  314. package/src/internal/ApprovalPeekBar.tsx +73 -0
  315. package/src/internal/BoundedContent.tsx +97 -0
  316. package/src/internal/DecisionButton.tsx +127 -0
  317. package/src/internal/InCardDecisionError.tsx +47 -0
  318. package/src/internal/RevealToggle.tsx +91 -0
  319. package/src/internal/VirtualizedThread.tsx +28 -2
  320. package/src/internal/__tests__/ApprovalPeekBar.test.tsx +34 -0
  321. package/src/internal/__tests__/BoundedContent.test.tsx +92 -0
  322. package/src/internal/__tests__/DecisionButton.test.tsx +107 -0
  323. package/src/internal/__tests__/RevealToggle.test.tsx +61 -0
  324. package/src/internal/__tests__/code-highlight.test.tsx +59 -0
  325. package/src/internal/__tests__/markdown-components.test.tsx +68 -2
  326. package/src/internal/__tests__/useAutoDisclosure.test.ts +74 -0
  327. package/src/internal/__tests__/useElapsedSince.test.tsx +68 -0
  328. package/src/internal/__tests__/useIsOverflowing.test.ts +36 -0
  329. package/src/internal/__tests__/useKeyedSubmission.test.tsx +126 -0
  330. package/src/internal/code-highlight.tsx +120 -0
  331. package/src/internal/markdown-components.tsx +20 -3
  332. package/src/internal/useAutoDisclosure.ts +58 -0
  333. package/src/internal/useElapsedSince.ts +72 -0
  334. package/src/internal/useIsOverflowing.ts +61 -0
  335. package/src/internal/useIsTextTruncated.ts +55 -0
  336. package/src/internal/useKeyedSubmission.ts +101 -0
  337. package/src/session/SessionViewer.tsx +21 -4
  338. package/src/session/__tests__/SessionViewer-fileReviewDock.test.tsx +198 -0
  339. package/src/session/__tests__/audienceWiring.test.tsx +4 -0
  340. package/src/session/__tests__/useSessionFileChanges.test.ts +303 -0
  341. package/src/session/index.ts +3 -0
  342. package/src/session/inspector/ChangesTab.tsx +20 -17
  343. package/src/session/inspector/SessionInspector.tsx +12 -10
  344. package/src/session/inspector/__tests__/ArtifactsTab.test.tsx +0 -1
  345. package/src/session/inspector/__tests__/ChangesTab.test.tsx +38 -0
  346. package/src/session/inspector/__tests__/useSessionInspector.test.ts +46 -61
  347. package/src/session/inspector/index.ts +0 -3
  348. package/src/session/inspector/useSessionInspector.ts +27 -20
  349. package/src/session/useSessionConversation.ts +80 -3
  350. package/src/session/useSessionFileChanges.ts +207 -0
  351. package/src/styles.css +123 -10
  352. package/src/version-history/DiffViewer.tsx +10 -7
  353. package/src/version-history/UnifiedDiffView.tsx +66 -0
  354. package/src/version-history/__tests__/DiffViewer.test.tsx +57 -0
  355. package/src/version-history/__tests__/UnifiedDiffView.test.tsx +50 -0
  356. package/src/version-history/__tests__/computeDiff.test.ts +35 -0
  357. package/src/version-history/__tests__/parseUnifiedDiff.test.ts +82 -0
  358. package/src/version-history/computeDiff.ts +6 -37
  359. package/src/version-history/diff-hunks.ts +63 -0
  360. package/src/version-history/index.ts +1 -0
  361. package/src/version-history/parseUnifiedDiff.ts +34 -0
  362. package/src/workflow/WorkflowExecutionApprovalCard.tsx +49 -24
  363. package/src/workflow/WorkflowExecutionTimeline.tsx +15 -4
  364. package/src/workflow/WorkflowExecutionTimelineEvent.tsx +8 -3
  365. package/src/workflow/WorkflowExecutionViewer.tsx +72 -28
  366. package/src/workflow/WorkflowFileReviewList.tsx +152 -0
  367. package/src/workflow/WorkflowTaskApprovalCard.tsx +37 -85
  368. package/src/workflow/__tests__/ExecutionInspector.test.tsx +30 -2
  369. package/src/workflow/__tests__/WorkflowExecutionApprovalCard.test.tsx +129 -0
  370. package/src/workflow/__tests__/WorkflowFileReviewList.test.tsx +129 -0
  371. package/src/workflow/__tests__/WorkflowTaskApprovalCard.test.tsx +43 -11
  372. package/src/workflow/__tests__/useWorkflowExecutionActions.test.tsx +276 -0
  373. package/src/workflow/execution-inspector/ExecutionInspector.tsx +42 -18
  374. package/src/workflow/index.ts +5 -0
  375. package/src/workflow/useWorkflowExecutionActions.ts +177 -29
  376. package/styles.css +1 -1
  377. package/version-history/DiffViewer.d.ts.map +1 -1
  378. package/version-history/DiffViewer.js +9 -3
  379. package/version-history/DiffViewer.js.map +1 -1
  380. package/version-history/UnifiedDiffView.d.ts +29 -0
  381. package/version-history/UnifiedDiffView.d.ts.map +1 -0
  382. package/version-history/UnifiedDiffView.js +36 -0
  383. package/version-history/UnifiedDiffView.js.map +1 -0
  384. package/version-history/computeDiff.d.ts +3 -1
  385. package/version-history/computeDiff.d.ts.map +1 -1
  386. package/version-history/computeDiff.js +5 -35
  387. package/version-history/computeDiff.js.map +1 -1
  388. package/version-history/diff-hunks.d.ts +21 -0
  389. package/version-history/diff-hunks.d.ts.map +1 -0
  390. package/version-history/diff-hunks.js +58 -0
  391. package/version-history/diff-hunks.js.map +1 -0
  392. package/version-history/index.d.ts +1 -0
  393. package/version-history/index.d.ts.map +1 -1
  394. package/version-history/index.js +1 -0
  395. package/version-history/index.js.map +1 -1
  396. package/version-history/parseUnifiedDiff.d.ts +22 -0
  397. package/version-history/parseUnifiedDiff.d.ts.map +1 -0
  398. package/version-history/parseUnifiedDiff.js +34 -0
  399. package/version-history/parseUnifiedDiff.js.map +1 -0
  400. package/workflow/WorkflowExecutionApprovalCard.d.ts +8 -1
  401. package/workflow/WorkflowExecutionApprovalCard.d.ts.map +1 -1
  402. package/workflow/WorkflowExecutionApprovalCard.js +17 -3
  403. package/workflow/WorkflowExecutionApprovalCard.js.map +1 -1
  404. package/workflow/WorkflowExecutionTimeline.d.ts +11 -2
  405. package/workflow/WorkflowExecutionTimeline.d.ts.map +1 -1
  406. package/workflow/WorkflowExecutionTimeline.js +2 -2
  407. package/workflow/WorkflowExecutionTimeline.js.map +1 -1
  408. package/workflow/WorkflowExecutionTimelineEvent.d.ts +4 -1
  409. package/workflow/WorkflowExecutionTimelineEvent.d.ts.map +1 -1
  410. package/workflow/WorkflowExecutionTimelineEvent.js +2 -2
  411. package/workflow/WorkflowExecutionTimelineEvent.js.map +1 -1
  412. package/workflow/WorkflowExecutionViewer.d.ts.map +1 -1
  413. package/workflow/WorkflowExecutionViewer.js +18 -10
  414. package/workflow/WorkflowExecutionViewer.js.map +1 -1
  415. package/workflow/WorkflowFileReviewList.d.ts +46 -0
  416. package/workflow/WorkflowFileReviewList.d.ts.map +1 -0
  417. package/workflow/WorkflowFileReviewList.js +48 -0
  418. package/workflow/WorkflowFileReviewList.js.map +1 -0
  419. package/workflow/WorkflowTaskApprovalCard.d.ts +8 -1
  420. package/workflow/WorkflowTaskApprovalCard.d.ts.map +1 -1
  421. package/workflow/WorkflowTaskApprovalCard.js +12 -19
  422. package/workflow/WorkflowTaskApprovalCard.js.map +1 -1
  423. package/workflow/execution-inspector/ExecutionInspector.d.ts +21 -4
  424. package/workflow/execution-inspector/ExecutionInspector.d.ts.map +1 -1
  425. package/workflow/execution-inspector/ExecutionInspector.js +6 -3
  426. package/workflow/execution-inspector/ExecutionInspector.js.map +1 -1
  427. package/workflow/index.d.ts +1 -0
  428. package/workflow/index.d.ts.map +1 -1
  429. package/workflow/index.js +1 -0
  430. package/workflow/index.js.map +1 -1
  431. package/workflow/useWorkflowExecutionActions.d.ts +62 -4
  432. package/workflow/useWorkflowExecutionActions.d.ts.map +1 -1
  433. package/workflow/useWorkflowExecutionActions.js +94 -18
  434. package/workflow/useWorkflowExecutionActions.js.map +1 -1
  435. package/session/inspector/PlanTab.d.ts +0 -15
  436. package/session/inspector/PlanTab.d.ts.map +0 -1
  437. package/session/inspector/PlanTab.js +0 -19
  438. package/session/inspector/PlanTab.js.map +0 -1
  439. package/src/session/inspector/PlanTab.tsx +0 -31
@@ -1,94 +1,12 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { memo, useEffect, useMemo, useRef, useState } from "react";
4
- import { ApprovalAction, ToolCallStatus, } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { memo, useMemo } from "react";
5
4
  import { cn } from "@stigmer/theme";
6
5
  import { useRenderTracer } from "../internal/dev";
7
6
  import { ToolCallItem } from "./ToolCallItem";
8
- import { resolveToolCategoryFromCall, extractPrimaryArg } from "./tool-categories";
9
- function isResolvedApproval(tc) {
10
- return (tc.approvalAction === ApprovalAction.APPROVE ||
11
- tc.approvalAction === ApprovalAction.SKIP ||
12
- tc.approvalAction === ApprovalAction.REJECT);
13
- }
14
- function deriveAggregateStatus(toolCalls) {
15
- let hasRunning = false;
16
- let hasWaiting = false;
17
- let hasFailed = false;
18
- let allTerminal = true;
19
- for (const tc of toolCalls) {
20
- switch (tc.status) {
21
- case ToolCallStatus.TOOL_CALL_RUNNING:
22
- hasRunning = true;
23
- allTerminal = false;
24
- break;
25
- case ToolCallStatus.TOOL_CALL_WAITING_APPROVAL:
26
- if (isResolvedApproval(tc)) {
27
- break;
28
- }
29
- hasWaiting = true;
30
- allTerminal = false;
31
- break;
32
- case ToolCallStatus.TOOL_CALL_FAILED:
33
- hasFailed = true;
34
- break;
35
- case ToolCallStatus.TOOL_CALL_COMPLETED:
36
- case ToolCallStatus.TOOL_CALL_SKIPPED:
37
- break;
38
- default:
39
- allTerminal = false;
40
- break;
41
- }
42
- }
43
- if (hasRunning)
44
- return "running";
45
- if (hasWaiting)
46
- return "waiting";
47
- if (hasFailed)
48
- return "failed";
49
- if (allTerminal)
50
- return "completed";
51
- return "pending";
52
- }
53
- function defaultFormatSummary(toolCalls, status) {
54
- if (toolCalls.length === 1) {
55
- const tc = toolCalls[0];
56
- const cat = resolveToolCategoryFromCall(tc);
57
- const primary = extractPrimaryArg(tc);
58
- if (primary) {
59
- const truncated = primary.length > 60 ? primary.slice(0, 57) + "\u2026" : primary;
60
- return `${cat.label}: ${truncated}`;
61
- }
62
- return cat.label;
63
- }
64
- const noun = toolCalls.length === 1 ? "tool" : "tools";
65
- switch (status) {
66
- case "running":
67
- return `Running ${toolCalls.length} ${noun}`;
68
- case "waiting":
69
- return "Waiting for approval";
70
- case "failed":
71
- return `Ran ${toolCalls.length} ${noun} (with errors)`;
72
- case "completed":
73
- return `Ran ${toolCalls.length} ${noun}`;
74
- case "pending":
75
- return `${toolCalls.length} ${noun} pending`;
76
- }
77
- }
78
- const STATUS_ICON = {
79
- running: SpinnerIcon,
80
- waiting: ClockIcon,
81
- failed: XCircleIcon,
82
- completed: CheckCircleIcon,
83
- pending: DotIcon,
84
- };
85
- const STATUS_COLOR = {
86
- running: "text-foreground",
87
- waiting: "text-warning",
88
- failed: "text-destructive",
89
- completed: "text-success",
90
- pending: "text-muted-foreground",
91
- };
7
+ import { ToolRunGroup } from "./ToolRunGroup";
8
+ import { segmentToolCalls } from "./segment-tool-calls";
9
+ import { isCollapsedToolCall } from "./tool-categories";
92
10
  /**
93
11
  * Shallow comparison for `ToolCallGroupProps`.
94
12
  *
@@ -112,49 +30,42 @@ export function toolCallGroupPropsEqual(prev, next) {
112
30
  prev.className === next.className);
113
31
  }
114
32
  /**
115
- * Renders a summary line for a group of tool calls from a single
116
- * AI turn. Click to expand and see individual tool calls.
33
+ * Renders one AI turn's tool activity as a **persistent-row timeline** rather
34
+ * than a collapsible "Ran N tools" box. Each call stays visible after it
35
+ * settles, so completed work is never hidden behind a pill — the thread reads
36
+ * like a virtual human at work.
117
37
  *
118
- * Two-level progressive disclosure:
119
- * 1. **Collapsed** aggregate status icon + summary label.
120
- * 2. **Expanded** — list of {@link ToolCallItem} rows, each
121
- * expandable to show detail (args, result, error, timing) or
122
- * a nested sub-agent thread.
38
+ * The turn is segmented by {@link segmentToolCalls}:
39
+ * - high-signal calls (edits, shell, MCP, sub-agents, …) render as persistent
40
+ * {@link ToolCallItem} rows; a content-bearing call shows its body inline
41
+ * (no card chevron), bounded by a single in-place reveal;
42
+ * - runs of consecutive low-signal same-category calls (read / list / search)
43
+ * fold into one collapsible {@link ToolRunGroup} chip — the *only* collapse,
44
+ * because that is the only genuine noise.
123
45
  *
124
- * Default summaries use active-voice phrasing ("Ran 3 tools",
125
- * "Running 2 tools") with category-aware labels for single tools
126
- * (e.g., "Shell: ls -la /tmp"). Platform builders can override
127
- * via the `formatSummary` prop.
46
+ * The rows are clustered under a light left rail (the neutral counterpart to
47
+ * {@link SubAgentSection}'s primary-tinted rail for delegated work), keeping a
48
+ * turn's tools visually associated with their AI message without a tab that
49
+ * hides things.
128
50
  *
129
- * Wrapped in `React.memo` with a custom comparator that checks
130
- * `toolCalls` elements by reference (structural sharing keeps
131
- * individual `ToolCall` objects stable for unchanged calls).
51
+ * Wrapped in `React.memo` with a custom comparator that checks `toolCalls`
52
+ * elements by reference (structural sharing keeps individual `ToolCall` objects
53
+ * stable for unchanged calls), so settled rows skip re-renders while siblings
54
+ * stream (DD-009/010).
132
55
  *
133
56
  * @example
134
57
  * ```tsx
135
58
  * <ToolCallGroup toolCalls={message.toolCalls} />
136
59
  * ```
137
60
  */
138
- export const ToolCallGroup = memo(function ToolCallGroup({ toolCalls, subAgentExecutions, formatSummary, defaultExpanded = false, className, }) {
61
+ export const ToolCallGroup = memo(function ToolCallGroup({ toolCalls, subAgentExecutions, formatSummary, className, }) {
139
62
  useRenderTracer("ToolCallGroup", { toolCallCount: toolCalls.length });
140
- const status = deriveAggregateStatus(toolCalls);
141
- const isActive = status === "running" || status === "pending" || status === "waiting";
142
- const [expanded, setExpanded] = useState(defaultExpanded || isActive);
143
- const userToggledRef = useRef(false);
144
- useEffect(() => {
145
- if (userToggledRef.current)
146
- return;
147
- if (isActive) {
148
- setExpanded(true);
149
- }
150
- else {
151
- setExpanded(false);
152
- }
153
- }, [isActive]);
154
- const handleToggle = () => {
155
- userToggledRef.current = true;
156
- setExpanded((v) => !v);
157
- };
63
+ // Drop runner-collapsed duplicates (a superseded same-turn denial twin of an
64
+ // approval gate) so one gated resource renders one card, not two. The blanked
65
+ // twin is kept in the persisted transcript (the backend's append-only guard
66
+ // forbids dropping it); it is simply not drawn.
67
+ const visibleToolCalls = useMemo(() => toolCalls.filter((tc) => !isCollapsedToolCall(tc)), [toolCalls]);
68
+ const segments = useMemo(() => segmentToolCalls(visibleToolCalls), [visibleToolCalls]);
158
69
  const subAgentMap = useMemo(() => {
159
70
  if (!subAgentExecutions || subAgentExecutions.length === 0)
160
71
  return null;
@@ -164,34 +75,14 @@ export const ToolCallGroup = memo(function ToolCallGroup({ toolCalls, subAgentEx
164
75
  }
165
76
  return map;
166
77
  }, [subAgentExecutions]);
167
- if (toolCalls.length === 0)
78
+ if (visibleToolCalls.length === 0)
168
79
  return null;
169
- const summary = formatSummary
170
- ? formatSummary(toolCalls)
171
- : defaultFormatSummary(toolCalls, status);
172
- const Icon = STATUS_ICON[status];
173
- const ariaLabel = `${summary}, ${status}`;
174
- return (_jsxs("div", { role: "group", "aria-label": ariaLabel, className: cn("rounded-md border border-border bg-muted-faint", className), children: [_jsxs("button", { type: "button", "aria-expanded": expanded, onClick: handleToggle, className: cn("flex w-full items-center gap-2 px-2.5 py-1.5 text-left text-xs text-muted-foreground transition-colors", "hover:bg-muted-subtle", "cursor-pointer"), children: [_jsx("span", { className: cn("shrink-0", STATUS_COLOR[status]), "aria-hidden": "true", children: _jsx(Icon, {}) }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: summary }), _jsx(ChevronIcon, { expanded: expanded })] }), _jsx("div", { className: cn("grid transition-[grid-template-rows] duration-150 ease-out", expanded ? "grid-rows-[1fr]" : "grid-rows-[0fr]"), children: _jsx("div", { className: "overflow-hidden", children: expanded && (_jsx("div", { className: "border-t border-border-muted", children: toolCalls.map((tc) => (_jsx(ToolCallItem, { toolCall: tc, subAgentExecution: subAgentMap?.get(tc.id) ?? null }, tc.id || tc.name))) })) }) })] }));
80
+ const ariaLabel = `${visibleToolCalls.length} tool ${visibleToolCalls.length === 1 ? "call" : "calls"}`;
81
+ return (_jsx("div", { role: "group", "aria-label": ariaLabel, "data-cursor-target": "tool-call-group", className: cn(
82
+ // Cursor-style: each tool call (and folded run chip) is its own
83
+ // self-contained card; the turn's tools stack with a small gap between
84
+ // them rather than sharing a left rail, so the thread reads as a column
85
+ // of discrete cards.
86
+ "flex flex-col gap-2", className), children: segments.map((segment) => segment.kind === "run" ? (_jsx(ToolRunGroup, { category: segment.category, toolCalls: segment.toolCalls, formatLabel: formatSummary }, segment.key)) : (_jsx(ToolCallItem, { toolCall: segment.toolCall, subAgentExecution: subAgentMap?.get(segment.toolCall.id) ?? null }, segment.key))) }));
175
87
  }, toolCallGroupPropsEqual);
176
- // ---------------------------------------------------------------------------
177
- // Inline SVG icons — same as SP1, kept inline for SDK independence
178
- // ---------------------------------------------------------------------------
179
- function SpinnerIcon() {
180
- return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", className: "animate-spin", children: _jsx("path", { d: "M6 1.5A4.5 4.5 0 1 1 1.5 6", strokeLinecap: "round" }) }));
181
- }
182
- function ClockIcon() {
183
- return (_jsxs("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("circle", { cx: "6", cy: "6", r: "4.5" }), _jsx("path", { d: "M6 3.5V6L7.5 7.5" })] }));
184
- }
185
- function CheckCircleIcon() {
186
- return (_jsxs("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("circle", { cx: "6", cy: "6", r: "4.5" }), _jsx("path", { d: "M4 6L5.5 7.5L8 4.5" })] }));
187
- }
188
- function XCircleIcon() {
189
- return (_jsxs("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("circle", { cx: "6", cy: "6", r: "4.5" }), _jsx("path", { d: "M4.5 4.5L7.5 7.5M7.5 4.5L4.5 7.5" })] }));
190
- }
191
- function DotIcon() {
192
- return (_jsx("svg", { width: "8", height: "8", viewBox: "0 0 8 8", fill: "currentColor", children: _jsx("circle", { cx: "4", cy: "4", r: "3" }) }));
193
- }
194
- function ChevronIcon({ expanded }) {
195
- return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: cn("shrink-0 text-muted-foreground transition-transform duration-150", expanded && "rotate-90"), "aria-hidden": "true", children: _jsx("path", { d: "M4.5 2.5L7.5 6L4.5 9.5" }) }));
196
- }
197
88
  //# sourceMappingURL=ToolCallGroup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolCallGroup.js","sourceRoot":"","sources":["../../src/execution/ToolCallGroup.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ToolCallGroup.js","sourceRoot":"","sources":["../../src/execution/ToolCallGroup.tsx"],"names":[],"mappings":"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"}
@@ -12,33 +12,61 @@ export interface ToolCallItemProps {
12
12
  */
13
13
  readonly subAgentExecution?: SubAgentExecution | null;
14
14
  /**
15
- * Initial expansion state. Defaults to `false`.
15
+ * Forces the detail panel open on first render regardless of the
16
+ * auto-disclosure policy. Defaults to `false`.
16
17
  */
17
18
  readonly defaultExpanded?: boolean;
19
+ /**
20
+ * Whether the row renders as its own self-contained card (a thin rounded
21
+ * border). Defaults to `true`. Set to `false` when the row is nested inside a
22
+ * container that already provides the border — e.g. the folded
23
+ * `ToolRunGroup` chip — where the row falls back to a divider-separated
24
+ * row to avoid a card-in-a-card.
25
+ */
26
+ readonly bordered?: boolean;
18
27
  /** Additional CSS class names for the root container. */
19
28
  readonly className?: string;
20
29
  }
21
30
  /**
22
31
  * Renders a single tool call as a row in the tool call group.
23
32
  *
24
- * Two rendering modes:
33
+ * Three rendering modes, set by one rule — **does the body carry content the
34
+ * one-line row cannot?**
25
35
  *
26
- * - **Non-expandable** (completed/skipped Read): a static `<div>` row
27
- * with a clickable {@link FilePathLink}. No chevron, no expansion.
28
- * The clickable path IS the complete information.
29
- * - **Expandable** (all other tools): a `<button>` row that toggles a
30
- * {@link ToolCallDetail} or {@link SubAgentSection} detail panel.
36
+ * - **Non-expandable** (completed/skipped Read): a static `<div>` row with a
37
+ * clickable {@link FilePathLink}. The path IS the complete information.
38
+ * - **Preview** (content-bearing: shell / edit / write / fetch / web-search /
39
+ * unknown / mcp): a plain (non-button) header above an **always-visible**
40
+ * {@link ToolCallDetail} body Cursor-style "previews aren't collapsible".
41
+ * There is no header chevron; each content block self-bounds with its own
42
+ * single in-place reveal (`RevealToggle`), so a long diff or output
43
+ * never floods the thread. The body is suppressed only for an `empty` result
44
+ * (e.g. a no-output shell), which stays a clean one-line row.
45
+ * - **Summary / sub-agent** (read / list / search / delete / think, and
46
+ * sub-agent delegations): a chevron-gated `div[role=button]` header that
47
+ * discloses a body hidden by default — {@link ToolCallDetail}, a
48
+ * {@link SubAgentSection}, or, when gated, an inline {@link ApprovalCardBody}.
49
+ * {@link useAutoDisclosure} force-opens it while *running* or *awaiting
50
+ * approval*, then settles it closed; a manual click always wins thereafter.
51
+ *
52
+ * The two disclosure axes — the card-level chevron and a block's
53
+ * content-overflow reveal — never govern the same body, which is what removes
54
+ * the old "expand, then Show more" double control.
31
55
  *
32
56
  * Shows category-aware labels (e.g., "Shell", "Read", "Edit") with
33
57
  * the primary argument as a subtitle, a category-specific icon, and
34
58
  * an inline approval decision badge when applicable.
35
59
  *
60
+ * Wrapped in `React.memo` — structural sharing (DD-009/010) preserves
61
+ * the `ToolCall` reference when unchanged, so a settled row skips
62
+ * re-renders while sibling tools stream.
63
+ *
36
64
  * @example
37
65
  * ```tsx
38
66
  * <ToolCallItem toolCall={tc} />
39
67
  * <ToolCallItem toolCall={tc} subAgentExecution={sub} />
40
68
  * ```
41
69
  */
42
- export declare function ToolCallItem({ toolCall, subAgentExecution, defaultExpanded, className, }: ToolCallItemProps): import("react/jsx-runtime").JSX.Element;
70
+ export declare const ToolCallItem: import("react").NamedExoticComponent<ToolCallItemProps>;
43
71
  export declare const CATEGORY_ICON: Record<ToolCategory, () => React.JSX.Element>;
44
72
  //# sourceMappingURL=ToolCallItem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolCallItem.d.ts","sourceRoot":"","sources":["../../src/execution/ToolCallItem.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iEAAiE,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kEAAkE,CAAC;AAS1G,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKtD,sCAAsC;AACtC,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACtD;;OAEG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,iBAAiB,EACjB,eAAuB,EACvB,SAAS,GACV,EAAE,iBAAiB,2CAuKnB;AAkED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,OAAO,CAevE,CAAC"}
1
+ {"version":3,"file":"ToolCallItem.d.ts","sourceRoot":"","sources":["../../src/execution/ToolCallItem.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iEAAiE,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kEAAkE,CAAC;AAgB1G,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItE,sCAAsC;AACtC,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,YAAY,yDA+TvB,CAAC;AAmFH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,OAAO,CAevE,CAAC"}
@@ -1,49 +1,114 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState } from "react";
3
+ import { memo } from "react";
4
4
  import { ApprovalAction, ToolCallStatus, } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
5
5
  import { cn } from "@stigmer/theme";
6
+ import { useRenderTracer } from "../internal/dev";
7
+ import { useAutoDisclosure } from "../internal/useAutoDisclosure";
8
+ import { useIsTextTruncated } from "../internal/useIsTextTruncated";
6
9
  import { ToolCallDetail, formatDuration } from "./ToolCallDetail";
7
10
  import { SubAgentSection } from "./SubAgentSection";
11
+ import { ApprovalCardBody } from "./ApprovalCard";
12
+ import { useApproval } from "./ApprovalContext";
13
+ import { useFileReviewRowState } from "./FileReviewContext";
8
14
  import { FilePathLink } from "./FilePathLink";
15
+ import { isFileCategory } from "./tool-categories";
9
16
  import { useToolPresentation } from "./tool-presenter";
10
- import { useSandboxNormalize } from "./SandboxContext";
11
17
  import { useThreadSelection } from "./useThreadSelection";
12
18
  /**
13
19
  * Renders a single tool call as a row in the tool call group.
14
20
  *
15
- * Two rendering modes:
21
+ * Three rendering modes, set by one rule — **does the body carry content the
22
+ * one-line row cannot?**
16
23
  *
17
- * - **Non-expandable** (completed/skipped Read): a static `<div>` row
18
- * with a clickable {@link FilePathLink}. No chevron, no expansion.
19
- * The clickable path IS the complete information.
20
- * - **Expandable** (all other tools): a `<button>` row that toggles a
21
- * {@link ToolCallDetail} or {@link SubAgentSection} detail panel.
24
+ * - **Non-expandable** (completed/skipped Read): a static `<div>` row with a
25
+ * clickable {@link FilePathLink}. The path IS the complete information.
26
+ * - **Preview** (content-bearing: shell / edit / write / fetch / web-search /
27
+ * unknown / mcp): a plain (non-button) header above an **always-visible**
28
+ * {@link ToolCallDetail} body Cursor-style "previews aren't collapsible".
29
+ * There is no header chevron; each content block self-bounds with its own
30
+ * single in-place reveal (`RevealToggle`), so a long diff or output
31
+ * never floods the thread. The body is suppressed only for an `empty` result
32
+ * (e.g. a no-output shell), which stays a clean one-line row.
33
+ * - **Summary / sub-agent** (read / list / search / delete / think, and
34
+ * sub-agent delegations): a chevron-gated `div[role=button]` header that
35
+ * discloses a body hidden by default — {@link ToolCallDetail}, a
36
+ * {@link SubAgentSection}, or, when gated, an inline {@link ApprovalCardBody}.
37
+ * {@link useAutoDisclosure} force-opens it while *running* or *awaiting
38
+ * approval*, then settles it closed; a manual click always wins thereafter.
39
+ *
40
+ * The two disclosure axes — the card-level chevron and a block's
41
+ * content-overflow reveal — never govern the same body, which is what removes
42
+ * the old "expand, then Show more" double control.
22
43
  *
23
44
  * Shows category-aware labels (e.g., "Shell", "Read", "Edit") with
24
45
  * the primary argument as a subtitle, a category-specific icon, and
25
46
  * an inline approval decision badge when applicable.
26
47
  *
48
+ * Wrapped in `React.memo` — structural sharing (DD-009/010) preserves
49
+ * the `ToolCall` reference when unchanged, so a settled row skips
50
+ * re-renders while sibling tools stream.
51
+ *
27
52
  * @example
28
53
  * ```tsx
29
54
  * <ToolCallItem toolCall={tc} />
30
55
  * <ToolCallItem toolCall={tc} subAgentExecution={sub} />
31
56
  * ```
32
57
  */
33
- export function ToolCallItem({ toolCall, subAgentExecution, defaultExpanded = false, className, }) {
34
- const [expanded, setExpanded] = useState(defaultExpanded);
58
+ export const ToolCallItem = memo(function ToolCallItem({ toolCall, subAgentExecution, defaultExpanded = false, bordered = true, className, }) {
59
+ useRenderTracer("ToolCallItem", { status: toolCall.status, id: toolCall.id });
35
60
  const status = mapToolCallStatus(toolCall);
36
61
  const StatusIcon = STATUS_ICON[status];
37
62
  const duration = formatDuration(toolCall.startedAt, toolCall.completedAt);
38
63
  const isSubAgent = subAgentExecution != null;
39
- const { category, label, primaryArg, resultSummary } = useToolPresentation(toolCall);
64
+ const { category, label, primaryArg, result, resultSummary, disclosure } = useToolPresentation(toolCall);
40
65
  const CategoryIcon = CATEGORY_ICON[category];
66
+ // An unresolved approval gating this exact call (parent or nested sub-agent),
67
+ // or null. Drives the inline approval panel and forces the row open.
68
+ const approval = useApproval(toolCall.id);
69
+ // The card-level disclosure for *summary* rows (preview rows ignore it — their
70
+ // body is always visible). Force-open only while the row carries live or
71
+ // actionable content: while it runs, or while it awaits approval; a manual
72
+ // toggle takes over from there. Called unconditionally to honour the rules of
73
+ // hooks even though preview rows do not read `expanded`.
74
+ const autoOpen = toolCall.status === ToolCallStatus.TOOL_CALL_RUNNING || approval != null;
75
+ const [expanded, handleToggle] = useAutoDisclosure(autoOpen, {
76
+ initialOpen: defaultExpanded || autoOpen,
77
+ });
41
78
  const displayLabel = isSubAgent
42
79
  ? subAgentExecution.subject || subAgentExecution.name || label
43
80
  : label;
44
- const normalize = useSandboxNormalize();
45
81
  const approvalBadge = getApprovalBadge(toolCall);
82
+ // A flowed file edit stamped with its change set id badges the set's live
83
+ // review state (pending review / kept / discarded) right on the row — the
84
+ // observational record stays in place while the decision surface is the
85
+ // set's own bar. Null for unstamped rows and honest-degradation cases.
86
+ const reviewState = useFileReviewRowState(toolCall.fileChangeSetId, primaryArg);
87
+ const reviewBadge = reviewState ? REVIEW_BADGE[reviewState] : null;
46
88
  const selection = useThreadSelection("tool-call", toolCall.id);
89
+ // Search/list show their query/path as the header subtitle (truncated). Track
90
+ // whether it actually clips so the expanded detail can restate the full,
91
+ // wrapping value only when needed — avoiding a redundant repeat of a short
92
+ // value the header already shows in full. Gated to these two categories so
93
+ // only the rows that consume the signal pay for the measurement.
94
+ const measuresSubtitle = category === "search" || category === "list";
95
+ const { ref: subtitleRef, isTruncated: primaryArgTruncated } = useIsTextTruncated(measuresSubtitle);
96
+ // Cursor-style chrome: each tool call is its own self-contained card — a thin
97
+ // rounded neutral border. A pending gate carries a restrained left accent on
98
+ // the card itself (warning, or destructive for a delete); that accent is the
99
+ // only "awaiting you" cue now that the amber fill is gone. Nested inside a
100
+ // folded run chip the card degrades to a divider-separated row (via
101
+ // `bordered={false}`) so we never draw a card inside a card.
102
+ const cardClass = bordered
103
+ ? cn(
104
+ // border-prominent (not border): a transparent card needs a line the eye
105
+ // actually catches — the default border token is white at 14% opacity,
106
+ // which vanishes on the dark thread surface.
107
+ "rounded-lg border border-border-prominent overflow-hidden", approval != null &&
108
+ (category === "delete"
109
+ ? "border-l-2 border-l-destructive"
110
+ : "border-l-2 border-l-warning"), selection?.isSelected && "ring-1 ring-primary/40")
111
+ : cn("border-b border-border-muted last:border-b-0", selection?.isSelected && "ring-1 ring-primary/40 rounded-sm");
47
112
  // Completed/skipped Read items are non-expandable — the clickable
48
113
  // path in the row is the complete information. Failed reads remain
49
114
  // expandable to show the error.
@@ -51,20 +116,59 @@ export function ToolCallItem({ toolCall, subAgentExecution, defaultExpanded = fa
51
116
  category === "read" &&
52
117
  (toolCall.status === ToolCallStatus.TOOL_CALL_COMPLETED ||
53
118
  toolCall.status === ToolCallStatus.TOOL_CALL_SKIPPED);
54
- const trailingContent = (_jsxs(_Fragment, { children: [approvalBadge && (_jsx("span", { className: cn("shrink-0 rounded px-1 py-0.5 text-[10px] font-medium leading-none", approvalBadge.colorClass), children: approvalBadge.label })), toolCall.mcpServerSlug && (_jsx("span", { className: "shrink-0 rounded bg-muted px-1 py-0.5 font-mono text-muted-foreground", children: toolCall.mcpServerSlug })), _jsx("span", { className: cn("shrink-0", STATUS_COLOR[status]), "aria-hidden": "true", children: _jsx(StatusIcon, {}) }), duration && (_jsx("span", { className: "shrink-0 tabular-nums text-muted-foreground", children: duration })), selection && (_jsx("button", { type: "button", onClick: (e) => {
119
+ const trailingContent = (_jsxs(_Fragment, { children: [approvalBadge && (_jsx("span", { className: cn("shrink-0 rounded px-1 py-0.5 text-[10px] font-medium leading-none", approvalBadge.colorClass), children: approvalBadge.label })), reviewBadge && (_jsx("span", { className: cn("shrink-0 rounded px-1 py-0.5 text-[10px] font-medium leading-none", reviewBadge.colorClass), "data-cursor-target": "file-review-row-badge", children: reviewBadge.label })), toolCall.mcpServerSlug && (_jsx("span", { className: "shrink-0 rounded bg-muted px-1 py-0.5 font-mono text-muted-foreground", children: toolCall.mcpServerSlug })), _jsx("span", { className: cn("shrink-0", STATUS_COLOR[status]), "aria-hidden": "true", children: _jsx(StatusIcon, {}) }), duration && (_jsx("span", { className: "shrink-0 tabular-nums text-muted-foreground", children: duration })), selection && (_jsx("button", { type: "button", onClick: (e) => {
55
120
  e.stopPropagation();
56
121
  selection.select();
57
122
  }, className: cn("shrink-0 rounded p-0.5 text-muted-foreground hover:text-foreground hover:bg-muted transition-colors", selection.isSelected && "text-primary"), "aria-label": "Inspect tool call", "aria-pressed": selection.isSelected, children: _jsx(InspectIcon, {}) }))] }));
58
123
  if (isNonExpandableRead) {
59
- return (_jsx("div", { className: cn("border-b border-border-muted last:border-b-0", selection?.isSelected && "ring-1 ring-primary/40 rounded-sm", className), children: _jsxs("div", { className: "flex w-full items-center gap-2 px-2.5 py-1.5 text-xs", children: [_jsx("span", { className: "shrink-0 text-muted-foreground", "aria-hidden": "true", children: _jsx(CategoryIcon, {}) }), _jsxs("span", { className: "min-w-0 flex-1 flex items-center gap-1.5 overflow-hidden", children: [_jsx("span", { className: "shrink-0 font-medium text-foreground", children: displayLabel }), primaryArg && (_jsx(FilePathLink, { path: primaryArg, className: "min-w-0 text-xs" }))] }), trailingContent] }) }));
124
+ return (_jsx("div", { "data-cursor-target": "tool-call-row", className: cn(cardClass, className), children: _jsxs("div", { className: "flex w-full items-center gap-2 px-2.5 py-1.5 text-xs", children: [_jsx("span", { className: "shrink-0 text-muted-foreground", "aria-hidden": "true", children: _jsx(CategoryIcon, {}) }), _jsxs("span", { className: "min-w-0 flex-1 flex items-center gap-1.5 overflow-hidden", children: [_jsx("span", { className: "shrink-0 font-medium text-foreground", children: displayLabel }), primaryArg && (_jsx(FilePathLink, { path: primaryArg, className: "min-w-0 text-xs" }))] }), trailingContent] }) }));
60
125
  }
61
- const displaySubtitle = isSubAgent
62
- ? null
63
- : category === "shell" && primaryArg
64
- ? normalize(primaryArg)
65
- : primaryArg;
66
- return (_jsxs("div", { className: cn("border-b border-border-muted last:border-b-0", selection?.isSelected && "ring-1 ring-primary/40 rounded-sm", className), children: [_jsxs("button", { type: "button", "aria-expanded": expanded, onClick: () => setExpanded((v) => !v), className: cn("flex w-full items-center gap-2 px-2.5 py-1.5 text-left text-xs transition-colors", "hover:bg-muted-subtle", expanded && "bg-muted-faint"), children: [_jsx("span", { className: "shrink-0 text-muted-foreground", "aria-hidden": "true", children: _jsx(CategoryIcon, {}) }), _jsxs("span", { className: "min-w-0 flex-1 flex items-baseline gap-1.5 overflow-hidden", children: [_jsx("span", { className: "shrink-0 font-medium text-foreground", children: displayLabel }), displaySubtitle && (_jsx("span", { className: "min-w-0 truncate text-muted-foreground font-mono", children: displaySubtitle })), !isSubAgent && resultSummary && (_jsx("span", { className: "shrink-0 tabular-nums text-muted-foreground", children: resultSummary }))] }), trailingContent, _jsx(ChevronIcon, { expanded: expanded })] }), expanded && (_jsx("div", { className: "px-2.5 pb-2.5 pt-1", children: isSubAgent ? (_jsx(SubAgentSection, { subAgentExecution: subAgentExecution, collapsible: false })) : (_jsx(ToolCallDetail, { toolCall: toolCall })) }))] }));
67
- }
126
+ // Shell shows neither a command subtitle nor an exit summary in the header —
127
+ // both live in the terminal session body below, so the header stays minimal
128
+ // (icon + label + status + duration).
129
+ const displaySubtitle = isSubAgent || category === "shell" ? null : primaryArg;
130
+ // For file tools the subtitle is a path: render it filename-first through
131
+ // FilePathLink (full path on hover) rather than the raw, often-absolute string
132
+ // that buried the file name behind a long prefix.
133
+ const subtitleIsFilePath = !isSubAgent && primaryArg != null && isFileCategory(category);
134
+ // Preview categories (shell, edit, write, fetch, web-search, unknown, mcp)
135
+ // render their body ALWAYS — Cursor-style "previews aren't collapsible" — so
136
+ // no header chevron competes with the body's own in-place reveal. Summary
137
+ // categories and sub-agents keep the chevron: their body is genuinely hidden
138
+ // by default, so the chevron has a real job. The two disclosure axes
139
+ // (card-level chevron vs. content-overflow reveal) never govern one body.
140
+ const isPreviewCategory = !isSubAgent && disclosure === "preview";
141
+ // The disclosed body, shared by both layouts: a pending gate decides inline,
142
+ // a sub-agent shows its delegation, otherwise the category detail.
143
+ const body = isSubAgent ? (_jsx(SubAgentSection, { subAgentExecution: subAgentExecution, collapsible: false })) : approval ? (
144
+ // The row above is this approval's header, so render only the body (preview
145
+ // + actions). The enclosing card already carries the border + warning/
146
+ // destructive accent for a pending gate, so the body renders borderless.
147
+ _jsx(ApprovalCardBody, { pendingApproval: approval.pendingApproval, onSubmit: approval.onSubmit, isSubmitting: approval.isSubmitting, error: approval.error })) : (_jsx(ToolCallDetail, { toolCall: toolCall, primaryArgTruncated: primaryArgTruncated }));
148
+ // The header's metadata, identical in both layouts (the chevron is appended
149
+ // only by the summary layout below).
150
+ const headerInner = (_jsxs(_Fragment, { children: [_jsx("span", { className: "shrink-0 text-muted-foreground", "aria-hidden": "true", children: _jsx(CategoryIcon, {}) }), _jsxs("span", { className: "min-w-0 flex-1 flex items-baseline gap-1.5 overflow-hidden", children: [_jsx("span", { className: "shrink-0 font-medium text-foreground", children: displayLabel }), subtitleIsFilePath && primaryArg ? (_jsx(FilePathLink, { path: primaryArg, className: "min-w-0 text-xs text-muted-foreground" })) : (displaySubtitle && (_jsx("span", { ref: measuresSubtitle ? subtitleRef : undefined, title: displaySubtitle, className: "min-w-0 truncate text-muted-foreground font-mono", children: displaySubtitle }))), !isSubAgent && category !== "shell" && resultSummary && (_jsx("span", { className: "shrink-0 tabular-nums text-muted-foreground", children: resultSummary }))] }), trailingContent] }));
151
+ // Preview layout: a plain (non-button) header above an always-visible body.
152
+ // The body renders only when it has something to show — a pending gate, or a
153
+ // non-empty result — so a no-output shell (which normalizes to an `empty`
154
+ // result) stays a clean one-line row, never an empty padded box.
155
+ if (isPreviewCategory) {
156
+ const showBody = approval != null || result.type !== "empty";
157
+ return (_jsxs("div", { "data-cursor-target": "tool-call-row", className: cn(cardClass, className), children: [_jsx("div", { className: "flex w-full items-center gap-2 px-2.5 py-1.5 text-xs", children: headerInner }), showBody && (_jsx("div", { className: "px-2.5 pb-2.5 pt-1", "data-cursor-target": "tool-preview", children: body }))] }));
158
+ }
159
+ // Summary / sub-agent layout: a chevron-gated header disclosing a body hidden
160
+ // by default. The header is a div[role=button], not a <button>, because it
161
+ // carries the nested "Inspect tool call" <button> (a <button> may not contain
162
+ // another); Enter/Space drive the toggle for keyboard parity.
163
+ return (_jsxs("div", { "data-cursor-target": "tool-call-row", className: cn(cardClass, className), children: [_jsxs("div", { role: "button", tabIndex: 0, "aria-expanded": expanded, onClick: handleToggle, onKeyDown: (e) => {
164
+ if (e.key === "Enter" || e.key === " ") {
165
+ e.preventDefault();
166
+ handleToggle();
167
+ }
168
+ }, className: cn("flex w-full cursor-pointer items-center gap-2 px-2.5 py-1.5 text-left text-xs transition-colors", "hover:bg-muted-subtle",
169
+ // ring-inset so the card's overflow-hidden does not clip the focus ring.
170
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring", expanded && "bg-muted-faint"), children: [headerInner, _jsx(ChevronIcon, { expanded: expanded })] }), expanded && _jsx("div", { className: "px-2.5 pb-2.5 pt-1", children: body })] }));
171
+ });
68
172
  function getApprovalBadge(toolCall) {
69
173
  if (!toolCall.requiresApproval)
70
174
  return null;
@@ -79,6 +183,21 @@ function getApprovalBadge(toolCall) {
79
183
  return null;
80
184
  }
81
185
  }
186
+ // ---------------------------------------------------------------------------
187
+ // File-review badge — a stamped edit row's live review state
188
+ // ---------------------------------------------------------------------------
189
+ /**
190
+ * The badge pill for each {@link FileReviewRowState}, in the approval badge's
191
+ * visual vocabulary. "Kept"/"Discarded" match the decision surface's verdict
192
+ * copy (see FileReviewCard's VerdictBadge) so the row and the bar always speak
193
+ * the same language.
194
+ */
195
+ const REVIEW_BADGE = {
196
+ pending: { label: "Pending review", colorClass: "bg-warning/15 text-warning" },
197
+ kept: { label: "Kept", colorClass: "bg-success/15 text-success" },
198
+ discarded: { label: "Discarded", colorClass: "bg-destructive/15 text-destructive" },
199
+ failed: { label: "Review failed", colorClass: "bg-destructive/15 text-destructive" },
200
+ };
82
201
  function mapToolCallStatus(toolCall) {
83
202
  switch (toolCall.status) {
84
203
  case ToolCallStatus.TOOL_CALL_RUNNING: